diff --git a/src/parser/parsers.h b/src/parser/parsers.h index bcae62e14f7..bbb50b6647d 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -330,6 +330,9 @@ template Result elemidx(Ctx&); template Result dataidx(Ctx&); template Result localidx(Ctx&); template +MaybeResult maybeLabelidx(Ctx&, + bool inDelegate = false); +template Result labelidx(Ctx&, bool inDelegate = false); template Result tagidx(Ctx&); template Result typeuse(Ctx&); @@ -1969,16 +1972,18 @@ Result<> makeBreakTable(Ctx& ctx, Index pos, const std::vector& annotations) { std::vector labels; + // Parse at least one label; return an error only if we parse none. while (true) { - // Parse at least one label; return an error only if we parse none. - auto label = labelidx(ctx); - if (labels.empty()) { - CHECK_ERR(label); - } else if (label.getErr()) { + auto label = maybeLabelidx(ctx); + if (!label) { break; } + CHECK_ERR(label); labels.push_back(*label); } + if (labels.empty()) { + return ctx.in.err("expected label"); + } auto defaultLabel = labels.back(); labels.pop_back(); return ctx.makeSwitch(pos, annotations, labels, defaultLabel); @@ -2701,17 +2706,26 @@ template Result localidx(Ctx& ctx) { return ctx.in.err("expected local index or identifier"); } +template +Result labelidx(Ctx& ctx, bool inDelegate) { + if (auto idx = maybeLabelidx(ctx, inDelegate)) { + CHECK_ERR(idx); + return *idx; + } + return ctx.in.err("expected label index or identifier"); +} + // labelidx ::= x:u32 => x // | v:id => x (if labels[x] = v) template -Result labelidx(Ctx& ctx, bool inDelegate) { +MaybeResult maybeLabelidx(Ctx& ctx, bool inDelegate) { if (auto x = ctx.in.takeU32()) { return ctx.getLabelFromIdx(*x, inDelegate); } if (auto id = ctx.in.takeID()) { return ctx.getLabelFromName(*id, inDelegate); } - return ctx.in.err("expected label index or identifier"); + return {}; } // tagidx ::= x:u32 => x