diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/passes/StripEH.cpp | 78 | ||||
-rw-r--r-- | src/passes/pass.cpp | 1 | ||||
-rw-r--r-- | src/passes/passes.h | 1 |
4 files changed, 81 insertions, 0 deletions
diff --git a/src/passes/CMakeLists.txt b/src/passes/CMakeLists.txt index 9d16f9782..4cf28fa65 100644 --- a/src/passes/CMakeLists.txt +++ b/src/passes/CMakeLists.txt @@ -110,6 +110,7 @@ set(passes_SOURCES Souperify.cpp SpillPointers.cpp StackCheck.cpp + StripEH.cpp SSAify.cpp Untee.cpp Vacuum.cpp diff --git a/src/passes/StripEH.cpp b/src/passes/StripEH.cpp new file mode 100644 index 000000000..d2a68d630 --- /dev/null +++ b/src/passes/StripEH.cpp @@ -0,0 +1,78 @@ +/* + * Copyright 2023 WebAssembly Community Group participants + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// +// Removes all EH instructions and tags. Removes catch blocks and converts +// 'throw's into 'unreachable's. Any exception thrown will crash the program as +// they are now traps. +// + +#include <ir/drop.h> +#include <ir/utils.h> + +namespace wasm { + +namespace { + +struct StripEHImpl : public WalkerPass<PostWalker<StripEHImpl>> { + bool isFunctionParallel() override { return true; } + + bool refinalize = false; + + std::unique_ptr<Pass> create() override { + return std::make_unique<StripEHImpl>(); + } + + void visitThrow(Throw* curr) { + auto& wasm = *getModule(); + Builder builder(wasm); + replaceCurrent(getDroppedChildrenAndAppend(curr, + wasm, + getPassOptions(), + builder.makeUnreachable(), + DropMode::IgnoreParentEffects)); + } + + void visitTry(Try* curr) { + replaceCurrent(curr->body); + refinalize = true; + } + + void visitFunction(Function* curr) { + if (refinalize) { + ReFinalize().walkFunctionInModule(curr, getModule()); + } + } +}; + +struct StripEH : public Pass { + void run(Module* wasm) override { + PassRunner runner(wasm); + // We run this as an inner pass to make it parallel. This StripEH pass + // itself cannot be parallel because we need to disable the EH feature. + runner.add(std::make_unique<StripEHImpl>()); + runner.setIsNested(true); + runner.run(); + wasm->removeTags([](Tag*) { return true; }); + wasm->features.disable(FeatureSet::ExceptionHandling); + } +}; + +} // anonymous namespace + +Pass* createStripEHPass() { return new StripEH(); } + +} // namespace wasm diff --git a/src/passes/pass.cpp b/src/passes/pass.cpp index ff2c7d45f..0411dcc75 100644 --- a/src/passes/pass.cpp +++ b/src/passes/pass.cpp @@ -464,6 +464,7 @@ void PassRegistry::registerPasses() { registerPass("strip-producers", "strip the wasm producers section", createStripProducersPass); + registerPass("strip-eh", "strip EH instructions", createStripEHPass); registerPass("strip-target-features", "strip the wasm target features section", createStripTargetFeaturesPass); diff --git a/src/passes/passes.h b/src/passes/passes.h index 346741b1a..d8855d4a8 100644 --- a/src/passes/passes.h +++ b/src/passes/passes.h @@ -145,6 +145,7 @@ Pass* createStripTargetFeaturesPass(); Pass* createSouperifyPass(); Pass* createSouperifySingleUsePass(); Pass* createSpillPointersPass(); +Pass* createStripEHPass(); Pass* createStubUnsupportedJSOpsPass(); Pass* createSSAifyPass(); Pass* createSSAifyNoMergePass(); |