internal static Delegate CreateMethodHandleLinkTo(MemberName mn) { MethodType type = mn.getMethodType(); Type delegateType = MethodHandleUtil.GetMemberWrapperDelegateType(type.dropParameterTypes(type.parameterCount() - 1, type.parameterCount())); DynamicMethodBuilder dm = new DynamicMethodBuilder("DirectMethodHandle." + mn.getName() + type, type, null, null, null, null, true); dm.Ldarg(type.parameterCount() - 1); dm.ilgen.EmitCastclass(typeof(JlInvoke.MemberName)); dm.ilgen.Emit(OpCodes.Ldfld, typeof(JlInvoke.MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Castclass, delegateType); for (int i = 0, count = type.parameterCount() - 1; i < count; i++) { dm.Ldarg(i); } dm.CallDelegate(delegateType); dm.Ret(); return(dm.CreateDelegate()); }
internal static Delegate CreateMethodHandleInvoke(MemberName mn) { MethodType type = mn.getMethodType().insertParameterTypes(0, mn.getDeclaringClass()); Type targetDelegateType = MethodHandleUtil.GetMemberWrapperDelegateType(type); DynamicMethodBuilder dm = new DynamicMethodBuilder("DirectMethodHandle." + mn.getName() + type, type, typeof(Container <,>).MakeGenericType(typeof(object), typeof(IKVM.Runtime.InvokeCache <>).MakeGenericType(targetDelegateType)), null, null, null, true); dm.Ldarg(0); dm.EmitCheckcast(CoreClasses.java.lang.invoke.MethodHandle.Wrapper); switch (mn.getName()) { case "invokeExact": dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeExact.MakeGenericMethod(targetDelegateType)); break; case "invoke": dm.LoadValueAddress(); dm.Call(ByteCodeHelperMethods.GetDelegateForInvoke.MakeGenericMethod(targetDelegateType)); break; case "invokeBasic": dm.Call(ByteCodeHelperMethods.GetDelegateForInvokeBasic.MakeGenericMethod(targetDelegateType)); break; default: throw new InvalidOperationException(); } dm.Ldarg(0); for (int i = 1, count = type.parameterCount(); i < count; i++) { dm.Ldarg(i); } dm.CallDelegate(targetDelegateType); dm.Ret(); return(dm.CreateDelegate()); }
private NativeInvokerBytecodeGenerator(LambdaForm lambdaForm, MethodType invokerType) { if (invokerType != invokerType.basicType()) { throw new BailoutException(Bailout.NotBasicType, invokerType); } this.lambdaForm = lambdaForm; this.invokerType = invokerType; this.delegateType = MethodHandleUtil.GetMemberWrapperDelegateType(invokerType); MethodInfo mi = MethodHandleUtil.GetDelegateInvokeMethod(delegateType); Type[] paramTypes = MethodHandleUtil.GetParameterTypes(typeof(object[]), mi); // HACK the code we generate is not verifiable (known issue: locals aren't typed correctly), so we stick the DynamicMethod into mscorlib (a security critical assembly) this.dm = new DynamicMethod(lambdaForm.debugName, mi.ReturnType, paramTypes, typeof(object).Module, true); this.ilgen = CodeEmitter.Create(this.dm); if (invokerType.parameterCount() > MethodHandleUtil.MaxArity) { this.packedArgType = paramTypes[paramTypes.Length - 1]; this.packedArgPos = paramTypes.Length - 1; } else { this.packedArgPos = Int32.MaxValue; } locals = new CodeEmitterLocal[lambdaForm.names.Length]; for (int i = lambdaForm._arity(); i < lambdaForm.names.Length; i++) { Name name = lambdaForm.names[i]; if (name.index() != i) { throw new BailoutException(Bailout.PreconditionViolated, "name.index() != i"); } switch (name.typeChar()) { case 'L': locals[i] = ilgen.DeclareLocal(Types.Object); break; case 'I': locals[i] = ilgen.DeclareLocal(Types.Int32); break; case 'J': locals[i] = ilgen.DeclareLocal(Types.Int64); break; case 'F': locals[i] = ilgen.DeclareLocal(Types.Single); break; case 'D': locals[i] = ilgen.DeclareLocal(Types.Double); break; case 'V': break; default: throw new BailoutException(Bailout.PreconditionViolated, "Unsupported typeChar(): " + name.typeChar()); } } }