< 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 >