Ejemplo n.º 1
0
        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());
        }
Ejemplo n.º 2
0
        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());
        }
    private NativeInvokerBytecodeGenerator(LambdaForm lambdaForm, MethodType invokerType)
    {
        if (invokerType != invokerType.basicType())
        {
            throw new BailoutException(Bailout.NotBasicType, invokerType);
        }
        this.lambdaForm   = lambdaForm;
        this.invokerType  = invokerType;
        this.delegateType = MethodHandleUtil.GetMemberWrapperDelegateType(invokerType);
        MethodInfo mi = MethodHandleUtil.GetDelegateInvokeMethod(delegateType);

        Type[] paramTypes = MethodHandleUtil.GetParameterTypes(typeof(object[]), mi);
        // HACK the code we generate is not verifiable (known issue: locals aren't typed correctly), so we stick the DynamicMethod into mscorlib (a security critical assembly)
        this.dm    = new DynamicMethod(lambdaForm.debugName, mi.ReturnType, paramTypes, typeof(object).Module, true);
        this.ilgen = CodeEmitter.Create(this.dm);
        if (invokerType.parameterCount() > MethodHandleUtil.MaxArity)
        {
            this.packedArgType = paramTypes[paramTypes.Length - 1];
            this.packedArgPos  = paramTypes.Length - 1;
        }
        else
        {
            this.packedArgPos = Int32.MaxValue;
        }

        locals = new CodeEmitterLocal[lambdaForm.names.Length];
        for (int i = lambdaForm._arity(); i < lambdaForm.names.Length; i++)
        {
            Name name = lambdaForm.names[i];
            if (name.index() != i)
            {
                throw new BailoutException(Bailout.PreconditionViolated, "name.index() != i");
            }
            switch (name.typeChar())
            {
            case 'L':
                locals[i] = ilgen.DeclareLocal(Types.Object);
                break;

            case 'I':
                locals[i] = ilgen.DeclareLocal(Types.Int32);
                break;

            case 'J':
                locals[i] = ilgen.DeclareLocal(Types.Int64);
                break;

            case 'F':
                locals[i] = ilgen.DeclareLocal(Types.Single);
                break;

            case 'D':
                locals[i] = ilgen.DeclareLocal(Types.Double);
                break;

            case 'V':
                break;

            default:
                throw new BailoutException(Bailout.PreconditionViolated, "Unsupported typeChar(): " + name.typeChar());
            }
        }
    }