summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/contexts.h16
-rw-r--r--src/parser/parsers.h17
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