diff options
author | Thomas Lively <tlively@google.com> | 2024-12-13 13:23:42 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-12-13 13:23:42 -0800 |
commit | 8a88ba280b2847d4d25d0859a87529e2132ebab8 (patch) | |
tree | a4723dbd4f43b1b01b8bcc3bcdbf5f80f7d93d4a /src/parser/contexts.h | |
parent | 52bc45fc34ec6868400216074744147e9d922685 (diff) | |
download | binaryen-8a88ba280b2847d4d25d0859a87529e2132ebab8.tar.gz binaryen-8a88ba280b2847d4d25d0859a87529e2132ebab8.tar.bz2 binaryen-8a88ba280b2847d4d25d0859a87529e2132ebab8.zip |
Support control flow inputs in IRBuilder (#7149)
Since multivalue was standardized, WebAssembly has supported not only
multiple results but also an arbitrary number of inputs on control flow
structures, but until now Binaryen did not support control flow input.
Binaryen IR still has no way to represent control flow input, so lower
it away using scratch locals in IRBuilder. Since both the text and
binary parsers use IRBuilder, this gives us full support for parsing
control flow inputs.
The lowering scheme is mostly simple. A local.set writing the control
flow inputs to a scratch local is inserted immediately before the
control flow structure begins and a local.get retrieving those inputs is
inserted inside the control flow structure before the rest of its body.
The only complications come from ifs, in which the inputs must be
retrieved at the beginning of both arms, and from loops, where branches
to the beginning of the loop must be transformed so their values are
written to the scratch local along the way.
Resolves #6407.
Diffstat (limited to 'src/parser/contexts.h')
-rw-r--r-- | src/parser/contexts.h | 45 |
1 files changed, 22 insertions, 23 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 807b6c003..3e0bc7c40 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -1447,11 +1447,7 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { Result<HeapType> getBlockTypeFromTypeUse(Index pos, HeapType type) { assert(type.isSignature()); - if (type.getSignature().params != Type::none) { - return in.err(pos, "block parameters not yet supported"); - } - // TODO: Once we support block parameters, return an error here if any of - // them are named. + // TODO: Error if block parameters are named return type; } @@ -1822,9 +1818,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { HeapType type) { // TODO: validate labels? // TODO: Move error on input types to here? - return withLoc(pos, - irBuilder.makeBlock(label ? *label : Name{}, - type.getSignature().results)); + if (!type.isSignature()) { + return in.err(pos, "expected function type"); + } + return withLoc( + pos, irBuilder.makeBlock(label ? *label : Name{}, type.getSignature())); } Result<> makeIf(Index pos, @@ -1832,10 +1830,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { std::optional<Name> label, HeapType type) { // TODO: validate labels? - // TODO: Move error on input types to here? + if (!type.isSignature()) { + return in.err(pos, "expected function type"); + } return withLoc( - pos, - irBuilder.makeIf(label ? *label : Name{}, type.getSignature().results)); + pos, irBuilder.makeIf(label ? *label : Name{}, type.getSignature())); } Result<> visitElse() { return withLoc(irBuilder.visitElse()); } @@ -1845,10 +1844,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { std::optional<Name> label, HeapType type) { // TODO: validate labels? - // TODO: Move error on input types to here? + if (!type.isSignature()) { + return in.err(pos, "expected function type"); + } return withLoc( - pos, - irBuilder.makeLoop(label ? *label : Name{}, type.getSignature().results)); + pos, irBuilder.makeLoop(label ? *label : Name{}, type.getSignature())); } Result<> makeTry(Index pos, @@ -1856,10 +1856,11 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { std::optional<Name> label, HeapType type) { // TODO: validate labels? - // TODO: Move error on input types to here? + if (!type.isSignature()) { + return in.err(pos, "expected function type"); + } return withLoc( - pos, - irBuilder.makeTry(label ? *label : Name{}, type.getSignature().results)); + pos, irBuilder.makeTry(label ? *label : Name{}, type.getSignature())); } Result<> makeTryTable(Index pos, @@ -1875,12 +1876,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { labels.push_back(info.label); isRefs.push_back(info.isRef); } - return withLoc(pos, - irBuilder.makeTryTable(label ? *label : Name{}, - type.getSignature().results, - tags, - labels, - isRefs)); + return withLoc( + pos, + irBuilder.makeTryTable( + label ? *label : Name{}, type.getSignature(), tags, labels, isRefs)); } Result<> visitCatch(Index pos, Name tag) { |