public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context) { Expression basicBody = _tryExpr.GenCode(rhc, objx, context); if (basicBody.Type == typeof(void)) { basicBody = Expression.Block(basicBody, Expression.Default(typeof(object))); } Expression tryBody = Expression.Convert(basicBody, typeof(object)); CatchBlock[] catches = new CatchBlock[_catchExprs.count()]; for (int i = 0; i < _catchExprs.count(); i++) { CatchClause clause = (CatchClause)_catchExprs.nth(i); ParameterExpression parmExpr = Expression.Parameter(clause.Type, clause.Lb.Name); clause.Lb.ParamExpression = parmExpr; catches[i] = Expression.Catch(parmExpr, Expression.Convert(clause.Handler.GenCode(rhc, objx, context), typeof(object))); } Expression tryStmt = _finallyExpr == null ? catches.Length == 0 ? tryBody : Expression.TryCatch(tryBody, catches) : Expression.TryCatchFinally(tryBody, _finallyExpr.GenCode(RHC.Statement, objx, context), catches); return(tryStmt); }
public int CompareTo(object other) { IPersistentVector v = (IPersistentVector)other; if (v == null) { return(1); } if (count() < v.count()) { return(-1); } else if (count() > v.count()) { return(1); } for (int i = 0; i < count(); i++) { int c = Util.compare(nth(i), v.nth(i)); if (c != 0) { return(c); } } return(0); }
public override Expression GenDlr(GenContext context) { Expression basicBody = _tryExpr.GenDlr(context); // Wrap the basic body, a Comma, in a return to a label LabelTarget target = Expression.Label(basicBody.Type, "ret_label"); //Expression tryBody = Expression.Return(target, basicBody); Expression tryBody = basicBody; CatchBlock[] catches = new CatchBlock[_catchExprs.count()]; for (int i = 0; i < _catchExprs.count(); i++) { CatchClause clause = (CatchClause)_catchExprs.nth(i); ParameterExpression parmExpr = Expression.Parameter(clause.Type, clause.Lb.Name); clause.Lb.ParamExpression = parmExpr; catches[i] = Expression.Catch(parmExpr, clause.Handler.GenDlr(context)); } TryExpression tryStmt = _finallyExpr == null ? Expression.TryCatch(tryBody, catches) : Expression.TryCatchFinally(tryBody, _finallyExpr.GenDlr(context), catches); Expression defaultValue = Expression.Default(basicBody.Type); Expression whole = Expression.Block(tryStmt, Expression.Label(target, defaultValue)); return(whole); }
public Expr Parse(object frm) { ISeq form = (ISeq)frm; IPersistentVector loopLocals = (IPersistentVector)Compiler.LOOP_LOCALS.deref(); if (Compiler.IN_TAIL_POSITION.deref() == null || loopLocals == null) { throw new InvalidOperationException("Can only recur from tail position"); } if (Compiler.IN_CATCH_FINALLY.deref() != null) { throw new InvalidOperationException("Cannot recur from catch/finally."); } IPersistentVector args = PersistentVector.EMPTY; for (ISeq s = form.next(); s != null; s = s.next()) { args = args.cons(Compiler.GenerateAST(s.first())); } if (args.count() != loopLocals.count()) { throw new ArgumentException(string.Format("Mismatched argument count to recur, expected: {0} args, got {1}", loopLocals.count(), args.count())); } return(new RecurExpr(loopLocals, args)); }
static bool doEquiv(IPersistentVector v, object obj) { if (obj is IPersistentVector ipv) { if (ipv.count() != v.count()) { return(false); } for (int i = 0; i < v.count(); i++) { if (!Util.equiv(v.nth(i), ipv.nth(i))) { return(false); } } return(true); } if (obj is IList ilist) { if (ilist.Count != v.count()) // THis test in the JVM code can't be right: || ma.GetHashCode() != v.GetHashCode()) { return(false); } for (int i = 0; i < v.count(); i++) { if (!Util.equiv(v.nth(i), ilist[i])) { return(false); } } return(true); } if (!(obj is Sequential)) { return(false); } ISeq ms = RT.seq(obj); for (int i = 0; i < v.count(); i++, ms = ms.next()) { if (ms == null || !Util.equiv(v.nth(i), ms.first())) { return(false); } } if (ms != null) { return(false); } return(true); }
public object Eval() { Object[] ret = new Object[_keyvals.count()]; for (int i = 0; i < _keyvals.count(); i++) { ret[i] = ((Expr)_keyvals.nth(i)).Eval(); } return(RT.map(ret)); }
public object Eval() { IPersistentVector ret = PersistentVector.EMPTY; for (int i = 0; i < _args.count(); i++) { ret = (IPersistentVector)ret.cons(((Expr)_args.nth(i)).Eval()); } return(ret); }
private static Type[] SeqToTypeArray(IPersistentVector interfaces) { Type[] types = new Type[interfaces.count()]; for (int i = 0; i < interfaces.count(); i++) { types[i] = (Type)interfaces.nth(i); } return(types); }
internal static int GetMatchingParams(string methodName, List<ParameterInfo[]> parmlists, IPersistentVector argexprs, List<Type> rets) { // Assume matching lengths int matchIndex = -1; bool tied = false; bool foundExact = false; for (int i = 0; i < parmlists.Count; i++) { bool match = true; ISeq aseq = argexprs.seq(); int exact = 0; for (int p = 0; match && p < argexprs.count() && aseq != null; ++p, aseq = aseq.next()) { Expr arg = (Expr)aseq.first(); Type atype = arg.HasClrType ? arg.ClrType : typeof(object); Type ptype = parmlists[i][p].ParameterType; if (arg.HasClrType && atype == ptype) exact++; else match = Reflector.ParamArgTypeMatch(ptype, atype); } if (exact == argexprs.count()) { if ( !foundExact || matchIndex == -1 || rets[matchIndex].IsAssignableFrom(rets[i])) matchIndex = i; foundExact = true; } else if (match && !foundExact) { if (matchIndex == -1) matchIndex = i; else { if (Reflector.Subsumes(parmlists[i], parmlists[matchIndex])) { matchIndex = i; tied = false; } else if (Array.Equals(parmlists[i], parmlists[matchIndex])) if (rets[matchIndex].IsAssignableFrom(rets[i])) matchIndex = i; else if (!Reflector.Subsumes(parmlists[matchIndex], parmlists[i])) tied = true; } } } if (tied) throw new ArgumentException("More than one matching method found: " + methodName); return matchIndex; }
public object Eval() { object ret = null; for (int i = 0; i < _exprs.count(); i++) { ret = ((Expr)_exprs.nth(i)).Eval(); } return(ret); }
internal static void EmitArgsAsArray(IPersistentVector args, ObjExpr objx, CljILGen ilg) { ilg.EmitInt(args.count()); ilg.Emit(OpCodes.Newarr, typeof(Object)); for (int i = 0; i < args.count(); i++) { ilg.Emit(OpCodes.Dup); ilg.EmitInt(i); ((Expr)args.nth(i)).Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Stelem_Ref); } }
void GenerateMethod(ObjExpr objx, GenContext context) { if (Prim != null) { GeneratePrimMethod(objx, context); } TypeBuilder tb = objx.TypeBuilder; MethodBuilder mb = tb.DefineMethod(MethodName, MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual, ReturnType, ArgTypes); //Console.Write("InMd: {0} {1}(", ReturnType.Name, MethodName); //foreach (Type t in ArgTypes) // Console.Write("{0}", t.Name); //Console.WriteLine(")"); GenInterface.SetCustomAttributes(mb, _methodMeta); if (_parms != null) { for (int i = 0; i < _parms.count(); i++) { IPersistentMap meta = GenInterface.ExtractAttributes(RT.meta(_parms.nth(i))); if (meta != null && meta.count() > 0) { ParameterBuilder pb = mb.DefineParameter(i + 1, ParameterAttributes.None, ((Symbol)_parms.nth(i)).Name); GenInterface.SetCustomAttributes(pb, meta); } } } ILGen gen = new ILGen(mb.GetILGenerator()); gen.EmitLoadArg(0); for (int i = 1; i <= _argLocals.count(); i++) { gen.EmitLoadArg(i); } gen.EmitCall(_staticMethodBuilder); if (ReturnType != StaticReturnType) { gen.Emit(OpCodes.Castclass, ReturnType); } gen.Emit(OpCodes.Ret); if (IsExplicit) { tb.DefineMethodOverride(mb, _explicitMethodInfo); } }
private Expression GenDlrViaReflection(GenContext context) { Expression[] parms = new Expression[_args.count()]; for (int i = 0; i < _args.count(); i++) { parms[i] = Compiler.MaybeBox(((Expr)_args.nth(i)).GenDlr(context)); } Expression[] moreArgs = new Expression[3]; moreArgs[0] = Expression.Constant(_methodName); moreArgs[1] = _target.GenDlr(context); moreArgs[2] = Expression.NewArrayInit(typeof(object), parms); return(Expression.Call(Compiler.Method_Reflector_CallInstanceMethod, moreArgs)); }
private void GenerateFnClass(IPersistentVector interfaces, GenContext context) { 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, _baseType, true); for (int i = 0; i < interfaces.count(); i++) { _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i)); } MarkAsSerializable(_typeBuilder); GenInterface.SetCustomAttributes(_typeBuilder, _classMeta); GenerateStaticConstructor(_typeBuilder, _baseType, context.IsDebuggable); _ctorInfo = GenerateConstructor(_typeBuilder, _baseType); if (_altCtorDrops > 0) { GenerateFieldOnlyConstructor(_typeBuilder, _baseType); } if (SupportsMeta) { /*_nonMetaCtorInfo = */ GenerateNonMetaConstructor(_typeBuilder, _baseType); } GenerateMetaFunctions(_typeBuilder); GenerateStatics(context); GenerateMethods(context); }
private static MethodInfo GetMatchingMethodAux(Type targetType, IPersistentVector args, string methodName, bool getStatics) { MethodInfo method = null; List <MethodInfo> methods = HostExpr.GetMethods(targetType, args.count(), methodName, getStatics); if (methods.Count == 0) { method = null; } else { int index = 0; if (methods.Count > 1) { List <ParameterInfo[]> parms = new List <ParameterInfo[]>(methods.Count); List <Type> rets = new List <Type>(methods.Count); foreach (MethodInfo mi in methods) { parms.Add(mi.GetParameters()); rets.Add(mi.ReturnType); } index = GetMatchingParams(methodName, parms, args, rets); } method = (index >= 0 ? methods[index] : null); } return(method); }
public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg) { if (_variadic) { ParameterInfo[] pinfos = _method.GetParameters(); for (int i = 0; i < pinfos.Length - 1; i++) { Expr e = (Expr)_args.nth(i); if (Compiler.MaybePrimitiveType(e) == pinfos[i].ParameterType) { ((MaybePrimitiveExpr)e).EmitUnboxed(RHC.Expression, objx, ilg); } else { e.Emit(RHC.Expression, objx, ilg); HostExpr.EmitUnboxArg(objx, ilg, pinfos[i].ParameterType); } } IPersistentVector restArgs = RT.subvec(_args, pinfos.Length - 1, _args.count()); MethodExpr.EmitArgsAsArray(restArgs, objx, ilg); ilg.EmitCall(Compiler.Method_ArraySeq_create); } else { MethodExpr.EmitTypedArgs(objx, ilg, _method.GetParameters(), _args); } ilg.EmitCall(_method); }
public RecordEnumerable(ILookup rec, IPersistentVector baseFields, IEnumerator extmap) { _rec = rec; _baseFields = baseFields; _basecnt = baseFields.count(); _extmap = extmap; }
/// <summary> /// Enqueue nested actions. /// </summary> /// <returns></returns> /// <remarks>lowercase for core.clj compatibility</remarks> public static int releasePendingSends() { IPersistentVector sends = Agent.Nested; if (sends == null) { return(0); } for (int i = 0; i < sends.count(); i++) { Action a = (Action)sends.valAt(i); a.Agent.Enqueue(a); } Nested = PersistentVector.EMPTY; return(sends.count()); }
public static Expr Parse(ParserContext pcon, IPersistentVector form) { ParserContext pconToUse = pcon.EvEx(); bool constant = true; IPersistentVector args = PersistentVector.EMPTY; for (int i = 0; i < form.count(); i++ ) { Expr v = Compiler.Analyze(pconToUse, form.nth(i)); args = (IPersistentVector)args.cons(v); if ( !(v is LiteralExpr) ) constant = false; } Expr ret = new VectorExpr(args); if ( form is IObj && ((IObj)form).meta() != null ) return Compiler.OptionallyGenerateMetaInit(pcon,form, ret); else if ( constant ) { IPersistentVector rv = PersistentVector.EMPTY; for ( int i=0; i<args.count(); i++ ) { LiteralExpr ve = (LiteralExpr)args.nth(i); rv = (IPersistentVector)rv.cons(ve.Val); } return new ConstantExpr(rv); } else return ret; }
public Expr Parse(ParserContext pcon, object frms) { ISeq forms = (ISeq)frms; if (Util.equals(RT.first(forms), Compiler.DoSym)) { forms = RT.next(forms); } IPersistentVector exprs = PersistentVector.EMPTY; for (; forms != null; forms = forms.next()) { Expr e = (pcon.Rhc != RHC.Eval && (pcon.Rhc == RHC.Statement || forms.next() != null)) ? Compiler.Analyze(pcon.SetRhc(RHC.Statement), forms.first()) : Compiler.Analyze(pcon, forms.first()); exprs = exprs.cons(e); } if (exprs.count() == 0) { exprs = exprs.cons(Compiler.NilExprInstance); } return(new BodyExpr(exprs)); }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null) { Var fvar = varFexpr.Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.ProtocolKeyword); if (pvar != null && Compiler.ProtocolCallsitesVar.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); IList<MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false); if (methods.Count != 1) throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); _onMethod = (MethodInfo) methods[0]; } } } if (tag != null) _tag = tag; else if (varFexpr != null) { object arglists = RT.get(RT.meta(varFexpr.Var), Compiler.ArglistsKeyword); object sigTag = null; for (ISeq s = RT.seq(arglists); s != null; s = s.next()) { APersistentVector sig = (APersistentVector)s.first(); int restOffset = sig.IndexOf(Compiler.AmpersandSym); if (args.count() == sig.count() || (restOffset > -1 && args.count() >= restOffset)) { sigTag = Compiler.TagOf(sig); break; } } _tag = sigTag ?? varFexpr.Tag; } else _tag = null; }
public Expression GenCode(RHC rhc, ObjExpr objx, GenContext context) { int n = _bindingInits.count(); List <ParameterExpression> parms = new List <ParameterExpression>(n); List <Expression> forms = new List <Expression>(n); /// First, set up the environment. for (int i = 0; i < n; i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); ParameterExpression parmExpr = Expression.Parameter(typeof(IFn), bi.Binding.Name); bi.Binding.ParamExpression = parmExpr; parms.Add(parmExpr); } // Then initialize for (int i = 0; i < n; i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); ParameterExpression parmExpr = (ParameterExpression)bi.Binding.ParamExpression; forms.Add(Expression.Assign(parmExpr, bi.Init.GenCode(RHC.Expression, objx, context))); } // The work forms.Add(_body.GenCode(rhc, objx, context)); return(Expression.Block(parms, forms)); }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args, bool tailPosition) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; _tailPosition = tailPosition; VarExpr varFexpr = fexpr as VarExpr; if (varFexpr != null) { Var fvar = varFexpr.Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.ProtocolKeyword); if (pvar != null && Compiler.ProtocolCallsitesVar.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); IList <MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false); if (methods.Count != 1) { throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } _onMethod = (MethodInfo)methods[0]; } } } if (tag != null) { _tag = tag; } else if (varFexpr != null) { Var v = varFexpr.Var; //object arglists = RT.get(RT.meta(v), Compiler.ArglistsKeyword); object sigTag = SigTag(_args.count(), v); _tag = sigTag ?? varFexpr.Tag; } else { _tag = null; } }
public override object invoke() { if (_i < _v.count()) { return(_v.nth(_i++)); } return(RT.EOS); }
void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed) { List <LocalBuilder> locals = new List <LocalBuilder>(); for (int i = 0; i < _bindingInits.count(); i++) { BindingInit bi = (BindingInit)_bindingInits.nth(i); Type primType = Compiler.MaybePrimitiveType(bi.Init); if (primType != null) { LocalBuilder local = ilg.DeclareLocal(primType); locals.Add(local); GenContext.SetLocalName(local, bi.Binding.Name); bi.Binding.LocalVar = local; ((MaybePrimitiveExpr)bi.Init).EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Stloc, local); } else { LocalBuilder local = ilg.DeclareLocal(typeof(Object)); locals.Add(local); GenContext.SetLocalName(local, bi.Binding.Name); bi.Binding.LocalVar = local; bi.Init.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Stloc, local); } } Label loopLabel = ilg.DefineLabel(); ilg.MarkLabel(loopLabel); try { if (_isLoop) { Var.pushThreadBindings(PersistentHashMap.create(Compiler.LoopLabelVar, loopLabel)); } if (emitUnboxed) { ((MaybePrimitiveExpr)_body).EmitUnboxed(rhc, objx, ilg); } else { _body.Emit(rhc, objx, ilg); } } finally { if (_isLoop) { Var.popThreadBindings(); } } }
public void CreateOnNonEmptyCollectionReturnsVector() { IPersistentVector v = LazilyPersistentVector.createOwning(new object[] { 1, 2, 3 }); Expect(v.count(), EqualTo(3)); Expect(v.nth(0), EqualTo(1)); Expect(v.nth(1), EqualTo(2)); Expect(v.nth(2), EqualTo(3)); }
public void NthInRangeWorks() { IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3); Expect(v.count(), EqualTo(3)); Expect(v.nth(0), EqualTo(1)); Expect(v.nth(1), EqualTo(2)); Expect(v.nth(2), EqualTo(3)); }
public override Expression GenDlr(GenContext context) { List <Expression> exprs = new List <Expression>(_exprs.count()); for (int i = 0; i < _exprs.count() - 1; i++) { Expr e = (Expr)_exprs.nth(i); exprs.Add(e.GenDlr(context)); } // In Java version, this is split off because the Context in the calls above is forced to be C.STATEMENT. // TODO: Wrap this into the loop above. No real need to do this way. Expr last = (Expr)_exprs.nth(_exprs.count() - 1); exprs.Add(last.GenDlr(context)); return(Expression.Block(exprs)); }
void GenerateMethod(MethodInfo staticMethodInfo, GenContext context) { string methodName = IsVariadic ? "doInvoke" : "invoke"; TypeBuilder tb = context.FnExpr.TypeBuilder; // TODO: Cache all the CreateObjectTypeArray values MethodBuilder mb = tb.DefineMethod(methodName, MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual, typeof(object), Compiler.CreateObjectTypeArray(NumParams)); ILGenerator gen = mb.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); for (int i = 1; i <= _argLocals.count(); i++) { gen.Emit(OpCodes.Ldarg, i); } gen.Emit(OpCodes.Call, staticMethodInfo); gen.Emit(OpCodes.Ret); }
public void AssocNAddsAtEndForEmpty() { PersistentVector v1 = PersistentVector.create(); IPersistentVector v2 = v1.assocN(0, "abc"); Expect(v1.count(), EqualTo(0)); Expect(v2.count(), EqualTo(1)); Expect(v2.nth(0), EqualTo("abc")); }
public static Expr Parse(IPersistentVector form) { IPersistentVector args = PersistentVector.EMPTY; for (int i = 0; i < form.count(); i++ ) args = (IPersistentVector)args.cons(Compiler.GenerateAST(form.nth(i),false)); Expr ret = new VectorExpr(args); return Compiler.OptionallyGenerateMetaInit(form, ret); }
public void ConsWorks() { PersistentVector v1 = PersistentVector.create(2, 3, 4); IPersistentVector v2 = v1; for (int i = 3; i < 100000; i++) { v2 = v2.cons(i + 2); } Expect(v1.count(), EqualTo(3)); Expect(v2.count(), EqualTo(100000)); for (int i = 0; i < v2.count(); ++i) { Expect(v2.nth(i), EqualTo(i + 2)); } }
public void NthInRangeWorks() { IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3); Expect(v.count()).To.Equal(3); Expect(v.nth(0)).To.Equal(1); Expect(v.nth(1)).To.Equal(2); Expect(v.nth(2)).To.Equal(3); }
public void CreatingOwningOnParamsReturnsVector() { IPersistentVector v = LazilyPersistentVector.createOwning(1, 2, 3); Expect(v.count(), EqualTo(3)); Expect(v.nth(0), EqualTo(1)); Expect(v.nth(1), EqualTo(2)); Expect(v.nth(2), EqualTo(3)); }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; if (fexpr is VarExpr) { Var fvar = ((VarExpr)fexpr).Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.PROTOCOL_KEY); if (pvar != null && Compiler.PROTOCOL_CALLSITES.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); List<MethodBase> methods = Reflector.GetMethods(_protocolOn, mname, null, args.count() - 1, false); if (methods.Count != 1) throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); _onMethod = (MethodInfo) methods[0]; } } } _tag = tag ?? (fexpr is VarExpr ? ((VarExpr)fexpr).Tag : null); }
private static Expression GenerateVectorExpr(IPersistentVector v) { int n = v.count(); Expression[] args = new Expression[v.count()]; for (int i = 0; i < n; i++) args[i] = Generate(v.nth(i)); Expression arrayExpr = Expression.NewArrayInit(typeof(object), MaybeBox(args)); Expression ret = Expression.Call(Method_RT_vector, arrayExpr); ret = OptionallyGenerateMetaInit(v,ret); return ret; }
private static MethodInfo GetMatchingMethodAux(Type targetType, IPersistentVector args, string methodName, bool getStatics) { MethodInfo method = null; List<MethodInfo> methods = HostExpr.GetMethods(targetType, args.count(), methodName, getStatics); if (methods.Count == 0) method = null; else { int index = 0; if (methods.Count > 1) { List<ParameterInfo[]> parms = new List<ParameterInfo[]>(methods.Count); List<Type> rets = new List<Type>(methods.Count); foreach (MethodInfo mi in methods) { parms.Add(mi.GetParameters()); rets.Add(mi.ReturnType); } index = GetMatchingParams(methodName, parms, args, rets); } method = (index >= 0 ? methods[index] : null); } return method; }
public InvokeExpr(string source, IPersistentMap spanMap, Symbol tag, Expr fexpr, IPersistentVector args) { _source = source; _spanMap = spanMap; _fexpr = fexpr; _args = args; if (fexpr is VarExpr) { Var fvar = ((VarExpr)fexpr).Var; Var pvar = (Var)RT.get(fvar.meta(), Compiler.PROTOCOL_KEY); if (pvar != null && Compiler.PROTOCOL_CALLSITES.isBound) { _isProtocol = true; _siteIndex = Compiler.RegisterProtocolCallsite(fvar); Object pon = RT.get(pvar.get(), _onKey); _protocolOn = HostExpr.MaybeType(pon, false); if (_protocolOn != null) { IPersistentMap mmap = (IPersistentMap)RT.get(pvar.get(), _methodMapKey); Keyword mmapVal = (Keyword)mmap.valAt(Keyword.intern(fvar.sym)); if (mmapVal == null) { throw new ArgumentException(String.Format("No method of interface: {0} found for function: {1} of protocol: {2} (The protocol method may have been defined before and removed.)", _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); } String mname = Compiler.munge(mmapVal.Symbol.ToString()); List<MethodInfo> methods = Reflector.GetMethods(_protocolOn, mname, args.count() - 1, false); if (methods.Count != 1) throw new ArgumentException(String.Format("No single method: {0} of interface: {1} found for function: {2} of protocol: {3}", mname, _protocolOn.FullName, fvar.Symbol, pvar.Symbol)); _onMethod = methods[0]; } } //else if (pvar == null && Compiler.VAR_CALLSITES.isBound // && fvar.Namespace.Name.Name.StartsWith("clojure") // && !RT.booleanCast(RT.get(RT.meta(fvar), _dynamicKey))) //{ // // Java TODO: more specific criteria for binding these // _isDirect = true; // _siteIndex = Compiler.RegisterVarCallsite(fvar); //} } _tag = tag ?? (fexpr is VarExpr ? ((VarExpr)fexpr).Tag : null); }
private static Type[] SeqToTypeArray(IPersistentVector interfaces) { Type[] types = new Type[interfaces.count()]; for (int i = 0; i < interfaces.count(); i++) types[i] = (Type)interfaces.nth(i); return types; }
// There is a tremendous overlap between this and GenerateFnExpr+GenerateFnMethod. TODO: DRY it. private static LambdaExpression GenerateTypedDelegateExpression(Type delegateType, Symbol name, IPersistentVector parms, ISeq body) { // Create the form that is more or less correct ISeq form = (name == null) ? RT.cons(Compiler.FN, RT.cons(parms, body)) : RT.cons(Compiler.FN, RT.cons(name, RT.cons(parms, body))); FnDef fnDef = new FnDef(null); // compute tag from delegateType? fnDef.ComputeNames(form); MethodDef methodDef = new MethodDef(fnDef, (MethodDef)METHODS.deref()); try { LabelTarget loopLabel = Expression.Label(); Var.pushThreadBindings(PersistentHashMap.create( METHODS, methodDef, LOOP_LABEL, loopLabel, LOCAL_ENV, LOCAL_ENV.deref(), LOOP_LOCALS, null)); // register 'this' as local 0 LocalBinding thisB = RegisterLocal(Symbol.intern(fnDef.ThisName ?? "fn__" + RT.nextID()), null, null); thisB.ParamExpression = fnDef.ThisParam; IPersistentVector argLocals = PersistentVector.EMPTY; int parmsCount = parms.count(); ParamParseState paramState = ParamParseState.Required; for (int i = 0; i < parmsCount; i++) { if (!(parms.nth(i) is Symbol)) throw new ArgumentException("fn params must be Symbols"); Symbol p = parms.nth(i) as Symbol; if (p.Namespace != null) throw new Exception("Can't use qualified name as parameter: " + p); if (p.Equals(Compiler._AMP_)) { if (paramState == ParamParseState.Required) paramState = ParamParseState.Rest; else throw new Exception("Invalid parameter list"); } else { // TODO: Need more type inferencing to make this work. //LocalBinding b = RegisterLocal(p, paramState == ParamParseState.Rest ? ISEQ : TagOf(p), null); LocalBinding b = RegisterLocal(p, TagOf(p), null); argLocals = argLocals.cons(b); switch (paramState) { case ParamParseState.Required: methodDef.ReqParms = methodDef.ReqParms.cons(b); break; case ParamParseState.Rest: methodDef.RestParm = b; paramState = ParamParseState.Done; break; default: throw new Exception("Unexpected parameter"); } } } MethodInfo invokeMI = delegateType.GetMethod("Invoke"); Type returnType = invokeMI.ReturnType; ParameterInfo[] delParams = invokeMI.GetParameters(); bool isVariadic = (invokeMI.CallingConvention & CallingConventions.VarArgs) != 0; if (isVariadic != methodDef.IsVariadic) throw new ArgumentException("Arglist and delegate type must agree on being variadic."); if (delParams.Length != argLocals.count() ) throw new ArgumentException("Wrong number of parameters to generate typed delegate"); if (methodDef.NumParams > MAX_POSITIONAL_ARITY) throw new Exception(string.Format("Can't specify more than {0} parameters",MAX_POSITIONAL_ARITY)); LOOP_LOCALS.set(argLocals); methodDef.ArgLocals = argLocals; List<ParameterExpression> parmExprs = new List<ParameterExpression>(argLocals.count()); for (int i = 0; i < argLocals.count(); i++) { LocalBinding b = (LocalBinding)argLocals.nth(i); ParameterExpression pexpr = Expression.Parameter(delParams[i].ParameterType, b.Name); //asdf-tag b.ParamExpression = pexpr; parmExprs.Add(pexpr); } methodDef.Lambda = Expression.Lambda( delegateType, Expression.Block( Expression.Label(loopLabel), Expression.Convert(GenerateBodyExpr(body),returnType)), fnDef.Name, parmExprs); return methodDef.Lambda; } finally { Var.popThreadBindings(); } }
public static bool IsPrimInterface(IPersistentVector arglist) { if (arglist.count() > 4) return false; for (int i = 0; i < arglist.count(); i++) if (IsPrimType(Compiler.TagOf(arglist.nth(i)))) return true; if (IsPrimType(Compiler.TagOf(arglist))) return true; return false; }
public static string PrimInterface(IPersistentVector arglist) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < arglist.count(); i++) sb.Append(TypeChar(Compiler.TagOf(arglist.nth(i)))); sb.Append(TypeChar(Compiler.TagOf(arglist))); string ret = sb.ToString(); bool prim = ret.Contains("L") || ret.Contains("D"); if (prim && arglist.count() > 4) throw new ArgumentException("fns taking primitives support only 4 or fewer args"); if (prim) return "clojure.lang.primifs." + ret; return null; }
internal static Expression GenArgArray(GenContext context, IPersistentVector args) { Expression[] exprs = new Expression[args.count()]; for (int i = 0; i < args.count(); i++) { Expr arg = (Expr)args.nth(i); exprs[i] = Compiler.MaybeBox(arg.GenDlr(context)); } Expression argArray = Expression.NewArrayInit(typeof(object), exprs); return argArray; }
/// <summary> /// Compares an <see cref="IPersistentVector">IPersistentVector</see> to another object for equality. /// </summary> /// <param name="v">The <see cref="IPersistentVector">IPersistentVector</see> to compare.</param> /// <param name="obj">The other object to compare.</param> /// <returns><value>true</value> if the specified Object is equal to the current Object; /// otherwise, <value>false</value>. /// </returns> public static bool doEquals(IPersistentVector v, object obj) { if (obj is IList || obj is IPersistentVector) { IList ma = obj as IList; if (ma.Count != v.count() || ma.GetHashCode() != v.GetHashCode()) return false; for (int i = 0; i < v.count(); i++) { if (!Util.equals(v.nth(i), ma[i])) return false; } return true; } else { if (!(obj is Sequential)) return false; ISeq ms = RT.seq(obj); for (int i = 0; i < v.count(); i++, ms = ms.next()) { if (ms == null || !Util.equals(v.nth(i), ms.first())) return false; } if (ms != null) return false; } return true; }
static string[] InterfaceNames(IPersistentVector interfaces) { int icnt = interfaces.count(); string[] inames = icnt > 0 ? new string[icnt] : null; for (int i = 0; i < icnt; i++) inames[i] = SlashName((Type)interfaces.nth(i)); return inames; }
/// <summary> /// Compares an <see cref="IPersistentVector">IPersistentVector</see> to another object for equality. /// </summary> /// <param name="v">The <see cref="IPersistentVector">IPersistentVector</see> to compare.</param> /// <param name="obj">The other object to compare.</param> /// <returns><value>true</value> if the specified Object is equal to the current Object; /// otherwise, <value>false</value>. /// </returns> public static bool doEquals(IPersistentVector v, object obj) { if ( obj is IList || obj is IPersistentVector ) { IList ma = obj as IList; if (ma.Count != v.count() || ma.GetHashCode() != v.GetHashCode()) return false; for ( int i=0; i<v.count(); i++ ) { if (!Util.equals(v.nth(i), ma[i])) return false; } return true; } // Example in original code of Sequential/IPersistentVector conflation. //if(!(obj instanceof Sequential)) // return false; // ISeq ms = ((IPersistentCollection) obj).seq(); // for(int i = 0; i < v.count(); i++, ms = ms.rest()) // { // if(ms == null || !Util.equals(v.nth(i), ms.first())) // return false; // } // if(ms != null) // return false; // } //return true; ISeq ms = obj as ISeq; if (ms == null) { IPersistentCollection mc = obj as IPersistentCollection; if (mc == null) return false; ms = mc.seq(); } // Once we have the ISeq, we're ready to go. for (int i = 0; i < v.count(); i++, ms = ms.rest()) { if (ms == null || !Util.equals(v.nth(i), ms.first())) return false; } if (ms != null) return false; return true; }
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); 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.StartsWith("__"); --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 ArgumentException("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; //string[] inames = InterfaceNames(interfaces); Type stub = CompileStub(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); // Needs its own GenContext so it has its own DynInitHelper // Can't reuse Compiler.EvalContext if it is a DefType because we have to use the given name and will get a conflict on redefinition GenContext context = Compiler.COMPILER_CONTEXT.get() as GenContext ?? (ret.IsDefType ? new GenContext("deftype" + RT.nextID().ToString(),".dll",".",true) : Compiler.EvalContext); GenContext genC = context.WithNewDynInitHelper(ret.InternalName + "__dynInitHelper_" + RT.nextID().ToString()); //genC.FnCompileMode = FnMode.Full; try { Var.pushThreadBindings( RT.map( Compiler.CONSTANTS, PersistentVector.EMPTY, Compiler.CONSTANT_IDS, new IdentityHashMap(), Compiler.KEYWORDS, PersistentHashMap.EMPTY, Compiler.VARS, PersistentHashMap.EMPTY, Compiler.KEYWORD_CALLSITES, PersistentVector.EMPTY, Compiler.PROTOCOL_CALLSITES, PersistentVector.EMPTY, Compiler.VAR_CALLSITES, PersistentVector.EMPTY, Compiler.COMPILER_CONTEXT, genC )); if (ret.IsDefType) { Var.pushThreadBindings( RT.map( Compiler.METHOD, null, Compiler.LOCAL_ENV, ret._fields, Compiler.COMPILE_STUB_SYM, Symbol.intern(null, tagName), Compiler.COMPILE_STUB_CLASS, stub )); } // now (methodname [args] body)* // TODO: SourceLocation? //ret.line = (Integer)LINE.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.KEYWORDS.deref(); ret.Vars = (IPersistentMap)Compiler.VARS.deref(); ret.Constants = (PersistentVector)Compiler.CONSTANTS.deref(); ret._constantsID = RT.nextID(); ret.KeywordCallsites = (IPersistentVector)Compiler.KEYWORD_CALLSITES.deref(); ret.ProtocolCallsites = (IPersistentVector)Compiler.PROTOCOL_CALLSITES.deref(); ret.VarCallsites = (IPersistentVector)Compiler.VAR_CALLSITES.deref(); } finally { if (ret.IsDefType) Var.popThreadBindings(); Var.popThreadBindings(); } ret.Compile(stub, interfaces, false, genC); Compiler.RegisterDuplicateType(ret.CompiledType); return ret; }
private static void DefineMethod(TypeBuilder proxyTB, IPersistentVector sig) { Symbol mname = (Symbol)sig.nth(0); Type[] paramTypes = GenClass.CreateTypeArray((ISeq)sig.nth(1)); Type retType = (Type)sig.nth(2); ISeq pmetas = (ISeq)(sig.count() >= 4 ? sig.nth(3) : null); MethodBuilder mb = proxyTB.DefineMethod(mname.Name, MethodAttributes.Abstract | MethodAttributes.Public| MethodAttributes.Virtual, retType, paramTypes); SetCustomAttributes(mb, GenInterface.ExtractAttributes(RT.meta(mname))); int i=1; for (ISeq s = pmetas; s != null; s = s.next(), i++) { IPersistentMap meta = GenInterface.ExtractAttributes((IPersistentMap)s.first()); if (meta != null && meta.count() > 0) { ParameterBuilder pb = mb.DefineParameter(i, ParameterAttributes.None, String.Format("p_{0}",i)); GenInterface.SetCustomAttributes(pb, meta); } } }
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(); } }
internal static ObjExpr Build( IPersistentVector interfaceSyms, IPersistentVector fieldSyms, Symbol thisSym, string tagName, Symbol className, Symbol typeTag, ISeq methodForms, Object frm, IPersistentMap opts) { 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); ret.Opts = opts; 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, IList<MethodInfo>> overrideables; Dictionary<IPersistentVector, IList<MethodInfo>> explicits; GatherMethods(superClass, RT.seq(interfaces), out overrideables, out explicits); 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 baseClass = ret.CompileBaseClass(genC, superClass, SeqToTypeArray(interfaces), frm); Symbol thisTag = Symbol.intern(null, baseClass.FullName); 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, Compiler.CompilerContextVar, genC )); if (ret.IsDefType) { Var.pushThreadBindings( RT.mapUniqueKeys( Compiler.MethodVar, null, Compiler.LocalEnvVar, ret.Fields, Compiler.CompileStubSymVar, Symbol.intern(null, tagName), Compiler.CompileStubClassVar, baseClass )); 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, explicits); 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 baseclass 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 baseclass classes and not try to convert, leading to a dynsite. ret.Compile(baseClass, baseClass, interfaces, false, genC); Compiler.RegisterDuplicateType(ret.CompiledType); return ret; }
static bool doEquiv(IPersistentVector v, object obj) { if (obj is IList || obj is IPersistentVector) { ICollection ma = (ICollection)obj; if (ma.Count != v.count()) return false; IEnumerator ima = ma.GetEnumerator(); foreach (object ov in ((IList)v)) { ima.MoveNext(); if (!Util.equiv(ov, ima.Current)) return false; } return true; } else { // Example in Java of Sequential / IPersistentCollection conflation //if (!(obj is Sequential)) // return false; //ISeq ms = ((IPersistentCollection)obj).seq(); ISeq ms = obj as ISeq; if (ms == null) { IPersistentCollection mc = obj as IPersistentCollection; if (mc == null) return false; ms = mc.seq(); } // Once we have the ISeq, we're ready to go. for (int i = 0; i < v.count(); i++, ms = ms.rest()) { if (ms == null || !Util.equiv(v.nth(i), ms.first())) return false; } if (ms != null) return false; } return true; }
private void GenerateFnClass(IPersistentVector interfaces, GenContext context) { 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, _baseType, true); for (int i = 0; i < interfaces.count(); i++) _typeBuilder.AddInterfaceImplementation((Type)interfaces.nth(i)); MarkAsSerializable(_typeBuilder); GenInterface.SetCustomAttributes(_typeBuilder, _classMeta); GenerateStaticConstructor(_typeBuilder, _baseType, context.IsDebuggable); _ctorInfo = GenerateConstructor(_typeBuilder, _baseType); if (_altCtorDrops > 0) GenerateFieldOnlyConstructor(_typeBuilder, _baseType); if (SupportsMeta) { _nonmetaCtorInfo = GenerateNonMetaConstructor(_typeBuilder, _baseType); } GenerateMetaFunctions(_typeBuilder); //GenerateReloadVarsMethod(_typeBuilder, context); // The incoming context holds info on the containing function. // That is the one that holds the closed-over variable values. //GenContext newContext = CreateContext(context, _typeBuilder, _baseType); //GenerateMethods(newContext); GenerateStatics(context); GenerateMethods(context); }
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(); } }
static bool doEquiv(IPersistentVector v, object obj) { if (obj is IList || obj is IPersistentVector) { ICollection ma = (ICollection)obj; if (ma.Count != v.count()) return false; IEnumerator ima = ma.GetEnumerator(); foreach (object ov in ((IList)v)) { ima.MoveNext(); if (!Util.equiv(ov, ima.Current)) return false; } return true; } else { if (!(obj is Sequential)) return false; ISeq ms = RT.seq(obj); for (int i = 0; i < v.count(); i++, ms = ms.next()) { if (ms == null || !Util.equiv(v.nth(i), ms.first())) return false; } if (ms != null) return false; } return true; }
internal static Expression[] GenTypedArgArray(GenContext context, ParameterInfo[] infos, IPersistentVector args) { Expression[] exprs = new Expression[args.count()]; for (int i = 0; i < infos.Length; i++) { Expr e = (Expr)args.nth(i); // Java: this is in a try/catch, where the catch prints a stack trace if (MaybePrimitiveType(e) == infos[i].ParameterType) exprs[i] = ((MaybePrimitiveExpr)e).GenDlrUnboxed(context); else // Java follows this with: HostExpr.emitUnboxArg(fn, gen, parameterTypes[i]); //exprs[i] = e.GenDlr(context); exprs[i] = Expression.Convert(e.GenDlr(context), infos[i].ParameterType); ; } return exprs; }