예제 #1
0
        /// <summary>
        /// Create a LF which simply reinvokes a target of the given basic type. </summary>
        internal static LambdaForm MakeReinvokerForm(MethodHandle target, int whichCache, Object constraint, String debugString, bool forceInline, NamedFunction getTargetFn, NamedFunction preActionFn)
        {
            MethodType mtype        = target.Type().BasicType();
            bool       customized   = (whichCache <0 || mtype.ParameterSlotCount()> MethodType.MAX_MH_INVOKER_ARITY);
            bool       hasPreAction = (preActionFn != null);
            LambdaForm form;

            if (!customized)
            {
                form = mtype.Form().CachedLambdaForm(whichCache);
                if (form != null)
                {
                    return(form);
                }
            }
            const int THIS_DMH = 0;
            const int ARG_BASE = 1;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
            int ARG_LIMIT  = ARG_BASE + mtype.ParameterCount();
            int nameCursor = ARG_LIMIT;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int PRE_ACTION = hasPreAction ? nameCursor++ : -1;
            int PRE_ACTION = hasPreAction ? nameCursor++: -1;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int NEXT_MH = customized ? -1 : nameCursor++;
            int NEXT_MH = customized ? -1 : nameCursor++;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int REINVOKE = nameCursor++;
            int REINVOKE = nameCursor++;

            LambdaForm.Name[] names = LambdaForm.Arguments(nameCursor - ARG_LIMIT, mtype.InvokerType());
            assert(names.Length == nameCursor);
            names[THIS_DMH] = names[THIS_DMH].WithConstraint(constraint);
            Object[] targetArgs;
            if (hasPreAction)
            {
                names[PRE_ACTION] = new LambdaForm.Name(preActionFn, names[THIS_DMH]);
            }
            if (customized)
            {
                targetArgs      = Arrays.CopyOfRange(names, ARG_BASE, ARG_LIMIT, typeof(Object[]));
                names[REINVOKE] = new LambdaForm.Name(target, targetArgs);                 // the invoker is the target itself
            }
            else
            {
                names[NEXT_MH]  = new LambdaForm.Name(getTargetFn, names[THIS_DMH]);
                targetArgs      = Arrays.CopyOfRange(names, THIS_DMH, ARG_LIMIT, typeof(Object[]));
                targetArgs[0]   = names[NEXT_MH];               // overwrite this MH with next MH
                names[REINVOKE] = new LambdaForm.Name(mtype, targetArgs);
            }
            form = new LambdaForm(debugString, ARG_LIMIT, names, forceInline);
            if (!customized)
            {
                form = mtype.Form().SetCachedLambdaForm(whichCache, form);
            }
            return(form);
        }
예제 #2
0
        private static LambdaForm MakePreparedLambdaForm(MethodType mtype, int which)
        {
            bool   needsInit = (which == LF_INVSTATIC_INIT);
            bool   doesAlloc = (which == LF_NEWINVSPECIAL);
            String linkerName, lambdaName;

            switch (which)
            {
            case LF_INVVIRTUAL:
                linkerName = "linkToVirtual";
                lambdaName = "DMH.invokeVirtual";
                break;

            case LF_INVSTATIC:
                linkerName = "linkToStatic";
                lambdaName = "DMH.invokeStatic";
                break;

            case LF_INVSTATIC_INIT:
                linkerName = "linkToStatic";
                lambdaName = "DMH.invokeStaticInit";
                break;

            case LF_INVSPECIAL:
                linkerName = "linkToSpecial";
                lambdaName = "DMH.invokeSpecial";
                break;

            case LF_INVINTERFACE:
                linkerName = "linkToInterface";
                lambdaName = "DMH.invokeInterface";
                break;

            case LF_NEWINVSPECIAL:
                linkerName = "linkToSpecial";
                lambdaName = "DMH.newInvokeSpecial";
                break;

            default:
                throw new InternalError("which=" + which);
            }
            MethodType mtypeWithArg = mtype.AppendParameterTypes(typeof(MemberName));

            if (doesAlloc)
            {
                mtypeWithArg = mtypeWithArg.InsertParameterTypes(0, typeof(Object)).ChangeReturnType(typeof(void));                 // <init> returns void -  insert newly allocated obj
            }
            MemberName linker = new MemberName(typeof(MethodHandle), linkerName, mtypeWithArg, REF_invokeStatic);

            try
            {
                linker = IMPL_NAMES.ResolveOrFail(REF_invokeStatic, linker, null, typeof(NoSuchMethodException));
            }
            catch (ReflectiveOperationException ex)
            {
                throw newInternalError(ex);
            }
            const int DMH_THIS = 0;
            const int ARG_BASE = 1;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
            int ARG_LIMIT  = ARG_BASE + mtype.ParameterCount();
            int nameCursor = ARG_LIMIT;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1);
            int NEW_OBJ = (doesAlloc ? nameCursor++: -1);
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int GET_MEMBER = nameCursor++;
            int GET_MEMBER = nameCursor++;
//JAVA TO C# CONVERTER WARNING: The original Java variable was marked 'final':
//ORIGINAL LINE: final int LINKER_CALL = nameCursor++;
            int LINKER_CALL = nameCursor++;

            Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.InvokerType());
            assert(names.Length == nameCursor);
            if (doesAlloc)
            {
                // names = { argx,y,z,... new C, init method }
                names[NEW_OBJ]    = new Name(Lazy.NF_allocateInstance, names[DMH_THIS]);
                names[GET_MEMBER] = new Name(Lazy.NF_constructorMethod, names[DMH_THIS]);
            }
            else if (needsInit)
            {
                names[GET_MEMBER] = new Name(Lazy.NF_internalMemberNameEnsureInit, names[DMH_THIS]);
            }
            else
            {
                names[GET_MEMBER] = new Name(Lazy.NF_internalMemberName, names[DMH_THIS]);
            }
            assert(FindDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]);
            Object[] outArgs = Arrays.CopyOfRange(names, ARG_BASE, GET_MEMBER + 1, typeof(Object[]));
            assert(outArgs[outArgs.Length - 1] == names[GET_MEMBER]);             // look, shifted args!
            int result = LAST_RESULT;

            if (doesAlloc)
            {
                assert(outArgs[outArgs.Length - 2] == names[NEW_OBJ]);                 // got to move this one
                System.Array.Copy(outArgs, 0, outArgs, 1, outArgs.Length - 2);
                outArgs[0] = names[NEW_OBJ];
                result     = NEW_OBJ;
            }
            names[LINKER_CALL] = new Name(linker, outArgs);
            lambdaName        += "_" + shortenSignature(basicTypeSignature(mtype));
            LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);

            // This is a tricky bit of code.  Don't send it through the LF interpreter.
            lform.CompileToBytecode();
            return(lform);
        }