summaryrefslogtreecommitdiff
path: root/src/parser/contexts.h
diff options
context:
space:
mode:
authorThomas Lively <tlively@google.com>2023-11-30 02:52:01 +0100
committerGitHub <noreply@github.com>2023-11-29 17:52:01 -0800
commit71b9cc0b50b119988b7ad3a5f5d2feec4d6c4a95 (patch)
tree70a560571537f51d78b75f7804259b8881d368bc /src/parser/contexts.h
parent24742589f5471a5e72755d8fe1da9e49923a35ff (diff)
downloadbinaryen-71b9cc0b50b119988b7ad3a5f5d2feec4d6c4a95.tar.gz
binaryen-71b9cc0b50b119988b7ad3a5f5d2feec4d6c4a95.tar.bz2
binaryen-71b9cc0b50b119988b7ad3a5f5d2feec4d6c4a95.zip
[Parser] Parse try/catch/catch_all/delegate (#6128)
Parse the legacy v3 syntax for try/catch/catch_all/delegate in both its folded and unfolded forms. The first sources of significant complexity is the optional IDs after `catch` and `catch_all` in the unfolded form, which can be confused for tag indices and require backtracking to parse correctly. The second source of complexity is the handling of delegate labels, which are relative to the try's parent scope despite being parsed after the try's scope has already started. Handling this correctly requires punching a whole big enough to drive a truck through through both the parser and IRBuilder abstractions.
Diffstat (limited to 'src/parser/contexts.h')
-rw-r--r--src/parser/contexts.h37
1 files changed, 32 insertions, 5 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index ed4d1283c..adb7694f6 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -308,8 +308,8 @@ struct NullInstrParserCtx {
MemoryIdxT getMemoryFromName(Name) { return Ok{}; }
DataIdxT getDataFromIdx(uint32_t) { return Ok{}; }
DataIdxT getDataFromName(Name) { return Ok{}; }
- LabelIdxT getLabelFromIdx(uint32_t) { return Ok{}; }
- LabelIdxT getLabelFromName(Name) { return Ok{}; }
+ LabelIdxT getLabelFromIdx(uint32_t, bool) { return Ok{}; }
+ LabelIdxT getLabelFromName(Name, bool) { return Ok{}; }
TagIdxT getTagFromIdx(uint32_t) { return Ok{}; }
TagIdxT getTagFromName(Name) { return Ok{}; }
@@ -328,6 +328,13 @@ struct NullInstrParserCtx {
Result<> makeLoop(Index, std::optional<Name>, BlockTypeT) {
return Ok{};
}
+ template<typename BlockTypeT>
+ Result<> makeTry(Index, std::optional<Name>, BlockTypeT) {
+ return Ok{};
+ }
+ Result<> visitCatch(Index, TagIdxT) { return Ok{}; }
+ Result<> visitCatchAll(Index) { return Ok{}; }
+ Result<> visitDelegate(Index, LabelIdxT) { return Ok{}; }
Result<> visitEnd() { return Ok{}; }
Result<> makeUnreachable(Index) { return Ok{}; }
@@ -1020,10 +1027,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
return name;
}
- Result<Index> getLabelFromIdx(uint32_t idx) { return idx; }
+ Result<Index> getLabelFromIdx(uint32_t idx, bool) { return idx; }
- Result<Index> getLabelFromName(Name name) {
- return irBuilder.getLabelIndex(name);
+ Result<Index> getLabelFromName(Name name, bool inDelegate) {
+ return irBuilder.getLabelIndex(name, inDelegate);
}
Result<Name> getTagFromIdx(uint32_t idx) {
@@ -1109,6 +1116,26 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
irBuilder.makeLoop(label ? *label : Name{}, type.getSignature().results));
}
+ Result<> makeTry(Index pos, std::optional<Name> label, HeapType type) {
+ // TODO: validate labels?
+ // TODO: Move error on input types to here?
+ return withLoc(
+ pos,
+ irBuilder.makeTry(label ? *label : Name{}, type.getSignature().results));
+ }
+
+ Result<> visitCatch(Index pos, Name tag) {
+ return withLoc(pos, irBuilder.visitCatch(tag));
+ }
+
+ Result<> visitCatchAll(Index pos) {
+ return withLoc(pos, irBuilder.visitCatchAll());
+ }
+
+ Result<> visitDelegate(Index pos, Index label) {
+ return withLoc(pos, irBuilder.visitDelegate(label));
+ }
+
Result<> visitEnd() { return withLoc(irBuilder.visitEnd()); }
Result<> makeUnreachable(Index pos) {