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 Emit(RHC rhc, ObjExpr objx, CljILGen ilg) { objx.EmitVar(ilg, _var); if (_shadowsCoreMapping) { LocalBuilder locNs = ilg.DeclareLocal(typeof(Namespace)); GenContext.SetLocalName(locNs, "ns"); ilg.Emit(OpCodes.Dup); ilg.EmitFieldGet(VarNsFI); ilg.Emit(OpCodes.Stloc, locNs); LocalBuilder locSym = ilg.DeclareLocal(typeof(Symbol)); GenContext.SetLocalName(locSym, "sym"); ilg.Emit(OpCodes.Dup); ilg.EmitFieldGet(VarSymFI); ilg.Emit(OpCodes.Stloc, locSym); ilg.Emit(OpCodes.Ldloc, locNs); ilg.Emit(OpCodes.Ldloc, locSym); ilg.Emit(OpCodes.Call, NamespaceReferMI); } if (_isDynamic) { ilg.Emit(OpCodes.Call, Compiler.Method_Var_setDynamic0); } if (_meta != null) { if (_initProvided || true) //IncludesExplicitMetadata((MapExpr)_meta)) { ilg.Emit(OpCodes.Dup); _meta.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Castclass, typeof(IPersistentMap)); ilg.Emit(OpCodes.Call, Compiler.Method_Var_setMeta); } } if (_initProvided) { ilg.Emit(OpCodes.Dup); if (_init is FnExpr expr) { expr.EmitForDefn(objx, ilg); } else { _init.Emit(RHC.Expression, objx, ilg); } ilg.Emit(OpCodes.Call, Compiler.Method_Var_bindRoot); } if (rhc == RHC.Statement) { ilg.Emit(OpCodes.Pop); } }
public static void EmitPrepForCall(CljILGen ilg, Type targetType, Type declaringType) { EmitConvertToType(ilg, targetType, declaringType, false); if (declaringType.IsValueType) { LocalBuilder vtTemp = ilg.DeclareLocal(declaringType); GenContext.SetLocalName(vtTemp, "valueTemp"); ilg.Emit(OpCodes.Stloc, vtTemp); ilg.Emit(OpCodes.Ldloca, vtTemp); } }
public override void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val) { GenContext.EmitDebugInfo(ilg, _spanMap); if (_targetType != null && _tinfo != null) { _target.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Castclass, _targetType); val.Emit(RHC.Expression, objx, ilg); LocalBuilder tmp = ilg.DeclareLocal(typeof(object)); GenContext.SetLocalName(tmp, "valTemp"); ilg.Emit(OpCodes.Dup); ilg.Emit(OpCodes.Stloc, tmp); if (FieldType.IsValueType) { HostExpr.EmitUnboxArg(objx, ilg, FieldType); } else { ilg.Emit(OpCodes.Castclass, FieldType); } EmitSet(ilg); ilg.Emit(OpCodes.Ldloc, tmp); } else { _target.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Ldstr, _memberName); val.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Call, Compiler.Method_Reflector_SetInstanceFieldOrProperty); } if (rhc == RHC.Statement) { ilg.Emit(OpCodes.Pop); } }
void EmitProto(RHC rhc, ObjExpr objx, CljILGen ilg) { Label onLabel = ilg.DefineLabel(); Label callLabel = ilg.DefineLabel(); Label endLabel = ilg.DefineLabel(); Var v = ((VarExpr)_fexpr).Var; Expr e = (Expr)_args.nth(0); e.Emit(RHC.Expression, objx, ilg); // target ilg.Emit(OpCodes.Dup); // target, target LocalBuilder targetTemp = ilg.DeclareLocal(typeof(Object)); GenContext.SetLocalName(targetTemp, "target"); ilg.Emit(OpCodes.Stloc, targetTemp); // target ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class ilg.EmitLoadArg(0); // class, this ilg.EmitFieldGet(objx.CachedTypeField(_siteIndex)); // class, cached-class ilg.Emit(OpCodes.Beq, callLabel); // if (_protocolOn != null) { ilg.Emit(OpCodes.Ldloc, targetTemp); // target ilg.Emit(OpCodes.Isinst, _protocolOn); // null or target ilg.Emit(OpCodes.Ldnull); // (null or target), null ilg.Emit(OpCodes.Cgt_Un); // (0 or 1) ilg.Emit(OpCodes.Brtrue, onLabel); } ilg.Emit(OpCodes.Ldloc, targetTemp); // target ilg.Emit(OpCodes.Call, Compiler.Method_Util_classOf); // class LocalBuilder typeTemp = ilg.DeclareLocal(typeof(Type)); GenContext.SetLocalName(typeTemp, "type"); ilg.Emit(OpCodes.Stloc, typeTemp); // (typeType <= class) ilg.EmitLoadArg(0); // this ilg.Emit(OpCodes.Ldloc, typeTemp); // this, class ilg.EmitFieldSet(objx.CachedTypeField(_siteIndex)); // ilg.MarkLabel(callLabel); objx.EmitVar(ilg, v); // var ilg.Emit(OpCodes.Call, Compiler.Method_Var_getRawRoot); // proto-fn ilg.Emit(OpCodes.Castclass, typeof(AFunction)); ilg.Emit(OpCodes.Ldloc, targetTemp); // proto-fn, target EmitArgsAndCall(1, rhc, objx, ilg); ilg.Emit(OpCodes.Br, endLabel); ilg.MarkLabel(onLabel); ilg.Emit(OpCodes.Ldloc, targetTemp); // target if (_protocolOn != null) { ilg.Emit(OpCodes.Castclass, _protocolOn); MethodExpr.EmitTypedArgs(objx, ilg, _onMethod.GetParameters(), RT.subvec(_args, 1, _args.count())); //if (rhc == RHC.Return) //{ // ObjMethod2 method = (ObjMethod)Compiler.MethodVar.deref(); // method.EmitClearLocals(context); //} ilg.Emit(OpCodes.Callvirt, _onMethod); HostExpr.EmitBoxReturn(objx, ilg, _onMethod.ReturnType); } ilg.MarkLabel(endLabel); }
public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg) { Label endLabel = ilg.DefineLabel(); Label faultLabel = ilg.DefineLabel(); GenContext.EmitDebugInfo(ilg, _spanMap); LocalBuilder thunkLoc = ilg.DeclareLocal(typeof(ILookupThunk)); LocalBuilder targetLoc = ilg.DeclareLocal(typeof(Object)); LocalBuilder resultLoc = ilg.DeclareLocal(typeof(Object)); GenContext.SetLocalName(thunkLoc, "thunk"); GenContext.SetLocalName(targetLoc, "target"); GenContext.SetLocalName(resultLoc, "result"); // TODO: Debug info // pseudo-code: // ILookupThunk thunk = objclass.ThunkField(i) // object target = ...code... // object val = thunk.get(target) // if ( val != thunk ) // return val // else // KeywordLookupSite site = objclass.SiteField(i) // thunk = site.fault(target) // objclass.ThunkField(i) = thunk // val = thunk.get(target) // return val ilg.EmitFieldGet(objx.ThunkField(_siteIndex)); // thunk ilg.Emit(OpCodes.Stloc, thunkLoc); // (thunkLoc <= thunk) _target.Emit(RHC.Expression, objx, ilg); // target ilg.Emit(OpCodes.Stloc, targetLoc); // (targetLoc <= target) ilg.Emit(OpCodes.Ldloc, thunkLoc); ilg.Emit(OpCodes.Ldloc, targetLoc); ilg.EmitCall(Compiler.Method_ILookupThunk_get); // result ilg.Emit(OpCodes.Stloc, resultLoc); // (resultLoc <= result) ilg.Emit(OpCodes.Ldloc, thunkLoc); ilg.Emit(OpCodes.Ldloc, resultLoc); ilg.Emit(OpCodes.Beq, faultLabel); ilg.Emit(OpCodes.Ldloc, resultLoc); // result ilg.Emit(OpCodes.Br, endLabel); ilg.MarkLabel(faultLabel); ilg.EmitFieldGet(objx.KeywordLookupSiteField(_siteIndex)); // site ilg.Emit(OpCodes.Ldloc, targetLoc); // site, target ilg.EmitCall(Compiler.Method_ILookupSite_fault); // new-thunk ilg.Emit(OpCodes.Dup); // new-thunk, new-thunk ilg.EmitFieldSet(objx.ThunkField(_siteIndex)); // new-thunk ilg.Emit(OpCodes.Ldloc, targetLoc); // new-thunk, target ilg.EmitCall(Compiler.Method_ILookupThunk_get); // result ilg.MarkLabel(endLabel); // result if (rhc == RHC.Statement) { ilg.Emit(OpCodes.Pop); } }
// TODO: Eliminate common code between EmitProtoLight and EmitProtoFull void EmitProtoLight(RHC rhc, ObjExpr objx, CljILGen ilg) { Label endLabel = ilg.DefineLabel(); Var v = ((VarExpr)_fexpr).Var; Expr e = (Expr)_args.nth(0); e.Emit(RHC.Expression, objx, ilg); // target LocalBuilder targetTemp = ilg.DeclareLocal(typeof(Object)); GenContext.SetLocalName(targetTemp, "target"); ilg.Emit(OpCodes.Stloc, targetTemp); // (targetTemp <= target) ilg.EmitString(String.Format("In Light Proto for {0}", v.Symbol.ToString())); ilg.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) })); //if (_protocolOn != null) //{ // ilg.Emit(OpCodes.Ldloc, targetTemp); // target // ilg.Emit(OpCodes.Isinst, _protocolOn); // (target or null) // ilg.Emit(OpCodes.Ldnull); // (target or null), null // ilg.Emit(OpCodes.Cgt_Un); // (0 or 1) // ilg.Emit(OpCodes.Brtrue, onLabel); //} objx.EmitVar(ilg, v); // var ilg.Emit(OpCodes.Call, Compiler.Method_Var_getRawRoot); // proto-fn ilg.Emit(OpCodes.Dup); ilg.Emit(OpCodes.Call, typeof(Object).GetMethod("GetType")); ilg.Emit(OpCodes.Callvirt, typeof(Object).GetMethod("ToString")); ilg.EmitString("Expected AFunction, got "); ilg.Emit(OpCodes.Call, typeof(Console).GetMethod("Write", new Type[] { typeof(String) })); ilg.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) })); ilg.Emit(OpCodes.Castclass, typeof(AFunction)); ilg.EmitString("Castclass worked "); ilg.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) })); ilg.Emit(OpCodes.Ldloc, targetTemp); // proto-fn, target EmitArgsAndCall(1, rhc, objx, ilg); ilg.EmitString("gen'd args and called"); ilg.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) })); ilg.Emit(OpCodes.Br, endLabel); //ilg.MarkLabel(onLabel); //ilg.Emit(OpCodes.Ldloc, targetTemp); // target //if (_protocolOn != null) //{ // ilg.Emit(OpCodes.Castclass, _protocolOn); // MethodExpr.EmitTypedArgs(objx, ilg, _onMethod.GetParameters(), RT.subvec(_args, 1, _args.count())); // //if (rhc == RHC.Return) // //{ // // ObjMethod2 method = (ObjMethod)Compiler.MethodVar.deref(); // // method.EmitClearLocals(context); // //} // ilg.Emit(OpCodes.Callvirt,_onMethod); // HostExpr.EmitBoxReturn(objx, ilg, _onMethod.ReturnType); //} ilg.MarkLabel(endLabel); }
void DoEmit(RHC rhc, ObjExpr objx, CljILGen ilg, bool emitUnboxed) { Label nullLabel = ilg.DefineLabel(); Label falseLabel = ilg.DefineLabel(); Label endLabel = ilg.DefineLabel(); Label trueLabel = ilg.DefineLabel(); GenContext.EmitDebugInfo(ilg, _sourceSpan); StaticMethodExpr sme = _testExpr as StaticMethodExpr; if (sme != null && sme.CanEmitIntrinsicPredicate()) { sme.EmitIntrinsicPredicate(RHC.Expression, objx, ilg, falseLabel); } else if (Compiler.MaybePrimitiveType(_testExpr) == typeof(bool)) { ((MaybePrimitiveExpr)_testExpr).EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Brfalse, falseLabel); } else { LocalBuilder tempLoc = ilg.DeclareLocal(typeof(Object)); GenContext.SetLocalName(tempLoc, "test"); _testExpr.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Dup); ilg.Emit(OpCodes.Stloc, tempLoc); ilg.Emit(OpCodes.Brfalse, nullLabel); ilg.Emit(OpCodes.Ldloc, tempLoc); ilg.Emit(OpCodes.Isinst, typeof(bool)); ilg.Emit(OpCodes.Ldnull); ilg.Emit(OpCodes.Cgt_Un); ilg.Emit(OpCodes.Brfalse, trueLabel); ilg.Emit(OpCodes.Ldloc, tempLoc); ilg.Emit(OpCodes.Unbox_Any, typeof(bool)); ilg.Emit(OpCodes.Ldc_I4_0); ilg.Emit(OpCodes.Ceq); ilg.Emit(OpCodes.Brtrue, falseLabel); } ilg.MarkLabel(trueLabel); if (emitUnboxed) { ((MaybePrimitiveExpr)_thenExpr).EmitUnboxed(rhc, objx, ilg); } else { _thenExpr.Emit(rhc, objx, ilg); } if (_thenExpr.HasNormalExit()) { ilg.Emit(OpCodes.Br, endLabel); } ilg.MarkLabel(nullLabel); ilg.MarkLabel(falseLabel); if (emitUnboxed) { ((MaybePrimitiveExpr)_elseExpr).EmitUnboxed(rhc, objx, ilg); } else { _elseExpr.Emit(rhc, objx, ilg); } ilg.MarkLabel(endLabel); }