2 // Mono.ILASM.ExternTable.cs
5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
11 using System
.Collections
;
12 using System
.Reflection
;
14 namespace Mono
.ILASM
{
16 public abstract class ExternRef
{
18 protected string name
;
19 protected Hashtable class_table
;
20 protected Hashtable typeref_table
;
22 public abstract void Resolve (CodeGen codegen
);
23 public abstract PEAPI
.IExternRef
GetExternRef ();
25 public ExternRef (string name
)
28 typeref_table
= new Hashtable ();
29 class_table
= new Hashtable ();
32 public ExternTypeRef
GetTypeRef (string full_name
, bool is_valuetype
, ExternTable table
)
34 ExternTypeRef type_ref
= typeref_table
[full_name
] as ExternTypeRef
;
39 type_ref
= new ExternTypeRef (this, full_name
, is_valuetype
, table
);
40 typeref_table
[full_name
] = type_ref
;
45 public PEAPI
.ClassRef
GetType (string full_name
)
47 PEAPI
.ClassRef klass
= class_table
[full_name
] as PEAPI
.ClassRef
;
52 string name_space
, name
;
53 ExternTable
.GetNameAndNamespace (full_name
, out name_space
, out name
);
55 klass
= (PEAPI
.ClassRef
) GetExternRef ().AddClass (name_space
, name
);
56 class_table
[full_name
] = klass
;
61 public PEAPI
.ClassRef
GetValueType (string full_name
)
63 PEAPI
.ClassRef klass
= class_table
[full_name
] as PEAPI
.ClassRef
;
68 string name_space
, name
;
69 ExternTable
.GetNameAndNamespace (full_name
, out name_space
, out name
);
71 klass
= (PEAPI
.ClassRef
) GetExternRef ().AddValueClass (name_space
, name
);
72 class_table
[full_name
] = klass
;
78 public class ExternModule
: ExternRef
{
80 public PEAPI
.ModuleRef ModuleRef
;
82 public ExternModule (string name
) : base (name
)
86 public override void Resolve (CodeGen codegen
)
88 ModuleRef
= codegen
.PEFile
.AddExternModule (name
);
92 public override PEAPI
.IExternRef
GetExternRef ()
98 public class ExternAssembly
: ExternRef
{
100 public PEAPI
.AssemblyRef AssemblyRef
;
102 private int major
, minor
, build
, revision
;
103 private byte [] public_key
;
104 private byte [] public_key_token
;
105 private string locale
;
106 private byte [] hash
;
108 private ArrayList cattrs_list
;
110 public ExternAssembly (string name
, AssemblyName asmb_name
) : base (name
)
113 major
= minor
= build
= revision
= -1;
116 public override void Resolve (CodeGen code_gen
)
118 AssemblyRef
= code_gen
.PEFile
.AddExternAssembly (name
);
120 AssemblyRef
.AddVersionInfo (major
, minor
, build
, revision
);
121 if (public_key
!= null)
122 AssemblyRef
.AddKey (public_key
);
123 if (public_key_token
!= null)
124 AssemblyRef
.AddKeyToken (public_key_token
);
126 AssemblyRef
.AddCulture (locale
);
128 AssemblyRef
.AddHash (hash
);
130 if (cattrs_list
!= null) {
131 foreach (CustomAttr cattr
in cattrs_list
)
132 cattr
.AddTo (code_gen
, AssemblyRef
);
135 class_table
= new Hashtable ();
138 public override PEAPI
.IExternRef
GetExternRef ()
143 public void SetVersion (int major
, int minor
, int build
, int revision
)
148 this.revision
= revision
;
151 public void SetPublicKey (byte [] public_key
)
153 this.public_key
= public_key
;
156 public void SetPublicKeyToken (byte [] public_key_token
)
158 this.public_key_token
= public_key_token
;
161 public void SetLocale (string locale
)
163 this.locale
= locale
;
166 public void SetHash (byte [] hash
)
171 public void AddCustomAttribute (CustomAttr cattr
)
173 if (cattrs_list
== null)
174 cattrs_list
= new ArrayList ();
175 cattrs_list
.Add (cattr
);
180 public class ExternTable
{
182 Hashtable assembly_table
;
183 Hashtable module_table
;
185 public ExternTable ()
188 string mscorlib_name
= "mscorlib";
189 AssemblyName mscorlib
= new AssemblyName ();
190 mscorlib
.Name
= mscorlib_name
;
191 AddAssembly (mscorlib_name
, mscorlib
);
193 // Also need to alias corlib, normally corlib and
194 // mscorlib are used interchangably
195 assembly_table
["corlib"] = assembly_table
["mscorlib"];
198 public ExternAssembly
AddAssembly (string name
, AssemblyName asmb_name
)
200 ExternAssembly ea
= null;
202 if (assembly_table
== null) {
203 assembly_table
= new Hashtable ();
205 ea
= assembly_table
[name
] as ExternAssembly
;
210 ea
= new ExternAssembly (name
, asmb_name
);
212 assembly_table
[name
] = ea
;
217 public ExternModule
AddModule (string name
)
219 ExternModule em
= null;
221 if (module_table
== null) {
222 module_table
= new Hashtable ();
224 em
= module_table
[name
] as ExternModule
;
229 em
= new ExternModule (name
);
231 module_table
[name
] = em
;
236 public void Resolve (CodeGen code_gen
)
238 // Assembly table is never null because we add mscorlib
239 foreach (ExternAssembly ext
in assembly_table
.Values
)
240 ext
.Resolve (code_gen
);
241 if (module_table
== null)
243 foreach (ExternModule ext
in module_table
.Values
)
244 ext
.Resolve (code_gen
);
247 public ExternTypeRef
GetTypeRef (string asmb_name
, string full_name
, bool is_valuetype
)
249 ExternAssembly ext_asmb
;
250 ext_asmb
= assembly_table
[asmb_name
] as ExternAssembly
;
252 if (ext_asmb
== null)
253 throw new Exception (String
.Format ("Assembly {0} not defined.", asmb_name
));
255 return ext_asmb
.GetTypeRef (full_name
, is_valuetype
, this);
258 public ExternTypeRef
GetModuleTypeRef (string mod_name
, string full_name
, bool is_valuetype
)
261 mod
= module_table
[mod_name
] as ExternModule
;
264 throw new Exception (String
.Format ("Module {0} not defined.", mod_name
));
266 return mod
.GetTypeRef (full_name
, is_valuetype
, this);
269 public static void GetNameAndNamespace (string full_name
,
270 out string name_space
, out string name
) {
272 int last_dot
= full_name
.LastIndexOf ('.');
275 name_space
= String
.Empty
;
280 name_space
= full_name
.Substring (0, last_dot
);
281 name
= full_name
.Substring (last_dot
+ 1);