summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/contexts.h23
-rw-r--r--src/parser/parsers.h21
2 files changed, 41 insertions, 3 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index eb47dd502..e360a7175 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -280,6 +280,7 @@ struct NullInstrParserCtx {
using ExprT = Ok;
using FieldIdxT = Ok;
+ using FuncIdxT = Ok;
using LocalIdxT = Ok;
using GlobalIdxT = Ok;
using MemoryIdxT = Ok;
@@ -296,6 +297,8 @@ struct NullInstrParserCtx {
template<typename HeapTypeT> FieldIdxT getFieldFromName(HeapTypeT, Name) {
return Ok{};
}
+ FuncIdxT getFuncFromIdx(uint32_t) { return Ok{}; }
+ FuncIdxT getFuncFromName(Name) { return Ok{}; }
LocalIdxT getLocalFromIdx(uint32_t) { return Ok{}; }
LocalIdxT getLocalFromName(Name) { return Ok{}; }
GlobalIdxT getGlobalFromIdx(uint32_t) { return Ok{}; }
@@ -378,6 +381,7 @@ struct NullInstrParserCtx {
Result<> makeMemoryCopy(Index, MemoryIdxT*, MemoryIdxT*) { return Ok{}; }
Result<> makeMemoryFill(Index, MemoryIdxT*) { return Ok{}; }
+ Result<> makeCall(Index, FuncIdxT, bool) { return Ok{}; }
Result<> makeBreak(Index, LabelIdxT) { return Ok{}; }
Result<> makeReturn(Index) { return Ok{}; }
template<typename HeapTypeT> Result<> makeRefNull(Index, HeapTypeT) {
@@ -802,6 +806,7 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
using ExprT = Expression*;
using FieldIdxT = Index;
+ using FuncIdxT = Name;
using LocalIdxT = Index;
using LabelIdxT = Index;
using GlobalIdxT = Name;
@@ -895,6 +900,20 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
return idx;
}
+ Result<Name> getFuncFromIdx(uint32_t idx) {
+ if (idx >= wasm.functions.size()) {
+ return in.err("function index out of bounds");
+ }
+ return wasm.functions[idx]->name;
+ }
+
+ Result<Name> getFuncFromName(Name name) {
+ if (!wasm.getFunctionOrNull(name)) {
+ return in.err("function $" + name.toString() + " does not exist");
+ }
+ return name;
+ }
+
Result<Index> getLocalFromName(Name name) {
if (!func) {
return in.err("cannot access locals outside of a function");
@@ -1220,6 +1239,10 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
return withLoc(pos, irBuilder.makeMemoryFill(*m));
}
+ Result<> makeCall(Index pos, Name func, bool isReturn) {
+ return withLoc(pos, irBuilder.makeCall(func, isReturn));
+ }
+
Result<> makeBreak(Index pos, Index label) {
return withLoc(pos, irBuilder.makeBreak(label));
}
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 3a4f9c212..7ac25def4 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -173,6 +173,7 @@ template<typename Ctx> MaybeResult<Index> maybeTypeidx(Ctx& ctx);
template<typename Ctx> Result<typename Ctx::HeapTypeT> typeidx(Ctx&);
template<typename Ctx>
Result<typename Ctx::FieldIdxT> fieldidx(Ctx&, typename Ctx::HeapTypeT);
+template<typename Ctx> Result<typename Ctx::FuncIdxT> funcidx(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::MemoryIdxT> maybeMemidx(Ctx&);
template<typename Ctx> Result<typename Ctx::MemoryIdxT> memidx(Ctx&);
template<typename Ctx> MaybeResult<typename Ctx::MemoryIdxT> maybeMemuse(Ctx&);
@@ -1205,7 +1206,9 @@ template<typename Ctx> Result<> makeLoop(Ctx& ctx, Index pos) {
}
template<typename Ctx> Result<> makeCall(Ctx& ctx, Index pos, bool isReturn) {
- return ctx.in.err("unimplemented instruction");
+ auto func = funcidx(ctx);
+ CHECK_ERR(func);
+ return ctx.makeCall(pos, *func, isReturn);
}
template<typename Ctx>
@@ -1509,8 +1512,8 @@ template<typename Ctx> Result<typename Ctx::HeapTypeT> typeidx(Ctx& ctx) {
return ctx.in.err("expected type index or identifier");
}
-// fieldidx_t ::= x:u32 => x
-// | v:id => x (if t.fields[x] = v)
+// fieldidx ::= x:u32 => x
+// | v:id => x (if t.fields[x] = v)
template<typename Ctx>
Result<typename Ctx::FieldIdxT> fieldidx(Ctx& ctx,
typename Ctx::HeapTypeT type) {
@@ -1523,6 +1526,18 @@ Result<typename Ctx::FieldIdxT> fieldidx(Ctx& ctx,
return ctx.in.err("expected field index or identifier");
}
+// funcidx ::= x:u32 => x
+// | v:id => x (if t.funcs[x] = v)
+template<typename Ctx> Result<typename Ctx::FuncIdxT> funcidx(Ctx& ctx) {
+ if (auto x = ctx.in.takeU32()) {
+ return ctx.getFuncFromIdx(*x);
+ }
+ if (auto id = ctx.in.takeID()) {
+ return ctx.getFuncFromName(*id);
+ }
+ return ctx.in.err("expected function index or identifier");
+}
+
// memidx ::= x:u32 => x
// | v:id => x (if memories[x] = v)
template<typename Ctx>