WithNewDynInitHelper() 개인적인 메소드

private WithNewDynInitHelper ( ) : GenContext
리턴 GenContext
예제 #1
0
        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();
            }
        }
예제 #2
0
        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();
            }
        }
예제 #3
0
        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();
            }
        }
예제 #4
0
        internal static ObjExpr Build(
            IPersistentVector interfaceSyms,
            IPersistentVector fieldSyms,
            Symbol thisSym,
            string tagName,
            Symbol className,
            Symbol typeTag,
            ISeq methodForms,
            Object frm)
        {
            NewInstanceExpr ret = new NewInstanceExpr(null);

            ret._src         = frm;
            ret._name        = className.ToString();
            ret._classMeta   = GenInterface.ExtractAttributes(RT.meta(className));
            ret.InternalName = ret._name;  // ret.Name.Replace('.', '/');
            // Java: ret.objtype = Type.getObjectType(ret.internalName);

            if (thisSym != null)
            {
                ret._thisName = thisSym.Name;
            }

            if (fieldSyms != null)
            {
                IPersistentMap fmap      = PersistentHashMap.EMPTY;
                object[]       closesvec = new object[2 * fieldSyms.count()];
                for (int i = 0; i < fieldSyms.count(); i++)
                {
                    Symbol       sym = (Symbol)fieldSyms.nth(i);
                    LocalBinding lb  = new LocalBinding(-1, sym, null, new MethodParamExpr(Compiler.TagType(Compiler.TagOf(sym))), false, false, false);
                    fmap                 = fmap.assoc(sym, lb);
                    closesvec[i * 2]     = lb;
                    closesvec[i * 2 + 1] = lb;
                }
                // Java TODO: inject __meta et al into closes - when?
                // use array map to preserve ctor order
                ret.Closes = new PersistentArrayMap(closesvec);
                ret.Fields = fmap;
                for (int i = fieldSyms.count() - 1; i >= 0 && (((Symbol)fieldSyms.nth(i)).Name.Equals("__meta") || ((Symbol)fieldSyms.nth(i)).Name.Equals("__extmap")); --i)
                {
                    ret._altCtorDrops++;
                }
            }

            // Java TODO: set up volatiles
            //ret._volatiles = PersistentHashSet.create(RT.seq(RT.get(ret._optionsMap, volatileKey)));

            IPersistentVector interfaces = PersistentVector.EMPTY;

            for (ISeq s = RT.seq(interfaceSyms); s != null; s = s.next())
            {
                Type t = (Type)Compiler.Resolve((Symbol)s.first());
                if (!t.IsInterface)
                {
                    throw new ParseException("only interfaces are supported, had: " + t.Name);
                }
                interfaces = interfaces.cons(t);
            }
            Type superClass = typeof(Object);

            Dictionary <IPersistentVector, List <MethodInfo> > overrideables;

            GatherMethods(superClass, RT.seq(interfaces), out overrideables);

            ret._methodMap = overrideables;


            GenContext context = Compiler.IsCompiling
                ? Compiler.CompilerContextVar.get() as GenContext
                : (ret.IsDefType
                    ? GenContext.CreateWithExternalAssembly("deftype" + RT.nextID().ToString(), ".dll", true)
                    : (Compiler.CompilerContextVar.get() as GenContext
                       ??
                       Compiler.EvalContext));

            GenContext genC = context.WithNewDynInitHelper(ret.InternalName + "__dynInitHelper_" + RT.nextID().ToString());

            Type   stub    = CompileStub(genC, superClass, ret, SeqToTypeArray(interfaces), frm);
            Symbol thisTag = Symbol.intern(null, stub.FullName);

            //Symbol stubTag = Symbol.intern(null,stub.FullName);
            //Symbol thisTag = Symbol.intern(null, tagName);


            try
            {
                Var.pushThreadBindings(
                    RT.map(
                        Compiler.ConstantsVar, PersistentVector.EMPTY,
                        Compiler.ConstantIdsVar, new IdentityHashMap(),
                        Compiler.KeywordsVar, PersistentHashMap.EMPTY,
                        Compiler.VarsVar, PersistentHashMap.EMPTY,
                        Compiler.KeywordCallsitesVar, PersistentVector.EMPTY,
                        Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY,
                        Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(),
                        Compiler.NoRecurVar, null,
                        Compiler.CompilerContextVar, genC
                        ));

                if (ret.IsDefType)
                {
                    Var.pushThreadBindings(
                        RT.map(
                            Compiler.MethodVar, null,
                            Compiler.LocalEnvVar, ret.Fields,
                            Compiler.CompileStubSymVar, Symbol.intern(null, tagName),
                            Compiler.CompileStubClassVar, stub
                            ));
                    ret._hintedFields = RT.subvec(fieldSyms, 0, fieldSyms.count() - ret._altCtorDrops);
                }
                // now (methodname [args] body)*

                ret.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();

                IPersistentCollection methods = null;
                for (ISeq s = methodForms; s != null; s = RT.next(s))
                {
                    NewInstanceMethod m = NewInstanceMethod.Parse(ret, (ISeq)RT.first(s), thisTag, overrideables);
                    methods = RT.conj(methods, m);
                }

                ret._methods          = methods;
                ret.Keywords          = (IPersistentMap)Compiler.KeywordsVar.deref();
                ret.Vars              = (IPersistentMap)Compiler.VarsVar.deref();
                ret.Constants         = (PersistentVector)Compiler.ConstantsVar.deref();
                ret._constantsID      = RT.nextID();
                ret.KeywordCallsites  = (IPersistentVector)Compiler.KeywordCallsitesVar.deref();
                ret.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref();
                ret.VarCallsites      = (IPersistentSet)Compiler.VarCallsitesVar.deref();
            }
            finally
            {
                if (ret.IsDefType)
                {
                    Var.popThreadBindings();
                }
                Var.popThreadBindings();
            }

            // TOD:  Really, the first stub here should be 'superclass' but can't handle hostexprs nested in method bodies -- reify method compilation takes place before this sucker is compiled, so can't replace the call.
            // Might be able to flag stub classes and not try to convert, leading to a dynsite.

            //if (RT.CompileDLR)
            ret.Compile(stub, stub, interfaces, false, genC);
            //else
            //    ret.CompileNoDlr(stub, stub, interfaces, false, genC);

            Compiler.RegisterDuplicateType(ret.CompiledType);

            return(ret);
        }
