public DefineGlobalMethod ( string name, System attributes, System returnType, System parameterTypes ) : System.Reflection.Emit.MethodBuilder | ||
name | string | |
attributes | System | |
returnType | System | |
parameterTypes | System | |
return | System.Reflection.Emit.MethodBuilder |
/// <summary> /// Compiles the signature for the procedure but not the body. /// This needs to be done first so that other methods can /// call this method, this way we don't have problems with; /// dependencies between methods. /// </summary> public MethodBuilder CompileSignature(ModuleBuilder module) { Type[] argTypes = new Type[ArgumentCount]; for (int i = 0; i < argTypes.Length; i++) { argTypes[i] = typeof(int); } if (HasResultArgument) { argTypes[argTypes.Length - 1] = typeof(int).MakeByRefType(); } MethodBuilder method = module.DefineGlobalMethod(_name, MethodAttributes.HideBySig | MethodAttributes.Static | MethodAttributes.Public, typeof(void), argTypes); int pos = 1; foreach (Variable arg in ValueArguments) { SymbolTable.DefineArgument(arg.Name); method.DefineParameter(pos, ParameterAttributes.In, arg.Name); pos++; } if (HasResultArgument) { SymbolTable.DefineArgument(ResultArgument.Name); method.DefineParameter(pos, ParameterAttributes.Out, ResultArgument.Name); } SymbolTable.Clear(); return method; }
private void GenerateAssemblyLookup(ModuleBuilder module) { if (_embeddedAssemblies.Count == 0) { return; } foreach (Assembly ass in _embeddedAssemblies) { string shortname = ass.FullName.Substring(0, ass.FullName.IndexOf(",")); string tempfile = Path.GetTempFileName(); File.Copy(new Uri(ass.EscapedCodeBase).LocalPath, tempfile, true); MemoryStream ms = new MemoryStream(File.ReadAllBytes(tempfile)); ms.Seek(0, SeekOrigin.Begin); module.DefineManifestResource(shortname, ms, ResourceAttributes.Public); File.Delete(tempfile); } MethodBuilder resolveAssemblyMethod = module.DefineGlobalMethod("ResolveAssembly", MethodAttributes.Public | MethodAttributes.Static, typeof(Assembly), new Type[] { typeof(object), typeof(System.ResolveEventArgs) }); ILGenerator ilResolve = resolveAssemblyMethod.GetILGenerator(); CompileContext resolvecontext = new CompileContext(); resolvecontext.PushIL(ilResolve); LocalBuilder localStream = ilResolve.DeclareLocal(typeof(Stream)); LocalBuilder localBuf = ilResolve.DeclareLocal(typeof(byte[])); LocalBuilder localName = ilResolve.DeclareLocal(typeof(string)); ilResolve.Emit(OpCodes.Ldarg_1); ilResolve.Emit(OpCodes.Call, typeof(ResolveEventArgs).GetMethod("get_Name")); ilResolve.Emit(OpCodes.Stloc, localName); ilResolve.Emit(OpCodes.Ldloc, localName); ilResolve.Emit(OpCodes.Ldc_I4_0); ilResolve.Emit(OpCodes.Ldloc, localName); ilResolve.Emit(OpCodes.Ldstr, ","); ilResolve.Emit(OpCodes.Call, typeof(string).GetMethod("IndexOf", new Type[] { typeof(string) })); ilResolve.Emit(OpCodes.Call, typeof(string).GetMethod("Substring", new Type[] { typeof(int), typeof(int) })); ilResolve.Emit(OpCodes.Stloc, localName); Assign(localStream, Call(Call(typeof(Assembly), "GetExecutingAssembly", false), "GetManifestResourceStream", false, localName), resolvecontext); Label notNull = ilResolve.DefineLabel(); ilResolve.Emit(OpCodes.Ldloc, localStream); ilResolve.Emit(OpCodes.Brtrue, notNull); { //Not found, just return null ilResolve.Emit(OpCodes.Ldnull); ilResolve.Emit(OpCodes.Ret); } ilResolve.MarkLabel(notNull); Call(localStream, "get_Length", false).Compile(resolvecontext); ilResolve.Emit(OpCodes.Conv_Ovf_I); ilResolve.Emit(OpCodes.Newarr, typeof(System.Byte)); ilResolve.Emit(OpCodes.Stloc, localBuf); ilResolve.Emit(OpCodes.Ldloc, localStream); ilResolve.Emit(OpCodes.Ldloc, localBuf); ilResolve.Emit(OpCodes.Ldc_I4_0); ilResolve.Emit(OpCodes.Ldloc, localBuf); ilResolve.Emit(OpCodes.Ldlen); ilResolve.Emit(OpCodes.Conv_I4); ilResolve.Emit(OpCodes.Callvirt, typeof(Stream).GetMethod("Read", new Type[] { typeof(byte[]), typeof(int), typeof(int) })); ilResolve.Emit(OpCodes.Pop); //Notify that we loaded this embedded... ilResolve.Emit(OpCodes.Ldarg_1); ilResolve.Emit(OpCodes.Call, typeof(ResolveEventArgs).GetMethod("get_Name")); ilResolve.Emit(OpCodes.Ldstr, " was not found externally, loading embedded version..."); ilResolve.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) })); ilResolve.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) })); Call(typeof(Assembly), "Load", false, localBuf).Compile(resolvecontext); ilResolve.Emit(OpCodes.Ret); resolvecontext.PopIL(); MethodBuilder moduleInitializer = module.DefineGlobalMethod(".cctor", MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.RTSpecialName, null, new Type[] { }); ILGenerator ilStartup = moduleInitializer.GetILGenerator(); ilStartup.Emit(OpCodes.Call, typeof(System.AppDomain).GetMethod("get_CurrentDomain")); ilStartup.Emit(OpCodes.Ldnull); ilStartup.Emit(OpCodes.Ldftn, resolveAssemblyMethod); ilStartup.Emit(OpCodes.Newobj, MethodResolver.GetConstructor(typeof(System.ResolveEventHandler))); ilStartup.Emit(OpCodes.Callvirt, MethodResolver.GetMethod(typeof(System.AppDomain), "add_AssemblyResolve")); ilStartup.Emit(OpCodes.Ret); }
void Save(string assemblyFileName, PortableExecutableKinds portableExecutableKind, ImageFileMachine imageFileMachine) { this.peKind = portableExecutableKind; this.machine = imageFileMachine; if ((peKind & PortableExecutableKinds.PE32Plus) != 0 || (peKind & PortableExecutableKinds.Unmanaged32Bit) != 0) { throw new NotImplementedException(peKind.ToString()); } if (machine == ImageFileMachine.IA64 || machine == ImageFileMachine.AMD64) { throw new NotImplementedException(machine.ToString()); } if (resource_writers != null) { foreach (IResourceWriter writer in resource_writers) { writer.Generate(); writer.Close(); } } // Create a main module if not already created ModuleBuilder mainModule = null; if (modules != null) { foreach (ModuleBuilder module in modules) { if (module.FullyQualifiedName == assemblyFileName) { mainModule = module; } } } if (mainModule == null) { mainModule = DefineDynamicModule("RefEmit_OnDiskManifestModule", assemblyFileName); } if (!is_module_only) { mainModule.IsMain = true; } /* * Create a new entry point if the one specified * by the user is in another module. */ if ((entry_point != null) && entry_point.DeclaringType.Module != mainModule) { Type[] paramTypes; if (entry_point.GetParametersCount() == 1) { paramTypes = new Type [] { typeof(string) } } ; else { paramTypes = Type.EmptyTypes; } MethodBuilder mb = mainModule.DefineGlobalMethod("__EntryPoint$", MethodAttributes.Static | MethodAttributes.PrivateScope, entry_point.ReturnType, paramTypes); ILGenerator ilgen = mb.GetILGenerator(); if (paramTypes.Length == 1) { ilgen.Emit(OpCodes.Ldarg_0); } ilgen.Emit(OpCodes.Tailcall); ilgen.Emit(OpCodes.Call, entry_point); ilgen.Emit(OpCodes.Ret); entry_point = mb; } if (version_res != null) { DefineVersionInfoResourceImpl(assemblyFileName); } if (sn != null) { // runtime needs to value to embed it into the assembly public_key = sn.PublicKey; } foreach (ModuleBuilder module in modules) { if (module != mainModule) { module.Save(); } } // Write out the main module at the end, because it needs to // contain the hash of the other modules mainModule.Save(); if ((sn != null) && (sn.CanSign)) { sn.Sign(System.IO.Path.Combine(this.AssemblyDir, assemblyFileName)); } created = true; }
private MethodBuilder BuildFunctionStub(Function function, ModuleBuilder builder) { if (function == null || builder == null) throw new ArgumentNullException(); // // Создаем функцию // // Имя (уникальное) string functionName = function.Name; while (m_Functions.Find(functionName, SymbolType.Function) != null) functionName += "#"; // Возвращаемый тип System.Type returnType = function.Type.ToSystemType(); // Параметры System.Type[] parameters = null; if (function.Parameters != null) { parameters = new System.Type[function.Parameters.Count]; for (int x = 0; x < function.Parameters.Count; x++) { parameters[x] = function.Parameters[x].Type.ToSystemType(); } } // Создаем метод (глобально) MethodBuilder method = builder.DefineGlobalMethod(functionName, MethodAttributes.Public | MethodAttributes.Static, returnType, parameters); if (function.Parameters != null) { for (int x = 0; x < function.Parameters.Count; x++) { ParameterBuilder p = null; p = method.DefineParameter(x + 1, ParameterAttributes.None, function.Parameters[x].Name); function.Body.SymbolTable.Add(p.Name, SymbolType.Variable, function.Parameters[x], p); } } function.Builder = method; m_Functions.Add(functionName, SymbolType.Function, function, method); return method; }
/// <summary> /// Emits metadata declaration for this function given a ModuleBuilder object /// </summary> /// <param name="mb">ModuleBuilder object</param> public void EmitDeclaration(ModuleBuilder mb) { // Define global public static method this.mb = mb.DefineGlobalMethod(name, MethodAttributes.Public | MethodAttributes.Static, Type.GetType("System.Void"), null); // Setup arguments Type[] types = new Type[localScope.arguments.Count]; for (int i = 0; i < localScope.arguments.Count; i++) { types[i] = localScope.arguments[i].type.ToCLRType(); } // Set method arguments this.mb.SetParameters(types); // Set return type this.mb.SetReturnType(returnType.ToCLRType()); }
private static TypeBuilder[] EmitSource(Module module, ModuleBuilder moduleB, Set replacedMethods, MetaDataMapper mapper) { ModuleEx moduleEx = new ModuleEx(module); ArrayList allMethods = new ArrayList(); ArrayList allCtors = new ArrayList(); ArrayList allTypes = new ArrayList(); Hashtable map = mapper.MapTable; //FieldInfo -> FieldBuilder, MethodInfo -> MethodBuilder... mapping //Type -> Type mapping is performed through moduleB.GetType(), because of array & ref types Type[] types = module.GetTypes(); Sort(types); foreach(Type type in types) { TypeBuilder typeB; if(type.DeclaringType != null) { typeB = (mapper.Map(type.DeclaringType) as TypeBuilder).DefineNestedType(type.Name, type.Attributes, mapper.Map(type.BaseType), mapper.Map(GetDeclaredInterfaces(type))); //Don't know how to declare nested enums :(( //Anyway, "nested-value-types BUG" affects them, too } else { typeB = moduleB.DefineType(type.FullName, type.Attributes, mapper.Map(type.BaseType), mapper.Map(GetDeclaredInterfaces(type))); } allTypes.Add(typeB); } //The end of type declarations... foreach(Type type in types) { TypeBuilder typeB = mapper.Map(type) as TypeBuilder; FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach(FieldInfo field in fields) { if(field.IsLiteral) continue; //Andrew: ZLP FieldAttributes attributes = AddInternalAttribute(field.Attributes); FieldBuilder fieldB = typeB.DefineField(field.Name, mapper.Map(field.FieldType), attributes); map[field] = fieldB; } PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach(PropertyInfo property in properties) { ParameterInfo[] parameters = property.GetIndexParameters(); Type[] paramTypes = new Type[parameters.Length]; for(int i=0; i<paramTypes.Length; i++) paramTypes[i] = mapper.Map( parameters[i].ParameterType); PropertyBuilder propertyB = typeB.DefineProperty(property.Name, property.Attributes, mapper.Map(property.PropertyType), paramTypes); map[property] = propertyB; } EventInfo[] events = type.GetEvents(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach(EventInfo Event in events) { EventBuilder eventB = typeB.DefineEvent(Event.Name, Event.Attributes, mapper.Map(Event.EventHandlerType)); map[Event] = eventB; } MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach(MethodInfo method in methods) { ParameterInfo[] parameters = method.GetParameters(); Type[] paramTypes = new Type[parameters.Length]; for(int i=0; i<paramTypes.Length; i++) paramTypes[i] = mapper.Map( parameters[i].ParameterType); MethodAttributes attributes = AddInternalAttribute(method.Attributes); MethodBuilder methodB = typeB.DefineMethod(method.Name, attributes, method.CallingConvention, mapper.Map(method.ReturnType), paramTypes); for(int i=0; i<paramTypes.Length; i++) methodB.DefineParameter(i+1, parameters[i].Attributes, parameters[i].Name); map[method] = methodB; if(!replacedMethods.Contains(method)) allMethods.Add(method); } ConstructorInfo[] ctors = type.GetConstructors(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.DeclaredOnly); foreach(ConstructorInfo ctor in ctors) { ParameterInfo[] parameters = ctor.GetParameters(); Type[] paramTypes = new Type[parameters.Length]; for(int i=0; i<paramTypes.Length; i++) paramTypes[i] = mapper.Map( parameters[i].ParameterType); MethodAttributes attributes = AddInternalAttribute(ctor.Attributes); ConstructorBuilder ctorB = typeB.DefineConstructor(attributes, ctor.CallingConvention, paramTypes); for(int i=0; i<paramTypes.Length; i++) ctorB.DefineParameter(i+1, parameters[i].Attributes, parameters[i].Name); map[ctor] = ctorB; if(!replacedMethods.Contains(ctor)) allCtors.Add(ctor); } if(type.IsValueType) typeB.DefineDefaultConstructor(MethodAttributes.Public); }//foreach type MethodInfo[] globalMethods = module.GetMethods(); foreach(MethodInfo method in globalMethods) { ParameterInfo[] parameters = method.GetParameters(); Type[] paramTypes = new Type[parameters.Length]; for(int i=0; i<paramTypes.Length; i++) paramTypes[i] = mapper.Map( parameters[i].ParameterType); MethodAttributes attributes = AddInternalAttribute(method.Attributes); MethodBuilder methodB = moduleB.DefineGlobalMethod(method.Name, attributes, method.CallingConvention, mapper.Map(method.ReturnType), paramTypes); for(int i=0; i<paramTypes.Length; i++) methodB.DefineParameter(i+1, parameters[i].Attributes, parameters[i].Name); map[method] = methodB; if(!replacedMethods.Contains(method)) allMethods.Add(method); } //The end of fields, methods, ctors declarations... foreach(MethodInfo method in allMethods) { ILGenerator generator = (mapper.Map(method) as MethodBuilder).GetILGenerator(); ProcessMethod(generator, moduleEx.GetMethodEx(method), method, mapper); } foreach(ConstructorInfo ctor in allCtors) { ILGenerator generator = (mapper.Map(ctor) as ConstructorBuilder).GetILGenerator(); ProcessMethod(generator, moduleEx.GetMethodEx(ctor), ctor, mapper); } TypeBuilder[] result = new TypeBuilder[allTypes.Count]; allTypes.CopyTo(result); return(result); }