summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wasm/wasm-binary.cpp10
-rw-r--r--test/polymorphic_stack.wast10
-rw-r--r--test/polymorphic_stack.wast.from-wast10
-rw-r--r--test/polymorphic_stack.wast.fromBinary11
-rw-r--r--test/polymorphic_stack.wast.fromBinary.noDebugInfo11
5 files changed, 51 insertions, 1 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 88b967fdf..47bcc8ba5 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -666,6 +666,14 @@ void WasmBinaryWriter::visitSwitch(Switch *curr) {
recurse(curr->value);
}
recurse(curr->condition);
+ if (!BranchUtils::isBranchTaken(curr)) {
+ // if the branch is not taken, then it's dangerous to emit it, as
+ // wasm type checking rules are stricter than ours - we tolerate
+ // an untaken branch to a target with a different value, but not
+ // wasm. so just don't emit it
+ o << int8_t(BinaryConsts::Unreachable);
+ return;
+ }
o << int8_t(BinaryConsts::TableSwitch) << U32LEB(curr->targets.size());
for (auto target : curr->targets) {
o << U32LEB(getBreakIndex(target));
@@ -1796,7 +1804,7 @@ void WasmBinaryBuilder::processExpressions() { // until an end or else marker, o
Expression* WasmBinaryBuilder::popExpression() {
if (expressionStack.empty()) {
- throw ParseException("attempted pop from empty stack");
+ throw ParseException("attempted pop from empty stack at " + std::to_string(pos));
}
auto ret = expressionStack.back();
// to simulate the wasm polymorphic stack mode, leave a final
diff --git a/test/polymorphic_stack.wast b/test/polymorphic_stack.wast
index 2241ab910..b618fbb6c 100644
--- a/test/polymorphic_stack.wast
+++ b/test/polymorphic_stack.wast
@@ -86,5 +86,15 @@
)
)
)
+ (func $br_table_unreachable_to_also_unreachable (result i32)
+ (block $a (result i32)
+ (block $b
+ (br_table $a $b ;; seems to send a value, but is not taken
+ (unreachable)
+ (unreachable)
+ )
+ )
+ )
+ )
)
diff --git a/test/polymorphic_stack.wast.from-wast b/test/polymorphic_stack.wast.from-wast
index b4b88f16b..c20f9218d 100644
--- a/test/polymorphic_stack.wast.from-wast
+++ b/test/polymorphic_stack.wast.from-wast
@@ -90,4 +90,14 @@
)
)
)
+ (func $br_table_unreachable_to_also_unreachable (type $1) (result i32)
+ (block $a (result i32)
+ (block $b
+ (br_table $a $b
+ (unreachable)
+ (unreachable)
+ )
+ )
+ )
+ )
)
diff --git a/test/polymorphic_stack.wast.fromBinary b/test/polymorphic_stack.wast.fromBinary
index e0ee6577d..b139c9c06 100644
--- a/test/polymorphic_stack.wast.fromBinary
+++ b/test/polymorphic_stack.wast.fromBinary
@@ -125,5 +125,16 @@
(unreachable)
)
)
+ (func $br_table_unreachable_to_also_unreachable (type $1) (result i32)
+ (block $label$0 (result i32)
+ (block $label$1
+ (unreachable)
+ (unreachable)
+ (unreachable)
+ (unreachable)
+ )
+ (unreachable)
+ )
+ )
)
diff --git a/test/polymorphic_stack.wast.fromBinary.noDebugInfo b/test/polymorphic_stack.wast.fromBinary.noDebugInfo
index 857a3660c..e707d5046 100644
--- a/test/polymorphic_stack.wast.fromBinary.noDebugInfo
+++ b/test/polymorphic_stack.wast.fromBinary.noDebugInfo
@@ -125,5 +125,16 @@
(unreachable)
)
)
+ (func $6 (type $1) (result i32)
+ (block $label$0 (result i32)
+ (block $label$1
+ (unreachable)
+ (unreachable)
+ (unreachable)
+ (unreachable)
+ )
+ (unreachable)
+ )
+ )
)