private void emitPushArgument(Class ptype, object arg) { BasicType bptype = BasicType.basicType(ptype); if (arg is Name) { Name n = (Name)arg; emitLoadInsn(n._type(), n.index()); emitImplicitConversion(n._type(), ptype, n); } else if ((arg == null || arg is string) && bptype == BasicType.L_TYPE) { emitConst(arg); } else { if (Wrapper.isWrapperType(ikvm.extensions.ExtensionMethods.getClass(arg)) && bptype != BasicType.L_TYPE) { emitConst(arg); } else { EmitConstant(arg); emitImplicitConversion(BasicType.L_TYPE, ptype, arg); } } }
/** * Store the name to its local, if necessary. */ private void emitStoreResult(Name name) { if (name != null && name._type() != BasicType.V_TYPE) { // non-void: actually assign emitStoreInsn(name._type(), name.index()); } }
/** * Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type. */ private void emitReturn(Name onStack) { // return statement Class rclass = invokerType.returnType(); BasicType rtype = lambdaForm.returnType(); //assert(rtype == basicType(rclass)); // must agree if (rtype == BasicType.V_TYPE) { // [IKVM] unlike the JVM, the CLR doesn't like left over values on the stack if (onStack != null && onStack._type() != BasicType.V_TYPE) { ilgen.Emit(OpCodes.Pop); } } else { LambdaForm.Name rn = lambdaForm.names[lambdaForm.result]; // put return value on the stack if it is not already there if (rn != onStack) { emitLoadInsn(rtype, lambdaForm.result); } emitImplicitConversion(rtype, rclass, rn); } ilgen.Emit(OpCodes.Ret); }