protected static void EmitBody(ObjExpr objx, CljILGen ilg, Type retType, Expr body) { MaybePrimitiveExpr be = (MaybePrimitiveExpr)body; if (Util.IsPrimitive(retType) && be.CanEmitPrimitive) { Type bt = Compiler.MaybePrimitiveType(be); if (bt == retType) { be.EmitUnboxed(RHC.Return, objx, ilg); } else if (retType == typeof(long) && bt == typeof(int)) { be.EmitUnboxed(RHC.Return, objx, ilg); ilg.Emit(OpCodes.Conv_I8); } else if (retType == typeof(double) && bt == typeof(float)) { be.EmitUnboxed(RHC.Return, objx, ilg); ilg.Emit(OpCodes.Conv_R8); } else if (retType == typeof(int) && bt == typeof(long)) { be.EmitUnboxed(RHC.Return, objx, ilg); ilg.Emit(OpCodes.Call, Compiler.Method_RT_intCast_long); } else if (retType == typeof(float) && bt == typeof(double)) { be.EmitUnboxed(RHC.Return, objx, ilg); ilg.Emit(OpCodes.Conv_R4); } else { throw new ArgumentException(String.Format("Mismatched primitive return, expected: {0}, had: {1}", retType, be.ClrType)); } } else { body.Emit(RHC.Return, objx, ilg); if (body.HasNormalExit()) { if (retType == typeof(void)) { ilg.Emit(OpCodes.Pop); } else { EmitUnboxArg(ilg, typeof(object), retType); } } } }
internal void EmitAssignLocal(CljILGen ilg, LocalBinding lb, Expr val) { if (!IsMutable(lb)) throw new ArgumentException("Cannot assign to non-mutable: ", lb.Name); FieldBuilder fb = null; bool hasField = ClosedOverFieldsMap.TryGetValue(lb, out fb); ilg.Emit(OpCodes.Ldarg_0); // this Type primt = lb.PrimitiveType; if (primt != null) { MaybePrimitiveExpr mbe = val as MaybePrimitiveExpr; if (!(mbe != null && mbe.CanEmitPrimitive)) throw new ArgumentException("Must assign primitive to primitive mutable", lb.Name); mbe.EmitUnboxed(RHC.Expression, this, ilg); } else { val.Emit(RHC.Expression, this, ilg); } if (hasField) { ilg.MaybeEmitVolatileOp(IsVolatile(lb)); ilg.Emit(OpCodes.Stfld, fb); } else ilg.Emit(OpCodes.Stloc, lb.LocalVar); }
public static void EmitTypedArg(ObjExpr objx, CljILGen ilg, Type paramType, Expr arg) { Type primt = Compiler.MaybePrimitiveType(arg); MaybePrimitiveExpr mpe = arg as MaybePrimitiveExpr; if (primt == paramType) { mpe.EmitUnboxed(RHC.Expression, objx, ilg); } else if (primt == typeof(int) && paramType == typeof(long)) { mpe.EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Conv_I8); } else if (primt == typeof(long) && paramType == typeof(int)) { mpe.EmitUnboxed(RHC.Expression, objx, ilg); if (RT.booleanCast(RT.UncheckedMathVar.deref())) { ilg.Emit(OpCodes.Call, Compiler.Method_RT_uncheckedIntCast_long); } else { ilg.Emit(OpCodes.Call, Compiler.Method_RT_intCast_long); } } else if (primt == typeof(float) && paramType == typeof(double)) { mpe.EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Conv_R8); } else if (primt == typeof(double) && paramType == typeof(float)) { mpe.EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Conv_R4); } else { arg.Emit(RHC.Expression, objx, ilg); HostExpr.EmitUnboxArg(objx, ilg, paramType); } }
public void EmitUnboxed(RHC rhc, ObjExpr objx, CljILGen ilg) { for (int i = 0; i < _exprs.count() - 1; i++) { Expr e = (Expr)_exprs.nth(i); e.Emit(RHC.Statement, objx, ilg); } MaybePrimitiveExpr mbe = (MaybePrimitiveExpr)LastExpr; mbe.EmitUnboxed(rhc, objx, ilg); }
private static void EmitExpr(ObjExpr objx, CljILGen ilg, Expr expr, bool emitUnboxed) { MaybePrimitiveExpr mbe = expr as MaybePrimitiveExpr; if (emitUnboxed && mbe != null) { mbe.EmitUnboxed(RHC.Expression, objx, ilg); } else { expr.Emit(RHC.Expression, objx, ilg); } }
public void Emit(RHC rhc, ObjExpr objx, CljILGen ilg) { Label?loopLabel = (Label)Compiler.LoopLabelVar.deref(); if (loopLabel == null) { throw new InvalidOperationException("Recur not in proper context."); } { for (int i = 0; i < _loopLocals.count(); i++) { LocalBinding lb = (LocalBinding)_loopLocals.nth(i); Expr arg = (Expr)_args.nth(i); Type primt = lb.PrimitiveType; if (primt != null) { MaybePrimitiveExpr mpeArg = arg as MaybePrimitiveExpr; Type pt = Compiler.MaybePrimitiveType(arg); if (pt == primt) { mpeArg.EmitUnboxed(RHC.Expression, objx, ilg); } else if (primt == typeof(long) && pt == typeof(int)) { mpeArg.EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Conv_I8); } else if (primt == typeof(double) && pt == typeof(float)) { mpeArg.EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Conv_R8); } else if (primt == typeof(int) && pt == typeof(long)) { mpeArg.EmitUnboxed(RHC.Expression, objx, ilg); ilg.EmitCall(Compiler.Method_RT_intCast_long); } else if (primt == typeof(float) && pt == typeof(double)) { mpeArg.EmitUnboxed(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Conv_R4); } else { throw new ArgumentException(String.Format( "{0}:{1} recur arg for primitive local: {2} is not matching primitive, had: {3}, needed {4}", _source, _spanMap != null ? (int)_spanMap.valAt(RT.StartLineKey, 0) : 0, lb.Name, (arg.HasClrType ? arg.ClrType.Name : "Object"), primt.Name)); } } else { arg.Emit(RHC.Expression, objx, ilg); } } } for (int i = _loopLocals.count() - 1; i >= 0; i--) { LocalBinding lb = (LocalBinding)_loopLocals.nth(i); //Type primt = lb.PrimitiveType; if (lb.IsArg) { //ilg.Emit(OpCodes.Starg, lb.Index - (objx.IsStatic ? 0 : 1)); ilg.EmitStoreArg(lb.Index); } else { ilg.Emit(OpCodes.Stloc, lb.LocalVar); } } ilg.Emit(OpCodes.Br, loopLabel.Value); }