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 |