/// <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); }
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); }