X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Freflection.cs;h=6f2f183a83b97ef251bdabdaba13838bff6956da;hb=419fee3d9bf5b2e7b51d1f6dff9c3d696719e444;hp=de056143935d5ae287ce27baf74ece12690ec713;hpb=e5d8bddb52783265fda7c2efd48d854e78654097;p=mono.git diff --git a/mcs/mcs/reflection.cs b/mcs/mcs/reflection.cs index de056143935..6f2f183a83b 100644 --- a/mcs/mcs/reflection.cs +++ b/mcs/mcs/reflection.cs @@ -19,12 +19,40 @@ using System.Security; namespace Mono.CSharp { - public class ReflectionImporter : MetadataImporter +#if STATIC + public class ReflectionImporter { - public ReflectionImporter (BuildinTypes buildin) - : base () + public ReflectionImporter (ModuleContainer module, BuiltinTypes builtin) + { + throw new NotSupportedException (); + } + + public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace) + { + throw new NotSupportedException (); + } + + public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace) + { + throw new NotSupportedException (); + } + + public TypeSpec ImportType (Type type) + { + throw new NotSupportedException (); + } + } +#else + public sealed class ReflectionImporter : MetadataImporter + { + public ReflectionImporter (ModuleContainer module, BuiltinTypes builtin) + : base (module) + { + Initialize (builtin); + } + + public override void AddCompiledType (TypeBuilder builder, TypeSpec spec) { - Initialize (buildin); } protected override MemberKind DetermineKindFromBaseType (Type baseType) @@ -41,60 +69,198 @@ namespace Mono.CSharp return MemberKind.Class; } - protected override bool HasVolatileModifier (FieldInfo field) + protected override bool HasVolatileModifier (Type[] modifiers) { - var reqs = field.GetRequiredCustomModifiers (); - if (reqs.Length > 0) { - foreach (var t in reqs) { - if (t == typeof (IsVolatile)) - return true; - } + foreach (var t in modifiers) { + if (t == typeof (IsVolatile)) + return true; } return false; } - void Initialize (BuildinTypes buildin) + public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace) + { + // It can be used more than once when importing same assembly + // into 2 or more global aliases + var definition = GetAssemblyDefinition (assembly); + + // + // This part tries to simulate loading of top-level + // types only, any missing dependencies are ignores here. + // Full error report is reported later when the type is + // actually used + // + Type[] all_types; + try { + all_types = assembly.GetTypes (); + } catch (ReflectionTypeLoadException e) { + all_types = e.Types; + } + + ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod); + } + + public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace) + { + var module_definition = new ImportedModuleDefinition (module); + module_definition.ReadAttributes (); + + Type[] all_types; + try { + all_types = module.GetTypes (); + } catch (ReflectionTypeLoadException e) { + all_types = e.Types; + } + + ImportTypes (all_types, targetNamespace, false); + + return module_definition; + } + + void Initialize (BuiltinTypes builtin) { // // Setup mapping for build-in types to avoid duplication of their definition // - buildin_types.Add (typeof (object), buildin.Object); - buildin_types.Add (typeof (System.ValueType), buildin.ValueType); - buildin_types.Add (typeof (System.Attribute), buildin.Attribute); - - buildin_types.Add (typeof (int), buildin.Int); - buildin_types.Add (typeof (long), buildin.Long); - buildin_types.Add (typeof (uint), buildin.UInt); - buildin_types.Add (typeof (ulong), buildin.ULong); - buildin_types.Add (typeof (byte), buildin.Byte); - buildin_types.Add (typeof (sbyte), buildin.SByte); - buildin_types.Add (typeof (short), buildin.Short); - buildin_types.Add (typeof (ushort), buildin.UShort); - - buildin_types.Add (typeof (System.Collections.IEnumerator), buildin.IEnumerator); - buildin_types.Add (typeof (System.Collections.IEnumerable), buildin.IEnumerable); - buildin_types.Add (typeof (System.IDisposable), buildin.IDisposable); - - buildin_types.Add (typeof (char), buildin.Char); - buildin_types.Add (typeof (string), buildin.String); - buildin_types.Add (typeof (float), buildin.Float); - buildin_types.Add (typeof (double), buildin.Double); - buildin_types.Add (typeof (decimal), buildin.Decimal); - buildin_types.Add (typeof (bool), buildin.Bool); - buildin_types.Add (typeof (System.IntPtr), buildin.IntPtr); - buildin_types.Add (typeof (System.UIntPtr), buildin.UIntPtr); - - buildin_types.Add (typeof (System.MulticastDelegate), buildin.MulticastDelegate); - buildin_types.Add (typeof (System.Delegate), buildin.Delegate); - buildin_types.Add (typeof (System.Enum), buildin.Enum); - buildin_types.Add (typeof (System.Array), buildin.Array); - buildin_types.Add (typeof (void), buildin.Void); - buildin_types.Add (typeof (System.Type), buildin.Type); - buildin_types.Add (typeof (System.Exception), buildin.Exception); - buildin_types.Add (typeof (System.RuntimeFieldHandle), buildin.RuntimeFieldHandle); - buildin_types.Add (typeof (System.RuntimeTypeHandle), buildin.RuntimeTypeHandle); + compiled_types.Add (typeof (object), builtin.Object); + compiled_types.Add (typeof (System.ValueType), builtin.ValueType); + compiled_types.Add (typeof (System.Attribute), builtin.Attribute); + + compiled_types.Add (typeof (int), builtin.Int); + compiled_types.Add (typeof (long), builtin.Long); + compiled_types.Add (typeof (uint), builtin.UInt); + compiled_types.Add (typeof (ulong), builtin.ULong); + compiled_types.Add (typeof (byte), builtin.Byte); + compiled_types.Add (typeof (sbyte), builtin.SByte); + compiled_types.Add (typeof (short), builtin.Short); + compiled_types.Add (typeof (ushort), builtin.UShort); + + compiled_types.Add (typeof (System.Collections.IEnumerator), builtin.IEnumerator); + compiled_types.Add (typeof (System.Collections.IEnumerable), builtin.IEnumerable); + compiled_types.Add (typeof (System.IDisposable), builtin.IDisposable); + + compiled_types.Add (typeof (char), builtin.Char); + compiled_types.Add (typeof (string), builtin.String); + compiled_types.Add (typeof (float), builtin.Float); + compiled_types.Add (typeof (double), builtin.Double); + compiled_types.Add (typeof (decimal), builtin.Decimal); + compiled_types.Add (typeof (bool), builtin.Bool); + compiled_types.Add (typeof (System.IntPtr), builtin.IntPtr); + compiled_types.Add (typeof (System.UIntPtr), builtin.UIntPtr); + + compiled_types.Add (typeof (System.MulticastDelegate), builtin.MulticastDelegate); + compiled_types.Add (typeof (System.Delegate), builtin.Delegate); + compiled_types.Add (typeof (System.Enum), builtin.Enum); + compiled_types.Add (typeof (System.Array), builtin.Array); + compiled_types.Add (typeof (void), builtin.Void); + compiled_types.Add (typeof (System.Type), builtin.Type); + compiled_types.Add (typeof (System.Exception), builtin.Exception); + compiled_types.Add (typeof (System.RuntimeFieldHandle), builtin.RuntimeFieldHandle); + compiled_types.Add (typeof (System.RuntimeTypeHandle), builtin.RuntimeTypeHandle); + } + } + + [System.Runtime.InteropServices.StructLayout (System.Runtime.InteropServices.LayoutKind.Explicit)] + struct SingleConverter + { + [System.Runtime.InteropServices.FieldOffset (0)] + int i; + [System.Runtime.InteropServices.FieldOffset (0)] + float f; + + public static int SingleToInt32Bits (float v) + { + SingleConverter c = new SingleConverter (); + c.f = v; + return c.i; + } + } + +#endif + + public class AssemblyDefinitionDynamic : AssemblyDefinition + { + // + // In-memory only assembly container + // + public AssemblyDefinitionDynamic (ModuleContainer module, string name) + : base (module, name) + { + } + + // + // Assembly container with file output + // + public AssemblyDefinitionDynamic (ModuleContainer module, string name, string fileName) + : base (module, name, fileName) + { } + + public Module IncludeModule (string moduleFile) + { + return builder_extra.AddModule (moduleFile); + } + +#if !STATIC + public override ModuleBuilder CreateModuleBuilder () + { + if (file_name == null) + return Builder.DefineDynamicModule (Name, false); + + return base.CreateModuleBuilder (); + } +#endif + // + // Initializes the code generator + // + public bool Create (AppDomain domain, AssemblyBuilderAccess access) + { +#if STATIC + throw new NotSupportedException (); +#else + ResolveAssemblySecurityAttributes (); + var an = CreateAssemblyName (); + + Builder = file_name == null ? + domain.DefineDynamicAssembly (an, access) : + domain.DefineDynamicAssembly (an, access, Dirname (file_name)); + + module.Create (this, CreateModuleBuilder ()); + builder_extra = new AssemblyBuilderMonoSpecific (Builder, Compiler); + return true; +#endif + } + + static string Dirname (string name) + { + int pos = name.LastIndexOf ('/'); + + if (pos != -1) + return name.Substring (0, pos); + + pos = name.LastIndexOf ('\\'); + if (pos != -1) + return name.Substring (0, pos); + + return "."; + } + +#if !STATIC + protected override void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine) + { + try { + var module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + var set_module_only = module_only.GetSetMethod (true); + + set_module_only.Invoke (Builder, new object[] { true }); + } catch { + base.SaveModule (pekind, machine); + } + + Builder.Save (file_name, pekind, machine); + } +#endif } // @@ -105,7 +271,6 @@ namespace Mono.CSharp { static MethodInfo adder_method; static MethodInfo add_permission; - static MethodInfo set_module_only; static MethodInfo add_type_forwarder; static MethodInfo win32_icon_define; static FieldInfo assembly_version; @@ -206,54 +371,32 @@ namespace Mono.CSharp } } - public override void SetVersion (string version, Location loc) + public override void SetVersion (Version version, Location loc) { try { if (assembly_version == null) assembly_version = typeof (AssemblyBuilder).GetField ("version", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField); - assembly_version.SetValue (builder, version); + assembly_version.SetValue (builder, version.ToString (4)); } catch { base.SetVersion (version, loc); } } - - public override void SetModuleTarget () - { - try { - if (set_module_only == null) { - var module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - set_module_only = module_only.GetSetMethod (true); - } - - set_module_only.Invoke (builder, new object[] { true }); - } catch { - base.SetModuleTarget (); - } - } } - public class DynamicLoader + // + // Reflection based references loader + // + class DynamicLoader : AssemblyReferencesLoader { readonly ReflectionImporter importer; - readonly Report reporter; - - // A list of default references, they can fail to load as the user didn't not specify them - string[] default_references; - - List paths; public DynamicLoader (ReflectionImporter importer, CompilerContext compiler) + : base (compiler) { - this.importer = importer; - this.reporter = compiler.Report; - - default_references = GetDefaultReferences (); - - paths = new List (); - paths.AddRange (RootContext.ReferencesLookupPaths); paths.Add (GetSystemDir ()); - paths.Add (Directory.GetCurrentDirectory ()); + + this.importer = importer; } public ReflectionImporter Importer { @@ -262,67 +405,8 @@ namespace Mono.CSharp } } - void Error6 (string name, string log) - { - if (log != null && log.Length > 0) - reporter.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous "); - reporter.Error (6, "cannot find metadata file `{0}'", name); - } - - void Error9 (string type, string filename, string log) + protected override string[] GetDefaultReferences () { - if (log != null && log.Length > 0) - reporter.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous "); - reporter.Error (9, "file `{0}' has invalid `{1}' metadata", filename, type); - } - - void BadAssembly (string filename, string log) - { -/* - MethodInfo adder_method = null; // AssemblyDefinition.AddModule_Method; - - if (adder_method != null) { - AssemblyName an = new AssemblyName (); - an.Name = ".temp"; - var ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run); - try { - object m = null; - try { - m = adder_method.Invoke (ab, new object [] { filename }); - } catch (TargetInvocationException ex) { - throw ex.InnerException; - } - - if (m != null) { - Report.Error (1509, "Referenced file `{0}' is not an assembly. Consider using `-addmodule' option instead", - Path.GetFileName (filename)); - return; - } - } catch (FileNotFoundException) { - // did the file get deleted during compilation? who cares? swallow the exception - } catch (BadImageFormatException) { - // swallow exception - } catch (FileLoadException) { - // swallow exception - } - } -*/ - Error9 ("assembly", filename, log); - } - - // - // Returns the directory where the system assemblies are installed - // - static string GetSystemDir () - { - return Path.GetDirectoryName (typeof (object).Assembly.Location); - } - - string[] GetDefaultReferences () - { - if (!RootContext.LoadDefaultReferences) - return new string [0]; - // // For now the "default config" is harcoded into the compiler // we can move this outside later @@ -337,18 +421,35 @@ namespace Mono.CSharp default_references.Add ("System.Windows.Browser"); #endif - if (RootContext.Version > LanguageVersion.ISO_2) + if (compiler.Settings.Version > LanguageVersion.ISO_2) default_references.Add ("System.Core"); - if (RootContext.Version > LanguageVersion.V_3) + if (compiler.Settings.Version > LanguageVersion.V_3) default_references.Add ("Microsoft.CSharp"); return default_references.ToArray (); } - public Assembly LoadAssemblyFile (string assembly, bool soft) + // + // Returns the directory where the system assemblies are installed + // + static string GetSystemDir () + { + return Path.GetDirectoryName (typeof (object).Assembly.Location); + } + + public override bool HasObjectType (Assembly assembly) + { + return assembly.GetType (compiler.BuiltinTypes.Object.FullName) != null; + } + + public override Assembly LoadAssemblyFile (string fileName) + { + return LoadAssemblyFile (fileName, false); + } + + Assembly LoadAssemblyFile (string assembly, bool soft) { Assembly a = null; - string total_log = ""; try { try { @@ -373,35 +474,34 @@ namespace Mono.CSharp a = Assembly.LoadFrom (full_path); err = false; break; - } catch (FileNotFoundException ff) { - if (soft) - return a; - total_log += ff.FusionLog; + } catch (FileNotFoundException) { } } + if (err) { - Error6 (assembly, total_log); + Error_FileNotFound (assembly); return a; } } - } catch (BadImageFormatException f) { - // .NET 2.0 throws this if we try to load a module without an assembly manifest ... - BadAssembly (f.FileName, f.FusionLog); - } catch (FileLoadException f) { - // ... while .NET 1.1 throws this - BadAssembly (f.FileName, f.FusionLog); + } catch (BadImageFormatException) { + Error_FileCorrupted (assembly); } return a; } - void LoadModule (AssemblyDefinition assembly, string module) + public override Assembly LoadAssemblyDefault (string fileName) + { + return LoadAssemblyFile (fileName, true); + } + + Module LoadModuleFile (AssemblyDefinitionDynamic assembly, string module) { string total_log = ""; try { try { - assembly.AddModule (module); + return assembly.IncludeModule (module); } catch (FileNotFoundException) { bool err = true; foreach (string dir in paths) { @@ -410,84 +510,47 @@ namespace Mono.CSharp full_path += ".netmodule"; try { - assembly.AddModule (full_path); - err = false; - break; + return assembly.IncludeModule (full_path); } catch (FileNotFoundException ff) { total_log += ff.FusionLog; } } if (err) { - Error6 (module, total_log); - return; + Error_FileNotFound (module); + return null; } } - } catch (BadImageFormatException f) { - Error9 ("module", f.FileName, f.FusionLog); - } catch (FileLoadException f) { - Error9 ("module", f.FileName, f.FusionLog); + } catch (BadImageFormatException) { + Error_FileCorrupted (module); } + + return null; } - /// - /// Loads all assemblies referenced on the command line - /// - public void LoadReferences (ModuleContainer module) + public void LoadModules (AssemblyDefinitionDynamic assembly, RootNamespace targetNamespace) { - Assembly a; - var loaded = new List> (); - - // - // Load Core Library for default compilation - // - if (RootContext.StdLib) { - a = LoadAssemblyFile ("mscorlib", false); - if (a != null) - loaded.Add (Tuple.Create (module.GlobalRootNamespace, a)); - } - - foreach (string r in default_references) { - a = LoadAssemblyFile (r, true); - if (a != null) - loaded.Add (Tuple.Create (module.GlobalRootNamespace, a)); - } - - foreach (string r in RootContext.AssemblyReferences) { - a = LoadAssemblyFile (r, false); - if (a == null) + foreach (var moduleName in compiler.Settings.Modules) { + var m = LoadModuleFile (assembly, moduleName); + if (m == null) continue; - var key = Tuple.Create (module.GlobalRootNamespace, a); - if (loaded.Contains (key)) - continue; - - loaded.Add (key); - } - - foreach (var entry in RootContext.AssemblyReferencesAliases) { - a = LoadAssemblyFile (entry.Item2, false); - if (a == null) - continue; - - var key = Tuple.Create (module.CreateRootNamespace (entry.Item1), a); - if (loaded.Contains (key)) - continue; - - loaded.Add (key); - } - - foreach (var entry in loaded) { - importer.ImportAssembly (entry.Item2, entry.Item1); + var md = importer.ImportModule (m, targetNamespace); + assembly.AddModule (md); } } - public void LoadModules (AssemblyDefinition assembly) + public override void LoadReferences (ModuleContainer module) { - if (RootContext.Modules.Count == 0) + Assembly corlib; + List> loaded; + base.LoadReferencesCore (module, out corlib, out loaded); + + if (corlib == null) return; - foreach (var module in RootContext.Modules) { - LoadModule (assembly, module); + importer.ImportAssembly (corlib, module.GlobalRootNamespace); + foreach (var entry in loaded) { + importer.ImportAssembly (entry.Item2, entry.Item1); } } }