8268124: Update java.lang to use switch expressions

Reviewed-by: naoto, darcy, mchung, iris, lancea, dfuchs
This commit is contained in:
Patrick Concannon 2021-06-10 11:12:37 +00:00
parent a187fcc3ec
commit d43c8a74b3
22 changed files with 421 additions and 551 deletions

View File

@ -72,23 +72,15 @@ abstract class CharacterData {
if (ch >>> 8 == 0) { // fast-path
return CharacterDataLatin1.instance;
} else {
switch(ch >>> 16) { //plane 00-16
case(0):
return CharacterData00.instance;
case(1):
return CharacterData01.instance;
case(2):
return CharacterData02.instance;
case(3):
return CharacterData03.instance;
case(14):
return CharacterData0E.instance;
case(15): // Private Use
case(16): // Private Use
return CharacterDataPrivateUse.instance;
default:
return CharacterDataUndefined.instance;
}
return switch (ch >>> 16) { //plane 00-16
case 0 -> CharacterData00.instance;
case 1 -> CharacterData01.instance;
case 2 -> CharacterData02.instance;
case 3 -> CharacterData03.instance;
case 14 -> CharacterData0E.instance;
case 15, 16 -> CharacterDataPrivateUse.instance; // Both cases Private Use
default -> CharacterDataUndefined.instance;
};
}
}
}

View File

@ -170,25 +170,14 @@ final class ConditionalSpecialCasing {
}
private static boolean isConditionMet(String src, int index, Locale locale, int condition) {
switch (condition) {
case FINAL_CASED:
return isFinalCased(src, index, locale);
case AFTER_SOFT_DOTTED:
return isAfterSoftDotted(src, index);
case MORE_ABOVE:
return isMoreAbove(src, index);
case AFTER_I:
return isAfterI(src, index);
case NOT_BEFORE_DOT:
return !isBeforeDot(src, index);
default:
return true;
}
return switch (condition) {
case FINAL_CASED -> isFinalCased(src, index, locale);
case AFTER_SOFT_DOTTED -> isAfterSoftDotted(src, index);
case MORE_ABOVE -> isMoreAbove(src, index);
case AFTER_I -> isAfterI(src, index);
case NOT_BEFORE_DOT -> !isBeforeDot(src, index);
default -> true;
};
}
/**

View File

@ -213,38 +213,27 @@ public final class Long extends Number
if (i >= 0)
return toString(i, radix);
else {
switch (radix) {
case 2:
return toBinaryString(i);
case 4:
return toUnsignedString0(i, 2);
case 8:
return toOctalString(i);
case 10:
/*
* We can get the effect of an unsigned division by 10
* on a long value by first shifting right, yielding a
* positive value, and then dividing by 5. This
* allows the last digit and preceding digits to be
* isolated more quickly than by an initial conversion
* to BigInteger.
*/
long quot = (i >>> 1) / 5;
long rem = i - quot * 10;
return toString(quot) + rem;
case 16:
return toHexString(i);
case 32:
return toUnsignedString0(i, 5);
default:
return toUnsignedBigInteger(i).toString(radix);
}
return switch (radix) {
case 2 -> toBinaryString(i);
case 4 -> toUnsignedString0(i, 2);
case 8 -> toOctalString(i);
case 10 -> {
/*
* We can get the effect of an unsigned division by 10
* on a long value by first shifting right, yielding a
* positive value, and then dividing by 5. This
* allows the last digit and preceding digits to be
* isolated more quickly than by an initial conversion
* to BigInteger.
*/
long quot = (i >>> 1) / 5;
long rem = i - quot * 10;
yield toString(quot) + rem;
}
case 16 -> toHexString(i);
case 32 -> toUnsignedString0(i, 5);
default -> toUnsignedBigInteger(i).toString(radix);
};
}
}

View File

