private void CompileWithStaticGlobals(out DlrMainCallTarget target, out IAttributesCollection globals) { // Create typegen TypeGen typeGen = Snippets.Shared.DefineType(MakeDebugName(), typeof(CustomSymbolDictionary), false, SourceUnit.EmitDebugSymbols); typeGen.TypeBuilder.DefineDefaultConstructor(MethodAttributes.Public); // Create rewriter GlobalStaticFieldRewriter rewriter = new GlobalStaticFieldRewriter(typeGen); // Compile lambda LambdaExpression lambda = rewriter.RewriteLambda(Code, "Initialize"); lambda.CompileToMethod(typeGen.TypeBuilder, CompilerHelpers.PublicStatic, SourceUnit.EmitDebugSymbols); // Create globals dictionary, finish type rewriter.EmitDictionary(); Type type = typeGen.FinishType(); globals = (IAttributesCollection)Activator.CreateInstance(type); // Create target target = (DlrMainCallTarget)Delegate.CreateDelegate(typeof(DlrMainCallTarget), type.GetMethod("Initialize")); // TODO: clean this up after clarifying dynamic site initialization logic InitializeFields(type); }
public void FinalizeType() { if (_typeBuilder != null && !_typeBuilder.IsCreated()) { CreateStaticCtor(); _typeGen.FinishType(); } }
private void CompilePythonModule(string fileName, PythonCompilerSink sink, bool createMain) { assemblyGen.SetPythonSourceFile(fileName); CompilerContext context = new CompilerContext(fileName, sink); Parser p = Parser.FromFile(state, context); Stmt body = p.ParseFileInput(); if (sink.Errors > 0) { return; } GlobalSuite gs = IronPython.Compiler.Binder.Bind(body, context); string moduleName = Path.GetFileNameWithoutExtension(fileName); TypeGen tg = OutputGenerator.GenerateModuleType(moduleName, assemblyGen); CodeGen init; if (!AutoImportAll) { init = OutputGenerator.GenerateModuleInitialize(context, gs, tg); } else { // auto-import all compiled modules, useful for CodeDom scenarios. init = OutputGenerator.GenerateModuleInitialize(context, gs, tg, delegate(CodeGen cg) { for (int i = 0; i < sourceFiles.Count; i++) { string otherModName = Path.GetFileNameWithoutExtension(sourceFiles[i]); if (otherModName == moduleName) { continue; } FromImportStmt stmt = new FromImportStmt( new DottedName(new Name[] { Name.Make(otherModName) }), FromImportStmt.Star, null); stmt.start = new Location(1, 1); stmt.end = new Location(1, 1); stmt.Emit(cg); } }); } if (createMain) { CodeGen main = OutputGenerator.GenerateModuleEntryPoint(tg, init, Path.GetFileNameWithoutExtension(mainFile), referencedAssemblies); assemblyGen.SetEntryPoint(main.MethodInfo, targetKind); } AddPythonModuleAttribute(tg, moduleName); tg.FinishType(); }
public Type Finish() { if (type is TypeBuilder) { type = tg.FinishType(); Records.typedescriptors[type] = this; MethodInfo ci = type.GetMethod("make"); var pari = ci.GetParameters(); int pcount = pari.Length; if (pcount < 9 && !(pcount == 1 && pari[0].ParameterType == typeof(object[]))) { Constructor = CreateCallable(ci); } else { Constructor = Closure.Create(Delegate.CreateDelegate(typeof(CallTargetN), ci)) as Callable; } DefaultConstructor = CreateCallable(type.GetMethod("$make", Type.EmptyTypes)); DefaultInit = CreateCallable(type.GetMethod("$init")); // update fields predicate = type.GetMethod(predicate.Name); Predicate = Closure.Create(Delegate.CreateDelegate(typeof(CallTarget1), predicate)) as Callable; foreach (FieldDescriptor fd in fields) { fd.field = type.GetField(fd.field.Name, BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly); fd.accessor = type.GetMethod(fd.accessor.Name); fd.Accessor = CreateCallable(fd.accessor); if (fd.mutable) { fd.mutator = type.GetMethod(fd.mutator.Name); fd.Mutator = CreateCallable(fd.mutator); } else { fd.Mutator = Builtins.FALSE; } } } return(type); }
/// <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); // 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); 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(); }