Skip to content

Commit

Permalink
review
Browse files Browse the repository at this point in the history
  • Loading branch information
andreaTP committed Oct 1, 2024
1 parent 47a5a15 commit 55167d5
Show file tree
Hide file tree
Showing 15 changed files with 161 additions and 121 deletions.
6 changes: 0 additions & 6 deletions aot-tests/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- Enable better debugging -->
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-util</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
1 change: 0 additions & 1 deletion aot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@
<dependency>
<groupId>org.ow2.asm</groupId>
<artifactId>asm-util</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.approvaltests</groupId>
Expand Down
26 changes: 10 additions & 16 deletions aot/src/main/java/com/dylibso/chicory/aot/AotEmitters.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import static com.dylibso.chicory.aot.AotMethods.CHECK_INTERRUPTION;
import static com.dylibso.chicory.aot.AotMethods.INSTANCE_READ_GLOBAL;
import static com.dylibso.chicory.aot.AotMethods.INSTANCE_SET_ELEMENT;
import static com.dylibso.chicory.aot.AotMethods.INSTANCE_WRITE_GLOBAL;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_COPY;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_DROP;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_FILL;
Expand Down Expand Up @@ -31,13 +30,14 @@
import static com.dylibso.chicory.aot.AotMethods.TABLE_SET;
import static com.dylibso.chicory.aot.AotMethods.TABLE_SIZE;
import static com.dylibso.chicory.aot.AotMethods.THROW_OUT_OF_BOUNDS_MEMORY_ACCESS;
import static com.dylibso.chicory.aot.AotMethods.WRITE_GLOBAL;
import static com.dylibso.chicory.aot.AotUtil.StackSize;
import static com.dylibso.chicory.aot.AotUtil.callIndirectMethodName;
import static com.dylibso.chicory.aot.AotUtil.callIndirectMethodType;
import static com.dylibso.chicory.aot.AotUtil.convertFromLong;
import static com.dylibso.chicory.aot.AotUtil.convertToLong;
import static com.dylibso.chicory.aot.AotUtil.emitInvokeStatic;
import static com.dylibso.chicory.aot.AotUtil.emitInvokeVirtual;
import static com.dylibso.chicory.aot.AotUtil.emitJvmToLong;
import static com.dylibso.chicory.aot.AotUtil.emitLongToJvm;
import static com.dylibso.chicory.aot.AotUtil.emitPop;
import static com.dylibso.chicory.aot.AotUtil.jvmType;
import static com.dylibso.chicory.aot.AotUtil.loadTypeOpcode;
Expand Down Expand Up @@ -218,25 +218,19 @@ public static void GLOBAL_GET(AotContext ctx, AnnotatedInstruction ins, MethodVi
asm.visitLdcInsn(globalIndex);
emitInvokeVirtual(asm, INSTANCE_READ_GLOBAL);

Method unboxer = convertFromLong(ctx.globalTypes().get(globalIndex));
emitInvokeStatic(asm, unboxer);
var globalType = ctx.globalTypes().get(globalIndex);
emitLongToJvm(asm, ctx.globalTypes().get(globalIndex));

ctx.pushStackSize(stackSize(unboxer.getReturnType()));
ctx.pushStackSize(stackSize(globalType));
}

public static void GLOBAL_SET(AotContext ctx, AnnotatedInstruction ins, MethodVisitor asm) {
int globalIndex = (int) ins.operand(0);

emitInvokeStatic(asm, convertToLong(ctx.globalTypes().get(globalIndex)));
asm.visitVarInsn(Opcodes.ALOAD, ctx.instanceSlot());
// from long | integer on top of the stack
// to integer | long
asm.visitInsn(Opcodes.DUP_X2);
asm.visitInsn(Opcodes.POP);
emitJvmToLong(asm, ctx.globalTypes().get(globalIndex));
asm.visitLdcInsn(globalIndex);
asm.visitInsn(Opcodes.DUP_X2);
asm.visitInsn(Opcodes.POP);
emitInvokeVirtual(asm, INSTANCE_WRITE_GLOBAL);
asm.visitVarInsn(Opcodes.ALOAD, ctx.instanceSlot());
emitInvokeStatic(asm, WRITE_GLOBAL);
}

