SaveAssembly() private method

private SaveAssembly ( ) : void
return void
Ejemplo n.º 1
0
        public static Type GenerateClass(string className,
            Type superClass,
            ISeq interfaces,  // of Types
            ISeq ctors,
            ISeq ctorTypes,
            ISeq methods,
            IPersistentMap exposesFields,
            IPersistentMap exposesMethods,
            string prefix,
            bool hasMain,
            string factoryName,
            string stateName,
            string initName,
            string postInitName,
            string implCname,
            string implNamespace,
            bool loadImplNameSpace)
        {
            string path = (string)Compiler.COMPILE_PATH.deref();
            if ( path == null)
                throw new Exception("*compile-path* not set");

            string extension = hasMain ? ".exe" : ".dll";

            //GenContext context = new GenContext(className, extension, path, CompilerMode.File);
            GenContext context = new GenContext(className, extension, path, true);

            // define the class
            List<Type> interfaceTypes = new List<Type>();

            for (ISeq s = interfaces; s != null; s = s.next())
                interfaceTypes.Add((Type)s.first());

            //TypeBuilder proxyTB = context.ModuleBldr.DefineType(
            TypeBuilder proxyTB = context.ModuleBuilder.DefineType(
                className,
                TypeAttributes.Class | TypeAttributes.Public,
                superClass,
                interfaceTypes.ToArray());

            List<MethodSignature> sigs = GetAllSignatures(superClass,interfaceTypes,methods);
            Dictionary<string,List<MethodSignature>>  overloads = ComputeOverloads(sigs);

            HashSet<string> varNames = ComputeOverloadNames(overloads);
            foreach ( MethodSignature sig in sigs )
                varNames.Add(sig.Name);

            if (!String.IsNullOrEmpty(initName)) varNames.Add(initName);
            if (!String.IsNullOrEmpty(postInitName)) varNames.Add(postInitName);
            if (hasMain) varNames.Add(_mainName);

            Dictionary<string, FieldBuilder> varMap = DefineStaticFields(proxyTB, varNames);

            FieldBuilder stateFB = String.IsNullOrEmpty(stateName) ? null : DefineStateField(proxyTB, stateName);
            DefineStaticCtor(proxyTB,prefix,varMap,loadImplNameSpace,implNamespace,implCname);

            FieldBuilder initFB = null;
            FieldBuilder postInitFB = null;
            FieldBuilder mainFB = null;

            varMap.TryGetValue(initName, out initFB);
            varMap.TryGetValue(postInitName, out postInitFB);
            varMap.TryGetValue(_mainName, out mainFB);

            DefineCtors(proxyTB, superClass,
                implNamespace + "." + prefix + initName,
                implNamespace + "." + prefix + postInitName,
                ctorTypes, initFB, postInitFB, stateFB, factoryName);

            EmitMethods(proxyTB, sigs, overloads, varMap, exposesMethods);
            EmitExposers(proxyTB, superClass, exposesFields);

            if (hasMain)
                EmitMain(context, proxyTB, implNamespace + "." + prefix + _mainName, mainFB);

            Type t = proxyTB.CreateType();

            context.SaveAssembly();

            return t;
        }
