diff options
author | Thomas Lively <tlively@google.com> | 2023-10-02 16:09:05 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-02 16:09:05 -0700 |
commit | 0fe08192d866f72d0f4e680c862bb7af48dec1ac (patch) | |
tree | a37b814de2ab85a64612ea112b6303776a44bfa7 /src/parser/parsers.h | |
parent | 77f36789aac707d1d5daed20e6e7612c9a9af51b (diff) | |
download | binaryen-0fe08192d866f72d0f4e680c862bb7af48dec1ac.tar.gz binaryen-0fe08192d866f72d0f4e680c862bb7af48dec1ac.tar.bz2 binaryen-0fe08192d866f72d0f4e680c862bb7af48dec1ac.zip |
[Parser] Parse labels and br (#5970)
The parser previously parsed labels and could attach them to control flow
structures, but did not maintain the context necessary to correctly parse
branches. Support parsing labels as both names and indices in IRBuilder,
handling shadowing correctly, and use that support to implement parsing of br.
Diffstat (limited to 'src/parser/parsers.h')
-rw-r--r-- | src/parser/parsers.h | 17 |
1 files changed, 16 insertions, 1 deletions
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 |