summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm-binary.h4
-rw-r--r--src/wasm/wasm-binary.cpp61
-rw-r--r--test/binaryen.js/kitchen-sink.js.txt2
-rw-r--r--test/exception-handling.wast.fromBinary68
-rw-r--r--test/lit/passes/stack-ir-roundtrip-eh.wast5
-rw-r--r--test/reference-types.wast.fromBinary10
-rw-r--r--test/tags.wast.fromBinary16
7 files changed, 112 insertions, 54 deletions
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index f6924aa14..a00a1df46 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -454,6 +454,7 @@ enum Subsection {
NameData = 9,
// see: https://github.com/WebAssembly/gc/issues/193
NameField = 10,
+ NameTag = 11,
DylinkMemInfo = 1,
DylinkNeeded = 2,
@@ -1552,6 +1553,9 @@ public:
// at index i we have all refs to the global i
std::map<Index, std::vector<Name*>> globalRefs;
+ // at index i we have all refs to the tag i
+ std::map<Index, std::vector<Name*>> tagRefs;
+
// Throws a parsing error if we are not in a function context
void requireFunctionContext(const char* error);
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 685da0bf1..1fb43c884 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1070,6 +1070,30 @@ void WasmBinaryWriter::writeNames() {
}
}
+ // tag names
+ if (!wasm->tags.empty()) {
+ Index count = 0;
+ for (auto& tag : wasm->tags) {
+ if (tag->hasExplicitName) {
+ count++;
+ }
+ }
+
+ if (count) {
+ auto substart =
+ startSubsection(BinaryConsts::UserSections::Subsection::NameTag);
+ o << U32LEB(count);
+ for (Index i = 0; i < wasm->tags.size(); i++) {
+ auto& tag = wasm->tags[i];
+ if (tag->hasExplicitName) {
+ o << U32LEB(i);
+ writeEscapedName(tag->name.str);
+ }
+ }
+ finishSubsection(substart);
+ }
+ }
+
finishSection(start);
}
@@ -3012,24 +3036,26 @@ void WasmBinaryBuilder::processNames() {
*ref = getFunctionName(index);
}
}
-
for (auto& [index, refs] : tableRefs) {
for (auto* ref : refs) {
*ref = getTableName(index);
}
}
-
for (auto& [index, refs] : memoryRefs) {
for (auto ref : refs) {
*ref = getMemoryName(index);
}
}
-
for (auto& [index, refs] : globalRefs) {
for (auto* ref : refs) {
*ref = getGlobalName(index);
}
}
+ for (auto& [index, refs] : tagRefs) {
+ for (auto* ref : refs) {
+ *ref = getTagName(index);
+ }
+ }
// Everything now has its proper name.
@@ -3455,6 +3481,22 @@ void WasmBinaryBuilder::readNames(size_t payloadLen) {
}
}
}
+ } else if (nameType == BinaryConsts::UserSections::Subsection::NameTag) {
+ auto num = getU32LEB();
+ NameProcessor processor;
+ for (size_t i = 0; i < num; i++) {
+ auto index = getU32LEB();
+ auto rawName = getInlineString();
+ auto name = processor.process(rawName);
+ if (index < wasm.tags.size()) {
+ wasm.tags[index]->setExplicitName(name);
+ } else {
+ std::cerr << "warning: tag index out of bounds in name section, "
+ "tag subsection: "
+ << std::string(rawName.str) << " at index "
+ << std::to_string(index) << std::endl;
+ }
+ }
} else {
std::cerr << "warning: unknown name subsection with id "
<< std::to_string(nameType) << " at " << pos << std::endl;
@@ -6652,6 +6694,11 @@ void WasmBinaryBuilder::visitTryOrTryInBlock(Expression*& out) {
}
};
+ // We cannot immediately update tagRefs in the loop below, as catchTags is
+ // being grown, an so references would get invalidated. Store the indexes
+ // here, then do that later.
+ std::vector<Index> tagIndexes;
+
while (lastSeparator == BinaryConsts::Catch ||
lastSeparator == BinaryConsts::CatchAll) {
if (lastSeparator == BinaryConsts::Catch) {
@@ -6659,10 +6706,10 @@ void WasmBinaryBuilder::visitTryOrTryInBlock(Expression*& out) {
if (index >= wasm.tags.size()) {
throwError("bad tag index");
}
+ tagIndexes.push_back(index);
auto* tag = wasm.tags[index].get();
curr->catchTags.push_back(tag->name);
readCatchBody(tag->sig.params);
-
} else { // catch_all
if (curr->hasCatchAll()) {
throwError("there should be at most one 'catch_all' clause per try");
@@ -6672,6 +6719,11 @@ void WasmBinaryBuilder::visitTryOrTryInBlock(Expression*& out) {
}
breakStack.pop_back();
+ for (Index i = 0; i < tagIndexes.size(); i++) {
+ // We don't know the final name yet.
+ tagRefs[tagIndexes[i]].push_back(&curr->catchTags[i]);
+ }
+
if (lastSeparator == BinaryConsts::Delegate) {
curr->delegateTarget = getExceptionTargetName(getU32LEB());
}
@@ -6768,6 +6820,7 @@ void WasmBinaryBuilder::visitThrow(Throw* curr) {
}
auto* tag = wasm.tags[index].get();
curr->tag = tag->name;
+ tagRefs[index].push_back(&curr->tag); // we don't know the final name yet
size_t num = tag->sig.params.size();
curr->operands.resize(num);
for (size_t i = 0; i < num; i++) {
diff --git a/test/binaryen.js/kitchen-sink.js.txt b/test/binaryen.js/kitchen-sink.js.txt
index de3510545..f92ceeb4a 100644
--- a/test/binaryen.js/kitchen-sink.js.txt
+++ b/test/binaryen.js/kitchen-sink.js.txt
@@ -4797,7 +4797,7 @@ module loaded from binary form:
(type $i32_i32_=>_none (func (param i32 i32)))
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
(global $a-global i32 (i32.const 3))
- (tag $tag$0 (param i32 i32))
+ (tag $a-tag (param i32 i32))
(func $adder (param $0 i32) (param $1 i32) (result i32)
(i32.add
(local.get $0)
diff --git a/test/exception-handling.wast.fromBinary b/test/exception-handling.wast.fromBinary
index 74e8f4d4a..73a4ae975 100644
--- a/test/exception-handling.wast.fromBinary
+++ b/test/exception-handling.wast.fromBinary
@@ -4,11 +4,11 @@
(type $i64_=>_none (func (param i64)))
(type $i32_i64_=>_none (func (param i32 i64)))
(type $eqref_=>_none (func (param eqref)))
- (tag $tag$0 (param i32))
- (tag $tag$1 (param i64))
- (tag $tag$2 (param i32 i64))
- (tag $tag$3 (param eqref))
- (tag $tag$4 (param))
+ (tag $e-i32 (param i32))
+ (tag $e-i64 (param i64))
+ (tag $e-i32-i64 (param i32 i64))
+ (tag $e-eqref (param eqref))
+ (tag $e-empty (param))
(func $foo
(nop)
)
@@ -23,11 +23,11 @@
(local $4 i32)
(try $label$3
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -35,12 +35,12 @@
)
(try $label$6
(do
- (throw $tag$2
+ (throw $e-i32-i64
(i32.const 0)
(i64.const 0)
)
)
- (catch $tag$2
+ (catch $e-i32-i64
(local.set $2
(pop i32 i64)
)
@@ -77,7 +77,7 @@
(do
(br $label$7)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -89,7 +89,7 @@
(do
(nop)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -100,7 +100,7 @@
(call $foo)
(call $bar)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -110,16 +110,16 @@
)
(try $label$19
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
)
- (catch $tag$1
+ (catch $e-i64
(drop
(pop i64)
)
@@ -127,7 +127,7 @@
)
(try $label$22
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
@@ -137,16 +137,16 @@
)
(try $label$25
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
)
- (catch $tag$1
+ (catch $e-i64
(drop
(pop i64)
)
@@ -160,11 +160,11 @@
(do
(try $label$29
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -174,7 +174,7 @@
)
)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -182,11 +182,11 @@
(catch_all
(try $label$33
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -199,7 +199,7 @@
)
(try $label$37
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
@@ -271,7 +271,7 @@
(do
(nop)
)
- (catch $tag$4
+ (catch $e-empty
(nop)
)
)
@@ -281,7 +281,7 @@
(do
(call $foo)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -296,7 +296,7 @@
(do
(call $foo)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -316,7 +316,7 @@
(do
(call $foo)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -337,7 +337,7 @@
(do
(call $foo)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -387,8 +387,8 @@
(do
(nop)
)
- (catch $tag$0
- (throw $tag$0
+ (catch $e-i32
+ (throw $e-i32
(if (result i32)
(pop i32)
(i32.const 0)
@@ -401,7 +401,7 @@
(do
(nop)
)
- (catch $tag$3
+ (catch $e-eqref
(drop
(pop eqref)
)
@@ -414,7 +414,7 @@
(block $label$1
(try $label$4
(do
- (throw $tag$0
+ (throw $e-i32
(i32.const 0)
)
)
diff --git a/test/lit/passes/stack-ir-roundtrip-eh.wast b/test/lit/passes/stack-ir-roundtrip-eh.wast
index df68d3f8a..790462cb9 100644
--- a/test/lit/passes/stack-ir-roundtrip-eh.wast
+++ b/test/lit/passes/stack-ir-roundtrip-eh.wast
@@ -2,6 +2,7 @@
;; RUN: wasm-opt %s --generate-stack-ir --roundtrip -all -S -o - | filecheck %s
(module
+ ;; CHECK: (tag $tag (param i32))
(tag $tag (param i32))
;; CHECK: (func $delegate-child
;; CHECK-NEXT: (try $label$9
@@ -10,7 +11,7 @@
;; CHECK-NEXT: (do
;; CHECK-NEXT: (nop)
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (catch $tag$0
+ ;; CHECK-NEXT: (catch $tag
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (pop i32)
;; CHECK-NEXT: )
@@ -23,7 +24,7 @@
;; CHECK-NEXT: )
;; CHECK-NEXT: )
;; CHECK-NEXT: )
- ;; CHECK-NEXT: (catch $tag$0
+ ;; CHECK-NEXT: (catch $tag
;; CHECK-NEXT: (drop
;; CHECK-NEXT: (pop i32)
;; CHECK-NEXT: )
diff --git a/test/reference-types.wast.fromBinary b/test/reference-types.wast.fromBinary
index 01523cab8..80d85fd26 100644
--- a/test/reference-types.wast.fromBinary
+++ b/test/reference-types.wast.fromBinary
@@ -18,7 +18,7 @@
(table $0 3 3 funcref)
(elem (i32.const 0) $take_eqref $take_funcref $take_anyref)
(elem declare func $foo $ref-taken-but-not-in-table)
- (tag $tag$0 (param i32))
+ (tag $e-i32 (param i32))
(export "export_func" (func $import_func))
(export "export_global" (global $import_global))
(func $take_eqref (param $0 eqref)
@@ -416,7 +416,7 @@
(do
(local.get $local_eqref)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -429,7 +429,7 @@
(do
(ref.func $foo)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -442,7 +442,7 @@
(do
(local.get $local_eqref)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
@@ -455,7 +455,7 @@
(do
(ref.null eq)
)
- (catch $tag$0
+ (catch $e-i32
(drop
(pop i32)
)
diff --git a/test/tags.wast.fromBinary b/test/tags.wast.fromBinary
index 81043d682..5528068c0 100644
--- a/test/tags.wast.fromBinary
+++ b/test/tags.wast.fromBinary
@@ -2,15 +2,15 @@
(type $i32_f32_=>_none (func (param i32 f32)))
(type $i32_=>_none (func (param i32)))
(type $none_=>_none (func))
- (import "env" "im0" (tag $eimport$0 (param i32)))
+ (import "env" "im0" (tag $e-import (param i32)))
(import "env" "im1" (tag $eimport$1 (param i32 f32)))
(tag $tag$0 (param i32))
- (tag $tag$1 (param i32 f32))
- (tag $tag$2 (param))
- (tag $tag$3 (param i32 f32))
- (tag $tag$4 (param i32 f32))
- (tag $tag$5 (param i32))
- (export "ex0" (tag $tag$5))
- (export "ex1" (tag $tag$1))
+ (tag $e (param i32 f32))
+ (tag $empty (param))
+ (tag $e-params0 (param i32 f32))
+ (tag $e-params1 (param i32 f32))
+ (tag $e-export (param i32))
+ (export "ex0" (tag $e-export))
+ (export "ex1" (tag $e))
)