Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move static code used at runtime by aot compiled modules to a separate package #552

Merged
merged 1 commit into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions aot-runtime/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.dylibso.chicory</groupId>
<artifactId>chicory</artifactId>
<version>999-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>aot-runtime</artifactId>
<packaging>jar</packaging>

<name>Chicory - AOT runtime</name>
<description>Experimental AOT runtime library for Chicory</description>

<dependencies>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>runtime</artifactId>
</dependency>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>wasm</artifactId>
</dependency>
</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
package com.dylibso.chicory.aot.runtime;

import static com.dylibso.chicory.wasm.types.Value.REF_NULL_VALUE;
import static java.util.Objects.requireNonNullElse;

import com.dylibso.chicory.runtime.Instance;
import com.dylibso.chicory.runtime.Memory;
import com.dylibso.chicory.runtime.OpcodeImpl;
import com.dylibso.chicory.runtime.TableInstance;
import com.dylibso.chicory.runtime.TrapException;
import com.dylibso.chicory.runtime.exceptions.WASMRuntimeException;
import com.dylibso.chicory.wasm.exceptions.ChicoryException;
import com.dylibso.chicory.wasm.types.FunctionType;
import java.util.List;

public final class AotMethods {

private AotMethods() {}

public static long[] callIndirect(
long[] args, int typeId, int funcTableIdx, int tableIdx, Instance instance) {
TableInstance table = instance.table(tableIdx);

instance = requireNonNullElse(table.instance(funcTableIdx), instance);

int funcId = table.ref(funcTableIdx);
if (funcId == REF_NULL_VALUE) {
throw new ChicoryException("uninitialized element " + funcTableIdx);
}

FunctionType expectedType = instance.type(typeId);
FunctionType actualType = instance.type(instance.functionType(funcId));
if (!actualType.typesMatch(expectedType)) {
throw new ChicoryException("indirect call type mismatch");
}

checkInterruption();
return instance.getMachine().call(funcId, args);
}

public static long[] callIndirect(long[] args, int typeId, int funcId, Instance instance) {
FunctionType expectedType = instance.type(typeId);
FunctionType actualType = instance.type(instance.functionType(funcId));
if (!actualType.typesMatch(expectedType)) {
throw throwIndirectCallTypeMismatch();
}
return instance.getMachine().call(funcId, args);
}

public static boolean isRefNull(int ref) {
return ref == REF_NULL_VALUE;
}

public static int tableGet(int index, int tableIndex, Instance instance) {
return (int) OpcodeImpl.TABLE_GET(instance, tableIndex, index);
}

public static void tableSet(int index, int value, int tableIndex, Instance instance) {
instance.table(tableIndex).setRef(index, value, instance);
}

public static int tableGrow(int value, int size, int tableIndex, Instance instance) {
return instance.table(tableIndex).grow(size, value, instance);
}

public static int tableSize(int tableIndex, Instance instance) {
return instance.table(tableIndex).size();
}

public static void tableFill(
int offset, int value, int size, int tableIndex, Instance instance) {
OpcodeImpl.TABLE_FILL(instance, tableIndex, size, value, offset);
}

public static void tableCopy(
int d, int s, int size, int dstTableIndex, int srcTableIndex, Instance instance) {
OpcodeImpl.TABLE_COPY(instance, srcTableIndex, dstTableIndex, size, s, d);
}

public static void tableInit(
int offset, int elemidx, int size, int elementidx, int tableidx, Instance instance) {
OpcodeImpl.TABLE_INIT(instance, tableidx, elementidx, size, elemidx, offset);
}

public static int tableRef(TableInstance table, int index) {
int funcId = table.ref(index);
if (funcId == REF_NULL_VALUE) {
throw new ChicoryException("uninitialized element " + index);
}
return funcId;
}

public static void memoryCopy(int destination, int offset, int size, Memory memory) {
memory.copy(destination, offset, size);
}

public static void memoryFill(int offset, byte value, int size, Memory memory) {
int end = size + offset;
memory.fill(value, offset, end);
}

public static void memoryInit(
int destination, int offset, int size, int segmentId, Memory memory) {
memory.initPassiveSegment(segmentId, destination, offset, size);
}

public static byte memoryReadByte(int base, int offset, Memory memory) {
validateBase(base);
return memory.read(base + offset);
}

public static short memoryReadShort(int base, int offset, Memory memory) {
validateBase(base);
return memory.readShort(base + offset);
}

public static int memoryReadInt(int base, int offset, Memory memory) {
validateBase(base);
return memory.readInt(base + offset);
}

public static long memoryReadLong(int base, int offset, Memory memory) {
validateBase(base);
return memory.readLong(base + offset);
}

public static float memoryReadFloat(int base, int offset, Memory memory) {
validateBase(base);
return memory.readFloat(base + offset);
}

public static double memoryReadDouble(int base, int offset, Memory memory) {
validateBase(base);
return memory.readDouble(base + offset);
}

public static void memoryWriteByte(int base, byte value, int offset, Memory memory) {
validateBase(base);
memory.writeByte(base + offset, value);
}

public static void memoryWriteShort(int base, short value, int offset, Memory memory) {
validateBase(base);
memory.writeShort(base + offset, value);
}

public static void memoryWriteInt(int base, int value, int offset, Memory memory) {
validateBase(base);
memory.writeI32(base + offset, value);
}

public static void memoryWriteLong(int base, long value, int offset, Memory memory) {
validateBase(base);
memory.writeLong(base + offset, value);
}

public static void memoryWriteFloat(int base, float value, int offset, Memory memory) {
validateBase(base);
memory.writeF32(base + offset, value);
}

public static void memoryWriteDouble(int base, double value, int offset, Memory memory) {
validateBase(base);
memory.writeF64(base + offset, value);
}

public static void validateBase(int base) {
if (base < 0) {
throwOutOfBoundsMemoryAccess();
}
}

public static RuntimeException throwIndirectCallTypeMismatch() {
return new ChicoryException("indirect call type mismatch");
}

public static RuntimeException throwOutOfBoundsMemoryAccess() {
throw new WASMRuntimeException("out of bounds memory access");
}

public static RuntimeException throwTrapException() {
throw new TrapException("Trapped on unreachable instruction", List.of());
}

public static void checkInterruption() {
if (Thread.currentThread().isInterrupted()) {
throw new ChicoryException("Thread interrupted");
}
}

public static void writeGlobal(long value, int index, Instance instance) {
instance.writeGlobal(index, value);
}
}
4 changes: 4 additions & 0 deletions aot/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
<description>Experimental AOT for Chicory</description>

