Skip to content

Commit 114ed43

Browse files
committed
fix proper wasm emitting of untaken br_tables
1 parent 04418d5 commit 114ed43

5 files changed

Lines changed: 51 additions & 1 deletion

src/wasm/wasm-binary.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,14 @@ void WasmBinaryWriter::visitSwitch(Switch *curr) {
666666
recurse(curr->value);
667667
}
668668
recurse(curr->condition);
669+
if (!BranchUtils::isBranchTaken(curr)) {
670+
// if the branch is not taken, then it's dangerous to emit it, as
671+
// wasm type checking rules are stricter than ours - we tolerate
672+
// an untaken branch to a target with a different value, but not
673+
// wasm. so just don't emit it
674+
o << int8_t(BinaryConsts::Unreachable);
675+
return;
676+
}
669677
o << int8_t(BinaryConsts::TableSwitch) << U32LEB(curr->targets.size());
670678
for (auto target : curr->targets) {
671679
o << U32LEB(getBreakIndex(target));
@@ -1796,7 +1804,7 @@ void WasmBinaryBuilder::processExpressions() { // until an end or else marker, o
17961804

17971805
Expression* WasmBinaryBuilder::popExpression() {
17981806
if (expressionStack.empty()) {
1799-
throw ParseException("attempted pop from empty stack");
1807+
throw ParseException("attempted pop from empty stack at " + std::to_string(pos));
18001808
}
18011809
auto ret = expressionStack.back();
18021810
// to simulate the wasm polymorphic stack mode, leave a final

test/polymorphic_stack.wast

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,5 +86,15 @@
8686
)
8787
)
8888
)
89+
(func $br_table_unreachable_to_also_unreachable (result i32)
90+
(block $a (result i32)
91+
(block $b
92+
(br_table $a $b ;; seems to send a value, but is not taken
93+
(unreachable)
94+
(unreachable)
95+
)
96+
)
97+
)
98+
)
8999
)
90100

test/polymorphic_stack.wast.from-wast

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,14 @@
9090
)
9191
)
9292
)
93+
(func $br_table_unreachable_to_also_unreachable (type $1) (result i32)
94+
(block $a (result i32)
95+
(block $b
96+
(br_table $a $b
97+
(unreachable)
98+
(unreachable)
99+
)
100+
)
101+
)
102+
)
93103
)

test/polymorphic_stack.wast.fromBinary

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,16 @@
125125
(unreachable)
126126
)
127127
)
128+
(func $br_table_unreachable_to_also_unreachable (type $1) (result i32)
129+
(block $label$0 (result i32)
130+
(block $label$1
131+
(unreachable)
132+
(unreachable)
133+
(unreachable)
134+
(unreachable)
135+
)
136+
(unreachable)
137+
)
138+
)
128139
)
129140

test/polymorphic_stack.wast.fromBinary.noDebugInfo

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,5 +125,16 @@
125125
(unreachable)
126126
)
127127
)
128+
(func $6 (type $1) (result i32)
129+
(block $label$0 (result i32)
130+
(block $label$1
131+
(unreachable)
132+
(unreachable)
133+
(unreachable)
134+
(unreachable)
135+
)
136+
(unreachable)
137+
)
138+
)
128139
)
129140

0 commit comments

Comments
 (0)