From 57c58c2e977135c06be1147cff4b731c52e4aa8e Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 27 Jun 2023 19:07:57 +0100 Subject: Add WASM call instruction --- .../wasm/structure/ast/instructions/WasmCall.java | 8 ++++++ .../ast/instructions/WasmInstruction.java | 2 +- .../ast/linking/WasmRelocatableIndex.java | 1 + .../binary/WasmBinaryFormatInstructions.java | 5 ++++ .../structure/binary/WasmBinaryFormatLinking.java | 29 +++++++++++++++++++--- .../wasm/structure/binary/WasmBinaryWriter.java | 9 +++++++ 6 files changed, 49 insertions(+), 5 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCall.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCall.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCall.java new file mode 100644 index 00000000..29f2ff7e --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmCall.java @@ -0,0 +1,8 @@ +package org.shedlang.compiler.backends.wasm.structure.ast.instructions; + +import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmFuncName; + +public record WasmCall( + WasmFuncName funcName +) implements WasmInstruction { +} diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java index 65b4b672..e0bce7b5 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/instructions/WasmInstruction.java @@ -1,4 +1,4 @@ package org.shedlang.compiler.backends.wasm.structure.ast.instructions; -public sealed interface WasmInstruction permits WasmCallIndirect, WasmDrop, WasmI32Const, WasmI32Load, WasmI64Const, WasmLocalGet, WasmLocalSet, WasmMemoryAddressConst, WasmReturn { +public sealed interface WasmInstruction permits WasmCall, WasmCallIndirect, WasmDrop, WasmI32Const, WasmI32Load, WasmI64Const, WasmLocalGet, WasmLocalSet, WasmMemoryAddressConst, WasmReturn { } 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 3801bf59..90989b14 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 @@ -3,6 +3,7 @@ package org.shedlang.compiler.backends.wasm.structure.ast.linking; import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmFuncType; public sealed interface WasmRelocatableIndex { + record FuncIndex(String name) implements WasmRelocatableIndex {} record MemoryAddress(WasmMemoryAddress address) implements WasmRelocatableIndex {} record TypeIndex(WasmFuncType funcType) implements WasmRelocatableIndex {} } 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 4bfae740..aa2fff35 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 @@ -25,6 +25,11 @@ public class WasmBinaryFormatInstructions { writer.writeByte(0x0f); } + case WasmCall call -> { + writer.writeByte(0x10); + writer.writeFuncIndex(call.funcName()); + } + case WasmCallIndirect callIndirect -> { writer.writeByte(0x11); writer.writeTypeIndex(callIndirect.funcType()); 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 fb5ea132..5e8a9425 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 @@ -69,6 +69,9 @@ public class WasmBinaryFormatLinking { WasmBinaryWriter writer ) { var index = switch (relocationEntry.index()) { + case WasmRelocatableIndex.FuncIndex funcIndex -> + symbolTable.funcNameToFuncIndex(funcIndex.name()).value(); + case WasmRelocatableIndex.MemoryAddress memoryAddress -> symbolTable.memoryAddressToSymbolIndex(memoryAddress.address()).value(); @@ -229,17 +232,20 @@ public class WasmBinaryFormatLinking { private final int functionSymbolIndexOffset; private final Map memoryAddressToSymbolIndex; private final Map funcTypeToTypeIndex; + private final Map funcNameToSymbolIndex; public SymbolTable( List symbolInfos, int functionSymbolIndexOffset, Map memoryAddressToSymbolIndex, - Map funcTypeToTypeIndex + Map funcTypeToTypeIndex, + Map funcNameToSymbolIndex ) { this.symbolInfos = symbolInfos; this.functionSymbolIndexOffset = functionSymbolIndexOffset; this.memoryAddressToSymbolIndex = memoryAddressToSymbolIndex; this.funcTypeToTypeIndex = funcTypeToTypeIndex; + this.funcNameToSymbolIndex = funcNameToSymbolIndex; } public WasmSymbolIndex funcIndexToSymbolIndex(WasmFuncIndex funcIndex) { @@ -265,6 +271,16 @@ public class WasmBinaryFormatLinking { return typeIndex; } } + + public WasmSymbolIndex funcNameToFuncIndex(String name) { + var syjmbolIndex = funcNameToSymbolIndex.get(name); + if (syjmbolIndex == null) { + // TODO: better error + throw new RuntimeException("could not find index for func: " + name); + } else { + return syjmbolIndex; + } + } } private static SymbolTable generateSymbolTable(WasmModule module) { @@ -272,6 +288,7 @@ public class WasmBinaryFormatLinking { var memoryAddressToSymbolIndex = new HashMap(); var functionSymbolIndexOffset = 0; + var funcNameToSymbolIndex = new HashMap(); for (var function : module.indexedFunctions()) { var flags = switch (function) { case WasmModule.IndexedFunction.Definition definition -> @@ -285,17 +302,20 @@ public class WasmBinaryFormatLinking { function.funcIndex(), function.name() ); + var symbolIndex = new WasmSymbolIndex(symbolInfos.size()); symbolInfos.add(symbolInfo); + funcNameToSymbolIndex.put(function.name(), symbolIndex); } for (var dataSegment : module.dataSegments()) { for (var dataSymbol : dataSegment.symbols()) { var symbolInfo = new SymbolInfo.Data(List.of(), dataSymbol); + var symbolIndex = new WasmSymbolIndex(symbolInfos.size()); + symbolInfos.add(symbolInfo); memoryAddressToSymbolIndex.put( new WasmMemoryAddress(dataSymbol.dataSegmentIndex(), dataSymbol.offset()), - new WasmSymbolIndex(symbolInfos.size()) + symbolIndex ); - symbolInfos.add(symbolInfo); } } @@ -327,7 +347,8 @@ public class WasmBinaryFormatLinking { symbolInfos, functionSymbolIndexOffset, memoryAddressToSymbolIndex, - funcTypeToTypeIndex + funcTypeToTypeIndex, + funcNameToSymbolIndex ); } 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 c14fd1db..6636c5d1 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,6 +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.WasmTableIndex; import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmFuncType; @@ -47,6 +48,14 @@ public class WasmBinaryWriter { WasmBinaryFormatValues.writeString(value, writer); } + public void writeFuncIndex(WasmFuncName funcName) throws IOException { + writeRelocatableIndex( + WasmRelocationType.FUNCTION_INDEX_LEB, + () -> writePaddedUnsignedInt32(0), + new WasmRelocatableIndex.FuncIndex(funcName.value()) + ); + } + public void writeMemoryAddressConst(WasmMemoryAddress index) throws IOException { writeRelocatableIndex( WasmRelocationType.MEMORY_ADDR_SLEB, -- cgit v1.2.3