Skip to content

Commit f331120

Browse files
authored
Fixup block-nested pops even when EH is not enabled (#7130)
While parsing a binary file, there may be pops that need to be fixed up even if EH is not (yet) enabled because the target features section has not been parsed yet. Previously `EHUtils::handleBlockNestedPops` did not do anything if EH was not enabled, so the binary parser would fail to fix up pops in that case. Add an optional parameter to override this behavior so the parser can fix up pops unconditionally. Fixes #7127.
1 parent 74782d2 commit f331120

5 files changed

Lines changed: 17 additions & 7 deletions

File tree

src/ir/eh-utils.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,9 @@ void handleBlockNestedPop(Try* try_, Function* func, Module& wasm) {
148148
}
149149
}
150150

151-
void handleBlockNestedPops(Function* func, Module& wasm) {
152-
if (!wasm.features.hasExceptionHandling()) {
151+
void handleBlockNestedPops(Function* func, Module& wasm, FeaturePolicy policy) {
152+
if (policy == FeaturePolicy::SkipIfNoEH &&
153+
!wasm.features.hasExceptionHandling()) {
153154
return;
154155
}
155156
FindAll<Try> trys(func->body);

src/ir/eh-utils.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,14 @@ bool containsValidDanglingPop(Expression* catchBody);
3838
// '(local.get $new)' where the 'pop' used to be.
3939
void handleBlockNestedPop(Try* try_, Function* func, Module& wasm);
4040

41-
// Calls handleBlockNestedPop for each 'Try's in a given function.
42-
void handleBlockNestedPops(Function* func, Module& wasm);
41+
enum class FeaturePolicy { SkipIfNoEH, RunIfNoEH };
42+
43+
// Calls handleBlockNestedPop for each 'Try's in a given function. By default,
44+
// does no work if EH is not enabled, but this can be overridden with the
45+
// RunIfNoEH policy.
46+
void handleBlockNestedPops(Function* func,
47+
Module& wasm,
48+
FeaturePolicy policy = FeaturePolicy::SkipIfNoEH);
4349

4450
// Given a catch body, find the pop corresponding to the catch. There might be
4551
// pops nested inside a try inside this catch, and we must ignore them, like

src/wasm/wasm-ir-builder.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1018,7 +1018,10 @@ Result<> IRBuilder::visitEnd() {
10181018
func->body = maybeWrapForLabel(*expr);
10191019
labelDepths.clear();
10201020
if (scope.needsPopFixup()) {
1021-
EHUtils::handleBlockNestedPops(func, wasm);
1021+
// We may be in the binary parser, where pops need to be fixed up before
1022+
// we know that EH will be enabled.
1023+
EHUtils::handleBlockNestedPops(
1024+
func, wasm, EHUtils::FeaturePolicy::RunIfNoEH);
10221025
}
10231026
this->func = nullptr;
10241027
blockHint = 0;

test/lit/binary/stacky-eh-legacy.test

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,15 +35,15 @@
3535
;; The fixup will hoist the 'pop' and create another local to store it right
3636
;; after 'catch'.
3737

38-
;; RUN: wasm-opt -all %s.wasm -S -o - | filecheck %s
38+
;; RUN: wasm-opt %s.wasm -S -o - | filecheck %s
3939

4040
;; CHECK: (type $0 (func (param i32)))
4141

4242
;; CHECK: (type $1 (func))
4343

4444
;; CHECK: (tag $tag$0 (param i32))
4545

46-
;; CHECK: (func $0 (type $1)
46+
;; CHECK: (func $0
4747
;; CHECK-NEXT: (local $0 i32)
4848
;; CHECK-NEXT: (local $1 i32)
4949
;; CHECK-NEXT: (local $2 i32)
39 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)