From 2e82e3ea352b9f4c2432252797c47516b9770eb2 Mon Sep 17 00:00:00 2001 From: Thomas Lively Date: Tue, 18 Oct 2022 19:07:00 -0500 Subject: [Parser] Parse global.get and global.set (#5155) Also add some missing error checking for the similar local instructions and make some neighboring styling more consistent. --- src/wasm/wat-parser.cpp | 90 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 75 insertions(+), 15 deletions(-) (limited to 'src/wasm/wat-parser.cpp') diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp index e17701094..0114d9477 100644 --- a/src/wasm/wat-parser.cpp +++ b/src/wasm/wat-parser.cpp @@ -558,6 +558,7 @@ struct NullInstrParserCtx { using ExprT = Ok; using LocalT = Ok; + using GlobalT = Ok; InstrsT makeInstrs() { return Ok{}; } void appendInstr(InstrsT&, InstrT) {} @@ -565,26 +566,31 @@ struct NullInstrParserCtx { ExprT makeExpr(InstrsT) { return Ok{}; } - LocalT getLocalFromIdx(uint32_t idx) { return Ok{}; } - LocalT getLocalFromName(Name name) { return Ok{}; } + LocalT getLocalFromIdx(uint32_t) { return Ok{}; } + LocalT getLocalFromName(Name) { return Ok{}; } + GlobalT getGlobalFromIdx(uint32_t) { return Ok{}; } + GlobalT getGlobalFromName(Name) { return Ok{}; } - InstrT makeUnreachable(Index pos) { return Ok{}; } - InstrT makeNop(Index pos) { return Ok{}; } - InstrT makeBinary(Index pos, BinaryOp op) { return Ok{}; } - InstrT makeUnary(Index pos, UnaryOp op) { return Ok{}; } - template InstrT makeSelect(Index pos, ResultsT* res) { + InstrT makeUnreachable(Index) { return Ok{}; } + InstrT makeNop(Index) { return Ok{}; } + InstrT makeBinary(Index, BinaryOp) { return Ok{}; } + InstrT makeUnary(Index, UnaryOp) { return Ok{}; } + template InstrT makeSelect(Index, ResultsT*) { return Ok{}; } - InstrT makeDrop(Index pos) { return Ok{}; } + InstrT makeDrop(Index) { return Ok{}; } InstrT makeI32Const(Index, uint32_t) { return Ok{}; } InstrT makeI64Const(Index, uint64_t) { return Ok{}; } InstrT makeF32Const(Index, float) { return Ok{}; } InstrT makeF64Const(Index, double) { return Ok{}; } - InstrT makeLocalGet(Index pos, LocalT local) { return Ok{}; } - InstrT makeLocalTee(Index pos, LocalT local) { return Ok{}; } - InstrT makeLocalSet(Index pos, LocalT local) { return Ok{}; } + InstrT makeLocalGet(Index, LocalT) { return Ok{}; } + InstrT makeLocalTee(Index, LocalT) { return Ok{}; } + InstrT makeLocalSet(Index, LocalT) { return Ok{}; } + + InstrT makeGlobalGet(Index, GlobalT) { return Ok{}; } + InstrT makeGlobalSet(Index, GlobalT) { return Ok{}; } template InstrT makeRefNull(Index, HeapTypeT) { return {}; @@ -599,6 +605,7 @@ template struct InstrParserCtx : TypeParserCtx { using ExprT = Expression*; using LocalT = Index; + using GlobalT = Name; Builder builder; @@ -1167,7 +1174,16 @@ struct ParseDefsCtx : InstrParserCtx { return types[idx]; } - Index getLocalFromIdx(uint32_t idx) { return idx; } + Result getLocalFromIdx(uint32_t idx) { + if (!func) { + return in.err("cannot access locals outside of a funcion"); + } + if (idx >= func->getNumLocals()) { + return in.err("local index out of bounds"); + } + return idx; + } + Result getLocalFromName(Name name) { if (!func) { return in.err("cannot access locals outside of a function"); @@ -1178,6 +1194,20 @@ struct ParseDefsCtx : InstrParserCtx { return func->getLocalIndex(name); } + Result getGlobalFromIdx(uint32_t idx) { + if (idx >= wasm.globals.size()) { + return in.err("global index out of bounds"); + } + return wasm.globals[idx]->name; + } + + Result getGlobalFromName(Name name) { + if (!wasm.getGlobalOrNull(name)) { + return in.err("global $" + name.toString() + " does not exist"); + } + return name; + } + Result makeTypeUse(Index pos, std::optional type, ParamsT* params, @@ -1285,6 +1315,19 @@ struct ParseDefsCtx : InstrParserCtx { CHECK_ERR(val); return push(pos, builder.makeLocalSet(local, *val)); } + + Result<> makeGlobalGet(Index pos, Name global) { + assert(wasm.getGlobalOrNull(global)); + auto type = wasm.getGlobal(global)->type; + return push(pos, builder.makeGlobalGet(global, type)); + } + + Result<> makeGlobalSet(Index pos, Name global) { + assert(wasm.getGlobalOrNull(global)); + auto val = pop(pos); + CHECK_ERR(val); + return push(pos, builder.makeGlobalSet(global, *val)); + } }; // ================ @@ -1463,6 +1506,7 @@ Result makeStringSliceIter(Ctx&, Index); // Modules template MaybeResult maybeTypeidx(Ctx& ctx); template Result typeidx(Ctx&); +template Result globalidx(Ctx&); template Result localidx(Ctx&); template Result typeuse(Ctx&); MaybeResult inlineImport(ParseInput&); @@ -1922,12 +1966,16 @@ Result makeLocalSet(Ctx& ctx, Index pos) { template Result makeGlobalGet(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto global = globalidx(ctx); + CHECK_ERR(global); + return ctx.makeGlobalGet(pos, *global); } template Result makeGlobalSet(Ctx& ctx, Index pos) { - return ctx.in.err("unimplemented instruction"); + auto global = globalidx(ctx); + CHECK_ERR(global); + return ctx.makeGlobalSet(pos, *global); } template @@ -2402,8 +2450,20 @@ template Result typeidx(Ctx& ctx) { return ctx.in.err("expected type index or identifier"); } +// globalidx ::= x:u32 => x +// | v:id => x (if globals[x] = v) +template Result globalidx(Ctx& ctx) { + if (auto x = ctx.in.takeU32()) { + return ctx.getGlobalFromIdx(*x); + } + if (auto id = ctx.in.takeID()) { + return ctx.getGlobalFromName(*id); + } + return ctx.in.err("expected global index or identifier"); +} + // localidx ::= x:u32 => x -// | v:id => x (if types[x] = v) +// | v:id => x (if locals[x] = v) template Result localidx(Ctx& ctx) { if (auto x = ctx.in.takeU32()) { return ctx.getLocalFromIdx(*x); -- cgit v1.2.3