8297733: Refactor Cast binding to enum
Reviewed-by: mcimadamore
This commit is contained in:
parent
19d849884b
commit
a38c63da56
@ -25,6 +25,7 @@
|
|||||||
package jdk.internal.foreign.abi;
|
package jdk.internal.foreign.abi;
|
||||||
|
|
||||||
import jdk.internal.foreign.NativeMemorySegmentImpl;
|
import jdk.internal.foreign.NativeMemorySegmentImpl;
|
||||||
|
import jdk.internal.foreign.Utils;
|
||||||
|
|
||||||
import java.lang.foreign.Arena;
|
import java.lang.foreign.Arena;
|
||||||
import java.lang.foreign.MemoryLayout;
|
import java.lang.foreign.MemoryLayout;
|
||||||
@ -367,7 +368,28 @@ public interface Binding {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static Binding cast(Class<?> fromType, Class<?> toType) {
|
static Binding cast(Class<?> fromType, Class<?> toType) {
|
||||||
return new Cast(fromType, toType);
|
if (fromType == int.class) {
|
||||||
|
if (toType == boolean.class) {
|
||||||
|
return Cast.INT_TO_BOOLEAN;
|
||||||
|
} else if (toType == byte.class) {
|
||||||
|
return Cast.INT_TO_BYTE;
|
||||||
|
} else if (toType == short.class) {
|
||||||
|
return Cast.INT_TO_SHORT;
|
||||||
|
} else if (toType == char.class) {
|
||||||
|
return Cast.INT_TO_CHAR;
|
||||||
|
}
|
||||||
|
} else if (toType == int.class) {
|
||||||
|
if (fromType == boolean.class) {
|
||||||
|
return Cast.BOOLEAN_TO_INT;
|
||||||
|
} else if (fromType == byte.class) {
|
||||||
|
return Cast.BYTE_TO_INT;
|
||||||
|
} else if (fromType == short.class) {
|
||||||
|
return Cast.SHORT_TO_INT;
|
||||||
|
} else if (fromType == char.class) {
|
||||||
|
return Cast.CHAR_TO_INT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unknown conversion: " + fromType + " -> " + toType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -713,7 +735,40 @@ public interface Binding {
|
|||||||
* value onto the stack.
|
* value onto the stack.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
record Cast(Class<?> fromType, Class<?> toType) implements Binding {
|
enum Cast implements Binding {
|
||||||
|
INT_TO_BOOLEAN(int.class, boolean.class) {
|
||||||
|
@Override
|
||||||
|
public void interpret(Deque<Object> stack, BindingInterpreter.StoreFunc storeFunc,
|
||||||
|
BindingInterpreter.LoadFunc loadFunc, Context context) {
|
||||||
|
// implement least significant byte non-zero test
|
||||||
|
int arg = (int) stack.pop();
|
||||||
|
boolean result = Utils.byteToBoolean((byte) arg);
|
||||||
|
stack.push(result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
INT_TO_BYTE(int.class, byte.class),
|
||||||
|
INT_TO_CHAR(int.class, char.class),
|
||||||
|
INT_TO_SHORT(int.class, short.class),
|
||||||
|
BOOLEAN_TO_INT(boolean.class, int.class),
|
||||||
|
BYTE_TO_INT(byte.class, int.class),
|
||||||
|
CHAR_TO_INT(char.class, int.class),
|
||||||
|
SHORT_TO_INT(short.class, int.class);
|
||||||
|
|
||||||
|
private final Class<?> fromType;
|
||||||
|
private final Class<?> toType;
|
||||||
|
|
||||||
|
Cast(Class<?> fromType, Class<?> toType) {
|
||||||
|
this.fromType = fromType;
|
||||||
|
this.toType = toType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> fromType() {
|
||||||
|
return fromType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Class<?> toType() {
|
||||||
|
return toType;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Tag tag() {
|
public Tag tag() {
|
||||||
|
@ -676,10 +676,9 @@ public class BindingSpecializer {
|
|||||||
Class<?> fromType = cast.fromType();
|
Class<?> fromType = cast.fromType();
|
||||||
Class<?> toType = cast.toType();
|
Class<?> toType = cast.toType();
|
||||||
|
|
||||||
if (fromType == int.class) {
|
popType(fromType);
|
||||||
popType(int.class);
|
switch (cast) {
|
||||||
|
case INT_TO_BOOLEAN -> {
|
||||||
if (toType == boolean.class) {
|
|
||||||
// implement least significant byte non-zero test
|
// implement least significant byte non-zero test
|
||||||
|
|
||||||
// select first byte
|
// select first byte
|
||||||
@ -688,28 +687,16 @@ public class BindingSpecializer {
|
|||||||
|
|
||||||
// convert to boolean
|
// convert to boolean
|
||||||
emitInvokeStatic(Utils.class, "byteToBoolean", "(B)Z");
|
emitInvokeStatic(Utils.class, "byteToBoolean", "(B)Z");
|
||||||
} else if (toType == byte.class) {
|
|
||||||
mv.visitInsn(I2B);
|
|
||||||
} else if (toType == short.class) {
|
|
||||||
mv.visitInsn(I2S);
|
|
||||||
} else {
|
|
||||||
assert toType == char.class;
|
|
||||||
mv.visitInsn(I2C);
|
|
||||||
}
|
}
|
||||||
|
case INT_TO_BYTE -> mv.visitInsn(I2B);
|
||||||
pushType(toType);
|
case INT_TO_CHAR -> mv.visitInsn(I2C);
|
||||||
} else {
|
case INT_TO_SHORT -> mv.visitInsn(I2S);
|
||||||
popType(fromType);
|
case BOOLEAN_TO_INT, BYTE_TO_INT, CHAR_TO_INT, SHORT_TO_INT -> {
|
||||||
|
// no-op in bytecode
|
||||||
assert fromType == boolean.class
|
}
|
||||||
|| fromType == byte.class
|
default -> throw new IllegalStateException("Unknown cast: " + cast);
|
||||||
|| fromType == short.class
|
|
||||||
|| fromType == char.class;
|
|
||||||
// no-op in bytecode
|
|
||||||
|
|
||||||
assert toType == int.class;
|
|
||||||
pushType(int.class);
|
|
||||||
}
|
}
|
||||||
|
pushType(toType);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void emitUnboxAddress() {
|
private void emitUnboxAddress() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user