@@ -60,6 +60,8 @@ template<typename Ctx> MaybeResult<> block(Ctx&, bool);
6060template <typename Ctx> MaybeResult<> ifelse (Ctx&, bool );
6161template <typename Ctx> MaybeResult<> loop (Ctx&, bool );
6262template <typename Ctx> MaybeResult<> trycatch (Ctx&, bool );
63+ template <typename Ctx> MaybeResult<typename Ctx::CatchT> catchinstr (Ctx&);
64+ template <typename Ctx> MaybeResult<> trytable (Ctx&, bool );
6365template <typename Ctx> Result<> makeUnreachable (Ctx&, Index);
6466template <typename Ctx> Result<> makeNop (Ctx&, Index);
6567template <typename Ctx> Result<> makeBinary (Ctx&, Index, BinaryOp op);
@@ -657,7 +659,7 @@ template<typename Ctx> Result<uint32_t> tupleArity(Ctx& ctx) {
657659// Instructions
658660// ============
659661
660- // blockinstr ::= block | loop | if-else | try-catch
662+ // blockinstr ::= block | loop | if-else | try-catch | try_table
661663template <typename Ctx> MaybeResult<> foldedBlockinstr (Ctx& ctx) {
662664 if (auto i = block (ctx, true )) {
663665 return i;
@@ -671,7 +673,9 @@ template<typename Ctx> MaybeResult<> foldedBlockinstr(Ctx& ctx) {
671673 if (auto i = trycatch (ctx, true )) {
672674 return i;
673675 }
674- // TODO: Other block instructions
676+ if (auto i = trytable (ctx, true )) {
677+ return i;
678+ }
675679 return {};
676680}
677681
@@ -688,7 +692,9 @@ template<typename Ctx> MaybeResult<> unfoldedBlockinstr(Ctx& ctx) {
688692 if (auto i = trycatch (ctx, false )) {
689693 return i;
690694 }
691- // TODO: Other block instructions
695+ if (auto i = trytable (ctx, false )) {
696+ return i;
697+ }
692698 return {};
693699}
694700
@@ -1159,6 +1165,81 @@ template<typename Ctx> MaybeResult<> trycatch(Ctx& ctx, bool folded) {
11591165 return ctx.visitEnd ();
11601166}
11611167
1168+ template <typename Ctx> MaybeResult<typename Ctx::CatchT> catchinstr (Ctx& ctx) {
1169+ typename Ctx::CatchT result;
1170+ if (ctx.in .takeSExprStart (" catch" sv)) {
1171+ auto tag = tagidx (ctx);
1172+ CHECK_ERR (tag);
1173+ auto label = labelidx (ctx);
1174+ CHECK_ERR (label);
1175+ result = ctx.makeCatch (*tag, *label);
1176+ } else if (ctx.in .takeSExprStart (" catch_ref" sv)) {
1177+ auto tag = tagidx (ctx);
1178+ CHECK_ERR (tag);
1179+ auto label = labelidx (ctx);
1180+ CHECK_ERR (label);
1181+ result = ctx.makeCatchRef (*tag, *label);
1182+ } else if (ctx.in .takeSExprStart (" catch_all" sv)) {
1183+ auto label = labelidx (ctx);
1184+ CHECK_ERR (label);
1185+ result = ctx.makeCatchAll (*label);
1186+ } else if (ctx.in .takeSExprStart (" catch_all_ref" sv)) {
1187+ auto label = labelidx (ctx);
1188+ CHECK_ERR (label);
1189+ result = ctx.makeCatchAllRef (*label);
1190+ } else {
1191+ return {};
1192+ }
1193+
1194+ if (!ctx.in .takeRParen ()) {
1195+ return ctx.in .err (" expected ')' at end of catch clause" );
1196+ }
1197+
1198+ return result;
1199+ }
1200+
1201+ // trytable ::= 'try_table' label blocktype catchinstr* instr* end id?
1202+ // | '(' 'try_table' label blocktype catchinstr* instr* ')'
1203+ template <typename Ctx> MaybeResult<> trytable (Ctx& ctx, bool folded) {
1204+ auto pos = ctx.in .getPos ();
1205+
1206+ if ((folded && !ctx.in .takeSExprStart (" try_table" sv)) ||
1207+ (!folded && !ctx.in .takeKeyword (" try_table" sv))) {
1208+ return {};
1209+ }
1210+
1211+ auto label = ctx.in .takeID ();
1212+
1213+ auto type = blocktype (ctx);
1214+ CHECK_ERR (type);
1215+
1216+ auto catches = ctx.makeCatchList ();
1217+ while (auto c = catchinstr (ctx)) {
1218+ CHECK_ERR (c);
1219+ ctx.appendCatch (catches, *c);
1220+ }
1221+
1222+ CHECK_ERR (ctx.makeTryTable (pos, label, *type, catches));
1223+
1224+ CHECK_ERR (instrs (ctx));
1225+
1226+ if (folded) {
1227+ if (!ctx.in .takeRParen ()) {
1228+ return ctx.in .err (" expected ')' at end of try_table" );
1229+ }
1230+ } else {
1231+ if (!ctx.in .takeKeyword (" end" sv)) {
1232+ return ctx.in .err (" expected 'end' at end of try_table" );
1233+ }
1234+
1235+ auto id = ctx.in .takeID ();
1236+ if (id && id != label) {
1237+ return ctx.in .err (" end label does not match try_table label" );
1238+ }
1239+ }
1240+ return ctx.visitEnd ();
1241+ }
1242+
11621243template <typename Ctx> Result<> makeUnreachable (Ctx& ctx, Index pos) {
11631244 return ctx.makeUnreachable (pos);
11641245}
0 commit comments