This should fix #76928. This fix incorporates ideas from a patch
[mono.git] / mcs / ilasm / codegen / MethodRef.cs
1 //
2 // Mono.ILASM.MethodRef
3 //
4 // Author(s):
5 //  Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper, All rights reserved
8 //
9
10
11 using System;
12 using System.Collections;
13
14 namespace Mono.ILASM {
15
16         public class MethodRef : IMethodRef {
17
18                 private TypeRef owner;
19                 private PEAPI.CallConv call_conv;
20                 private ITypeRef ret_type;
21                 private string name;
22                 private ITypeRef[] param;
23
24                 private PEAPI.Method peapi_method;
25                 private bool is_resolved;
26                 private int gen_param_count;
27
28                 public MethodRef (TypeRef owner, PEAPI.CallConv call_conv,
29                         ITypeRef ret_type, string name, ITypeRef[] param, int gen_param_count)
30                 {
31                         this.owner = owner;
32                         this.call_conv = call_conv;
33                         this.ret_type = ret_type;
34                         this.name = name;
35                         this.param = param;
36                         this.gen_param_count = gen_param_count;
37                         is_resolved = false;
38                 }
39
40                 public PEAPI.Method PeapiMethod {
41                         get { return peapi_method; }
42                 }
43
44                 public PEAPI.CallConv CallConv {
45                         get { return call_conv; }
46                         set { call_conv = value; }
47                 }
48
49                 public ITypeRef Owner {
50                         get { return owner; }
51                 }
52
53                 public void Resolve (CodeGen code_gen)
54                 {
55                         if (is_resolved)
56                                 return;
57
58                         TypeDef owner_def = code_gen.TypeManager[owner.FullName];
59                         if (owner_def == null)
60                                 throw new Exception (String.Format ("Reference to undefined class '{0}'", owner.FullName));
61
62                         string write_name;
63
64                         if (name == "<init>")
65                                 write_name = ".ctor";
66                         else
67                                 write_name = name;
68
69                         string sig;
70
71                         if ((call_conv & PEAPI.CallConv.Vararg) == 0) {
72                                 sig = MethodDef.CreateSignature (ret_type, name, param, gen_param_count);
73                                 peapi_method = owner_def.ResolveMethod (sig, code_gen);
74                         } else {
75                                 sig = MethodDef.CreateVarargSignature (ret_type, name, param);
76                                 ArrayList opt_list = new ArrayList ();
77                                 bool in_opt = false;
78                                 foreach (ITypeRef type in param) {
79                                         if (type is SentinelTypeRef) {
80                                                 in_opt = true;
81                                         } else if (in_opt) {
82                                                 type.Resolve (code_gen);
83                                                 opt_list.Add (type.PeapiType);
84                                         }
85                                 }
86                                 peapi_method = owner_def.ResolveVarargMethod (sig, code_gen,
87                                                 (PEAPI.Type[]) opt_list.ToArray (typeof (PEAPI.Type)));
88                         }
89
90                         is_resolved = true;
91
92                 }
93
94         }
95
96 }
97