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); }
private void DoEmitPrimOrStatic(ObjExpr fn, TypeBuilder tb, bool isStatic) { MethodAttributes attribs = isStatic ? MethodAttributes.Static | MethodAttributes.Public : MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual; string methodName = isStatic ? "invokeStatic" : "invokePrim"; MethodBuilder baseMB = tb.DefineMethod(methodName, attribs, GetReturnType(), _argTypes); if (!isStatic) { SetCustomAttributes(baseMB); } CljILGen baseIlg = new CljILGen(baseMB.GetILGenerator()); try { Label loopLabel = baseIlg.DefineLabel(); Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this)); GenContext.EmitDebugInfo(baseIlg, SpanMap); baseIlg.MarkLabel(loopLabel); EmitBody(Objx, baseIlg, _retType, _body); if (_body.HasNormalExit()) { baseIlg.Emit(OpCodes.Ret); } } finally { Var.popThreadBindings(); } // Generate the regular invoke, calling the static or prim method MethodBuilder regularMB = tb.DefineMethod(GetMethodName(), MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual, typeof(Object), GetArgTypes()); SetCustomAttributes(regularMB); CljILGen regIlg = new CljILGen(regularMB.GetILGenerator()); if (!isStatic) { regIlg.Emit(OpCodes.Ldarg_0); } for (int i = 0; i < _argTypes.Length; i++) { regIlg.EmitLoadArg(i + 1); HostExpr.EmitUnboxArg(fn, regIlg, _argTypes[i]); } regIlg.Emit(OpCodes.Call, baseMB); if (GetReturnType().IsValueType) { regIlg.Emit(OpCodes.Box, GetReturnType()); } regIlg.Emit(OpCodes.Ret); }
static void EmitUnboxArg(CljILGen ilg, Type argType, Type paramType) { if (argType == paramType) { return; } HostExpr.EmitUnboxArg(ilg, paramType); }
public override void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val) { GenContext.EmitDebugInfo(ilg, _spanMap); val.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Dup); HostExpr.EmitUnboxArg(objx, ilg, FieldType); ilg.EmitPropertySet(_tinfo); if (rhc == RHC.Statement) { ilg.Emit(OpCodes.Pop); } }
public override void EmitAssign(RHC rhc, ObjExpr objx, CljILGen ilg, Expr val) { if (_tinfo.IsInitOnly) { throw new InvalidOperationException(String.Format("Attempt to set readonly static field {0} in class {1}", _tinfo.Name, _tinfo.DeclaringType)); } GenContext.EmitDebugInfo(ilg, _spanMap); val.Emit(RHC.Expression, objx, ilg); ilg.Emit(OpCodes.Dup); HostExpr.EmitUnboxArg(objx, ilg, FieldType); ilg.MaybeEmitVolatileOp(_tinfo); ilg.EmitFieldSet(_tinfo); if (rhc == RHC.Statement) { ilg.Emit(OpCodes.Pop); } }
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 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); } }
private void DoEmitPrim(ObjExpr fn, TypeBuilder tb) { MethodAttributes attribs = MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual; string methodName = "invokePrim"; Type returnType; if (_retType == typeof(double) || _retType == typeof(long)) { returnType = ReturnType; } else { returnType = typeof(object); } MethodBuilder baseMB = tb.DefineMethod(methodName, attribs, returnType, _argTypes); SetCustomAttributes(baseMB); CljILGen baseIlg = new CljILGen(baseMB.GetILGenerator()); try { Label loopLabel = baseIlg.DefineLabel(); Var.pushThreadBindings(RT.map(Compiler.LoopLabelVar, loopLabel, Compiler.MethodVar, this)); GenContext.EmitDebugInfo(baseIlg, SpanMap); baseIlg.MarkLabel(loopLabel); EmitBody(Objx, baseIlg, _retType, Body); if (Body.HasNormalExit()) { baseIlg.Emit(OpCodes.Ret); } } finally { Var.popThreadBindings(); } // Generate the regular invoke, calling the prim method MethodBuilder regularMB = tb.DefineMethod(MethodName, MethodAttributes.ReuseSlot | MethodAttributes.Public | MethodAttributes.Virtual, typeof(Object), ArgTypes); SetCustomAttributes(regularMB); CljILGen regIlg = new CljILGen(regularMB.GetILGenerator()); regIlg.Emit(OpCodes.Ldarg_0); for (int i = 0; i < _argTypes.Length; i++) { regIlg.EmitLoadArg(i + 1); HostExpr.EmitUnboxArg(fn, regIlg, _argTypes[i]); } regIlg.Emit(OpCodes.Call, baseMB); if (ReturnType.IsValueType) { regIlg.Emit(OpCodes.Box, ReturnType); } regIlg.Emit(OpCodes.Ret); }