From 0e29eaa163eb58da6ef509b36245b7cc3d58e242 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 22 Dec 2024 17:41:30 +0000 Subject: Use explicit indirect function table --- .../compiler/backends/wasm/PatioToWasm.java | 19 +++++++++++----- .../ast/instructions/WasmCallIndirect.java | 4 ++-- .../ast/linking/WasmRelocatableIndex.java | 2 ++ .../wasm/structure/ast/modules/WasmTableName.java | 4 ++++ .../binary/WasmBinaryFormatInstructions.java | 2 +- .../structure/binary/WasmBinaryFormatLinking.java | 25 ++++++++++++++++++++-- .../wasm/structure/binary/WasmBinaryWriter.java | 14 ++++++------ .../wasm/structure/binary/WasmIndexTable.java | 23 ++++++++++++++++++-- 8 files changed, 75 insertions(+), 18 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmTableName.java (limited to 'src/main/java') 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 funcNameToSymbolIndex; private final Map globalNameToSymbolIndex; private final Map tagNameToSymbolIndex; + private final Map tableNameToSymbolIndex; public SymbolTable( List symbolInfos, @@ -256,7 +260,8 @@ public class WasmBinaryFormatLinking { Map funcTypeToTypeIndex, Map funcNameToSymbolIndex, Map globalNameToSymbolIndex, - Map tagNameToSymbolIndex + Map tagNameToSymbolIndex, + Map 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(); 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(); + 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 functionNameToFuncIndex; private final Map globalNameToGlobalIndex; private final Map tagNameToTagIndex; + private final Map tableNameToTableIndex; private WasmIndexTable( Map funcTypeToTypeIndex, Map functionNameToFuncIndex, Map globalNameToGlobalIndex, - Map tagNameToTagIndex + Map tagNameToTagIndex, + Map 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; + } + } } -- cgit v1.2.3