Fix reading breaks to the function exit (#1304)
* remove unneeded code to handle a br to the return from the function. Now that we use getBlockOrSingleton there, it does that for us anyhow
diff --git a/src/wasm-binary.h b/src/wasm-binary.h
index 068f59d..a407c56 100644
--- a/src/wasm-binary.h
+++ b/src/wasm-binary.h
@@ -864,7 +864,6 @@
};
std::vector<BreakTarget> breakStack;
std::unordered_set<Name> breakTargetNames;
- bool breaksToReturn; // whether a break is done to the function scope, which is in effect a return
std::vector<Expression*> expressionStack;
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index b5bce86..2d1e873 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -1204,8 +1204,6 @@
// reader
-static Name RETURN_BREAK("binaryen|break-to-return");
-
void WasmBinaryBuilder::read() {
readHeader();
@@ -1626,17 +1624,14 @@
if (debug) std::cerr << "processing function: " << i << std::endl;
nextLabel = 0;
useDebugLocation = false;
- breaksToReturn = false;
// process body
assert(breakTargetNames.size() == 0);
assert(breakStack.empty());
- breakStack.emplace_back(RETURN_BREAK, func->result != none); // the break target for the function scope
assert(expressionStack.empty());
assert(depth == 0);
func->body = getBlockOrSingleton(func->result);
assert(depth == 0);
- assert(breakStack.size() == 1);
- breakStack.pop_back();
+ assert(breakStack.size() == 0);
assert(breakTargetNames.size() == 0);
if (!expressionStack.empty()) {
throw ParseException("stack not empty on function exit");
@@ -1644,10 +1639,6 @@
if (pos != endOfFunction) {
throw ParseException("binary offset at function exit not at expected location");
}
- if (breaksToReturn) {
- // we broke to return, so we need an outer block to break to
- func->body = Builder(wasm).blockifyWithName(func->body, RETURN_BREAK);
- }
}
currFunction = nullptr;
functions.push_back(func);
@@ -2325,15 +2316,12 @@
WasmBinaryBuilder::BreakTarget WasmBinaryBuilder::getBreakTarget(int32_t offset) {
if (debug) std::cerr << "getBreakTarget " << offset << std::endl;
+ if (breakStack.size() < 1 + size_t(offset)) {
+ throw ParseException("bad breakindex (low)");
+ }
size_t index = breakStack.size() - 1 - offset;
if (index >= breakStack.size()) {
- throw ParseException("bad breakindex");
- }
- if (index == 0) {
- // trying to access the topmost element means we break out
- // to the function scope, doing in effect a return, we'll
- // need to create a block for that.
- breaksToReturn = true;
+ throw ParseException("bad breakindex (high)");
}
if (debug) std::cerr << "breaktarget "<< breakStack[index].name << " arity " << breakStack[index].arity << std::endl;
auto& ret = breakStack[index];
diff --git a/test/br_to_exit.wasm b/test/br_to_exit.wasm
new file mode 100644
index 0000000..53bded1
--- /dev/null
+++ b/test/br_to_exit.wasm
Binary files differ
diff --git a/test/br_to_exit.wasm.fromBinary b/test/br_to_exit.wasm.fromBinary
new file mode 100644
index 0000000..2659ab3
--- /dev/null
+++ b/test/br_to_exit.wasm.fromBinary
@@ -0,0 +1,10 @@
+(module
+ (type $0 (func))
+ (memory $0 0)
+ (func $0 (; 0 ;) (type $0)
+ (block $label$0
+ (br $label$0)
+ )
+ )
+)
+