コード例 #1
0
    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
    }
コード例 #2
0
    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
    }
コード例 #3
0
    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
    }
コード例 #4
0
    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
    }
コード例 #5
0
    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
    }