Merge mozilla-inbound to mozilla-central a=merge

This commit is contained in:
Razvan Maries 2019-04-26 18:35:43 +03:00
Родитель 5f945421d4 5850ec9571
Коммит ebb7081cb2
15 изменённых файлов: 485 добавлений и 1 удалений

Просмотреть файл

@ -0,0 +1,226 @@
// |jit-test| skip-if: !wasmReftypesEnabled()
let ins
= wasmEvalText(
`(module
(table 8 anyref) ;; table 0
(table $t 10 anyref) ;; table 1
;; fill/get for table 0, referenced implicitly
(func (export "fill0") (param $i i32) (param $r anyref) (param $n i32)
(table.fill (local.get $i) (local.get $r) (local.get $n))
)
(func (export "get0") (param $i i32) (result anyref)
(table.get (local.get $i))
)
;; fill/get for table 1, referenced explicitly
(func (export "fill1") (param $i i32) (param $r anyref) (param $n i32)
(table.fill $t (local.get $i) (local.get $r) (local.get $n))
)
(func (export "get1") (param $i i32) (result anyref)
(table.get $t (local.get $i))
)
)`);
function Obj(n) {
this.n = n;
}
function mkObj(n) {
return new Obj(n);
}
const obj1 = mkObj(1);
const obj2 = mkObj(2);
const obj3 = mkObj(3);
const obj4 = mkObj(4);
const obj5 = mkObj(5);
const obj6 = mkObj(6);
const obj7 = mkObj(7);
const obj8 = mkObj(8);
// An initial test to ascertain that tables 0 and 1 are independent
// Fill in table 0, then check it.
assertEq(ins.exports.fill0(2, obj7, 5), undefined)
assertEq(ins.exports.fill0(1, obj8, 3), undefined);
function check_table0() {
assertEq(ins.exports.get0(0), null);
assertEq(ins.exports.get0(1), obj8);
assertEq(ins.exports.get0(2), obj8);
assertEq(ins.exports.get0(3), obj8);
assertEq(ins.exports.get0(4), obj7);
assertEq(ins.exports.get0(5), obj7);
assertEq(ins.exports.get0(6), obj7);
assertEq(ins.exports.get0(7), null);
}
// Check that table 0 has the expected content.
check_table0();
// Check that messing with table 0 above hasn't changed table 1.
for (let i = 0; i < 10; i++) {
assertEq(ins.exports.get1(i), null);
}
// Now a bunch of tests involving only table 1.
// Within the table
assertEq(ins.exports.fill1(2, obj1, 3), undefined);
assertEq(ins.exports.get1(1), null);
assertEq(ins.exports.get1(2), obj1);
assertEq(ins.exports.get1(3), obj1);
assertEq(ins.exports.get1(4), obj1);
assertEq(ins.exports.get1(5), null);
// Within the table
assertEq(ins.exports.fill1(4, obj2, 2), undefined);
assertEq(ins.exports.get1(3), obj1);
assertEq(ins.exports.get1(4), obj2);
assertEq(ins.exports.get1(5), obj2);
assertEq(ins.exports.get1(6), null);
// Within the table
assertEq(ins.exports.fill1(4, obj3, 0), undefined);
assertEq(ins.exports.get1(3), obj1);
assertEq(ins.exports.get1(4), obj2);
assertEq(ins.exports.get1(5), obj2);
// Within the table
assertEq(ins.exports.fill1(8, obj4, 2), undefined);
assertEq(ins.exports.get1(7), null);
assertEq(ins.exports.get1(8), obj4);
assertEq(ins.exports.get1(9), obj4);
// Within the table
assertEq(ins.exports.fill1(9, null, 1), undefined);
assertEq(ins.exports.get1(8), obj4);
assertEq(ins.exports.get1(9), null);
// Within the table
assertEq(ins.exports.fill1(10, obj5, 0), undefined);
assertEq(ins.exports.get1(9), null);
// Partly outside the table
assertErrorMessage(() => ins.exports.fill1(8, obj6, 3),
RangeError, /table index out of bounds/);
assertEq(ins.exports.get1(7), null);
assertEq(ins.exports.get1(8), obj6);
assertEq(ins.exports.get1(9), obj6);
// Boundary tests on table 1: at the edge of the table.
// Length-zero fill1 at the edge of the table must succeed
assertEq(ins.exports.fill1(10, null, 0), undefined);
// Length-one fill1 at the edge of the table fails
assertErrorMessage(() => ins.exports.fill1(10, null, 1),
RangeError, /table index out of bounds/);
// Length-more-than-one fill1 at the edge of the table fails
assertErrorMessage(() => ins.exports.fill1(10, null, 2),
RangeError, /table index out of bounds/);
// Boundary tests on table 1: beyond the edge of the table:
// Length-zero fill1 beyond the edge of the table fails
assertErrorMessage(() => ins.exports.fill1(11, null, 0),
RangeError, /table index out of bounds/);
// Length-one fill1 beyond the edge of the table fails
assertErrorMessage(() => ins.exports.fill1(11, null, 1),
RangeError, /table index out of bounds/);
// Length-more-than-one fill1 beyond the edge of the table fails
assertErrorMessage(() => ins.exports.fill1(11, null, 2),
RangeError, /table index out of bounds/);
// Type errors. Required sig is: (i32, anyref, i32) -> void
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 10 anyref)
(func $expected-3-args-got-0
(table.fill $t)
))`),
WebAssembly.CompileError, /popping value from empty stack/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 10 anyref)
(func $expected-3-args-got-1
(table.fill $t (i32.const 0))
))`),
WebAssembly.CompileError, /popping value from empty stack/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 10 anyref)
(func $expected-3-args-got-2
(table.fill $t (ref.null) (i32.const 0))
))`),
WebAssembly.CompileError, /popping value from empty stack/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 10 anyref)
(func $argty-1-wrong
(table.fill $t (i32.const 0) (ref.null) (f64.const 0))
))`),
WebAssembly.CompileError,
/type mismatch: expression has type f64 but expected i32/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 10 anyref)
(func $argty-2-wrong
(table.fill $t (i32.const 0) (f32.const 0) (i32.const 0))
))`),
WebAssembly.CompileError,
/type mismatch: expression has type f32 but expected anyref/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 10 anyref)
(func $argty-3-wrong
(table.fill $t (i64.const 0) (ref.null) (i32.const 0))
))`),
WebAssembly.CompileError,
/type mismatch: expression has type i64 but expected i32/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 10 anyref)
(func $retty-wrong (result i32)
(table.fill $t (i32.const 0) (ref.null) (i32.const 0))
))`),
WebAssembly.CompileError,
/popping value from empty stack/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t 0 funcref)
(func $tables-of-funcref-not-allowed (param $r anyref)
(table.fill $t (i32.const 1) (local.get $r) (i32.const 1))
))`),
WebAssembly.CompileError, /table.fill only on tables of anyref/);
assertErrorMessage(() => wasmEvalText(
`(module
(table $t1 1 anyref)
(table $t2 1 funcref)
(func $tables-of-funcref-not-allowed-2 (param $r anyref)
(table.fill $t2 (i32.const 0) (local.get $r) (i32.const 1))
))`),
WebAssembly.CompileError, /table.fill only on tables of anyref/);
// Following all the above tests on table 1, check table 0 hasn't changed.
check_table0();

