Skip to content

Commit

Permalink
[Parser] Parse table operations
Browse files Browse the repository at this point in the history
Including table.get, table.set, table.size, table.grow, table.fill, and
table.copy.
  • Loading branch information
tlively committed Dec 8, 2023
1 parent 9efe1d0 commit d76f1d8
Show file tree
Hide file tree
Showing 6 changed files with 279 additions and 17 deletions.
44 changes: 44 additions & 0 deletions src/parser/contexts.h
Original file line number Diff line number Diff line change
Expand Up @@ -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{};
Expand Down Expand Up @@ -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));
}
Expand Down
29 changes: 23 additions & 6 deletions src/parser/parsers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1432,27 +1432,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) {
Expand Down
12 changes: 6 additions & 6 deletions src/wasm-ir-builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,12 +148,12 @@ class IRBuilder : public UnifiedExpressionVisitor<IRBuilder, Result<>> {
[[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();
Expand Down
2 changes: 2 additions & 0 deletions src/wasm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1380,6 +1380,7 @@ class RefEq : public SpecificExpression<Expression::RefEqId> {

class TableGet : public SpecificExpression<Expression::TableGetId> {
public:
TableGet() = default;
TableGet(MixedArena& allocator) {}

Name table;
Expand All @@ -1391,6 +1392,7 @@ class TableGet : public SpecificExpression<Expression::TableGetId> {

class TableSet : public SpecificExpression<Expression::TableSetId> {
public:
TableSet() = default;
TableSet(MixedArena& allocator) {}

Name table;
Expand Down
42 changes: 38 additions & 4 deletions src/wasm/wasm-ir-builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>();
Expand Down
167 changes: 166 additions & 1 deletion test/lit/wat-kitchen-sink.wast
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit d76f1d8

Please sign in to comment.