예제 #5
0
파일: FnExpr.cs 프로젝트: silky/clojure-clr
        public static Expr Parse(ParserContext pcon, ISeq form, string name)
        {
            ISeq origForm = form;

            FnExpr fn = new FnExpr(Compiler.TagOf(form));

            fn._src = form;

            if (((IMeta)form.first()).meta() != null)
            {
                fn._onceOnly = RT.booleanCast(RT.get(RT.meta(form.first()), KW_ONCE));
            }

            fn.ComputeNames(form, name);

            List <string> prims = new List <string>();

            //arglist might be preceded by symbol naming this fn
            if (RT.second(form) is Symbol)
            {
                Symbol nm = (Symbol)RT.second(form);
                fn._thisName = nm.Name;
                fn._isStatic = false; // RT.booleanCast(RT.get(nm.meta(), Compiler.STATIC_KEY));
                form         = RT.cons(Compiler.FnSym, RT.next(RT.next(form)));
            }

            // Normalize body
            //now (fn [args] body...) or (fn ([args] body...) ([args2] body2...) ...)
            //turn former into latter
            if (RT.second(form) is IPersistentVector)
            {
                form = RT.list(Compiler.FnSym, RT.next(form));
            }

            fn.SpanMap = (IPersistentMap)Compiler.SourceSpanVar.deref();

            GenContext newContext = null;

            GenContext context = Compiler.CompilerContextVar.deref() as GenContext ?? Compiler.EvalContext;

            newContext = context.WithNewDynInitHelper(fn.InternalName + "__dynInitHelper_" + RT.nextID().ToString());
            Var.pushThreadBindings(RT.map(Compiler.CompilerContextVar, newContext));


            try
            {
                try
                {
                    Var.pushThreadBindings(RT.mapUniqueKeys(
                                               Compiler.ConstantsVar, PersistentVector.EMPTY,
                                               Compiler.ConstantIdsVar, new IdentityHashMap(),
                                               Compiler.KeywordsVar, PersistentHashMap.EMPTY,
                                               Compiler.VarsVar, PersistentHashMap.EMPTY,
                                               Compiler.KeywordCallsitesVar, PersistentVector.EMPTY,
                                               Compiler.ProtocolCallsitesVar, PersistentVector.EMPTY,
                                               Compiler.VarCallsitesVar, Compiler.EmptyVarCallSites(),
                                               Compiler.NoRecurVar, null));
                    SortedDictionary <int, FnMethod> methods = new SortedDictionary <int, FnMethod>();
                    FnMethod variadicMethod = null;

                    for (ISeq s = RT.next(form); s != null; s = RT.next(s))
                    {
                        FnMethod f = FnMethod.Parse(fn, (ISeq)RT.first(s), fn._isStatic);
                        if (f.IsVariadic)
                        {
                            if (variadicMethod == null)
                            {
                                variadicMethod = f;
                            }
                            else
                            {
                                throw new ParseException("Can't have more than 1 variadic overload");
                            }
                        }
                        else if (!methods.ContainsKey(f.RequiredArity))
                        {
                            methods[f.RequiredArity] = f;
                        }
                        else
                        {
                            throw new ParseException("Can't have 2 overloads with the same arity.");
                        }
                        if (f.Prim != null)
                        {
                            prims.Add(f.Prim);
                        }
                    }

                    if (variadicMethod != null && methods.Count > 0 && methods.Keys.Max() >= variadicMethod.NumParams)
                    {
                        throw new ParseException("Can't have fixed arity methods with more params than the variadic method.");
                    }

                    if (fn._isStatic && fn.Closes.count() > 0)
                    {
                        throw new ParseException("static fns can't be closures");
                    }

                    IPersistentCollection allMethods = null;
                    foreach (FnMethod method in methods.Values)
                    {
                        allMethods = RT.conj(allMethods, method);
                    }
                    if (variadicMethod != null)
                    {
                        allMethods = RT.conj(allMethods, variadicMethod);
                    }

                    fn._methods          = allMethods;
                    fn._variadicMethod   = variadicMethod;
                    fn.Keywords          = (IPersistentMap)Compiler.KeywordsVar.deref();
                    fn.Vars              = (IPersistentMap)Compiler.VarsVar.deref();
                    fn.Constants         = (PersistentVector)Compiler.ConstantsVar.deref();
                    fn.KeywordCallsites  = (IPersistentVector)Compiler.KeywordCallsitesVar.deref();
                    fn.ProtocolCallsites = (IPersistentVector)Compiler.ProtocolCallsitesVar.deref();
                    fn.VarCallsites      = (IPersistentSet)Compiler.VarCallsitesVar.deref();

                    fn._constantsID = RT.nextID();
                }
                finally
                {
                    Var.popThreadBindings();
                }


                IPersistentMap fmeta = RT.meta(origForm);
                if (fmeta != null)
                {
                    fmeta = fmeta.without(RT.LineKey).without(RT.ColumnKey).without(RT.SourceSpanKey).without(RT.FileKey);
                }
                fn._hasMeta = RT.count(fmeta) > 0;


                IPersistentVector primTypes = PersistentVector.EMPTY;
                foreach (string typename in prims)
                {
                    primTypes = primTypes.cons(Type.GetType(typename));
                }

                fn.Compile(
                    fn.IsVariadic ? typeof(RestFn) : typeof(AFunction),
                    null,
                    primTypes,
                    fn._onceOnly,
                    newContext);

                if (fn.SupportsMeta)
                {
                    return(new MetaExpr(fn, MapExpr.Parse(pcon.EvalOrExpr(), fmeta)));
                }
                else
                {
                    return(fn);
                }
            }
            finally
            {
                if (newContext != null)
                {
                    Var.popThreadBindings();
                }
            }
        }
예제 #6
0
        public Type Compile(Type superType, Type stubType, IPersistentVector interfaces, bool onetimeUse, GenContext context)
        {
            if (CompiledType != null)
            {
                return(CompiledType);
            }

            string publicTypeName = IsDefType /* || (CanBeDirect && 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.CompilingDefTypeVar, true
                                                   ));
                        //,
                        //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)
                    {
                        EmitFieldOnlyConstructors(TypeBuilder, superType);
                    }

                    if (SupportsMeta)
                    {
                        EmitNonMetaConstructor(TypeBuilder, superType);
                        EmitMetaFunctions(TypeBuilder);
                    }

                    EmitStatics(TypeBuilder);
                    EmitMethods(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();
            }
        }