Просмотреть файл

@ -430,6 +430,7 @@ enum class AstExprKind {
StructNarrow,
#endif
#ifdef ENABLE_WASM_REFTYPES
TableFill,
TableGet,
TableGrow,
TableSet,
@ -919,6 +920,25 @@ class AstMemOrTableInit : public AstExpr {
#endif
#ifdef ENABLE_WASM_REFTYPES
class AstTableFill : public AstExpr {
AstRef targetTable_;
AstExpr* start_;
AstExpr* val_;
AstExpr* len_;
public:
static const AstExprKind Kind = AstExprKind::TableFill;
explicit AstTableFill(AstRef targetTable,
AstExpr* start, AstExpr* val, AstExpr* len)
: AstExpr(Kind, ExprType::Void), targetTable_(targetTable),
start_(start), val_(val), len_(len) {}
AstRef& targetTable() { return targetTable_; }
AstExpr& start() const { return *start_; }
AstExpr& val() const { return *val_; }
AstExpr& len() const { return *len_; }
};
class AstTableGet : public AstExpr {
AstRef targetTable_;
AstExpr* index_;

Просмотреть файл

@ -6850,6 +6850,7 @@ class BaseCompiler final : public BaseCompilerInterface {
MOZ_MUST_USE bool emitMemFill();
MOZ_MUST_USE bool emitMemOrTableInit(bool isMem);
#endif
MOZ_MUST_USE bool emitTableFill();
MOZ_MUST_USE bool emitTableGet();
MOZ_MUST_USE bool emitTableGrow();
MOZ_MUST_USE bool emitTableSet();
@ -10332,6 +10333,37 @@ bool BaseCompiler::emitMemOrTableInit(bool isMem) {
}
#endif
MOZ_MUST_USE
bool BaseCompiler::emitTableFill() {
uint32_t lineOrBytecode = readCallSiteLineOrBytecode();
Nothing nothing;
uint32_t tableIndex;
if (!iter_.readTableFill(&tableIndex, &nothing, &nothing, &nothing)) {
return false;
}
if (deadCode_) {
return true;
}
// fill(start:u32, val:ref, len:u32, table:u32) -> u32
//
// Returns -1 on trap, otherwise 0.
pushI32(tableIndex);
if (!emitInstanceCall(lineOrBytecode, SASigTableFill,
/*pushReturnedValue=*/false)) {
return false;
}
Label ok;
masm.branchTest32(Assembler::NotSigned, ReturnReg, ReturnReg, &ok);
trap(Trap::ThrowReported);
masm.bind(&ok);
return true;
}
MOZ_MUST_USE
bool BaseCompiler::emitTableGet() {
uint32_t lineOrBytecode = readCallSiteLineOrBytecode();
@ -11565,6 +11597,8 @@ bool BaseCompiler::emitBody() {
CHECK_NEXT(emitMemOrTableInit(/*isMem=*/false));
#endif // ENABLE_WASM_BULKMEM_OPS
#ifdef ENABLE_WASM_REFTYPES
case uint32_t(MiscOp::TableFill):
CHECK_NEXT(emitTableFill());
case uint32_t(MiscOp::TableGrow):
CHECK_NEXT(emitTableGrow());
case uint32_t(MiscOp::TableSize):

Просмотреть файл

@ -121,6 +121,8 @@ const SymbolicAddressSignature SASigTableCopy = {
{_PTR, _I32, _I32, _I32, _I32, _I32, _END}};
const SymbolicAddressSignature SASigElemDrop = {
SymbolicAddress::ElemDrop, _I32, 2, {_PTR, _I32, _END}};
const SymbolicAddressSignature SASigTableFill = {
SymbolicAddress::TableFill, _I32, 5, {_PTR, _I32, _RoN, _I32, _I32, _END}};
const SymbolicAddressSignature SASigTableGet = {
SymbolicAddress::TableGet, _PTR, 3, {_PTR, _I32, _I32, _END}};
const SymbolicAddressSignature SASigTableGrow = {
@ -766,6 +768,9 @@ void* wasm::AddressOf(SymbolicAddress imm, ABIFunctionType* abiType) {
case SymbolicAddress::ElemDrop:
*abiType = Args_General2;
return FuncCast(Instance::elemDrop, *abiType);
case SymbolicAddress::TableFill:
*abiType = Args_General5;
return FuncCast(Instance::tableFill, *abiType);
case SymbolicAddress::TableInit:
*abiType = Args_General6;
return FuncCast(Instance::tableInit, *abiType);
@ -895,6 +900,7 @@ bool wasm::NeedsBuiltinThunk(SymbolicAddress sym) {
case SymbolicAddress::MemInit:
case SymbolicAddress::TableCopy:
case SymbolicAddress::ElemDrop:
case SymbolicAddress::TableFill:
case SymbolicAddress::TableGet:
case SymbolicAddress::TableGrow:
case SymbolicAddress::TableInit:

Просмотреть файл

@ -58,6 +58,7 @@ extern const SymbolicAddressSignature SASigMemFill;
extern const SymbolicAddressSignature SASigMemInit;
extern const SymbolicAddressSignature SASigTableCopy;
extern const SymbolicAddressSignature SASigElemDrop;
extern const SymbolicAddressSignature SASigTableFill;
extern const SymbolicAddressSignature SASigTableGet;
extern const SymbolicAddressSignature SASigTableGrow;
extern const SymbolicAddressSignature SASigTableInit;

Просмотреть файл

@ -385,7 +385,7 @@ enum class MiscOp {
// Reftypes, per proposal as of February 2019.
TableGrow = 0x0f,
TableSize = 0x10,
// TableFill = 0x11, // reserved
TableFill = 0x11,
// Structure operations. Note, these are unofficial.
StructNew = 0x50,

Просмотреть файл

@ -1361,6 +1361,8 @@ static const char* ThunkedNativeToDescription(SymbolicAddress func) {
return "call to native memory.init function";
case SymbolicAddress::TableCopy:
return "call to native table.copy function";
case SymbolicAddress::TableFill:
return "call to native table.fill function";
case SymbolicAddress::ElemDrop:
return "call to native elem.drop function";
case SymbolicAddress::TableGet:

Просмотреть файл

@ -851,6 +851,53 @@ Instance::tableInit(Instance* instance, uint32_t dstOffset, uint32_t srcOffset,
return -1;
}
/* static */ int32_t /* -1 to signal trap; 0 for ok */
Instance::tableFill(Instance* instance, uint32_t start, void* value,
uint32_t len, uint32_t tableIndex)
{
Table& table = *instance->tables()[tableIndex];
MOZ_RELEASE_ASSERT(table.kind() == TableKind::AnyRef);
if (len == 0) {
// Even though the length is zero, we must check for a valid offset. But
// zero-length operations at the edge of the table are allowed.
if (start <= table.length()) {
return 0;
}
} else {
// Here, we know that |len - 1| cannot underflow.
bool mustTrap = false;
// We must write the table until we trap, so we have to deal with
// arithmetic overflow in the limit calculation.
uint64_t highestOffset = uint64_t(start) + uint64_t(len - 1);
if (highestOffset >= table.length()) {
// We would write past the end. Compute what we have space for in the
// target and make that the new len.
uint64_t avail = table.length() < start ? 0 : table.length() - start;
MOZ_ASSERT(len > avail);
len = uint32_t(avail);
mustTrap = true;
}
for (uint32_t i = 0; i < len; i++) {
uint32_t index = start + i;
MOZ_ASSERT(index < table.length());
table.setAnyRef(index, AnyRef::fromCompiledCode(value));
}
if (!mustTrap) {
return 0;
}
}
JSContext* cx = TlsContext.get();
JS_ReportErrorNumberASCII(cx, GetErrorMessage, nullptr,
JSMSG_WASM_TABLE_OUT_OF_BOUNDS);
return -1;
}
// The return convention for tableGet() is awkward but avoids a situation where
// Ion code has to hold a value that may or may not be a pointer to GC'd
// storage, or where Ion has to pass in a pointer to storage where a return

Просмотреть файл

@ -200,6 +200,8 @@ class Instance {
uint32_t srcOffset, uint32_t len,
uint32_t dstTableIndex, uint32_t srcTableIndex);
static int32_t elemDrop(Instance* instance, uint32_t segIndex);
static int32_t tableFill(Instance* instance, uint32_t start, void* value,
uint32_t len, uint32_t tableIndex);
static void* tableGet(Instance* instance, uint32_t index,
uint32_t tableIndex);
static uint32_t tableGrow(Instance* instance, void* initValue, uint32_t delta,

Просмотреть файл

@ -3137,6 +3137,60 @@ static bool EmitMemOrTableInit(FunctionCompiler& f, bool isMem) {
// Note, table.{get,grow,set} on table(funcref) are currently rejected by the
// verifier.
static bool EmitTableFill(FunctionCompiler& f) {
uint32_t tableIndex;
MDefinition *start, *val, *len;
if (!f.iter().readTableFill(&tableIndex, &start, &val, &len)) {
return false;
}
if (f.inDeadCode()) {
return true;
}
uint32_t lineOrBytecode = f.readCallSiteLineOrBytecode();
const SymbolicAddressSignature& callee = SASigTableFill;
CallCompileState args;
if (!f.passInstance(callee.argTypes[0], &args)) {
return false;
}
if (!f.passArg(start, callee.argTypes[1], &args)) {
return false;
}
if (!f.passArg(val, callee.argTypes[2], &args)) {
return false;
}
if (!f.passArg(len, callee.argTypes[3], &args)) {
return false;
}
MDefinition* tableIndexArg =
f.constant(Int32Value(tableIndex), MIRType::Int32);
if (!tableIndexArg) {
return false;
}
if (!f.passArg(tableIndexArg, callee.argTypes[4], &args)) {
return false;
}
if (!f.finishCall(&args)) {
return false;
}
MDefinition* ret;
if (!f.builtinInstanceMethodCall(callee, lineOrBytecode, args, &ret)) {
return false;
}
if (!f.checkI32NegativeMeansFailedResult(ret)) {
return false;
}
return true;
}
static bool EmitTableGet(FunctionCompiler& f) {
uint32_t tableIndex;
MDefinition* index;
@ -3865,6 +3919,8 @@ static bool EmitBodyExprs(FunctionCompiler& f) {
CHECK(EmitMemOrTableInit(f, /*isMem=*/false));
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint32_t(MiscOp::TableFill):
CHECK(EmitTableFill(f));
case uint32_t(MiscOp::TableGrow):
CHECK(EmitTableGrow(f));
case uint32_t(MiscOp::TableSize):

Просмотреть файл

@ -296,6 +296,8 @@ OpKind wasm::Classify(OpBytes op) {
case MiscOp::MemInit:
case MiscOp::TableInit:
WASM_BULK_OP(OpKind::MemOrTableInit);
case MiscOp::TableFill:
WASM_REF_OP(OpKind::TableFill);
case MiscOp::TableGrow:
WASM_REF_OP(OpKind::TableGrow);
case MiscOp::TableSize:

Просмотреть файл

@ -168,6 +168,7 @@ enum class OpKind {
DataOrElemDrop,
MemFill,
MemOrTableInit,
TableFill,
TableGet,
TableGrow,
TableSet,
@ -466,6 +467,8 @@ class MOZ_STACK_CLASS OpIter : private Policy {
MOZ_MUST_USE bool readMemOrTableInit(bool isMem, uint32_t* segIndex,
uint32_t* dstTableIndex, Value* dst,
Value* src, Value* len);
MOZ_MUST_USE bool readTableFill(uint32_t* tableIndex, Value* start,
Value* val, Value* len);
MOZ_MUST_USE bool readTableGet(uint32_t* tableIndex, Value* index);
MOZ_MUST_USE bool readTableGrow(uint32_t* tableIndex, Value* initValue,
Value* delta);
@ -1973,6 +1976,38 @@ inline bool OpIter<Policy>::readMemOrTableInit(bool isMem, uint32_t* segIndex,
return true;
}
template <typename Policy>
inline bool OpIter<Policy>::readTableFill(uint32_t* tableIndex, Value* start,
Value* val, Value* len) {
MOZ_ASSERT(Classify(op_) == OpKind::TableFill);
if (!popWithType(ValType::I32, len)) {
return false;
}
if (!popWithType(ValType::AnyRef, val)) {
return false;
}
if (!popWithType(ValType::I32, start)) {
return false;
}
if (!readVarU32(tableIndex)) {
return false;
}
if (*tableIndex >= env_.tables.length()) {
return fail("table index out of range for table.fill");
}
if (env_.tables[*tableIndex].kind != TableKind::AnyRef) {
return fail("table.fill only on tables of anyref");
}
return true;
}
template <typename Policy>
inline bool OpIter<Policy>::readTableGet(uint32_t* tableIndex, Value* index) {
MOZ_ASSERT(Classify(op_) == OpKind::TableGet);

Просмотреть файл

@ -146,6 +146,7 @@ class WasmToken {
TableInit,
#endif
#ifdef ENABLE_WASM_REFTYPES
TableFill,
TableGet,
TableGrow,
TableSet,
@ -346,6 +347,7 @@ class WasmToken {
case TableInit:
#endif
#ifdef ENABLE_WASM_REFTYPES
case TableFill:
case TableGet:
case TableGrow:
case TableSet:
@ -2260,6 +2262,9 @@ WasmToken WasmTokenStream::next() {
}
#endif
#ifdef ENABLE_WASM_REFTYPES
if (consume(u"fill")) {
return WasmToken(WasmToken::TableFill, begin, cur_);
}
if (consume(u"get")) {
return WasmToken(WasmToken::TableGet, begin, cur_);
}
@ -3791,6 +3796,31 @@ static AstMemOrTableInit* ParseMemOrTableInit(WasmParseContext& c,
#endif
#ifdef ENABLE_WASM_REFTYPES
static AstTableFill* ParseTableFill(WasmParseContext& c, bool inParens) {
// (table.fill table start val len)
// (table.fill start val len)
AstRef targetTable = AstRef(0);
c.ts.getIfRef(&targetTable);
AstExpr* start = ParseExpr(c, inParens);
if (!start) {
return nullptr;
}
AstExpr* val = ParseExpr(c, inParens);
if (!val) {
return nullptr;
}
AstExpr* len = ParseExpr(c, inParens);
if (!len) {
return nullptr;
}
return new (c.lifo) AstTableFill(targetTable, start, val, len);
}
static AstTableGet* ParseTableGet(WasmParseContext& c, bool inParens) {
// (table.get table index)
// (table.get index)
@ -4046,6 +4076,8 @@ static AstExpr* ParseExprBody(WasmParseContext& c, WasmToken token,
return ParseMemOrTableInit(c, inParens, /*isMem=*/false);
#endif
#ifdef ENABLE_WASM_REFTYPES
case WasmToken::TableFill:
return ParseTableFill(c, inParens);
case WasmToken::TableGet:
return ParseTableGet(c, inParens);
case WasmToken::TableGrow:
@ -5659,6 +5691,11 @@ static bool ResolveMemOrTableInit(Resolver& r, AstMemOrTableInit& s) {
#endif
#ifdef ENABLE_WASM_REFTYPES
static bool ResolveTableFill(Resolver& r, AstTableFill& s) {
return ResolveExpr(r, s.start()) && ResolveExpr(r, s.val()) &&
ResolveExpr(r, s.len()) && r.resolveTable(s.targetTable());
}
static bool ResolveTableGet(Resolver& r, AstTableGet& s) {
return ResolveExpr(r, s.index()) && r.resolveTable(s.targetTable());
}
@ -5811,6 +5848,8 @@ static bool ResolveExpr(Resolver& r, AstExpr& expr) {
return ResolveMemOrTableInit(r, expr.as<AstMemOrTableInit>());
#endif
#ifdef ENABLE_WASM_REFTYPES
case AstExprKind::TableFill:
return ResolveTableFill(r, expr.as<AstTableFill>());
case AstExprKind::TableGet:
return ResolveTableGet(r, expr.as<AstTableGet>());
case AstExprKind::TableGrow:
@ -6433,6 +6472,12 @@ static bool EncodeMemOrTableInit(Encoder& e, AstMemOrTableInit& s) {
#endif
#ifdef ENABLE_WASM_REFTYPES
static bool EncodeTableFill(Encoder& e, AstTableFill& s) {
return EncodeExpr(e, s.start()) && EncodeExpr(e, s.val()) &&
EncodeExpr(e, s.len()) && e.writeOp(MiscOp::TableFill) &&
e.writeVarU32(s.targetTable().index());
}
static bool EncodeTableGet(Encoder& e, AstTableGet& s) {
return EncodeExpr(e, s.index()) && e.writeOp(Op::TableGet) &&
e.writeVarU32(s.targetTable().index());
@ -6610,6 +6655,8 @@ static bool EncodeExpr(Encoder& e, AstExpr& expr) {
return EncodeMemOrTableInit(e, expr.as<AstMemOrTableInit>());
#endif
#ifdef ENABLE_WASM_REFTYPES
case AstExprKind::TableFill:
return EncodeTableFill(e, expr.as<AstTableFill>());
case AstExprKind::TableGet:
return EncodeTableGet(e, expr.as<AstTableGet>());
case AstExprKind::TableGrow:

Просмотреть файл

@ -1890,6 +1890,7 @@ enum class SymbolicAddress {
MemInit,
TableCopy,
ElemDrop,
TableFill,
TableGet,
TableGrow,
TableInit,

Просмотреть файл

@ -870,6 +870,11 @@ static bool DecodeFunctionBodyExprs(const ModuleEnvironment& env,
}
#endif
#ifdef ENABLE_WASM_REFTYPES
case uint32_t(MiscOp::TableFill): {
uint32_t unusedTableIndex;
CHECK(iter.readTableFill(&unusedTableIndex,
&nothing, &nothing, &nothing));
}
case uint32_t(MiscOp::TableGrow): {
uint32_t unusedTableIndex;
CHECK(iter.readTableGrow(&unusedTableIndex, &nothing, &nothing));