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