<dependencies>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>aot-runtime</artifactId>
</dependency>
<dependency>
<groupId>com.dylibso.chicory</groupId>
<artifactId>runtime</artifactId>
Expand Down
62 changes: 31 additions & 31 deletions aot/src/main/java/com/dylibso/chicory/aot/AotEmitters.java
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
package com.dylibso.chicory.aot;

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.MEMORY_COPY;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_DROP;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_FILL;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_GROW;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_INIT;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_PAGES;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_READ_BYTE;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_READ_DOUBLE;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_READ_FLOAT;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_READ_INT;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_READ_LONG;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_READ_SHORT;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_WRITE_BYTE;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_WRITE_DOUBLE;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_WRITE_FLOAT;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_WRITE_INT;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_WRITE_LONG;
import static com.dylibso.chicory.aot.AotMethods.MEMORY_WRITE_SHORT;
import static com.dylibso.chicory.aot.AotMethods.REF_IS_NULL;
import static com.dylibso.chicory.aot.AotMethods.TABLE_COPY;
import static com.dylibso.chicory.aot.AotMethods.TABLE_FILL;
import static com.dylibso.chicory.aot.AotMethods.TABLE_GET;
import static com.dylibso.chicory.aot.AotMethods.TABLE_GROW;
import static com.dylibso.chicory.aot.AotMethods.TABLE_INIT;
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.AotMethodRefs.CHECK_INTERRUPTION;
import static com.dylibso.chicory.aot.AotMethodRefs.INSTANCE_READ_GLOBAL;
import static com.dylibso.chicory.aot.AotMethodRefs.INSTANCE_SET_ELEMENT;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_COPY;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_DROP;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_FILL;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_GROW;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_INIT;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_PAGES;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_READ_BYTE;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_READ_DOUBLE;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_READ_FLOAT;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_READ_INT;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_READ_LONG;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_READ_SHORT;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_WRITE_BYTE;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_WRITE_DOUBLE;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_WRITE_FLOAT;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_WRITE_INT;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_WRITE_LONG;
import static com.dylibso.chicory.aot.AotMethodRefs.MEMORY_WRITE_SHORT;
import static com.dylibso.chicory.aot.AotMethodRefs.REF_IS_NULL;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_COPY;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_FILL;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_GET;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_GROW;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_INIT;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_SET;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_SIZE;
import static com.dylibso.chicory.aot.AotMethodRefs.THROW_OUT_OF_BOUNDS_MEMORY_ACCESS;
import static com.dylibso.chicory.aot.AotMethodRefs.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;
Expand Down
17 changes: 9 additions & 8 deletions aot/src/main/java/com/dylibso/chicory/aot/AotMachine.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
package com.dylibso.chicory.aot;

import static com.dylibso.chicory.aot.AotMethods.CHECK_INTERRUPTION;
import static com.dylibso.chicory.aot.AotMethods.INSTANCE_CALL_HOST_FUNCTION;
import static com.dylibso.chicory.aot.AotMethods.INSTANCE_TABLE;
import static com.dylibso.chicory.aot.AotMethods.TABLE_INSTANCE;
import static com.dylibso.chicory.aot.AotMethods.TABLE_REF;
import static com.dylibso.chicory.aot.AotMethods.THROW_INDIRECT_CALL_TYPE_MISMATCH;
import static com.dylibso.chicory.aot.AotMethods.THROW_TRAP_EXCEPTION;
import static com.dylibso.chicory.aot.AotMethodRefs.CALL_INDIRECT;
import static com.dylibso.chicory.aot.AotMethodRefs.CHECK_INTERRUPTION;
import static com.dylibso.chicory.aot.AotMethodRefs.INSTANCE_CALL_HOST_FUNCTION;
import static com.dylibso.chicory.aot.AotMethodRefs.INSTANCE_TABLE;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_INSTANCE;
import static com.dylibso.chicory.aot.AotMethodRefs.TABLE_REF;
import static com.dylibso.chicory.aot.AotMethodRefs.THROW_INDIRECT_CALL_TYPE_MISMATCH;
import static com.dylibso.chicory.aot.AotMethodRefs.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.defaultValue;
Expand Down Expand Up @@ -654,7 +655,7 @@ private void compileCallIndirect(
asm.visitVarInsn(Opcodes.ILOAD, funcId);
asm.visitVarInsn(Opcodes.ALOAD, refInstance);

emitInvokeStatic(asm, AotMethods.CALL_INDIRECT);
emitInvokeStatic(asm, CALL_INDIRECT);

emitUnboxResult(type, asm);
}
Expand Down
Loading
Loading