internal static DynamicMethod CreateInvokeExact(MethodType type) { FinishTypes(type); DynamicMethodBuilder dm = new DynamicMethodBuilder("InvokeExact", type, typeof(MethodHandle), null, null, null, false); Type targetDelegateType = GetMemberWrapperDelegateType(type.insertParameterTypes(0, CoreClasses.java.lang.invoke.MethodHandle.Wrapper.ClassObject)); dm.ilgen.Emit(OpCodes.Ldarg_0); dm.ilgen.Emit(OpCodes.Ldfld, typeof(MethodHandle).GetField("form", BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Ldfld, typeof(LambdaForm).GetField("vmentry", BindingFlags.Instance | BindingFlags.NonPublic)); if (type.returnType() == java.lang.Void.TYPE) { dm.ilgen.Emit(OpCodes.Call, typeof(MethodHandleUtil).GetMethod("GetVoidAdapter", BindingFlags.Static | BindingFlags.NonPublic)); } else { dm.ilgen.Emit(OpCodes.Ldfld, typeof(MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic)); } dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType); dm.ilgen.Emit(OpCodes.Ldarg_0); for (int i = 0; i < type.parameterCount(); i++) { dm.Ldarg(i); TypeWrapper tw = TypeWrapper.FromClass(type.parameterType(i)); if (tw.IsNonPrimitiveValueType) { tw.EmitBox(dm.ilgen); } else if (tw.IsGhost) { tw.EmitConvSignatureTypeToStackType(dm.ilgen); } else if (tw == PrimitiveTypeWrapper.BYTE) { dm.ilgen.Emit(OpCodes.Conv_I1); } } dm.CallDelegate(targetDelegateType); TypeWrapper retType = TypeWrapper.FromClass(type.returnType()); if (retType.IsNonPrimitiveValueType) { retType.EmitUnbox(dm.ilgen); } else if (retType.IsGhost) { retType.EmitConvStackTypeToSignatureType(dm.ilgen, null); } else if (!retType.IsPrimitive && retType != CoreClasses.java.lang.Object.Wrapper) { dm.EmitCheckcast(retType); } dm.Ret(); dm.ilgen.DoEmit(); return(dm.dm); }
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 CreateVoidAdapter(MethodType type) { DynamicMethodBuilder dm = new DynamicMethodBuilder("VoidAdapter", type.changeReturnType(java.lang.Void.TYPE), null, null, null, null, true); Type targetDelegateType = GetMemberWrapperDelegateType(type); dm.Ldarg(0); dm.EmitCheckcast(CoreClasses.java.lang.invoke.MethodHandle.Wrapper); dm.ilgen.Emit(OpCodes.Ldfld, typeof(MethodHandle).GetField("form", BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Ldfld, typeof(LambdaForm).GetField("vmentry", BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Ldfld, typeof(MemberName).GetField("vmtarget", BindingFlags.Instance | BindingFlags.NonPublic)); dm.ilgen.Emit(OpCodes.Castclass, targetDelegateType); for (int i = 0; i < type.parameterCount(); i++) { dm.Ldarg(i); } dm.CallDelegate(targetDelegateType); dm.ilgen.Emit(OpCodes.Pop); 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()); }