From b86ef5ce8a89b488e0d1df6468857769b4e0e25b Mon Sep 17 00:00:00 2001 From: rossberg Date: Wed, 18 Jan 2017 04:07:57 -0800 Subject: [PATCH] [wasm] Fix and tighten memory validation Makes us pass the spec's memory.wast test. R=titzer@chromium.org BUG= Review-Url: https://codereview.chromium.org/2640453003 Cr-Commit-Position: refs/heads/master@{#42452} --- src/wasm/function-body-decoder.cc | 11 ++ src/wasm/wasm-js.cc | 5 +- src/wasm/wasm-module.cc | 13 +- test/cctest/wasm/test-run-wasm.cc | 1 + test/cctest/wasm/test-wasm-trap-position.cc | 1 + test/cctest/wasm/wasm-run-utils.h | 2 + .../mjsunit/regress/wasm/regression-667745.js | 1 + test/mjsunit/wasm/grow-memory.js | 6 + test/mjsunit/wasm/memory-size.js | 1 + test/mjsunit/wasm/stack.js | 18 ++- .../wasm/trap-location-with-trap-if.js | 2 + test/mjsunit/wasm/trap-location.js | 2 + .../wasm/function-body-decoder-unittest.cc | 138 ++++++++++++------ 13 files changed, 138 insertions(+), 63 deletions(-) diff --git a/src/wasm/function-body-decoder.cc b/src/wasm/function-body-decoder.cc index 152fba1ffe..86b83c069c 100644 --- a/src/wasm/function-body-decoder.cc +++ b/src/wasm/function-body-decoder.cc @@ -622,6 +622,13 @@ class WasmFullDecoder : public WasmDecoder { return bytes; } + bool CheckHasMemory() { + if (!module_->has_memory) { + error(pc_ - 1, "memory instruction with no memory"); + } + return module_->has_memory; + } + // Decodes the body of a function. void DecodeFunctionBody() { TRACE("wasm-decode %p...%p (module+%d, %d bytes) %s\n", @@ -1112,6 +1119,7 @@ class WasmFullDecoder : public WasmDecoder { len = DecodeStoreMem(kWasmF64, MachineType::Float64()); break; case kExprGrowMemory: { + if (!CheckHasMemory()) break; MemoryIndexOperand operand(this, pc_); DCHECK_NOT_NULL(module_); if (module_->origin != kAsmJsOrigin) { @@ -1124,6 +1132,7 @@ class WasmFullDecoder : public WasmDecoder { break; } case kExprMemorySize: { + if (!CheckHasMemory()) break; MemoryIndexOperand operand(this, pc_); Push(kWasmI32, BUILD(CurrentMemoryPages)); len = 1 + operand.length; @@ -1304,6 +1313,7 @@ class WasmFullDecoder : public WasmDecoder { void PopControl() { control_.pop_back(); } int DecodeLoadMem(ValueType type, MachineType mem_type) { + if (!CheckHasMemory()) return 0; MemoryAccessOperand operand(this, pc_, ElementSizeLog2Of(mem_type.representation())); @@ -1315,6 +1325,7 @@ class WasmFullDecoder : public WasmDecoder { } int DecodeStoreMem(ValueType type, MachineType mem_type) { + if (!CheckHasMemory()) return 0; MemoryAccessOperand operand(this, pc_, ElementSizeLog2Of(mem_type.representation())); Value val = Pop(1, type); diff --git a/src/wasm/wasm-js.cc b/src/wasm/wasm-js.cc index f0435e0cd2..c281bf5c1c 100644 --- a/src/wasm/wasm-js.cc +++ b/src/wasm/wasm-js.cc @@ -308,7 +308,10 @@ void WebAssemblyInstance(const v8::FunctionCallbackInfo& args) { MaybeLocal instance = InstantiateModuleImpl(i_isolate, i_module_obj, args, &thrower); - if (instance.IsEmpty()) return; + if (instance.IsEmpty()) { + DCHECK(thrower.error()); + return; + } v8::ReturnValue return_value = args.GetReturnValue(); return_value.Set(instance.ToLocalChecked()); diff --git a/src/wasm/wasm-module.cc b/src/wasm/wasm-module.cc index 0e8e6c8162..d4dab0b444 100644 --- a/src/wasm/wasm-module.cc +++ b/src/wasm/wasm-module.cc @@ -1293,7 +1293,7 @@ class WasmInstanceBuilder { Address mem_start = static_cast
(memory_->backing_store()); uint32_t mem_size = static_cast(memory_->byte_length()->Number()); - LoadDataSegments(mem_start, mem_size); + if (!LoadDataSegments(mem_start, mem_size)) return nothing; uint32_t old_mem_size = compiled_module_->mem_size(); Address old_mem_start = @@ -1305,7 +1305,7 @@ class WasmInstanceBuilder { old_mem_size, mem_size); compiled_module_->set_memory(memory_); } else { - LoadDataSegments(nullptr, 0); + if (!LoadDataSegments(nullptr, 0)) return nothing; } //-------------------------------------------------------------------------- @@ -1545,7 +1545,7 @@ class WasmInstanceBuilder { } // Load data segments into the memory. - void LoadDataSegments(Address mem_addr, size_t mem_size) { + bool LoadDataSegments(Address mem_addr, size_t mem_size) { Handle module_bytes(compiled_module_->module_bytes(), isolate_); for (const WasmDataSegment& segment : module_->data_segments) { @@ -1553,18 +1553,19 @@ class WasmInstanceBuilder { // Segments of size == 0 are just nops. if (source_size == 0) continue; uint32_t dest_offset = EvalUint32InitExpr(segment.dest_addr); - if (dest_offset >= mem_size || source_size >= mem_size || - dest_offset > (mem_size - source_size)) { + if (dest_offset + source_size > mem_size || + dest_offset + source_size < dest_offset) { thrower_->LinkError("data segment (start = %" PRIu32 ", size = %" PRIu32 ") does not fit into memory (size = %" PRIuS ")", dest_offset, source_size, mem_size); - return; + return false; } byte* dest = mem_addr + dest_offset; const byte* src = reinterpret_cast( module_bytes->GetCharsAddress() + segment.source_offset); memcpy(dest, src, source_size); } + return true; } void WriteGlobalValue(WasmGlobal& global, Handle value) { diff --git a/test/cctest/wasm/test-run-wasm.cc b/test/cctest/wasm/test-run-wasm.cc index 2fa1c10f66..a5f7ddec2b 100644 --- a/test/cctest/wasm/test-run-wasm.cc +++ b/test/cctest/wasm/test-run-wasm.cc @@ -1808,6 +1808,7 @@ TEST(Build_Wasm_UnreachableIf2) { WASM_EXEC_TEST(Unreachable_Load) { WasmRunner r(execution_mode); + r.module().AddMemory(0L); BUILD(r, WASM_BLOCK_I(WASM_BRV(0, WASM_GET_LOCAL(0)), WASM_LOAD_MEM(MachineType::Int8(), WASM_GET_LOCAL(0)))); CHECK_EQ(11, r.Call(11)); diff --git a/test/cctest/wasm/test-wasm-trap-position.cc b/test/cctest/wasm/test-wasm-trap-position.cc index 59ecebcff0..0418d46bab 100644 --- a/test/cctest/wasm/test-wasm-trap-position.cc +++ b/test/cctest/wasm/test-wasm-trap-position.cc @@ -101,6 +101,7 @@ TEST(IllegalLoad) { TestSignatures sigs; // Set the execution context, such that a runtime error can be thrown. r.SetModuleContext(); + r.module().AddMemory(0L); BUILD(r, WASM_IF(WASM_ONE, WASM_SEQ(WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V_1(-3)), diff --git a/test/cctest/wasm/wasm-run-utils.h b/test/cctest/wasm/wasm-run-utils.h index f85f4ca3e2..64e801d8e2 100644 --- a/test/cctest/wasm/wasm-run-utils.h +++ b/test/cctest/wasm/wasm-run-utils.h @@ -105,8 +105,10 @@ class TestingModule : public ModuleEnv { void ChangeOriginToAsmjs() { module_.origin = kAsmJsOrigin; } byte* AddMemory(uint32_t size) { + CHECK(!module_.has_memory); CHECK_NULL(instance->mem_start); CHECK_EQ(0, instance->mem_size); + module_.has_memory = true; instance->mem_start = reinterpret_cast(malloc(size)); CHECK(instance->mem_start); memset(instance->mem_start, 0, size); diff --git a/test/mjsunit/regress/wasm/regression-667745.js b/test/mjsunit/regress/wasm/regression-667745.js index edc3e23bd3..7179e54b5c 100644 --- a/test/mjsunit/regress/wasm/regression-667745.js +++ b/test/mjsunit/regress/wasm/regression-667745.js @@ -9,6 +9,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); (function() { var builder = new WasmModuleBuilder(); + builder.addMemory(0, 0, false); builder.addFunction("test", kSig_i_iii) .addBody([ kExprI32Const, 0x0b, diff --git a/test/mjsunit/wasm/grow-memory.js b/test/mjsunit/wasm/grow-memory.js index 37289a5b77..71eb4fec95 100644 --- a/test/mjsunit/wasm/grow-memory.js +++ b/test/mjsunit/wasm/grow-memory.js @@ -184,6 +184,7 @@ testGrowMemoryReadWrite8(); function testGrowMemoryZeroInitialSize() { var builder = genGrowMemoryBuilder(); + builder.addMemory(0, kV8MaxPages, false); var module = builder.instantiate(); var offset; function peek() { return module.exports.load(offset); } @@ -217,6 +218,7 @@ testGrowMemoryZeroInitialSize(); function testGrowMemoryZeroInitialSize32() { var builder = genGrowMemoryBuilder(); + builder.addMemory(0, kV8MaxPages, false); var module = builder.instantiate(); var offset; function peek() { return module.exports.load(offset); } @@ -242,6 +244,7 @@ testGrowMemoryZeroInitialSize32(); function testGrowMemoryZeroInitialSize16() { var builder = genGrowMemoryBuilder(); + builder.addMemory(0, kV8MaxPages, false); var module = builder.instantiate(); var offset; function peek() { return module.exports.load16(offset); } @@ -267,6 +270,7 @@ testGrowMemoryZeroInitialSize16(); function testGrowMemoryZeroInitialSize8() { var builder = genGrowMemoryBuilder(); + builder.addMemory(0, kV8MaxPages, false); var module = builder.instantiate(); var offset; function peek() { return module.exports.load8(offset); } @@ -292,6 +296,7 @@ testGrowMemoryZeroInitialSize8(); function testGrowMemoryTrapMaxPagesZeroInitialMemory() { var builder = genGrowMemoryBuilder(); + builder.addMemory(0, kV8MaxPages, false); var module = builder.instantiate(); var maxPages = 16385; function growMem(pages) { return module.exports.grow_memory(pages); } @@ -313,6 +318,7 @@ testGrowMemoryTrapMaxPages(); function testGrowMemoryTrapsWithNonSmiInput() { var builder = genGrowMemoryBuilder(); + builder.addMemory(0, kV8MaxPages, false); var module = builder.instantiate(); function growMem(pages) { return module.exports.grow_memory(pages); } // The parameter of grow_memory is unsigned. Therefore -1 stands for diff --git a/test/mjsunit/wasm/memory-size.js b/test/mjsunit/wasm/memory-size.js index bd747176a8..0c96efb798 100644 --- a/test/mjsunit/wasm/memory-size.js +++ b/test/mjsunit/wasm/memory-size.js @@ -10,6 +10,7 @@ load("test/mjsunit/wasm/wasm-module-builder.js"); (function testMemorySizeZero() { print("testMemorySizeZero()"); var builder = new WasmModuleBuilder(); + builder.addMemory(0, 0, false); builder.addFunction("memory_size", kSig_i_v) .addBody([kExprMemorySize, kMemoryZero]) .exportFunc(); diff --git a/test/mjsunit/wasm/stack.js b/test/mjsunit/wasm/stack.js index 650b1436a2..79ab28e367 100644 --- a/test/mjsunit/wasm/stack.js +++ b/test/mjsunit/wasm/stack.js @@ -42,6 +42,8 @@ function STACK() { var builder = new WasmModuleBuilder(); +builder.addMemory(0, 1, false); + builder.addImport("mod", "func", kSig_v_v); builder.addFunction("main", kSig_v_v) @@ -70,8 +72,8 @@ var module = builder.instantiate({mod: {func: STACK}}); // The line numbers below will change as this test gains / loses lines.. " at STACK (stack.js:39:11)\n" + // -- " at main ([1]+1)\n" + // -- - " at testSimpleStack (stack.js:76:18)\n" + // -- - " at stack.js:78:3"; // -- + " at testSimpleStack (stack.js:78:18)\n" + // -- + " at stack.js:80:3"; // -- module.exports.main(); assertEquals(expected_string, stripPath(stack)); @@ -90,8 +92,8 @@ Error.prepareStackTrace = function(error, frames) { // isWasm function line pos file [ false, "STACK", 39, 0, "stack.js"], [ true, "main", 1, 1, null], - [ false, "testStackFrames", 87, 0, "stack.js"], - [ false, null, 96, 0, "stack.js"] + [ false, "testStackFrames", 89, 0, "stack.js"], + [ false, null, 98, 0, "stack.js"] ]); })(); @@ -104,8 +106,8 @@ Error.prepareStackTrace = function(error, frames) { verifyStack(e.stack, [ // isWasm function line pos file [ true, "exec_unreachable", 2, 1, null], - [ false, "testWasmUnreachable", 100, 0, "stack.js"], - [ false, null, 111, 0, "stack.js"] + [ false, "testWasmUnreachable", 102, 0, "stack.js"], + [ false, null, 113, 0, "stack.js"] ]); } })(); @@ -120,8 +122,8 @@ Error.prepareStackTrace = function(error, frames) { // isWasm function line pos file [ true, "", 3, 3, null], [ true, "call_mem_out_of_bounds", 4, 1, null], - [ false, "testWasmMemOutOfBounds", 115, 0, "stack.js"], - [ false, null, 127, 0, "stack.js"] + [ false, "testWasmMemOutOfBounds", 117, 0, "stack.js"], + [ false, null, 129, 0, "stack.js"] ]); } })(); diff --git a/test/mjsunit/wasm/trap-location-with-trap-if.js b/test/mjsunit/wasm/trap-location-with-trap-if.js index 752ec6c2df..d0b65337bb 100644 --- a/test/mjsunit/wasm/trap-location-with-trap-if.js +++ b/test/mjsunit/wasm/trap-location-with-trap-if.js @@ -14,6 +14,8 @@ Error.prepareStackTrace = function(error, frames) { var builder = new WasmModuleBuilder(); +builder.addMemory(0, 1, false); + var sig_index = builder.addType(kSig_i_v) // Build a function to resemble this code: diff --git a/test/mjsunit/wasm/trap-location.js b/test/mjsunit/wasm/trap-location.js index 1aee6d1567..890672357c 100644 --- a/test/mjsunit/wasm/trap-location.js +++ b/test/mjsunit/wasm/trap-location.js @@ -14,6 +14,8 @@ Error.prepareStackTrace = function(error, frames) { var builder = new WasmModuleBuilder(); +builder.addMemory(0, 1, false); + var sig_index = builder.addType(kSig_i_v) // Build a function to resemble this code: diff --git a/test/unittests/wasm/function-body-decoder-unittest.cc b/test/unittests/wasm/function-body-decoder-unittest.cc index 66bbaa7580..196e2357c5 100644 --- a/test/unittests/wasm/function-body-decoder-unittest.cc +++ b/test/unittests/wasm/function-body-decoder-unittest.cc @@ -201,6 +201,60 @@ class FunctionBodyDecoderTest : public TestWithZone { } }; +namespace { +// A helper for tests that require a module environment for functions, +// globals, or memories. +class TestModuleEnv : public ModuleEnv { + public: + explicit TestModuleEnv(ModuleOrigin origin = kWasmOrigin) + : ModuleEnv(&mod, nullptr) { + mod.origin = origin; + } + byte AddGlobal(ValueType type, bool mutability = true) { + mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false}); + CHECK(mod.globals.size() <= 127); + return static_cast(mod.globals.size() - 1); + } + byte AddSignature(FunctionSig* sig) { + mod.signatures.push_back(sig); + CHECK(mod.signatures.size() <= 127); + return static_cast(mod.signatures.size() - 1); + } + byte AddFunction(FunctionSig* sig) { + mod.functions.push_back({sig, // sig + 0, // func_index + 0, // sig_index + 0, // name_offset + 0, // name_length + 0, // code_start_offset + 0, // code_end_offset + false, // import + false}); // export + CHECK(mod.functions.size() <= 127); + return static_cast(mod.functions.size() - 1); + } + byte AddImport(FunctionSig* sig) { + byte result = AddFunction(sig); + mod.functions[result].imported = true; + return result; + } + + void InitializeMemory() { + mod.has_memory = true; + mod.min_mem_pages = 1; + mod.max_mem_pages = 100; + } + + void InitializeFunctionTable() { + mod.function_tables.push_back( + {0, 0, true, std::vector(), false, false, SignatureMap()}); + } + + private: + WasmModule mod; +}; +} // namespace + TEST_F(FunctionBodyDecoderTest, Int32Const1) { byte code[] = {kExprI32Const, 0}; for (int i = -64; i <= 63; i++) { @@ -1023,6 +1077,9 @@ TEST_F(FunctionBodyDecoderTest, TypeConversions) { } TEST_F(FunctionBodyDecoderTest, MacrosStmt) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); EXPECT_VERIFIES(v_i, WASM_SET_LOCAL(0, WASM_I32V_3(87348))); EXPECT_VERIFIES(v_i, WASM_STORE_MEM(MachineType::Int32(), WASM_I32V_1(24), WASM_I32V_1(40))); @@ -1159,12 +1216,18 @@ TEST_F(FunctionBodyDecoderTest, AllSimpleExpressions) { } TEST_F(FunctionBodyDecoderTest, MemorySize) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); byte code[] = {kExprMemorySize, 0}; EXPECT_VERIFIES_C(i_i, code); EXPECT_FAILURE_C(f_ff, code); } TEST_F(FunctionBodyDecoderTest, LoadMemOffset) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); for (int offset = 0; offset < 128; offset += 7) { byte code[] = {kExprI32Const, 0, kExprI32LoadMem, ZERO_ALIGNMENT, static_cast(offset)}; @@ -1173,6 +1236,9 @@ TEST_F(FunctionBodyDecoderTest, LoadMemOffset) { } TEST_F(FunctionBodyDecoderTest, LoadMemAlignment) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); struct { WasmOpcode instruction; uint32_t maximum_aligment; @@ -1207,6 +1273,9 @@ TEST_F(FunctionBodyDecoderTest, LoadMemAlignment) { } TEST_F(FunctionBodyDecoderTest, StoreMemOffset) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); for (int offset = 0; offset < 128; offset += 7) { byte code[] = {WASM_STORE_MEM_OFFSET(MachineType::Int32(), offset, WASM_ZERO, WASM_ZERO)}; @@ -1215,6 +1284,9 @@ TEST_F(FunctionBodyDecoderTest, StoreMemOffset) { } TEST_F(FunctionBodyDecoderTest, StoreMemOffset_void) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); EXPECT_FAILURE(i_i, WASM_STORE_MEM_OFFSET(MachineType::Int32(), 0, WASM_ZERO, WASM_ZERO)); } @@ -1230,6 +1302,9 @@ TEST_F(FunctionBodyDecoderTest, StoreMemOffset_void) { #define VARINT4(x) BYTE0(x) | 0x80, BYTE1(x) | 0x80, BYTE2(x) | 0x80, BYTE3(x) TEST_F(FunctionBodyDecoderTest, LoadMemOffset_varint) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, VARINT1(0x45)); EXPECT_VERIFIES(i_i, WASM_ZERO, kExprI32LoadMem, ZERO_ALIGNMENT, @@ -1241,6 +1316,9 @@ TEST_F(FunctionBodyDecoderTest, LoadMemOffset_varint) { } TEST_F(FunctionBodyDecoderTest, StoreMemOffset_varint) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT, VARINT1(0x33)); EXPECT_VERIFIES(v_i, WASM_ZERO, WASM_ZERO, kExprI32StoreMem, ZERO_ALIGNMENT, @@ -1252,6 +1330,9 @@ TEST_F(FunctionBodyDecoderTest, StoreMemOffset_varint) { } TEST_F(FunctionBodyDecoderTest, AllLoadMemCombinations) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); for (size_t i = 0; i < arraysize(kValueTypes); i++) { ValueType local_type = kValueTypes[i]; for (size_t j = 0; j < arraysize(machineTypes); j++) { @@ -1268,6 +1349,9 @@ TEST_F(FunctionBodyDecoderTest, AllLoadMemCombinations) { } TEST_F(FunctionBodyDecoderTest, AllStoreMemCombinations) { + TestModuleEnv module_env; + module = &module_env; + module_env.InitializeMemory(); for (size_t i = 0; i < arraysize(kValueTypes); i++) { ValueType local_type = kValueTypes[i]; for (size_t j = 0; j < arraysize(machineTypes); j++) { @@ -1283,54 +1367,6 @@ TEST_F(FunctionBodyDecoderTest, AllStoreMemCombinations) { } } -namespace { -// A helper for tests that require a module environment for functions and -// globals. -class TestModuleEnv : public ModuleEnv { - public: - explicit TestModuleEnv(ModuleOrigin origin = kWasmOrigin) - : ModuleEnv(&mod, nullptr) { - mod.origin = origin; - } - byte AddGlobal(ValueType type, bool mutability = true) { - mod.globals.push_back({type, mutability, WasmInitExpr(), 0, false, false}); - CHECK(mod.globals.size() <= 127); - return static_cast(mod.globals.size() - 1); - } - byte AddSignature(FunctionSig* sig) { - mod.signatures.push_back(sig); - CHECK(mod.signatures.size() <= 127); - return static_cast(mod.signatures.size() - 1); - } - byte AddFunction(FunctionSig* sig) { - mod.functions.push_back({sig, // sig - 0, // func_index - 0, // sig_index - 0, // name_offset - 0, // name_length - 0, // code_start_offset - 0, // code_end_offset - false, // import - false}); // export - CHECK(mod.functions.size() <= 127); - return static_cast(mod.functions.size() - 1); - } - byte AddImport(FunctionSig* sig) { - byte result = AddFunction(sig); - mod.functions[result].imported = true; - return result; - } - - void InitializeFunctionTable() { - mod.function_tables.push_back( - {0, 0, true, std::vector(), false, false, SignatureMap()}); - } - - private: - WasmModule mod; -}; -} // namespace - TEST_F(FunctionBodyDecoderTest, SimpleCalls) { FunctionSig* sig = sigs.i_i(); TestModuleEnv module_env; @@ -1665,6 +1701,7 @@ TEST_F(FunctionBodyDecoderTest, AllSetGlobalCombinations) { TEST_F(FunctionBodyDecoderTest, WasmGrowMemory) { TestModuleEnv module_env; module = &module_env; + module_env.InitializeMemory(); byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0}; EXPECT_VERIFIES_C(i_i, code); @@ -1674,6 +1711,7 @@ TEST_F(FunctionBodyDecoderTest, WasmGrowMemory) { TEST_F(FunctionBodyDecoderTest, AsmJsGrowMemory) { TestModuleEnv module_env(kAsmJsOrigin); module = &module_env; + module_env.InitializeMemory(); byte code[] = {WASM_GET_LOCAL(0), kExprGrowMemory, 0}; EXPECT_FAILURE_C(i_i, code); @@ -1705,6 +1743,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) { { TestModuleEnv module_env(kAsmJsOrigin); module = &module_env; + module_env.InitializeMemory(); for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) { TestBinop(AsmJsBinOps[i].op, AsmJsBinOps[i].sig); } @@ -1713,6 +1752,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsBinOpsCheckOrigin) { { TestModuleEnv module_env; module = &module_env; + module_env.InitializeMemory(); for (size_t i = 0; i < arraysize(AsmJsBinOps); i++) { byte code[] = { WASM_BINOP(AsmJsBinOps[i].op, WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))}; @@ -1751,6 +1791,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) { { TestModuleEnv module_env(kAsmJsOrigin); module = &module_env; + module_env.InitializeMemory(); for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) { TestUnop(AsmJsUnOps[i].op, AsmJsUnOps[i].sig); } @@ -1759,6 +1800,7 @@ TEST_F(FunctionBodyDecoderTest, AsmJsUnOpsCheckOrigin) { { TestModuleEnv module_env; module = &module_env; + module_env.InitializeMemory(); for (size_t i = 0; i < arraysize(AsmJsUnOps); i++) { byte code[] = {WASM_UNOP(AsmJsUnOps[i].op, WASM_GET_LOCAL(0))}; EXPECT_FAILURE_SC(AsmJsUnOps[i].sig, code);