< prev index next >

src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java

Print this page

        

*** 385,394 **** --- 385,402 ---- } private BoundMethodHandle.SpeciesData newSpeciesData(BasicType type) { return oldSpeciesData().extendWith(type); } + BoundMethodHandle bindArgumentQ(BoundMethodHandle mh, int pos, Object value, MethodHandle unbox) { + assert(mh.speciesData() == oldSpeciesData()); + BasicType bt = Q_TYPE; + MethodType type2 = bindArgumentType(mh, pos, bt); + LambdaForm form2 = bindArgumentForm(1+pos); + return mh.copyWithExtendL(type2, form2, value) + .copyWithExtendL(type2, form2, unbox); + } BoundMethodHandle bindArgumentL(BoundMethodHandle mh, int pos, Object value) { assert(mh.speciesData() == oldSpeciesData()); BasicType bt = L_TYPE; MethodType type2 = bindArgumentType(mh, pos, bt); LambdaForm form2 = bindArgumentForm(1+pos);
*** 445,466 **** } LambdaFormBuffer buf = buffer(); buf.startEdit(); BoundMethodHandle.SpeciesData oldData = oldSpeciesData(); ! BoundMethodHandle.SpeciesData newData = newSpeciesData(lambdaForm.parameterType(pos)); Name oldBaseAddress = lambdaForm.parameter(0); // BMH holding the values Name newBaseAddress; NamedFunction getter = newData.getterFunction(oldData.fieldCount()); if (pos != 0) { // The newly created LF will run with a different BMH. // Switch over any pre-existing BMH field references to the new BMH class. buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress); newBaseAddress = oldBaseAddress.withConstraint(newData); buf.renameParameter(0, newBaseAddress); buf.replaceParameterByNewExpression(pos, new Name(getter, newBaseAddress)); } else { // cannot bind the MH arg itself, unless oldData is empty assert(oldData == BoundMethodHandle.SpeciesData.EMPTY); newBaseAddress = new Name(L_TYPE).withConstraint(newData); buf.replaceParameterByNewExpression(0, new Name(getter, newBaseAddress)); --- 453,491 ---- } LambdaFormBuffer buf = buffer(); buf.startEdit(); BoundMethodHandle.SpeciesData oldData = oldSpeciesData(); ! BasicType ptype = lambdaForm.parameterType(pos); ! BoundMethodHandle.SpeciesData newData = (ptype != Q_TYPE) ? newSpeciesData(ptype) ! : oldData.extendWith(L_TYPE).extendWith(L_TYPE); // value + unbox MH Name oldBaseAddress = lambdaForm.parameter(0); // BMH holding the values Name newBaseAddress; NamedFunction getter = newData.getterFunction(oldData.fieldCount()); if (pos != 0) { // The newly created LF will run with a different BMH. // Switch over any pre-existing BMH field references to the new BMH class. buf.replaceFunctions(oldData.getterFunctions(), newData.getterFunctions(), oldBaseAddress); newBaseAddress = oldBaseAddress.withConstraint(newData); buf.renameParameter(0, newBaseAddress); + if (ptype == Q_TYPE) { + // Q-types are stored in boxed form. Unboxing step is required. + int exprPos = lambdaForm.arity(); + int UNBOX_MH = exprPos++; + int BOXED_VALUE = exprPos++; + int UNBOXED_VALUE = exprPos++; + NamedFunction unboxGetter = newData.getterFunction(oldData.fieldCount()+1); + buf.insertExpression(UNBOX_MH, new Name(unboxGetter, newBaseAddress)); + buf.insertExpression(BOXED_VALUE, new Name(getter, newBaseAddress)); + MethodType unboxInvokerType = MethodType.methodType(Q_TYPE.basicTypeClass(), L_TYPE.basicTypeClass()); + Name unbox = new Name(unboxInvokerType, buf.name(UNBOX_MH), buf.name(BOXED_VALUE)); + buf.insertExpression(UNBOXED_VALUE, unbox); + buf.replaceParameterByCopy(pos, UNBOXED_VALUE); + } else { buf.replaceParameterByNewExpression(pos, new Name(getter, newBaseAddress)); + } } else { // cannot bind the MH arg itself, unless oldData is empty assert(oldData == BoundMethodHandle.SpeciesData.EMPTY); newBaseAddress = new Name(L_TYPE).withConstraint(newData); buf.replaceParameterByNewExpression(0, new Name(getter, newBaseAddress));
< prev index next >