Ejemplo n.º 2
0
        internal static object Compile(TextReader rdr, string sourceDirectory, string sourceName, string relativePath)
        {
            if (COMPILE_PATH.deref() == null)
                throw new Exception("*compile-path* not set");

            object eofVal = new object();
            object form;

            //string sourcePath = sourceDirectory == null ? sourceName : sourceDirectory + "\\" + sourceName;
            string sourcePath = relativePath;

            LineNumberingTextReader lntr =
                (rdr is LineNumberingTextReader) ? (LineNumberingTextReader)rdr : new LineNumberingTextReader(rdr);

            GenContext context = new GenContext(sourceName, ".dll", sourceDirectory, true);
            GenContext evalContext = new GenContext("EvalForCompile", false);

            Var.pushThreadBindings(RT.map(
                SOURCE_PATH, sourcePath,
                SOURCE, sourceName,
                METHOD, null,
                LOCAL_ENV, null,
                LOOP_LOCALS, null,
                NEXT_LOCAL_NUM, 0,
                RT.CURRENT_NS, RT.CURRENT_NS.deref(),
                    //LINE_BEFORE, lntr.LineNumber,
                    //LINE_AFTER, lntr.LineNumber,
                DOCUMENT_INFO, Expression.SymbolDocument(sourceName),  // I hope this is enough
                CONSTANTS, PersistentVector.EMPTY,
                CONSTANT_IDS, new IdentityHashMap(),
                KEYWORDS, PersistentHashMap.EMPTY,
                VARS, PersistentHashMap.EMPTY,
                KEYWORD_CALLSITES, PersistentVector.EMPTY,  // jvm doesn't do this, don't know why
                VAR_CALLSITES, PersistentVector.EMPTY,      // jvm doesn't do this, don't know why
                PROTOCOL_CALLSITES, PersistentVector.EMPTY, // jvm doesn't do this, don't know why
                COMPILER_CONTEXT, context
                ));

            try
            {
                FnExpr objx = new FnExpr(null);
                objx.InternalName = sourcePath.Replace(Path.PathSeparator, '/').Substring(0, sourcePath.LastIndexOf('.')) + "__init";

                TypeBuilder exprTB = context.AssemblyGen.DefinePublicType("__REPL__", typeof(object), true);

                //List<string> names = new List<string>();
                List<Expr> exprs = new List<Expr>();

                int i = 0;
                while ((form = LispReader.read(lntr, false, eofVal, false)) != eofVal)
                {
                    //Java version: LINE_AFTER.set(lntr.LineNumber);

                    Compile1(context, evalContext, exprTB, form, exprs, ref i);

                    //Java version: LINE_BEFORE.set(lntr.LineNumber);
                }

                Type exprType = exprTB.CreateType();

                // Need to put the loader init in its own type because we can't generate calls on the MethodBuilders
                //  until after their types have been closed.

                TypeBuilder initTB = context.AssemblyGen.DefinePublicType("__Init__", typeof(object), true);

                Expression pushNSExpr = Expression.Call(null, Method_Compiler_PushNS);
                Expression popExpr = Expression.Call(null, Method_Var_popThreadBindings);

                BodyExpr bodyExpr = new BodyExpr(PersistentVector.create1(exprs));
                FnMethod method = new FnMethod(objx, null, bodyExpr);
                objx.AddMethod(method);

                objx.Keywords = (IPersistentMap)KEYWORDS.deref();
                objx.Vars = (IPersistentMap)VARS.deref();
                objx.Constants = (PersistentVector)CONSTANTS.deref();
                objx.KeywordCallsites = (IPersistentVector)KEYWORD_CALLSITES.deref();
                objx.ProtocolCallsites = (IPersistentVector)PROTOCOL_CALLSITES.deref();
                objx.VarCallsites = (IPersistentVector)VAR_CALLSITES.deref();

                objx.Compile(typeof(AFunction), PersistentVector.EMPTY, false, context);

                Expression fnNew = objx.GenCode(RHC.Expression,objx,context);
                Expression fnInvoke = Expression.Call(fnNew, fnNew.Type.GetMethod("invoke", System.Type.EmptyTypes));

                Expression tryCatch = Expression.TryCatchFinally(fnInvoke, popExpr);

                Expression body = Expression.Block(pushNSExpr, tryCatch);

                // create initializer call
                MethodBuilder mbInit = initTB.DefineMethod("Initialize", MethodAttributes.Public | MethodAttributes.Static);
                LambdaExpression initFn = Expression.Lambda(body);
                //initFn.CompileToMethod(mbInit, DebugInfoGenerator.CreatePdbGenerator());
                initFn.CompileToMethod(mbInit, context.IsDebuggable);

                initTB.CreateType();

                context.SaveAssembly();
            }
            catch (LispReader.ReaderException e)
            {
                throw new CompilerException(sourceName, e.Line, e.InnerException);
            }
            finally
            {
                Var.popThreadBindings();
            }
            return null;
        }