summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/parser/contexts.h44
-rw-r--r--src/parser/parsers.h29
-rw-r--r--src/wasm-ir-builder.h12
-rw-r--r--src/wasm.h2
-rw-r--r--src/wasm/wasm-ir-builder.cpp42
-rw-r--r--test/lit/wat-kitchen-sink.wast167
6 files changed, 279 insertions, 17 deletions
diff --git a/src/parser/contexts.h b/src/parser/contexts.h
index 396b115bf..7ce5bbf96 100644
--- a/src/parser/contexts.h
+++ b/src/parser/contexts.h
@@ -411,6 +411,12 @@ struct NullInstrParserCtx {
Result<> makeRefIsNull(Index) { return Ok{}; }
Result<> makeRefFunc(Index, FuncIdxT) { return Ok{}; }
Result<> makeRefEq(Index) { return Ok{}; }
+ Result<> makeTableGet(Index, TableIdxT*) { return Ok{}; }
+ Result<> makeTableSet(Index, TableIdxT*) { return Ok{}; }
+ Result<> makeTableSize(Index, TableIdxT*) { return Ok{}; }
+ Result<> makeTableGrow(Index, TableIdxT*) { return Ok{}; }
+ Result<> makeTableFill(Index, TableIdxT*) { return Ok{}; }
+ Result<> makeTableCopy(Index, TableIdxT*, TableIdxT*) { return Ok{}; }
Result<> makeThrow(Index, TagIdxT) { return Ok{}; }
template<typename HeapTypeT> Result<> makeCallRef(Index, HeapTypeT, bool) {
return Ok{};
@@ -1524,6 +1530,44 @@ struct ParseDefsCtx : TypeParserCtx<ParseDefsCtx> {
Result<> makeRefEq(Index pos) { return withLoc(pos, irBuilder.makeRefEq()); }
+ Result<> makeTableGet(Index pos, Name* table) {
+ auto t = getTable(pos, table);
+ CHECK_ERR(t);
+ return withLoc(pos, irBuilder.makeTableGet(*t));
+ }
+
+ Result<> makeTableSet(Index pos, Name* table) {
+ auto t = getTable(pos, table);
+ CHECK_ERR(t);
+ return withLoc(pos, irBuilder.makeTableSet(*t));
+ }
+
+ Result<> makeTableSize(Index pos, Name* table) {
+ auto t = getTable(pos, table);
+ CHECK_ERR(t);
+ return withLoc(pos, irBuilder.makeTableSize(*t));
+ }
+
+ Result<> makeTableGrow(Index pos, Name* table) {
+ auto t = getTable(pos, table);
+ CHECK_ERR(t);
+ return withLoc(pos, irBuilder.makeTableGrow(*t));
+ }
+
+ Result<> makeTableFill(Index pos, Name* table) {
+ auto t = getTable(pos, table);
+ CHECK_ERR(t);
+ return withLoc(pos, irBuilder.makeTableFill(*t));
+ }
+
+ Result<> makeTableCopy(Index pos, Name* destTable, Name* srcTable) {
+ auto dest = getTable(pos, destTable);
+ CHECK_ERR(dest);
+ auto src = getTable(pos, srcTable);
+ CHECK_ERR(src);
+ return withLoc(pos, irBuilder.makeTableCopy(*dest, *src));
+ }
+
Result<> makeThrow(Index pos, Name tag) {
return withLoc(pos, irBuilder.makeThrow(tag));
}
diff --git a/src/parser/parsers.h b/src/parser/parsers.h
index 281980108..67bd8bddd 100644
--- a/src/parser/parsers.h
+++ b/src/parser/parsers.h
@@ -1433,27 +1433,44 @@ template<typename Ctx> Result<> makeRefEq(Ctx& ctx, Index pos) {
}
template<typename Ctx> Result<> makeTableGet(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto table = maybeTableidx(ctx);
+ CHECK_ERR(table);
+ return ctx.makeTableGet(pos, table.getPtr());
}
template<typename Ctx> Result<> makeTableSet(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto table = maybeTableidx(ctx);
+ CHECK_ERR(table);
+ return ctx.makeTableSet(pos, table.getPtr());
}
template<typename Ctx> Result<> makeTableSize(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto table = maybeTableidx(ctx);
+ CHECK_ERR(table);
+ return ctx.makeTableSize(pos, table.getPtr());
}
template<typename Ctx> Result<> makeTableGrow(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto table = maybeTableidx(ctx);
+ CHECK_ERR(table);
+ return ctx.makeTableGrow(pos, table.getPtr());
}
template<typename Ctx> Result<> makeTableFill(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto table = maybeTableidx(ctx);
+ CHECK_ERR(table);
+ return ctx.makeTableFill(pos, table.getPtr());
}
template<typename Ctx> Result<> makeTableCopy(Ctx& ctx, Index pos) {
- return ctx.in.err("unimplemented instruction");
+ auto destTable = maybeTableidx(ctx);
+ CHECK_ERR(destTable);
+ auto srcTable = maybeTableidx(ctx);
+ CHECK_ERR(srcTable);
+ if (destTable && !srcTable) {
+ return ctx.in.err("expected table index or identifier");
+ }
+ return ctx.makeTableCopy(pos, destTable.getPtr(), srcTable.getPtr());
}
template<typename Ctx> Result<> makeThrow(Ctx& ctx, Index pos) {
diff --git a/src/wasm-ir-builder.h b/src/wasm-ir-builder.h
index 96d0c44a1..ab633b9fa 100644
--- a/src/wasm-ir-builder.h
+++ b/src/wasm-ir-builder.h
@@ -148,12 +148,12 @@ public:
[[nodiscard]] Result<> makeRefIsNull();
[[nodiscard]] Result<> makeRefFunc(Name func);
[[nodiscard]] Result<> makeRefEq();
- // [[nodiscard]] Result<> makeTableGet();
- // [[nodiscard]] Result<> makeTableSet();
- // [[nodiscard]] Result<> makeTableSize();
- // [[nodiscard]] Result<> makeTableGrow();
- // [[nodiscard]] Result<> makeTableFill();
- // [[nodiscard]] Result<> makeTableCopy();
+ [[nodiscard]] Result<> makeTableGet(Name table);
+ [[nodiscard]] Result<> makeTableSet(Name table);
+ [[nodiscard]] Result<> makeTableSize(Name table);
+ [[nodiscard]] Result<> makeTableGrow(Name table);
+ [[nodiscard]] Result<> makeTableFill(Name table);
+ [[nodiscard]] Result<> makeTableCopy(Name destTable, Name srcTable);
[[nodiscard]] Result<> makeTry(Name label, Type type);
[[nodiscard]] Result<> makeThrow(Name tag);
// [[nodiscard]] Result<> makeRethrow();
diff --git a/src/wasm.h b/src/wasm.h
index 24138c99d..7da80d896 100644
--- a/src/wasm.h
+++ b/src/wasm.h
@@ -1380,6 +1380,7 @@ public:
class TableGet : public SpecificExpression<Expression::TableGetId> {
public:
+ TableGet() = default;
TableGet(MixedArena& allocator) {}
Name table;
@@ -1391,6 +1392,7 @@ public:
class TableSet : public SpecificExpression<Expression::TableSetId> {
public:
+ TableSet() = default;
TableSet(MixedArena& allocator) {}
Name table;
diff --git a/src/wasm/wasm-ir-builder.cpp b/src/wasm/wasm-ir-builder.cpp
index be2bb4404..a95329f7d 100644
--- a/src/wasm/wasm-ir-builder.cpp
+++ b/src/wasm/wasm-ir-builder.cpp
@@ -1159,13 +1159,47 @@ Result<> IRBuilder::makeRefEq() {
return Ok{};
}
-// Result<> IRBuilder::makeTableGet() {}
+Result<> IRBuilder::makeTableGet(Name table) {
+ TableGet curr;
+ CHECK_ERR(visitTableGet(&curr));
+ auto type = wasm.getTable(table)->type;
+ push(builder.makeTableGet(table, curr.index, type));
+ return Ok{};
+}
+
+Result<> IRBuilder::makeTableSet(Name table) {
+ TableSet curr;
+ CHECK_ERR(visitTableSet(&curr));
+ push(builder.makeTableSet(table, curr.index, curr.value));
+ return Ok{};
+}
+
+Result<> IRBuilder::makeTableSize(Name table) {
+ push(builder.makeTableSize(table));
+ return Ok{};
+}
-// Result<> IRBuilder::makeTableSet() {}
+Result<> IRBuilder::makeTableGrow(Name table) {
+ TableGrow curr;
+ CHECK_ERR(visitTableGrow(&curr));
+ push(builder.makeTableGrow(table, curr.value, curr.delta));
+ return Ok{};
+}
-// Result<> IRBuilder::makeTableSize() {}
+Result<> IRBuilder::makeTableFill(Name table) {
+ TableFill curr;
+ CHECK_ERR(visitTableFill(&curr));
+ push(builder.makeTableFill(table, curr.dest, curr.value, curr.size));
+ return Ok{};
+}
-// Result<> IRBuilder::makeTableGrow() {}
+Result<> IRBuilder::makeTableCopy(Name destTable, Name srcTable) {
+ TableCopy curr;
+ CHECK_ERR(visitTableCopy(&curr));
+ push(builder.makeTableCopy(
+ curr.dest, curr.source, curr.size, destTable, srcTable));
+ return Ok{};
+}
Result<> IRBuilder::makeTry(Name label, Type type) {
auto* tryy = wasm.allocator.alloc<Try>();
diff --git a/test/lit/wat-kitchen-sink.wast b/test/lit/wat-kitchen-sink.wast
index 6c4e33a18..db16728d1 100644
--- a/test/lit/wat-kitchen-sink.wast
+++ b/test/lit/wat-kitchen-sink.wast
@@ -292,7 +292,7 @@
;; tags
(tag)
- ;; CHECK: (elem declare func $ref-func)
+ ;; CHECK: (elem declare func $ref-func $table-fill $table-grow $table-set)
;; CHECK: (tag $1)
@@ -2957,6 +2957,171 @@
ref.eq
)
+ ;; CHECK: (func $table-get (type $void)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.get $timport$0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.get $funcs
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.get $table-any
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $table-get
+ i32.const 0
+ table.get
+ drop
+ i32.const 1
+ table.get 1
+ drop
+ i32.const 2
+ table.get $table-any
+ drop
+ )
+
+ ;; CHECK: (func $table-set (type $void)
+ ;; CHECK-NEXT: (table.set $timport$0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (table.set $funcs
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (ref.func $table-set)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (table.set $table-any
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $table-set
+ i32.const 0
+ ref.null func
+ table.set
+ i32.const 1
+ ref.func $table-set
+ table.set 1
+ i32.const 2
+ ref.null any
+ table.set $table-any
+ )
+
+ ;; CHECK: (func $table-size (type $void)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.size $timport$0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.size $funcs)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.size $table-any)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $table-size
+ table.size
+ drop
+ table.size 1
+ drop
+ table.size $table-any
+ drop
+ )
+
+ ;; CHECK: (func $table-grow (type $void)
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.grow $timport$0
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.grow $funcs
+ ;; CHECK-NEXT: (ref.func $table-grow)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (drop
+ ;; CHECK-NEXT: (table.grow $table-any
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $table-grow
+ ref.null func
+ i32.const 0
+ table.grow
+ drop
+ ref.func $table-grow
+ i32.const 1
+ table.grow 1
+ drop
+ ref.null any
+ i32.const 2
+ table.grow $table-any
+ drop
+ )
+
+ ;; CHECK: (func $table-fill (type $void)
+ ;; CHECK-NEXT: (table.fill $timport$0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (ref.null nofunc)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (table.fill $funcs
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: (ref.func $table-fill)
+ ;; CHECK-NEXT: (i32.const 3)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (table.fill $table-any
+ ;; CHECK-NEXT: (i32.const 4)
+ ;; CHECK-NEXT: (ref.null none)
+ ;; CHECK-NEXT: (i32.const 5)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $table-fill
+ i32.const 0
+ ref.null func
+ i32.const 1
+ table.fill
+ i32.const 2
+ ref.func $table-fill
+ i32.const 3
+ table.fill 1
+ i32.const 4
+ ref.null any
+ i32.const 5
+ table.fill $table-any
+ )
+
+ ;; CHECK: (func $table-copy (type $void)
+ ;; CHECK-NEXT: (table.copy $timport$0 $timport$0
+ ;; CHECK-NEXT: (i32.const 0)
+ ;; CHECK-NEXT: (i32.const 1)
+ ;; CHECK-NEXT: (i32.const 2)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: (table.copy $funcs $funcs
+ ;; CHECK-NEXT: (i32.const 3)
+ ;; CHECK-NEXT: (i32.const 4)
+ ;; CHECK-NEXT: (i32.const 5)
+ ;; CHECK-NEXT: )
+ ;; CHECK-NEXT: )
+ (func $table-copy
+ i32.const 0
+ i32.const 1
+ i32.const 2
+ table.copy
+ i32.const 3
+ i32.const 4
+ i32.const 5
+ table.copy 1 $funcs
+ )
+
;; CHECK: (func $i31-new (type $34) (param $0 i32) (result i31ref)
;; CHECK-NEXT: (ref.i31
;; CHECK-NEXT: (local.get $0)