| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdlib.h> | 5 #include <stdlib.h> |
| 6 #include <string.h> | 6 #include <string.h> |
| 7 | 7 |
| 8 #include "src/snapshot/code-serializer.h" | 8 #include "src/snapshot/code-serializer.h" |
| 9 #include "src/version.h" | 9 #include "src/version.h" |
| 10 #include "src/wasm/module-decoder.h" | 10 #include "src/wasm/module-decoder.h" |
| 11 #include "src/wasm/wasm-macro-gen.h" | 11 #include "src/wasm/wasm-macro-gen.h" |
| 12 #include "src/wasm/wasm-module-builder.h" | 12 #include "src/wasm/wasm-module-builder.h" |
| 13 #include "src/wasm/wasm-module.h" | 13 #include "src/wasm/wasm-module.h" |
| 14 #include "src/wasm/wasm-opcodes.h" | 14 #include "src/wasm/wasm-opcodes.h" |
| 15 | 15 |
| 16 #include "test/cctest/cctest.h" | 16 #include "test/cctest/cctest.h" |
| 17 #include "test/common/wasm/test-signatures.h" | 17 #include "test/common/wasm/test-signatures.h" |
| 18 #include "test/common/wasm/wasm-module-runner.h" | 18 #include "test/common/wasm/wasm-module-runner.h" |
| 19 | 19 |
| 20 using namespace v8::base; | 20 using namespace v8::base; |
| 21 using namespace v8::internal; | 21 using namespace v8::internal; |
| 22 using namespace v8::internal::compiler; | 22 using namespace v8::internal::compiler; |
| 23 using namespace v8::internal::wasm; | 23 using namespace v8::internal::wasm; |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 void Cleanup(Isolate* isolate = nullptr) { |
| 27 // By sending a low memory notifications, we will try hard to collect all |
| 28 // garbage and will therefore also invoke all weak callbacks of actually |
| 29 // unreachable persistent handles. |
| 30 if (!isolate) { |
| 31 isolate = CcTest::InitIsolateOnce(); |
| 32 } |
| 33 reinterpret_cast<v8::Isolate*>(isolate)->LowMemoryNotification(); |
| 34 } |
| 35 |
| 26 void TestModule(Zone* zone, WasmModuleBuilder* builder, | 36 void TestModule(Zone* zone, WasmModuleBuilder* builder, |
| 27 int32_t expected_result) { | 37 int32_t expected_result) { |
| 28 ZoneBuffer buffer(zone); | 38 ZoneBuffer buffer(zone); |
| 29 builder->WriteTo(buffer); | 39 builder->WriteTo(buffer); |
| 30 | 40 |
| 31 Isolate* isolate = CcTest::InitIsolateOnce(); | 41 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 32 HandleScope scope(isolate); | 42 HandleScope scope(isolate); |
| 33 testing::SetupIsolateForWasmModule(isolate); | 43 testing::SetupIsolateForWasmModule(isolate); |
| 34 int32_t result = testing::CompileAndRunWasmModule( | 44 int32_t result = testing::CompileAndRunWasmModule( |
| 35 isolate, buffer.begin(), buffer.end(), ModuleOrigin::kWasmOrigin); | 45 isolate, buffer.begin(), buffer.end(), ModuleOrigin::kWasmOrigin); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 48 ModuleOrigin::kWasmOrigin); | 58 ModuleOrigin::kWasmOrigin); |
| 49 CHECK(try_catch.HasCaught()); | 59 CHECK(try_catch.HasCaught()); |
| 50 isolate->clear_pending_exception(); | 60 isolate->clear_pending_exception(); |
| 51 } | 61 } |
| 52 | 62 |
| 53 void ExportAsMain(WasmFunctionBuilder* f) { f->ExportAs(CStrVector("main")); } | 63 void ExportAsMain(WasmFunctionBuilder* f) { f->ExportAs(CStrVector("main")); } |
| 54 | 64 |
| 55 } // namespace | 65 } // namespace |
| 56 | 66 |
| 57 TEST(Run_WasmModule_Return114) { | 67 TEST(Run_WasmModule_Return114) { |
| 58 static const int32_t kReturnValue = 114; | 68 { |
| 59 TestSignatures sigs; | 69 static const int32_t kReturnValue = 114; |
| 60 v8::internal::AccountingAllocator allocator; | 70 TestSignatures sigs; |
| 61 Zone zone(&allocator, ZONE_NAME); | 71 v8::internal::AccountingAllocator allocator; |
| 72 Zone zone(&allocator, ZONE_NAME); |
| 62 | 73 |
| 63 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 74 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 64 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 75 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 65 ExportAsMain(f); | 76 ExportAsMain(f); |
| 66 byte code[] = {WASM_I8(kReturnValue)}; | 77 byte code[] = {WASM_I8(kReturnValue)}; |
| 67 f->EmitCode(code, sizeof(code)); | 78 f->EmitCode(code, sizeof(code)); |
| 68 TestModule(&zone, builder, kReturnValue); | 79 TestModule(&zone, builder, kReturnValue); |
| 80 } |
| 81 Cleanup(); |
| 69 } | 82 } |
| 70 | 83 |
| 71 TEST(Run_WasmModule_CallAdd) { | 84 TEST(Run_WasmModule_CallAdd) { |
| 72 v8::internal::AccountingAllocator allocator; | 85 { |
| 73 Zone zone(&allocator, ZONE_NAME); | 86 v8::internal::AccountingAllocator allocator; |
| 74 TestSignatures sigs; | 87 Zone zone(&allocator, ZONE_NAME); |
| 88 TestSignatures sigs; |
| 75 | 89 |
| 76 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 90 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 77 | 91 |
| 78 WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_ii()); | 92 WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_ii()); |
| 79 uint16_t param1 = 0; | 93 uint16_t param1 = 0; |
| 80 uint16_t param2 = 1; | 94 uint16_t param2 = 1; |
| 81 byte code1[] = {WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))}; | 95 byte code1[] = { |
| 82 f1->EmitCode(code1, sizeof(code1)); | 96 WASM_I32_ADD(WASM_GET_LOCAL(param1), WASM_GET_LOCAL(param2))}; |
| 97 f1->EmitCode(code1, sizeof(code1)); |
| 83 | 98 |
| 84 WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v()); | 99 WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v()); |
| 85 | 100 |
| 86 ExportAsMain(f2); | 101 ExportAsMain(f2); |
| 87 byte code2[] = { | 102 byte code2[] = { |
| 88 WASM_CALL_FUNCTION(f1->func_index(), WASM_I8(77), WASM_I8(22))}; | 103 WASM_CALL_FUNCTION(f1->func_index(), WASM_I8(77), WASM_I8(22))}; |
| 89 f2->EmitCode(code2, sizeof(code2)); | 104 f2->EmitCode(code2, sizeof(code2)); |
| 90 TestModule(&zone, builder, 99); | 105 TestModule(&zone, builder, 99); |
| 106 } |
| 107 Cleanup(); |
| 91 } | 108 } |
| 92 | 109 |
| 93 TEST(Run_WasmModule_ReadLoadedDataSegment) { | 110 TEST(Run_WasmModule_ReadLoadedDataSegment) { |
| 94 static const byte kDataSegmentDest0 = 12; | 111 { |
| 95 v8::internal::AccountingAllocator allocator; | 112 static const byte kDataSegmentDest0 = 12; |
| 96 Zone zone(&allocator, ZONE_NAME); | 113 v8::internal::AccountingAllocator allocator; |
| 97 TestSignatures sigs; | 114 Zone zone(&allocator, ZONE_NAME); |
| 115 TestSignatures sigs; |
| 98 | 116 |
| 99 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 117 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 100 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 118 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 101 | 119 |
| 102 ExportAsMain(f); | 120 ExportAsMain(f); |
| 103 byte code[] = { | 121 byte code[] = { |
| 104 WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))}; | 122 WASM_LOAD_MEM(MachineType::Int32(), WASM_I8(kDataSegmentDest0))}; |
| 105 f->EmitCode(code, sizeof(code)); | 123 f->EmitCode(code, sizeof(code)); |
| 106 byte data[] = {0xaa, 0xbb, 0xcc, 0xdd}; | 124 byte data[] = {0xaa, 0xbb, 0xcc, 0xdd}; |
| 107 builder->AddDataSegment(data, sizeof(data), kDataSegmentDest0); | 125 builder->AddDataSegment(data, sizeof(data), kDataSegmentDest0); |
| 108 TestModule(&zone, builder, 0xddccbbaa); | 126 TestModule(&zone, builder, 0xddccbbaa); |
| 127 } |
| 128 Cleanup(); |
| 109 } | 129 } |
| 110 | 130 |
| 111 TEST(Run_WasmModule_CheckMemoryIsZero) { | 131 TEST(Run_WasmModule_CheckMemoryIsZero) { |
| 112 static const int kCheckSize = 16 * 1024; | 132 { |
| 113 v8::internal::AccountingAllocator allocator; | 133 static const int kCheckSize = 16 * 1024; |
| 114 Zone zone(&allocator, ZONE_NAME); | 134 v8::internal::AccountingAllocator allocator; |
| 115 TestSignatures sigs; | 135 Zone zone(&allocator, ZONE_NAME); |
| 136 TestSignatures sigs; |
| 116 | 137 |
| 117 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 138 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 118 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 139 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 119 | 140 |
| 120 uint16_t localIndex = f->AddLocal(kAstI32); | 141 uint16_t localIndex = f->AddLocal(kAstI32); |
| 121 ExportAsMain(f); | 142 ExportAsMain(f); |
| 122 byte code[] = {WASM_BLOCK_I( | 143 byte code[] = {WASM_BLOCK_I( |
| 123 WASM_WHILE( | 144 WASM_WHILE( |
| 124 WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_3(kCheckSize)), | 145 WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I32V_3(kCheckSize)), |
| 125 WASM_IF_ELSE( | 146 WASM_IF_ELSE( |
| 126 WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)), | 147 WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(localIndex)), |
| 127 WASM_BRV(3, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))), | 148 WASM_BRV(3, WASM_I8(-1)), WASM_INC_LOCAL_BY(localIndex, 4))), |
| 128 WASM_I8(11))}; | 149 WASM_I8(11))}; |
| 129 f->EmitCode(code, sizeof(code)); | 150 f->EmitCode(code, sizeof(code)); |
| 130 TestModule(&zone, builder, 11); | 151 TestModule(&zone, builder, 11); |
| 152 } |
| 153 Cleanup(); |
| 131 } | 154 } |
| 132 | 155 |
| 133 TEST(Run_WasmModule_CallMain_recursive) { | 156 TEST(Run_WasmModule_CallMain_recursive) { |
| 134 v8::internal::AccountingAllocator allocator; | 157 { |
| 135 Zone zone(&allocator, ZONE_NAME); | 158 v8::internal::AccountingAllocator allocator; |
| 136 TestSignatures sigs; | 159 Zone zone(&allocator, ZONE_NAME); |
| 160 TestSignatures sigs; |
| 137 | 161 |
| 138 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 162 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 139 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 163 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 140 | 164 |
| 141 uint16_t localIndex = f->AddLocal(kAstI32); | 165 uint16_t localIndex = f->AddLocal(kAstI32); |
| 142 ExportAsMain(f); | 166 ExportAsMain(f); |
| 143 byte code[] = { | 167 byte code[] = { |
| 144 WASM_SET_LOCAL(localIndex, | 168 WASM_SET_LOCAL(localIndex, |
| 145 WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)), | 169 WASM_LOAD_MEM(MachineType::Int32(), WASM_ZERO)), |
| 146 WASM_IF_ELSE_I(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)), | 170 WASM_IF_ELSE_I(WASM_I32_LTS(WASM_GET_LOCAL(localIndex), WASM_I8(5)), |
| 147 WASM_SEQ(WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, | 171 WASM_SEQ(WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, |
| 148 WASM_INC_LOCAL(localIndex)), | 172 WASM_INC_LOCAL(localIndex)), |
| 149 WASM_CALL_FUNCTION0(0)), | 173 WASM_CALL_FUNCTION0(0)), |
| 150 WASM_I8(55))}; | 174 WASM_I8(55))}; |
| 151 f->EmitCode(code, sizeof(code)); | 175 f->EmitCode(code, sizeof(code)); |
| 152 TestModule(&zone, builder, 55); | 176 TestModule(&zone, builder, 55); |
| 177 } |
| 178 Cleanup(); |
| 153 } | 179 } |
| 154 | 180 |
| 155 TEST(Run_WasmModule_Global) { | 181 TEST(Run_WasmModule_Global) { |
| 156 v8::internal::AccountingAllocator allocator; | 182 { |
| 157 Zone zone(&allocator, ZONE_NAME); | 183 v8::internal::AccountingAllocator allocator; |
| 158 TestSignatures sigs; | 184 Zone zone(&allocator, ZONE_NAME); |
| 185 TestSignatures sigs; |
| 159 | 186 |
| 160 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 187 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 161 uint32_t global1 = builder->AddGlobal(kAstI32, 0); | 188 uint32_t global1 = builder->AddGlobal(kAstI32, 0); |
| 162 uint32_t global2 = builder->AddGlobal(kAstI32, 0); | 189 uint32_t global2 = builder->AddGlobal(kAstI32, 0); |
| 163 WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v()); | 190 WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v()); |
| 164 byte code1[] = { | 191 byte code1[] = { |
| 165 WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))}; | 192 WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))}; |
| 166 f1->EmitCode(code1, sizeof(code1)); | 193 f1->EmitCode(code1, sizeof(code1)); |
| 167 WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v()); | 194 WasmFunctionBuilder* f2 = builder->AddFunction(sigs.i_v()); |
| 168 ExportAsMain(f2); | 195 ExportAsMain(f2); |
| 169 byte code2[] = {WASM_SET_GLOBAL(global1, WASM_I32V_1(56)), | 196 byte code2[] = {WASM_SET_GLOBAL(global1, WASM_I32V_1(56)), |
| 170 WASM_SET_GLOBAL(global2, WASM_I32V_1(41)), | 197 WASM_SET_GLOBAL(global2, WASM_I32V_1(41)), |
| 171 WASM_RETURN1(WASM_CALL_FUNCTION0(f1->func_index()))}; | 198 WASM_RETURN1(WASM_CALL_FUNCTION0(f1->func_index()))}; |
| 172 f2->EmitCode(code2, sizeof(code2)); | 199 f2->EmitCode(code2, sizeof(code2)); |
| 173 TestModule(&zone, builder, 97); | 200 TestModule(&zone, builder, 97); |
| 201 } |
| 202 Cleanup(); |
| 174 } | 203 } |
| 175 | 204 |
| 176 // Approximate gtest TEST_F style, in case we adopt gtest. | 205 // Approximate gtest TEST_F style, in case we adopt gtest. |
| 177 class WasmSerializationTest { | 206 class WasmSerializationTest { |
| 178 public: | 207 public: |
| 179 WasmSerializationTest() : zone_(&allocator_, ZONE_NAME) { | 208 WasmSerializationTest() : zone_(&allocator_, ZONE_NAME) { |
| 180 // Don't call here if we move to gtest. | 209 // Don't call here if we move to gtest. |
| 181 SetUp(); | 210 SetUp(); |
| 182 } | 211 } |
| 183 | 212 |
| (...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 v8::WasmCompiledModule::SerializedModule data_; | 360 v8::WasmCompiledModule::SerializedModule data_; |
| 332 v8::WasmCompiledModule::CallerOwnedBuffer wire_bytes_; | 361 v8::WasmCompiledModule::CallerOwnedBuffer wire_bytes_; |
| 333 v8::WasmCompiledModule::CallerOwnedBuffer serialized_bytes_; | 362 v8::WasmCompiledModule::CallerOwnedBuffer serialized_bytes_; |
| 334 v8::Isolate* current_isolate_v8_; | 363 v8::Isolate* current_isolate_v8_; |
| 335 }; | 364 }; |
| 336 | 365 |
| 337 const char* WasmSerializationTest::kFunctionName = "increment"; | 366 const char* WasmSerializationTest::kFunctionName = "increment"; |
| 338 | 367 |
| 339 TEST(DeserializeValidModule) { | 368 TEST(DeserializeValidModule) { |
| 340 WasmSerializationTest test; | 369 WasmSerializationTest test; |
| 341 HandleScope scope(test.current_isolate()); | 370 { |
| 342 test.DeserializeAndRun(); | 371 HandleScope scope(test.current_isolate()); |
| 372 test.DeserializeAndRun(); |
| 373 } |
| 374 Cleanup(test.current_isolate()); |
| 375 Cleanup(); |
| 343 } | 376 } |
| 344 | 377 |
| 345 TEST(DeserializeMismatchingVersion) { | 378 TEST(DeserializeMismatchingVersion) { |
| 346 WasmSerializationTest test; | 379 WasmSerializationTest test; |
| 347 HandleScope scope(test.current_isolate()); | 380 { |
| 348 test.InvalidateVersion(); | 381 HandleScope scope(test.current_isolate()); |
| 349 test.DeserializeAndRun(); | 382 test.InvalidateVersion(); |
| 383 test.DeserializeAndRun(); |
| 384 } |
| 385 Cleanup(test.current_isolate()); |
| 386 Cleanup(); |
| 350 } | 387 } |
| 351 | 388 |
| 352 TEST(DeserializeNoSerializedData) { | 389 TEST(DeserializeNoSerializedData) { |
| 353 WasmSerializationTest test; | 390 WasmSerializationTest test; |
| 354 HandleScope scope(test.current_isolate()); | 391 { |
| 355 test.ClearSerializedData(); | 392 HandleScope scope(test.current_isolate()); |
| 356 test.DeserializeAndRun(); | 393 test.ClearSerializedData(); |
| 394 test.DeserializeAndRun(); |
| 395 } |
| 396 Cleanup(test.current_isolate()); |
| 397 Cleanup(); |
| 357 } | 398 } |
| 358 | 399 |
| 359 TEST(DeserializeWireBytesAndSerializedDataInvalid) { | 400 TEST(DeserializeWireBytesAndSerializedDataInvalid) { |
| 360 WasmSerializationTest test; | 401 WasmSerializationTest test; |
| 361 HandleScope scope(test.current_isolate()); | 402 { |
| 362 test.InvalidateVersion(); | 403 HandleScope scope(test.current_isolate()); |
| 363 test.InvalidateWireBytes(); | 404 test.InvalidateVersion(); |
| 364 test.Deserialize(); | 405 test.InvalidateWireBytes(); |
| 406 test.Deserialize(); |
| 407 } |
| 408 Cleanup(test.current_isolate()); |
| 409 Cleanup(); |
| 365 } | 410 } |
| 366 | 411 |
| 367 TEST(MemorySize) { | 412 TEST(MemorySize) { |
| 368 // Initial memory size is 16, see wasm-module-builder.cc | 413 { |
| 369 static const int kExpectedValue = 16; | 414 // Initial memory size is 16, see wasm-module-builder.cc |
| 370 TestSignatures sigs; | 415 static const int kExpectedValue = 16; |
| 371 v8::internal::AccountingAllocator allocator; | 416 TestSignatures sigs; |
| 372 Zone zone(&allocator, ZONE_NAME); | 417 v8::internal::AccountingAllocator allocator; |
| 418 Zone zone(&allocator, ZONE_NAME); |
| 373 | 419 |
| 374 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 420 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 375 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 421 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 376 ExportAsMain(f); | 422 ExportAsMain(f); |
| 377 byte code[] = {WASM_MEMORY_SIZE}; | 423 byte code[] = {WASM_MEMORY_SIZE}; |
| 378 f->EmitCode(code, sizeof(code)); | 424 f->EmitCode(code, sizeof(code)); |
| 379 TestModule(&zone, builder, kExpectedValue); | 425 TestModule(&zone, builder, kExpectedValue); |
| 426 } |
| 427 Cleanup(); |
| 380 } | 428 } |
| 381 | 429 |
| 382 TEST(Run_WasmModule_MemSize_GrowMem) { | 430 TEST(Run_WasmModule_MemSize_GrowMem) { |
| 383 // Initial memory size = 16 + GrowMemory(10) | 431 { |
| 384 static const int kExpectedValue = 26; | 432 // Initial memory size = 16 + GrowMemory(10) |
| 385 TestSignatures sigs; | 433 static const int kExpectedValue = 26; |
| 386 v8::internal::AccountingAllocator allocator; | 434 TestSignatures sigs; |
| 387 Zone zone(&allocator, ZONE_NAME); | 435 v8::internal::AccountingAllocator allocator; |
| 436 Zone zone(&allocator, ZONE_NAME); |
| 388 | 437 |
| 389 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 438 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 390 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 439 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 391 ExportAsMain(f); | 440 ExportAsMain(f); |
| 392 byte code[] = {WASM_GROW_MEMORY(WASM_I8(10)), WASM_DROP, WASM_MEMORY_SIZE}; | 441 byte code[] = {WASM_GROW_MEMORY(WASM_I8(10)), WASM_DROP, WASM_MEMORY_SIZE}; |
| 393 f->EmitCode(code, sizeof(code)); | 442 f->EmitCode(code, sizeof(code)); |
| 394 TestModule(&zone, builder, kExpectedValue); | 443 TestModule(&zone, builder, kExpectedValue); |
| 444 } |
| 445 Cleanup(); |
| 395 } | 446 } |
| 396 | 447 |
| 397 TEST(GrowMemoryZero) { | 448 TEST(GrowMemoryZero) { |
| 398 // Initial memory size is 16, see wasm-module-builder.cc | 449 { |
| 399 static const int kExpectedValue = 16; | 450 // Initial memory size is 16, see wasm-module-builder.cc |
| 400 TestSignatures sigs; | 451 static const int kExpectedValue = 16; |
| 401 v8::internal::AccountingAllocator allocator; | 452 TestSignatures sigs; |
| 402 Zone zone(&allocator, ZONE_NAME); | 453 v8::internal::AccountingAllocator allocator; |
| 454 Zone zone(&allocator, ZONE_NAME); |
| 403 | 455 |
| 404 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 456 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 405 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 457 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 406 ExportAsMain(f); | 458 ExportAsMain(f); |
| 407 byte code[] = {WASM_GROW_MEMORY(WASM_I32V(0))}; | 459 byte code[] = {WASM_GROW_MEMORY(WASM_I32V(0))}; |
| 408 f->EmitCode(code, sizeof(code)); | 460 f->EmitCode(code, sizeof(code)); |
| 409 TestModule(&zone, builder, kExpectedValue); | 461 TestModule(&zone, builder, kExpectedValue); |
| 462 } |
| 463 Cleanup(); |
| 410 } | 464 } |
| 411 | 465 |
| 412 class InterruptThread : public v8::base::Thread { | 466 class InterruptThread : public v8::base::Thread { |
| 413 public: | 467 public: |
| 414 explicit InterruptThread(Isolate* isolate, int32_t* memory) | 468 explicit InterruptThread(Isolate* isolate, int32_t* memory) |
| 415 : Thread(Options("TestInterruptLoop")), | 469 : Thread(Options("TestInterruptLoop")), |
| 416 isolate_(isolate), | 470 isolate_(isolate), |
| 417 memory_(memory) {} | 471 memory_(memory) {} |
| 418 | 472 |
| 419 static void OnInterrupt(v8::Isolate* isolate, void* data) { | 473 static void OnInterrupt(v8::Isolate* isolate, void* data) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 434 } | 488 } |
| 435 | 489 |
| 436 Isolate* isolate_; | 490 Isolate* isolate_; |
| 437 volatile int32_t* memory_; | 491 volatile int32_t* memory_; |
| 438 static const int32_t interrupt_location_ = 10; | 492 static const int32_t interrupt_location_ = 10; |
| 439 static const int32_t interrupt_value_ = 154; | 493 static const int32_t interrupt_value_ = 154; |
| 440 static const int32_t signal_value_ = 1221; | 494 static const int32_t signal_value_ = 1221; |
| 441 }; | 495 }; |
| 442 | 496 |
| 443 TEST(TestInterruptLoop) { | 497 TEST(TestInterruptLoop) { |
| 444 // Do not dump the module of this test because it contains an infinite loop. | 498 { |
| 445 if (FLAG_dump_wasm_module) return; | 499 // Do not dump the module of this test because it contains an infinite loop. |
| 446 | 500 if (FLAG_dump_wasm_module) return; |
| 447 // This test tests that WebAssembly loops can be interrupted, i.e. that if an | 501 |
| 448 // InterruptCallback is registered by {Isolate::RequestInterrupt}, then the | 502 // This test tests that WebAssembly loops can be interrupted, i.e. that if |
| 449 // InterruptCallback is eventually called even if a loop in WebAssembly code | 503 // an |
| 450 // is executed. | 504 // InterruptCallback is registered by {Isolate::RequestInterrupt}, then the |
| 451 // Test setup: | 505 // InterruptCallback is eventually called even if a loop in WebAssembly code |
| 452 // The main thread executes a WebAssembly function with a loop. In the loop | 506 // is executed. |
| 453 // {signal_value_} is written to memory to signal a helper thread that the | 507 // Test setup: |
| 454 // main thread reached the loop in the WebAssembly program. When the helper | 508 // The main thread executes a WebAssembly function with a loop. In the loop |
| 455 // thread reads {signal_value_} from memory, it registers the | 509 // {signal_value_} is written to memory to signal a helper thread that the |
| 456 // InterruptCallback. Upon exeution, the InterruptCallback write into the | 510 // main thread reached the loop in the WebAssembly program. When the helper |
| 457 // WebAssemblyMemory to end the loop in the WebAssembly program. | 511 // thread reads {signal_value_} from memory, it registers the |
| 458 TestSignatures sigs; | 512 // InterruptCallback. Upon exeution, the InterruptCallback write into the |
| 459 Isolate* isolate = CcTest::InitIsolateOnce(); | 513 // WebAssemblyMemory to end the loop in the WebAssembly program. |
| 460 v8::internal::AccountingAllocator allocator; | 514 TestSignatures sigs; |
| 461 Zone zone(&allocator, ZONE_NAME); | 515 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 462 | 516 v8::internal::AccountingAllocator allocator; |
| 463 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 517 Zone zone(&allocator, ZONE_NAME); |
| 464 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 518 |
| 465 ExportAsMain(f); | 519 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 466 byte code[] = {WASM_LOOP(WASM_IFB( | 520 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 467 WASM_NOT(WASM_LOAD_MEM( | 521 ExportAsMain(f); |
| 522 byte code[] = { |
| 523 WASM_LOOP( |
| 524 WASM_IFB(WASM_NOT(WASM_LOAD_MEM( |
| 468 MachineType::Int32(), | 525 MachineType::Int32(), |
| 469 WASM_I32V(InterruptThread::interrupt_location_ * 4))), | 526 WASM_I32V(InterruptThread::interrupt_location_ * 4))), |
| 470 WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, | 527 WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, |
| 471 WASM_I32V(InterruptThread::signal_value_)), | 528 WASM_I32V(InterruptThread::signal_value_)), |
| 472 WASM_BR(1))), | 529 WASM_BR(1))), |
| 473 WASM_I32V(121)}; | 530 WASM_I32V(121)}; |
| 474 f->EmitCode(code, sizeof(code)); | 531 f->EmitCode(code, sizeof(code)); |
| 475 ZoneBuffer buffer(&zone); | 532 ZoneBuffer buffer(&zone); |
| 476 builder->WriteTo(buffer); | 533 builder->WriteTo(buffer); |
| 477 | 534 |
| 478 HandleScope scope(isolate); | 535 HandleScope scope(isolate); |
| 479 testing::SetupIsolateForWasmModule(isolate); | 536 testing::SetupIsolateForWasmModule(isolate); |
| 480 ErrorThrower thrower(isolate, "Test"); | 537 ErrorThrower thrower(isolate, "Test"); |
| 481 const Handle<JSObject> instance = | 538 const Handle<JSObject> instance = |
| 482 testing::CompileInstantiateWasmModuleForTesting( | 539 testing::CompileInstantiateWasmModuleForTesting( |
| 483 isolate, &thrower, buffer.begin(), buffer.end(), | 540 isolate, &thrower, buffer.begin(), buffer.end(), |
| 484 ModuleOrigin::kWasmOrigin); | 541 ModuleOrigin::kWasmOrigin); |
| 485 CHECK(!instance.is_null()); | 542 CHECK(!instance.is_null()); |
| 486 | 543 |
| 487 MaybeHandle<JSArrayBuffer> maybe_memory = | 544 MaybeHandle<JSArrayBuffer> maybe_memory = |
| 488 GetInstanceMemory(isolate, instance); | 545 GetInstanceMemory(isolate, instance); |
| 489 Handle<JSArrayBuffer> memory = maybe_memory.ToHandleChecked(); | 546 Handle<JSArrayBuffer> memory = maybe_memory.ToHandleChecked(); |
| 490 int32_t* memory_array = reinterpret_cast<int32_t*>(memory->backing_store()); | 547 int32_t* memory_array = reinterpret_cast<int32_t*>(memory->backing_store()); |
| 491 | 548 |
| 492 InterruptThread thread(isolate, memory_array); | 549 InterruptThread thread(isolate, memory_array); |
| 493 thread.Start(); | 550 thread.Start(); |
| 494 testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr, | 551 testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr, |
| 495 ModuleOrigin::kWasmOrigin); | 552 ModuleOrigin::kWasmOrigin); |
| 496 int32_t val = memory_array[InterruptThread::interrupt_location_]; | 553 int32_t val = memory_array[InterruptThread::interrupt_location_]; |
| 497 CHECK_EQ(InterruptThread::interrupt_value_, | 554 CHECK_EQ(InterruptThread::interrupt_value_, |
| 498 ReadLittleEndianValue<int32_t>(&val)); | 555 ReadLittleEndianValue<int32_t>(&val)); |
| 556 } |
| 557 Cleanup(); |
| 499 } | 558 } |
| 500 | 559 |
| 501 TEST(Run_WasmModule_GrowMemoryInIf) { | 560 TEST(Run_WasmModule_GrowMemoryInIf) { |
| 502 TestSignatures sigs; | 561 { |
| 503 v8::internal::AccountingAllocator allocator; | 562 TestSignatures sigs; |
| 504 Zone zone(&allocator, ZONE_NAME); | 563 v8::internal::AccountingAllocator allocator; |
| 505 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 564 Zone zone(&allocator, ZONE_NAME); |
| 506 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 565 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 507 ExportAsMain(f); | 566 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 508 byte code[] = {WASM_IF_ELSE_I(WASM_I32V(0), WASM_GROW_MEMORY(WASM_I32V(1)), | 567 ExportAsMain(f); |
| 509 WASM_I32V(12))}; | 568 byte code[] = {WASM_IF_ELSE_I(WASM_I32V(0), WASM_GROW_MEMORY(WASM_I32V(1)), |
| 510 f->EmitCode(code, sizeof(code)); | 569 WASM_I32V(12))}; |
| 511 TestModule(&zone, builder, 12); | 570 f->EmitCode(code, sizeof(code)); |
| 571 TestModule(&zone, builder, 12); |
| 572 } |
| 573 Cleanup(); |
| 512 } | 574 } |
| 513 | 575 |
| 514 TEST(Run_WasmModule_GrowMemOobOffset) { | 576 TEST(Run_WasmModule_GrowMemOobOffset) { |
| 515 static const int kPageSize = 0x10000; | 577 { |
| 516 // Initial memory size = 16 + GrowMemory(10) | 578 static const int kPageSize = 0x10000; |
| 517 static const int index = kPageSize * 17 + 4; | 579 // Initial memory size = 16 + GrowMemory(10) |
| 518 int value = 0xaced; | 580 static const int index = kPageSize * 17 + 4; |
| 519 TestSignatures sigs; | 581 int value = 0xaced; |
| 520 v8::internal::AccountingAllocator allocator; | 582 TestSignatures sigs; |
| 521 Zone zone(&allocator, ZONE_NAME); | 583 v8::internal::AccountingAllocator allocator; |
| 522 | 584 Zone zone(&allocator, ZONE_NAME); |
| 523 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 585 |
| 524 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); | 586 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 525 ExportAsMain(f); | 587 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); |
| 526 byte code[] = { | 588 ExportAsMain(f); |
| 527 WASM_GROW_MEMORY(WASM_I8(1)), | 589 byte code[] = {WASM_GROW_MEMORY(WASM_I8(1)), |
| 528 WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), WASM_I32V(value))}; | 590 WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), |
| 529 f->EmitCode(code, sizeof(code)); | 591 WASM_I32V(value))}; |
| 530 TestModuleException(&zone, builder); | 592 f->EmitCode(code, sizeof(code)); |
| 593 TestModuleException(&zone, builder); |
| 594 } |
| 595 Cleanup(); |
| 531 } | 596 } |
| 532 | 597 |
| 533 TEST(Run_WasmModule_GrowMemOobFixedIndex) { | 598 TEST(Run_WasmModule_GrowMemOobFixedIndex) { |
| 534 static const int kPageSize = 0x10000; | 599 { |
| 535 // Initial memory size = 16 + GrowMemory(10) | 600 static const int kPageSize = 0x10000; |
| 536 static const int index = kPageSize * 26 + 4; | 601 // Initial memory size = 16 + GrowMemory(10) |
| 537 int value = 0xaced; | 602 static const int index = kPageSize * 26 + 4; |
| 538 TestSignatures sigs; | 603 int value = 0xaced; |
| 539 Isolate* isolate = CcTest::InitIsolateOnce(); | 604 TestSignatures sigs; |
| 540 Zone zone(isolate->allocator(), ZONE_NAME); | 605 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 541 | 606 Zone zone(isolate->allocator(), ZONE_NAME); |
| 542 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 607 |
| 543 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i()); | 608 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 544 ExportAsMain(f); | 609 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i()); |
| 545 byte code[] = { | 610 ExportAsMain(f); |
| 546 WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP, | 611 byte code[] = {WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP, |
| 547 WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), WASM_I32V(value)), | 612 WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), |
| 548 WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))}; | 613 WASM_I32V(value)), |
| 549 f->EmitCode(code, sizeof(code)); | 614 WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))}; |
| 550 | 615 f->EmitCode(code, sizeof(code)); |
| 551 HandleScope scope(isolate); | 616 |
| 552 ZoneBuffer buffer(&zone); | 617 HandleScope scope(isolate); |
| 553 builder->WriteTo(buffer); | 618 ZoneBuffer buffer(&zone); |
| 554 testing::SetupIsolateForWasmModule(isolate); | 619 builder->WriteTo(buffer); |
| 555 | 620 testing::SetupIsolateForWasmModule(isolate); |
| 556 ErrorThrower thrower(isolate, "Test"); | 621 |
| 557 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting( | 622 ErrorThrower thrower(isolate, "Test"); |
| 558 isolate, &thrower, buffer.begin(), buffer.end(), | 623 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting( |
| 559 ModuleOrigin::kWasmOrigin); | 624 isolate, &thrower, buffer.begin(), buffer.end(), |
| 560 CHECK(!instance.is_null()); | 625 ModuleOrigin::kWasmOrigin); |
| 561 | 626 CHECK(!instance.is_null()); |
| 562 // Initial memory size is 16 pages, should trap till index > MemSize on | 627 |
| 563 // consecutive GrowMem calls | 628 // Initial memory size is 16 pages, should trap till index > MemSize on |
| 564 for (uint32_t i = 1; i < 5; i++) { | 629 // consecutive GrowMem calls |
| 565 Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(i), isolate)}; | 630 for (uint32_t i = 1; i < 5; i++) { |
| 631 Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(i), isolate)}; |
| 632 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); |
| 633 testing::RunWasmModuleForTesting(isolate, instance, 1, params, |
| 634 ModuleOrigin::kWasmOrigin); |
| 635 CHECK(try_catch.HasCaught()); |
| 636 isolate->clear_pending_exception(); |
| 637 } |
| 638 |
| 639 Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(1), isolate)}; |
| 640 int32_t result = testing::RunWasmModuleForTesting( |
| 641 isolate, instance, 1, params, ModuleOrigin::kWasmOrigin); |
| 642 CHECK(result == 0xaced); |
| 643 } |
| 644 Cleanup(); |
| 645 } |
| 646 |
| 647 TEST(Run_WasmModule_GrowMemOobVariableIndex) { |
| 648 { |
| 649 static const int kPageSize = 0x10000; |
| 650 int value = 0xaced; |
| 651 TestSignatures sigs; |
| 652 Isolate* isolate = CcTest::InitIsolateOnce(); |
| 653 v8::internal::AccountingAllocator allocator; |
| 654 Zone zone(&allocator, ZONE_NAME); |
| 655 |
| 656 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 657 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i()); |
| 658 ExportAsMain(f); |
| 659 byte code[] = {WASM_GROW_MEMORY(WASM_I8(1)), WASM_DROP, |
| 660 WASM_STORE_MEM(MachineType::Int32(), WASM_GET_LOCAL(0), |
| 661 WASM_I32V(value)), |
| 662 WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))}; |
| 663 f->EmitCode(code, sizeof(code)); |
| 664 |
| 665 HandleScope scope(isolate); |
| 666 ZoneBuffer buffer(&zone); |
| 667 builder->WriteTo(buffer); |
| 668 testing::SetupIsolateForWasmModule(isolate); |
| 669 |
| 670 ErrorThrower thrower(isolate, "Test"); |
| 671 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting( |
| 672 isolate, &thrower, buffer.begin(), buffer.end(), |
| 673 ModuleOrigin::kWasmOrigin); |
| 674 |
| 675 CHECK(!instance.is_null()); |
| 676 |
| 677 // Initial memory size is 16 pages, should trap till index > MemSize on |
| 678 // consecutive GrowMem calls |
| 679 for (int i = 1; i < 5; i++) { |
| 680 Handle<Object> params[1] = { |
| 681 Handle<Object>(Smi::FromInt((16 + i) * kPageSize - 3), isolate)}; |
| 682 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); |
| 683 testing::RunWasmModuleForTesting(isolate, instance, 1, params, |
| 684 ModuleOrigin::kWasmOrigin); |
| 685 CHECK(try_catch.HasCaught()); |
| 686 isolate->clear_pending_exception(); |
| 687 } |
| 688 |
| 689 for (int i = 1; i < 5; i++) { |
| 690 Handle<Object> params[1] = { |
| 691 Handle<Object>(Smi::FromInt((20 + i) * kPageSize - 4), isolate)}; |
| 692 int32_t result = testing::RunWasmModuleForTesting( |
| 693 isolate, instance, 1, params, ModuleOrigin::kWasmOrigin); |
| 694 CHECK(result == 0xaced); |
| 695 } |
| 696 |
| 566 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); | 697 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); |
| 698 Handle<Object> params[1] = { |
| 699 Handle<Object>(Smi::FromInt(25 * kPageSize), isolate)}; |
| 567 testing::RunWasmModuleForTesting(isolate, instance, 1, params, | 700 testing::RunWasmModuleForTesting(isolate, instance, 1, params, |
| 568 ModuleOrigin::kWasmOrigin); | 701 ModuleOrigin::kWasmOrigin); |
| 569 CHECK(try_catch.HasCaught()); | 702 CHECK(try_catch.HasCaught()); |
| 570 isolate->clear_pending_exception(); | 703 isolate->clear_pending_exception(); |
| 571 } | 704 } |
| 572 | 705 Cleanup(); |
| 573 Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(1), isolate)}; | |
| 574 int32_t result = testing::RunWasmModuleForTesting( | |
| 575 isolate, instance, 1, params, ModuleOrigin::kWasmOrigin); | |
| 576 CHECK(result == 0xaced); | |
| 577 } | |
| 578 | |
| 579 TEST(Run_WasmModule_GrowMemOobVariableIndex) { | |
| 580 static const int kPageSize = 0x10000; | |
| 581 int value = 0xaced; | |
| 582 TestSignatures sigs; | |
| 583 Isolate* isolate = CcTest::InitIsolateOnce(); | |
| 584 v8::internal::AccountingAllocator allocator; | |
| 585 Zone zone(&allocator, ZONE_NAME); | |
| 586 | |
| 587 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | |
| 588 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_i()); | |
| 589 ExportAsMain(f); | |
| 590 byte code[] = { | |
| 591 WASM_GROW_MEMORY(WASM_I8(1)), WASM_DROP, | |
| 592 WASM_STORE_MEM(MachineType::Int32(), WASM_GET_LOCAL(0), WASM_I32V(value)), | |
| 593 WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))}; | |
| 594 f->EmitCode(code, sizeof(code)); | |
| 595 | |
| 596 HandleScope scope(isolate); | |
| 597 ZoneBuffer buffer(&zone); | |
| 598 builder->WriteTo(buffer); | |
| 599 testing::SetupIsolateForWasmModule(isolate); | |
| 600 | |
| 601 ErrorThrower thrower(isolate, "Test"); | |
| 602 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting( | |
| 603 isolate, &thrower, buffer.begin(), buffer.end(), | |
| 604 ModuleOrigin::kWasmOrigin); | |
| 605 | |
| 606 CHECK(!instance.is_null()); | |
| 607 | |
| 608 // Initial memory size is 16 pages, should trap till index > MemSize on | |
| 609 // consecutive GrowMem calls | |
| 610 for (int i = 1; i < 5; i++) { | |
| 611 Handle<Object> params[1] = { | |
| 612 Handle<Object>(Smi::FromInt((16 + i) * kPageSize - 3), isolate)}; | |
| 613 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); | |
| 614 testing::RunWasmModuleForTesting(isolate, instance, 1, params, | |
| 615 ModuleOrigin::kWasmOrigin); | |
| 616 CHECK(try_catch.HasCaught()); | |
| 617 isolate->clear_pending_exception(); | |
| 618 } | |
| 619 | |
| 620 for (int i = 1; i < 5; i++) { | |
| 621 Handle<Object> params[1] = { | |
| 622 Handle<Object>(Smi::FromInt((20 + i) * kPageSize - 4), isolate)}; | |
| 623 int32_t result = testing::RunWasmModuleForTesting( | |
| 624 isolate, instance, 1, params, ModuleOrigin::kWasmOrigin); | |
| 625 CHECK(result == 0xaced); | |
| 626 } | |
| 627 | |
| 628 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); | |
| 629 Handle<Object> params[1] = { | |
| 630 Handle<Object>(Smi::FromInt(25 * kPageSize), isolate)}; | |
| 631 testing::RunWasmModuleForTesting(isolate, instance, 1, params, | |
| 632 ModuleOrigin::kWasmOrigin); | |
| 633 CHECK(try_catch.HasCaught()); | |
| 634 isolate->clear_pending_exception(); | |
| 635 } | 706 } |
| 636 | 707 |
| 637 TEST(Run_WasmModule_Global_init) { | 708 TEST(Run_WasmModule_Global_init) { |
| 638 v8::internal::AccountingAllocator allocator; | 709 { |
| 639 Zone zone(&allocator, ZONE_NAME); | 710 v8::internal::AccountingAllocator allocator; |
| 640 TestSignatures sigs; | 711 Zone zone(&allocator, ZONE_NAME); |
| 641 | 712 TestSignatures sigs; |
| 642 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 713 |
| 643 uint32_t global1 = | 714 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 644 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(777777)); | 715 uint32_t global1 = |
| 645 uint32_t global2 = | 716 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(777777)); |
| 646 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(222222)); | 717 uint32_t global2 = |
| 647 WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v()); | 718 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(222222)); |
| 648 byte code[] = { | 719 WasmFunctionBuilder* f1 = builder->AddFunction(sigs.i_v()); |
| 649 WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))}; | 720 byte code[] = { |
| 650 f1->EmitCode(code, sizeof(code)); | 721 WASM_I32_ADD(WASM_GET_GLOBAL(global1), WASM_GET_GLOBAL(global2))}; |
| 651 ExportAsMain(f1); | 722 f1->EmitCode(code, sizeof(code)); |
| 652 TestModule(&zone, builder, 999999); | 723 ExportAsMain(f1); |
| 724 TestModule(&zone, builder, 999999); |
| 725 } |
| 726 Cleanup(); |
| 653 } | 727 } |
| 654 | 728 |
| 655 template <typename CType> | 729 template <typename CType> |
| 656 static void RunWasmModuleGlobalInitTest(LocalType type, CType expected) { | 730 static void RunWasmModuleGlobalInitTest(LocalType type, CType expected) { |
| 657 v8::internal::AccountingAllocator allocator; | 731 { |
| 658 Zone zone(&allocator, ZONE_NAME); | 732 v8::internal::AccountingAllocator allocator; |
| 659 TestSignatures sigs; | 733 Zone zone(&allocator, ZONE_NAME); |
| 660 | 734 TestSignatures sigs; |
| 661 LocalType types[] = {type}; | 735 |
| 662 FunctionSig sig(1, 0, types); | 736 LocalType types[] = {type}; |
| 663 | 737 FunctionSig sig(1, 0, types); |
| 664 for (int padding = 0; padding < 5; padding++) { | 738 |
| 665 // Test with a simple initializer | 739 for (int padding = 0; padding < 5; padding++) { |
| 666 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 740 // Test with a simple initializer |
| 667 | 741 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 668 for (int i = 0; i < padding; i++) { // pad global before | 742 |
| 669 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 20000)); | 743 for (int i = 0; i < padding; i++) { // pad global before |
| 670 } | 744 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 20000)); |
| 671 uint32_t global = | 745 } |
| 672 builder->AddGlobal(type, false, false, WasmInitExpr(expected)); | 746 uint32_t global = |
| 673 for (int i = 0; i < padding; i++) { // pad global after | 747 builder->AddGlobal(type, false, false, WasmInitExpr(expected)); |
| 674 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 30000)); | 748 for (int i = 0; i < padding; i++) { // pad global after |
| 675 } | 749 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 30000)); |
| 676 | 750 } |
| 677 WasmFunctionBuilder* f1 = builder->AddFunction(&sig); | 751 |
| 678 byte code[] = {WASM_GET_GLOBAL(global)}; | 752 WasmFunctionBuilder* f1 = builder->AddFunction(&sig); |
| 679 f1->EmitCode(code, sizeof(code)); | 753 byte code[] = {WASM_GET_GLOBAL(global)}; |
| 680 ExportAsMain(f1); | 754 f1->EmitCode(code, sizeof(code)); |
| 681 TestModule(&zone, builder, expected); | 755 ExportAsMain(f1); |
| 682 } | 756 TestModule(&zone, builder, expected); |
| 683 | 757 } |
| 684 for (int padding = 0; padding < 5; padding++) { | 758 |
| 685 // Test with a global index | 759 for (int padding = 0; padding < 5; padding++) { |
| 686 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); | 760 // Test with a global index |
| 687 for (int i = 0; i < padding; i++) { // pad global before | 761 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); |
| 688 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 40000)); | 762 for (int i = 0; i < padding; i++) { // pad global before |
| 689 } | 763 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 40000)); |
| 690 | 764 } |
| 691 uint32_t global1 = | 765 |
| 692 builder->AddGlobal(type, false, false, WasmInitExpr(expected)); | 766 uint32_t global1 = |
| 693 | 767 builder->AddGlobal(type, false, false, WasmInitExpr(expected)); |
| 694 for (int i = 0; i < padding; i++) { // pad global middle | 768 |
| 695 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 50000)); | 769 for (int i = 0; i < padding; i++) { // pad global middle |
| 696 } | 770 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 50000)); |
| 697 | 771 } |
| 698 uint32_t global2 = builder->AddGlobal( | 772 |
| 699 type, false, false, WasmInitExpr(WasmInitExpr::kGlobalIndex, global1)); | 773 uint32_t global2 = |
| 700 | 774 builder->AddGlobal(type, false, false, |
| 701 for (int i = 0; i < padding; i++) { // pad global after | 775 WasmInitExpr(WasmInitExpr::kGlobalIndex, global1)); |
| 702 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 60000)); | 776 |
| 703 } | 777 for (int i = 0; i < padding; i++) { // pad global after |
| 704 | 778 builder->AddGlobal(kAstI32, false, false, WasmInitExpr(i + 60000)); |
| 705 WasmFunctionBuilder* f1 = builder->AddFunction(&sig); | 779 } |
| 706 byte code[] = {WASM_GET_GLOBAL(global2)}; | 780 |
| 707 f1->EmitCode(code, sizeof(code)); | 781 WasmFunctionBuilder* f1 = builder->AddFunction(&sig); |
| 708 ExportAsMain(f1); | 782 byte code[] = {WASM_GET_GLOBAL(global2)}; |
| 709 TestModule(&zone, builder, expected); | 783 f1->EmitCode(code, sizeof(code)); |
| 710 } | 784 ExportAsMain(f1); |
| 785 TestModule(&zone, builder, expected); |
| 786 } |
| 787 } |
| 788 Cleanup(); |
| 711 } | 789 } |
| 712 | 790 |
| 713 TEST(Run_WasmModule_Global_i32) { | 791 TEST(Run_WasmModule_Global_i32) { |
| 714 RunWasmModuleGlobalInitTest<int32_t>(kAstI32, -983489); | 792 RunWasmModuleGlobalInitTest<int32_t>(kAstI32, -983489); |
| 715 RunWasmModuleGlobalInitTest<int32_t>(kAstI32, 11223344); | 793 RunWasmModuleGlobalInitTest<int32_t>(kAstI32, 11223344); |
| 716 } | 794 } |
| 717 | 795 |
| 718 TEST(Run_WasmModule_Global_f32) { | 796 TEST(Run_WasmModule_Global_f32) { |
| 719 RunWasmModuleGlobalInitTest<float>(kAstF32, -983.9f); | 797 RunWasmModuleGlobalInitTest<float>(kAstF32, -983.9f); |
| 720 RunWasmModuleGlobalInitTest<float>(kAstF32, 1122.99f); | 798 RunWasmModuleGlobalInitTest<float>(kAstF32, 1122.99f); |
| 721 } | 799 } |
| 722 | 800 |
| 723 TEST(Run_WasmModule_Global_f64) { | 801 TEST(Run_WasmModule_Global_f64) { |
| 724 RunWasmModuleGlobalInitTest<double>(kAstF64, -833.9); | 802 RunWasmModuleGlobalInitTest<double>(kAstF64, -833.9); |
| 725 RunWasmModuleGlobalInitTest<double>(kAstF64, 86374.25); | 803 RunWasmModuleGlobalInitTest<double>(kAstF64, 86374.25); |
| 726 } | 804 } |
| OLD | NEW |