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 : ICustomAttrTarget {
18 protected string name;
19 protected Hashtable class_table;
20 protected Hashtable typeref_table;
21 protected ArrayList customattr_list;
23 public abstract void Resolve (CodeGen codegen);
24 public abstract PEAPI.IExternRef GetExternRef ();
26 public ExternRef (string name)
29 typeref_table = new Hashtable ();
30 class_table = new Hashtable ();
37 public void AddCustomAttribute (CustomAttr customattr)
39 if (customattr_list == null)
40 customattr_list = new ArrayList ();
42 customattr_list.Add (customattr);
45 public ExternTypeRef GetTypeRef (string full_name, bool is_valuetype, ExternTable table)
47 ExternTypeRef type_ref = typeref_table [full_name] as ExternTypeRef;
49 if (type_ref != null) {
51 type_ref.MakeValueClass ();
55 type_ref = new ExternTypeRef (this, full_name, is_valuetype, table);
56 typeref_table [full_name] = type_ref;
61 public PEAPI.ClassRef GetType (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 ().AddClass (name_space, name);
72 class_table[full_name] = klass;
77 public PEAPI.ClassRef GetValueType (string full_name)
79 PEAPI.ClassRef klass = class_table[full_name] as PEAPI.ClassRef;
84 string name_space, name;
85 ExternTable.GetNameAndNamespace (full_name, out name_space, out name);
87 klass = (PEAPI.ClassRef) GetExternRef ().AddValueClass (name_space, name);
88 class_table[full_name] = klass;
94 public class ExternModule : ExternRef {
96 public PEAPI.ModuleRef ModuleRef;
98 public ExternModule (string name) : base (name)
102 public override void Resolve (CodeGen codegen)
104 ModuleRef = codegen.PEFile.AddExternModule (name);
105 if (customattr_list != null)
106 foreach (CustomAttr customattr in customattr_list)
107 customattr.AddTo (codegen, ModuleRef);
111 public override PEAPI.IExternRef GetExternRef ()
117 public class ExternAssembly : ExternRef, IDeclSecurityTarget {
119 public PEAPI.AssemblyRef AssemblyRef;
121 private int major, minor, build, revision;
122 private byte [] public_key;
123 private byte [] public_key_token;
124 private string locale;
125 private byte [] hash;
126 private ArrayList declsec_list;
128 public ExternAssembly (string name, AssemblyName asmb_name) : base (name)
131 major = minor = build = revision = -1;
134 public override void Resolve (CodeGen code_gen)
136 AssemblyRef = code_gen.PEFile.AddExternAssembly (name);
138 AssemblyRef.AddVersionInfo (major, minor, build, revision);
139 if (public_key != null)
140 AssemblyRef.AddKey (public_key);
141 if (public_key_token != null)
142 AssemblyRef.AddKeyToken (public_key_token);
144 AssemblyRef.AddCulture (locale);
146 AssemblyRef.AddHash (hash);
148 if (customattr_list != null)
149 foreach (CustomAttr customattr in customattr_list)
150 customattr.AddTo (code_gen, AssemblyRef);
152 if (declsec_list != null)
153 foreach (DeclSecurity decl_sec in declsec_list)
154 decl_sec.AddTo (code_gen, AssemblyRef);
156 class_table = new Hashtable ();
159 public override PEAPI.IExternRef GetExternRef ()
164 public void AddDeclSecurity (DeclSecurity decl_sec)
166 if (declsec_list == null)
167 declsec_list = new ArrayList ();
169 declsec_list.Add (decl_sec);
172 public void SetVersion (int major, int minor, int build, int revision)
177 this.revision = revision;
180 public void SetPublicKey (byte [] public_key)
182 this.public_key = public_key;
185 public void SetPublicKeyToken (byte [] public_key_token)
187 this.public_key_token = public_key_token;
190 public void SetLocale (string locale)
192 this.locale = locale;
195 public void SetHash (byte [] hash)
203 public class ExternTable {
205 Hashtable assembly_table;
206 Hashtable module_table;
208 public void AddCorlib ()
211 string mscorlib_name = "mscorlib";
212 AssemblyName mscorlib = new AssemblyName ();
213 mscorlib.Name = mscorlib_name;
214 AddAssembly (mscorlib_name, mscorlib);
216 // Also need to alias corlib, normally corlib and
217 // mscorlib are used interchangably
218 assembly_table["corlib"] = assembly_table["mscorlib"];
221 public ExternAssembly AddAssembly (string name, AssemblyName asmb_name)
223 ExternAssembly ea = null;
225 if (assembly_table == null) {
226 assembly_table = new Hashtable ();
228 ea = assembly_table [name] as ExternAssembly;
233 ea = new ExternAssembly (name, asmb_name);
235 assembly_table [name] = ea;
240 public ExternModule AddModule (string name)
242 ExternModule em = null;
244 if (module_table == null) {
245 module_table = new Hashtable ();
247 em = module_table [name] as ExternModule;
252 em = new ExternModule (name);
254 module_table [name] = em;
259 public void Resolve (CodeGen code_gen)
261 if (assembly_table != null)
262 foreach (ExternAssembly ext in assembly_table.Values)
263 ext.Resolve (code_gen);
264 if (module_table == null)
266 foreach (ExternModule ext in module_table.Values)
267 ext.Resolve (code_gen);
270 public ExternTypeRef GetTypeRef (string asmb_name, string full_name, bool is_valuetype)
272 ExternAssembly ext_asmb = null;
273 if (assembly_table == null && (asmb_name == "mscorlib" || asmb_name == "corlib"))
274 /* AddCorlib if mscorlib is being referenced but
275 we haven't encountered a ".assembly 'name'" as yet. */
277 if (assembly_table != null)
278 ext_asmb = assembly_table[asmb_name] as ExternAssembly;
280 if (ext_asmb == null)
281 throw new Exception (String.Format ("Assembly {0} not defined.", asmb_name));
283 return ext_asmb.GetTypeRef (full_name, is_valuetype, this);
286 public ExternTypeRef GetModuleTypeRef (string mod_name, string full_name, bool is_valuetype)
289 mod = module_table [mod_name] as ExternModule;
292 throw new Exception (String.Format ("Module {0} not defined.", mod_name));
294 return mod.GetTypeRef (full_name, is_valuetype, this);
297 public static void GetNameAndNamespace (string full_name,
298 out string name_space, out string name) {
300 int last_dot = full_name.LastIndexOf ('.');
303 name_space = String.Empty;
308 name_space = full_name.Substring (0, last_dot);
309 name = full_name.Substring (last_dot + 1);