X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Filasm%2Fcodegen%2FExternTable.cs;h=037ecfada85d04521baabf5c74d462dce137c0a0;hb=5d9434fcb3acc1ed7d3d30603faae797d672fe65;hp=503f752fe811fce3f204cd09aa3e4461c1261540;hpb=98a86ecd4ba2d3b4631d98ac5a4abf23f4e6c3e3;p=mono.git diff --git a/mcs/ilasm/codegen/ExternTable.cs b/mcs/ilasm/codegen/ExternTable.cs index 503f752fe81..037ecfada85 100644 --- a/mcs/ilasm/codegen/ExternTable.cs +++ b/mcs/ilasm/codegen/ExternTable.cs @@ -10,14 +10,24 @@ using System; using System.Collections; using System.Reflection; +using System.Security; +using System.Globalization; namespace Mono.ILASM { - public abstract class ExternRef { + public interface IScope { + ExternTypeRef GetTypeRef (string full_name, bool is_valuetype); + PEAPI.ClassRef GetType (string full_name, bool is_valuetype); + string FullName { get; } + } + + public abstract class ExternRef : ICustomAttrTarget, IScope { protected string name; protected Hashtable class_table; protected Hashtable typeref_table; + protected ArrayList customattr_list; + protected bool is_resolved; public abstract void Resolve (CodeGen codegen); public abstract PEAPI.IExternRef GetExternRef (); @@ -29,50 +39,64 @@ namespace Mono.ILASM { class_table = new Hashtable (); } - public ExternTypeRef GetTypeRef (string full_name, bool is_valuetype, ExternTable table) - { - ExternTypeRef type_ref = typeref_table [full_name] as ExternTypeRef; - - if (type_ref != null) - return type_ref; - - type_ref = new ExternTypeRef (this, full_name, is_valuetype, table); - typeref_table [full_name] = type_ref; - - return type_ref; + public string Name { + get { return name; } + } + + public virtual string FullName { + get { return name; } } - public PEAPI.ClassRef GetType (string full_name) + public void AddCustomAttribute (CustomAttr customattr) { - PEAPI.ClassRef klass = class_table[full_name] as PEAPI.ClassRef; - - if (klass != null) - return klass; + if (customattr_list == null) + customattr_list = new ArrayList (); - string name_space, name; - ExternTable.GetNameAndNamespace (full_name, out name_space, out name); + customattr_list.Add (customattr); + } - klass = (PEAPI.ClassRef) GetExternRef ().AddClass (name_space, name); - class_table[full_name] = klass; + public ExternTypeRef GetTypeRef (string full_name, bool is_valuetype) + { + string first= full_name; + string rest = ""; + int slash = full_name.IndexOf ('/'); + if (slash > 0) { + first = full_name.Substring (0, slash); + rest = full_name.Substring (slash + 1); + } + + ExternTypeRef type_ref = typeref_table [first] as ExternTypeRef; + + if (type_ref != null) { + if (is_valuetype && rest == "") + type_ref.MakeValueClass (); + } else { + type_ref = new ExternTypeRef (this, first, is_valuetype); + typeref_table [first] = type_ref; + } - return klass; + return (rest == "" ? type_ref : type_ref.GetTypeRef (rest, is_valuetype)); } - public PEAPI.ClassRef GetValueType (string full_name) + public PEAPI.ClassRef GetType (string full_name, bool is_valuetype) { PEAPI.ClassRef klass = class_table[full_name] as PEAPI.ClassRef; - - if (klass != null) + + if (klass != null) return klass; string name_space, name; ExternTable.GetNameAndNamespace (full_name, out name_space, out name); - klass = (PEAPI.ClassRef) GetExternRef ().AddValueClass (name_space, name); - class_table[full_name] = klass; + if (is_valuetype) + klass = (PEAPI.ClassRef) GetExternRef ().AddValueClass (name_space, name); + else + klass = (PEAPI.ClassRef) GetExternRef ().AddClass (name_space, name); + class_table [full_name] = klass; return klass; } + } public class ExternModule : ExternRef { @@ -83,9 +107,25 @@ namespace Mono.ILASM { { } + public override string FullName { + get { + //'name' field should not contain the [.module ] + //as its used for resolving + return String.Format ("[.module {0}]", name); + } + } + public override void Resolve (CodeGen codegen) { + if (is_resolved) + return; + ModuleRef = codegen.PEFile.AddExternModule (name); + if (customattr_list != null) + foreach (CustomAttr customattr in customattr_list) + customattr.AddTo (codegen, ModuleRef); + + is_resolved = true; } @@ -95,7 +135,7 @@ namespace Mono.ILASM { } } - public class ExternAssembly : ExternRef { + public class ExternAssembly : ExternRef, IDeclSecurityTarget { public PEAPI.AssemblyRef AssemblyRef; @@ -104,15 +144,41 @@ namespace Mono.ILASM { private byte [] public_key_token; private string locale; private byte [] hash; + private DeclSecurity decl_sec; + private AssemblyName asmb_name; public ExternAssembly (string name, AssemblyName asmb_name) : base (name) { this.name = name; + this.asmb_name = asmb_name; major = minor = build = revision = -1; } + public override string FullName { + get { + //'name' field should not contain the [] + //as its used for resolving + return String.Format ("[{0}]", name); + } + } + + public AssemblyName AssemblyName { + get { return asmb_name; } + } + + public DeclSecurity DeclSecurity { + get { + if (decl_sec == null) + decl_sec = new DeclSecurity (); + return decl_sec; + } + } + public override void Resolve (CodeGen code_gen) { + if (is_resolved) + return; + AssemblyRef = code_gen.PEFile.AddExternAssembly (name); if (major != -1) AssemblyRef.AddVersionInfo (major, minor, build, revision); @@ -124,41 +190,57 @@ namespace Mono.ILASM { AssemblyRef.AddCulture (locale); if (hash != null) AssemblyRef.AddHash (hash); + + if (customattr_list != null) + foreach (CustomAttr customattr in customattr_list) + customattr.AddTo (code_gen, AssemblyRef); + + if (decl_sec != null) + decl_sec.AddTo (code_gen, AssemblyRef); + class_table = new Hashtable (); + + is_resolved = true; } public override PEAPI.IExternRef GetExternRef () { return AssemblyRef; } - + public void SetVersion (int major, int minor, int build, int revision) { this.major = major; this.minor = minor; this.build = build; this.revision = revision; + asmb_name.Version = new Version (major, minor, build, revision); } public void SetPublicKey (byte [] public_key) { this.public_key = public_key; + asmb_name.SetPublicKey (public_key); } public void SetPublicKeyToken (byte [] public_key_token) { this.public_key_token = public_key_token; + asmb_name.SetPublicKey (public_key); } public void SetLocale (string locale) { this.locale = locale; + //FIXME: is this correct? + asmb_name.CultureInfo = new CultureInfo (locale); } public void SetHash (byte [] hash) { this.hash = hash; } + } @@ -166,8 +248,9 @@ namespace Mono.ILASM { Hashtable assembly_table; Hashtable module_table; + bool is_resolved; - public ExternTable () + public void AddCorlib () { // Add mscorlib string mscorlib_name = "mscorlib"; @@ -220,35 +303,53 @@ namespace Mono.ILASM { public void Resolve (CodeGen code_gen) { - // Assembly table is never null because we add mscorlib - foreach (ExternAssembly ext in assembly_table.Values) - ext.Resolve (code_gen); + if (is_resolved) + return; + + if (assembly_table != null) + foreach (ExternAssembly ext in assembly_table.Values) + ext.Resolve (code_gen); if (module_table == null) return; foreach (ExternModule ext in module_table.Values) ext.Resolve (code_gen); + + is_resolved = true; } public ExternTypeRef GetTypeRef (string asmb_name, string full_name, bool is_valuetype) { - ExternAssembly ext_asmb; - ext_asmb = assembly_table[asmb_name] as ExternAssembly; + ExternAssembly ext_asmb = null; + if (assembly_table == null && (asmb_name == "mscorlib" || asmb_name == "corlib")) { + /* AddCorlib if mscorlib is being referenced but + we haven't encountered a ".assembly 'name'" as yet. */ + Report.Warning (String.Format ("Reference to undeclared extern assembly '{0}', adding.", asmb_name)); + AddCorlib (); + } + if (assembly_table != null) + ext_asmb = assembly_table[asmb_name] as ExternAssembly; + + if (ext_asmb == null) { + System.Reflection.AssemblyName asmname = new System.Reflection.AssemblyName (); + asmname.Name = asmb_name; - if (ext_asmb == null) - throw new Exception (String.Format ("Assembly {0} not defined.", asmb_name)); + Report.Warning (String.Format ("Reference to undeclared extern assembly '{0}', adding.", asmb_name)); + ext_asmb = AddAssembly (asmb_name, asmname); + } - return ext_asmb.GetTypeRef (full_name, is_valuetype, this); + return ext_asmb.GetTypeRef (full_name, is_valuetype); } public ExternTypeRef GetModuleTypeRef (string mod_name, string full_name, bool is_valuetype) { - ExternModule mod; - mod = module_table [mod_name] as ExternModule; + ExternModule mod = null; + if (module_table != null) + mod = module_table [mod_name] as ExternModule; if (mod == null) - throw new Exception (String.Format ("Module {0} not defined.", mod_name)); + Report.Error ("Module " + mod_name + " not defined."); - return mod.GetTypeRef (full_name, is_valuetype, this); + return mod.GetTypeRef (full_name, is_valuetype); } public static void GetNameAndNamespace (string full_name,