Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(16)

Side by Side Diff: test/cctest/wasm/test-run-wasm-module.cc

Issue 2405293002: [wasm] Add stack checks to loops. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/wasm/module-decoder.h" 8 #include "src/wasm/module-decoder.h"
9 #include "src/wasm/wasm-macro-gen.h" 9 #include "src/wasm/wasm-macro-gen.h"
10 #include "src/wasm/wasm-module-builder.h" 10 #include "src/wasm/wasm-module-builder.h"
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after
305 Zone zone(&allocator); 305 Zone zone(&allocator);
306 306
307 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); 307 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
308 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); 308 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
309 ExportAsMain(f); 309 ExportAsMain(f);
310 byte code[] = {WASM_GROW_MEMORY(WASM_I32V(0))}; 310 byte code[] = {WASM_GROW_MEMORY(WASM_I32V(0))};
311 f->EmitCode(code, sizeof(code)); 311 f->EmitCode(code, sizeof(code));
312 TestModule(&zone, builder, kExpectedValue); 312 TestModule(&zone, builder, kExpectedValue);
313 } 313 }
314 314
315 class InterruptThread : public v8::base::Thread {
316 public:
317 explicit InterruptThread(Isolate* isolate, int32_t* memory)
318 : Thread(Options("TestInterruptLoop")),
319 isolate_(isolate),
320 memory_(memory) {}
321
322 static void OnInterrupt(v8::Isolate* isolate, void* data) {
323 int32_t* m = reinterpret_cast<int32_t*>(data);
324 // Set the interrupt location to 0 to break the loop in {TestInterruptLoop}.
325 m[interrupt_location_] = interrupt_value_;
326 }
327
328 virtual void Run() {
329 // Wait for the main thread to write the signal value.
330 while (memory_[0] != signal_value_) {
331 }
332 isolate_->RequestInterrupt(&OnInterrupt, memory_);
333 }
334
335 Isolate* isolate_;
336 int32_t* memory_;
337 static const int32_t interrupt_location_ = 10;
338 static const int32_t interrupt_value_ = 154;
339 static const int32_t signal_value_ = 1221;
340 };
341
342 TEST(TestInterruptLoop) {
343 // This test tests that WebAssembly loops can be interrupted, i.e. that if an
344 // InterruptCallback is registered by {Isolate::RequestInterrupt}, then the
345 // InterruptCallback is eventually called even if a loop in WebAssembly code
346 // is executed.
347 // Test setup:
348 // The main thread executes a WebAssembly function with a loop. In the loop
349 // {signal_value_} is written to memory to signal a helper thread that the
350 // main thread reached the loop in the WebAssembly program. When the helper
351 // thread reads {signal_value_} from memory, it registers the
352 // InterruptCallback. Upon exeution, the InterruptCallback write into the
353 // WebAssemblyMemory to end the loop in the WebAssembly program.
354 TestSignatures sigs;
355 Isolate* isolate = CcTest::InitIsolateOnce();
356 v8::internal::AccountingAllocator allocator;
357 Zone zone(&allocator);
358
359 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
360 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
361 ExportAsMain(f);
362 byte code[] = {WASM_LOOP(WASM_IFB(
363 WASM_NOT(WASM_LOAD_MEM(
364 MachineType::Int32(),
365 WASM_I32V(InterruptThread::interrupt_location_ * 4))),
366 WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO,
367 WASM_I32V(InterruptThread::signal_value_)),
368 WASM_BR(1))),
369 WASM_I32V(121)};
370 f->EmitCode(code, sizeof(code));
371 ZoneBuffer buffer(&zone);
372 builder->WriteTo(buffer);
373
374 HandleScope scope(isolate);
375 testing::SetupIsolateForWasmModule(isolate);
376 ErrorThrower thrower(isolate, "Test");
377 const Handle<JSObject> instance =
378 testing::CompileInstantiateWasmModuleForTesting(
379 isolate, &thrower, &zone, buffer.begin(), buffer.end(),
380 ModuleOrigin::kWasmOrigin);
381 CHECK(!instance.is_null());
382
383 MaybeHandle<JSArrayBuffer> maybe_memory =
384 testing::GetInstanceMemoryForTesting(isolate, instance);
385 Handle<JSArrayBuffer> memory = maybe_memory.ToHandleChecked();
386 int32_t* memory_array = reinterpret_cast<int32_t*>(memory->backing_store());
387
388 InterruptThread thread(isolate, memory_array);
389 thread.Start();
390 testing::RunWasmModuleForTesting(isolate, instance, 0, nullptr,
391 ModuleOrigin::kWasmOrigin);
392 CHECK_EQ(InterruptThread::interrupt_value_,
393 memory_array[InterruptThread::interrupt_location_]);
394 }
395
315 TEST(Run_WasmModule_GrowMemoryInIf) { 396 TEST(Run_WasmModule_GrowMemoryInIf) {
316 TestSignatures sigs; 397 TestSignatures sigs;
317 v8::internal::AccountingAllocator allocator; 398 v8::internal::AccountingAllocator allocator;
318 Zone zone(&allocator); 399 Zone zone(&allocator);
319 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone); 400 WasmModuleBuilder* builder = new (&zone) WasmModuleBuilder(&zone);
320 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v()); 401 WasmFunctionBuilder* f = builder->AddFunction(sigs.i_v());
321 ExportAsMain(f); 402 ExportAsMain(f);
322 byte code[] = {WASM_IF_ELSE_I(WASM_I32V(0), WASM_GROW_MEMORY(WASM_I32V(1)), 403 byte code[] = {WASM_IF_ELSE_I(WASM_I32V(0), WASM_GROW_MEMORY(WASM_I32V(1)),
323 WASM_I32V(12))}; 404 WASM_I32V(12))};
324 f->EmitCode(code, sizeof(code)); 405 f->EmitCode(code, sizeof(code));
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP, 441 WASM_GROW_MEMORY(WASM_GET_LOCAL(0)), WASM_DROP,
361 WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), WASM_I32V(value)), 442 WASM_STORE_MEM(MachineType::Int32(), WASM_I32V(index), WASM_I32V(value)),
362 WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))}; 443 WASM_LOAD_MEM(MachineType::Int32(), WASM_I32V(index))};
363 f->EmitCode(code, sizeof(code)); 444 f->EmitCode(code, sizeof(code));
364 445
365 HandleScope scope(isolate); 446 HandleScope scope(isolate);
366 ZoneBuffer buffer(&zone); 447 ZoneBuffer buffer(&zone);
367 builder->WriteTo(buffer); 448 builder->WriteTo(buffer);
368 testing::SetupIsolateForWasmModule(isolate); 449 testing::SetupIsolateForWasmModule(isolate);
369 450
451 ErrorThrower thrower(isolate, "Test");
370 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting( 452 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting(
371 isolate, &zone, buffer.begin(), buffer.end(), ModuleOrigin::kWasmOrigin); 453 isolate, &thrower, &zone, buffer.begin(), buffer.end(),
454 ModuleOrigin::kWasmOrigin);
372 CHECK(!instance.is_null()); 455 CHECK(!instance.is_null());
373 456
374 // Initial memory size is 16 pages, should trap till index > MemSize on 457 // Initial memory size is 16 pages, should trap till index > MemSize on
375 // consecutive GrowMem calls 458 // consecutive GrowMem calls
376 for (uint32_t i = 1; i < 5; i++) { 459 for (uint32_t i = 1; i < 5; i++) {
377 Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(i), isolate)}; 460 Handle<Object> params[1] = {Handle<Object>(Smi::FromInt(i), isolate)};
378 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); 461 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
379 testing::RunWasmModuleForTesting(isolate, instance, 1, params, 462 testing::RunWasmModuleForTesting(isolate, instance, 1, params,
380 ModuleOrigin::kWasmOrigin); 463 ModuleOrigin::kWasmOrigin);
381 CHECK(try_catch.HasCaught()); 464 CHECK(try_catch.HasCaught());
(...skipping 21 matching lines...) Expand all
403 WASM_GROW_MEMORY(WASM_I8(1)), WASM_DROP, 486 WASM_GROW_MEMORY(WASM_I8(1)), WASM_DROP,
404 WASM_STORE_MEM(MachineType::Int32(), WASM_GET_LOCAL(0), WASM_I32V(value)), 487 WASM_STORE_MEM(MachineType::Int32(), WASM_GET_LOCAL(0), WASM_I32V(value)),
405 WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))}; 488 WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))};
406 f->EmitCode(code, sizeof(code)); 489 f->EmitCode(code, sizeof(code));
407 490
408 HandleScope scope(isolate); 491 HandleScope scope(isolate);
409 ZoneBuffer buffer(&zone); 492 ZoneBuffer buffer(&zone);
410 builder->WriteTo(buffer); 493 builder->WriteTo(buffer);
411 testing::SetupIsolateForWasmModule(isolate); 494 testing::SetupIsolateForWasmModule(isolate);
412 495
496 ErrorThrower thrower(isolate, "Test");
413 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting( 497 Handle<JSObject> instance = testing::CompileInstantiateWasmModuleForTesting(
414 isolate, &zone, buffer.begin(), buffer.end(), ModuleOrigin::kWasmOrigin); 498 isolate, &thrower, &zone, buffer.begin(), buffer.end(),
499 ModuleOrigin::kWasmOrigin);
415 500
416 CHECK(!instance.is_null()); 501 CHECK(!instance.is_null());
417 502
418 // Initial memory size is 16 pages, should trap till index > MemSize on 503 // Initial memory size is 16 pages, should trap till index > MemSize on
419 // consecutive GrowMem calls 504 // consecutive GrowMem calls
420 for (int i = 1; i < 5; i++) { 505 for (int i = 1; i < 5; i++) {
421 Handle<Object> params[1] = { 506 Handle<Object> params[1] = {
422 Handle<Object>(Smi::FromInt((16 + i) * kPageSize - 3), isolate)}; 507 Handle<Object>(Smi::FromInt((16 + i) * kPageSize - 3), isolate)};
423 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate)); 508 v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
424 testing::RunWasmModuleForTesting(isolate, instance, 1, params, 509 testing::RunWasmModuleForTesting(isolate, instance, 1, params,
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
527 612
528 TEST(Run_WasmModule_Global_f32) { 613 TEST(Run_WasmModule_Global_f32) {
529 RunWasmModuleGlobalInitTest<float>(kAstF32, -983.9f); 614 RunWasmModuleGlobalInitTest<float>(kAstF32, -983.9f);
530 RunWasmModuleGlobalInitTest<float>(kAstF32, 1122.99f); 615 RunWasmModuleGlobalInitTest<float>(kAstF32, 1122.99f);
531 } 616 }
532 617
533 TEST(Run_WasmModule_Global_f64) { 618 TEST(Run_WasmModule_Global_f64) {
534 RunWasmModuleGlobalInitTest<double>(kAstF64, -833.9); 619 RunWasmModuleGlobalInitTest<double>(kAstF64, -833.9);
535 RunWasmModuleGlobalInitTest<double>(kAstF64, 86374.25); 620 RunWasmModuleGlobalInitTest<double>(kAstF64, 86374.25);
536 } 621 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698