diff options
Diffstat (limited to 'src/parser')
-rw-r--r-- | src/parser/contexts.h | 16 | ||||
-rw-r--r-- | src/parser/parsers.h | 17 |
2 files changed, 31 insertions, 2 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h index 7eedcccc2..862d9772d 100644 --- a/src/parser/contexts.h +++ b/src/parser/contexts.h @@ -279,6 +279,7 @@ struct NullInstrParserCtx { using GlobalIdxT = Ok; using MemoryIdxT = Ok; using DataIdxT = Ok; + using LabelIdxT = Ok; using MemargT = Ok; @@ -298,6 +299,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{}; } MemargT getMemarg(uint64_t, uint32_t) { return Ok{}; } @@ -370,7 +373,7 @@ struct NullInstrParserCtx { Result<> makeMemoryCopy(Index, MemoryIdxT*, MemoryIdxT*) { return Ok{}; } Result<> makeMemoryFill(Index, MemoryIdxT*) { return Ok{}; } - + Result<> makeBreak(Index, LabelIdxT) { return Ok{}; } Result<> makeReturn(Index) { return Ok{}; } template<typename HeapTypeT> Result<> makeRefNull(Index, HeapTypeT) { return Ok{}; @@ -793,6 +796,7 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { using FieldIdxT = Index; using LocalIdxT = Index; + using LabelIdxT = Index; using GlobalIdxT = Name; using MemoryIdxT = Name; using DataIdxT = Name; @@ -936,6 +940,12 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return name; } + Result<Index> getLabelFromIdx(uint32_t idx) { return idx; } + + Result<Index> getLabelFromName(Name name) { + return irBuilder.getLabelIndex(name); + } + Result<TypeUseT> makeTypeUse(Index pos, std::optional<HeapTypeT> type, ParamsT* params, @@ -1203,6 +1213,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> { return withLoc(pos, irBuilder.makeMemoryFill(*m)); } + Result<> makeBreak(Index pos, Index label) { + return withLoc(pos, irBuilder.makeBreak(label)); + } + Result<> makeReturn(Index pos) { return withLoc(pos, irBuilder.makeReturn()); } diff --git a/src/parser/parsers.h b/src/parser/parsers.h index 38005253f..32f6709df 100644 --- a/src/parser/parsers.h +++ b/src/parser/parsers.h @@ -177,6 +177,7 @@ template<typename Ctx> Result<typename Ctx::MemoryIdxT> memidx(Ctx&); template<typename Ctx> MaybeResult<typename Ctx::MemoryIdxT> maybeMemuse(Ctx&); template<typename Ctx> Result<typename Ctx::GlobalIdxT> globalidx(Ctx&); template<typename Ctx> Result<typename Ctx::LocalIdxT> localidx(Ctx&); +template<typename Ctx> Result<typename Ctx::LabelIdxT> labelidx(Ctx&); template<typename Ctx> Result<typename Ctx::TypeUseT> typeuse(Ctx&); MaybeResult<ImportNames> inlineImport(ParseInput&); Result<std::vector<Name>> inlineExports(ParseInput&); @@ -1195,7 +1196,9 @@ Result<> makeCallIndirect(Ctx& ctx, Index pos, bool isReturn) { } template<typename Ctx> Result<> makeBreak(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto label = labelidx(ctx); + CHECK_ERR(label); + return ctx.makeBreak(pos, *label); } template<typename Ctx> Result<> makeBreakTable(Ctx& ctx, Index pos) { @@ -1569,6 +1572,18 @@ template<typename Ctx> Result<typename Ctx::LocalIdxT> localidx(Ctx& ctx) { return ctx.in.err("expected local index or identifier"); } +// labelidx ::= x:u32 => x +// | v:id => x (if labels[x] = v) +template<typename Ctx> Result<typename Ctx::LabelIdxT> labelidx(Ctx& ctx) { + if (auto x = ctx.in.takeU32()) { + return ctx.getLabelFromIdx(*x); + } + if (auto id = ctx.in.takeID()) { + return ctx.getLabelFromName(*id); + } + return ctx.in.err("expected label index or identifier"); +} + // typeuse ::= '(' 'type' x:typeidx ')' => x, [] // (if typedefs[x] = [t1*] -> [t2*] // | '(' 'type' x:typeidx ')' ((t1,IDs):param)* (t2:result)* => x, IDs |