2 // Mono.ILASM.ExternMethodRef
5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
12 using System.Collections;
14 namespace Mono.ILASM {
16 public class ExternMethodRef : IMethodRef {
18 private ExternTypeRef owner;
19 private ITypeRef ret_type;
21 private ITypeRef[] param;
22 private PEAPI.CallConv call_conv;
24 private PEAPI.Method peapi_method;
25 private bool is_resolved;
26 private int gen_param_count;
28 public ExternMethodRef (ExternTypeRef owner, ITypeRef ret_type,
29 PEAPI.CallConv call_conv, string name, ITypeRef[] param, int gen_param_count)
32 this.ret_type = ret_type;
35 this.call_conv = call_conv;
36 this.gen_param_count = gen_param_count;
37 if (gen_param_count > 0)
38 CallConv |= PEAPI.CallConv.Generic;
43 public PEAPI.Method PeapiMethod {
44 get { return peapi_method; }
47 public PEAPI.CallConv CallConv {
48 get { return call_conv; }
49 set { call_conv = value; }
52 public ITypeRef Owner {
56 public void Resolve (CodeGen code_gen)
61 if ((call_conv & PEAPI.CallConv.Vararg) != 0) {
62 ResolveVararg (code_gen);
66 PEAPI.Type[] param_list = new PEAPI.Type[param.Length];
69 ret_type.Resolve (code_gen);
72 foreach (ITypeRef typeref in param) {
73 typeref.Resolve (code_gen);
74 param_list[count++] = typeref.PeapiType;
82 owner.Resolve (code_gen);
84 if (owner.UseTypeSpec) {
85 PEAPI.Type owner_ref = owner.PeapiType;
86 peapi_method = code_gen.PEFile.AddMethodToTypeSpec (owner_ref, write_name,
87 ret_type.PeapiType, param_list, gen_param_count);
89 PEAPI.ClassRef owner_ref;
90 owner_ref = (PEAPI.ClassRef) owner.PeapiType;
91 peapi_method = owner_ref.AddMethod (write_name,
92 ret_type.PeapiType, param_list, gen_param_count);
95 peapi_method.AddCallConv (call_conv);
100 protected void ResolveVararg (CodeGen code_gen)
105 ArrayList param_list = new ArrayList ();
106 ArrayList opt_list = new ArrayList ();
110 ret_type.Resolve (code_gen);
113 foreach (ITypeRef typeref in param) {
115 typeref.Resolve (code_gen);
116 opt_list.Add (typeref.PeapiType);
117 } else if (TypeRef.Ellipsis == typeref) {
120 typeref.Resolve (code_gen);
121 param_list.Add (typeref.PeapiType);
125 if (name == "<init>")
126 write_name = ".ctor";
131 throw new NotImplementedException ("Vararg methods on arrays are not supported yet.");
133 owner.Resolve (code_gen);
135 if (owner.UseTypeSpec) {
136 PEAPI.Type owner_ref = owner.PeapiType;
137 peapi_method = code_gen.PEFile.AddVarArgMethodToTypeSpec (owner_ref,
138 write_name, ret_type.PeapiType,
139 (PEAPI.Type[]) param_list.ToArray (typeof (PEAPI.Type)),
140 (PEAPI.Type[]) opt_list.ToArray (typeof (PEAPI.Type)));
142 PEAPI.ClassRef owner_ref;
143 owner_ref = (PEAPI.ClassRef) owner.PeapiType;
144 peapi_method = owner_ref.AddVarArgMethod (write_name,
146 (PEAPI.Type[]) param_list.ToArray (typeof (PEAPI.Type)),
147 (PEAPI.Type[]) opt_list.ToArray (typeof (PEAPI.Type)));
151 peapi_method.AddCallConv (call_conv);