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
    }
Exemple #6
0
    // 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
    }
Exemple #8
0
    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);
    }