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 MethodHandle permuteArguments(MethodHandle target, MethodType newType, MethodType oldType, int[] permutationOrNull) { #if FIRST_PASS return(null); #else // LAME why does OpenJDK name the parameter permutationOrNull while it is not allowed to be null? if (permutationOrNull.Length != oldType.parameterCount()) { throw new java.lang.IllegalArgumentException("wrong number of arguments in permutation"); } MethodHandleUtil.DynamicMethodBuilder dm = new MethodHandleUtil.DynamicMethodBuilder("MethodHandleImpl.permuteArguments", newType, target); for (int i = 0, argCount = newType.parameterCount(); i < permutationOrNull.Length; i++) { // make sure to only read each array element once, to avoid having to make a defensive copy of the array int perm = permutationOrNull[i]; if (perm < 0 || perm >= argCount) { throw new java.lang.IllegalArgumentException("permutation argument out of range"); } dm.Ldarg(perm); dm.Convert(oldType.parameterType(i), newType.parameterType(perm), 0); } dm.CallTarget(); dm.Convert(oldType.returnType(), newType.returnType(), 0); dm.Ret(); return(dm.CreateAdapter()); #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 }
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 }
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 }