| Index: test/cctest/wasm/test-run-wasm-module.cc
|
| diff --git a/test/cctest/wasm/test-run-wasm-module.cc b/test/cctest/wasm/test-run-wasm-module.cc
|
| index 45a66957f6aa912fa033ebb06af308b8915bfa13..a9694b4882eda999d762482112fb09adb5d4bd36 100644
|
| --- a/test/cctest/wasm/test-run-wasm-module.cc
|
| +++ b/test/cctest/wasm/test-run-wasm-module.cc
|
| @@ -23,6 +23,16 @@ using namespace v8::internal::compiler;
|
| using namespace v8::internal::wasm;
|
|
|
| namespace {
|
| +void Cleanup(Isolate* isolate = nullptr) {
|
| + // By sending a low memory notifications, we will try hard to collect all
|
| + // garbage and will therefore also invoke all weak callbacks of actually
|
| + // unreachable persistent handles.
|
| + if (!isolate) {
|
| + isolate = CcTest::InitIsolateOnce();
|
| + }
|
| + reinterpret_cast<v8::Isolate*>(isolate)->LowMemoryNotification();
|
| +}
|
| +
|
| void TestModule(Zone* zone, WasmModuleBuilder* builder,
|
| int32_t expected_result) {
|
| ZoneBuffer buffer(zone);
|
| @@ -55,122 +65,141 @@ void ExportAsMain(WasmFunctionBuilder* f) { f->ExportAs(CStrVector("main")); }
|
| } // namespace
|
|
|
| TEST(Run_WasmModule_Return114) {
|
| - static const int32_t kReturnValue = 114;
|
| - TestSignatures sigs;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f);
|
| - byte code[] = {WASM_I8(kReturnValue)};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModule(&zone, builder, kReturnValue);
|
| + {
|
| + static const int32_t kReturnValue = 114;
|
| + TestSignatures sigs;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_I8(kReturnValue)};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModule(&zone, builder, kReturnValue);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_CallAdd) {
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - TestSignatures sigs;
|
| + {
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + TestSignatures sigs;
|
|
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
|
|
| - WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_ii());
|
| - uint16_t param1 = 0;
|
| - uint16_t param2 = 1;
|
| - byte code1[] = {WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))};
|
| - f1->EmitCode(code1, sizeof(code1));
|
| + WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_ii());
|
| + uint16_t param1 = 0;
|
| + uint16_t param2 = 1;
|
| + byte code1[] = {
|
| + WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))};
|
| + f1->EmitCode(code1, sizeof(code1));
|
|
|
| - WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v());
|
| + WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v());
|
|
|
| - ExportAsMain(f2);
|
| - byte code2[] = {
|
| - WASM_CALL_FUNCTION(f1->func_index(), WASM_I8(77), WASM_I8(22))};
|
| - f2->EmitCode(code2, sizeof(code2));
|
| - TestModule(&zone, builder, 99);
|
| + ExportAsMain(f2);
|
| + byte code2[] = {
|
| + WASM_CALL_FUNCTION(f1->func_index(), WASM_I8(77), WASM_I8(22))};
|
| + f2->EmitCode(code2, sizeof(code2));
|
| + TestModule(&zone, builder, 99);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_ReadLoadedDataSegment) {
|
| - static const byte kDataSegmentDest0 = 12;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - TestSignatures sigs;
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| -
|
| - ExportAsMain(f);
|
| - byte code[] = {
|
| - WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))};
|
| - f->EmitCode(code, sizeof(code));
|
| - byte data[] = {0xaa, 0xbb, 0xcc, 0xdd};
|
| - builder->AddDataSegment(data, sizeof(data), kDataSegmentDest0);
|
| - TestModule(&zone, builder, 0xddccbbaa);
|
| + {
|
| + static const byte kDataSegmentDest0 = 12;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + TestSignatures sigs;
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| +
|
| + ExportAsMain(f);
|
| + byte code[] = {
|
| + WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))};
|
| + f->EmitCode(code, sizeof(code));
|
| + byte data[] = {0xaa, 0xbb, 0xcc, 0xdd};
|
| + builder->AddDataSegment(data, sizeof(data), kDataSegmentDest0);
|
| + TestModule(&zone, builder, 0xddccbbaa);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_CheckMemoryIsZero) {
|
| - static const int kCheckSize = 16 * 1024;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - TestSignatures sigs;
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| -
|
| - uint16_t localIndex = f->AddLocal(kAstI32);
|
| - ExportAsMain(f);
|
| - byte code[] = {WASM_BLOCK_I(
|
| - WASM_WHILE(
|
| - WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_3(kCheckSize)),
|
| - WASM_IF_ELSE(
|
| - WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)),
|
| - WASM_BRV(3, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))),
|
| - WASM_I8(11))};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModule(&zone, builder, 11);
|
| + {
|
| + static const int kCheckSize = 16 * 1024;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + TestSignatures sigs;
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| +
|
| + uint16_t localIndex = f->AddLocal(kAstI32);
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_BLOCK_I(
|
| + WASM_WHILE(
|
| + WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_3(kCheckSize)),
|
| + WASM_IF_ELSE(
|
| + WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)),
|
| + WASM_BRV(3, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))),
|
| + WASM_I8(11))};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModule(&zone, builder, 11);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_CallMain_recursive) {
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - TestSignatures sigs;
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| -
|
| - uint16_t localIndex = f->AddLocal(kAstI32);
|
| - ExportAsMain(f);
|
| - byte code[] = {
|
| - WASM_SET_LOCAL(localIndex,
|
| - WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
|
| - WASM_IF_ELSE_I(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)),
|
| - WASM_SEQ(WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
|
| - WASM_INC_LOCAL(localIndex)),
|
| - WASM_CALL_FUNCTION0(0)),
|
| - WASM_I8(55))};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModule(&zone, builder, 55);
|
| + {
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + TestSignatures sigs;
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| +
|
| + uint16_t localIndex = f->AddLocal(kAstI32);
|
| + ExportAsMain(f);
|
| + byte code[] = {
|
| + WASM_SET_LOCAL(localIndex,
|
| + WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)),
|
| + WASM_IF_ELSE_I(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)),
|
| + WASM_SEQ(WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
|
| + WASM_INC_LOCAL(localIndex)),
|
| + WASM_CALL_FUNCTION0(0)),
|
| + WASM_I8(55))};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModule(&zone, builder, 55);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_Global) {
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - TestSignatures sigs;
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - uint32_t global1 = builder->AddGlobal(kAstI32, 0);
|
| - uint32_t global2 = builder->AddGlobal(kAstI32, 0);
|
| - WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v());
|
| - byte code1[] = {
|
| - WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))};
|
| - f1->EmitCode(code1, sizeof(code1));
|
| - WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f2);
|
| - byte code2[] = {WASM_SET_GLOBAL(global1, WASM_I32V_1(56)),
|
| - WASM_SET_GLOBAL(global2, WASM_I32V_1(41)),
|
| - WASM_RETURN1(WASM_CALL_FUNCTION0(f1->func_index()))};
|
| - f2->EmitCode(code2, sizeof(code2));
|
| - TestModule(&zone, builder, 97);
|
| + {
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + TestSignatures sigs;
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + uint32_t global1 = builder->AddGlobal(kAstI32, 0);
|
| + uint32_t global2 = builder->AddGlobal(kAstI32, 0);
|
| + WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v());
|
| + byte code1[] = {
|
| + WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))};
|
| + f1->EmitCode(code1, sizeof(code1));
|
| + WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f2);
|
| + byte code2[] = {WASM_SET_GLOBAL(global1, WASM_I32V_1(56)),
|
| + WASM_SET_GLOBAL(global2, WASM_I32V_1(41)),
|
| + WASM_RETURN1(WASM_CALL_FUNCTION0(f1->func_index()))};
|
| + f2->EmitCode(code2, sizeof(code2));
|
| + TestModule(&zone, builder, 97);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| // Approximate gtest TEST_F style, in case we adopt gtest.
|
| @@ -338,75 +367,100 @@ const char* WasmSerializationTest::kFunctionName = "increment";
|
|
|
| TEST(DeserializeValidModule) {
|
| WasmSerializationTest test;
|
| - HandleScope scope(test.current_isolate());
|
| - test.DeserializeAndRun();
|
| + {
|
| + HandleScope scope(test.current_isolate());
|
| + test.DeserializeAndRun();
|
| + }
|
| + Cleanup(test.current_isolate());
|
| + Cleanup();
|
| }
|
|
|
| TEST(DeserializeMismatchingVersion) {
|
| WasmSerializationTest test;
|
| - HandleScope scope(test.current_isolate());
|
| - test.InvalidateVersion();
|
| - test.DeserializeAndRun();
|
| + {
|
| + HandleScope scope(test.current_isolate());
|
| + test.InvalidateVersion();
|
| + test.DeserializeAndRun();
|
| + }
|
| + Cleanup(test.current_isolate());
|
| + Cleanup();
|
| }
|
|
|
| TEST(DeserializeNoSerializedData) {
|
| WasmSerializationTest test;
|
| - HandleScope scope(test.current_isolate());
|
| - test.ClearSerializedData();
|
| - test.DeserializeAndRun();
|
| + {
|
| + HandleScope scope(test.current_isolate());
|
| + test.ClearSerializedData();
|
| + test.DeserializeAndRun();
|
| + }
|
| + Cleanup(test.current_isolate());
|
| + Cleanup();
|
| }
|
|
|
| TEST(DeserializeWireBytesAndSerializedDataInvalid) {
|
| WasmSerializationTest test;
|
| - HandleScope scope(test.current_isolate());
|
| - test.InvalidateVersion();
|
| - test.InvalidateWireBytes();
|
| - test.Deserialize();
|
| + {
|
| + HandleScope scope(test.current_isolate());
|
| + test.InvalidateVersion();
|
| + test.InvalidateWireBytes();
|
| + test.Deserialize();
|
| + }
|
| + Cleanup(test.current_isolate());
|
| + Cleanup();
|
| }
|
|
|
| TEST(MemorySize) {
|
| - // Initial memory size is 16, see wasm-module-builder.cc
|
| - static const int kExpectedValue = 16;
|
| - TestSignatures sigs;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f);
|
| - byte code[] = {WASM_MEMORY_SIZE};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModule(&zone, builder, kExpectedValue);
|
| + {
|
| + // Initial memory size is 16, see wasm-module-builder.cc
|
| + static const int kExpectedValue = 16;
|
| + TestSignatures sigs;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_MEMORY_SIZE};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModule(&zone, builder, kExpectedValue);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_MemSize_GrowMem) {
|
| - // Initial memory size = 16 + GrowMemory(10)
|
| - static const int kExpectedValue = 26;
|
| - TestSignatures sigs;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f);
|
| - byte code[] = {WASM_GROW_MEMORY(WASM_I8(10)), WASM_DROP, WASM_MEMORY_SIZE};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModule(&zone, builder, kExpectedValue);
|
| + {
|
| + // Initial memory size = 16 + GrowMemory(10)
|
| + static const int kExpectedValue = 26;
|
| + TestSignatures sigs;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_GROW_MEMORY(WASM_I8(10)), WASM_DROP, WASM_MEMORY_SIZE};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModule(&zone, builder, kExpectedValue);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(GrowMemoryZero) {
|
| - // Initial memory size is 16, see wasm-module-builder.cc
|
| - static const int kExpectedValue = 16;
|
| - TestSignatures sigs;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f);
|
| - byte code[] = {WASM_GROW_MEMORY(WASM_I32V(0))};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModule(&zone, builder, kExpectedValue);
|
| + {
|
| + // Initial memory size is 16, see wasm-module-builder.cc
|
| + static const int kExpectedValue = 16;
|
| + TestSignatures sigs;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_GROW_MEMORY(WASM_I32V(0))};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModule(&zone, builder, kExpectedValue);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| class InterruptThread : public v8::base::Thread {
|
| @@ -441,273 +495,297 @@ class InterruptThread : public v8::base::Thread {
|
| };
|
|
|
| TEST(TestInterruptLoop) {
|
| - // Do not dump the module of this test because it contains an infinite loop.
|
| - if (FLAG_dump_wasm_module) return;
|
| -
|
| - // This test tests that WebAssembly loops can be interrupted, i.e. that if an
|
| - // InterruptCallback is registered by {Isolate::RequestInterrupt}, then the
|
| - // InterruptCallback is eventually called even if a loop in WebAssembly code
|
| - // is executed.
|
| - // Test setup:
|
| - // The main thread executes a WebAssembly function with a loop. In the loop
|
| - // {signal_value_} is written to memory to signal a helper thread that the
|
| - // main thread reached the loop in the WebAssembly program. When the helper
|
| - // thread reads {signal_value_} from memory, it registers the
|
| - // InterruptCallback. Upon exeution, the InterruptCallback write into the
|
| - // WebAssemblyMemory to end the loop in the WebAssembly program.
|
| - TestSignatures sigs;
|
| - Isolate* isolate = CcTest::InitIsolateOnce();
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f);
|
| - byte code[] = {WASM_LOOP(WASM_IFB(
|
| - WASM_NOT(WASM_LOAD_MEM(
|
| + {
|
| + // Do not dump the module of this test because it contains an infinite loop.
|
| + if (FLAG_dump_wasm_module) return;
|
| +
|
| + // This test tests that WebAssembly loops can be interrupted, i.e. that if
|
| + // an
|
| + // InterruptCallback is registered by {Isolate::RequestInterrupt}, then the
|
| + // InterruptCallback is eventually called even if a loop in WebAssembly code
|
| + // is executed.
|
| + // Test setup:
|
| + // The main thread executes a WebAssembly function with a loop. In the loop
|
| + // {signal_value_} is written to memory to signal a helper thread that the
|
| + // main thread reached the loop in the WebAssembly program. When the helper
|
| + // thread reads {signal_value_} from memory, it registers the
|
| + // InterruptCallback. Upon exeution, the InterruptCallback write into the
|
| + // WebAssemblyMemory to end the loop in the WebAssembly program.
|
| + TestSignatures sigs;
|
| + Isolate* isolate = CcTest::InitIsolateOnce();
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f);
|
| + byte code[] = {
|
| + WASM_LOOP(
|
| + WASM_IFB(WASM_NOT(WASM_LOAD_MEM(
|
| MachineType::Int32(),
|
| WASM_I32V(InterruptThread::interrupt_location_ * 4))),
|
| WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
|
| WASM_I32V(InterruptThread::signal_value_)),
|
| WASM_BR(1))),
|
| - WASM_I32V(121)};
|
| - f->EmitCode(code, sizeof(code));
|
| - ZoneBuffer buffer(&zone);
|
| - builder->WriteTo(buffer);
|
| -
|
| - HandleScope scope(isolate);
|
| - testing::SetupIsolateForWasmModule(isolate);
|
| - ErrorThrower thrower(isolate, "Test");
|
| - const Handle<JSObject> instance =
|
| - testing::CompileInstantiateWasmModuleForTesting(
|
| - isolate, &thrower, buffer.begin(), buffer.end(),
|
| - ModuleOrigin::kWasmOrigin);
|
| - CHECK(!instance.is_null());
|
| -
|
| - MaybeHandle<JSArrayBuffer> maybe_memory =
|
| - GetInstanceMemory(isolate, instance);
|
| - Handle<JSArrayBuffer> memory = maybe_memory.ToHandleChecked();
|
| - int32_t* memory_array = reinterpret_cast<int32_t*>(memory->backing_store());
|
| + WASM_I32V(121)};
|
| + f->EmitCode(code, sizeof(code));
|
| + ZoneBuffer buffer(&zone);
|
| + builder->WriteTo(buffer);
|
|
|
| - InterruptThread thread(isolate, memory_array);
|
| - thread.Start();
|
| - testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr,
|
| - ModuleOrigin::kWasmOrigin);
|
| - int32_t val = memory_array[InterruptThread::interrupt_location_];
|
| - CHECK_EQ(InterruptThread::interrupt_value_,
|
| - ReadLittleEndianValue<int32_t>(&val));
|
| + HandleScope scope(isolate);
|
| + testing::SetupIsolateForWasmModule(isolate);
|
| + ErrorThrower thrower(isolate, "Test");
|
| + const Handle<JSObject> instance =
|
| + testing::CompileInstantiateWasmModuleForTesting(
|
| + isolate, &thrower, buffer.begin(), buffer.end(),
|
| + ModuleOrigin::kWasmOrigin);
|
| + CHECK(!instance.is_null());
|
| +
|
| + MaybeHandle<JSArrayBuffer> maybe_memory =
|
| + GetInstanceMemory(isolate, instance);
|
| + Handle<JSArrayBuffer> memory = maybe_memory.ToHandleChecked();
|
| + int32_t* memory_array = reinterpret_cast<int32_t*>(memory->backing_store());
|
| +
|
| + InterruptThread thread(isolate, memory_array);
|
| + thread.Start();
|
| + testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr,
|
| + ModuleOrigin::kWasmOrigin);
|
| + int32_t val = memory_array[InterruptThread::interrupt_location_];
|
| + CHECK_EQ(InterruptThread::interrupt_value_,
|
| + ReadLittleEndianValue<int32_t>(&val));
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_GrowMemoryInIf) {
|
| - TestSignatures sigs;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f);
|
| - byte code[] = {WASM_IF_ELSE_I(WASM_I32V(0), WASM_GROW_MEMORY(WASM_I32V(1)),
|
| - WASM_I32V(12))};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModule(&zone, builder, 12);
|
| + {
|
| + TestSignatures sigs;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_IF_ELSE_I(WASM_I32V(0), WASM_GROW_MEMORY(WASM_I32V(1)),
|
| + WASM_I32V(12))};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModule(&zone, builder, 12);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_GrowMemOobOffset) {
|
| - static const int kPageSize = 0x10000;
|
| - // Initial memory size = 16 + GrowMemory(10)
|
| - static const int index = kPageSize * 17 + 4;
|
| - int value = 0xaced;
|
| - TestSignatures sigs;
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| - ExportAsMain(f);
|
| - byte code[] = {
|
| - WASM_GROW_MEMORY(WASM_I8(1)),
|
| - WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), WASM_I32V(value))};
|
| - f->EmitCode(code, sizeof(code));
|
| - TestModuleException(&zone, builder);
|
| + {
|
| + static const int kPageSize = 0x10000;
|
| + // Initial memory size = 16 + GrowMemory(10)
|
| + static const int index = kPageSize * 17 + 4;
|
| + int value = 0xaced;
|
| + TestSignatures sigs;
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| +
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_GROW_MEMORY(WASM_I8(1)),
|
| + WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index),
|
| + WASM_I32V(value))};
|
| + f->EmitCode(code, sizeof(code));
|
| + TestModuleException(&zone, builder);
|
| + }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_GrowMemOobFixedIndex) {
|
| - static const int kPageSize = 0x10000;
|
| - // Initial memory size = 16 + GrowMemory(10)
|
| - static const int index = kPageSize * 26 + 4;
|
| - int value = 0xaced;
|
| - TestSignatures sigs;
|
| - Isolate* isolate = CcTest::InitIsolateOnce();
|
| - Zone zone(isolate->allocator(), ZONE_NAME);
|
| + {
|
| + static const int kPageSize = 0x10000;
|
| + // Initial memory size = 16 + GrowMemory(10)
|
| + static const int index = kPageSize * 26 + 4;
|
| + int value = 0xaced;
|
| + TestSignatures sigs;
|
| + Isolate* isolate = CcTest::InitIsolateOnce();
|
| + Zone zone(isolate->allocator(), ZONE_NAME);
|
|
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
|
| - ExportAsMain(f);
|
| - byte code[] = {
|
| - WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP,
|
| - WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), WASM_I32V(value)),
|
| - WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))};
|
| - f->EmitCode(code, sizeof(code));
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP,
|
| + WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index),
|
| + WASM_I32V(value)),
|
| + WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))};
|
| + f->EmitCode(code, sizeof(code));
|
|
|
| - HandleScope scope(isolate);
|
| - ZoneBuffer buffer(&zone);
|
| - builder->WriteTo(buffer);
|
| - testing::SetupIsolateForWasmModule(isolate);
|
| + HandleScope scope(isolate);
|
| + ZoneBuffer buffer(&zone);
|
| + builder->WriteTo(buffer);
|
| + testing::SetupIsolateForWasmModule(isolate);
|
|
|
| - ErrorThrower thrower(isolate, "Test");
|
| - Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting(
|
| - isolate, &thrower, buffer.begin(), buffer.end(),
|
| - ModuleOrigin::kWasmOrigin);
|
| - CHECK(!instance.is_null());
|
| + ErrorThrower thrower(isolate, "Test");
|
| + Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting(
|
| + isolate, &thrower, buffer.begin(), buffer.end(),
|
| + ModuleOrigin::kWasmOrigin);
|
| + CHECK(!instance.is_null());
|
| +
|
| + // Initial memory size is 16 pages, should trap till index > MemSize on
|
| + // consecutive GrowMem calls
|
| + for (uint32_t i = 1; i < 5; i++) {
|
| + Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(i), isolate)};
|
| + v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
|
| + testing::RunWasmModuleForTesting(isolate, instance, 1, params,
|
| + ModuleOrigin::kWasmOrigin);
|
| + CHECK(try_catch.HasCaught());
|
| + isolate->clear_pending_exception();
|
| + }
|
|
|
| - // Initial memory size is 16 pages, should trap till index > MemSize on
|
| - // consecutive GrowMem calls
|
| - for (uint32_t i = 1; i < 5; i++) {
|
| - Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(i), isolate)};
|
| - v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
|
| - testing::RunWasmModuleForTesting(isolate, instance, 1, params,
|
| - ModuleOrigin::kWasmOrigin);
|
| - CHECK(try_catch.HasCaught());
|
| - isolate->clear_pending_exception();
|
| + Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(1), isolate)};
|
| + int32_t result = testing::RunWasmModuleForTesting(
|
| + isolate, instance, 1, params, ModuleOrigin::kWasmOrigin);
|
| + CHECK(result == 0xaced);
|
| }
|
| -
|
| - Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(1), isolate)};
|
| - int32_t result = testing::RunWasmModuleForTesting(
|
| - isolate, instance, 1, params, ModuleOrigin::kWasmOrigin);
|
| - CHECK(result == 0xaced);
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_GrowMemOobVariableIndex) {
|
| - static const int kPageSize = 0x10000;
|
| - int value = 0xaced;
|
| - TestSignatures sigs;
|
| - Isolate* isolate = CcTest::InitIsolateOnce();
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
|
| - ExportAsMain(f);
|
| - byte code[] = {
|
| - WASM_GROW_MEMORY(WASM_I8(1)), WASM_DROP,
|
| - WASM_STORE_MEM(MachineType::Int32(), WASM_GET_LOCAL(0), WASM_I32V(value)),
|
| - WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))};
|
| - f->EmitCode(code, sizeof(code));
|
| + {
|
| + static const int kPageSize = 0x10000;
|
| + int value = 0xaced;
|
| + TestSignatures sigs;
|
| + Isolate* isolate = CcTest::InitIsolateOnce();
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
|
|
| - HandleScope scope(isolate);
|
| - ZoneBuffer buffer(&zone);
|
| - builder->WriteTo(buffer);
|
| - testing::SetupIsolateForWasmModule(isolate);
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i());
|
| + ExportAsMain(f);
|
| + byte code[] = {WASM_GROW_MEMORY(WASM_I8(1)), WASM_DROP,
|
| + WASM_STORE_MEM(MachineType::Int32(), WASM_GET_LOCAL(0),
|
| + WASM_I32V(value)),
|
| + WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))};
|
| + f->EmitCode(code, sizeof(code));
|
|
|
| - ErrorThrower thrower(isolate, "Test");
|
| - Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting(
|
| - isolate, &thrower, buffer.begin(), buffer.end(),
|
| - ModuleOrigin::kWasmOrigin);
|
| + HandleScope scope(isolate);
|
| + ZoneBuffer buffer(&zone);
|
| + builder->WriteTo(buffer);
|
| + testing::SetupIsolateForWasmModule(isolate);
|
|
|
| - CHECK(!instance.is_null());
|
| + ErrorThrower thrower(isolate, "Test");
|
| + Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting(
|
| + isolate, &thrower, buffer.begin(), buffer.end(),
|
| + ModuleOrigin::kWasmOrigin);
|
| +
|
| + CHECK(!instance.is_null());
|
| +
|
| + // Initial memory size is 16 pages, should trap till index > MemSize on
|
| + // consecutive GrowMem calls
|
| + for (int i = 1; i < 5; i++) {
|
| + Handle<Object> params[1] = {
|
| + Handle<Object>(Smi::FromInt((16 + i) * kPageSize - 3), isolate)};
|
| + v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
|
| + testing::RunWasmModuleForTesting(isolate, instance, 1, params,
|
| + ModuleOrigin::kWasmOrigin);
|
| + CHECK(try_catch.HasCaught());
|
| + isolate->clear_pending_exception();
|
| + }
|
| +
|
| + for (int i = 1; i < 5; i++) {
|
| + Handle<Object> params[1] = {
|
| + Handle<Object>(Smi::FromInt((20 + i) * kPageSize - 4), isolate)};
|
| + int32_t result = testing::RunWasmModuleForTesting(
|
| + isolate, instance, 1, params, ModuleOrigin::kWasmOrigin);
|
| + CHECK(result == 0xaced);
|
| + }
|
|
|
| - // Initial memory size is 16 pages, should trap till index > MemSize on
|
| - // consecutive GrowMem calls
|
| - for (int i = 1; i < 5; i++) {
|
| - Handle<Object> params[1] = {
|
| - Handle<Object>(Smi::FromInt((16 + i) * kPageSize - 3), isolate)};
|
| v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
|
| + Handle<Object> params[1] = {
|
| + Handle<Object>(Smi::FromInt(25 * kPageSize), isolate)};
|
| testing::RunWasmModuleForTesting(isolate, instance, 1, params,
|
| ModuleOrigin::kWasmOrigin);
|
| CHECK(try_catch.HasCaught());
|
| isolate->clear_pending_exception();
|
| }
|
| -
|
| - for (int i = 1; i < 5; i++) {
|
| - Handle<Object> params[1] = {
|
| - Handle<Object>(Smi::FromInt((20 + i) * kPageSize - 4), isolate)};
|
| - int32_t result = testing::RunWasmModuleForTesting(
|
| - isolate, instance, 1, params, ModuleOrigin::kWasmOrigin);
|
| - CHECK(result == 0xaced);
|
| - }
|
| -
|
| - v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
|
| - Handle<Object> params[1] = {
|
| - Handle<Object>(Smi::FromInt(25 * kPageSize), isolate)};
|
| - testing::RunWasmModuleForTesting(isolate, instance, 1, params,
|
| - ModuleOrigin::kWasmOrigin);
|
| - CHECK(try_catch.HasCaught());
|
| - isolate->clear_pending_exception();
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_Global_init) {
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - TestSignatures sigs;
|
| -
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - uint32_t global1 =
|
| - builder->AddGlobal(kAstI32, false, false, WasmInitExpr(777777));
|
| - uint32_t global2 =
|
| - builder->AddGlobal(kAstI32, false, false, WasmInitExpr(222222));
|
| - WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v());
|
| - byte code[] = {
|
| - WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))};
|
| - f1->EmitCode(code, sizeof(code));
|
| - ExportAsMain(f1);
|
| - TestModule(&zone, builder, 999999);
|
| -}
|
| -
|
| -template <typename CType>
|
| -static void RunWasmModuleGlobalInitTest(LocalType type, CType expected) {
|
| - v8::internal::AccountingAllocator allocator;
|
| - Zone zone(&allocator, ZONE_NAME);
|
| - TestSignatures sigs;
|
| -
|
| - LocalType types[] = {type};
|
| - FunctionSig sig(1, 0, types);
|
| + {
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + TestSignatures sigs;
|
|
|
| - for (int padding = 0; padding < 5; padding++) {
|
| - // Test with a simple initializer
|
| WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| -
|
| - for (int i = 0; i < padding; i++) { // pad global before
|
| - builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 20000));
|
| - }
|
| - uint32_t global =
|
| - builder->AddGlobal(type, false, false, WasmInitExpr(expected));
|
| - for (int i = 0; i < padding; i++) { // pad global after
|
| - builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 30000));
|
| - }
|
| -
|
| - WasmFunctionBuilder* f1 = builder->AddFunction(&sig);
|
| - byte code[] = {WASM_GET_GLOBAL(global)};
|
| + uint32_t global1 =
|
| + builder->AddGlobal(kAstI32, false, false, WasmInitExpr(777777));
|
| + uint32_t global2 =
|
| + builder->AddGlobal(kAstI32, false, false, WasmInitExpr(222222));
|
| + WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v());
|
| + byte code[] = {
|
| + WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))};
|
| f1->EmitCode(code, sizeof(code));
|
| ExportAsMain(f1);
|
| - TestModule(&zone, builder, expected);
|
| + TestModule(&zone, builder, 999999);
|
| }
|
| + Cleanup();
|
| +}
|
|
|
| - for (int padding = 0; padding < 5; padding++) {
|
| - // Test with a global index
|
| - WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| - for (int i = 0; i < padding; i++) { // pad global before
|
| - builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 40000));
|
| - }
|
| -
|
| - uint32_t global1 =
|
| - builder->AddGlobal(type, false, false, WasmInitExpr(expected));
|
| +template <typename CType>
|
| +static void RunWasmModuleGlobalInitTest(LocalType type, CType expected) {
|
| + {
|
| + v8::internal::AccountingAllocator allocator;
|
| + Zone zone(&allocator, ZONE_NAME);
|
| + TestSignatures sigs;
|
|
|
| - for (int i = 0; i < padding; i++) { // pad global middle
|
| - builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 50000));
|
| + LocalType types[] = {type};
|
| + FunctionSig sig(1, 0, types);
|
| +
|
| + for (int padding = 0; padding < 5; padding++) {
|
| + // Test with a simple initializer
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| +
|
| + for (int i = 0; i < padding; i++) { // pad global before
|
| + builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 20000));
|
| + }
|
| + uint32_t global =
|
| + builder->AddGlobal(type, false, false, WasmInitExpr(expected));
|
| + for (int i = 0; i < padding; i++) { // pad global after
|
| + builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 30000));
|
| + }
|
| +
|
| + WasmFunctionBuilder* f1 = builder->AddFunction(&sig);
|
| + byte code[] = {WASM_GET_GLOBAL(global)};
|
| + f1->EmitCode(code, sizeof(code));
|
| + ExportAsMain(f1);
|
| + TestModule(&zone, builder, expected);
|
| }
|
|
|
| - uint32_t global2 = builder->AddGlobal(
|
| - type, false, false, WasmInitExpr(WasmInitExpr::kGlobalIndex, global1));
|
| -
|
| - for (int i = 0; i < padding; i++) { // pad global after
|
| - builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 60000));
|
| + for (int padding = 0; padding < 5; padding++) {
|
| + // Test with a global index
|
| + WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
|
| + for (int i = 0; i < padding; i++) { // pad global before
|
| + builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 40000));
|
| + }
|
| +
|
| + uint32_t global1 =
|
| + builder->AddGlobal(type, false, false, WasmInitExpr(expected));
|
| +
|
| + for (int i = 0; i < padding; i++) { // pad global middle
|
| + builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 50000));
|
| + }
|
| +
|
| + uint32_t global2 =
|
| + builder->AddGlobal(type, false, false,
|
| + WasmInitExpr(WasmInitExpr::kGlobalIndex, global1));
|
| +
|
| + for (int i = 0; i < padding; i++) { // pad global after
|
| + builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 60000));
|
| + }
|
| +
|
| + WasmFunctionBuilder* f1 = builder->AddFunction(&sig);
|
| + byte code[] = {WASM_GET_GLOBAL(global2)};
|
| + f1->EmitCode(code, sizeof(code));
|
| + ExportAsMain(f1);
|
| + TestModule(&zone, builder, expected);
|
| }
|
| -
|
| - WasmFunctionBuilder* f1 = builder->AddFunction(&sig);
|
| - byte code[] = {WASM_GET_GLOBAL(global2)};
|
| - f1->EmitCode(code, sizeof(code));
|
| - ExportAsMain(f1);
|
| - TestModule(&zone, builder, expected);
|
| }
|
| + Cleanup();
|
| }
|
|
|
| TEST(Run_WasmModule_Global_i32) {
|
|
|