public static void TABLE_GET(AotContext ctx, AnnotatedInstruction ins, MethodVisitor asm) {
Expand Down Expand Up @@ -777,7 +771,7 @@ private static void emitUnboxResult(MethodVisitor asm, AotContext ctx, List<Valu
asm.visitVarInsn(Opcodes.ALOAD, ctx.tempSlot());
asm.visitLdcInsn(i);
asm.visitInsn(Opcodes.LALOAD);
emitInvokeStatic(asm, convertFromLong(type));
emitLongToJvm(asm, type);
}
}
}
16 changes: 8 additions & 8 deletions aot/src/main/java/com/dylibso/chicory/aot/AotMachine.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@
import static com.dylibso.chicory.aot.AotMethods.THROW_TRAP_EXCEPTION;
import static com.dylibso.chicory.aot.AotUtil.callIndirectMethodName;
import static com.dylibso.chicory.aot.AotUtil.callIndirectMethodType;
import static com.dylibso.chicory.aot.AotUtil.convertFromLong;
import static com.dylibso.chicory.aot.AotUtil.convertFromLongHandle;
import static com.dylibso.chicory.aot.AotUtil.convertToLong;
import static com.dylibso.chicory.aot.AotUtil.convertToLongHandle;
import static com.dylibso.chicory.aot.AotUtil.defaultValue;
import static com.dylibso.chicory.aot.AotUtil.emitInvokeStatic;
import static com.dylibso.chicory.aot.AotUtil.emitInvokeVirtual;
import static com.dylibso.chicory.aot.AotUtil.emitJvmToLong;
import static com.dylibso.chicory.aot.AotUtil.emitLongToJvm;
import static com.dylibso.chicory.aot.AotUtil.emitPop;
import static com.dylibso.chicory.aot.AotUtil.jvmReturnType;
import static com.dylibso.chicory.aot.AotUtil.jvmToLongHandle;
import static com.dylibso.chicory.aot.AotUtil.jvmTypes;
import static com.dylibso.chicory.aot.AotUtil.loadTypeOpcode;
import static com.dylibso.chicory.aot.AotUtil.localType;
import static com.dylibso.chicory.aot.AotUtil.longToJvmHandle;
import static com.dylibso.chicory.aot.AotUtil.methodNameFor;
import static com.dylibso.chicory.aot.AotUtil.methodTypeFor;
import static com.dylibso.chicory.aot.AotUtil.slotCount;
Expand Down Expand Up @@ -526,7 +526,7 @@ private static MethodHandle adaptSignature(FunctionType type, MethodHandle handl
var argTypes = type.params();
var argHandlers = new MethodHandle[type.params().size()];
for (int i = 0; i < argHandlers.length; i++) {
argHandlers[i] = convertFromLongHandle(argTypes.get(i));
argHandlers[i] = longToJvmHandle(argTypes.get(i));
}
MethodHandle result = filterArguments(handle, 0, argHandlers);
result = result.asSpreader(long[].class, argTypes.size());
Expand All @@ -537,7 +537,7 @@ private static MethodHandle adaptSignature(FunctionType type, MethodHandle handl
if (type.returns().size() > 1) {
return result;
}
result = filterReturnValue(result, convertToLongHandle(type.returns().get(0)));
result = filterReturnValue(result, jvmToLongHandle(type.returns().get(0)));
return filterReturnValue(result, LongArrayWrapper.HANDLE);
}

Expand Down Expand Up @@ -598,7 +598,7 @@ private static void emitBoxArguments(MethodVisitor asm, List<ValueType> types) {
asm.visitLdcInsn(i);
ValueType valueType = types.get(i);
asm.visitVarInsn(loadTypeOpcode(valueType), slot);
emitInvokeStatic(asm, convertToLong(valueType));
emitJvmToLong(asm, valueType);
asm.visitInsn(Opcodes.LASTORE);
slot += slotCount(valueType);
}
Expand All @@ -614,7 +614,7 @@ private static void emitUnboxResult(FunctionType type, MethodVisitor asm) {
// unbox the result from long[0]
asm.visitLdcInsn(0);
asm.visitInsn(Opcodes.LALOAD);
emitInvokeStatic(asm, convertFromLong(type.returns().get(0)));
emitLongToJvm(asm, type.returns().get(0));
asm.visitInsn(returnTypeOpcode(type));
}
}
Expand Down
11 changes: 9 additions & 2 deletions aot/src/main/java/com/dylibso/chicory/aot/AotMethods.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public final class AotMethods {
static final Method CALL_INDIRECT;
static final Method INSTANCE_CALL_HOST_FUNCTION;
static final Method INSTANCE_READ_GLOBAL;
static final Method INSTANCE_WRITE_GLOBAL;
static final Method WRITE_GLOBAL;
static final Method INSTANCE_SET_ELEMENT;
static final Method MEMORY_COPY;
static final Method MEMORY_FILL;
Expand Down Expand Up @@ -67,7 +67,9 @@ public final class AotMethods {
INSTANCE_CALL_HOST_FUNCTION =
Instance.class.getMethod("callHostFunction", int.class, long[].class);
INSTANCE_READ_GLOBAL = Instance.class.getMethod("readGlobal", int.class);
INSTANCE_WRITE_GLOBAL = Instance.class.getMethod("writeGlobal", int.class, long.class);
WRITE_GLOBAL =
AotMethods.class.getMethod(
"writeGlobal", long.class, int.class, Instance.class);
INSTANCE_SET_ELEMENT = Instance.class.getMethod("setElement", int.class, Element.class);
MEMORY_COPY =
AotMethods.class.getMethod(
Expand Down Expand Up @@ -340,4 +342,9 @@ public static void checkInterruption() {
throw new ChicoryException("Thread interrupted");
}
}

@UsedByGeneratedCode
public static void writeGlobal(long value, int index, Instance instance) {
instance.writeGlobal(index, value);
}
}
152 changes: 100 additions & 52 deletions aot/src/main/java/com/dylibso/chicory/aot/AotUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,35 +28,46 @@ public enum StackSize {
TWO
}

private static final Method LONG_2_I32;
private static final Method LONG_2_I64;
private static final Method LONG_2_F32;
private static final Method LONG_2_F64;
private static final Method LONG_2_EXTREF;
private static final Method LONG_2_FUNCREF;
private static final Method I32_2_LONG;
private static final Method I64_2_LONG;
private static final Method F32_2_LONG;
private static final Method F64_2_LONG;
private static final Method EXTREF_2_LONG;
private static final Method FUNCREF_2_LONG;
private static final Method LONG_TO_I32;
private static final Method LONG_TO_I64;
private static final Method LONG_TO_F32;
private static final Method LONG_TO_F64;
private static final Method I32_TO_LONG;
private static final Method I64_TO_LONG;
private static final Method F32_TO_LONG;
private static final Method F64_TO_LONG;
private static final MethodHandle LONG_TO_I32_MH;
private static final MethodHandle LONG_TO_I64_MH;
private static final MethodHandle LONG_TO_F32_MH;
private static final MethodHandle LONG_TO_F64_MH;
private static final MethodHandle I32_TO_LONG_MH;
private static final MethodHandle I64_TO_LONG_MH;
private static final MethodHandle F32_TO_LONG_MH;
private static final MethodHandle F64_TO_LONG_MH;

static {
try {
I32_2_LONG = ValueConversions.class.getMethod("asLong", int.class);
I64_2_LONG = ValueConversions.class.getMethod("asLong", long.class);
F32_2_LONG = ValueConversions.class.getMethod("asLong", float.class);
F64_2_LONG = ValueConversions.class.getMethod("asLong", double.class);
EXTREF_2_LONG = ValueConversions.class.getMethod("asLong", int.class);
FUNCREF_2_LONG = ValueConversions.class.getMethod("asLong", int.class);
LONG_2_I32 = ValueConversions.class.getMethod("toInt", long.class);
LONG_2_I64 = ValueConversions.class.getMethod("toLong", long.class);
LONG_2_F32 = ValueConversions.class.getMethod("toFloat", long.class);
LONG_2_F64 = ValueConversions.class.getMethod("toDouble", long.class);
LONG_2_EXTREF = ValueConversions.class.getMethod("toInt", long.class);
LONG_2_FUNCREF = ValueConversions.class.getMethod("toInt", long.class);
LONG_TO_I32 = ValueConversions.class.getMethod("longToI32", long.class);
LONG_TO_I64 = ValueConversions.class.getMethod("longToI64", long.class);
LONG_TO_F32 = ValueConversions.class.getMethod("longToF32", long.class);
LONG_TO_F64 = ValueConversions.class.getMethod("longToF64", long.class);
I32_TO_LONG = ValueConversions.class.getMethod("i32ToLong", int.class);
I64_TO_LONG = ValueConversions.class.getMethod("i64ToLong", long.class);
F32_TO_LONG = ValueConversions.class.getMethod("f32ToLong", float.class);
F64_TO_LONG = ValueConversions.class.getMethod("f64ToLong", double.class);

LONG_TO_I32_MH = publicLookup().unreflect(LONG_TO_I32);
LONG_TO_I64_MH = publicLookup().unreflect(LONG_TO_I64);
LONG_TO_F32_MH = publicLookup().unreflect(LONG_TO_F32);
LONG_TO_F64_MH = publicLookup().unreflect(LONG_TO_F64);
I32_TO_LONG_MH = publicLookup().unreflect(I32_TO_LONG);
I64_TO_LONG_MH = publicLookup().unreflect(I64_TO_LONG);
F32_TO_LONG_MH = publicLookup().unreflect(F32_TO_LONG);
F64_TO_LONG_MH = publicLookup().unreflect(F64_TO_LONG);
} catch (NoSuchMethodException e) {
throw new AssertionError(e);
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}

Expand Down Expand Up @@ -119,57 +130,79 @@ public static ValueType localType(FunctionType type, FunctionBody body, int loca
}
}

public static Method convertFromLong(ValueType type) {
public static void emitLongToJvm(MethodVisitor asm, ValueType type) {
switch (type) {
case I32:
return LONG_2_I32;
case ExternRef:
case FuncRef:
asm.visitInsn(Opcodes.L2I);
return;
case I64:
return LONG_2_I64;
return;
case F32:
return LONG_2_F32;
emitInvokeStatic(asm, LONG_TO_F32);
return;
case F64:
return LONG_2_F64;
case ExternRef:
return LONG_2_EXTREF;
case FuncRef:
return LONG_2_FUNCREF;
emitInvokeStatic(asm, LONG_TO_F64);
return;
default:
throw new IllegalArgumentException("Unsupported ValueType: " + type.name());
}
}

public static Method convertToLong(ValueType type) {
public static void emitJvmToLong(MethodVisitor asm, ValueType type) {
switch (type) {
case I32:
return I32_2_LONG;
case ExternRef:
case FuncRef:
asm.visitInsn(Opcodes.I2L);
return;
case I64:
return I64_2_LONG;
return;
case F32:
return F32_2_LONG;
emitInvokeStatic(asm, F32_TO_LONG);
return;
case F64:
return F64_2_LONG;
case ExternRef:
return EXTREF_2_LONG;
case FuncRef:
return FUNCREF_2_LONG;
emitInvokeStatic(asm, F64_TO_LONG);
return;
default:
throw new IllegalArgumentException("Unsupported ValueType: " + type.name());
}
}

public static MethodHandle convertFromLongHandle(ValueType type) {
try {
return publicLookup().unreflect(convertFromLong(type));
} catch (IllegalAccessException e) {
throw new AssertionError(e);
public static MethodHandle longToJvmHandle(ValueType type) {
switch (type) {
case I32:
case ExternRef:
case FuncRef:
return LONG_TO_I32_MH;
case I64:
// filterArguments:
// Null arguments in the array are treated as identity functions
return null;
case F32:
return LONG_TO_F32_MH;
case F64:
return LONG_TO_F64_MH;
default:
throw new IllegalArgumentException("Unsupported ValueType: " + type.name());
}
}

public static MethodHandle convertToLongHandle(ValueType type) {
try {
return publicLookup().unreflect(convertToLong(type));
} catch (IllegalAccessException e) {
throw new AssertionError(e);
public static MethodHandle jvmToLongHandle(ValueType type) {
switch (type) {
case I32:
case ExternRef:
case FuncRef:
return I32_TO_LONG_MH;
case I64:
return I64_TO_LONG_MH;
case F32:
return F32_TO_LONG_MH;
case F64:
return F64_TO_LONG_MH;
default:
throw new IllegalArgumentException("Unsupported ValueType: " + type.name());
}
}

Expand Down Expand Up @@ -238,6 +271,21 @@ public static StackSize stackSize(Class<?> clazz) {
throw new IllegalArgumentException("Unsupported JVM type: " + clazz);
}

public static StackSize stackSize(ValueType type) {
switch (type) {
case I32:
case F32:
case ExternRef:
case FuncRef:
return StackSize.ONE;
case I64:
case F64:
return StackSize.TWO;
default:
throw new IllegalArgumentException("Unsupported type: " + type);
}
}

public static int slotCount(ValueType type) {
switch (type) {
case I32:
Expand Down
Loading

0 comments on commit 55167d5

Please sign in to comment.