public static MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target, java.lang.Class spreadArgType, int spreadArgPos, int spreadArgCount) { #if FIRST_PASS return(null); #else TypeWrapper twComponent = TypeWrapper.FromClass(spreadArgType).ElementTypeWrapper; MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("AdapterMethodHandle.spreadArguments", newType, target); for (int i = 0, count = newType.parameterCount(); i < count; i++) { if (i == spreadArgPos) { for (int j = 0; j < spreadArgCount; j++) { dm.Ldarg(i); dm.LoadArrayElement(j, twComponent); dm.Convert(twComponent.ClassObject, target.type().parameterType(i + j), 0); } } else { dm.Ldarg(i); } } dm.CallTarget(); dm.Ret(); return(dm.CreateAdapter()); #endif }
public static object invoke(MethodHandle mh, object[] args) { #if FIRST_PASS return(null); #else MethodType type = mh.type(); if (mh.isVarargsCollector()) { java.lang.Class varargType = type.parameterType(type.parameterCount() - 1); if (type.parameterCount() == args.Length) { if (!varargType.isInstance(args[args.Length - 1])) { Array arr = (Array)java.lang.reflect.Array.newInstance(varargType.getComponentType(), 1); arr.SetValue(args[args.Length - 1], 0); args[args.Length - 1] = arr; } } else if (type.parameterCount() - 1 > args.Length) { throw new WrongMethodTypeException(); } else { object[] newArgs = new object[type.parameterCount()]; Array.Copy(args, newArgs, newArgs.Length - 1); Array varargs = (Array)java.lang.reflect.Array.newInstance(varargType.getComponentType(), args.Length - (newArgs.Length - 1)); Array.Copy(args, newArgs.Length - 1, varargs, 0, varargs.Length); newArgs[newArgs.Length - 1] = varargs; args = newArgs; } } if (mh.type().parameterCount() != args.Length) { throw new WrongMethodTypeException(); } mh = mh.asSpreader(typeof(object[]), args.Length); return(IKVM.Runtime.ByteCodeHelper.GetDelegateForInvoke <IKVM.Runtime.MH <MethodHandle, object[], object> >(mh, ref cache)(mh, args)); #endif }
public static object createDelegate(MethodType newType, MethodHandle mh, int argnum, object argument) { #if FIRST_PASS return(null); #else Delegate del = (Delegate)mh.vmtarget; if (argnum == 0 && del.Target == null // we don't have to check for instance methods on a Value Type, because DirectMethodHandle can't use a direct delegate for that anyway && (!del.Method.IsStatic || !del.Method.GetParameters()[0].ParameterType.IsValueType) && !ReflectUtil.IsDynamicMethod(del.Method)) { return(Delegate.CreateDelegate(MethodHandleUtil.CreateDelegateType(newType), argument, del.Method)); } else { // slow path where we're generating a DynamicMethod if (mh.type().parameterType(argnum).isPrimitive()) { argument = JVM.Unbox(argument); } MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("BoundMethodHandle", newType, mh, argument); for (int i = 0, count = mh.type().parameterCount(), pos = 0; i < count; i++) { if (i == argnum) { dm.LoadValue(); } else { dm.Ldarg(pos++); } } dm.CallTarget(); dm.Ret(); return(dm.CreateDelegate()); } #endif }
public static MethodHandle makeRetype(MethodType newType, MethodHandle target, bool raw) { #if FIRST_PASS return(null); #else MethodType oldType = target.type(); if (oldType == newType) { return(target); } if (!AdapterMethodHandle.canRetype(newType, oldType, raw)) { return(null); } // TODO does raw translate into a level? return(makePairwiseConvert(newType, target, 0)); #endif }
public static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target, int level) { #if FIRST_PASS return(null); #else MethodType oldType = target.type(); MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("AdapterMethodHandle.pairwiseConvert", newType, target); for (int i = 0, count = newType.parameterCount(); i < count; i++) { dm.Ldarg(i); dm.Convert(newType.parameterType(i), oldType.parameterType(i), level); } dm.CallTarget(); dm.Convert(oldType.returnType(), newType.returnType(), level); dm.Ret(); return(dm.CreateAdapter()); #endif }
// hooked up via map.xml (as a replacement for makePairwiseConvertByEditor) public static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType, bool strict, bool monobox) { #if FIRST_PASS return(null); #else object[] convSpecs = MethodHandleImpl.computeValueConversions(srcType, target.type(), strict, monobox); List <LambdaForm.Name> names = new List <LambdaForm.Name>(); names.Add(new LambdaForm.Name(0, LambdaForm.BasicType.L_TYPE)); for (int i = 0; i < srcType.parameterCount(); i++) { names.Add(new LambdaForm.Name(i + 1, LambdaForm.BasicType.basicType(srcType.parameterType(i)))); } LambdaForm.Name[] invokeArgs = new LambdaForm.Name[srcType.parameterCount()]; for (int i = 0; i < invokeArgs.Length; i++) { object convSpec = convSpecs[i]; if (convSpec == null) { invokeArgs[i] = names[i + 1]; } else { LambdaForm.Name temp = new LambdaForm.Name(convSpec as MethodHandle ?? MethodHandleImpl.Lazy.MH_castReference.bindTo(convSpec), names[i + 1]); names.Add(temp); invokeArgs[i] = temp; } } names.Add(new LambdaForm.Name(target, invokeArgs)); if (convSpecs[convSpecs.Length - 1] != null) { object convSpec = convSpecs[convSpecs.Length - 1]; if (convSpec != java.lang.Void.TYPE) { names.Add(new LambdaForm.Name(convSpec as MethodHandle ?? MethodHandleImpl.Lazy.MH_castReference.bindTo(convSpec), names[names.Count - 1])); } } if (target.type().returnType() == java.lang.Void.TYPE && srcType.returnType() != java.lang.Void.TYPE) { names.Add(new LambdaForm.Name(LambdaForm.constantZero(LambdaForm.BasicType.basicType(srcType.returnType())))); } LambdaForm form = new LambdaForm("PairwiseConvert", srcType.parameterCount() + 1, names.ToArray()); return(new LightWeightMethodHandle(srcType, form)); #endif }
public static MethodHandle makeCollectArguments(MethodHandle target, MethodHandle collector, int collectArgPos, bool retainOriginalArgs) { #if FIRST_PASS return(null); #else MethodType targetType = target.type(); MethodType collectorType = collector.type(); bool isfilter = collectorType.returnType() == java.lang.Void.TYPE; MethodType newType = targetType.dropParameterTypes(collectArgPos, collectArgPos + (isfilter ? 0 : 1)); if (!retainOriginalArgs) { newType = newType.insertParameterTypes(collectArgPos, collectorType.parameterList()); } MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("AdapterMethodHandle.collectArguments", newType, target, collector.vmtarget); for (int i = 0, count = newType.parameterCount(); i < count || i == collectArgPos; i++) { if (i == collectArgPos) { dm.LoadValue(); for (int j = 0; j < collectorType.parameterCount(); j++) { dm.Ldarg(i + j); } dm.CallValue(); collectArgPos = -1; i--; if (!retainOriginalArgs) { i += collectorType.parameterCount(); } } else { dm.Ldarg(i); } } dm.CallTarget(); dm.Ret(); return(dm.CreateAdapter()); #endif }
internal static T GetDelegateForInvokeExact <T>(MethodHandle mh) where T : class { MethodType type = mh.type(); if (mh._invokeExactDelegate == null) { if (type._invokeExactDynamicMethod == null) { type._invokeExactDynamicMethod = DynamicMethodBuilder.CreateInvokeExact(type); } mh._invokeExactDelegate = type._invokeExactDynamicMethod.CreateDelegate(GetDelegateTypeForInvokeExact(type), mh); T del = mh._invokeExactDelegate as T; if (del != null) { return(del); } } throw Invokers.newWrongMethodTypeException(GetDelegateMethodType(typeof(T)), type); }