diff options
author | Thomas Lively <tlively@google.com> | 2023-09-18 18:40:00 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-19 01:40:00 +0000 |
commit | 8c5bb9b8a0b150ebab0d0dec545206b055de9564 (patch) | |
tree | 9851b38ef65a1634f451697638728d6e36bd714a /src | |
parent | 452e50747ed397fe17c69dd428387b949feaa05d (diff) | |
download | binaryen-8c5bb9b8a0b150ebab0d0dec545206b055de9564.tar.gz binaryen-8c5bb9b8a0b150ebab0d0dec545206b055de9564.tar.bz2 binaryen-8c5bb9b8a0b150ebab0d0dec545206b055de9564.zip |
Fix visitBlock and add visitBlockStart in IRBuilder (#5959)
Visiting a block should push it onto the stack just like visiting any other
expression, but we previously had a `visitBlock` that introduced a new scope
instead. Fix `visitBlock` to behave as expected and introduce a new
`visitBlockStart` method to introduce a new scope.
Unfortunately this cannot be fully tested yet because the wat parser uses the
`makeXYZ` API intead of the `visit` API, but at least I updated `makeBlock` to
call `visitBlockStart`, so that is tested.
Diffstat (limited to 'src')
-rw-r--r-- | src/wasm-ir-builder.h | 19 | ||||
-rw-r--r-- | src/wasm/wasm-ir-builder.cpp | 9 |
2 files changed, 19 insertions, 9 deletions
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h index 50c034897..1a19f62e8 100644 --- a/src/wasm-ir-builder.h +++ b/src/wasm-ir-builder.h @@ -45,15 +45,13 @@ public: [[nodiscard]] Result<Expression*> build(); // Call visit() on an existing Expression with its non-child fields - // initialized to initialize the child fields and refinalize it. The specific - // visitors are internal implementation details. + // initialized to initialize the child fields and refinalize it. [[nodiscard]] Result<> visit(Expression*); - [[nodiscard]] Result<> visitExpression(Expression*); - [[nodiscard]] Result<> visitBlock(Block*); - [[nodiscard]] Result<> visitReturn(Return*); - [[nodiscard]] Result<> visitStructNew(StructNew*); - [[nodiscard]] Result<> visitArrayNew(ArrayNew*); + // Handle the boundaries of control flow structures. Users may choose to use + // the corresponding `makeXYZ` function below instead of `visitXYZStart`, but + // either way must call `visitEnd` and friends at the appropriate times. + [[nodiscard]] Result<> visitBlockStart(Block* block); [[nodiscard]] Result<> visitEnd(); // Alternatively, call makeXYZ to have the IRBuilder allocate the nodes. This @@ -171,6 +169,13 @@ public: void setFunction(Function* func) { this->func = func; } + // Private functions that must be public for technical reasons. + [[nodiscard]] Result<> visitExpression(Expression*); + [[nodiscard]] Result<> visitBlock(Block*); + [[nodiscard]] Result<> visitReturn(Return*); + [[nodiscard]] Result<> visitStructNew(StructNew*); + [[nodiscard]] Result<> visitArrayNew(ArrayNew*); + private: Module& wasm; Function* func; diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp index 6445cc3c9..bc3180423 100644 --- a/src/wasm/wasm-ir-builder.cpp +++ b/src/wasm/wasm-ir-builder.cpp @@ -233,7 +233,7 @@ Result<> IRBuilder::visitExpression(Expression* curr) { } Result<> IRBuilder::visitBlock(Block* curr) { - scopeStack.push_back({{}, curr}); + // No children; pushing and finalizing will be handled by `visit`. return Ok{}; } @@ -281,6 +281,11 @@ Result<> IRBuilder::visitArrayNew(ArrayNew* curr) { return Ok{}; } +Result<> IRBuilder::visitBlockStart(Block* curr) { + scopeStack.push_back({{}, curr}); + return Ok{}; +} + Result<> IRBuilder::visitEnd() { if (scopeStack.empty() || !scopeStack.back().block) { return Err{"unexpected end"}; @@ -347,7 +352,7 @@ Result<> IRBuilder::makeBlock(Name label, Type type) { auto* block = wasm.allocator.alloc<Block>(); block->name = label; block->type = type; - scopeStack.push_back({{}, block}); + CHECK_ERR(visitBlockStart(block)); return Ok{}; } |