summaryrefslogtreecommitdiff
path: root/src/wasm
diff options
context:
space:
mode:
Diffstat (limited to 'src/wasm')
-rw-r--r--src/wasm/wasm-binary.cpp20
-rw-r--r--src/wasm/wasm-s-parser.cpp12
-rw-r--r--src/wasm/wasm-stack.cpp5
-rw-r--r--src/wasm/wasm-validator.cpp19
-rw-r--r--src/wasm/wasm.cpp9
-rw-r--r--src/wasm/wat-parser.cpp6
6 files changed, 71 insertions, 0 deletions
diff --git a/src/wasm/wasm-binary.cpp b/src/wasm/wasm-binary.cpp
index 969c15aaa..0c78442a7 100644
--- a/src/wasm/wasm-binary.cpp
+++ b/src/wasm/wasm-binary.cpp
@@ -4012,6 +4012,9 @@ BinaryConsts::ASTNodes WasmBinaryReader::readExpression(Expression*& curr) {
if (maybeVisitTableGrow(curr, opcode)) {
break;
}
+ if (maybeVisitTableFill(curr, opcode)) {
+ break;
+ }
throwError("invalid code after misc prefix: " + std::to_string(opcode));
break;
}
@@ -5369,6 +5372,23 @@ bool WasmBinaryReader::maybeVisitTableGrow(Expression*& out, uint32_t code) {
return true;
}
+bool WasmBinaryReader::maybeVisitTableFill(Expression*& out, uint32_t code) {
+ if (code != BinaryConsts::TableFill) {
+ return false;
+ }
+ Index tableIdx = getU32LEB();
+ if (tableIdx >= wasm.tables.size()) {
+ throwError("bad table index");
+ }
+ auto* size = popNonVoidExpression();
+ auto* value = popNonVoidExpression();
+ auto* dest = popNonVoidExpression();
+ auto* ret = Builder(wasm).makeTableFill(Name(), dest, value, size);
+ tableRefs[tableIdx].push_back(&ret->table);
+ out = ret;
+ return true;
+}
+
bool WasmBinaryReader::maybeVisitBinary(Expression*& out, uint8_t code) {
Binary* curr;
#define INT_TYPED_CODE(code) \
diff --git a/src/wasm/wasm-s-parser.cpp b/src/wasm/wasm-s-parser.cpp
index 7da6ae0a5..dec9249c3 100644
--- a/src/wasm/wasm-s-parser.cpp
+++ b/src/wasm/wasm-s-parser.cpp
@@ -2641,6 +2641,18 @@ Expression* SExpressionWasmBuilder::makeTableGrow(Element& s) {
return Builder(wasm).makeTableGrow(tableName, value, delta);
}
+Expression* SExpressionWasmBuilder::makeTableFill(Element& s) {
+ auto tableName = s[1]->str();
+ auto* table = wasm.getTableOrNull(tableName);
+ if (!table) {
+ throw ParseException("invalid table name in table.fill", s.line, s.col);
+ }
+ auto* dest = parseExpression(s[2]);
+ auto* value = parseExpression(s[3]);
+ auto* size = parseExpression(s[4]);
+ return Builder(wasm).makeTableFill(tableName, dest, value, size);
+}
+
// try can be either in the form of try-catch or try-delegate.
// try-catch is written in the folded wast format as
// (try
diff --git a/src/wasm/wasm-stack.cpp b/src/wasm/wasm-stack.cpp
index 1ddf69d41..2042189fd 100644
--- a/src/wasm/wasm-stack.cpp
+++ b/src/wasm/wasm-stack.cpp
@@ -1909,6 +1909,11 @@ void BinaryInstWriter::visitTableGrow(TableGrow* curr) {
o << U32LEB(parent.getTableIndex(curr->table));
}
+void BinaryInstWriter::visitTableFill(TableFill* curr) {
+ o << int8_t(BinaryConsts::MiscPrefix) << U32LEB(BinaryConsts::TableFill);
+ o << U32LEB(parent.getTableIndex(curr->table));
+}
+
void BinaryInstWriter::visitTry(Try* curr) {
breakStack.push_back(curr->name);
o << int8_t(BinaryConsts::Try);
diff --git a/src/wasm/wasm-validator.cpp b/src/wasm/wasm-validator.cpp
index c1836a7ff..41ddd00f5 100644
--- a/src/wasm/wasm-validator.cpp
+++ b/src/wasm/wasm-validator.cpp
@@ -440,6 +440,7 @@ public:
void visitTableSet(TableSet* curr);
void visitTableSize(TableSize* curr);
void visitTableGrow(TableGrow* curr);
+ void visitTableFill(TableFill* curr);
void noteDelegate(Name name, Expression* curr);
void noteRethrow(Name name, Expression* curr);
void visitTry(Try* curr);
@@ -2294,6 +2295,24 @@ void FunctionValidator::visitTableGrow(TableGrow* curr) {
}
}
+void FunctionValidator::visitTableFill(TableFill* curr) {
+ shouldBeTrue(
+ getModule()->features.hasBulkMemory(),
+ curr,
+ "table.fill requires reference types [--enable-reference-types]");
+ auto* table = getModule()->getTableOrNull(curr->table);
+ if (shouldBeTrue(!!table, curr, "table.fill table must exist")) {
+ shouldBeSubType(curr->value->type,
+ table->type,
+ curr,
+ "table.fill value must have right type");
+ }
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->dest->type, Type(Type::i32), curr, "table.fill dest must be i32");
+ shouldBeEqualOrFirstIsUnreachable(
+ curr->size->type, Type(Type::i32), curr, "table.fill size must be i32");
+}
+
void FunctionValidator::noteDelegate(Name name, Expression* curr) {
if (name != DELEGATE_CALLER_TARGET) {
shouldBeTrue(delegateTargetNames.count(name) != 0,
diff --git a/src/wasm/wasm.cpp b/src/wasm/wasm.cpp
index ca7e265f8..52a09e90c 100644
--- a/src/wasm/wasm.cpp
+++ b/src/wasm/wasm.cpp
@@ -855,6 +855,15 @@ void TableGrow::finalize() {
}
}
+void TableFill::finalize() {
+ if (dest->type == Type::unreachable || value->type == Type::unreachable ||
+ size->type == Type::unreachable) {
+ type = Type::unreachable;
+ } else {
+ type = Type::none;
+ }
+}
+
void Try::finalize() {
// If none of the component bodies' type is a supertype of the others, assume
// the current type is already correct. TODO: Calculate a proper LUB.
diff --git a/src/wasm/wat-parser.cpp b/src/wasm/wat-parser.cpp
index 6a18b2f87..b31019811 100644
--- a/src/wasm/wat-parser.cpp
+++ b/src/wasm/wat-parser.cpp
@@ -1936,6 +1936,7 @@ template<typename Ctx> Result<typename Ctx::InstrT> makeTableGet(Ctx&, Index);
template<typename Ctx> Result<typename Ctx::InstrT> makeTableSet(Ctx&, Index);
template<typename Ctx> Result<typename Ctx::InstrT> makeTableSize(Ctx&, Index);
template<typename Ctx> Result<typename Ctx::InstrT> makeTableGrow(Ctx&, Index);
+template<typename Ctx> Result<typename Ctx::InstrT> makeTableFill(Ctx&, Index);
template<typename Ctx> Result<typename Ctx::InstrT> makeTry(Ctx&, Index);
template<typename Ctx>
Result<typename Ctx::InstrT>
@@ -3006,6 +3007,11 @@ Result<typename Ctx::InstrT> makeTableGrow(Ctx& ctx, Index pos) {
}
template<typename Ctx>
+Result<typename Ctx::InstrT> makeTableFill(Ctx& ctx, Index pos) {
+ return ctx.in.err("unimplemented instruction");
+}
+
+template<typename Ctx>
Result<typename Ctx::InstrT> makeTry(Ctx& ctx, Index pos) {
return ctx.in.err("unimplemented instruction");
}