2
// reflection.cs: System.Reflection and System.Reflection.Emit specific implementations
4
// Author: Marek Safar (marek.safar@gmail.com)
6
// Dual licensed under the terms of the MIT X11 or GNU GPL
8
// Copyright 2009-2010 Novell, Inc.
13
using System.Collections.Generic;
14
using System.Reflection;
16
using System.Runtime.CompilerServices;
17
using System.Reflection.Emit;
18
using System.Security;
23
public class ReflectionImporter
25
public ReflectionImporter (ModuleContainer module, BuiltinTypes builtin)
27
throw new NotSupportedException ();
30
public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace)
32
throw new NotSupportedException ();
35
public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace)
37
throw new NotSupportedException ();
40
public TypeSpec ImportType (Type type)
42
throw new NotSupportedException ();
46
public sealed class ReflectionImporter : MetadataImporter
48
public ReflectionImporter (ModuleContainer module, BuiltinTypes builtin)
54
public override void AddCompiledType (TypeBuilder builder, TypeSpec spec)
58
protected override MemberKind DetermineKindFromBaseType (Type baseType)
60
if (baseType == typeof (ValueType))
61
return MemberKind.Struct;
63
if (baseType == typeof (System.Enum))
64
return MemberKind.Enum;
66
if (baseType == typeof (MulticastDelegate))
67
return MemberKind.Delegate;
69
return MemberKind.Class;
72
protected override bool HasVolatileModifier (Type[] modifiers)
74
foreach (var t in modifiers) {
75
if (t == typeof (IsVolatile))
82
public void ImportAssembly (Assembly assembly, RootNamespace targetNamespace)
84
// It can be used more than once when importing same assembly
85
// into 2 or more global aliases
86
var definition = GetAssemblyDefinition (assembly);
89
// This part tries to simulate loading of top-level
90
// types only, any missing dependencies are ignores here.
91
// Full error report is reported later when the type is
96
all_types = assembly.GetTypes ();
97
} catch (ReflectionTypeLoadException e) {
101
ImportTypes (all_types, targetNamespace, definition.HasExtensionMethod);
104
public ImportedModuleDefinition ImportModule (Module module, RootNamespace targetNamespace)
106
var module_definition = new ImportedModuleDefinition (module);
107
module_definition.ReadAttributes ();
111
all_types = module.GetTypes ();
112
} catch (ReflectionTypeLoadException e) {
116
ImportTypes (all_types, targetNamespace, false);
118
return module_definition;
121
void Initialize (BuiltinTypes builtin)
124
// Setup mapping for build-in types to avoid duplication of their definition
126
compiled_types.Add (typeof (object), builtin.Object);
127
compiled_types.Add (typeof (System.ValueType), builtin.ValueType);
128
compiled_types.Add (typeof (System.Attribute), builtin.Attribute);
130
compiled_types.Add (typeof (int), builtin.Int);
131
compiled_types.Add (typeof (long), builtin.Long);
132
compiled_types.Add (typeof (uint), builtin.UInt);
133
compiled_types.Add (typeof (ulong), builtin.ULong);
134
compiled_types.Add (typeof (byte), builtin.Byte);
135
compiled_types.Add (typeof (sbyte), builtin.SByte);
136
compiled_types.Add (typeof (short), builtin.Short);
137
compiled_types.Add (typeof (ushort), builtin.UShort);
139
compiled_types.Add (typeof (System.Collections.IEnumerator), builtin.IEnumerator);
140
compiled_types.Add (typeof (System.Collections.IEnumerable), builtin.IEnumerable);
141
compiled_types.Add (typeof (System.IDisposable), builtin.IDisposable);
143
compiled_types.Add (typeof (char), builtin.Char);
144
compiled_types.Add (typeof (string), builtin.String);
145
compiled_types.Add (typeof (float), builtin.Float);
146
compiled_types.Add (typeof (double), builtin.Double);
147
compiled_types.Add (typeof (decimal), builtin.Decimal);
148
compiled_types.Add (typeof (bool), builtin.Bool);
149
compiled_types.Add (typeof (System.IntPtr), builtin.IntPtr);
150
compiled_types.Add (typeof (System.UIntPtr), builtin.UIntPtr);
152
compiled_types.Add (typeof (System.MulticastDelegate), builtin.MulticastDelegate);
153
compiled_types.Add (typeof (System.Delegate), builtin.Delegate);
154
compiled_types.Add (typeof (System.Enum), builtin.Enum);
155
compiled_types.Add (typeof (System.Array), builtin.Array);
156
compiled_types.Add (typeof (void), builtin.Void);
157
compiled_types.Add (typeof (System.Type), builtin.Type);
158
compiled_types.Add (typeof (System.Exception), builtin.Exception);
159
compiled_types.Add (typeof (System.RuntimeFieldHandle), builtin.RuntimeFieldHandle);
160
compiled_types.Add (typeof (System.RuntimeTypeHandle), builtin.RuntimeTypeHandle);
164
[System.Runtime.InteropServices.StructLayout (System.Runtime.InteropServices.LayoutKind.Explicit)]
165
struct SingleConverter
167
[System.Runtime.InteropServices.FieldOffset (0)]
170
#pragma warning disable 414
171
[System.Runtime.InteropServices.FieldOffset (0)]
173
#pragma warning restore 414
175
public static int SingleToInt32Bits (float v)
177
SingleConverter c = new SingleConverter ();
185
public class AssemblyDefinitionDynamic : AssemblyDefinition
188
// In-memory only assembly container
190
public AssemblyDefinitionDynamic (ModuleContainer module, string name)
191
: base (module, name)
196
// Assembly container with file output
198
public AssemblyDefinitionDynamic (ModuleContainer module, string name, string fileName)
199
: base (module, name, fileName)
203
public Module IncludeModule (string moduleFile)
205
return builder_extra.AddModule (moduleFile);
209
public override ModuleBuilder CreateModuleBuilder ()
211
if (file_name == null)
212
return Builder.DefineDynamicModule (Name, false);
214
return base.CreateModuleBuilder ();
218
// Initializes the code generator
220
public bool Create (AppDomain domain, AssemblyBuilderAccess access)
223
throw new NotSupportedException ();
225
ResolveAssemblySecurityAttributes ();
226
var an = CreateAssemblyName ();
228
Builder = file_name == null ?
229
domain.DefineDynamicAssembly (an, access) :
230
domain.DefineDynamicAssembly (an, access, Dirname (file_name));
232
module.Create (this, CreateModuleBuilder ());
233
builder_extra = new AssemblyBuilderMonoSpecific (Builder, Compiler);
238
static string Dirname (string name)
240
int pos = name.LastIndexOf ('/');
243
return name.Substring (0, pos);
245
pos = name.LastIndexOf ('\\');
247
return name.Substring (0, pos);
253
protected override void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine)
256
var module_only = typeof (AssemblyBuilder).GetProperty ("IsModuleOnly", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
257
var set_module_only = module_only.GetSetMethod (true);
259
set_module_only.Invoke (Builder, new object[] { true });
261
base.SaveModule (pekind, machine);
264
Builder.Save (file_name, pekind, machine);
270
// Extension to System.Reflection.Emit.AssemblyBuilder to have fully compatible
273
class AssemblyBuilderMonoSpecific : AssemblyBuilderExtension
275
static MethodInfo adder_method;
276
static MethodInfo add_permission;
277
static MethodInfo add_type_forwarder;
278
static MethodInfo win32_icon_define;
279
static FieldInfo assembly_version;
280
static FieldInfo assembly_algorithm;
281
static FieldInfo assembly_culture;
282
static FieldInfo assembly_flags;
284
AssemblyBuilder builder;
286
public AssemblyBuilderMonoSpecific (AssemblyBuilder ab, CompilerContext ctx)
292
public override Module AddModule (string module)
295
if (adder_method == null)
296
adder_method = typeof (AssemblyBuilder).GetMethod ("AddModule", BindingFlags.Instance | BindingFlags.NonPublic);
298
return (Module) adder_method.Invoke (builder, new object[] { module });
300
return base.AddModule (module);
304
public override void AddPermissionRequests (PermissionSet[] permissions)
307
if (add_permission == null)
308
add_permission = typeof (AssemblyBuilder).GetMethod ("AddPermissionRequests", BindingFlags.Instance | BindingFlags.NonPublic);
310
add_permission.Invoke (builder, permissions);
312
base.AddPermissionRequests (permissions);
316
public override void AddTypeForwarder (TypeSpec type, Location loc)
319
if (add_type_forwarder == null) {
320
add_type_forwarder = typeof (AssemblyBuilder).GetMethod ("AddTypeForwarder", BindingFlags.NonPublic | BindingFlags.Instance);
323
add_type_forwarder.Invoke (builder, new object[] { type.GetMetaInfo () });
325
base.AddTypeForwarder (type, loc);
329
public override void DefineWin32IconResource (string fileName)
332
if (win32_icon_define == null)
333
win32_icon_define = typeof (AssemblyBuilder).GetMethod ("DefineIconResource", BindingFlags.Instance | BindingFlags.NonPublic);
335
win32_icon_define.Invoke (builder, new object[] { fileName });
337
base.DefineWin32IconResource (fileName);
341
public override void SetAlgorithmId (uint value, Location loc)
344
if (assembly_algorithm == null)
345
assembly_algorithm = typeof (AssemblyBuilder).GetField ("algid", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField);
347
assembly_algorithm.SetValue (builder, value);
349
base.SetAlgorithmId (value, loc);
353
public override void SetCulture (string culture, Location loc)
356
if (assembly_culture == null)
357
assembly_culture = typeof (AssemblyBuilder).GetField ("culture", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField);
359
assembly_culture.SetValue (builder, culture);
361
base.SetCulture (culture, loc);
365
public override void SetFlags (uint flags, Location loc)
368
if (assembly_flags == null)
369
assembly_flags = typeof (AssemblyBuilder).GetField ("flags", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField);
371
assembly_flags.SetValue (builder, flags);
373
base.SetFlags (flags, loc);
377
public override void SetVersion (Version version, Location loc)
380
if (assembly_version == null)
381
assembly_version = typeof (AssemblyBuilder).GetField ("version", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.SetField);
383
assembly_version.SetValue (builder, version.ToString (4));
385
base.SetVersion (version, loc);
391
// Reflection based references loader
393
class DynamicLoader : AssemblyReferencesLoader<Assembly>
395
readonly ReflectionImporter importer;
397
public DynamicLoader (ReflectionImporter importer, CompilerContext compiler)
400
paths.Add (GetSystemDir ());
402
this.importer = importer;
405
public ReflectionImporter Importer {
411
protected override string[] GetDefaultReferences ()
414
// For now the "default config" is harcoded into the compiler
415
// we can move this outside later
417
var default_references = new List<string> (8);
419
default_references.Add ("System");
420
default_references.Add ("System.Xml");
422
default_references.Add ("System.Net");
423
default_references.Add ("System.Windows");
424
default_references.Add ("System.Windows.Browser");
427
if (compiler.Settings.Version > LanguageVersion.ISO_2)
428
default_references.Add ("System.Core");
429
if (compiler.Settings.Version > LanguageVersion.V_3)
430
default_references.Add ("Microsoft.CSharp");
432
return default_references.ToArray ();
436
// Returns the directory where the system assemblies are installed
438
static string GetSystemDir ()
440
return Path.GetDirectoryName (typeof (object).Assembly.Location);
443
public override bool HasObjectType (Assembly assembly)
445
return assembly.GetType (compiler.BuiltinTypes.Object.FullName) != null;
448
public override Assembly LoadAssemblyFile (string assembly, bool isImplicitReference)
454
char[] path_chars = { '/', '\\' };
456
if (assembly.IndexOfAny (path_chars) != -1) {
457
a = Assembly.LoadFrom (assembly);
459
string ass = assembly;
460
if (ass.EndsWith (".dll") || ass.EndsWith (".exe"))
461
ass = assembly.Substring (0, assembly.Length - 4);
462
a = Assembly.Load (ass);
464
} catch (FileNotFoundException) {
465
bool err = !isImplicitReference;
466
foreach (string dir in paths) {
467
string full_path = Path.Combine (dir, assembly);
468
if (!assembly.EndsWith (".dll") && !assembly.EndsWith (".exe"))
472
a = Assembly.LoadFrom (full_path);
475
} catch (FileNotFoundException) {
480
Error_FileNotFound (assembly);
484
} catch (BadImageFormatException) {
485
Error_FileCorrupted (assembly);
491
Module LoadModuleFile (AssemblyDefinitionDynamic assembly, string module)
493
string total_log = "";
497
return assembly.IncludeModule (module);
498
} catch (FileNotFoundException) {
500
foreach (string dir in paths) {
501
string full_path = Path.Combine (dir, module);
502
if (!module.EndsWith (".netmodule"))
503
full_path += ".netmodule";
506
return assembly.IncludeModule (full_path);
507
} catch (FileNotFoundException ff) {
508
total_log += ff.FusionLog;
512
Error_FileNotFound (module);
516
} catch (BadImageFormatException) {
517
Error_FileCorrupted (module);
523
public void LoadModules (AssemblyDefinitionDynamic assembly, RootNamespace targetNamespace)
525
foreach (var moduleName in compiler.Settings.Modules) {
526
var m = LoadModuleFile (assembly, moduleName);
530
var md = importer.ImportModule (m, targetNamespace);
531
assembly.AddModule (md);
535
public override void LoadReferences (ModuleContainer module)
538
List<Tuple<RootNamespace, Assembly>> loaded;
539
base.LoadReferencesCore (module, out corlib, out loaded);
544
importer.ImportAssembly (corlib, module.GlobalRootNamespace);
545
foreach (var entry in loaded) {
546
importer.ImportAssembly (entry.Item2, entry.Item1);
b'\\ No newline at end of file'