From 71b9cc0b50b119988b7ad3a5f5d2feec4d6c4a95 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Thu, 30 Nov 2023 02:52:01 +0100 Subject: [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. --- src/parser/contexts.h | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) (limited to 'src/parser/contexts.h') 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, BlockTypeT) { return Ok{}; } + template + Result<> makeTry(Index, std::optional, 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 { return name; } - Result getLabelFromIdx(uint32_t idx) { return idx; } + Result getLabelFromIdx(uint32_t idx, bool) { return idx; } - Result getLabelFromName(Name name) { - return irBuilder.getLabelIndex(name); + Result getLabelFromName(Name name, bool inDelegate) { + return irBuilder.getLabelIndex(name, inDelegate); } Result getTagFromIdx(uint32_t idx) { @@ -1109,6 +1116,26 @@ struct ParseDefsCtx : TypeParserCtx { irBuilder.makeLoop(label ? *label : Name{}, type.getSignature().results)); } + Result<> makeTry(Index pos, std::optional 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) { -- cgit v1.2.3