@ -1926,29 +1926,25 @@ public final class Math {
public static double ulp(double d) {
int exp = getExponent(d);
switch(exp) {
case Double.MAX_EXPONENT + 1: // NaN or infinity
return Math.abs(d);
return switch(exp) {
case Double.MAX_EXPONENT + 1 -> Math.abs(d); // NaN or infinity
case Double.MIN_EXPONENT - 1 -> Double.MIN_VALUE; // zero or subnormal
default -> {
assert exp <= Double.MAX_EXPONENT && exp >= Double.MIN_EXPONENT;
case Double.MIN_EXPONENT - 1: // zero or subnormal
return Double.MIN_VALUE;
default:
assert exp <= Double.MAX_EXPONENT && exp >= Double.MIN_EXPONENT;
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH-1);
if (exp >= Double.MIN_EXPONENT) {
return powerOfTwoD(exp);
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (DoubleConsts.SIGNIFICAND_WIDTH - 1);
if (exp >= Double.MIN_EXPONENT) {
yield powerOfTwoD(exp);
} else {
// return a subnormal result; left shift integer
// representation of Double.MIN_VALUE appropriate
// number of positions
yield Double.longBitsToDouble(1L <<
(exp - (Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH - 1))));
}
}
else {
// return a subnormal result; left shift integer
// representation of Double.MIN_VALUE appropriate
// number of positions
return Double.longBitsToDouble(1L <<
(exp - (Double.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1)) ));
}
}
};
}
/**
@ -1977,28 +1973,25 @@ public final class Math {
public static float ulp(float f) {
int exp = getExponent(f);
switch(exp) {
case Float.MAX_EXPONENT+1: // NaN or infinity
return Math.abs(f);
return switch(exp) {
case Float.MAX_EXPONENT + 1 -> Math.abs(f); // NaN or infinity
case Float.MIN_EXPONENT - 1 -> Float.MIN_VALUE; // zero or subnormal
default -> {
assert exp <= Float.MAX_EXPONENT && exp >= Float.MIN_EXPONENT;
case Float.MIN_EXPONENT-1: // zero or subnormal
return Float.MIN_VALUE;
default:
assert exp <= Float.MAX_EXPONENT && exp >= Float.MIN_EXPONENT;
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (FloatConsts.SIGNIFICAND_WIDTH-1);
if (exp >= Float.MIN_EXPONENT) {
return powerOfTwoF(exp);
} else {
// return a subnormal result; left shift integer
// representation of FloatConsts.MIN_VALUE appropriate
// number of positions
return Float.intBitsToFloat(1 <<
(exp - (Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1)) ));
// ulp(x) is usually 2^(SIGNIFICAND_WIDTH-1)*(2^ilogb(x))
exp = exp - (FloatConsts.SIGNIFICAND_WIDTH - 1);
if (exp >= Float.MIN_EXPONENT) {
yield powerOfTwoF(exp);
} else {
// return a subnormal result; left shift integer
// representation of FloatConsts.MIN_VALUE appropriate
// number of positions
yield Float.intBitsToFloat(1 <<
(exp - (Float.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH - 1))));
}
}
}
};
}
/**

View File

@ -72,11 +72,11 @@ final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
requireNonNull(type);
switch (kind) {
case CONSTRUCTOR: validateConstructor(type); break;
case GETTER: validateFieldType(type, false, true); break;
case SETTER: validateFieldType(type, true, true); break;
case STATIC_GETTER: validateFieldType(type, false, false); break;
case STATIC_SETTER: validateFieldType(type, true, false); break;
case CONSTRUCTOR -> validateConstructor(type);
case GETTER -> validateFieldType(type, false, true);
case SETTER -> validateFieldType(type, true, true);
case STATIC_GETTER -> validateFieldType(type, false, false);
case STATIC_SETTER -> validateFieldType(type, true, false);
}
this.kind = kind;
@ -134,57 +134,40 @@ final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
@Override
public String lookupDescriptor() {
switch (kind) {
case VIRTUAL:
case SPECIAL:
case INTERFACE_VIRTUAL:
case INTERFACE_SPECIAL:
return invocationType.dropParameterTypes(0, 1).descriptorString();
case STATIC:
case INTERFACE_STATIC:
return invocationType.descriptorString();
case CONSTRUCTOR:
return invocationType.changeReturnType(CD_void).descriptorString();
case GETTER:
case STATIC_GETTER:
return invocationType.returnType().descriptorString();
case SETTER:
return invocationType.parameterType(1).descriptorString();
case STATIC_SETTER:
return invocationType.parameterType(0).descriptorString();
default:
throw new IllegalStateException(kind.toString());
}
return switch (kind) {
case VIRTUAL,
SPECIAL,
INTERFACE_VIRTUAL,
INTERFACE_SPECIAL -> invocationType.dropParameterTypes(0, 1).descriptorString();
case STATIC,
INTERFACE_STATIC -> invocationType.descriptorString();
case CONSTRUCTOR -> invocationType.changeReturnType(CD_void).descriptorString();
case GETTER,
STATIC_GETTER -> invocationType.returnType().descriptorString();
case SETTER -> invocationType.parameterType(1).descriptorString();
case STATIC_SETTER -> invocationType.parameterType(0).descriptorString();
default -> throw new IllegalStateException(kind.toString());
};
}
public MethodHandle resolveConstantDesc(MethodHandles.Lookup lookup)
throws ReflectiveOperationException {
Class<?> resolvedOwner = (Class<?>) owner.resolveConstantDesc(lookup);
MethodType invocationType = (MethodType) this.invocationType().resolveConstantDesc(lookup);
switch (kind) {
case STATIC:
case INTERFACE_STATIC:
return lookup.findStatic(resolvedOwner, name, invocationType);
case INTERFACE_VIRTUAL:
case VIRTUAL:
return lookup.findVirtual(resolvedOwner, name, invocationType.dropParameterTypes(0, 1));
case SPECIAL:
case INTERFACE_SPECIAL:
return lookup.findSpecial(resolvedOwner, name, invocationType.dropParameterTypes(0, 1),
lookup.lookupClass());
case CONSTRUCTOR:
return lookup.findConstructor(resolvedOwner, invocationType.changeReturnType(void.class));
case GETTER:
return lookup.findGetter(resolvedOwner, name, invocationType.returnType());
case STATIC_GETTER:
return lookup.findStaticGetter(resolvedOwner, name, invocationType.returnType());
case SETTER:
return lookup.findSetter(resolvedOwner, name, invocationType.parameterType(1));
case STATIC_SETTER:
return lookup.findStaticSetter(resolvedOwner, name, invocationType.parameterType(0));
default:
throw new IllegalStateException(kind.name());
}
return switch (kind) {
case STATIC,
INTERFACE_STATIC -> lookup.findStatic(resolvedOwner, name, invocationType);
case VIRTUAL,
INTERFACE_VIRTUAL -> lookup.findVirtual(resolvedOwner, name, invocationType.dropParameterTypes(0, 1));
case SPECIAL,
INTERFACE_SPECIAL -> lookup.findSpecial(resolvedOwner, name, invocationType.dropParameterTypes(0, 1), lookup.lookupClass());
case CONSTRUCTOR -> lookup.findConstructor(resolvedOwner, invocationType.changeReturnType(void.class));
case GETTER -> lookup.findGetter(resolvedOwner, name, invocationType.returnType());
case STATIC_GETTER -> lookup.findStaticGetter(resolvedOwner, name, invocationType.returnType());
case SETTER -> lookup.findSetter(resolvedOwner, name, invocationType.parameterType(1));
case STATIC_SETTER -> lookup.findStaticSetter(resolvedOwner, name, invocationType.parameterType(0));
default -> throw new IllegalStateException(kind.name());
};
}
/**

View File

@ -156,15 +156,13 @@ public sealed interface MethodHandleDesc
ClassDesc owner,
String fieldName,
ClassDesc fieldType) {
MethodTypeDesc mtr;
switch (kind) {
case GETTER: mtr = MethodTypeDesc.of(fieldType, owner); break;
case SETTER: mtr = MethodTypeDesc.of(CD_void, owner, fieldType); break;
case STATIC_GETTER: mtr = MethodTypeDesc.of(fieldType); break;
case STATIC_SETTER: mtr = MethodTypeDesc.of(CD_void, fieldType); break;
default:
throw new IllegalArgumentException(kind.toString());
}
MethodTypeDesc mtr = switch (kind) {
case GETTER -> MethodTypeDesc.of(fieldType, owner);
case SETTER -> MethodTypeDesc.of(CD_void, owner, fieldType);
case STATIC_GETTER -> MethodTypeDesc.of(fieldType);
case STATIC_SETTER -> MethodTypeDesc.of(CD_void, fieldType);
default -> throw new IllegalArgumentException(kind.toString());
};
return new DirectMethodHandleDescImpl(kind, owner, fieldName, mtr);
}

View File

@ -64,19 +64,14 @@ abstract class BoundMethodHandle extends MethodHandle {
static BoundMethodHandle bindSingle(MethodType type, LambdaForm form, BasicType xtype, Object x) {
// for some type signatures, there exist pre-defined concrete BMH classes
try {
switch (xtype) {
case L_TYPE:
return bindSingle(type, form, x); // Use known fast path.
case I_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(I_TYPE_NUM).factory().invokeBasic(type, form, ValueConversions.widenSubword(x));
case J_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(J_TYPE_NUM).factory().invokeBasic(type, form, (long) x);
case F_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(F_TYPE_NUM).factory().invokeBasic(type, form, (float) x);
case D_TYPE:
return (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(D_TYPE_NUM).factory().invokeBasic(type, form, (double) x);
default : throw newInternalError("unexpected xtype: " + xtype);
}
return switch (xtype) {
case L_TYPE -> bindSingle(type, form, x); // Use known fast path.
case I_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(I_TYPE_NUM).factory().invokeBasic(type, form, ValueConversions.widenSubword(x));
case J_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(J_TYPE_NUM).factory().invokeBasic(type, form, (long) x);
case F_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(F_TYPE_NUM).factory().invokeBasic(type, form, (float) x);
case D_TYPE -> (BoundMethodHandle) SPECIALIZER.topSpecies().extendWith(D_TYPE_NUM).factory().invokeBasic(type, form, (double) x);
default -> throw newInternalError("unexpected xtype: " + xtype);
};
} catch (Throwable t) {
throw uncaughtException(t);
}

View File

@ -853,14 +853,14 @@ abstract class ClassSpecializer<T,K,S extends ClassSpecializer<T,K,S>.SpeciesDat
}
private int typeLoadOp(char t) {
switch (t) {
case 'L': return ALOAD;
case 'I': return ILOAD;
case 'J': return LLOAD;
case 'F': return FLOAD;
case 'D': return DLOAD;
default : throw newInternalError("unrecognized type " + t);
}
return switch (t) {
case 'L' -> ALOAD;
case 'I' -> ILOAD;
case 'J' -> LLOAD;
case 'F' -> FLOAD;
case 'D' -> DLOAD;
default -> throw newInternalError("unrecognized type " + t);
};
}
private void emitIntConstant(int con, MethodVisitor mv) {

View File

@ -163,11 +163,11 @@ abstract class DelegatingMethodHandle extends MethodHandle {
}
private static Kind whichKind(int whichCache) {
switch(whichCache) {
case MethodTypeForm.LF_REBIND: return BOUND_REINVOKER;
case MethodTypeForm.LF_DELEGATE: return DELEGATE;
default: return REINVOKER;
}
return switch (whichCache) {
case MethodTypeForm.LF_REBIND -> BOUND_REINVOKER;
case MethodTypeForm.LF_DELEGATE -> DELEGATE;
default -> REINVOKER;
};
}
static final NamedFunction NF_getTarget;

View File

@ -86,8 +86,8 @@ class DirectMethodHandle extends MethodHandle {
if (!member.isField()) {
// refKind reflects the original type of lookup via findSpecial or
// findVirtual etc.
switch (refKind) {
case REF_invokeSpecial: {
return switch (refKind) {
case REF_invokeSpecial -> {
member = member.asSpecial();
// if caller is an interface we need to adapt to get the
// receiver check inserted
@ -95,20 +95,20 @@ class DirectMethodHandle extends MethodHandle {
throw new InternalError("callerClass must not be null for REF_invokeSpecial");
}
LambdaForm lform = preparedLambdaForm(member, callerClass.isInterface());
return new Special(mtype, lform, member, true, callerClass);
yield new Special(mtype, lform, member, true, callerClass);
}
case REF_invokeInterface: {
case REF_invokeInterface -> {
// for interfaces we always need the receiver typecheck,
// so we always pass 'true' to ensure we adapt if needed
// to include the REF_invokeSpecial case
LambdaForm lform = preparedLambdaForm(member, true);
return new Interface(mtype, lform, member, true, refc);
yield new Interface(mtype, lform, member, true, refc);
}
default: {
default -> {
LambdaForm lform = preparedLambdaForm(member);
return new DirectMethodHandle(mtype, lform, member, true);
yield new DirectMethodHandle(mtype, lform, member, true);
}
}
};
} else {
LambdaForm lform = preparedFieldLambdaForm(member);
if (member.isStatic()) {
@ -194,20 +194,19 @@ class DirectMethodHandle extends MethodHandle {
assert(m.isInvocable()) : m; // call preparedFieldLambdaForm instead
MethodType mtype = m.getInvocationType().basicType();
assert(!m.isMethodHandleInvoke()) : m;
int which;
// MemberName.getReferenceKind represents the JVM optimized form of the call
// as distinct from the "kind" passed to DMH.make which represents the original
// bytecode-equivalent request. Specifically private/final methods that use a direct
// call have getReferenceKind adapted to REF_invokeSpecial, even though the actual
// invocation mode may be invokevirtual or invokeinterface.
switch (m.getReferenceKind()) {
case REF_invokeVirtual: which = LF_INVVIRTUAL; break;
case REF_invokeStatic: which = LF_INVSTATIC; break;
case REF_invokeSpecial: which = LF_INVSPECIAL; break;
case REF_invokeInterface: which = LF_INVINTERFACE; break;
case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
default: throw new InternalError(m.toString());
}
int which = switch (m.getReferenceKind()) {
case REF_invokeVirtual -> LF_INVVIRTUAL;
case REF_invokeStatic -> LF_INVSTATIC;
case REF_invokeSpecial -> LF_INVSPECIAL;
case REF_invokeInterface -> LF_INVINTERFACE;
case REF_newInvokeSpecial -> LF_NEWINVSPECIAL;
default -> throw new InternalError(m.toString());
};
if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
// precompute the barrier-free version:
preparedLambdaForm(mtype, which);
@ -664,14 +663,13 @@ class DirectMethodHandle extends MethodHandle {
private static LambdaForm preparedFieldLambdaForm(MemberName m) {
Class<?> ftype = m.getFieldType();
boolean isVolatile = m.isVolatile();
byte formOp;
switch (m.getReferenceKind()) {
case REF_getField: formOp = AF_GETFIELD; break;
case REF_putField: formOp = AF_PUTFIELD; break;
case REF_getStatic: formOp = AF_GETSTATIC; break;
case REF_putStatic: formOp = AF_PUTSTATIC; break;
default: throw new InternalError(m.toString());
}
byte formOp = switch (m.getReferenceKind()) {
case REF_getField -> AF_GETFIELD;
case REF_putField -> AF_PUTFIELD;
case REF_getStatic -> AF_GETSTATIC;
case REF_putStatic -> AF_PUTSTATIC;
default -> throw new InternalError(m.toString());
};
if (shouldBeInitialized(m)) {
// precompute the barrier-free version:
preparedFieldLambdaForm(formOp, isVolatile, ftype);

View File

@ -598,20 +598,14 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*;
}
private int invocationOpcode() throws InternalError {
switch (implKind) {
case MethodHandleInfo.REF_invokeStatic:
return INVOKESTATIC;
case MethodHandleInfo.REF_newInvokeSpecial:
return INVOKESPECIAL;
case MethodHandleInfo.REF_invokeVirtual:
return INVOKEVIRTUAL;
case MethodHandleInfo.REF_invokeInterface:
return INVOKEINTERFACE;
case MethodHandleInfo.REF_invokeSpecial:
return INVOKESPECIAL;
default:
throw new InternalError("Unexpected invocation kind: " + implKind);
}
return switch (implKind) {
case MethodHandleInfo.REF_invokeStatic -> INVOKESTATIC;
case MethodHandleInfo.REF_newInvokeSpecial -> INVOKESPECIAL;
case MethodHandleInfo.REF_invokeVirtual -> INVOKEVIRTUAL;
case MethodHandleInfo.REF_invokeInterface -> INVOKEINTERFACE;
case MethodHandleInfo.REF_invokeSpecial -> INVOKESPECIAL;
default -> throw new InternalError("Unexpected invocation kind: " + implKind);
};
}
}

View File

@ -492,15 +492,14 @@ class InvokerBytecodeGenerator {
}
private int loadInsnOpcode(BasicType type) throws InternalError {
switch (type) {
case I_TYPE: return Opcodes.ILOAD;
case J_TYPE: return Opcodes.LLOAD;
case F_TYPE: return Opcodes.FLOAD;
case D_TYPE: return Opcodes.DLOAD;
case L_TYPE: return Opcodes.ALOAD;
default:
throw new InternalError("unknown type: " + type);
}
return switch (type) {
case I_TYPE -> Opcodes.ILOAD;
case J_TYPE -> Opcodes.LLOAD;
case F_TYPE -> Opcodes.FLOAD;
case D_TYPE -> Opcodes.DLOAD;
case L_TYPE -> Opcodes.ALOAD;
default -> throw new InternalError("unknown type: " + type);
};
}
private void emitAloadInsn(int index) {
emitLoadInsn(L_TYPE, index);
@ -512,50 +511,48 @@ class InvokerBytecodeGenerator {
}
private int storeInsnOpcode(BasicType type) throws InternalError {
switch (type) {
case I_TYPE: return Opcodes.ISTORE;
case J_TYPE: return Opcodes.LSTORE;
case F_TYPE: return Opcodes.FSTORE;
case D_TYPE: return Opcodes.DSTORE;
case L_TYPE: return Opcodes.ASTORE;
default:
throw new InternalError("unknown type: " + type);
}
return switch (type) {
case I_TYPE -> Opcodes.ISTORE;
case J_TYPE -> Opcodes.LSTORE;
case F_TYPE -> Opcodes.FSTORE;
case D_TYPE -> Opcodes.DSTORE;
case L_TYPE -> Opcodes.ASTORE;
default -> throw new InternalError("unknown type: " + type);
};
}
private void emitAstoreInsn(int index) {
emitStoreInsn(L_TYPE, index);
}
private byte arrayTypeCode(Wrapper elementType) {
switch (elementType) {
case BOOLEAN: return Opcodes.T_BOOLEAN;
case BYTE: return Opcodes.T_BYTE;
case CHAR: return Opcodes.T_CHAR;
case SHORT: return Opcodes.T_SHORT;
case INT: return Opcodes.T_INT;
case LONG: return Opcodes.T_LONG;
case FLOAT: return Opcodes.T_FLOAT;
case DOUBLE: return Opcodes.T_DOUBLE;
case OBJECT: return 0; // in place of Opcodes.T_OBJECT
default: throw new InternalError();
}
return (byte) switch (elementType) {
case BOOLEAN -> Opcodes.T_BOOLEAN;
case BYTE -> Opcodes.T_BYTE;
case CHAR -> Opcodes.T_CHAR;
case SHORT -> Opcodes.T_SHORT;
case INT -> Opcodes.T_INT;
case LONG -> Opcodes.T_LONG;
case FLOAT -> Opcodes.T_FLOAT;
case DOUBLE -> Opcodes.T_DOUBLE;
case OBJECT -> 0; // in place of Opcodes.T_OBJECT
default -> throw new InternalError();
};
}
private int arrayInsnOpcode(byte tcode, int aaop) throws InternalError {
assert(aaop == Opcodes.AASTORE || aaop == Opcodes.AALOAD);
int xas;
switch (tcode) {
case Opcodes.T_BOOLEAN: xas = Opcodes.BASTORE; break;
case Opcodes.T_BYTE: xas = Opcodes.BASTORE; break;
case Opcodes.T_CHAR: xas = Opcodes.CASTORE; break;
case Opcodes.T_SHORT: xas = Opcodes.SASTORE; break;
case Opcodes.T_INT: xas = Opcodes.IASTORE; break;
case Opcodes.T_LONG: xas = Opcodes.LASTORE; break;
case Opcodes.T_FLOAT: xas = Opcodes.FASTORE; break;
case Opcodes.T_DOUBLE: xas = Opcodes.DASTORE; break;
case 0: xas = Opcodes.AASTORE; break;
default: throw new InternalError();
}
int xas = switch (tcode) {
case Opcodes.T_BOOLEAN -> Opcodes.BASTORE;
case Opcodes.T_BYTE -> Opcodes.BASTORE;
case Opcodes.T_CHAR -> Opcodes.CASTORE;
case Opcodes.T_SHORT -> Opcodes.SASTORE;
case Opcodes.T_INT -> Opcodes.IASTORE;
case Opcodes.T_LONG -> Opcodes.LASTORE;
case Opcodes.T_FLOAT -> Opcodes.FASTORE;
case Opcodes.T_DOUBLE -> Opcodes.DASTORE;
case 0 -> Opcodes.AASTORE;
default -> throw new InternalError();
};
return xas - Opcodes.AASTORE + aaop;
}
@ -1383,17 +1380,11 @@ class InvokerBytecodeGenerator {
}
private static int popInsnOpcode(BasicType type) {
switch (type) {
case I_TYPE:
case F_TYPE:
case L_TYPE:
return Opcodes.POP;
case J_TYPE:
case D_TYPE:
return Opcodes.POP2;
default:
throw new InternalError("unknown type: " + type);
}
return switch (type) {
case I_TYPE, F_TYPE, L_TYPE -> Opcodes.POP;
case J_TYPE, D_TYPE -> Opcodes.POP2;
default -> throw new InternalError("unknown type: " + type);
};
}
private Name emitTableSwitch(int pos, int numCases) {
@ -1663,14 +1654,14 @@ class InvokerBytecodeGenerator {
}
private void emitZero(BasicType type) {
switch (type) {
case I_TYPE: mv.visitInsn(Opcodes.ICONST_0); break;
case J_TYPE: mv.visitInsn(Opcodes.LCONST_0); break;
case F_TYPE: mv.visitInsn(Opcodes.FCONST_0); break;
case D_TYPE: mv.visitInsn(Opcodes.DCONST_0); break;
case L_TYPE: mv.visitInsn(Opcodes.ACONST_NULL); break;
default: throw new InternalError("unknown type: " + type);
}
mv.visitInsn(switch (type) {
case I_TYPE -> Opcodes.ICONST_0;
case J_TYPE -> Opcodes.LCONST_0;
case F_TYPE -> Opcodes.FCONST_0;
case D_TYPE -> Opcodes.DCONST_0;
case L_TYPE -> Opcodes.ACONST_NULL;
default -> throw new InternalError("unknown type: " + type);
});
}
private void emitPushArguments(Name args, int start) {
@ -1778,30 +1769,28 @@ class InvokerBytecodeGenerator {
// cast to {long,float,double} - this is verbose
boolean error = false;
switch (from) {
case LONG:
switch (to) {
case FLOAT: mv.visitInsn(Opcodes.L2F); break;
case DOUBLE: mv.visitInsn(Opcodes.L2D); break;
default: error = true; break;
case LONG -> {
switch (to) {
case FLOAT -> mv.visitInsn(Opcodes.L2F);
case DOUBLE -> mv.visitInsn(Opcodes.L2D);
default -> error = true;
}
}
break;
case FLOAT:
switch (to) {
case LONG : mv.visitInsn(Opcodes.F2L); break;
case DOUBLE: mv.visitInsn(Opcodes.F2D); break;
default: error = true; break;
case FLOAT -> {
switch (to) {
case LONG -> mv.visitInsn(Opcodes.F2L);
case DOUBLE -> mv.visitInsn(Opcodes.F2D);
default -> error = true;
}
}
break;
case DOUBLE:
switch (to) {
case LONG : mv.visitInsn(Opcodes.D2L); break;
case FLOAT: mv.visitInsn(Opcodes.D2F); break;
default: error = true; break;
case DOUBLE -> {
switch (to) {
case LONG -> mv.visitInsn(Opcodes.D2L);
case FLOAT -> mv.visitInsn(Opcodes.D2F);
default -> error = true;
}
}
break;
default:
error = true;
break;
default -> error = true;
}
if (error) {
throw new IllegalStateException("unhandled prim cast: " + from + "2" + to);

View File

@ -254,12 +254,11 @@ class Invokers {
static MemberName methodHandleInvokeLinkerMethod(String name,
MethodType mtype,
Object[] appendixResult) {
int which;
switch (name) {
case "invokeExact": which = MethodTypeForm.LF_EX_LINKER; break;
case "invoke": which = MethodTypeForm.LF_GEN_LINKER; break;
default: throw new InternalError("not invoker: "+name);
}
int which = switch (name) {
case "invokeExact" -> MethodTypeForm.LF_EX_LINKER;
case "invoke" -> MethodTypeForm.LF_GEN_LINKER;
default -> throw new InternalError("not invoker: " + name);
};
LambdaForm lform;
if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MH_LINKER_ARG_APPENDED) {
lform = invokeHandleForm(mtype, false, which);
@ -660,24 +659,16 @@ class Invokers {
private static NamedFunction createFunction(byte func) {
try {
switch (func) {
case NF_checkExactType:
return getNamedFunction("checkExactType", MethodType.methodType(void.class, MethodHandle.class, MethodType.class));
case NF_checkGenericType:
return getNamedFunction("checkGenericType", MethodType.methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
case NF_getCallSiteTarget:
return getNamedFunction("getCallSiteTarget", MethodType.methodType(MethodHandle.class, CallSite.class));
case NF_checkCustomized:
return getNamedFunction("checkCustomized", MethodType.methodType(void.class, MethodHandle.class));
case NF_checkVarHandleGenericType:
return getNamedFunction("checkVarHandleGenericType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
case NF_checkVarHandleExactType:
return getNamedFunction("checkVarHandleExactType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
case NF_directVarHandleTarget:
return getNamedFunction("directVarHandleTarget", MethodType.methodType(VarHandle.class, VarHandle.class));
default:
throw newInternalError("Unknown function: " + func);
}
return switch (func) {
case NF_checkExactType -> getNamedFunction("checkExactType", MethodType.methodType(void.class, MethodHandle.class, MethodType.class));
case NF_checkGenericType -> getNamedFunction("checkGenericType", MethodType.methodType(MethodHandle.class, MethodHandle.class, MethodType.class));
case NF_getCallSiteTarget -> getNamedFunction("getCallSiteTarget", MethodType.methodType(MethodHandle.class, CallSite.class));
case NF_checkCustomized -> getNamedFunction("checkCustomized", MethodType.methodType(void.class, MethodHandle.class));
case NF_checkVarHandleGenericType -> getNamedFunction("checkVarHandleGenericType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
case NF_checkVarHandleExactType -> getNamedFunction("checkVarHandleExactType", MethodType.methodType(MethodHandle.class, VarHandle.class, VarHandle.AccessDescriptor.class));
case NF_directVarHandleTarget -> getNamedFunction("directVarHandleTarget", MethodType.methodType(VarHandle.class, VarHandle.class));
default -> throw newInternalError("Unknown function: " + func);
};
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}

View File

@ -187,22 +187,17 @@ class LambdaForm {
return ALL_TYPES[type];
}
static BasicType basicType(char type) {
switch (type) {
case 'L': return L_TYPE;
case 'I': return I_TYPE;
case 'J': return J_TYPE;
case 'F': return F_TYPE;
case 'D': return D_TYPE;
case 'V': return V_TYPE;
return switch (type) {
case 'L' -> L_TYPE;
case 'I' -> I_TYPE;
case 'J' -> J_TYPE;
case 'F' -> F_TYPE;
case 'D' -> D_TYPE;
case 'V' -> V_TYPE;
// all subword types are represented as ints
case 'Z':
case 'B':
case 'S':
case 'C':
return I_TYPE;
default:
throw newInternalError("Unknown type char: '"+type+"'");
}
case 'Z', 'B', 'S', 'C' -> I_TYPE;
default -> throw newInternalError("Unknown type char: '" + type + "'");
};
}
static BasicType basicType(Wrapper type) {
char c = type.basicTypeChar();

View File

@ -313,20 +313,22 @@ final class MemberName implements Member, Cloneable {
/*non-public*/
boolean referenceKindIsConsistentWith(int originalRefKind) {
int refKind = getReferenceKind();
if (refKind == originalRefKind) return true;
switch (originalRefKind) {
case REF_invokeInterface:
// Looking up an interface method, can get (e.g.) Object.hashCode
assert(refKind == REF_invokeVirtual ||
refKind == REF_invokeSpecial) : this;
return true;
case REF_invokeVirtual:
case REF_newInvokeSpecial:
// Looked up a virtual, can get (e.g.) final String.hashCode.
assert(refKind == REF_invokeSpecial) : this;
return true;
if (refKind == originalRefKind) return true;
if (getClass().desiredAssertionStatus()) {
switch (originalRefKind) {
case REF_invokeInterface -> {
// Looking up an interface method, can get (e.g.) Object.hashCode
assert (refKind == REF_invokeVirtual || refKind == REF_invokeSpecial) : this;
}
case REF_invokeVirtual, REF_newInvokeSpecial -> {
// Looked up a virtual, can get (e.g.) final String.hashCode.
assert (refKind == REF_invokeSpecial) : this;
}
default -> {
assert (false) : this + " != " + MethodHandleNatives.refKindName((byte) originalRefKind);
}
}
}
assert(false) : this+" != "+MethodHandleNatives.refKindName((byte)originalRefKind);
return true;
}
private boolean staticIsConsistent() {

View File

@ -1558,32 +1558,22 @@ assertEquals("[three, thee, tee]", asListFix.invoke((Object)argv).toString());
return Optional.empty();
}
switch (info.getReferenceKind()) {
case REF_getField:
return Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.GETTER, owner, name, type.returnType()));
case REF_putField:
return Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.SETTER, owner, name, type.parameterType(0)));
case REF_getStatic:
return Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.STATIC_GETTER, owner, name, type.returnType()));
case REF_putStatic:
return Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.STATIC_SETTER, owner, name, type.parameterType(0)));
case REF_invokeVirtual:
return Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.VIRTUAL, owner, name, type));
case REF_invokeStatic:
return isInterface ?
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, owner, name, type)) :
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, owner, name, type));
case REF_invokeSpecial:
return isInterface ?
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_SPECIAL, owner, name, type)) :
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.SPECIAL, owner, name, type));
case REF_invokeInterface:
return Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, owner, name, type));
case REF_newInvokeSpecial:
return Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.CONSTRUCTOR, owner, name, type));
default:
return Optional.empty();
}
return switch (info.getReferenceKind()) {
case REF_getField -> Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.GETTER, owner, name, type.returnType()));
case REF_putField -> Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.SETTER, owner, name, type.parameterType(0)));
case REF_getStatic -> Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.STATIC_GETTER, owner, name, type.returnType()));
case REF_putStatic -> Optional.of(MethodHandleDesc.ofField(DirectMethodHandleDesc.Kind.STATIC_SETTER, owner, name, type.parameterType(0)));
case REF_invokeVirtual -> Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.VIRTUAL, owner, name, type));
case REF_invokeStatic -> isInterface ?
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_STATIC, owner, name, type)) :
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.STATIC, owner, name, type));
case REF_invokeSpecial -> isInterface ?
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_SPECIAL, owner, name, type)) :
Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.SPECIAL, owner, name, type));
case REF_invokeInterface -> Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.INTERFACE_VIRTUAL, owner, name, type));
case REF_newInvokeSpecial -> Optional.of(MethodHandleDesc.ofMethod(DirectMethodHandleDesc.Kind.CONSTRUCTOR, owner, name, type));
default -> Optional.empty();
};
}
/**

View File

@ -109,39 +109,39 @@ abstract class MethodHandleImpl {
// final fields.
static String opName(ArrayAccess a) {
switch (a) {
case GET: return "getElement";
case SET: return "setElement";
case LENGTH: return "length";
}
throw unmatchedArrayAccess(a);
return switch (a) {
case GET -> "getElement";
case SET -> "setElement";
case LENGTH -> "length";
default -> throw unmatchedArrayAccess(a);
};
}
static MethodHandle objectAccessor(ArrayAccess a) {
switch (a) {
case GET: return ArrayAccessor.OBJECT_ARRAY_GETTER;
case SET: return ArrayAccessor.OBJECT_ARRAY_SETTER;
case LENGTH: return ArrayAccessor.OBJECT_ARRAY_LENGTH;
}
throw unmatchedArrayAccess(a);
return switch (a) {
case GET -> ArrayAccessor.OBJECT_ARRAY_GETTER;
case SET -> ArrayAccessor.OBJECT_ARRAY_SETTER;
case LENGTH -> ArrayAccessor.OBJECT_ARRAY_LENGTH;
default -> throw unmatchedArrayAccess(a);
};
}
static int cacheIndex(ArrayAccess a) {
switch (a) {
case GET: return ArrayAccessor.GETTER_INDEX;
case SET: return ArrayAccessor.SETTER_INDEX;
case LENGTH: return ArrayAccessor.LENGTH_INDEX;
}
throw unmatchedArrayAccess(a);
return switch (a) {
case GET -> ArrayAccessor.GETTER_INDEX;
case SET -> ArrayAccessor.SETTER_INDEX;
case LENGTH -> ArrayAccessor.LENGTH_INDEX;
default -> throw unmatchedArrayAccess(a);
};
}
static Intrinsic intrinsic(ArrayAccess a) {
switch (a) {
case GET: return Intrinsic.ARRAY_LOAD;
case SET: return Intrinsic.ARRAY_STORE;
case LENGTH: return Intrinsic.ARRAY_LENGTH;
}
throw unmatchedArrayAccess(a);
return switch (a) {
case GET -> Intrinsic.ARRAY_LOAD;
case SET -> Intrinsic.ARRAY_STORE;
case LENGTH -> Intrinsic.ARRAY_LENGTH;
default -> throw unmatchedArrayAccess(a);
};
}
}
@ -213,21 +213,21 @@ abstract class MethodHandleImpl {
arrayArgClass = Object[].class;
elemClass = Object.class;
}
switch (access) {
case GET: return MethodType.methodType(elemClass, arrayArgClass, int.class);
case SET: return MethodType.methodType(void.class, arrayArgClass, int.class, elemClass);
case LENGTH: return MethodType.methodType(int.class, arrayArgClass);
}
throw unmatchedArrayAccess(access);
return switch (access) {
case GET -> MethodType.methodType(elemClass, arrayArgClass, int.class);
case SET -> MethodType.methodType(void.class, arrayArgClass, int.class, elemClass);
case LENGTH -> MethodType.methodType(int.class, arrayArgClass);
default -> throw unmatchedArrayAccess(access);
};
}
static MethodType correctType(Class<?> arrayClass, ArrayAccess access) {
Class<?> elemClass = arrayClass.getComponentType();
switch (access) {
case GET: return MethodType.methodType(elemClass, arrayClass, int.class);
case SET: return MethodType.methodType(void.class, arrayClass, int.class, elemClass);
case LENGTH: return MethodType.methodType(int.class, arrayClass);
}
throw unmatchedArrayAccess(access);
return switch (access) {
case GET -> MethodType.methodType(elemClass, arrayClass, int.class);
case SET -> MethodType.methodType(void.class, arrayClass, int.class, elemClass);
case LENGTH -> MethodType.methodType(int.class, arrayClass);
default -> throw unmatchedArrayAccess(access);
};
}
static MethodHandle getAccessor(Class<?> arrayClass, ArrayAccess access) {
String name = name(arrayClass, access);
@ -980,13 +980,12 @@ abstract class MethodHandleImpl {
static MethodHandle[] FAKE_METHOD_HANDLE_INVOKE = new MethodHandle[2];
static MethodHandle fakeMethodHandleInvoke(MemberName method) {
int idx;
assert(method.isMethodHandleInvoke());
switch (method.getName()) {
case "invoke": idx = 0; break;
case "invokeExact": idx = 1; break;
default: throw new InternalError(method.getName());
}
int idx = switch (method.getName()) {
case "invoke" -> 0;
case "invokeExact" -> 1;
default -> throw new InternalError(method.getName());
};
MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE[idx];
if (mh != null) return mh;
MethodType type = MethodType.methodType(Object.class, UnsupportedOperationException.class,
@ -1395,32 +1394,24 @@ abstract class MethodHandleImpl {
private static NamedFunction createFunction(byte func) {
try {
switch (func) {
case NF_checkSpreadArgument:
return new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
case NF_guardWithCatch:
return new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
MethodHandle.class, Object[].class));
case NF_tryFinally:
return new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class));
case NF_loop:
return new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class));
case NF_throwException:
return new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("throwException", Throwable.class));
case NF_profileBoolean:
return new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("profileBoolean", boolean.class, int[].class));
case NF_tableSwitch:
return new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("tableSwitch", int.class, MethodHandle.class, CasesHolder.class, Object[].class));
default:
throw new InternalError("Undefined function: " + func);
}
return switch (func) {
case NF_checkSpreadArgument -> new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
case NF_guardWithCatch -> new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("guardWithCatch", MethodHandle.class, Class.class,
MethodHandle.class, Object[].class));
case NF_tryFinally -> new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("tryFinally", MethodHandle.class, MethodHandle.class, Object[].class));
case NF_loop -> new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("loop", BasicType[].class, LoopClauses.class, Object[].class));
case NF_throwException -> new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("throwException", Throwable.class));
case NF_profileBoolean -> new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("profileBoolean", boolean.class, int[].class));
case NF_tableSwitch -> new NamedFunction(MethodHandleImpl.class
.getDeclaredMethod("tableSwitch", int.class, MethodHandle.class, CasesHolder.class, Object[].class));
default -> throw new InternalError("Undefined function: " + func);
};
} catch (ReflectiveOperationException ex) {
throw newInternalError(ex);
}

View File

@ -206,18 +206,18 @@ class MethodHandleNatives {
}
static String refKindName(byte refKind) {
assert(refKindIsValid(refKind));
switch (refKind) {
case REF_getField: return "getField";
case REF_getStatic: return "getStatic";
case REF_putField: return "putField";
case REF_putStatic: return "putStatic";
case REF_invokeVirtual: return "invokeVirtual";
case REF_invokeStatic: return "invokeStatic";
case REF_invokeSpecial: return "invokeSpecial";
case REF_newInvokeSpecial: return "newInvokeSpecial";
case REF_invokeInterface: return "invokeInterface";
default: return "REF_???";
}
return switch (refKind) {
case REF_getField -> "getField";
case REF_getStatic -> "getStatic";
case REF_putField -> "putField";
case REF_putStatic -> "putStatic";
case REF_invokeVirtual -> "invokeVirtual";
case REF_invokeStatic -> "invokeStatic";
case REF_invokeSpecial -> "invokeSpecial";
case REF_newInvokeSpecial -> "newInvokeSpecial";
case REF_invokeInterface -> "invokeInterface";
default -> "REF_???";
};
}
private static native int getNamedCon(int which, Object[] name);

View File

@ -274,32 +274,26 @@ public class MethodHandleProxies {
}
private static boolean isObjectMethod(Method m) {
switch (m.getName()) {
case "toString":
return (m.getReturnType() == String.class
&& m.getParameterCount() == 0);
case "hashCode":
return (m.getReturnType() == int.class
&& m.getParameterCount() == 0);
case "equals":
return (m.getReturnType() == boolean.class
&& m.getParameterCount() == 1
&& m.getParameterTypes()[0] == Object.class);
}
return false;
return switch (m.getName()) {
case "toString" -> m.getReturnType() == String.class
&& m.getParameterCount() == 0;
case "hashCode" -> m.getReturnType() == int.class
&& m.getParameterCount() == 0;
case "equals" -> m.getReturnType() == boolean.class
&& m.getParameterCount() == 1
&& m.getParameterTypes()[0] == Object.class;
default -> false;
};
}
private static Object callObjectMethod(Object self, Method m, Object[] args) {
assert(isObjectMethod(m)) : m;
switch (m.getName()) {
case "toString":
return self.getClass().getName() + "@" + Integer.toHexString(self.hashCode());
case "hashCode":
return System.identityHashCode(self);
case "equals":
return (self == args[0]);
}
return null;
return switch (m.getName()) {
case "toString" -> self.getClass().getName() + "@" + Integer.toHexString(self.hashCode());
case "hashCode" -> System.identityHashCode(self);
case "equals" -> (self == args[0]);
default -> null;
};
}
private static Method[] getSingleNameMethods(Class<?> intfc) {

View File

@ -5175,13 +5175,13 @@ assert((int)twice.invokeExact(21) == 42);
Wrapper w = Wrapper.forPrimitiveType(ptype);
// perform unboxing and/or primitive conversion
value = w.convert(value, ptype);
switch (w) {
case INT: return result.bindArgumentI(pos, (int)value);
case LONG: return result.bindArgumentJ(pos, (long)value);
case FLOAT: return result.bindArgumentF(pos, (float)value);
case DOUBLE: return result.bindArgumentD(pos, (double)value);
default: return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
}
return switch (w) {
case INT -> result.bindArgumentI(pos, (int) value);
case LONG -> result.bindArgumentJ(pos, (long) value);
case FLOAT -> result.bindArgumentF(pos, (float) value);
case DOUBLE -> result.bindArgumentD(pos, (double) value);
default -> result.bindArgumentI(pos, ValueConversions.widenSubword(value));
};
}
private static Class<?>[] insertArgumentsChecks(MethodHandle target, int insCount, int pos) throws RuntimeException {

View File

@ -2282,15 +2282,11 @@ public abstract class VarHandle implements Constable {
}
ConstantDesc[] toBSMArgs(ClassDesc declaringClass, ClassDesc varType) {
switch (this) {
case FIELD:
case STATIC_FIELD:
return new ConstantDesc[] {declaringClass, varType };
case ARRAY:
return new ConstantDesc[] {declaringClass };
default:
throw new InternalError("Cannot reach here");
}
return switch (this) {
case FIELD, STATIC_FIELD -> new ConstantDesc[]{declaringClass, varType};
case ARRAY -> new ConstantDesc[]{declaringClass};
default -> throw new InternalError("Cannot reach here");
};
}
}
@ -2385,20 +2381,16 @@ public abstract class VarHandle implements Constable {
@Override
public VarHandle resolveConstantDesc(MethodHandles.Lookup lookup)
throws ReflectiveOperationException {
switch (kind) {
case FIELD:
return lookup.findVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup),
constantName(),
(Class<?>) varType.resolveConstantDesc(lookup));
case STATIC_FIELD:
return lookup.findStaticVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup),
constantName(),
(Class<?>) varType.resolveConstantDesc(lookup));
case ARRAY:
return MethodHandles.arrayElementVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup));
default:
throw new InternalError("Cannot reach here");
}
return switch (kind) {
case FIELD -> lookup.findVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup),
constantName(),
(Class<?>) varType.resolveConstantDesc(lookup));
case STATIC_FIELD -> lookup.findStaticVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup),
constantName(),
(Class<?>) varType.resolveConstantDesc(lookup));
case ARRAY -> MethodHandles.arrayElementVarHandle((Class<?>) declaringClass.resolveConstantDesc(lookup));
default -> throw new InternalError("Cannot reach here");
};
}
/**
@ -2411,17 +2403,13 @@ public abstract class VarHandle implements Constable {
*/
@Override
public String toString() {
switch (kind) {
case FIELD:
case STATIC_FIELD:
return String.format("VarHandleDesc[%s%s.%s:%s]",
(kind == Kind.STATIC_FIELD) ? "static " : "",
declaringClass.displayName(), constantName(), varType.displayName());
case ARRAY:
return String.format("VarHandleDesc[%s[]]", declaringClass.displayName());
default:
throw new InternalError("Cannot reach here");
}
return switch (kind) {
case FIELD, STATIC_FIELD -> String.format("VarHandleDesc[%s%s.%s:%s]",
(kind == Kind.STATIC_FIELD) ? "static " : "",
declaringClass.displayName(), constantName(), varType.displayName());
case ARRAY -> String.format("VarHandleDesc[%s[]]", declaringClass.displayName());
default -> throw new InternalError("Cannot reach here");
};
}
}

