diff options
Diffstat (limited to 'src/wasm')
-rw-r--r-- | src/wasm/wasm-binary.cpp | 20 | ||||
-rw-r--r-- | src/wasm/wasm-s-parser.cpp | 12 | ||||
-rw-r--r-- | src/wasm/wasm-stack.cpp | 5 | ||||
-rw-r--r-- | src/wasm/wasm-validator.cpp | 19 | ||||
-rw-r--r-- | src/wasm/wasm.cpp | 9 | ||||
-rw-r--r-- | src/wasm/wat-parser.cpp | 6 |
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"); } |