public IAlgorithm Compile(InstructionInfo[] Instructions) { lock (GlobalLock) { Stopwatch sw = Stopwatch.StartNew(); typeBuilder = modBuilder.DefineType("AlgoClass_" + CompiledClasses, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(object), new Type[] { typeof(IAlgorithm) }); CreateConstructor(typeBuilder); CreateDeconstructor(typeBuilder); CreateUlongMethod(typeBuilder, Instructions); //CreateByteMethod(typeBuilder); Type InitType = typeBuilder.CreateType(); Algorithm = (IAlgorithm)InitType.GetConstructor(new Type[] { }).Invoke(new object[] { }); //asmBuilder.Save("Dderp.dll"); //ulong test = Algorithm.CalculateULong(1); CompiledClasses++; sw.Stop(); return Algorithm; } }
public CodeGen(Stmt stmt, string moduleName) { if (IO.Path.GetFileName(moduleName) != moduleName) { throw new System.Exception("can only output into current directory!"); } Reflect.AssemblyName name = new Reflect.AssemblyName(IO.Path.GetFileNameWithoutExtension(moduleName)); Emit.AssemblyBuilder asmb = System.AppDomain.CurrentDomain.DefineDynamicAssembly(name, Emit.AssemblyBuilderAccess.Save); Emit.ModuleBuilder modb = asmb.DefineDynamicModule(moduleName); Emit.TypeBuilder typeBuilder = modb.DefineType("Foo"); Emit.MethodBuilder methb = typeBuilder.DefineMethod("Main", Reflect.MethodAttributes.Static, typeof(void), System.Type.EmptyTypes); // CodeGenerator this.il = methb.GetILGenerator(); this.symbolTable = new Collections.Dictionary <string, Emit.LocalBuilder>(); // Go Compile! this.GenStmt(stmt); il.Emit(Emit.OpCodes.Ret); typeBuilder.CreateType(); modb.CreateGlobalFunctions(); asmb.SetEntryPoint(methb); asmb.Save(moduleName); this.symbolTable = null; this.il = null; }
public void Program() { var tempName = "EvilProg-" + Guid.NewGuid().ToString(); AssemblyName aName = new AssemblyName(tempName); AssemblyBuilder ab = AppDomain.CurrentDomain.DefineDynamicAssembly(aName, AssemblyBuilderAccess.Save); programModule = ab.DefineDynamicModule(aName.Name, tempName + ".exe", true); programType = programModule.DefineType("Program", TypeAttributes.Public); createReadInInt(); this.program(); var main = functionMap["main"]; programModule.SetUserEntryPoint(main); ab.SetEntryPoint(main); programType.CreateType(); string tempPath = tempName + ".exe"; ab.Save(tempPath); if (File.Exists(Options.ClrExec.Value)) File.Delete(Options.ClrExec.Value); File.Move(tempPath, Options.ClrExec.Value); File.Delete(tempPath); }
/// <summary> /// Generates the type. /// </summary> /// <returns></returns> public Type GenerateType() { if (_generatedType == null) { // Setup the assembly and type builder AssemblyName assemblyName = new AssemblyName("Mock.Generated-" + _interfaceToImplement.Name); AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name); _typeBuilder = moduleBuilder.DefineType("Mock.Generated.Mock" + _interfaceToImplement.Name, TypeAttributes.Public); _typeBuilder.AddInterfaceImplementation(_interfaceToImplement); // Generate the body of the type this.CreateFields(); this.CreateConstructor(); foreach (MethodInfo method in _interfaceToImplement.GetMethods(BindingFlags.Public | BindingFlags.Instance).Where(m => !m.Name.StartsWith("get_"))) { this.ImplementMethod(method); } foreach (PropertyInfo property in _interfaceToImplement.GetProperties(BindingFlags.Public | BindingFlags.Instance)) { this.ImplementProperty(property); } // Store the generated type for use again _generatedType = _typeBuilder.CreateType(); } return _generatedType; }
public Type CreateType(TypeBuilder typeBuilder) { Type proxyType = typeBuilder.CreateType(); ((AssemblyBuilder)typeBuilder.Assembly).Save("ProxyAssembly.dll"); AssemblyAssert.IsValidAssembly("ProxyAssembly.dll"); return proxyType; }
public void GenerateCode() { DefineClassVaribale(typeBuilder, typeDec); child = new MethodGen(typeBuilder, fieldList, "", this); GenerateMethod(typeDec.methodDec); typeBuilder.CreateType(); }
private void CompileMainClass(Node ActiveNode) { Emit.TypeBuilder _TypeBuilder = TypeTable[ActiveNode.Nodes[1].Value]; Emit.MethodBuilder MethBuilder = _TypeBuilder.DefineMethod("Main", Reflect.MethodAttributes.Static, typeof(void), System.Type.EmptyTypes); this.AssemblerGenerator = MethBuilder.GetILGenerator(); CurrentType = _TypeBuilder; OpenBlockVariables(); CreateCode(ActiveNode.Nodes[14]); CreateCode(ActiveNode.Nodes[15]); CloseBlockVariables(); // Отладочные команды AssemblerGenerator.Emit(Emit.OpCodes.Ldstr, "Programm was finished. Press Enter key to quit..."); AssemblerGenerator.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new System.Type[] { typeof(string) })); AssemblerGenerator.Emit(Emit.OpCodes.Call, typeof(System.Console).GetMethod("ReadLine", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static, null, new System.Type[] { }, null)); AssemblerGenerator.Emit(Emit.OpCodes.Pop); AssemblerGenerator.Emit(Emit.OpCodes.Ret); CreatedTypeTable[ActiveNode.Nodes[1].Value] = _TypeBuilder.CreateType(); ModBuilder.CreateGlobalFunctions(); AsmBuilder.SetEntryPoint(MethBuilder); }
/// <summary> /// Get the builded method. /// </summary> /// <returns>Builded method</returns> /// <seealso cref="AddMethod(string, Type[], Type)"/> public IResponse GetMethod() { TypeNotFinalizedBuildResponse response = methods.Pop(); response.Status = BuildedFunctionStatus.FunctionFinalizedTypeNotFinalized; var created = response.Emiter.CreateMethod(); if (methods.Count == 0) { AlreadyBuildedMethods = new Dictionary <Type, IResponse>(); if (typeBuilder != null) { Type currentType = typeBuilder.CreateType(); Debug.Assert(assemblyBuilder != null); #if !RUN_ONLY assemblyBuilder.Save(assemblyName.Name + ".dll"); #endif return(new TypeFinalizedBuildResponse() { Method = currentType.GetMethod(created.Name, created.GetParameters().Select(x => x.ParameterType).ToArray()) }); } } return(response); }
public CodeGenerator(Expression pExpression, String pModuleName, ref LogHandler rLogHandler) { _symbolTable = new Dictionary <String, Emit.LocalBuilder>(); _assemblyName = new Reflect.AssemblyName(Path.GetFileNameWithoutExtension(pModuleName)); _statement = pExpression; //Init Assembly _assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(_assemblyName, Emit.AssemblyBuilderAccess.Save); _moduleBuilder = _assemblyBuilder.DefineDynamicModule(pModuleName); _typeBuilder = _moduleBuilder.DefineType("PascalCompilerType"); _methodBuilder = _typeBuilder.DefineMethod ( "Main", Reflect.MethodAttributes.Static, typeof(void), Type.EmptyTypes ); _ilGenerator = _methodBuilder.GetILGenerator(); //Actual Work GenerateStatement(_statement, null); _ilGenerator.Emit(Emit.OpCodes.Ret); //Finalizing Work _typeBuilder.CreateType(); _moduleBuilder.CreateGlobalFunctions(); _assemblyBuilder.SetEntryPoint(_methodBuilder); _assemblyBuilder.Save(pModuleName); }
// .NET 4.5 and later have the documented SetMethodBody() method. static Type GetTypeNET45(TypeBuilder tb, MethodBuilder mb, IntPtr address) { byte[] code = new byte[1] { 0x2A }; int maxStack = 8; byte[] locals = GetLocalSignature(address); setMethodBodyMethodInfo.Invoke(mb, new object[5] { code, maxStack, locals, null, null }); var createdMethod = tb.CreateType().GetMethod(METHOD_NAME, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); return createdMethod.GetMethodBody().LocalVariables[0].LocalType; }
private void CompileClassDecl(Node ActiveNode) { Emit.TypeBuilder _TypeBuilder = TypeTable[ActiveNode.Nodes[1].Value]; CurrentType = _TypeBuilder; OpenBlockVariables(); CreateCode(ActiveNode.Nodes[3]); CloseBlockVariables(); CreateCode(ActiveNode.Nodes[4]); CreatedTypeTable[ActiveNode.Nodes[1].Value] = _TypeBuilder.CreateType(); }
public Type CreateType(String typeName, Type parent) { _typeBuilder = _moduleBuilder.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, parent, new[] { typeof(IProxy) }); _typeBuilder.AddInterfaceImplementation(typeof(IProxy)); ImplementProxyInterface(parent); var propHandlerDic = OverrideProperties(parent); GenerateConstructor(propHandlerDic); return _typeBuilder.CreateType(); }
private void finalizar(string nombreEjecutable) { //Asigno una pausa para indicar que finalizo la ejecucion del codigo objetivo generado anadirPausa(); //Creo el assembler .net y defino las ultimas opciones de configuracion il.Emit(Emit.OpCodes.Ret); Type pp = typeBuilder.CreateType(); modb.CreateGlobalFunctions(); asmb.SetEntryPoint(methb, Reflect.Emit.PEFileKinds.ConsoleApplication); asmb.Save(IO.Path.GetFileName(nombreEjecutable)); //Ahora procedo a limpiar la tabla de direcciones para su proximo uso. TablaDireccionesSimbolos.Clear(); this.il = null; }
public static Type CompileResultType(List <FieldInfo> listOfFields, string typeName) { System.Reflection.Emit.TypeBuilder tb = GetTypeBuilder(typeName); ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); // NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type) foreach (var field in listOfFields) { CreateProperty(tb, field.Name, field.Type); } Type objectType = tb.CreateType(); return(objectType); }
public Type CompileResultType() { System.Reflection.Emit.TypeBuilder tb = GetTypeBuilder(); ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); // NOTE: assuming your list contains Field objects with fields FieldName(string) and FieldType(Type) foreach (KeyValuePair <string, Tuple <Type, bool> > field in Fields) { CreateProperty(tb, field.Key, field.Value.Item1, field.Value.Item2); } Type objectType = tb.CreateType(); return(objectType); }
public CodeGenOld(ParseTreeNode stmt, string moduleName) { if (Path.GetFileName(moduleName) != moduleName) { throw new System.Exception("can only output into current directory!"); } AssemblyName name = new AssemblyName(Path.GetFileNameWithoutExtension(moduleName)); AssemblyBuilder asmb = System.AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Save); ModuleBuilder modb = asmb.DefineDynamicModule(moduleName); mainProgram = modb.DefineType("Program"); var mainArgs = new List<Tuple<string,Type>>(); var mainProgramDef = new FunctionDefinition() { methodDefinition=mainProgram.DefineMethod("Main", MethodAttributes.Static, typeof(void), System.Type.EmptyTypes), arguments=new List<FunctionDefinition.Argument>() }; functionTable.Add("Main",mainProgramDef); SymbolTable symbolTable = new SymbolTable(); // CodeGenerator var il = functionTable["Main"].methodDefinition.GetILGenerator(); // Go Compile! this.GenStmt(stmt, il, symbolTable); il.Emit(OpCodes.Ldstr, "Press any key to exit the program..."); il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("WriteLine", new Type[] { typeof(string) })); il.Emit(OpCodes.Call, typeof(System.Console).GetMethod("ReadKey", new Type[] { })); il.Emit(OpCodes.Ret); mainProgram.CreateType(); modb.CreateGlobalFunctions(); asmb.SetEntryPoint(functionTable["Main"].methodDefinition); asmb.Save(moduleName); foreach (var symbol in symbolTable.locals) { Console.WriteLine("{0}: {1}", symbol.Key, symbol.Value); } symbolTable = null; il = null; }
public static Type BuildPropertyObject(System.Collections.Generic.IEnumerable <System.Collections.Generic.KeyValuePair <string, Type> > obj) { string nameOfDLL = "magic.dll"; string nameOfAssembly = "magic_Assembly"; string nameOfModule = "magic_Module"; string nameOfType = "magic_Type"; System.Reflection.AssemblyName assemblyName = new System.Reflection.AssemblyName { Name = nameOfAssembly }; System.Reflection.Emit.AssemblyBuilder assemblyBuilder = System.Threading.Thread.GetDomain().DefineDynamicAssembly(assemblyName, System.Reflection.Emit.AssemblyBuilderAccess.RunAndSave); System.Reflection.Emit.ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(nameOfModule, nameOfDLL); System.Reflection.Emit.TypeBuilder typeBuilder = moduleBuilder.DefineType(nameOfType, System.Reflection.TypeAttributes.Public | System.Reflection.TypeAttributes.Class); foreach (var prop in obj) { string Name = prop.Key; Type DataType = prop.Value; System.Reflection.Emit.FieldBuilder field = typeBuilder.DefineField("_" + Name, DataType, System.Reflection.FieldAttributes.Private); System.Reflection.Emit.PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(Name, System.Reflection.PropertyAttributes.SpecialName, DataType, null); System.Reflection.MethodAttributes methodAttributes = System.Reflection.MethodAttributes.Public | System.Reflection.MethodAttributes.HideBySig | System.Reflection.MethodAttributes.SpecialName; System.Reflection.Emit.MethodBuilder methodBuilderGetter = typeBuilder.DefineMethod("get_" + Name, methodAttributes, DataType, new Type[] { }); System.Reflection.Emit.MethodBuilder methodBuilderSetter = typeBuilder.DefineMethod("set_" + Name, methodAttributes, typeof(void), new Type[] { DataType }); System.Reflection.Emit.ILGenerator ilGeneratorGetter = methodBuilderGetter.GetILGenerator(); ilGeneratorGetter.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilGeneratorGetter.Emit(System.Reflection.Emit.OpCodes.Ldfld, field); ilGeneratorGetter.Emit(System.Reflection.Emit.OpCodes.Ret); System.Reflection.Emit.ILGenerator ilGeneratorSetter = methodBuilderSetter.GetILGenerator(); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Ldarg_0); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Ldarg_1); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Stfld, field); ilGeneratorSetter.Emit(System.Reflection.Emit.OpCodes.Ret); propertyBuilder.SetGetMethod(methodBuilderGetter); propertyBuilder.SetSetMethod(methodBuilderSetter); } // Yes! you must do this, it should not be needed but it is! Type dynamicType = typeBuilder.CreateType(); // Save to file assemblyBuilder.Save(nameOfDLL); return(dynamicType); }
/// <summary>根据类名创建一个没有成员的类型的实例</summary> /// <param name="className">将要创建的类型的实例的类名。</param> /// <returns>返回创建的类型的实例。</returns> public static Type BuildType(string className) { AppDomain domain = Thread.GetDomain(); AssemblyName asmName = new AssemblyName(); asmName.Name = "MyDynamicAssembly"; //创建一个永久程序集,设置为AssemblyBuilderAccess.RunAndSave。 //创建一个永久单模程序块。 //创建TypeBuilder。 //创建类型。 AssemblyBuilder asmBuilder = domain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder moduleBuilder = asmBuilder.DefineDynamicModule(asmName.Name, asmName.Name + ".dll"); System.Reflection.Emit.TypeBuilder typeBuilder = moduleBuilder.DefineType(className, TypeAttributes.Public); Type type = typeBuilder.CreateType(); //保存程序集,以便可以被Ildasm.exe解析,或被测试程序引用。 //asmBuilder.Save(myAsmName.Name + ".dll"); return(type); }
public CodeGen(stmt stmt, string moduleName, int count) { if (IO.Path.GetFileName(moduleName) != moduleName) { throw new System.Exception("can only output into current directory!"); } stmts = stmt; Reflect.AssemblyName name = new Reflect.AssemblyName("FAJF"); //name of the assembly Emit.AssemblyBuilder asmb = System.AppDomain.CurrentDomain.DefineDynamicAssembly(name, Emit.AssemblyBuilderAccess.Save); Emit.ModuleBuilder modb = asmb.DefineDynamicModule(moduleName); Emit.TypeBuilder typeBuilder = modb.DefineType("resister"); //name of the class Emit.MethodBuilder methb = typeBuilder.DefineMethod("Main", Reflect.MethodAttributes.Static, typeof(void), System.Type.EmptyTypes); // CodeGenerator this.il = methb.GetILGenerator(); this.symbolTable = new Collections.Dictionary <string, Emit.LocalBuilder>(); counting = 0; counter = count; counters = 0; // Go Compile! this.GenStmt(stmt); il.Emit(Emit.OpCodes.Ret); typeBuilder.CreateType(); modb.CreateGlobalFunctions(); asmb.SetEntryPoint(methb); asmb.Save(moduleName); // this.il.EmitWriteLine("press any key to continue"); this.symbolTable = null; this.il = null; System.Diagnostics.Process.Start(moduleName); }
/// <summary>把属性加入到类型的实例</summary> /// <param name="type">类型的实例。</param> /// <param name="cpis">要加入的属性列表。</param> /// <returns>返回处理过的类型的实例。</returns> public static Type AddPropertyToType(Type type, List <CustPropertyInfo> cpis) { AppDomain myDomain = Thread.GetDomain(); AssemblyName myAsmName = new AssemblyName(); myAsmName.Name = "MyDynamicAssembly"; //创建一个永久程序集,设置为AssemblyBuilderAccess.RunAndSave。 //创建一个永久单模程序块。 //创建TypeBuilder。 //把lcpi中定义的属性加入到TypeBuilder。将清空其它的成员。其功能有待扩展,使其不影响其它成员。 //创建类型。 AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll"); System.Reflection.Emit.TypeBuilder myTypeBuilder = myModBuilder.DefineType(type.FullName, TypeAttributes.Public); AddPropertyToTypeBuilder(myTypeBuilder, cpis); Type retval = myTypeBuilder.CreateType(); //保存程序集,以便可以被Ildasm.exe解析,或被测试程序引用。 //myAsmBuilder.Save(myAsmName.Name + ".dll"); return(retval); }
public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context) { if (_compiledType != null) return _compiledType; string publicTypeName = IsDefType || (_isStatic && Compiler.IsCompiling) ? InternalName : InternalName + "__" + RT.nextID(); _typeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, superType, true); context = context.WithNewDynInitHelper().WithTypeBuilder(_typeBuilder); Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, context)); try { if (interfaces != null) { for (int i = 0; i < interfaces.count(); i++) _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i)); } ObjExpr.MarkAsSerializable(_typeBuilder); GenInterface.SetCustomAttributes(_typeBuilder, _classMeta); try { if (IsDefType) { Compiler.RegisterDuplicateType(_typeBuilder); Var.pushThreadBindings(RT.map( Compiler.CompileStubOrigClassVar, stubType )); //, //Compiler.COMPILE_STUB_CLASS, _baseType)); } EmitConstantFieldDefs(_typeBuilder); EmitKeywordCallsiteDefs(_typeBuilder); DefineStaticConstructor(_typeBuilder); if (SupportsMeta) _metaField = _typeBuilder.DefineField("__meta", typeof(IPersistentMap), FieldAttributes.Public | FieldAttributes.InitOnly); // If this IsDefType, then it has already emitted the closed-over fields on the base class. if ( ! IsDefType ) EmitClosedOverFields(_typeBuilder); EmitProtocolCallsites(_typeBuilder); _ctorInfo = EmitConstructor(_typeBuilder, superType); if (_altCtorDrops > 0) EmitFieldOnlyConstructor(_typeBuilder, superType); if (SupportsMeta) { EmitNonMetaConstructor(_typeBuilder, superType); EmitMetaFunctions(_typeBuilder); } EmitStatics(_typeBuilder); EmitMethods(_typeBuilder); //if (KeywordCallsites.count() > 0) // EmitSwapThunk(_typeBuilder); _compiledType = _typeBuilder.CreateType(); if (context.DynInitHelper != null) context.DynInitHelper.FinalizeType(); _ctorInfo = GetConstructorWithArgCount(_compiledType, CtorTypes().Length); return _compiledType; } finally { if (IsDefType) Var.popThreadBindings(); } } finally { Var.popThreadBindings(); } }
/// <summary> /// Compiles the type that is being built and returns its run-time Type. /// If you want to create instances directly, see the GetConstructorDelegate. /// </summary> public Type Compile() { if (_compiledType == null) { _CheckThread(); _delegates = new Delegate[_methods.Count]; var methodBuilders = new Dictionary <string, MethodBuilder>(); int index = -1; foreach (var method in _methods) { index++; var methodBuilder = _Compile(method, index); methodBuilders[method.Name] = methodBuilder; } foreach (var property in _properties.Values) { string name = property.Name; var propertyBuilder = _type.DefineProperty(name, PropertyAttributes.None, property.PropertyType, Type.EmptyTypes); propertyBuilder.SetGetMethod(methodBuilders["get_" + name]); propertyBuilder.SetSetMethod(methodBuilders["set_" + name]); } foreach (var eventInfo in _events.Values) { string name = eventInfo.Name; var eventBuilder = _type.DefineEvent(name, EventAttributes.None, eventInfo.Type); string addName = "add_" + name; string removeName = "remove_" + name; var addMethod = methodBuilders[addName]; var removeMethod = methodBuilders[removeName]; eventBuilder.SetAddOnMethod(addMethod); eventBuilder.SetRemoveOnMethod(removeMethod); foreach (var interfaceType in _interfaceTypes) { var method = interfaceType.GetMethod(addName); if (method != null) { _type.DefineMethodOverride(addMethod, method); } method = interfaceType.GetMethod(removeName); if (method != null) { _type.DefineMethodOverride(removeMethod, method); } } } var compiledType = _type.CreateType(); var thisExpression = Expression.Parameter(compiledType, "this"); var fields = _fields.ToArray(); foreach (var fieldPair in fields) { var leftPair = fieldPair.Key; var field = leftPair.Key; var rightPair = fieldPair.Value; string fieldName = rightPair.Value; var expression = Expression.MakeMemberAccess(thisExpression, compiledType.GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic)); _fields[leftPair] = new KeyValuePair <MemberExpression, string>(expression, fieldName); } index = -1; foreach (var method in _methods) { index++; if (method._respectVisibility) { continue; } if (!method.IsStatic) { var firstParameter = method._parameters.Keys.First(); method._parameters[firstParameter] = thisExpression; } var compiledMethod = method._Compile(null, null); _delegates[index] = compiledMethod; } var delegatesField = compiledType.GetField(".delegates", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); delegatesField.SetValue(null, _delegates); _compiledType = compiledType; } return(_compiledType); }
public override Type GetType(string className, bool throwOnError, bool ignoreCase) { if (className == null) { throw new ArgumentNullException("className"); } if (className.Length == 0) { throw new ArgumentException("className"); } TypeBuilder result = null; if (types == null && throwOnError) { throw new TypeLoadException(className); } TypeSpec ts = TypeSpec.Parse(className); if (!ignoreCase) { var displayNestedName = ts.TypeNameWithoutModifiers(); name_cache.TryGetValue(displayNestedName, out result); } else { if (types != null) { result = search_in_array(types, num_types, ts.Name); } if (!ts.IsNested && result != null) { result = GetMaybeNested(result, ts.Nested); } } if ((result == null) && throwOnError) { throw new TypeLoadException(className); } if (result != null && (ts.HasModifiers || ts.IsByRef)) { Type mt = result; if (result is TypeBuilder) { var tb = result as TypeBuilder; if (tb.is_created) { mt = tb.CreateType(); } } foreach (var mod in ts.Modifiers) { if (mod is PointerSpec) { mt = mt.MakePointerType(); } else if (mod is ArraySpec) { var spec = mod as ArraySpec; if (spec.IsBound) { return(null); } if (spec.Rank == 1) { mt = mt.MakeArrayType(); } else { mt = mt.MakeArrayType(spec.Rank); } } } if (ts.IsByRef) { mt = mt.MakeByRefType(); } result = mt as TypeBuilder; if (result == null) { return(mt); } } if (result != null && result.is_created) { return(result.CreateType()); } else { return(result); } }
private void EnsureTypeBuilt(GenContext context) { if (_typeBuilder != null) return; _baseTypeBuilder = GenerateFnBaseClass(context); _baseType = _baseTypeBuilder.CreateType(); GenerateFnClass(context, _baseType); _fnType = _typeBuilder.CreateType(); }
public override void GenCode(TypeBuilder tb, MethodBuilder mb, ILGenerator cg) { List<Type> parametersConstructor = new List<Type>(); List<FieldBuilder> campos = new List<FieldBuilder>(); foreach (var item in Parameters) { parametersConstructor.Add(Compiler.SearchType(item.Type)); campos.Add(tb.DefineField(item.Id, Compiler.SearchType(item.Type), FieldAttributes.Public)); } ConstructorBuilder constructor = tb.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, parametersConstructor.ToArray()); Compiler.RecordConstructors.Add(new RecordsConstructors(tb.Name, constructor)); ILGenerator ilgen = constructor.GetILGenerator(); Type objType = Type.GetType("System.Object"); ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);//creando el contructor vacio para generar el otro ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Call, objCtor); int i = 1; foreach (var item in campos)//poniendole los valores de los campos a lsa propiedades { ilgen.Emit(OpCodes.Ldarg_0);//este objeto ilgen=contructor.getIlgenerator() ilgen.Emit(OpCodes.Ldarg, i);//tiene un field item ilgen.Emit(OpCodes.Stfld, item);//y en el se pone el valor del argumento i del contructor i++; } ilgen.Emit(OpCodes.Ret); record = tb.CreateType(); }
private void DefineClassMethods(Entity c, TypeBuilder t) { ILGenerator il; // Conversion operations to super classes foreach (Resource r in schemas.SelectObjects(c, RDFS + "subClassOf")) { if (!(r is Entity)) continue; Type superclass = GetType((Entity)r); if (superclass == null || superclass == typeof(string)) continue; string methodname; if (superclass.Assembly == a) methodname = superclass.Name; else methodname = superclass.FullName.Replace(".", ""); MethodBuilder method = t.DefineMethod("As" + methodname, MethodAttributes.Public, superclass, Type.EmptyTypes); il = method.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Call, getentity); il.Emit(OpCodes.Ldarg_0); // this il.Emit(OpCodes.Call, getmodel); ConstructorInfo superconstructor = GetConstructor(superclass); il.Emit(OpCodes.Newobj, superconstructor); il.Emit(OpCodes.Ret); } // Properties foreach (Entity p in schemas.SelectSubjects(RDFS + "domain", c)) DefineProperty(c, p, t, true, true); foreach (Entity p in schemas.SelectSubjects(RDFS + "domain", (Entity)"http://www.w3.org/2000/01/rdf-schema#Resource")) { if (GetDefiningSchema(p) != targetschemauri) continue; DefineProperty(c, p, t, true, false); } foreach (Entity p in schemas.SelectSubjects(RDFS + "range", c)) DefineProperty(c, p, t, false, true); t.CreateType(); }
internal Assembly Generate() { if (module.GetType(proxyName) != null) return module.Assembly; String baseIfaceName = proxyName.Replace("Mozilla.XPCOM.Proxies.", ""); String ifaceName = "Mozilla.XPCOM.Interfaces." + baseIfaceName; Type ifaceType = System.Type.GetType(ifaceName + ",Mozilla.XPCOM.Interfaces", true); ushort inheritedMethodCount; String parentName = TypeInfo.GetParentInfo(baseIfaceName, out inheritedMethodCount); Type parentType; if (parentName == null) { parentType = typeof(BaseProxy); } else { parentType = System.Type.GetType("Mozilla.XPCOM.Proxies." + parentName + ",Mozilla.XPCOM.Proxies"); } Console.WriteLine("Defining {0} (inherits {1}, impls {2})", proxyName, parentType, ifaceName); tb = module.DefineType(proxyName, TypeAttributes.Class, parentType, new Type[1] { ifaceType }); thisField = typeof(BaseProxy).GetField("thisptr", BindingFlags.NonPublic | BindingFlags.Instance); EmitProxyConstructor(); MethodDescriptor[] descs = TypeInfo.GetMethodData(baseIfaceName); for (int i = inheritedMethodCount; i < descs.Length; i++) { if (descs[i] != null) GenerateProxyMethod(descs[i]); } tb.CreateType(); thisField = null; tb = null; return module.Assembly; }
internal override void Seal(TypeDescription existing = null) { if (PocoType != null || TypeBuilder != null) return; var name = "POCO" + Guid.NewGuid().ToString().Replace("-", ""); var protoMemberAttr = typeof(ProtoMemberAttribute).GetConstructor(new[] { typeof(int) }); var protoContractAttr = typeof(ProtoContractAttribute).GetConstructor(new Type[0]); var fields = new Dictionary<string, FieldInfo>(); TypeBuilder = ModuleBuilder.DefineType(name, TypeAttributes.Public, typeof(DynamicObject), new [] { typeof(IEnumerable) }); var ix = 1; foreach (var kv in Members.OrderBy(o => o.Key, StringComparer.Ordinal)) { var memberAttrBuilder = new CustomAttributeBuilder(protoMemberAttr, new object[] { ix }); kv.Value.Seal(existing); var propType = kv.Value.GetPocoType(existing); var field = TypeBuilder.DefineField(kv.Key, propType, FieldAttributes.Public); field.SetCustomAttribute(memberAttrBuilder); fields[kv.Key] = field; ix++; } var contractAttrBuilder = new CustomAttributeBuilder(protoContractAttr, new object[0]); TypeBuilder.SetCustomAttribute(contractAttrBuilder); // Define indexer var strEq = typeof(object).GetMethod("Equals", new[] { typeof(object) }); var tryGetIndexEmit = Sigil.Emit<TryGetIndexerDelegate>.BuildMethod(TypeBuilder, "TryGetIndex", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); tryGetIndexEmit.LoadArgument(2); // object[] var invalid = tryGetIndexEmit.DefineLabel("invalid"); tryGetIndexEmit .Duplicate() // object[] object[] .LoadLength<object>() // int object[] .LoadConstant(1); // int int object[] tryGetIndexEmit.UnsignedBranchIfNotEqual(invalid); // object[] tryGetIndexEmit .LoadConstant(0) // int object[] .LoadElement<object>() // object .IsInstance<string>(); // int var valid = tryGetIndexEmit.DefineLabel("valid"); tryGetIndexEmit .BranchIfTrue(valid) // --empty-- .LoadArgument(2); // object[] tryGetIndexEmit.MarkLabel(invalid); tryGetIndexEmit.Pop(); // --empty-- tryGetIndexEmit .LoadArgument(3) // object& .LoadNull() // null object& .StoreIndirect(typeof(object)); // --empty-- tryGetIndexEmit .LoadConstant(0) // int .Return(); // --empty-- tryGetIndexEmit.MarkLabel(valid); tryGetIndexEmit.LoadArgument(3); // object& tryGetIndexEmit .LoadArgument(2) // object[] object& .LoadConstant(0) // int object[] object& .LoadElement<object>(); // object object& Sigil.Label next; var done = tryGetIndexEmit.DefineLabel("done"); foreach (var mem in Members) { next = tryGetIndexEmit.DefineLabel("next_" + mem.Key); var memKey = mem.Key; var field = fields[memKey]; tryGetIndexEmit .Duplicate() // object object object& .LoadConstant(memKey); // string object object object& tryGetIndexEmit.CallVirtual(strEq); // int object object7& tryGetIndexEmit.BranchIfFalse(next); // object object& tryGetIndexEmit .Pop() // object& .LoadArgument(0) // this object& .LoadField(field); // fieldType object& if (field.FieldType.IsValueType) { tryGetIndexEmit.Box(field.FieldType); // fieldType object& } tryGetIndexEmit.Branch(done); // fieldType object& tryGetIndexEmit.MarkLabel(next); // object object& } tryGetIndexEmit .Pop() // object& .LoadNull(); // null object& tryGetIndexEmit.MarkLabel(done); // *something* object& tryGetIndexEmit .StoreIndirect(typeof(object)) // --empty-- .LoadConstant(1) // int .Return(); // --empty-- var tryGetIndex = tryGetIndexEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(tryGetIndex, typeof(DynamicObject).GetMethod("TryGetIndex")); // Implement IEnumerable var getEnumeratorEmit = Sigil.Emit<Func<IEnumerator>>.BuildMethod(TypeBuilder, "GetEnumerator", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); var newStrList = typeof(List<string>).GetConstructor(new[] { typeof(int) }); var newEnumerator = Enumerator.GetConstructor(new[] { typeof(List<string>), typeof(object) }); var add = typeof(List<string>).GetMethod("Add"); getEnumeratorEmit.LoadConstant(Members.Count); getEnumeratorEmit.NewObject(newStrList); foreach (var mem in Members) { getEnumeratorEmit.Duplicate(); getEnumeratorEmit.LoadConstant(mem.Key); getEnumeratorEmit.Call(add); } getEnumeratorEmit.LoadArgument(0); getEnumeratorEmit.NewObject(newEnumerator); getEnumeratorEmit.Return(); var getEnumerator = getEnumeratorEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(getEnumerator, typeof(IEnumerable).GetMethod("GetEnumerator")); // Define ToString() var toStringEmit = Sigil.Emit<Func<string>>.BuildMethod(TypeBuilder, "ToString", MethodAttributes.Public | MethodAttributes.Virtual, CallingConventions.Standard | CallingConventions.HasThis); var objToString = typeof(object).GetMethod("ToString"); var thunkField = TypeBuilder.DefineField("__ToStringThunk", typeof(Func<object, string>), FieldAttributes.Static | FieldAttributes.Private); var invoke = typeof(Func<object, string>).GetMethod("Invoke"); toStringEmit .LoadField(thunkField) .LoadArgument(0) .CallVirtual(invoke) .Return(); var toString = toStringEmit.CreateMethod(); TypeBuilder.DefineMethodOverride(toString, objToString); PocoType = TypeBuilder.CreateType(); // Set the ToStringCallback var firstInst = PocoType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]); var setThunk = firstInst.GetType().GetField("__ToStringThunk", BindingFlags.NonPublic | BindingFlags.Static); setThunk.SetValue(firstInst, ToStringFunc); }
public System.Type EndModule(TypeBuilder module) { var result = module.CreateType(); _assembly.SetCustomAttribute ( new CustomAttributeBuilder ( typeof(ModuleAttribute).GetConstructor ( new System.Type[] { typeof(System.Type), typeof(string[]) } ), new object[] { result, Name.FromNative(result.Name).Components } ) ); return result; }
public static Type CreateTypePortable(TypeBuilder typeBuilder) { return typeBuilder.CreateType(); }
public Type CreateType() { if (m_proxyType == null) { m_typeBuilder = m_moduleBuilder.DefineType(m_className, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoLayout, typeof(object), new Type[] {m_interfaceType}); //m_typeBuilder.AddInterfaceImplementation(m_interfaceType); m_innerFieldBuilder = m_typeBuilder.DefineField("inner", m_innerType, FieldAttributes.Private); BuildConstructor(); foreach (MethodInfo method in m_interfaceType.GetMethods()) { BuildMethod(method); } foreach (PropertyInfo property in m_interfaceType.GetProperties()) { BuildProperty(property); } foreach (EventInfo eventInfo in m_interfaceType.GetEvents()) { BuildEvent(eventInfo); } foreach (MethodBuilder methodBuilder in _unsupportedMethods.Values) { BuildNotSupportedException(methodBuilder); } m_proxyType = m_typeBuilder.CreateType(); } return m_proxyType; }
public virtual Type BuildType(Type baseType) { typeBuilder = this.ModuleBuilder.DefineType(baseType.FullName, TypeAttributes.Class | TypeAttributes.Public, baseType); // Build constructor for DataAccessModel var constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, null); var ctorGenerator = constructorBuilder.GetILGenerator(); ctorGenerator.Emit(OpCodes.Ldarg_0); ctorGenerator.Emit(OpCodes.Call, baseType.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null)); ctorGenerator.Emit(OpCodes.Ret); var methodInfo = typeBuilder.BaseType.GetMethod("Initialise", BindingFlags.Instance | BindingFlags.NonPublic); var methodAttributes = MethodAttributes.Virtual | MethodAttributes.SpecialName | MethodAttributes.HideBySig; methodAttributes |= methodInfo.Attributes & (MethodAttributes.Public | MethodAttributes.Private | MethodAttributes.Assembly | MethodAttributes.Family); var initialiseMethodBuilder = typeBuilder.DefineMethod(methodInfo.Name, methodAttributes, methodInfo.CallingConvention, methodInfo.ReturnType, Type.EmptyTypes); var initialiseGenerator = initialiseMethodBuilder.GetILGenerator(); dictionaryFieldBuilder = typeBuilder.DefineField("$$$dataAccessObjectsByType", typeof(Dictionary<Type,IQueryable>), FieldAttributes.Private); initialiseGenerator.Emit(OpCodes.Ldarg_0); initialiseGenerator.Emit(OpCodes.Ldc_I4, baseType.GetProperties().Count()); initialiseGenerator.Emit(OpCodes.Newobj, dictionaryFieldBuilder.FieldType.GetConstructor(new Type[] { typeof(int) })); initialiseGenerator.Emit(OpCodes.Stfld, dictionaryFieldBuilder); foreach (var propertyInfo in baseType.GetProperties()) { var queryableAttribute = propertyInfo.GetFirstCustomAttribute<DataAccessObjectsAttribute>(true); if (queryableAttribute == null) { continue; } if (typeof(RelatedDataAccessObjects<>).IsAssignableFromIgnoreGenericParameters(propertyInfo.PropertyType)) { throw new InvalidOperationException("DataAccessModel objects should not defined properties of type RelatedDataAccessObject<>"); } if (propertyInfo.GetGetMethod().IsAbstract || propertyInfo.GetSetMethod().IsAbstract) { // Generate the field for the queryable var fieldBuilder = typeBuilder.DefineField("$$" + propertyInfo.Name, propertyInfo.PropertyType, FieldAttributes.Private); initialiseGenerator.Emit(OpCodes.Ldarg_0); initialiseGenerator.Emit(OpCodes.Ldarg_0); initialiseGenerator.Emit(OpCodes.Ldnull); initialiseGenerator.Emit(OpCodes.Newobj, propertyInfo.PropertyType.GetConstructor(new [] { typeof(DataAccessModel), typeof(Expression)})); initialiseGenerator.Emit(OpCodes.Stfld, fieldBuilder); // Add to dictionary initialiseGenerator.Emit(OpCodes.Ldarg_0); initialiseGenerator.Emit(OpCodes.Ldfld, dictionaryFieldBuilder); initialiseGenerator.Emit(OpCodes.Ldtoken, propertyInfo.PropertyType.GetGenericArguments()[0]); initialiseGenerator.Emit(OpCodes.Call, MethodInfoFastRef.TypeGetTypeFromHandle); initialiseGenerator.Emit(OpCodes.Ldarg_0); initialiseGenerator.Emit(OpCodes.Ldfld, fieldBuilder); initialiseGenerator.Emit(OpCodes.Callvirt, dictionaryFieldBuilder.FieldType.GetMethod("set_Item")); var propertyBuilder = typeBuilder.DefineProperty(propertyInfo.Name, propertyInfo.Attributes, propertyInfo.PropertyType, Type.EmptyTypes); // Implement get method if (propertyInfo.GetGetMethod() != null && propertyInfo.GetGetMethod().IsAbstract) { propertyBuilder.SetGetMethod(BuildPropertyMethod("get", propertyInfo, fieldBuilder)); } // Implement set method if (propertyInfo.GetSetMethod() != null && propertyInfo.GetSetMethod().IsAbstract) { throw new InvalidOperationException(string.Format("The property '{0}.{1}' should not have a setter because it is a [DataAccessObjects] property", baseType.Name, propertyInfo.Name)); } } } initialiseGenerator.Emit(OpCodes.Ret); BuildGetDataAccessObjectsMethod(); return typeBuilder.CreateType(); }
public Type CreateType() { return(_typeBuilder.CreateType()); }
//Метод, переводящий семантическое дерево в сборку .NET public void ConvertFromTree(SemanticTree.IProgramNode p, string TargetFileName, string SourceFileName, CompilerOptions options, string[] ResourceFiles) { //SystemLibrary.SystemLibInitializer.RestoreStandardFunctions(); bool RunOnly = false; string fname = TargetFileName; comp_opt = options; ad = Thread.GetDomain(); //получаем домен приложения an = new AssemblyName(); //создаем имя сборки an.Version = new Version("1.0.0.0"); string dir = Directory.GetCurrentDirectory(); string source_name = fname;//p.Location.document.file_name; int pos = source_name.LastIndexOf(Path.DirectorySeparatorChar); if (pos != -1) //если имя файла указано с путем, то выделяем { dir = source_name.Substring(0, pos + 1); an.CodeBase = String.Concat("file:///", source_name.Substring(0, pos)); source_name = source_name.Substring(pos + 1); } string name = source_name.Substring(0, source_name.LastIndexOf('.')); if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe) an.Name = name;// + ".exe"; else an.Name = name; //+ ".dll"; if (name == "PABCRtl" || name == "PABCRtl32") { an.Flags = AssemblyNameFlags.PublicKey; an.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess; an.HashAlgorithm = System.Configuration.Assemblies.AssemblyHashAlgorithm.None; FileStream publicKeyStream = File.Open(Path.Combine(Path.GetDirectoryName(TargetFileName), name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk"), FileMode.Open); byte[] publicKey = new byte[publicKeyStream.Length]; publicKeyStream.Read(publicKey, 0, (int)publicKeyStream.Length); // Provide the assembly with a public key. an.SetPublicKey(publicKey); publicKeyStream.Close(); } if (RunOnly) ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, dir);//определяем сборку else ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save, dir);//определяем сборку //int nn = ad.GetAssemblies().Length; if (options.NeedDefineVersionInfo) { ab.DefineVersionInfoResource(options.Product, options.ProductVersion, options.Company, options.Copyright, options.TradeMark); } if (options.MainResourceFileName != null) { try { ab.DefineUnmanagedResource(options.MainResourceFileName); } catch { throw new TreeConverter.SourceFileError(options.MainResourceFileName); } } else if (options.MainResourceData != null) { try { ab.DefineUnmanagedResource(options.MainResourceData); } catch { throw new TreeConverter.SourceFileError(""); } } save_debug_info = comp_opt.dbg_attrs == DebugAttributes.Debug || comp_opt.dbg_attrs == DebugAttributes.ForDebbuging; add_special_debug_variables = comp_opt.dbg_attrs == DebugAttributes.ForDebbuging; //bool emit_sym = true; if (save_debug_info) //если модуль отладочный, то устанавливаем атрибут, запрещающий inline методов ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x01, 0x01, 0x00, 0x00 }); if (RunOnly) mb = ab.DefineDynamicModule(name, save_debug_info); else { if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe) mb = ab.DefineDynamicModule(name + ".exe", an.Name + ".exe", save_debug_info); //определяем модуль (save_debug_info - флаг включать отладочную информацию) else mb = ab.DefineDynamicModule(name + ".dll", an.Name + ".dll", save_debug_info); } cur_unit = Path.GetFileNameWithoutExtension(SourceFileName); string entry_cur_unit = cur_unit; entry_type = mb.DefineType(cur_unit + ".Program", TypeAttributes.Public);//определяем синтетический статический класс основной программы cur_type = entry_type; //точка входа в приложение if (p.main_function != null) { ConvertFunctionHeader(p.main_function); entry_meth = helper.GetMethod(p.main_function).mi as MethodBuilder; cur_meth = entry_meth; il = cur_meth.GetILGenerator(); if (options.target != TargetType.Dll && options.dbg_attrs == DebugAttributes.ForDebbuging) AddSpecialInitDebugCode(); } ILGenerator tmp_il = il; MethodBuilder tmp_meth = cur_meth; //при отладке компилятора здесь иногда ничего нет! ICommonNamespaceNode[] cnns = p.namespaces; //создаем отладочные документы if (save_debug_info) { first_doc = mb.DefineDocument(SourceFileName, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft); sym_docs.Add(SourceFileName, first_doc); for (int iii = 0; iii < cnns.Length; iii++) { string cnns_document_file_name = null; if (cnns[iii].Location != null) { cnns_document_file_name = cnns[iii].Location.document.file_name; doc = mb.DefineDocument(cnns_document_file_name, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft); } else doc = first_doc; if (!sym_docs.ContainsKey(cnns_document_file_name)) sym_docs.Add(cnns_document_file_name, doc);//сохраняем его в таблице документов } first_doc = sym_docs[cnns[0].Location == null ? SourceFileName : cnns[0].Location.document.file_name]; if (p.main_function != null) { if (p.main_function.function_code is IStatementsListNode) EntryPointLocation = ((IStatementsListNode)p.main_function.function_code).LeftLogicalBracketLocation; else EntryPointLocation = p.main_function.function_code.Location; } else EntryPointLocation = null; } ICommonNamespaceNode entry_ns = null; //Переводим заголовки типов for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name]; bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == ""; ICommonNamespaceNode cnn = cnns[iii]; cur_type = entry_type; if (!is_main_namespace) cur_unit = cnn.namespace_name; else cur_unit = entry_cur_unit; if (iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && iii == cnns.Length - 1) entry_ns = cnn; ConvertTypeHeaders(cnn.types); } //Переводим псевдоинстанции generic-типов foreach (ICommonTypeNode ictn in p.generic_type_instances) { ConvertTypeHeaderInSpecialOrder(ictn); } Dictionary<ICommonNamespaceNode, TypeBuilder> NamespacesTypes = new Dictionary<ICommonNamespaceNode, TypeBuilder>(); for (int iii = 0; iii < cnns.Length; iii++) { bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == ""; if (!is_main_namespace) { //определяем синтетический класс для модуля cur_type = mb.DefineType(cnns[iii].namespace_name + "." + cnns[iii].namespace_name, TypeAttributes.Public); types.Add(cur_type); NamespaceTypesList.Add(cur_type); NamespacesTypes.Add(cnns[iii], cur_type); if (cnns[iii].IsMain) { TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$GlobAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute)); ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public); cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 }); attr_class.CreateType(); } else { TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$ClassUnitAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute)); ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public); cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 }); attr_class.CreateType(); } } else { NamespacesTypes.Add(cnns[iii], entry_type); } } if (comp_opt.target == TargetType.Dll) { for (int iii = 0; iii < cnns.Length; iii++) { string tmp = cur_unit; if (cnns[iii].namespace_name != "") cur_unit = cnns[iii].namespace_name; else cur_unit = entry_cur_unit; foreach (ITemplateClass tc in cnns[iii].templates) { CreateTemplateClass(tc); } cur_unit = tmp; } for (int iii = 0; iii < cnns.Length; iii++) { string tmp = cur_unit; if (cnns[iii].namespace_name != "") cur_unit = cnns[iii].namespace_name; else cur_unit = entry_cur_unit; foreach (ITypeSynonym ts in cnns[iii].type_synonims) { CreateTypeSynonim(ts); } cur_unit = tmp; } } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; ConvertTypeMemberHeaders(cnns[iii].types); } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; ConvertFunctionHeaders(cnns[iii].functions); } if (p.InitializationCode != null) { tmp_il = il; if (entry_meth != null) { il = entry_meth.GetILGenerator(); ConvertStatement(p.InitializationCode); } il = tmp_il; } //Переводим псевдоинстанции generic-типов foreach (IGenericTypeInstance ictn in p.generic_type_instances) { ConvertGenericInstanceTypeMembers(ictn); } //Переводим псевдоинстанции функций foreach (IGenericFunctionInstance igfi in p.generic_function_instances) { ConvertGenericFunctionInstance(igfi); } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; //генерим инциализацию для полей foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types) GenerateInitCodeForFields(ctn); } ConstructorBuilder unit_cci = null; //Переводим заголовки всего остального (процедур, переменных) for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name]; bool is_main_namespace = iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll; ICommonNamespaceNode cnn = cnns[iii]; string tmp_unit_name = cur_unit; if (!is_main_namespace) cur_unit = cnn.namespace_name; else cur_unit = entry_cur_unit; cur_type = NamespacesTypes[cnn]; //ConvertFunctionHeaders(cnn.functions); if (!is_main_namespace) { //определяем статический конструктор класса для модуля ConstructorBuilder cb = cur_type.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); il = cb.GetILGenerator(); if (cnn.IsMain) unit_cci = cb; ModulesInitILGenerators.Add(cur_type, il); //переводим глобальные переменные модуля ConvertGlobalVariables(cnn.variables); //перводим константы ConvertNamespaceConstants(cnn.constants); ConvertNamespaceEvents(cnn.events); //il.Emit(OpCodes.Ret); } else { //Не нарвится мне порядок вызова. надо с этим разобраться init_variables_mb = helper.GetMethodBuilder(cnn.functions[cnn.functions.Length-1]);// cur_type.DefineMethod("$InitVariables", MethodAttributes.Public | MethodAttributes.Static); il = entry_meth.GetILGenerator(); ModulesInitILGenerators.Add(cur_type, il); il = init_variables_mb.GetILGenerator(); ConvertGlobalVariables(cnn.variables); il = entry_meth.GetILGenerator(); //перводим константы ConvertNamespaceConstants(cnn.constants); ConvertNamespaceEvents(cnn.events); //il.Emit(OpCodes.Ret); } cur_unit = tmp_unit_name; } if (p.InitializationCode != null) { tmp_il = il; if (entry_meth == null) { il = unit_cci.GetILGenerator(); ConvertStatement(p.InitializationCode); } il = tmp_il; } cur_type = entry_type; //is_in_unit = false; //переводим реализации for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name]; bool is_main_namespace = iii == 0 && comp_opt.target != TargetType.Dll; ICommonNamespaceNode cnn = cnns[iii]; string tmp_unit_name = cur_unit; if (!is_main_namespace) cur_unit = cnn.namespace_name; //if (iii > 0) is_in_unit = true; cur_unit_type = NamespacesTypes[cnns[iii]]; cur_type = cur_unit_type; ConvertTypeImplementations(cnn.types); ConvertFunctionsBodies(cnn.functions); cur_unit = tmp_unit_name; } if (comp_opt.target != TargetType.Dll && p.main_function != null) { cur_unit_type = NamespacesTypes[cnns[0]]; cur_type = cur_unit_type; ConvertBody(p.main_function.function_code); } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii].Location == null ? SourceFileName : cnns[iii].Location.document.file_name]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; //вставляем ret в int_meth foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types) GenerateRetForInitMeth(ctn); ModulesInitILGenerators[cur_type].Emit(OpCodes.Ret); } for (int iii = 0; iii < cnns.Length; iii++) { MakeAttribute(cnns[iii]); } doc = first_doc; cur_type = entry_type; CloseTypes();//закрываем типы entry_type.CreateType(); switch (comp_opt.target) { case TargetType.Exe: ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break; case TargetType.WinExe: if (!comp_opt.ForRunningWithEnvironment) ab.SetEntryPoint(entry_meth, PEFileKinds.WindowApplication); else ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break; } /**/ try { //ne osobo vazhnaja vesh, sohranjaet v exe-shnik spisok ispolzuemyh prostranstv imen, dlja strahovki obernuli try catch if (comp_opt.dbg_attrs == DebugAttributes.ForDebbuging) { string[] namespaces = p.UsedNamespaces; TypeBuilder attr_class = mb.DefineType("$UsedNsAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute)); FieldBuilder fld_ns = attr_class.DefineField("ns", TypeFactory.StringType, FieldAttributes.Public); FieldBuilder fld_count = attr_class.DefineField("count", TypeFactory.Int32Type, FieldAttributes.Public); ConstructorBuilder attr_ci = attr_class.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[2] { TypeFactory.Int32Type, TypeFactory.StringType }); ILGenerator attr_il = attr_ci.GetILGenerator(); attr_il.Emit(OpCodes.Ldarg_0); attr_il.Emit(OpCodes.Ldarg_1); attr_il.Emit(OpCodes.Stfld, fld_count); attr_il.Emit(OpCodes.Ldarg_0); attr_il.Emit(OpCodes.Ldarg_2); attr_il.Emit(OpCodes.Stfld, fld_ns); attr_il.Emit(OpCodes.Ret); int len = 2 + 2 + 4 + 1; foreach (string ns in namespaces) { len += ns.Length + 1; } byte[] bytes = new byte[len]; bytes[0] = 1; bytes[1] = 0; using (BinaryWriter bw = new BinaryWriter(new MemoryStream())) { bw.Write(namespaces.Length); System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (string ns in namespaces) { sb.Append(Convert.ToChar(ns.Length)); sb.Append(ns); //bw.Write(ns); } if (sb.Length > 127) { len += 1; bytes = new byte[len]; bytes[0] = 1; bytes[1] = 0; } bw.Write(sb.ToString()); bw.Seek(0, SeekOrigin.Begin); bw.BaseStream.Read(bytes, 2, len - 4); if (sb.Length > 127) { bytes[7] = (byte)(sb.Length & 0xFF); bytes[6] = (byte)(0x80 | ((sb.Length & 0xFF00) >> 8)); } } entry_type.SetCustomAttribute(attr_ci, bytes); attr_class.CreateType(); } } catch (Exception e) { } if (an.Name == "PABCRtl" || an.Name == "PABCRtl32") { CustomAttributeBuilder cab = new CustomAttributeBuilder(typeof(AssemblyKeyFileAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { an.Name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk" }); ab.SetCustomAttribute(cab); cab = new CustomAttributeBuilder(typeof(AssemblyDelaySignAttribute).GetConstructor(new Type[] { typeof(bool) }), new object[] { true }); ab.SetCustomAttribute(cab); cab = new CustomAttributeBuilder(typeof(TargetFrameworkAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { ".NETFramework,Version=v4.0" }); ab.SetCustomAttribute(cab); } ab.SetCustomAttribute(new CustomAttributeBuilder(typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }), new object[] { SecurityRuleSet.Level2 }, new PropertyInfo[] { typeof(SecurityRulesAttribute).GetProperty("SkipVerificationInFullTrust") }, new object[] { true })); if (entry_meth != null && comp_opt.target == TargetType.WinExe) { entry_meth.SetCustomAttribute(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new byte[] { 0x01, 0x00, 0x00, 0x00 }); } List<FileStream> ResStreams = new List<FileStream>(); if (ResourceFiles != null) foreach (string resname in ResourceFiles) { FileStream stream = File.OpenRead(resname); ResStreams.Add(stream); mb.DefineManifestResource(Path.GetFileName(resname), stream, ResourceAttributes.Public); } ab.SetCustomAttribute(typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute).GetConstructor(new Type[1] { TypeFactory.Int32Type }), new byte[] { 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }); if (RunOnly) { object main_class = ab.CreateInstance(cur_unit + ".Program"); MethodInfo methodInfo = main_class.GetType().GetMethod("Main"); methodInfo.Invoke(main_class, null); } else { int tries = 0; bool not_done = true; do { try { if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe) { if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86) ab.Save(an.Name + ".exe", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386); //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64) // ab.Save(an.Name + ".exe", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64); else ab.Save(an.Name + ".exe"); //сохраняем сборку } else { if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86) ab.Save(an.Name + ".dll", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386); //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64) // ab.Save(an.Name + ".dll", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64); else ab.Save(an.Name + ".dll"); } not_done = false; } catch (System.Runtime.InteropServices.COMException e) { throw new TreeConverter.SaveAssemblyError(e.Message); } catch (System.IO.IOException e) { if (tries < num_try_save) tries++; else throw new TreeConverter.SaveAssemblyError(e.Message); } } while (not_done); } foreach (FileStream fs in ResStreams) fs.Close(); } private void AddSpecialInitDebugCode() { //il.Emit(OpCodes.Call,typeof(Console).GetMethod("ReadLine")); //il.Emit(OpCodes.Pop); } private void ConvertNamespaceConstants(INamespaceConstantDefinitionNode[] Constants) { foreach (INamespaceConstantDefinitionNode Constant in Constants) ConvertConstantDefinitionNode(Constant, Constant.name, Constant.type, Constant.constant_value); } private void ConvertNamespaceEvents(ICommonNamespaceEventNode[] Events) { foreach (ICommonNamespaceEventNode Event in Events) Event.visit(this); } private void ConvertCommonFunctionConstantDefinitions(ICommonFunctionConstantDefinitionNode[] Constants) { foreach (ICommonFunctionConstantDefinitionNode Constant in Constants) //ConvertFunctionConstantDefinitionNode(Constant); ConvertConstantDefinitionNode(Constant, Constant.name, Constant.type, Constant.constant_value); } private void ConvertConstantDefinitionNode(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value) { if (constant_value is IArrayConstantNode) ConvertArrayConstantDef(cnst, name, type, constant_value); else if (constant_value is IRecordConstantNode || constant_value is ICompiledStaticMethodCallNodeAsConstant) ConvertConstantDefWithInitCall(cnst, name, type, constant_value); else if (constant_value is ICommonNamespaceFunctionCallNodeAsConstant || constant_value is IBasicFunctionCallNodeAsConstant || constant_value is ICommonConstructorCallAsConstant || constant_value is ICompiledStaticFieldReferenceNodeAsConstant) ConvertSetConstantDef(cnst, name, type, constant_value); else ConvertSimpleConstant(cnst, name, type, constant_value); } private void ConvertSetConstantDef(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value) { TypeInfo ti = helper.GetTypeReference(type); FieldAttributes attrs = FieldAttributes.Public | FieldAttributes.Static; if (comp_opt.target == TargetType.Dll) attrs |= FieldAttributes.InitOnly; FieldBuilder fb = cur_type.DefineField(name, ti.tp, attrs); //il.Emit(OpCodes.Newobj, ti.tp.GetConstructor(Type.EmptyTypes)); //il.Emit(OpCodes.Stsfld, fb); if (cnst != null) helper.AddConstant(cnst, fb); bool tmp = save_debug_info; save_debug_info = false; constant_value.visit(this); save_debug_info = tmp; il.Emit(OpCodes.Stsfld, fb); if (!ConvertedConstants.ContainsKey(constant_value)) ConvertedConstants.Add(constant_value, fb); } private void ConvertSimpleConstant(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value) { FieldBuilder fb = cur_type.DefineField(name, helper.GetTypeReference(type).tp, FieldAttributes.Static | FieldAttributes.Public | FieldAttributes.Literal); Type t = helper.GetTypeReference(type).tp; if (t.IsEnum) { if (!(t is EnumBuilder)) fb.SetConstant(Enum.ToObject(t, (constant_value as IEnumConstNode).constant_value)); else fb.SetConstant(constant_value.value); } else if (!(constant_value is INullConstantNode)) { if (constant_value.value.GetType() != t) { } else fb.SetConstant(constant_value.value); } } private void PushConstantValue(IConstantNode cnst) { if (cnst is IIntConstantNode) PushIntConst((cnst as IIntConstantNode).constant_value); else if (cnst is IDoubleConstantNode) PushDoubleConst((cnst as IDoubleConstantNode).constant_value); else if (cnst is IFloatConstantNode) PushFloatConst((cnst as IFloatConstantNode).constant_value); else if (cnst is ICharConstantNode) PushCharConst((cnst as ICharConstantNode).constant_value); else if (cnst is IStringConstantNode) PushStringConst((cnst as IStringConstantNode).constant_value); else if (cnst is IByteConstantNode) PushByteConst((cnst as IByteConstantNode).constant_value); else if (cnst is ILongConstantNode) PushLongConst((cnst as ILongConstantNode).constant_value); else if (cnst is IBoolConstantNode) PushBoolConst((cnst as IBoolConstantNode).constant_value); else if (cnst is ISByteConstantNode) PushSByteConst((cnst as ISByteConstantNode).constant_value); else if (cnst is IUShortConstantNode) PushUShortConst((cnst as IUShortConstantNode).constant_value); else if (cnst is IUIntConstantNode) PushUIntConst((cnst as IUIntConstantNode).constant_value); else if (cnst is IULongConstantNode) PushULongConst((cnst as IULongConstantNode).constant_value); else if (cnst is IShortConstantNode) PushShortConst((cnst as IShortConstantNode).constant_value); else if (cnst is IEnumConstNode) PushIntConst((cnst as IEnumConstNode).constant_value); else if (cnst is INullConstantNode) il.Emit(OpCodes.Ldnull); } private void ConvertConstantDefWithInitCall(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value) { TypeInfo ti = helper.GetTypeReference(type); FieldAttributes attrs = FieldAttributes.Public | FieldAttributes.Static; if (comp_opt.target == TargetType.Dll) attrs |= FieldAttributes.InitOnly; FieldBuilder fb = cur_type.DefineField(name, ti.tp, attrs); if (cnst != null) helper.AddConstant(cnst, fb); bool tmp = save_debug_info; save_debug_info = false; AddInitCall(il, fb, ti.init_meth, constant_value); save_debug_info = tmp; if (!ConvertedConstants.ContainsKey(constant_value)) ConvertedConstants.Add(constant_value, fb); } private void ConvertArrayConstantDef(IConstantDefinitionNode cnst, string name, ITypeNode type, IConstantNode constant_value) { //ConvertedConstants.ContainsKey(ArrayConstant) TypeInfo ti = helper.GetTypeReference(type); FieldAttributes attrs = FieldAttributes.Public | FieldAttributes.Static; if (comp_opt.target == TargetType.Dll) attrs |= FieldAttributes.InitOnly; FieldBuilder fb = cur_type.DefineField(name, ti.tp, attrs); if (cnst != null) helper.AddConstant(cnst, fb); CreateArrayGlobalVariable(il, fb, ti, constant_value as IArrayConstantNode, type); if (!ConvertedConstants.ContainsKey(constant_value)) ConvertedConstants.Add(constant_value, fb); } //это требование Reflection.Emit - все типы должны быть закрыты private void CloseTypes() { //(ssyy) TODO: подумать, в каком порядке создавать типы for (int i = 0; i < types.Count; i++) if (types[i].IsInterface) types[i].CreateType(); for (int i = 0; i < enums.Count; i++) enums[i].CreateType(); for (int i = 0; i < value_types.Count; i++) value_types[i].CreateType(); for (int i = 0; i < types.Count; i++) if (!types[i].IsInterface) types[i].CreateType(); } //перевод тела private void ConvertBody(IStatementNode body) { if (!(body is IStatementsListNode) && save_debug_info && body.Location != null) if (body.Location.begin_line_num == 0xFFFFFF) MarkSequencePoint(il, body.Location); body.visit(this); OptMakeExitLabel(); } private void OptMakeExitLabel() { if (ExitProcedureCall) { il.MarkLabel(ExitLabel); ExitProcedureCall = false; } } //перевод заголовков типов private void ConvertTypeHeaders(ICommonTypeNode[] types) { foreach (ICommonTypeNode t in types) { ConvertTypeHeaderInSpecialOrder(t); } } private void CreateTemplateClass(ITemplateClass t) { if (t.serialized_tree != null) { TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType); types.Add(tb); CustomAttributeBuilder cust_bldr = new CustomAttributeBuilder(this.TemplateClassAttributeConstructor, new object[1] { t.serialized_tree }); tb.SetCustomAttribute(cust_bldr); } } private void CreateTypeSynonim(ITypeSynonym t) { TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType); types.Add(tb); add_possible_type_attribute(tb, t); } private Type CreateTypedFileType(ICommonTypeNode t) { Type tt = helper.GetPascalTypeReference(t); if (tt != null) return tt; TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType); types.Add(tb); helper.AddPascalTypeReference(t, tb); add_possible_type_attribute(tb, t); return tb; } private Type CreateTypedSetType(ICommonTypeNode t) { Type tt = helper.GetPascalTypeReference(t); if (tt != null) return tt; TypeBuilder tb = mb.DefineType(cur_unit + ".%" + t.name, TypeAttributes.Public, TypeFactory.ObjectType); types.Add(tb); helper.AddPascalTypeReference(t, tb); add_possible_type_attribute(tb, t); return tb; } private Type CreateShortStringType(ITypeNode t) { TypeBuilder tb = mb.DefineType(cur_unit + ".$string" + (uid++).ToString(), TypeAttributes.Public, TypeFactory.ObjectType); types.Add(tb); add_possible_type_attribute(tb, t); return tb; } //переводим заголовки типов в порядке начиная с базовых классов (т. е. у которых наследники - откомпилированные типы) private void ConvertTypeHeaderInSpecialOrder(ICommonTypeNode t) { if (t.type_special_kind == type_special_kind.diap_type) return; if (t.type_special_kind == type_special_kind.array_kind) return; if (t.depended_from_indefinite) return; if (t.type_special_kind == type_special_kind.typed_file && comp_opt.target == TargetType.Dll) { if (!t.name.Contains(" ")) { CreateTypedFileType(t); return; } } else if (t.type_special_kind == type_special_kind.set_type && comp_opt.target == TargetType.Dll) { if (!t.name.Contains(" ")) { CreateTypedSetType(t); return; } } if (helper.GetTypeReference(t) != null && !t.is_generic_parameter) return; if (t.is_generic_parameter) { //ConvertTypeHeaderInSpecialOrder(t.generic_container); AddTypeWithoutConvert(t); if (converting_generic_param != t) { return; } converting_generic_param = null; } IGenericTypeInstance gti = t as IGenericTypeInstance; if (gti != null) { if (gti.original_generic is ICommonTypeNode) { ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)gti.original_generic); } foreach (ITypeNode itn in gti.generic_parameters) { if (itn is ICommonTypeNode && !itn.is_generic_parameter) { ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)itn); } } } if (t.is_generic_type_definition) { AddTypeWithoutConvert(t); foreach (ICommonTypeNode par in t.generic_params) { converting_generic_param = par; ConvertTypeHeaderInSpecialOrder(par); } } else if ((t.type_special_kind == type_special_kind.none_kind || t.type_special_kind == type_special_kind.record) && !t.IsEnum && !t.is_generic_type_instance && !t.is_generic_parameter) { AddTypeWithoutConvert(t); } foreach (ITypeNode interf in t.ImplementingInterfaces) if (!(interf is ICompiledTypeNode)) ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)interf); if (t.base_type != null && !(t.base_type is ICompiledTypeNode)) { ConvertTypeHeaderInSpecialOrder((ICommonTypeNode)t.base_type); } ConvertTypeHeader(t); } private void AddTypeWithoutConvert(ICommonTypeNode t) { if (helper.GetTypeReference(t) != null) return; TypeBuilder tb = mb.DefineType(cur_unit + "." + t.name, ConvertAttributes(t), null, new Type[0]); helper.AddType(t, tb); //(ssyy) обрабатываем generics if (t.is_generic_type_definition) { int count = t.generic_params.Count; string[] par_names = new string[count]; //Создаём массив имён параметров for (int i = 0; i < count; i++) { par_names[i] = t.generic_params[i].name; } //Определяем параметры в строящемся типе GenericTypeParameterBuilder[] net_pars = tb.DefineGenericParameters(par_names); for (int i = 0; i < count; i++) { //добавляем параметр во внутр. структуры helper.AddExistingType(t.generic_params[i], net_pars[i]); } } } //перевод релизаций типов private void ConvertTypeImplementations(ICommonTypeNode[] types) { foreach (ICommonTypeNode t in types) //если это не особый тип переводим реализацию наверно здесь много лишнего нужно оставить ISimpleArrayNode { if ( t.type_special_kind != type_special_kind.diap_type && !t.depended_from_indefinite) t.visit(this); } } private void ConvertTypeMemberHeaderAndRemoveFromList(ICommonTypeNode type, List<ICommonTypeNode> types) { if (!type.depended_from_indefinite) { if (type.type_special_kind == type_special_kind.array_wrapper && type.element_type.type_special_kind == type_special_kind.array_wrapper && type.element_type is ICommonTypeNode && types.IndexOf((ICommonTypeNode)(type.element_type)) > -1) { ConvertTypeMemberHeaderAndRemoveFromList((ICommonTypeNode)(type.element_type), types); } ConvertTypeMemberHeader(type); } types.Remove(type); } //перевод заголовков членов класса private void ConvertTypeMemberHeaders(ICommonTypeNode[] types) { //(ssyy) Переупорядочиваем, чтобы массивы создавались в правильном порядке List<ICommonTypeNode> ts = new List<ICommonTypeNode>(types); while (ts.Count > 0) { ConvertTypeMemberHeaderAndRemoveFromList(ts[0], ts); } foreach (ICommonTypeNode t in types) { foreach (ICommonMethodNode meth in t.methods) { if (meth.is_generic_function) { ConvertTypeInstancesMembersInFunction(meth); } } } } private Dictionary<TypeBuilder, TypeBuilder> added_types = new Dictionary<TypeBuilder, TypeBuilder>(); private void BuildCloseTypeOrder(ICommonTypeNode value, TypeBuilder tb) { foreach (ICommonClassFieldNode fld in value.fields) { ITypeNode ctn = fld.type; TypeInfo ti = helper.GetTypeReference(ctn); if (ctn is ICommonTypeNode && ti.tp.IsValueType && ti.tp is TypeBuilder) { BuildCloseTypeOrder((ICommonTypeNode)ctn, (TypeBuilder)ti.tp); } } if (!added_types.ContainsKey(tb)) { value_types.Add(tb); added_types[tb] = tb; } } private Type GetTypeOfGenericInstanceField(Type t, FieldInfo finfo) { if (finfo.FieldType.IsGenericParameter) { return t.GetGenericArguments()[finfo.FieldType.GenericParameterPosition]; } else { return finfo.FieldType; } } private void ConvertGenericInstanceTypeMembers(IGenericTypeInstance value) { if (helper.GetTypeReference(value) == null) { return; } ICompiledGenericTypeInstance compiled_inst = value as ICompiledGenericTypeInstance; if (compiled_inst != null) { ConvertCompiledGenericInstanceTypeMembers(compiled_inst); return; } ICommonGenericTypeInstance common_inst = value as ICommonGenericTypeInstance; if (common_inst != null) { ConvertCommonGenericInstanceTypeMembers(common_inst); return; } } //ssyy 04.02.2010. Вернул следующие 2 функции в исходное состояние. private void ConvertCompiledGenericInstanceTypeMembers(ICompiledGenericTypeInstance value) { Type t = helper.GetTypeReference(value).tp; bool is_delegated_type = t.BaseType == TypeFactory.MulticastDelegateType; foreach (IDefinitionNode dn in value.used_members.Keys) { ICompiledConstructorNode iccn = dn as ICompiledConstructorNode; if (iccn != null) { ConstructorInfo ci = TypeBuilder.GetConstructor(t, iccn.constructor_info); helper.AddConstructor(value.used_members[dn] as IFunctionNode, ci); continue; } ICompiledMethodNode icmn = dn as ICompiledMethodNode; if (icmn != null) { if (is_delegated_type && icmn.method_info.IsSpecialName) continue; MethodInfo mi = null; try { mi = TypeBuilder.GetMethod(t, icmn.method_info); } catch { if (icmn.method_info.DeclaringType.IsGenericType && !icmn.method_info.DeclaringType.IsGenericTypeDefinition) { Type gen_def_type = icmn.method_info.DeclaringType.GetGenericTypeDefinition(); foreach (MethodInfo mi2 in gen_def_type.GetMethods()) { if (mi2.MetadataToken == icmn.method_info.MetadataToken) { mi = mi2; break; } } mi = TypeBuilder.GetMethod(t, mi); } else mi = icmn.method_info; } helper.AddMethod(value.used_members[dn] as IFunctionNode, mi); continue; } ICompiledClassFieldNode icfn = dn as ICompiledClassFieldNode; if (icfn != null) { Type ftype = GetTypeOfGenericInstanceField(t, icfn.compiled_field); FieldInfo fi = TypeBuilder.GetField(t, icfn.compiled_field); helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype); continue; } } } private void ConvertCommonGenericInstanceTypeMembers(ICommonGenericTypeInstance value) { Type t = helper.GetTypeReference(value).tp; foreach (IDefinitionNode dn in value.used_members.Keys) { ICommonMethodNode icmn = dn as ICommonMethodNode; if (icmn != null) { if (icmn.is_constructor) { MethInfo mi = helper.GetConstructor(icmn); if (mi != null) { ConstructorInfo cnstr = mi.cnstr; ConstructorInfo ci = TypeBuilder.GetConstructor(t, cnstr); helper.AddConstructor(value.used_members[dn] as IFunctionNode, ci); } continue; } else { MethodInfo meth = helper.GetMethod(icmn).mi; if (meth.GetType().FullName == "System.Reflection.Emit.MethodOnTypeBuilderInstantiation") meth = meth.GetGenericMethodDefinition(); MethodInfo mi = TypeBuilder.GetMethod(t, meth); helper.AddMethod(value.used_members[dn] as IFunctionNode, mi); continue; } } ICommonClassFieldNode icfn = dn as ICommonClassFieldNode; if (icfn != null) { FldInfo fldinfo = helper.GetField(icfn); if (!(fldinfo is GenericFldInfo)) { FieldInfo finfo = fldinfo.fi; Type ftype = GetTypeOfGenericInstanceField(t, finfo); FieldInfo fi = TypeBuilder.GetField(t, finfo); helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, ftype); } else { FieldInfo finfo = fldinfo.fi; FieldInfo fi = finfo; helper.AddGenericField(value.used_members[dn] as ICommonClassFieldNode, fi, (fldinfo as GenericFldInfo).field_type); } continue; } } } private object[] get_constants(IConstantNode[] cnsts) { object[] objs = new object[cnsts.Length]; for (int i = 0; i < objs.Length; i++) { objs[i] = cnsts[i].value; } return objs; } private PropertyInfo[] get_named_properties(IPropertyNode[] props) { PropertyInfo[] arr = new PropertyInfo[props.Length]; for (int i = 0; i < arr.Length; i++) { if (props[i] is ICompiledPropertyNode) arr[i] = (props[i] as ICompiledPropertyNode).property_info; else arr[i] = helper.GetProperty(props[i]).prop; } return arr; } private FieldInfo[] get_named_fields(IVAriableDefinitionNode[] fields) { FieldInfo[] arr = new FieldInfo[fields.Length]; for (int i = 0; i < arr.Length; i++) { if (fields[i] is ICompiledClassFieldNode) arr[i] = (fields[i] as ICompiledClassFieldNode).compiled_field; else arr[i] = helper.GetField(fields[i] as ICommonClassFieldNode).fi; } return arr; } private void MakeAttribute(ICommonNamespaceNode cnn) { IAttributeNode[] attrs = cnn.Attributes; for (int i = 0; i < attrs.Length; i++) { CustomAttributeBuilder cab = new CustomAttributeBuilder ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments), get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers), get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers)); ab.SetCustomAttribute(cab); } } private void MakeAttribute(ICommonTypeNode ctn) { Type t = helper.GetTypeReference(ctn).tp; IAttributeNode[] attrs = ctn.Attributes; for (int i = 0; i < attrs.Length; i++) { //if (attrs[i].AttributeType == SystemLibrary.SystemLibrary.comimport_type) // continue; CustomAttributeBuilder cab = new CustomAttributeBuilder ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments), get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers), get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers)); if (t is TypeBuilder) (t as TypeBuilder).SetCustomAttribute(cab); else if (t is EnumBuilder) (t as EnumBuilder).SetCustomAttribute(cab); } } private void MakeAttribute(ICommonPropertyNode prop) { PropertyBuilder pb = (PropertyBuilder)helper.GetProperty(prop).prop; IAttributeNode[] attrs = prop.Attributes; for (int i = 0; i < attrs.Length; i++) { CustomAttributeBuilder cab = new CustomAttributeBuilder ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments), get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers), get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers)); pb.SetCustomAttribute(cab); } } private void MakeAttribute(ICommonClassFieldNode fld) { FieldBuilder fb = (FieldBuilder)helper.GetField(fld).fi; IAttributeNode[] attrs = fld.Attributes; for (int i = 0; i < attrs.Length; i++) { CustomAttributeBuilder cab = new CustomAttributeBuilder ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments), get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers), get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers)); fb.SetCustomAttribute(cab); } } private void MakeAttribute(ICommonFunctionNode func) { MethodBuilder mb = helper.GetMethod(func).mi as MethodBuilder; IAttributeNode[] attrs = func.Attributes; for (int i = 0; i < attrs.Length; i++) { CustomAttributeBuilder cab = new CustomAttributeBuilder ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments), get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers), get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers)); mb.SetCustomAttribute(cab); } foreach (IParameterNode pn in func.parameters) { ParamInfo pi = helper.GetParameter(pn); if (pi == null) continue; ParameterBuilder pb = pi.pb; attrs = pn.Attributes; for (int i = 0; i < attrs.Length; i++) { CustomAttributeBuilder cab = new CustomAttributeBuilder ((attrs[i].AttributeConstructor is ICompiledConstructorNode) ? (attrs[i].AttributeConstructor as ICompiledConstructorNode).constructor_info : helper.GetConstructor(attrs[i].AttributeConstructor).cnstr, get_constants(attrs[i].Arguments), get_named_properties(attrs[i].PropertyNames), get_constants(attrs[i].PropertyInitializers), get_named_fields(attrs[i].FieldNames), get_constants(attrs[i].FieldInitializers)); pb.SetCustomAttribute(cab); } } } //определяем заголовки членов класса private void ConvertTypeMemberHeader(ICommonTypeNode value) { //если это оболочка над массивом переводим ее особым образом if (value.type_special_kind == type_special_kind.diap_type || value.type_special_kind == type_special_kind.array_kind) return; if (value.fields.Length == 1 && value.fields[0].type is ISimpleArrayNode) { ConvertArrayWrapperType(value); return; } if (value is ISimpleArrayNode) return; //этот тип уже был переведен, поэтому находим его TypeInfo ti = helper.GetTypeReference(value); //ivan if (ti.tp.IsEnum || !(ti.tp is TypeBuilder)) return; TypeBuilder tb = (TypeBuilder)ti.tp; if (tb.IsValueType) BuildCloseTypeOrder(value, tb); //сохраняем контекст TypeInfo tmp_ti = cur_ti; cur_ti = ti; TypeBuilder tmp = cur_type; cur_type = tb; //(ssyy) Если это интерфейс, то пропускаем следующую хрень if (!value.IsInterface) { //определяем метод $Init$ для выделения памяти, если метод еще не определен (в структурах он опред-ся раньше) MethodBuilder clone_mb = null; MethodBuilder ass_mb = null; if (ti.init_meth != null && tb.IsValueType) { clone_mb = ti.clone_meth as MethodBuilder; ass_mb = ti.assign_meth as MethodBuilder; } foreach (ICommonClassFieldNode fld in value.fields) fld.visit(this); foreach (ICommonMethodNode meth in value.methods) ConvertMethodHeader(meth); foreach (ICommonPropertyNode prop in value.properties) prop.visit(this); foreach (IClassConstantDefinitionNode constant in value.constants) constant.visit(this); foreach (ICommonEventNode evnt in value.events) evnt.visit(this); //(ssyy) 21.05.2008 /*foreach (ICommonMethodNode meth in value.methods) { if (meth.is_generic_function) { ConvertTypeInstancesMembersInFunction(meth); } }*/ //добавляем ритерны в специальные методы //ti.init_meth.GetILGenerator().Emit(OpCodes.Ret); //if (hndl_mb != null) hndl_mb.GetILGenerator().Emit(OpCodes.Ret); if (clone_mb != null) { clone_mb.GetILGenerator().Emit(OpCodes.Ldloc_0); clone_mb.GetILGenerator().Emit(OpCodes.Ret); } if (ass_mb != null) { ass_mb.GetILGenerator().Emit(OpCodes.Ret); } if (ti.fix_meth != null) { ti.fix_meth.GetILGenerator().Emit(OpCodes.Ret); } }
internal Assembly Generate() { if (module.GetType(typeName) != null) return module.Assembly; String ifaceName = typeName.Replace("Mozilla.XPCOM.Interfaces.", ""); TypeInfo.MethodDescriptor[] descs = TypeInfo.GetMethodData(ifaceName); ushort inheritedMethodCount; String parentName = TypeInfo.GetParentInfo(ifaceName, out inheritedMethodCount); Type parentType; if (parentName != null) { parentName = "Mozilla.XPCOM.Interfaces." + parentName; parentType = module.Assembly.GetType(parentName); if (parentType == null) { InterfaceGenerator gen = new InterfaceGenerator(parentName); parentType = gen.Generate().GetType(parentName); } } else { parentType = typeof(object); } tb = module.DefineType(typeName, TypeAttributes.Public | TypeAttributes.Interface, parentType); for (int i = inheritedMethodCount; i < descs.Length; i++) { if (descs[i] != null) GenerateInterfaceMethod(descs[i]); } tb.CreateType(); return module.Assembly; }
internal ModuleBuilder (AssemblyBuilder assb, string name, string fullyqname, bool emitSymbolInfo, bool transient) { this.name = this.scopename = name; this.fqname = fullyqname; this.assembly = this.assemblyb = assb; this.transient = transient; // to keep mcs fast we do not want CryptoConfig wo be involved to create the RNG guid = Guid.FastNewGuidArray (); // guid = Guid.NewGuid().ToByteArray (); table_idx = get_next_table_index (this, 0x00, true); name_cache = new Hashtable (); us_string_cache = new Dictionary<string, int> (512); basic_init (this); CreateGlobalType (); if (assb.IsRun) { TypeBuilder tb = new TypeBuilder (this, TypeAttributes.Abstract, 0xFFFFFF); /*last valid token*/ Type type = tb.CreateType (); set_wrappers_type (this, type); } if (emitSymbolInfo) { #if MOONLIGHT symbolWriter = new Mono.CompilerServices.SymbolWriter.SymbolWriterImpl (this); #else Assembly asm = Assembly.LoadWithPartialName ("Mono.CompilerServices.SymbolWriter"); if (asm == null) throw new TypeLoadException ("The assembly for default symbol writer cannot be loaded"); Type t = asm.GetType ("Mono.CompilerServices.SymbolWriter.SymbolWriterImpl", true); symbolWriter = (ISymbolWriter) Activator.CreateInstance (t, new object[] { this }); #endif string fileName = fqname; if (assemblyb.AssemblyDir != null) fileName = Path.Combine (assemblyb.AssemblyDir, fileName); symbolWriter.Initialize (IntPtr.Zero, fileName, true); } }
public override AstNode VisitClassDecl(ClassDecl ast) { m_currentType = GetClrType(ast.Type) as TypeBuilder; foreach (var method in ast.Methods) { Visit(method); } GetClrCtor(ast.Type); m_currentType.CreateType(); return ast; }
public override Type GetType(string className, bool throwOnError, bool ignoreCase) { if (className == null) { throw new ArgumentNullException("className"); } if (className.Length == 0) { throw new ArgumentException("className"); } int subt; string orig = className; string modifiers; TypeBuilder result = null; if (types == null && throwOnError) { throw new TypeLoadException(className); } subt = className.IndexOfAny(type_modifiers); if (subt >= 0) { modifiers = className.Substring(subt); className = className.Substring(0, subt); } else { modifiers = null; } if (!ignoreCase) { result = name_cache [className] as TypeBuilder; } else { subt = className.IndexOf('+'); if (subt < 0) { if (types != null) { result = search_in_array(types, num_types, className); } } else { string pname, rname; pname = className.Substring(0, subt); rname = className.Substring(subt + 1); result = search_in_array(types, num_types, pname); if (result != null) { result = GetMaybeNested(result, rname); } } } if ((result == null) && throwOnError) { throw new TypeLoadException(orig); } if (result != null && (modifiers != null)) { Type mt = create_modified_type(result, modifiers); result = mt as TypeBuilder; if (result == null) { return(mt); } } if (result != null && result.is_created) { return(result.CreateType()); } else { return(result); } }
public Type CreateActorType(Type actorType) { Type implType = null; lock (constructedTypesCache) { if (constructedTypesCache.TryGetValue(actorType, out implType)) return implType; } templateType = typeof(ActorServerProxyTemplate<>).MakeGenericType(new[] { actorType }); this.actorType = actorType; actorImplBuilder = moduleBuilder.DefineType("Impl$" + actorType.Name, TypeAttributes.Public, templateType, Type.EmptyTypes); { var baseCtor = templateType.GetConstructor(new[] { actorType, typeof(IPEndPoint), typeof(ActorServerProxyOptions) }); var ctorBuilder = actorImplBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName, CallingConventions.HasThis, new[] { actorType, typeof(IPEndPoint), typeof(ActorServerProxyOptions) }); var ctIl = ctorBuilder.GetILGenerator(); EmitCallBaseCtor(ctIl, baseCtor); foreach (var miMapping in actorType.FindValidProxyMethods(onlyPublic: false)) { EmitSetHandlerForMethod(miMapping, ctIl); } foreach (var property in actorType.FindValidObservableProperties(onlyPublic: false)) { var newMethod = CreateObservableItemHandler(property.PublicName, property.InterfaceInfo.PropertyType); var errMethod = CreateObservableErrorHandler(property.PublicName); var innerPropType = property.InterfaceInfo.PropertyType.GetGenericArguments()[0]; var actionType = typeof(Action<>).MakeGenericType(new[] { innerPropType }); var errorActionType = typeof(Action<>).MakeGenericType(new[] { typeof(Exception) }); var obsMethod = EmitObservableSubscribeMethod(innerPropType); ctIl.Emit(OpCodes.Ldarg_0); ctIl.Emit(OpCodes.Ldfld, templateType.GetField("actorImplementation", BindingFlags.Instance | BindingFlags.NonPublic)); ctIl.EmitCall(OpCodes.Callvirt, property.InterfaceInfo.GetGetMethod(true), null); ctIl.Emit(OpCodes.Ldarg_0); ctIl.Emit(OpCodes.Ldftn, newMethod); ctIl.Emit(OpCodes.Newobj, actionType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); ctIl.Emit(OpCodes.Ldarg_0); ctIl.Emit(OpCodes.Ldftn, errMethod); ctIl.Emit(OpCodes.Newobj, errorActionType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); ctIl.EmitCall(OpCodes.Call, obsMethod, null); ctIl.Emit(OpCodes.Pop); } foreach (var method in actorType.FindValidObservableMethods(onlyPublic: false)) { var iInfo = method.InterfaceInfo; var newMethod = CreateObservableItemHandler(method.PublicName, iInfo.ReturnType); var errMethod = CreateObservableErrorHandler(method.PublicName); var innerPropType = iInfo.ReturnType.GetGenericArguments()[0]; var actionType = typeof(Action<>).MakeGenericType(new[] { innerPropType }); var errorActionType = typeof(Action<>).MakeGenericType(new[] { typeof(Exception) }); var obsMethod = EmitObservableSubscribeMethod(innerPropType); ctIl.Emit(OpCodes.Ldarg_0); ctIl.Emit(OpCodes.Ldfld, templateType.GetField("actorImplementation", BindingFlags.Instance | BindingFlags.NonPublic)); ctIl.EmitCall(OpCodes.Callvirt, iInfo, null); ctIl.Emit(OpCodes.Ldarg_0); ctIl.Emit(OpCodes.Ldftn, newMethod); ctIl.Emit(OpCodes.Newobj, actionType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); ctIl.Emit(OpCodes.Ldarg_0); ctIl.Emit(OpCodes.Ldftn, errMethod); ctIl.Emit(OpCodes.Newobj, errorActionType.GetConstructor(new[] { typeof(object), typeof(IntPtr) })); ctIl.EmitCall(OpCodes.Call, obsMethod, null); ctIl.Emit(OpCodes.Pop); } ctIl.Emit(OpCodes.Ret); } implType = actorImplBuilder.CreateType(); lock (constructedTypesCache) { constructedTypesCache[actorType] = implType; } return implType; }
// This code works with .NET 4.0+ but will throw an exception if .NET 2.0 is used // ("operation could destabilize the runtime") static Type GetTypeNET40(TypeBuilder tb, MethodBuilder mb, IntPtr address) { var ilg = mb.GetILGenerator(); ilg.Emit(SR.Emit.OpCodes.Ret); // We need at least one local to make sure the SignatureHelper from ILGenerator is used. ilg.DeclareLocal(typeof(int)); var locals = GetLocalSignature(address); var sigHelper = (SignatureHelper)localSignatureFieldInfo.GetValue(ilg); sigDoneFieldInfo.SetValue(sigHelper, true); currSigFieldInfo.SetValue(sigHelper, locals.Length); signatureFieldInfo.SetValue(sigHelper, locals); var createdMethod = tb.CreateType().GetMethod(METHOD_NAME, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance); return createdMethod.GetMethodBody().LocalVariables[0].LocalType; }
public Type CreateType() { Type res = _tb.CreateType(); return(res); }
public override AstNode VisitMainClass(MainClass ast) { m_currentType = m_module.DefineType(ast.Type.Name, TypeAttributes.Class | TypeAttributes.Abstract | TypeAttributes.Sealed); m_currentMethod = m_currentType.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new[] { typeof(string[]) }); m_ilgen = m_currentMethod.GetILGenerator(); foreach (var s in ast.Statements) { Visit(s); } m_ilgen.Emit(OpCodes.Ret); m_currentType.CreateType(); m_mainMethod = m_currentMethod; return ast; }
public Type?CreateType() { return(_tb.CreateType()); }
internal override void Seal(TypeDescription existing = null) { if (PocoType != null || TypeBuilder != null) return; var name = "POCO" + Guid.NewGuid().ToString().Replace("-", ""); var protoMemberAttr = typeof(ProtoMemberAttribute).GetConstructor(new[] { typeof(int) }); var protoContractAttr = typeof(ProtoContractAttribute).GetConstructor(new Type[0]); var fields = new Dictionary<string, FieldInfo>(); TypeBuilder = ModuleBuilder.DefineType(name, TypeAttributes.Public, typeof(DynamicObject), new [] { typeof(IEnumerable) }); var ix = 1; foreach (var kv in Members.OrderBy(o => o.Key, StringComparer.Ordinal)) { var memberAttrBuilder = new CustomAttributeBuilder(protoMemberAttr, new object[] { ix }); kv.Value.Seal(existing); var propType = kv.Value.GetPocoType(existing); var field = TypeBuilder.DefineField(kv.Key, propType, FieldAttributes.Public); field.SetCustomAttribute(memberAttrBuilder); fields[kv.Key] = field; ix++; } var contractAttrBuilder = new CustomAttributeBuilder(protoContractAttr, new object[0]); TypeBuilder.SetCustomAttribute(contractAttrBuilder); // Define indexer var strEq = typeof(string).GetMethod("Equals", new[] { typeof(string) }); var tryGetIndex = TypeBuilder.DefineMethod("TryGetIndex", MethodAttributes.Public | MethodAttributes.Virtual, typeof(bool), new[] { typeof(GetIndexBinder), typeof(object[]), Type.GetType("System.Object&") }); var il = tryGetIndex.GetILGenerator(); il.Emit(OpCodes.Ldarg_2); // object[] var invalid = il.DefineLabel(); il.Emit(OpCodes.Dup); // object[] object[] il.Emit(OpCodes.Ldlen); // length object[] il.Emit(OpCodes.Ldc_I4_1); // 1 length object[] il.Emit(OpCodes.Bne_Un_S, invalid); // object[] il.Emit(OpCodes.Ldc_I4_0); // 0 object[] il.Emit(OpCodes.Ldelem_Ref); // object il.Emit(OpCodes.Isinst, typeof(string));// bool var valid = il.DefineLabel(); il.Emit(OpCodes.Brtrue_S, valid); // ---- il.Emit(OpCodes.Ldc_I4_0); // 0 il.MarkLabel(invalid); // (object[] or 0) il.Emit(OpCodes.Pop); // ---- il.Emit(OpCodes.Ldarg_3); // (out object) il.Emit(OpCodes.Ldnull); // null (out object); il.Emit(OpCodes.Stind_Ref); // ---- il.Emit(OpCodes.Ldc_I4_0); // 0 il.Emit(OpCodes.Ret); il.MarkLabel(valid); il.Emit(OpCodes.Ldarg_3); // (out object) il.Emit(OpCodes.Ldarg_2); // object[] (out object) il.Emit(OpCodes.Ldc_I4_0); // 0 object[] (out object) il.Emit(OpCodes.Ldelem_Ref); // key (out object) Label next; var done = il.DefineLabel(); foreach (var mem in Members) { next = il.DefineLabel(); var memKey = mem.Key; var field = fields[memKey]; il.Emit(OpCodes.Dup); // key key (out object) il.Emit(OpCodes.Ldstr, memKey); // memKey key key (out object) il.Emit(OpCodes.Callvirt, strEq); // bool key (out object) il.Emit(OpCodes.Brfalse_S, next); // key (out object) il.Emit(OpCodes.Pop); // (out object) il.Emit(OpCodes.Ldarg_0); // this (out object) il.Emit(OpCodes.Ldfld, field); // ret (out object) if (field.FieldType.IsValueType) { il.Emit(OpCodes.Box, field.FieldType); // ret (out object); } il.Emit(OpCodes.Br, done); // ret (out object); il.MarkLabel(next); // key (out object); } il.Emit(OpCodes.Pop); // (out object) il.Emit(OpCodes.Ldnull); // null (out object) il.MarkLabel(done); // ret (out object); il.Emit(OpCodes.Stind_Ref); // ---- il.Emit(OpCodes.Ldc_I4_1); // 1 il.Emit(OpCodes.Ret); // ---- TypeBuilder.DefineMethodOverride(tryGetIndex, typeof(DynamicObject).GetMethod("TryGetIndex")); // Implement IEnumerable var getEnumerator = TypeBuilder.DefineMethod("GetEnumerator", MethodAttributes.Public | MethodAttributes.Virtual, typeof(IEnumerator), Type.EmptyTypes); il = getEnumerator.GetILGenerator(); var newStrList = typeof(List<string>).GetConstructor(new[] { typeof(int) }); var newEnumerator = Enumerator.GetConstructor(new[] { typeof(List<string>), typeof(object) }); var add = typeof(List<string>).GetMethod("Add"); il.Emit(OpCodes.Ldc_I4, Members.Count); // [count] il.Emit(OpCodes.Newobj, newStrList); // [mems] foreach (var mem in Members) { il.Emit(OpCodes.Dup); // [mems] [mems] il.Emit(OpCodes.Ldstr, mem.Key); // [key] [mems] [mems] il.Emit(OpCodes.Call, add); // [mems] } il.Emit(OpCodes.Ldarg_0); // [this] [mems] il.Emit(OpCodes.Newobj, newEnumerator); // [ret] il.Emit(OpCodes.Ret); // ----- TypeBuilder.DefineMethodOverride(getEnumerator, typeof(IEnumerable).GetMethod("GetEnumerator")); // Define ToString() var toString = TypeBuilder.DefineMethod("ToString", MethodAttributes.Public | MethodAttributes.Virtual, typeof(string), Type.EmptyTypes); var objToString = typeof(object).GetMethod("ToString"); var thunkField = TypeBuilder.DefineField("__ToStringThunk", typeof(Func<object, string>), FieldAttributes.Static | FieldAttributes.Private); var invoke = typeof(Func<object, string>).GetMethod("Invoke"); il = toString.GetILGenerator(); il.Emit(OpCodes.Ldsfld, thunkField); // [Func<object, string>] il.Emit(OpCodes.Ldarg_0); // [this] [Func<object, string>] il.Emit(OpCodes.Callvirt, invoke); // [string] il.Emit(OpCodes.Ret); // ----- TypeBuilder.DefineMethodOverride(toString, objToString); PocoType = TypeBuilder.CreateType(); // Set the ToStringCallback var firstInst = PocoType.GetConstructor(Type.EmptyTypes).Invoke(new object[0]); var setThunk = firstInst.GetType().GetField("__ToStringThunk", BindingFlags.NonPublic | BindingFlags.Static); setThunk.SetValue(firstInst, ToStringFunc); }
static Type BuildMemoryManagementType(TypeBuilder typeBuilder, Type memMgmtType, string dllName) { foreach (MethodInfo method in memMgmtType.GetMethods(BindingFlags.Public | BindingFlags.Instance)) { ParameterInfo[] paramInfos = method.GetParameters(); Type[] parameterTypes = new Type[paramInfos.Length]; for (int i = 0; i < paramInfos.Length; i++) { parameterTypes[i] = paramInfos[i].ParameterType; } ParameterInfo returnParamInfo = method.ReturnParameter; MethodBuilder methodBuilder = typeBuilder.DefinePInvokeMethod( method.Name, dllName, MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl, CallingConventions.Standard, returnParamInfo.ParameterType, parameterTypes, callingConvention, charset); methodBuilder.SetImplementationFlags(MethodImplAttributes.PreserveSig); } return typeBuilder.CreateType(); }
/// <summary> /// Creates an instance of the type itself and returns it. Cool!! /// </summary> /// <param name="tb">The <see cref="TypeBuilder"/> that we created our type with.</param> /// <returns>An instance of our type, cast as an <see cref="IFbClient"/>.</returns> private static IFbClient CreateInstance(TypeBuilder tb) { Type t = tb.CreateType(); #if (DEBUG) // In debug mode, we'll save the assembly out to disk, so we can look at it in Reflector. AssemblyBuilder ab = (AssemblyBuilder) tb.Assembly; ab.Save("DynamicAssembly.dll"); #endif // Create an instance of the type and return it. return (IFbClient) Activator.CreateInstance(t); }
//Метод, переводящий семантическое дерево в сборку .NET public void ConvertFromTree(SemanticTree.IProgramNode p, string TargetFileName, string SourceFileName, CompilerOptions options, string[] ResourceFiles) { //SystemLibrary.SystemLibInitializer.RestoreStandardFunctions(); bool RunOnly = false; string fname = TargetFileName; comp_opt = options; ad = Thread.GetDomain(); //получаем домен приложения //ad = ad.DomainManager.CreateDomain("D1", null, null); an = new AssemblyName(); //создаем имя сборки an.Version = new Version("1.0.0.0"); string dir = Directory.GetCurrentDirectory(); string source_name = fname;//p.Location.document.file_name; int pos = source_name.LastIndexOf(Path.DirectorySeparatorChar); if (pos != -1) //если имя файла указано с путем, то выделяем { dir = source_name.Substring(0, pos + 1); an.CodeBase = String.Concat("file:///", source_name.Substring(0, pos)); source_name = source_name.Substring(pos + 1); } string name = source_name.Substring(0, source_name.LastIndexOf('.')); if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe) an.Name = name;// + ".exe"; else an.Name = name; //+ ".dll"; if (name == "PABCRtl" || name == "PABCRtl32") { an.Flags = AssemblyNameFlags.PublicKey; an.VersionCompatibility = System.Configuration.Assemblies.AssemblyVersionCompatibility.SameProcess; an.HashAlgorithm = System.Configuration.Assemblies.AssemblyHashAlgorithm.None; FileStream publicKeyStream = File.Open(Path.Combine(Path.GetDirectoryName(TargetFileName), name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk"), FileMode.Open); byte[] publicKey = new byte[publicKeyStream.Length]; publicKeyStream.Read(publicKey, 0, (int)publicKeyStream.Length); // Provide the assembly with a public key. an.SetPublicKey(publicKey); publicKeyStream.Close(); } if (RunOnly) ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run, dir);//определяем сборку else ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save, dir);//определяем сборку //int nn = ad.GetAssemblies().Length; if (options.NeedDefineVersionInfo) { ab.DefineVersionInfoResource(options.Product, options.ProductVersion, options.Company, options.Copyright, options.TradeMark); } if (options.MainResourceFileName != null) { try { ab.DefineUnmanagedResource(options.MainResourceFileName); } catch { throw new TreeConverter.SourceFileError(options.MainResourceFileName); } } else if (options.MainResourceData != null) { try { ab.DefineUnmanagedResource(options.MainResourceData); } catch { throw new TreeConverter.SourceFileError(""); } } save_debug_info = comp_opt.dbg_attrs == DebugAttributes.Debug || comp_opt.dbg_attrs == DebugAttributes.ForDebbuging; add_special_debug_variables = comp_opt.dbg_attrs == DebugAttributes.ForDebbuging; //bool emit_sym = true; if (save_debug_info) //если модуль отладочный, то устанавливаем атрибут, запрещающий inline методов ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x01, 0x01, 0x00, 0x00 }); //ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00 }); //else // ab.SetCustomAttribute(typeof(System.Diagnostics.DebuggableAttribute).GetConstructor(new Type[] { typeof(bool), typeof(bool) }), new byte[] { 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 }); if (RunOnly) mb = ab.DefineDynamicModule(name, save_debug_info); else { if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe) mb = ab.DefineDynamicModule(name + ".exe", an.Name + ".exe", save_debug_info); //определяем модуль (save_debug_info - флаг включать отладочную информацию) else mb = ab.DefineDynamicModule(name + ".dll", an.Name + ".dll", save_debug_info); } cur_unit = Path.GetFileNameWithoutExtension(SourceFileName); string entry_cur_unit = cur_unit; entry_type = mb.DefineType(cur_unit + ".Program", TypeAttributes.Public);//определяем синтетический статический класс основной программы cur_type = entry_type; //точка входа в приложение if (p.main_function != null) { ConvertFunctionHeader(p.main_function); entry_meth = helper.GetMethod(p.main_function).mi as MethodBuilder; /*entry_meth = entry_type.DefineMethod(p.main_function.name, MethodAttributes.Public | MethodAttributes.Static, typeof(void), GetParamTypes(p.main_function)); for (int i = 0; i < p.main_function.parameters.Length; i++) { if (p.main_function.parameters[i].parameter_type == parameter_type.var) entry_meth.DefineParameter(i + 1, ParameterAttributes.Retval, p.main_function.parameters[i].name); else entry_meth.DefineParameter(i + 1, ParameterAttributes.None, p.main_function.parameters[i].name); }*/ cur_meth = entry_meth; il = cur_meth.GetILGenerator(); if (options.target != TargetType.Dll && options.dbg_attrs == DebugAttributes.ForDebbuging) AddSpecialInitDebugCode(); } ILGenerator tmp_il = il; MethodBuilder tmp_meth = cur_meth; //при отладке компилятора здесь иногда ничего нет! ICommonNamespaceNode[] cnns = p.namespaces; //создаем отладочные документы if (save_debug_info) { first_doc = mb.DefineDocument(SourceFileName, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft); for (int iii = 0; iii < cnns.Length; iii++) { if (cnns[iii].Location != null) doc = mb.DefineDocument(cnns[iii].Location.document.file_name, SymDocumentType.Text, SymLanguageType.Pascal, SymLanguageVendor.Microsoft); else doc = first_doc; sym_docs.Add(cnns[iii], doc);//сохраняем его в таблице документов } first_doc = sym_docs[cnns[0]]; if (p.main_function != null) { if (p.main_function.function_code is IStatementsListNode) EntryPointLocation = ((IStatementsListNode)p.main_function.function_code).LeftLogicalBracketLocation; else EntryPointLocation = p.main_function.function_code.Location; } else EntryPointLocation = null; } ICommonNamespaceNode entry_ns = null; //Переводим заголовки типов for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii]]; bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == ""; ICommonNamespaceNode cnn = cnns[iii]; cur_type = entry_type; if (!is_main_namespace) cur_unit = cnn.namespace_name; else cur_unit = entry_cur_unit; if (iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && iii == cnns.Length - 1) entry_ns = cnn; ConvertTypeHeaders(cnn.types); } //Переводим псевдоинстанции generic-типов foreach (ICommonTypeNode ictn in p.generic_type_instances) { ConvertTypeHeaderInSpecialOrder(ictn); } Dictionary<ICommonNamespaceNode, TypeBuilder> NamespacesTypes = new Dictionary<ICommonNamespaceNode, TypeBuilder>(); for (int iii = 0; iii < cnns.Length; iii++) { bool is_main_namespace = cnns[iii].namespace_name == "" && comp_opt.target != TargetType.Dll || comp_opt.target == TargetType.Dll && cnns[iii].namespace_name == ""; if (!is_main_namespace) { //определяем синтетический класс для модуля cur_type = mb.DefineType(cnns[iii].namespace_name + "." + cnns[iii].namespace_name, TypeAttributes.Public); types.Add(cur_type); NamespaceTypesList.Add(cur_type); NamespacesTypes.Add(cnns[iii], cur_type); if (cnns[iii].IsMain) { TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$GlobAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute)); ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public); cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 }); attr_class.CreateType(); } else { TypeBuilder attr_class = mb.DefineType(cnns[iii].namespace_name + "." + "$ClassUnitAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute)); ConstructorInfo attr_ci = attr_class.DefineDefaultConstructor(MethodAttributes.Public); cur_type.SetCustomAttribute(attr_ci, new byte[4] { 0x01, 0x00, 0x00, 0x00 }); attr_class.CreateType(); } } else { NamespacesTypes.Add(cnns[iii], entry_type); } } if (comp_opt.target == TargetType.Dll) { for (int iii = 0; iii < cnns.Length; iii++) { string tmp = cur_unit; if (cnns[iii].namespace_name != "") cur_unit = cnns[iii].namespace_name; else cur_unit = entry_cur_unit; foreach (ITemplateClass tc in cnns[iii].templates) { CreateTemplateClass(tc); } cur_unit = tmp; } for (int iii = 0; iii < cnns.Length; iii++) { string tmp = cur_unit; if (cnns[iii].namespace_name != "") cur_unit = cnns[iii].namespace_name; else cur_unit = entry_cur_unit; foreach (ITypeSynonym ts in cnns[iii].type_synonims) { CreateTypeSynonim(ts); } cur_unit = tmp; } } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii]]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; ConvertTypeMemberHeaders(cnns[iii].types); // cur_type = NamespacesTypes[cnns[iii]]; // cur_unit_type = NamespacesTypes[cnns[iii]]; // ConvertFunctionHeaders(cnns[iii].functions); } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii]]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; ConvertFunctionHeaders(cnns[iii].functions); } if (p.InitializationCode != null) { tmp_il = il; if (entry_meth != null) { il = entry_meth.GetILGenerator(); ConvertStatement(p.InitializationCode); } else { //il = unit_cci.GetILGenerator(); //ConvertStatement(p.InitializationCode); } il = tmp_il; } //Переводим псевдоинстанции generic-типов foreach (IGenericTypeInstance ictn in p.generic_type_instances) { ConvertGenericInstanceTypeMembers(ictn); } //Переводим псевдоинстанции функций foreach (IGenericFunctionInstance igfi in p.generic_function_instances) { ConvertGenericFunctionInstance(igfi); } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii]]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; //генерим инциализацию для полей foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types) GenerateInitCodeForFields(ctn); } ConstructorBuilder unit_cci = null; //Переводим заголовки всего остального (процедур, переменных) for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii]]; bool is_main_namespace = iii == cnns.Length - 1 && comp_opt.target != TargetType.Dll; ICommonNamespaceNode cnn = cnns[iii]; string tmp_unit_name = cur_unit; if (!is_main_namespace) cur_unit = cnn.namespace_name; else cur_unit = entry_cur_unit; cur_type = NamespacesTypes[cnn]; //ConvertFunctionHeaders(cnn.functions); if (!is_main_namespace) { //определяем статический конструктор класса для модуля ConstructorBuilder cb = cur_type.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes); il = cb.GetILGenerator(); if (cnn.IsMain) unit_cci = cb; ModulesInitILGenerators.Add(cur_type, il); //переводим глобальные переменные модуля ConvertGlobalVariables(cnn.variables); //перводим константы ConvertNamespaceConstants(cnn.constants); ConvertNamespaceEvents(cnn.events); //il.Emit(OpCodes.Ret); } else { //Не нарвится мне порядок вызова. надо с этим разобраться init_variables_mb = helper.GetMethodBuilder(cnn.functions[cnn.functions.Length-1]);// cur_type.DefineMethod("$InitVariables", MethodAttributes.Public | MethodAttributes.Static); il = entry_meth.GetILGenerator(); ModulesInitILGenerators.Add(cur_type, il); il = init_variables_mb.GetILGenerator(); ConvertGlobalVariables(cnn.variables); il = entry_meth.GetILGenerator(); //перводим константы ConvertNamespaceConstants(cnn.constants); ConvertNamespaceEvents(cnn.events); //il.Emit(OpCodes.Ret); } cur_unit = tmp_unit_name; } if (p.InitializationCode != null) { tmp_il = il; if (entry_meth == null) { il = unit_cci.GetILGenerator(); ConvertStatement(p.InitializationCode); } il = tmp_il; } cur_type = entry_type; //is_in_unit = false; //переводим реализации for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii]]; bool is_main_namespace = iii == 0 && comp_opt.target != TargetType.Dll; ICommonNamespaceNode cnn = cnns[iii]; string tmp_unit_name = cur_unit; if (!is_main_namespace) cur_unit = cnn.namespace_name; //if (iii > 0) is_in_unit = true; cur_unit_type = NamespacesTypes[cnns[iii]]; cur_type = cur_unit_type; ConvertTypeImplementations(cnn.types); ConvertFunctionsBodies(cnn.functions); cur_unit = tmp_unit_name; } if (comp_opt.target != TargetType.Dll && p.main_function != null) { cur_unit_type = NamespacesTypes[cnns[0]]; cur_type = cur_unit_type; ConvertBody(p.main_function.function_code); } for (int iii = 0; iii < cnns.Length; iii++) { if (save_debug_info) doc = sym_docs[cnns[iii]]; cur_type = NamespacesTypes[cnns[iii]]; cur_unit_type = NamespacesTypes[cnns[iii]]; //вставляем ret в int_meth foreach (SemanticTree.ICommonTypeNode ctn in cnns[iii].types) GenerateRetForInitMeth(ctn); ModulesInitILGenerators[cur_type].Emit(OpCodes.Ret); } for (int iii = 0; iii < cnns.Length; iii++) { MakeAttribute(cnns[iii]); } doc = first_doc; cur_type = entry_type; // il = entry_type.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes).GetILGenerator(); // if (p.InitializationCode != null) // ConvertStatement(p.InitializationCode); /*cur_meth = entry_meth; il = entry_meth.GetILGenerator(); //переводим тело основной программы //Тут только вызовы init, final if (p.main_function != null) { ConvertBody(p.main_function.function_code); il.Emit(OpCodes.Ret); }*/ CloseTypes();//закрываем типы entry_type.CreateType(); switch (comp_opt.target) { case TargetType.Exe: ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break; case TargetType.WinExe: if (!comp_opt.ForRunningWithEnvironment) ab.SetEntryPoint(entry_meth, PEFileKinds.WindowApplication); else ab.SetEntryPoint(entry_meth, PEFileKinds.ConsoleApplication); break; } /**/ try { //ne osobo vazhnaja vesh, sohranjaet v exe-shnik spisok ispolzuemyh prostranstv imen, dlja strahovki obernuli try catch if (comp_opt.dbg_attrs == DebugAttributes.ForDebbuging) { string[] namespaces = p.UsedNamespaces; TypeBuilder attr_class = mb.DefineType("$UsedNsAttr", TypeAttributes.Public | TypeAttributes.BeforeFieldInit, typeof(Attribute)); FieldBuilder fld_ns = attr_class.DefineField("ns", TypeFactory.StringType, FieldAttributes.Public); FieldBuilder fld_count = attr_class.DefineField("count", TypeFactory.Int32Type, FieldAttributes.Public); ConstructorBuilder attr_ci = attr_class.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[2] { TypeFactory.Int32Type, TypeFactory.StringType }); ILGenerator attr_il = attr_ci.GetILGenerator(); attr_il.Emit(OpCodes.Ldarg_0); attr_il.Emit(OpCodes.Ldarg_1); attr_il.Emit(OpCodes.Stfld, fld_count); attr_il.Emit(OpCodes.Ldarg_0); attr_il.Emit(OpCodes.Ldarg_2); attr_il.Emit(OpCodes.Stfld, fld_ns); attr_il.Emit(OpCodes.Ret); int len = 2 + 2 + 4 + 1; foreach (string ns in namespaces) { len += ns.Length + 1; } byte[] bytes = new byte[len]; bytes[0] = 1; bytes[1] = 0; using (BinaryWriter bw = new BinaryWriter(new MemoryStream())) { bw.Write(namespaces.Length); System.Text.StringBuilder sb = new System.Text.StringBuilder(); foreach (string ns in namespaces) { sb.Append(Convert.ToChar(ns.Length)); sb.Append(ns); //bw.Write(ns); } if (sb.Length > 127) { len += 1; bytes = new byte[len]; bytes[0] = 1; bytes[1] = 0; } bw.Write(sb.ToString()); bw.Seek(0, SeekOrigin.Begin); bw.BaseStream.Read(bytes, 2, len - 4); if (sb.Length > 127) { bytes[7] = (byte)(sb.Length & 0xFF); bytes[6] = (byte)(0x80 | ((sb.Length & 0xFF00) >> 8)); } } entry_type.SetCustomAttribute(attr_ci, bytes); attr_class.CreateType(); } } catch (Exception e) { } if (an.Name == "PABCRtl" || an.Name == "PABCRtl32") { CustomAttributeBuilder cab = new CustomAttributeBuilder(typeof(AssemblyKeyFileAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { an.Name == "PABCRtl" ? "PublicKey.snk" : "PublicKey32.snk" }); ab.SetCustomAttribute(cab); cab = new CustomAttributeBuilder(typeof(AssemblyDelaySignAttribute).GetConstructor(new Type[] { typeof(bool) }), new object[] { true }); ab.SetCustomAttribute(cab); cab = new CustomAttributeBuilder(typeof(TargetFrameworkAttribute).GetConstructor(new Type[] { typeof(string) }), new object[] { ".NETFramework,Version=v4.0" }); ab.SetCustomAttribute(cab); } ab.SetCustomAttribute(new CustomAttributeBuilder(typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }), new object[] { SecurityRuleSet.Level2 }, new PropertyInfo[] { typeof(SecurityRulesAttribute).GetProperty("SkipVerificationInFullTrust") }, new object[] { true })); /*ab.SetCustomAttribute(new CustomAttributeBuilder(typeof(System.Security.Permissions.SecurityPermissionAttribute).GetConstructor(new Type[] { typeof(System.Security.Permissions.SecurityAction) }), new object[] { System.Security.Permissions.SecurityAction.RequestMinimum }, new PropertyInfo[] { typeof(System.Security.Permissions.SecurityPermissionAttribute).GetProperty("UnmanagedCode") }, new object[] { true }));*/ if (entry_meth != null && comp_opt.target == TargetType.WinExe) { entry_meth.SetCustomAttribute(typeof(STAThreadAttribute).GetConstructor(Type.EmptyTypes), new byte[] { 0x01, 0x00, 0x00, 0x00 }); } List<FileStream> ResStreams = new List<FileStream>(); if (ResourceFiles != null) foreach (string resname in ResourceFiles) { FileStream stream = File.OpenRead(resname); ResStreams.Add(stream); mb.DefineManifestResource(Path.GetFileName(resname), stream, ResourceAttributes.Public); //System.Resources.ResourceManager rm; //System.Resources.ResourceSet rs;rs. } ab.SetCustomAttribute(typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute).GetConstructor(new Type[1] { TypeFactory.Int32Type }), new byte[] { 0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00 }); //ab.SetCustomAttribute(typeof(System.Runtime.CompilerServices.RuntimeCompatibilityAttribute, if (RunOnly) { object main_class = ab.CreateInstance(cur_unit + ".Program"); MethodInfo methodInfo = main_class.GetType().GetMethod("Main"); //AppDomain.CreateDomain( methodInfo.Invoke(main_class, null); //ad.ExecuteAssemblyByName(assembly_to_run.GetName(), new System.Security.Policy.Evidence(), null); } else { int tries = 0; bool not_done = true; do { try { if (comp_opt.target == TargetType.Exe || comp_opt.target == TargetType.WinExe) { if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86) ab.Save(an.Name + ".exe", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386); //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64) // ab.Save(an.Name + ".exe", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64); else ab.Save(an.Name + ".exe"); //сохраняем сборку } else { if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x86) ab.Save(an.Name + ".dll", PortableExecutableKinds.Required32Bit, ImageFileMachine.I386); //else if (comp_opt.platformtarget == NETGenerator.CompilerOptions.PlatformTarget.x64) // ab.Save(an.Name + ".dll", PortableExecutableKinds.PE32Plus, ImageFileMachine.IA64); else ab.Save(an.Name + ".dll"); } not_done = false; } catch (System.Runtime.InteropServices.COMException e) { throw new TreeConverter.SaveAssemblyError(e.Message); } catch (System.IO.IOException e) { if (tries < num_try_save) tries++; else throw new TreeConverter.SaveAssemblyError(e.Message); } } while (not_done); } foreach (FileStream fs in ResStreams) fs.Close(); //ad.ExecuteAssemblyByName(an, new System.Security.Policy.Evidence()); //это уже не нужно //Console.WriteLine(Environment.TickCount-ticks); }
public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context) { if (_compiledType != null) return _compiledType; string publicTypeName = IsDefType || (_isStatic && Compiler.IsCompiling) ? InternalName : InternalName + "__" + RT.nextID(); //Console.WriteLine("DefFn {0}, {1}", publicTypeName, context.AssemblyBuilder.GetName().Name); _typeBuilder = context.AssemblyGen.DefinePublicType(publicTypeName, superType, true); context = context.WithNewDynInitHelper().WithTypeBuilder(_typeBuilder); Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, context)); try { if (interfaces != null) { for (int i = 0; i < interfaces.count(); i++) _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i)); } ObjExpr.MarkAsSerializable(_typeBuilder); GenInterface.SetCustomAttributes(_typeBuilder, _classMeta); try { if (IsDefType) { Compiler.RegisterDuplicateType(_typeBuilder); Var.pushThreadBindings(RT.map( Compiler.CompileStubOrigClassVar, stubType )); //, //Compiler.COMPILE_STUB_CLASS, _baseType)); } EmitConstantFieldDefs(_typeBuilder); EmitKeywordCallsiteDefs(_typeBuilder); DefineStaticConstructor(_typeBuilder); if (SupportsMeta) _metaField = _typeBuilder.DefineField("__meta", typeof(IPersistentMap), FieldAttributes.Public | FieldAttributes.InitOnly); EmitClosedOverFields(_typeBuilder); EmitProtocolCallsites(_typeBuilder); _ctorInfo = EmitConstructor(_typeBuilder, superType); if (_altCtorDrops > 0) EmitFieldOnlyConstructor(_typeBuilder, superType); if (SupportsMeta) { EmitNonMetaConstructor(_typeBuilder, superType); EmitMetaFunctions(_typeBuilder); } EmitStatics(_typeBuilder); EmitMethods(_typeBuilder); //if (KeywordCallsites.count() > 0) // EmitSwapThunk(_typeBuilder); _compiledType = _typeBuilder.CreateType(); if (context.DynInitHelper != null) context.DynInitHelper.FinalizeType(); // If we don't pick up the ctor after we finalize the type, // we sometimes get a ctor which is not a RuntimeConstructorInfo // This causes System.DynamicILGenerator.Emit(opcode,ContructorInfo) to blow up. // The error says the ConstructorInfo is null, but there is a second case in the code. // Thank heavens one can run Reflector on mscorlib. ConstructorInfo[] cis = _compiledType.GetConstructors(); foreach (ConstructorInfo ci in cis) { if (ci.GetParameters().Length == CtorTypes().Length) { _ctorInfo = ci; break; } } return _compiledType; } finally { if (IsDefType) Var.popThreadBindings(); } } finally { Var.popThreadBindings(); } }
/// <summary> /// Emits all metadata /// </summary> public void EmitDeclaration() { // Create a new assembly and module an = new AssemblyName(name); ab = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Save); mb = ab.DefineDynamicModule(name, name + ".exe"); // Emit metadata for each function declaration foreach (FunctionDeclaration decl in functions) { decl.EmitDeclaration(mb); } // Type is used to store global variables tb = mb.DefineType("Data", TypeAttributes.Public | TypeAttributes.Abstract | TypeAttributes.Sealed); foreach (VariableDeclaration decl in variables) { decl.EmitDeclaration(tb); } // Creates a private, static constructor to instantiate any arrays ConstructorBuilder cb = tb.DefineConstructor(MethodAttributes.Private | MethodAttributes.Static, CallingConventions.Standard, null); // Creates the IL Generator object for the constructor ILGenerator ilGen = cb.GetILGenerator(); // Step through the variable list for (int i = 0; i < variables.Count; i++) { ArrayType arrType = variables[i].type as ArrayType; // If an array is found if (arrType != null) { // Instantiate array arrType.EmitInstance(ilGen); ilGen.Emit(OpCodes.Stsfld, variables[i].fb); } } // Return ilGen.Emit(OpCodes.Ret); // Create Data class tb.CreateType(); }