aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-12-22 17:41:30 +0000
committerMichael Williamson <mike@zwobble.org>2024-12-22 19:42:58 +0000
commit0e29eaa163eb58da6ef509b36245b7cc3d58e242 (patch)
tree6f876b7a5b4cf60dfd17dc8b79de803aaef3bc96 /src/main/java
parente6462d8438d7eccd9c3c812a65036b210cf7ae33 (diff)
Use explicit indirect function table
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java19
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCallIndirect.java4
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/linking/WasmRelocatableIndex.java2
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmTableName.java4
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java2
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatLinking.java25
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryWriter.java14
-rw-r--r--src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmIndexTable.java23
8 files changed, 75 insertions, 18 deletions
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java
index 20ddbc4c..978fe6cf 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/PatioToWasm.java
@@ -6,8 +6,7 @@ import org.pcollections.PVector;
import org.shedlang.compiler.backends.wasm.structure.ast.instructions.*;
import org.shedlang.compiler.backends.wasm.structure.ast.linking.WasmMemoryAddress;
import org.shedlang.compiler.backends.wasm.structure.ast.modules.*;
-import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmFuncType;
-import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmValueType;
+import org.shedlang.compiler.backends.wasm.structure.ast.types.*;
import org.shedlang.compiler.patio.*;
import org.shedlang.compiler.patio.instructions.*;
import org.shedlang.compiler.patio.operands.*;
@@ -22,11 +21,22 @@ import java.util.ArrayList;
import java.util.List;
public class PatioToWasm {
+ private static final String INDIRECT_FUNCTION_TABLE_NAME = "__indirect_function_table";
+
public static WasmModule generateCompilationUnit(
PatioCompilationUnit patioCompilationUnit,
WasmTarget target
) {
- var module = WasmModule.EMPTY;
+ var module = WasmModule.EMPTY.addImport(
+ new WasmImport(
+ "env",
+ INDIRECT_FUNCTION_TABLE_NAME,
+ new WasmImportDescriptor.Table(
+ INDIRECT_FUNCTION_TABLE_NAME,
+ new WasmTableType(WasmReferenceType.FUNC_REF, WasmLimits.min32(0))
+ )
+ )
+ );
var wasmMemoryBuilder = WasmMemoryBuilder.empty(target.indexType());
@@ -184,8 +194,7 @@ public class PatioToWasm {
context = context.addType(wasmFuncType);
context = context.addInstruction(new WasmCallIndirect(
- // TODO: remove hard-coded zero
- new WasmTableIndex(0),
+ new WasmTableName(INDIRECT_FUNCTION_TABLE_NAME),
wasmFuncType
));
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCallIndirect.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCallIndirect.java
index 716aa04c..56bc5205 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCallIndirect.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCallIndirect.java
@@ -1,10 +1,10 @@
package org.shedlang.compiler.backends.wasm.structure.ast.instructions;
-import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmTableIndex;
+import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmTableName;
import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmFuncType;
public record WasmCallIndirect(
- WasmTableIndex tableIndex,
+ WasmTableName tableName,
WasmFuncType funcType
) implements WasmInstruction {
}
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/linking/WasmRelocatableIndex.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/linking/WasmRelocatableIndex.java
index e8da5a63..035fb998 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/linking/WasmRelocatableIndex.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/linking/WasmRelocatableIndex.java
@@ -2,6 +2,7 @@ package org.shedlang.compiler.backends.wasm.structure.ast.linking;
import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmFuncName;
import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmGlobalName;
+import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmTableName;
import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmTagName;
import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmFuncType;
@@ -9,6 +10,7 @@ public sealed interface WasmRelocatableIndex {
record FuncIndex(WasmFuncName funcName) implements WasmRelocatableIndex {}
record GlobalIndex(WasmGlobalName globalName) implements WasmRelocatableIndex {}
record MemoryAddress(WasmMemoryAddress address) implements WasmRelocatableIndex {}
+ record TableIndex(WasmTableName tableName) implements WasmRelocatableIndex {}
record TableElementIndex(WasmFuncName funcName) implements WasmRelocatableIndex {}
record TagIndex(WasmTagName tagName) implements WasmRelocatableIndex {}
record TypeIndex(WasmFuncType funcType) implements WasmRelocatableIndex {}
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmTableName.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmTableName.java
new file mode 100644
index 00000000..42536446
--- /dev/null
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmTableName.java
@@ -0,0 +1,4 @@
+package org.shedlang.compiler.backends.wasm.structure.ast.modules;
+
+public record WasmTableName(String value) {
+}
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java
index af551003..3a712e33 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatInstructions.java
@@ -74,7 +74,7 @@ public class WasmBinaryFormatInstructions {
case WasmCallIndirect callIndirect -> {
writer.writeByte(0x11);
writer.writeTypeIndex(callIndirect.funcType());
- writer.writeTableIndex(callIndirect.tableIndex());
+ writer.writeTableIndex(callIndirect.tableName());
}
// == Parametric Instructions ==
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatLinking.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatLinking.java
index fed36ed5..6b8ff4ca 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatLinking.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatLinking.java
@@ -80,6 +80,9 @@ public class WasmBinaryFormatLinking {
case WasmRelocatableIndex.TagIndex tagIndex ->
symbolTable.tagNameToSymbolIndex(tagIndex.tagName()).value();
+
+ case WasmRelocatableIndex.TableIndex tableIndex ->
+ symbolTable.tableNameToSymbolIndex(tableIndex.tableName()).value();
};
writer.writeByte(relocationEntry.type().id());
@@ -249,6 +252,7 @@ public class WasmBinaryFormatLinking {
private final Map<String, WasmSymbolIndex> funcNameToSymbolIndex;
private final Map<String, WasmSymbolIndex> globalNameToSymbolIndex;
private final Map<String, WasmSymbolIndex> tagNameToSymbolIndex;
+ private final Map<String, WasmSymbolIndex> tableNameToSymbolIndex;
public SymbolTable(
List<SymbolInfo> symbolInfos,
@@ -256,7 +260,8 @@ public class WasmBinaryFormatLinking {
Map<WasmFuncType, WasmTypeIndex> funcTypeToTypeIndex,
Map<String, WasmSymbolIndex> funcNameToSymbolIndex,
Map<String, WasmSymbolIndex> globalNameToSymbolIndex,
- Map<String, WasmSymbolIndex> tagNameToSymbolIndex
+ Map<String, WasmSymbolIndex> tagNameToSymbolIndex,
+ Map<String, WasmSymbolIndex> tableNameToSymbolIndex
) {
this.symbolInfos = symbolInfos;
this.memoryAddressToSymbolIndex = memoryAddressToSymbolIndex;
@@ -264,6 +269,7 @@ public class WasmBinaryFormatLinking {
this.funcNameToSymbolIndex = funcNameToSymbolIndex;
this.globalNameToSymbolIndex = globalNameToSymbolIndex;
this.tagNameToSymbolIndex = tagNameToSymbolIndex;
+ this.tableNameToSymbolIndex = tableNameToSymbolIndex;
}
public WasmSymbolIndex memoryAddressToSymbolIndex(WasmMemoryAddress memoryAddress) {
@@ -315,6 +321,16 @@ public class WasmBinaryFormatLinking {
return symbolIndex;
}
}
+
+ public WasmSymbolIndex tableNameToSymbolIndex(WasmTableName name) {
+ var symbolIndex = tableNameToSymbolIndex.get(name.value());
+ if (symbolIndex == null) {
+ // TODO: better error
+ throw new RuntimeException("could not find index for table: " + name);
+ } else {
+ return symbolIndex;
+ }
+ }
}
private static SymbolTable generateSymbolTable(WasmModule module) {
@@ -404,6 +420,7 @@ public class WasmBinaryFormatLinking {
tagNameToSymbolIndex.put(tag.name(), symbolIndex);
}
+ var tableNameToSymbolIndex = new HashMap<String, WasmSymbolIndex>();
for (var table : module.indexedTables()) {
var flags = switch (table) {
case WasmModule.IndexedTable.Definition definition ->
@@ -419,7 +436,10 @@ public class WasmBinaryFormatLinking {
table.name()
);
+ var symbolIndex = new WasmSymbolIndex(symbolInfos.size());
symbolInfos.add(tableSymbolInfo);
+
+ tableNameToSymbolIndex.put(table.name(), symbolIndex);
}
return new SymbolTable(
@@ -428,7 +448,8 @@ public class WasmBinaryFormatLinking {
funcTypeToTypeIndex,
funcNameToSymbolIndex,
globalNameToSymbolIndex,
- tagNameToSymbolIndex
+ tagNameToSymbolIndex,
+ tableNameToSymbolIndex
);
}
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryWriter.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryWriter.java
index 4dc86a28..654d2a31 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryWriter.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryWriter.java
@@ -3,10 +3,7 @@ package org.shedlang.compiler.backends.wasm.structure.binary;
import org.shedlang.compiler.backends.wasm.structure.BinaryWriter;
import org.shedlang.compiler.backends.wasm.structure.ast.linking.WasmMemoryAddress;
import org.shedlang.compiler.backends.wasm.structure.ast.linking.WasmRelocatableIndex;
-import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmFuncName;
-import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmGlobalName;
-import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmTableIndex;
-import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmTagName;
+import org.shedlang.compiler.backends.wasm.structure.ast.modules.*;
import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmFuncType;
import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmIndexType;
@@ -97,8 +94,13 @@ public class WasmBinaryWriter {
);
}
- public void writeTableIndex(WasmTableIndex tableIndex) {
- writeUnsignedInt32(tableIndex.value());
+ public void writeTableIndex(WasmTableName tableName) throws IOException {
+ var tableIndex = indexTable.tableIndex(tableName);
+ writeRelocatableIndex(
+ WasmRelocationType.TABLE_NUMBER_LEB,
+ OptionalInt.of(tableIndex.value()),
+ new WasmRelocatableIndex.TableIndex(tableName)
+ );
}
public void writeTableElementIndexConst(WasmFuncName funcName) throws IOException {
diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmIndexTable.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmIndexTable.java
index 61b56ffb..b01e7135 100644
--- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmIndexTable.java
+++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmIndexTable.java
@@ -28,11 +28,17 @@ public class WasmIndexTable {
tagNameToTagIndex.put(indexedTag.name(), indexedTag.tagIndex());
}
+ var tableNameToTableIndex = new HashMap<String, WasmTableIndex>();
+ for (var indexedTable : module.indexedTables()) {
+ tableNameToTableIndex.put(indexedTable.name(), indexedTable.tableIndex());
+ }
+
return new WasmIndexTable(
funcTypeToTypeIndex,
functionNameToFuncIndex,
globalNameToGlobalIndex,
- tagNameToTagIndex
+ tagNameToTagIndex,
+ tableNameToTableIndex
);
}
@@ -40,17 +46,20 @@ public class WasmIndexTable {
private final Map<String, WasmFuncIndex> functionNameToFuncIndex;
private final Map<String, WasmGlobalIndex> globalNameToGlobalIndex;
private final Map<String, WasmTagIndex> tagNameToTagIndex;
+ private final Map<String, WasmTableIndex> tableNameToTableIndex;
private WasmIndexTable(
Map<WasmFuncType, WasmTypeIndex> funcTypeToTypeIndex,
Map<String, WasmFuncIndex> functionNameToFuncIndex,
Map<String, WasmGlobalIndex> globalNameToGlobalIndex,
- Map<String, WasmTagIndex> tagNameToTagIndex
+ Map<String, WasmTagIndex> tagNameToTagIndex,
+ Map<String, WasmTableIndex> tableNameToTableIndex
) {
this.funcTypeToTypeIndex = funcTypeToTypeIndex;
this.functionNameToFuncIndex = functionNameToFuncIndex;
this.globalNameToGlobalIndex = globalNameToGlobalIndex;
this.tagNameToTagIndex = tagNameToTagIndex;
+ this.tableNameToTableIndex = tableNameToTableIndex;
}
public WasmTypeIndex typeIndex(WasmFuncType type) {
@@ -86,4 +95,14 @@ public class WasmIndexTable {
return tagIndex;
}
}
+
+ public WasmTableIndex tableIndex(WasmTableName tableName) {
+ var tableIndex = tableNameToTableIndex.get(tableName.value());
+ if (tableIndex == null) {
+ // TODO: better error
+ throw new RuntimeException("missing table index for table: " + tableName.value());
+ } else {
+ return tableIndex;
+ }
+ }
}