private ILGen MakeRawKeysMethod() { FieldBuilder rawKeysCache = TypeGen.AddStaticField(typeof(SymbolId[]), "ExtraKeysCache"); ILGen init = TypeGen.TypeInitializer; init.EmitInt(_fields.Count); init.Emit(OpCodes.Newarr, typeof(SymbolId)); int current = 0; foreach (GlobalVariableExpression variable in _fields.Keys) { init.Emit(OpCodes.Dup); init.EmitInt(current++); EmitSymbolId(init, SymbolTable.StringToId(variable.Name)); init.EmitStoreElement(typeof(SymbolId)); } init.Emit(OpCodes.Stsfld, rawKeysCache); MethodInfo baseMethod = typeof(CustomSymbolDictionary).GetMethod("GetExtraKeys", BindingFlags.Public | BindingFlags.Instance); ILGen cg = TypeGen.DefineExplicitInterfaceImplementation(baseMethod); cg.Emit(OpCodes.Ldsfld, rawKeysCache); cg.Emit(OpCodes.Ret); return(cg); }
// This generates a method like the following: // // TrySetExtraValue(object name, object value) { // if (name1 == name) { // type.name1Slot = value; // return 1; // } // if (name2 == name) { // type.name2Slot = value; // return 1; // } // ... // return 0 // } private void MakeSetMethod() { MethodInfo baseMethod = typeof(CustomSymbolDictionary).GetMethod("TrySetExtraValue", BindingFlags.NonPublic | BindingFlags.Instance); ILGen cg = TypeGen.DefineMethodOverride(baseMethod); foreach (KeyValuePair <GlobalVariableExpression, FieldBuilder> kv in _fields) { SymbolId name = SymbolTable.StringToId(kv.Key.Name); EmitSymbolId(cg, name); // arg0 -> this cg.EmitLoadArg(1); cg.EmitCall(typeof(SymbolId), "op_Equality"); Label next = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, next); cg.EmitFieldGet(kv.Value); cg.EmitLoadArg(2); cg.EmitPropertySet(typeof(ModuleGlobalWrapper), "CurrentValue"); cg.EmitInt(1); cg.Emit(OpCodes.Ret); cg.MarkLabel(next); } cg.EmitInt(0); cg.Emit(OpCodes.Ret); }
protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen) { var lambda = RewriteForSave(typeGen, _code); MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName); lambda.CompileToMethod(mb, false); return new KeyValuePair<MethodBuilder, Type>(mb, typeof(DlrMainCallTarget)); }
private void MakeInitialization() { TypeGen.TypeBuilder.AddInterfaceImplementation(typeof(IModuleDictionaryInitialization)); MethodInfo baseMethod = typeof(IModuleDictionaryInitialization).GetMethod("InitializeModuleDictionary"); ILGen cg = TypeGen.DefineExplicitInterfaceImplementation(baseMethod); Label ok = cg.DefineLabel(); cg.EmitFieldGet(_contextField); cg.Emit(OpCodes.Ldnull); cg.Emit(OpCodes.Ceq); cg.Emit(OpCodes.Brtrue_S, ok); cg.EmitNew(typeof(InvalidOperationException), Type.EmptyTypes); cg.Emit(OpCodes.Throw); cg.MarkLabel(ok); // arg0 -> this // arg1 -> MyModuleDictType.ContextSlot cg.EmitLoadArg(1); cg.EmitFieldSet(_contextField); ConstructorInfo wrapperCtor = typeof(ModuleGlobalWrapper).GetConstructor(new Type[] { typeof(CodeContext), typeof(SymbolId) }); foreach (KeyValuePair <GlobalVariableExpression, FieldBuilder> kv in _fields) { // wrapper = new ModuleGlobalWrapper(context, name); cg.EmitLoadArg(1); EmitSymbolId(cg, SymbolTable.StringToId(kv.Key.Name)); cg.Emit(OpCodes.Newobj, wrapperCtor); cg.Emit(OpCodes.Stsfld, kv.Value); } cg.Emit(OpCodes.Ret); }
public CodeGen DefineMethod(string methodName, Type returnType, IList <Type> paramTypes, ConstantPool constantPool) { CodeGen cg; if (GenerateStaticMethods) { int index = Interlocked.Increment(ref _index); TypeGen tg = DefinePublicType("Type$" + methodName + "$" + index, typeof(object)); cg = tg.DefineMethod("Handle" + index, returnType, paramTypes, null, constantPool); cg.DynamicMethod = true; } else { Type[] parameterTypes = CompilerHelpers.MakeParamTypeArray(paramTypes, constantPool); string dynamicMethodName = methodName + "##" + Interlocked.Increment(ref _index); DynamicMethod target; #if SILVERLIGHT // Module-hosted DynamicMethod is not available in SILVERLIGHT target = new DynamicMethod(dynamicMethodName, returnType, parameterTypes); #else target = new DynamicMethod(dynamicMethodName, returnType, parameterTypes, _myModule); #endif cg = new CodeGen(null, this, target, target.GetILGenerator(), parameterTypes, constantPool); } return(cg); }
protected override Expression VisitConstant(ConstantExpression node) { object data = node.Value; Type type = node.Type; // if the constant can be emitted into IL, nothing to do if (CanEmitConstant(data, type)) { return(node); } type = TypeUtils.GetConstantType(type); int index; if (!_constantCache.TryGetValue(data, out index)) { int number = AddStaticData(data); FieldBuilder field = TypeGen.AddStaticField(type, "#Constant" + number); index = _staticFields.Count; _staticFields.Add(field); _constantCache.Add(data, index); } return(Expression.Field(null, _staticFields[index])); }
protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) { var lambda = RewriteForSave(typeGen, _code); lambda = Expression.Lambda<Func<Scope, LanguageContext, object>>( Expression.Block( new[] { IronPython.Compiler.Ast.ArrayGlobalAllocator._globalContext }, Expression.Assign( IronPython.Compiler.Ast.ArrayGlobalAllocator._globalContext, Expression.Call( null, typeof(PythonOps).GetMethod("CreateTopLevelCodeContext"), lambda.Parameters[0], lambda.Parameters[1] ) ), lambda.Body ), lambda.Name, lambda.Parameters ); MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName); lambda.CompileToMethod(mb, false); mb.SetCustomAttribute(new CustomAttributeBuilder( typeof(CachedOptimizedCodeAttribute).GetConstructor(new Type[] { typeof(string[]) }), new object[] { _names } )); return new KeyValuePair<MethodBuilder, Type>(mb, typeof(Func<Scope, LanguageContext, object>)); }
// // This generates a method like the following: // // TryGetExtraValue(int name, object out value) { // if (name1 == name) { // value = type.name1Slot.RawValue; // return value != Uninitialized.Instance; // } // if (name2 == name) { // value = type.name2Slot.RawValue; // return value != Uninitialized.Instance; // } // ... // return false // } private void MakeGetMethod() { MethodInfo baseMethod = typeof(CustomSymbolDictionary).GetMethod("TryGetExtraValue", BindingFlags.NonPublic | BindingFlags.Instance); ILGen cg = TypeGen.DefineMethodOverride(baseMethod); foreach (KeyValuePair <GlobalVariableExpression, FieldBuilder> kv in _fields) { SymbolId name = SymbolTable.StringToId(kv.Key.Name); EmitSymbolId(cg, name); // arg0 -> this cg.EmitLoadArg(1); cg.EmitCall(typeof(SymbolId), "op_Equality"); Label next = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, next); cg.EmitLoadArg(2); // Expects to push as an object. EmitGetRawFromObject(cg, kv.Value); cg.Emit(OpCodes.Stind_Ref); EmitGetRawFromObject(cg, kv.Value); cg.EmitFieldGet(typeof(Uninitialized), "Instance"); cg.Emit(OpCodes.Ceq); cg.Emit(OpCodes.Not); cg.Emit(OpCodes.Ret); cg.MarkLabel(next); } cg.EmitInt(0); cg.Emit(OpCodes.Ret); }
public StaticGlobalAllocator(LanguageContext/*!*/ context, string name) { _typeGen = Snippets.Shared.DefineType(name, typeof(object), false, false); _codeContextField = _typeGen.AddStaticField(typeof(CodeContext), "__global_context"); _codeContext = CreateFieldBuilderExpression(_codeContextField); _scope = new Scope(new PythonDictionary(new GlobalDictionaryStorage(_globalVals))); _context = new CodeContext(_scope, context); }
private TypeGen GenerateModuleGlobalsType(AssemblyGen ag) { TypeGen tg = ag.DefinePublicType(ModuleName == "ironscheme.boot.new" ? "#" : ModuleName, typeof(CustomSymbolDictionary)); tg.AddCodeContextField(); tg.DefaultConstructor = tg.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public); return(tg); }
public TypeGen DefineDebuggableType(string typeName, SourceUnit sourceUnit) { typeName = typeName.Replace(Type.Delimiter, '_'); // '.' is for separating the namespace and the type name. DebugAssembly.SetSourceUnit(sourceUnit); TypeGen tg = DebugAssembly.DefinePublicType(typeName + "$" + _debugTypeIndex++, typeof(object)); tg.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public); return(tg); }
internal static CodeGen CreateDebuggableDynamicCodeGenerator(CompilerContext context, string name, Type retType, IList <Type> paramTypes, IList <string> paramNames, ConstantPool constantPool) { TypeGen tg = ScriptDomainManager.CurrentManager.Snippets.DefineDebuggableType(name, context.SourceUnit); CodeGen cg = tg.DefineMethod("Initialize", retType, paramTypes, paramNames, constantPool); tg.AddCodeContextField(); cg.DynamicMethod = true; return(cg); }
protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen) { var lambda = RewriteForSave(typeGen, _code); MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName); lambda.CompileToMethod(mb, false); mb.SetCustomAttribute(new CustomAttributeBuilder( typeof(CachedOptimizedCodeAttribute).GetConstructor(new Type[] { typeof(string[]) }), new object[] { _names } )); return new KeyValuePair<MethodBuilder, Type>(mb, typeof(LookupCompilationDelegate)); }
public TypeGen DefineNestedType(string name, Type parent) { TypeBuilder tb = _myType.DefineNestedType(name, TypeAttributes.NestedPublic); tb.SetParent(parent); TypeGen ret = new TypeGen(_myAssembly, tb); _nestedTypeGens.Add(ret); ret.AddCodeContextField(); return(ret); }
protected override Expression VisitExtension(Expression node) { if (node.NodeType == ExpressionType.Dynamic) { // the node was dynamic, the dynamic nodes were removed, // we now need to rewrite any call sites. return(VisitDynamic((DynamicExpression)node)); } SymbolConstantExpression symbol = node as SymbolConstantExpression; if (symbol != null) { SymbolId id = symbol.Value; if (id == SymbolId.Empty) { return(Expression.Field(null, typeof(SymbolId).GetField("Empty"))); } FieldBuilderExpression value; if (!_indirectSymbolIds.TryGetValue(id, out value)) { // create field, emit fix-up... if (_symbolGen == null) { _symbolGen = new TypeGen(_typeGen.AssemblyGen, ((ModuleBuilder)_typeGen.TypeBuilder.Module).DefineType("Symbols" + Interlocked.Increment(ref _id))); #if SILVERLIGHT _finishedSymbolType = new StrongBox <Type>(); #endif } FieldBuilder field = _symbolGen.AddStaticField(typeof(SymbolId), FieldAttributes.Public, SymbolTable.IdToString(id)); ILGen init = _symbolGen.TypeInitializer; if (_indirectSymbolIds.Count == 0) { init.EmitType(_symbolGen.TypeBuilder); init.EmitCall(typeof(ScriptingRuntimeHelpers), "InitializeSymbols"); } #if SILVERLIGHT _indirectSymbolIds[id] = value = new FieldBuilderExpression(field, _finishedSymbolType); #else _indirectSymbolIds[id] = value = new FieldBuilderExpression(field); #endif } Debug.Assert(value != null); return(value); } return(Visit(node.Reduce())); }
private TypeGen GenerateModuleGlobalsType(AssemblyGen ag, ScriptCode sc) { var n = sc.CodeBlock.Name; switch (n) { case "visit-code": case "invoke-code": case "guard-code": TypeGen tg = ag.DefinePublicType("syntax-" + sc.CodeBlock.Name, typeof(CustomSymbolDictionary)); tg.AddCodeContextField(); tg.DefaultConstructor = tg.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public); return(tg); default: return(GenerateModuleGlobalsType(ag)); } }
protected override SlotFactory CreateSlotFactory(ScriptCode scriptCode) { AssemblyGen ag = null; if (scriptCode.SourceUnit.Kind == SourceCodeKind.Default && scriptCode.CodeBlock.Name != "ironscheme.boot.new") { if (ScriptDomainManager.Options.DebugMode) { if ((ScriptDomainManager.Options.AssemblyGenAttributes & AssemblyGenAttributes.SaveAndReloadAssemblies) != 0) { ag = ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly; //CreateModuleAssembly(scriptCode); } else { ag = ScriptDomainManager.CurrentManager.Snippets.DebugAssembly; } } else { if ((ScriptDomainManager.Options.AssemblyGenAttributes & AssemblyGenAttributes.SaveAndReloadAssemblies) != 0) { ag = ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly; //CreateModuleAssembly(scriptCode); } else { ag = ScriptDomainManager.CurrentManager.Snippets.Assembly; } } } else { ag = ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly; //CreateModuleAssembly(scriptCode); } ScriptDomainManager.CurrentManager.Snippets.CurrentAssembly = ag; TypeGen tg = GenerateModuleGlobalsType(ag, scriptCode); if (scriptCode.LibraryGlobals != null) { foreach (var kvp in scriptCode.LibraryGlobals) { var k = kvp.Key; var v = kvp.Value; var cg = v.Block.CreateGlobalMethodStub(tg); if (cg != null) { CodeGen._codeBlockStubs[v.Block] = cg; CodeGen._codeBlockLookup[k] = cg; } } } if (scriptCode.LibraryGlobalsX != null) { foreach (var kvp in scriptCode.LibraryGlobalsX) { var k = kvp.Key; var v = kvp.Value; var cg = v.Block.CreateGlobalMethodStub(tg); if (cg != null) { CodeGen._codeBlockStubsX[v.Block] = cg; CodeGen._codeBlockLookupX[k] = cg; } } } if (scriptCode.LibraryGlobalsN != null) { foreach (var kvp in scriptCode.LibraryGlobalsN) { var k = kvp.Key; var v = kvp.Value; var cgd = new List <CodeGenDescriptor>(); foreach (var i in v) { var cg = i.codeblock.Block.CreateGlobalMethodStub(tg); if (cg != null) { CodeGen._codeBlockStubsN[i.codeblock.Block] = cg; cgd.Add(new CodeGenDescriptor { arity = i.arity, varargs = i.varargs, cg = cg, }); } } CodeGen._codeBlockLookupN[k] = cgd.ToArray(); } } StaticFieldSlotFactory factory = new StaticFieldSlotFactory(tg); _languages[scriptCode.LanguageContext] = new LanguageInfo(factory, tg); return(factory); }
public LanguageInfo(StaticFieldSlotFactory slotFactory, TypeGen tg) { TypeGen = tg; SlotFactory = slotFactory; }
internal GlobalArrayRewriter(Dictionary <SymbolId, FieldBuilder> symbolDict, TypeGen typeGen) : base(symbolDict) { TypeGen = typeGen; }
private static void EmitOverrideGetHashCode(TypeGen typeGen) { Type baseType = typeGen.TypeBuilder.BaseType; MethodInfo baseMethod = baseType.GetMethod("GetHashCode", Type.EmptyTypes); Compiler cg = typeGen.DefineMethodOverride(baseMethod); // Check if a "hash" method exists on this class cg.EmitType(typeGen.TypeBuilder); cg.EmitString("hash"); cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod")); Label callBase = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, callBase); // If so, call it cg.EmitThis(); cg.EmitCall(typeof(RubyOps).GetMethod("CallHash")); cg.EmitReturn(); // Otherwise, call base class cg.MarkLabel(callBase); cg.EmitThis(); cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual cg.EmitReturn(); cg.Finish(); }
public StaticFieldSlotFactory(TypeGen typeGen) { _typeGen = typeGen; }
internal ToDiskRewriter(TypeGen typeGen) { _typeGen = typeGen; }
/// <summary> /// This takes an assembly name including extension and saves the provided ScriptCode objects into the assembly. /// /// The provided script codes can constitute code from multiple languages. The assemblyName can be either a fully qualified /// or a relative path. The DLR will simply save the assembly to the desired location. The assembly is created by the DLR and /// if a file already exists than an exception is raised. /// /// The DLR determines the internal format of the ScriptCode and the DLR can feel free to rev this as appropriate. /// </summary> public static void SaveToAssembly(string assemblyName, params SavableScriptCode[] codes) { ContractUtils.RequiresNotNull(assemblyName, "assemblyName"); ContractUtils.RequiresNotNullItems(codes, "codes"); // break the assemblyName into it's dir/name/extension string dir = Path.GetDirectoryName(assemblyName); if (String.IsNullOrEmpty(dir)) { dir = Environment.CurrentDirectory; } string name = Path.GetFileNameWithoutExtension(assemblyName); string ext = Path.GetExtension(assemblyName); // build the assembly & type gen that all the script codes will live in... AssemblyGen ag = new AssemblyGen(new AssemblyName(name), dir, ext, /*emitSymbols*/false); TypeBuilder tb = ag.DefinePublicType("DLRCachedCode", typeof(object), true); TypeGen tg = new TypeGen(ag, tb); var symbolDict = new Dictionary<SymbolId, FieldBuilder>(); // then compile all of the code Dictionary<Type, List<CodeInfo>> langCtxBuilders = new Dictionary<Type, List<CodeInfo>>(); foreach (SavableScriptCode sc in codes) { List<CodeInfo> builders; if (!langCtxBuilders.TryGetValue(sc.LanguageContext.GetType(), out builders)) { langCtxBuilders[sc.LanguageContext.GetType()] = builders = new List<CodeInfo>(); } KeyValuePair<MethodBuilder, Type> compInfo = sc.CompileForSave(tg, symbolDict); builders.Add(new CodeInfo(compInfo.Key, sc, compInfo.Value)); } MethodBuilder mb = tb.DefineMethod( "GetScriptCodeInfo", MethodAttributes.SpecialName | MethodAttributes.Public | MethodAttributes.Static, typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>), Type.EmptyTypes); ILGen ilgen = new ILGen(mb.GetILGenerator()); var langsWithBuilders = langCtxBuilders.ToArray(); // lang ctx array ilgen.EmitArray(typeof(Type), langsWithBuilders.Length, (index) => { ilgen.Emit(OpCodes.Ldtoken, langsWithBuilders[index].Key); ilgen.EmitCall(typeof(Type).GetMethod("GetTypeFromHandle", new[] { typeof(RuntimeTypeHandle) })); }); // builders array of array ilgen.EmitArray(typeof(Delegate[]), langsWithBuilders.Length, (index) => { List<CodeInfo> builders = langsWithBuilders[index].Value; ilgen.EmitArray(typeof(Delegate), builders.Count, (innerIndex) => { ilgen.EmitNull(); ilgen.Emit(OpCodes.Ldftn, builders[innerIndex].Builder); ilgen.EmitNew( builders[innerIndex].DelegateType, new[] { typeof(object), typeof(IntPtr) } ); }); }); // paths array of array ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => { List<CodeInfo> builders = langsWithBuilders[index].Value; ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => { ilgen.EmitString(builders[innerIndex].Code.SourceUnit.Path); }); }); // 4th element in tuple - custom per-language data ilgen.EmitArray(typeof(string[]), langsWithBuilders.Length, (index) => { List<CodeInfo> builders = langsWithBuilders[index].Value; ilgen.EmitArray(typeof(string), builders.Count, (innerIndex) => { ICustomScriptCodeData data = builders[innerIndex].Code as ICustomScriptCodeData; if (data != null) { ilgen.EmitString(data.GetCustomScriptCodeData()); } else { ilgen.Emit(OpCodes.Ldnull); } }); }); ilgen.EmitNew( typeof(MutableTuple<Type[], Delegate[][], string[][], string[][]>), new[] { typeof(Type[]), typeof(Delegate[][]), typeof(string[][]), typeof(string[][]) } ); ilgen.Emit(OpCodes.Ret); mb.SetCustomAttribute(new CustomAttributeBuilder( typeof(DlrCachedCodeAttribute).GetConstructor(Type.EmptyTypes), ArrayUtils.EmptyObjects )); tg.FinishType(); ag.SaveAssembly(); }
protected LambdaExpression RewriteForSave(TypeGen typeGen, LambdaExpression code) { var diskRewriter = new ToDiskRewriter(typeGen); return diskRewriter.RewriteLambda(code); }
public FieldSlotFactory(TypeGen typeGen, Slot instance) { this._typeGen = typeGen; this._instance = instance; }
static void GenerateConstructor(RecordTypeDescriptor rtd, TypeGen tg, Type parenttype) { // constructor logic { List<Type> paramtypes = new List<Type>(); List<FieldDescriptor> allfields = new List<FieldDescriptor>(rtd.GetAllFields()); int diff = allfields.Count - rtd.Fields.Length; foreach (FieldDescriptor var in allfields) { paramtypes.Add(var.Type); } List<Type> parenttypes = new List<Type>(); for (int i = 0; i < diff; i++) { parenttypes.Add(typeof(object)); //TODO: fix this, it looks broken } if (paramtypes.Count < 9) { CodeGen cg = tg.DefineConstructor(paramtypes.ToArray()); CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make", tg.TypeBuilder, paramtypes.ToArray(), allfields.ConvertAll(x => x.Name).ToArray()); for (int i = 0; i < allfields.Count; i++) { cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name); } int fi = 0; cg.EmitThis(); for (fi = 0; fi < diff; fi++) { cg.EmitArgGet(fi); mk.EmitArgGet(fi); } cg.Emit(OpCodes.Call, (rtd.Parent == null ? parenttype.GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor)); foreach (FieldDescriptor fd in rtd.Fields) { cg.EmitThis(); cg.EmitArgGet(fi); cg.EmitFieldSet(fd.field); mk.EmitArgGet(fi); fi++; } mk.EmitNew(cg.MethodBase as ConstructorInfo); mk.EmitReturn(); cg.EmitReturn(); rtd.cg = cg; } else { CodeGen cg = tg.DefineConstructor(paramtypes.ToArray()); CodeGen mk = tg.DefineMethod(MethodAttributes.Public | MethodAttributes.Static, "make", tg.TypeBuilder, new Type[] { typeof(object[]) }, new string[] { "args" }); for (int i = 0; i < allfields.Count; i++) { cg.DefineParameter(i + 1, ParameterAttributes.None, allfields[i].Name); } int fi = 0; cg.EmitThis(); for (fi = 0; fi < diff; fi++) { cg.EmitArgGet(fi); mk.EmitArgGet(0); mk.EmitConstant(fi); mk.Emit(OpCodes.Ldelem, typeof(object)); } cg.Emit(OpCodes.Call, (rtd.Parent == null ? typeof(object).GetConstructor(Type.EmptyTypes) : rtd.Parent.DefaultConstructor)); foreach (FieldDescriptor fd in rtd.Fields) { cg.EmitThis(); cg.EmitArgGet(fi); cg.EmitFieldSet(fd.field); mk.EmitArgGet(0); mk.EmitConstant(fi); mk.Emit(OpCodes.Ldelem, typeof(object)); fi++; } mk.EmitNew(cg.MethodBase as ConstructorInfo); mk.EmitReturn(); cg.EmitReturn(); rtd.cg = cg; } } }
internal static Type/*!*/ GetDelegateType(TypeGen/*!*/ typeGen, Type/*!*/ retType, System.Linq.Expressions.Expression/*!*/[]/*!*/ args) { Type delegateType; if (retType != typeof(void)) { Type[] types = new Type[args.Length + 2]; types[0] = typeof(CallSite); for (int i = 0; i < args.Length; i++) { types[i + 1] = args[i].Type; } types[types.Length - 1] = retType; delegateType = GetFuncType(types) ?? MakeNewCustomDelegate(typeGen, types); } else { Type[] types = new Type[args.Length + 2]; types[0] = typeof(CallSite); for (int i = 0; i < args.Length; i++) { types[i + 1] = args[i].Type; } delegateType = GetActionType(types) ?? MakeNewCustomDelegate(typeGen, ArrayUtils.Append(types, typeof(void))); } return delegateType; }
protected virtual MethodBuilder CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) { var diskRewriter = new ToDiskRewriter(typeGen); var lambda = diskRewriter.RewriteLambda(_code); MethodBuilder mb = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName); lambda.CompileToMethod(mb, false); return mb; }
internal MethodBuilder CompileToDisk(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) { if (_code == null) { throw Error.NoCodeToCompile(); } MethodBuilder mb = CompileForSave(typeGen, symbolDict); return mb; }
protected virtual KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen) { throw new NotSupportedException(); }
public TypeGen DefineNestedType(string name, Type parent) { TypeBuilder tb = _myType.DefineNestedType(name, TypeAttributes.NestedPublic); tb.SetParent(parent); TypeGen ret = new TypeGen(_myAssembly, tb); _nestedTypeGens.Add(ret); ret.AddCodeContextField(); return ret; }
static void GeneratePredicate(string n, RecordTypeDescriptor rtd, TypeGen tg) { // predicate MethodBuilder pb = tg.TypeBuilder.DefineMethod(n + "?", MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type[] { typeof(object) }); pb.DefineParameter(1, ParameterAttributes.None, "obj"); ILGenerator pgen = pb.GetILGenerator(); pgen.Emit(OpCodes.Ldarg_0); pgen.Emit(OpCodes.Isinst, tg.TypeBuilder); pgen.Emit(OpCodes.Ldnull); pgen.Emit(OpCodes.Cgt_Un); pgen.Emit(OpCodes.Call, typeof(RuntimeHelpers).GetMethod("BooleanToObject")); pgen.Emit(OpCodes.Ret); rtd.predicate = pb; }
static void GenerateFields(object fields, string n, RecordTypeDescriptor rtd, TypeGen tg, object fieldtypes) { object[] f = RequiresNotNull<object[]>(fields); object[] ftypes = RequiresNotNull<object[]>(fieldtypes); List<FieldDescriptor> rtd_fields = new List<FieldDescriptor>(); for (int i = 0; i < f.Length; i++) { Cons c = (Cons) f[i]; Type t = ClrGenerator.ExtractTypeInfo(List(SymbolTable.StringToObject("quote"), ftypes[i])); if (t == null) { ClrGenerator.ClrSyntaxError("GenerateFields", "type not found", ftypes[i]); } string fname = SymbolTable.IdToString(RequiresNotNull<SymbolId>(Second(c))); // we use standard names here, they will be mapped to the given names string aname = n + "-" + fname; string mname = n + "-" + fname + "-set!"; var fd = new FieldDescriptor { Name = fname }; FieldAttributes fattrs = FieldAttributes.Public | FieldAttributes.InitOnly; if (c.car == SymbolTable.StringToObject("mutable")) { fd.mutable = true; fattrs &= ~FieldAttributes.InitOnly; } FieldSlot s = tg.AddField(t, fname, fattrs) as FieldSlot; fd.field = s.Field; PropertyBuilder pi = tg.TypeBuilder.DefineProperty(fname, PropertyAttributes.None, t, new Type[0]); // accesor MethodBuilder ab = tg.TypeBuilder.DefineMethod(aname, MethodAttributes.Public | MethodAttributes.Static, t, new Type[] { tg.TypeBuilder }); ab.DefineParameter(1, ParameterAttributes.None, n); ILGenerator agen = ab.GetILGenerator(); agen.Emit(OpCodes.Ldarg_0); //agen.Emit(OpCodes.Castclass, tg.TypeBuilder); agen.Emit(OpCodes.Ldfld, fd.field); agen.Emit(OpCodes.Ret); fd.accessor = ab; pi.SetGetMethod(ab); // mutator if (fd.mutable) { MethodBuilder mb = tg.TypeBuilder.DefineMethod(mname, MethodAttributes.Public | MethodAttributes.Static, typeof(object), new Type[] { tg.TypeBuilder, t }); mb.DefineParameter(1, ParameterAttributes.None, n); ILGenerator mgen = mb.GetILGenerator(); mgen.Emit(OpCodes.Ldarg_0); //mgen.Emit(OpCodes.Castclass, tg.TypeBuilder); mgen.Emit(OpCodes.Ldarg_1); mgen.Emit(OpCodes.Stfld, fd.field); mgen.Emit(OpCodes.Ldsfld, Compiler.Generator.Unspecified); mgen.Emit(OpCodes.Ret); fd.mutator = mb; pi.SetSetMethod(mb); } rtd_fields.Add(fd); } rtd.fields = rtd_fields.ToArray(); }
protected virtual KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) { throw new NotSupportedException(); }
// we need to get the right execution context #if OBSOLETE private static void EmitOverrideEquals(TypeGen typeGen) { Type baseType = typeGen.TypeBuilder.BaseType; MethodInfo baseMethod = baseType.GetMethod("Equals", new Type[] { typeof(object) }); Compiler cg = typeGen.DefineMethodOverride(baseMethod); // Check if an "eql?" method exists on this class cg.EmitType(typeGen.TypeBuilder); cg.EmitString("eql?"); cg.EmitCall(typeof(RubyOps).GetMethod("ResolveDeclaredInstanceMethod")); Label callBase = cg.DefineLabel(); cg.Emit(OpCodes.Brfalse_S, callBase); // If so, call it cg.EmitThis(); cg.EmitArgGet(0); cg.EmitCall(typeof(RubyOps).GetMethod("CallEql")); cg.EmitReturn(); // Otherwise, call base class cg.MarkLabel(callBase); cg.EmitThis(); cg.EmitArgGet(0); cg.Emit(OpCodes.Call, baseMethod); // base call must be non-virtual cg.EmitReturn(); cg.Finish(); }
internal GlobalStaticFieldRewriter(TypeGen typeGen) { TypeGen = typeGen; }
private static Type/*!*/ MakeNewCustomDelegate(TypeGen/*!*/ typeGen, Type/*!*/[]/*!*/ types) { Type returnType = types[types.Length - 1]; Type[] parameters = ArrayUtils.RemoveLast(types); TypeBuilder builder = Snippets.Shared.DefineDelegateType("Delegate" + types.Length); builder.DefineConstructor(CtorAttributes, CallingConventions.Standard, _DelegateCtorSignature).SetImplementationFlags(ImplAttributes); builder.DefineMethod("Invoke", InvokeAttributes, returnType, parameters).SetImplementationFlags(ImplAttributes); return builder.CreateType(); }
private void MaybeInit() { if (_typeBuilder == null) { _typeBuilder = _assemblyGen.DefinePublicType(_typeName, typeof(object), true); _typeGen = new TypeGen(_assemblyGen, _typeBuilder); _fieldBuilders = new List<FieldBuilder>(); _fieldInits = new List<Expression>(); } }
protected override KeyValuePair<MethodBuilder, Type> CompileForSave(TypeGen typeGen, Dictionary<SymbolId, FieldBuilder> symbolDict) { // first, serialize constants and dynamic sites: ToDiskRewriter diskRewriter = new ToDiskRewriter(typeGen); LambdaExpression lambda = diskRewriter.RewriteLambda(Code); // rewrite global variables: var globalRewriter = new GlobalArrayRewriter(symbolDict, typeGen); lambda = globalRewriter.RewriteLambda(lambda); MethodBuilder builder = typeGen.TypeBuilder.DefineMethod(lambda.Name ?? "lambda_method", CompilerHelpers.PublicStatic | MethodAttributes.SpecialName); lambda.CompileToMethod(builder, false); builder.SetCustomAttribute(new CustomAttributeBuilder( typeof(CachedOptimizedCodeAttribute).GetConstructor(new Type[] { typeof(string[]) }), new object[] { ArrayUtils.ToArray(globalRewriter.Names) } )); return new KeyValuePair<MethodBuilder, Type>(builder, typeof(DlrMainCallTarget)); }
private Expression RewriteCallSite(CallSite site, TypeGen tg) { IExpressionSerializable serializer = site.Binder as IExpressionSerializable; if (serializer == null) { throw new ArgumentException("Generating code from non-serializable CallSiteBinder."); } Type siteType = site.GetType(); FieldBuilder fb = tg.AddStaticField(siteType, "sf" + (_id++).ToString()); Expression init = Expression.Call(siteType.GetMethod("Create"), serializer.CreateExpression()); _fieldBuilders.Add(fb); _fieldInits.Add(init); Type t = init.Type; if (t.IsGenericType) { Type[] args = t.GetGenericArguments()[0].GetGenericArguments(); ; // skip the first one, it is the site. for (int k = 1; k < args.Length; k++) { Type p = args[k]; //if (!p.Assembly.GetName().Name.Equals("mscorlib") && !p.Assembly.GetName().Name.Equals("Clojure")) // Console.WriteLine("Found {0}", p.ToString()); } } // rewrite the node... return Expression.Field(null, fb); }