예제 #1
0
        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);
        }
예제 #2
0
 public void FinalizeType()
 {
     if (_typeBuilder != null && !_typeBuilder.IsCreated())
     {
         CreateStaticCtor();
         _typeGen.FinishType();
     }
 }
예제 #3
0
        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();
        }
예제 #4
0
        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);
        }
예제 #5
0
        /// <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();
        }