View File

@ -339,28 +339,27 @@ public class ObjectMethods {
throw new IllegalArgumentException(type.toString());
}
List<MethodHandle> getterList = List.of(getters);
MethodHandle handle;
switch (methodName) {
case "equals":
MethodHandle handle = switch (methodName) {
case "equals" -> {
if (methodType != null && !methodType.equals(MethodType.methodType(boolean.class, recordClass, Object.class)))
throw new IllegalArgumentException("Bad method type: " + methodType);
handle = makeEquals(recordClass, getterList);
return methodType != null ? new ConstantCallSite(handle) : handle;
case "hashCode":
yield makeEquals(recordClass, getterList);
}
case "hashCode" -> {
if (methodType != null && !methodType.equals(MethodType.methodType(int.class, recordClass)))
throw new IllegalArgumentException("Bad method type: " + methodType);
handle = makeHashCode(recordClass, getterList);
return methodType != null ? new ConstantCallSite(handle) : handle;
case "toString":
yield makeHashCode(recordClass, getterList);
}
case "toString" -> {
if (methodType != null && !methodType.equals(MethodType.methodType(String.class, recordClass)))
throw new IllegalArgumentException("Bad method type: " + methodType);
List<String> nameList = "".equals(names) ? List.of() : List.of(names.split(";"));
if (nameList.size() != getterList.size())
throw new IllegalArgumentException("Name list and accessor list do not match");
handle = makeToString(recordClass, getterList, nameList);
return methodType != null ? new ConstantCallSite(handle) : handle;
default:
throw new IllegalArgumentException(methodName);
}
yield makeToString(recordClass, getterList, nameList);
}
default -> throw new IllegalArgumentException(methodName);
};
return methodType != null ? new ConstantCallSite(handle) : handle;
}
}