From cd63fb7d39491f917cf65c77d33f465de2e2dbda Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Sun, 25 Jun 2023 13:24:26 +0100 Subject: Write globals to symbol table --- .../wasm/structure/ast/modules/WasmGlobal.java | 2 +- .../structure/ast/modules/WasmGlobalIndex.java | 4 +++ .../ast/modules/WasmImportDescriptor.java | 2 +- .../wasm/structure/ast/modules/WasmModule.java | 37 +++++++++++++++++++++ .../structure/binary/WasmBinaryFormatLinking.java | 38 ++++++++++++++++++---- .../structure/binary/WasmBinaryFormatModules.java | 4 +++ 6 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobalIndex.java (limited to 'src/main/java') diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobal.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobal.java index 637376c2..7b8835a6 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobal.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobal.java @@ -3,5 +3,5 @@ package org.shedlang.compiler.backends.wasm.structure.ast.modules; import org.shedlang.compiler.backends.wasm.structure.ast.instructions.WasmExpression; import org.shedlang.compiler.backends.wasm.structure.ast.types.WasmGlobalType; -public record WasmGlobal(WasmGlobalType type, WasmExpression init) { +public record WasmGlobal(String name, WasmGlobalType type, WasmExpression init) { } diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobalIndex.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobalIndex.java new file mode 100644 index 00000000..76a5728f --- /dev/null +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmGlobalIndex.java @@ -0,0 +1,4 @@ +package org.shedlang.compiler.backends.wasm.structure.ast.modules; + +public record WasmGlobalIndex(int value) { +} diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmImportDescriptor.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmImportDescriptor.java index 95e9c8cb..fa7aa10f 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmImportDescriptor.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmImportDescriptor.java @@ -9,5 +9,5 @@ public sealed interface WasmImportDescriptor { record Func(String identifier, WasmFuncType type) implements WasmImportDescriptor {} record Table(WasmTableType type) implements WasmImportDescriptor {} record Memory(WasmMemoryType type) implements WasmImportDescriptor {} - record Global(WasmGlobalType type) implements WasmImportDescriptor {} + record Global(String identifier, WasmGlobalType type) implements WasmImportDescriptor {} } diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmModule.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmModule.java index 79a1e6f5..5875a591 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmModule.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/ast/modules/WasmModule.java @@ -79,6 +79,43 @@ public record WasmModule( return indexedFunctions; } + public sealed interface IndexedGlobal { + record Import(WasmGlobalIndex globalIndex, WasmImportDescriptor.Global descriptor) implements IndexedGlobal { + @Override + public String name() { + return descriptor.identifier(); + } + } + + record Definition(WasmGlobalIndex globalIndex, WasmGlobal global) implements IndexedGlobal { + @Override + public String name() { + return global.name(); + } + } + + WasmGlobalIndex globalIndex(); + String name(); + } + + public List indexedGlobals() { + var indexedGlobals = new ArrayList(); + + for (var import_ : imports) { + if (import_.descriptor() instanceof WasmImportDescriptor.Global global) { + var globalIndex = new WasmGlobalIndex(indexedGlobals.size()); + indexedGlobals.add(new IndexedGlobal.Import(globalIndex, global)); + } + } + + for (var global : globals) { + var globalIndex = new WasmGlobalIndex(indexedGlobals.size()); + indexedGlobals.add(new IndexedGlobal.Definition(globalIndex, global)); + } + + return indexedGlobals; + } + public WasmModule addType(WasmFuncType type) { return new WasmModule( types.plus(type), 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 59bab46e..c92baba2 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 @@ -2,15 +2,16 @@ package org.shedlang.compiler.backends.wasm.structure.binary; import org.shedlang.compiler.backends.wasm.structure.BinaryWriter; import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmFuncIndex; +import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmGlobalIndex; import org.shedlang.compiler.backends.wasm.structure.ast.modules.WasmModule; import java.io.IOException; import java.util.Collection; import java.util.List; +import java.util.stream.Stream; import static org.shedlang.compiler.backends.wasm.structure.binary.WasmBinaryFormatConventions.writeVec; -import static org.shedlang.compiler.backends.wasm.structure.binary.WasmBinaryFormatModules.writeCustomSection; -import static org.shedlang.compiler.backends.wasm.structure.binary.WasmBinaryFormatModules.writeFuncIndex; +import static org.shedlang.compiler.backends.wasm.structure.binary.WasmBinaryFormatModules.*; import static org.shedlang.compiler.backends.wasm.structure.binary.WasmBinaryFormatSize.writeSize; import static org.shedlang.compiler.backends.wasm.structure.binary.WasmBinaryFormatValues.writeString; @@ -79,6 +80,12 @@ public class WasmBinaryFormatLinking { writeFuncIndex(function.funcIndex, writer); writeString(function.name(), writer); } + case SymbolInfo.Global global -> { + writer.writeByte(SymbolType.GLOBAL.id); + Leb128Encoding.encodeUnsignedInt32(flagsToInt(global.flags), writer); + writeGlobalIndex(global.globalIndex, writer); + writeString(global.name(), writer); + } } } @@ -98,8 +105,8 @@ public class WasmBinaryFormatLinking { } private static List symbolInfos(WasmModule module) { - return module.indexedFunctions().stream() - .map(function -> { + var functionSymbols = module.indexedFunctions().stream() + .map(function -> { var flags = switch (function) { case WasmModule.IndexedFunction.Definition definition -> List.of(); @@ -112,13 +119,32 @@ public class WasmBinaryFormatLinking { function.funcIndex(), function.name() ); - }) - .toList(); + }); + + var globalSymbols = module.indexedGlobals().stream() + .map(global -> { + var flags = switch (global) { + case WasmModule.IndexedGlobal.Definition definition -> + List.of(); + + case WasmModule.IndexedGlobal.Import import_ -> + List.of(SymbolFlag.UNDEFINED, SymbolFlag.EXPLICIT_NAME); + }; + return new SymbolInfo.Global( + flags, + global.globalIndex(), + global.name() + ); + }); + + return Stream.concat(functionSymbols, globalSymbols).toList(); } private sealed interface SymbolInfo { record Function(List flags, WasmFuncIndex funcIndex, String name) implements SymbolInfo { + } + record Global(List flags, WasmGlobalIndex globalIndex, String name) implements SymbolInfo { } } diff --git a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatModules.java b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatModules.java index 3525bbe5..2f424d98 100644 --- a/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatModules.java +++ b/src/main/java/org/shedlang/compiler/backends/wasm/structure/binary/WasmBinaryFormatModules.java @@ -36,6 +36,10 @@ public class WasmBinaryFormatModules { Leb128Encoding.encodeUnsignedInt32(funcIndex.value(), writer); } + static void writeGlobalIndex(WasmGlobalIndex globalIndex, BinaryWriter writer) { + Leb128Encoding.encodeUnsignedInt32(globalIndex.value(), writer); + } + // == Sections == interface Write { -- cgit v1.2.3