static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) { boolean needsInit = (which == LF_INVSTATIC_INIT); boolean doesAlloc = (which == LF_NEWINVSPECIAL); String linkerName; LambdaForm.Kind kind; switch (which) { case LF_INVVIRTUAL: linkerName = "linkToVirtual"; kind = DIRECT_INVOKE_VIRTUAL; break; case LF_INVSTATIC: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC; break; case LF_INVSTATIC_INIT: linkerName = "linkToStatic"; kind = DIRECT_INVOKE_STATIC_INIT; break; case LF_INVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_INVOKE_SPECIAL; break; case LF_INVINTERFACE: linkerName = "linkToInterface"; kind = DIRECT_INVOKE_INTERFACE; break; case LF_NEWINVSPECIAL: linkerName = "linkToSpecial"; kind = DIRECT_NEW_INVOKE_SPECIAL; break; default: throw new InternalError("which=" + which); } MethodType mtypeWithArg = mtype.appendParameterTypes(MemberName.class); if (doesAlloc) mtypeWithArg = mtypeWithArg .insertParameterTypes(0, Object.class) // insert newly allocated obj .changeReturnType(void.class); // <init> returns void MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic); try { linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class); } catch (ReflectiveOperationException ex) { throw newInternalError(ex); } final int DMH_THIS = 0; final int ARG_BASE = 1; final int ARG_LIMIT = ARG_BASE + mtype.parameterCount(); int nameCursor = ARG_LIMIT; final int NEW_OBJ = (doesAlloc ? nameCursor++ : -1); final int GET_MEMBER = nameCursor++; final 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(NF_allocateInstance, names[DMH_THIS]); names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]); } else if (needsInit) { names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]); } else { names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]); } assert (findDirectMethodHandle(names[GET_MEMBER]) == names[DMH_THIS]); Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER + 1, Object[].class); 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.arraycopy(outArgs, 0, outArgs, 1, outArgs.length - 2); outArgs[0] = names[NEW_OBJ]; result = NEW_OBJ; } names[LINKER_CALL] = new Name(linker, outArgs); String lambdaName = kind.defaultLambdaName + "_" + shortenSignature(basicTypeSignature(mtype)); LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result, kind); // This is a tricky bit of code. Don't send it through the LF interpreter. lform.compileToBytecode(); return lform; }