From f331120e4b942a795d4a6b6d0d5a3d781c1e6a4c Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Mon, 2 Dec 2024 16:03:21 -0800 Subject: 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. --- src/ir/eh-utils.cpp | 5 +++-- src/ir/eh-utils.h | 10 ++++++++-- src/wasm/wasm-ir-builder.cpp | 5 ++++- 3 files changed, 15 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/ir/eh-utils.cpp b/src/ir/eh-utils.cpp index 70b5452a6..6d65de4ad 100644 --- a/src/ir/eh-utils.cpp +++ b/src/ir/eh-utils.cpp @@ -148,8 +148,9 @@ void handleBlockNestedPop(Try* try_, Function* func, Module& wasm) { } } -void handleBlockNestedPops(Function* func, Module& wasm) { - if (!wasm.features.hasExceptionHandling()) { +void handleBlockNestedPops(Function* func, Module& wasm, FeaturePolicy policy) { + if (policy == FeaturePolicy::SkipIfNoEH && + !wasm.features.hasExceptionHandling()) { return; } FindAll trys(func->body); diff --git a/src/ir/eh-utils.h b/src/ir/eh-utils.h index 79ccbc507..ee5ad661d 100644 --- a/src/ir/eh-utils.h +++ b/src/ir/eh-utils.h @@ -38,8 +38,14 @@ bool containsValidDanglingPop(Expression* catchBody); // '(local.get $new)' where the 'pop' used to be. void handleBlockNestedPop(Try* try_, Function* func, Module& wasm); -// Calls handleBlockNestedPop for each 'Try's in a given function. -void handleBlockNestedPops(Function* func, Module& wasm); +enum class FeaturePolicy { SkipIfNoEH, RunIfNoEH }; + +// Calls handleBlockNestedPop for each 'Try's in a given function. By default, +// does no work if EH is not enabled, but this can be overridden with the +// RunIfNoEH policy. +void handleBlockNestedPops(Function* func, + Module& wasm, + FeaturePolicy policy = FeaturePolicy::SkipIfNoEH); // Given a catch body, find the pop corresponding to the catch. There might be // pops nested inside a try inside this catch, and we must ignore them, like diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index fcb1fc48d..a51337cda 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -1018,7 +1018,10 @@ Result<> IRBuilder::visitEnd() { func->body = maybeWrapForLabel(*expr); labelDepths.clear(); if (scope.needsPopFixup()) { - EHUtils::handleBlockNestedPops(func, wasm); + // We may be in the binary parser, where pops need to be fixed up before + // we know that EH will be enabled. + EHUtils::handleBlockNestedPops( + func, wasm, EHUtils::FeaturePolicy::RunIfNoEH); } this->func = nullptr; blockHint = 0; -- cgit v1.2.3