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 <stdint.h> | 5 #include <stdint.h> |
6 #include <stdlib.h> | 6 #include <stdlib.h> |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
10 #include "src/utils.h" | 10 #include "src/utils.h" |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 BUILD(r, WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 379 BUILD(r, WASM_I32_SAR(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
380 | 380 |
381 FOR_INT32_INPUTS(i) { | 381 FOR_INT32_INPUTS(i) { |
382 FOR_INT32_INPUTS(j) { | 382 FOR_INT32_INPUTS(j) { |
383 int32_t expected = (*i) >> (*j & 0x1f); | 383 int32_t expected = (*i) >> (*j & 0x1f); |
384 CHECK_EQ(expected, r.Call(*i, *j)); | 384 CHECK_EQ(expected, r.Call(*i, *j)); |
385 } | 385 } |
386 } | 386 } |
387 } | 387 } |
388 | 388 |
389 WASM_EXEC_TEST(Int32DivS_trap) { | 389 WASM_EXEC_TEST_WITH_TRAP(Int32DivS_trap) { |
390 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), | 390 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
391 MachineType::Int32()); | 391 MachineType::Int32()); |
392 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 392 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
393 const int32_t kMin = std::numeric_limits<int32_t>::min(); | 393 const int32_t kMin = std::numeric_limits<int32_t>::min(); |
394 CHECK_EQ(0, r.Call(0, 100)); | 394 CHECK_EQ(0, r.Call(0, 100)); |
395 CHECK_TRAP(r.Call(100, 0)); | 395 CHECK_TRAP(r.Call(100, 0)); |
396 CHECK_TRAP(r.Call(-1001, 0)); | 396 CHECK_TRAP(r.Call(-1001, 0)); |
397 CHECK_TRAP(r.Call(kMin, -1)); | 397 CHECK_TRAP(r.Call(kMin, -1)); |
398 CHECK_TRAP(r.Call(kMin, 0)); | 398 CHECK_TRAP(r.Call(kMin, 0)); |
399 } | 399 } |
400 | 400 |
401 WASM_EXEC_TEST(Int32RemS_trap) { | 401 WASM_EXEC_TEST_WITH_TRAP(Int32RemS_trap) { |
402 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), | 402 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
403 MachineType::Int32()); | 403 MachineType::Int32()); |
404 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 404 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
405 const int32_t kMin = std::numeric_limits<int32_t>::min(); | 405 const int32_t kMin = std::numeric_limits<int32_t>::min(); |
406 CHECK_EQ(33, r.Call(133, 100)); | 406 CHECK_EQ(33, r.Call(133, 100)); |
407 CHECK_EQ(0, r.Call(kMin, -1)); | 407 CHECK_EQ(0, r.Call(kMin, -1)); |
408 CHECK_TRAP(r.Call(100, 0)); | 408 CHECK_TRAP(r.Call(100, 0)); |
409 CHECK_TRAP(r.Call(-1001, 0)); | 409 CHECK_TRAP(r.Call(-1001, 0)); |
410 CHECK_TRAP(r.Call(kMin, 0)); | 410 CHECK_TRAP(r.Call(kMin, 0)); |
411 } | 411 } |
412 | 412 |
413 WASM_EXEC_TEST(Int32DivU_trap) { | 413 WASM_EXEC_TEST_WITH_TRAP(Int32DivU_trap) { |
414 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), | 414 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
415 MachineType::Int32()); | 415 MachineType::Int32()); |
416 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 416 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
417 const int32_t kMin = std::numeric_limits<int32_t>::min(); | 417 const int32_t kMin = std::numeric_limits<int32_t>::min(); |
418 CHECK_EQ(0, r.Call(0, 100)); | 418 CHECK_EQ(0, r.Call(0, 100)); |
419 CHECK_EQ(0, r.Call(kMin, -1)); | 419 CHECK_EQ(0, r.Call(kMin, -1)); |
420 CHECK_TRAP(r.Call(100, 0)); | 420 CHECK_TRAP(r.Call(100, 0)); |
421 CHECK_TRAP(r.Call(-1001, 0)); | 421 CHECK_TRAP(r.Call(-1001, 0)); |
422 CHECK_TRAP(r.Call(kMin, 0)); | 422 CHECK_TRAP(r.Call(kMin, 0)); |
423 } | 423 } |
424 | 424 |
425 WASM_EXEC_TEST(Int32RemU_trap) { | 425 WASM_EXEC_TEST_WITH_TRAP(Int32RemU_trap) { |
426 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), | 426 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
427 MachineType::Int32()); | 427 MachineType::Int32()); |
428 BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 428 BUILD(r, WASM_I32_REMU(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
429 CHECK_EQ(17, r.Call(217, 100)); | 429 CHECK_EQ(17, r.Call(217, 100)); |
430 const int32_t kMin = std::numeric_limits<int32_t>::min(); | 430 const int32_t kMin = std::numeric_limits<int32_t>::min(); |
431 CHECK_TRAP(r.Call(100, 0)); | 431 CHECK_TRAP(r.Call(100, 0)); |
432 CHECK_TRAP(r.Call(-1001, 0)); | 432 CHECK_TRAP(r.Call(-1001, 0)); |
433 CHECK_TRAP(r.Call(kMin, 0)); | 433 CHECK_TRAP(r.Call(kMin, 0)); |
434 CHECK_EQ(kMin, r.Call(kMin, -1)); | 434 CHECK_EQ(kMin, r.Call(kMin, -1)); |
435 } | 435 } |
436 | 436 |
437 WASM_EXEC_TEST(Int32DivS_byzero_const) { | 437 WASM_EXEC_TEST_WITH_TRAP(Int32DivS_byzero_const) { |
438 for (int8_t denom = -2; denom < 8; ++denom) { | 438 for (int8_t denom = -2; denom < 8; ++denom) { |
439 WasmRunner<int32_t> r(execution_mode, MachineType::Int32()); | 439 WasmRunner<int32_t> r(execution_mode, MachineType::Int32()); |
440 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom))); | 440 BUILD(r, WASM_I32_DIVS(WASM_GET_LOCAL(0), WASM_I8(denom))); |
441 for (int32_t val = -7; val < 8; ++val) { | 441 for (int32_t val = -7; val < 8; ++val) { |
442 if (denom == 0) { | 442 if (denom == 0) { |
443 CHECK_TRAP(r.Call(val)); | 443 CHECK_TRAP(r.Call(val)); |
444 } else { | 444 } else { |
445 CHECK_EQ(val / denom, r.Call(val)); | 445 CHECK_EQ(val / denom, r.Call(val)); |
446 } | 446 } |
447 } | 447 } |
(...skipping 29 matching lines...) Expand all Loading... |
477 CHECK_EQ(0, r.Call(*i)); | 477 CHECK_EQ(0, r.Call(*i)); |
478 } else if (denom == -1 && *i == std::numeric_limits<int32_t>::min()) { | 478 } else if (denom == -1 && *i == std::numeric_limits<int32_t>::min()) { |
479 CHECK_EQ(0, r.Call(*i)); | 479 CHECK_EQ(0, r.Call(*i)); |
480 } else { | 480 } else { |
481 CHECK_EQ(*i % denom, r.Call(*i)); | 481 CHECK_EQ(*i % denom, r.Call(*i)); |
482 } | 482 } |
483 } | 483 } |
484 } | 484 } |
485 } | 485 } |
486 | 486 |
487 WASM_EXEC_TEST(Int32DivU_byzero_const) { | 487 WASM_EXEC_TEST_WITH_TRAP(Int32DivU_byzero_const) { |
488 for (uint32_t denom = 0xfffffffe; denom < 8; ++denom) { | 488 for (uint32_t denom = 0xfffffffe; denom < 8; ++denom) { |
489 WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32()); | 489 WasmRunner<uint32_t> r(execution_mode, MachineType::Uint32()); |
490 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32V_1(denom))); | 490 BUILD(r, WASM_I32_DIVU(WASM_GET_LOCAL(0), WASM_I32V_1(denom))); |
491 | 491 |
492 for (uint32_t val = 0xfffffff0; val < 8; ++val) { | 492 for (uint32_t val = 0xfffffff0; val < 8; ++val) { |
493 if (denom == 0) { | 493 if (denom == 0) { |
494 CHECK_TRAP(r.Call(val)); | 494 CHECK_TRAP(r.Call(val)); |
495 } else { | 495 } else { |
496 CHECK_EQ(val / denom, r.Call(val)); | 496 CHECK_EQ(val / denom, r.Call(val)); |
497 } | 497 } |
498 } | 498 } |
499 } | 499 } |
500 } | 500 } |
501 | 501 |
502 WASM_EXEC_TEST(Int32DivS_trap_effect) { | 502 WASM_EXEC_TEST_WITH_TRAP(Int32DivS_trap_effect) { |
503 TestingModule module(execution_mode); | 503 TestingModule module(execution_mode); |
504 module.AddMemoryElems<int32_t>(8); | 504 module.AddMemoryElems<int32_t>(8); |
505 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32()); | 505 WasmRunner<int32_t> r(&module, MachineType::Int32(), MachineType::Int32()); |
506 | 506 |
507 BUILD(r, WASM_IF_ELSE_I( | 507 BUILD(r, WASM_IF_ELSE_I( |
508 WASM_GET_LOCAL(0), | 508 WASM_GET_LOCAL(0), |
509 WASM_I32_DIVS( | 509 WASM_I32_DIVS( |
510 WASM_BLOCK_I(WASM_STORE_MEM(MachineType::Int8(), WASM_ZERO, | 510 WASM_BLOCK_I(WASM_STORE_MEM(MachineType::Int8(), WASM_ZERO, |
511 WASM_GET_LOCAL(0)), | 511 WASM_GET_LOCAL(0)), |
512 WASM_GET_LOCAL(0)), | 512 WASM_GET_LOCAL(0)), |
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1102 WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))), | 1102 WASM_F32_REINTERPRET_I32(WASM_GET_LOCAL(0))), |
1103 WASM_I8(107)); | 1103 WASM_I8(107)); |
1104 | 1104 |
1105 FOR_INT32_INPUTS(i) { | 1105 FOR_INT32_INPUTS(i) { |
1106 int32_t expected = *i; | 1106 int32_t expected = *i; |
1107 CHECK_EQ(107, r.Call(expected)); | 1107 CHECK_EQ(107, r.Call(expected)); |
1108 CHECK_EQ(expected, module.ReadMemory(&memory[0])); | 1108 CHECK_EQ(expected, module.ReadMemory(&memory[0])); |
1109 } | 1109 } |
1110 } | 1110 } |
1111 | 1111 |
1112 WASM_EXEC_TEST(LoadMaxUint32Offset) { | 1112 WASM_EXEC_TEST_WITH_TRAP(LoadMaxUint32Offset) { |
1113 TestingModule module(execution_mode); | 1113 TestingModule module(execution_mode); |
1114 module.AddMemoryElems<int32_t>(8); | 1114 module.AddMemoryElems<int32_t>(8); |
1115 WasmRunner<int32_t> r(&module); | 1115 WasmRunner<int32_t> r(&module); |
1116 | 1116 |
1117 BUILD(r, kExprI8Const, 0, // index | 1117 BUILD(r, kExprI8Const, 0, // index |
1118 static_cast<byte>(v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf( | 1118 static_cast<byte>(v8::internal::wasm::WasmOpcodes::LoadStoreOpcodeOf( |
1119 MachineType::Int32(), false)), // -- | 1119 MachineType::Int32(), false)), // -- |
1120 0, // alignment | 1120 0, // alignment |
1121 U32V_5(0xffffffff)); // offset | 1121 U32V_5(0xffffffff)); // offset |
1122 | 1122 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1505 CHECK_EQ(0x1a2b3c4d, r.Call(0)); | 1505 CHECK_EQ(0x1a2b3c4d, r.Call(0)); |
1506 | 1506 |
1507 module.WriteMemory(&memory[0], 0x5e6f7a8b); | 1507 module.WriteMemory(&memory[0], 0x5e6f7a8b); |
1508 CHECK_EQ(0x5e6f7a8b, r.Call(0)); | 1508 CHECK_EQ(0x5e6f7a8b, r.Call(0)); |
1509 | 1509 |
1510 module.WriteMemory(&memory[0], 0x7ca0b1c2); | 1510 module.WriteMemory(&memory[0], 0x7ca0b1c2); |
1511 CHECK_EQ(0x7ca0b1c2, r.Call(0)); | 1511 CHECK_EQ(0x7ca0b1c2, r.Call(0)); |
1512 } | 1512 } |
1513 } | 1513 } |
1514 | 1514 |
1515 WASM_EXEC_TEST(LoadMemI32_oob) { | 1515 WASM_EXEC_TEST_WITH_TRAP(LoadMemI32_oob) { |
1516 TestingModule module(execution_mode); | 1516 TestingModule module(execution_mode); |
1517 int32_t* memory = module.AddMemoryElems<int32_t>(8); | 1517 int32_t* memory = module.AddMemoryElems<int32_t>(8); |
1518 WasmRunner<int32_t> r(&module, MachineType::Uint32()); | 1518 WasmRunner<int32_t> r(&module, MachineType::Uint32()); |
1519 module.RandomizeMemory(1111); | 1519 module.RandomizeMemory(1111); |
1520 | 1520 |
1521 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))); | 1521 BUILD(r, WASM_LOAD_MEM(MachineType::Int32(), WASM_GET_LOCAL(0))); |
1522 | 1522 |
1523 module.WriteMemory(&memory[0], 88888888); | 1523 module.WriteMemory(&memory[0], 88888888); |
1524 CHECK_EQ(88888888, r.Call(0u)); | 1524 CHECK_EQ(88888888, r.Call(0u)); |
1525 for (uint32_t offset = 29; offset < 40; ++offset) { | 1525 for (uint32_t offset = 29; offset < 40; ++offset) { |
1526 CHECK_TRAP(r.Call(offset)); | 1526 CHECK_TRAP(r.Call(offset)); |
1527 } | 1527 } |
1528 | 1528 |
1529 for (uint32_t offset = 0x80000000; offset < 0x80000010; ++offset) { | 1529 for (uint32_t offset = 0x80000000; offset < 0x80000010; ++offset) { |
1530 CHECK_TRAP(r.Call(offset)); | 1530 CHECK_TRAP(r.Call(offset)); |
1531 } | 1531 } |
1532 } | 1532 } |
1533 | 1533 |
1534 WASM_EXEC_TEST(LoadMem_offset_oob) { | 1534 WASM_EXEC_TEST_WITH_TRAP(LoadMem_offset_oob) { |
1535 TestingModule module(execution_mode); | 1535 TestingModule module(execution_mode); |
1536 module.AddMemoryElems<int32_t>(8); | 1536 module.AddMemoryElems<int32_t>(8); |
1537 | 1537 |
1538 static const MachineType machineTypes[] = { | 1538 static const MachineType machineTypes[] = { |
1539 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), | 1539 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), |
1540 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), | 1540 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), |
1541 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(), | 1541 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(), |
1542 MachineType::Float64()}; | 1542 MachineType::Float64()}; |
1543 | 1543 |
1544 for (size_t m = 0; m < arraysize(machineTypes); ++m) { | 1544 for (size_t m = 0; m < arraysize(machineTypes); ++m) { |
(...skipping 30 matching lines...) Expand all Loading... |
1575 | 1575 |
1576 module.WriteMemory(&memory[0], 11111111); | 1576 module.WriteMemory(&memory[0], 11111111); |
1577 module.WriteMemory(&memory[1], 22222222); | 1577 module.WriteMemory(&memory[1], 22222222); |
1578 module.WriteMemory(&memory[2], 33333333); | 1578 module.WriteMemory(&memory[2], 33333333); |
1579 module.WriteMemory(&memory[3], 44444444); | 1579 module.WriteMemory(&memory[3], 44444444); |
1580 CHECK_EQ(22222222, r.Call(0)); | 1580 CHECK_EQ(22222222, r.Call(0)); |
1581 CHECK_EQ(33333333, r.Call(4)); | 1581 CHECK_EQ(33333333, r.Call(4)); |
1582 CHECK_EQ(44444444, r.Call(8)); | 1582 CHECK_EQ(44444444, r.Call(8)); |
1583 } | 1583 } |
1584 | 1584 |
1585 WASM_EXEC_TEST(LoadMemI32_const_oob_misaligned) { | 1585 WASM_EXEC_TEST_WITH_TRAP(LoadMemI32_const_oob_misaligned) { |
1586 const int kMemSize = 12; | 1586 const int kMemSize = 12; |
1587 // TODO(titzer): Fix misaligned accesses on MIPS and re-enable. | 1587 // TODO(titzer): Fix misaligned accesses on MIPS and re-enable. |
1588 for (int offset = 0; offset < kMemSize + 5; ++offset) { | 1588 for (int offset = 0; offset < kMemSize + 5; ++offset) { |
1589 for (int index = 0; index < kMemSize + 5; ++index) { | 1589 for (int index = 0; index < kMemSize + 5; ++index) { |
1590 TestingModule module(execution_mode); | 1590 TestingModule module(execution_mode); |
1591 module.AddMemoryElems<byte>(kMemSize); | 1591 module.AddMemoryElems<byte>(kMemSize); |
1592 | 1592 |
1593 WasmRunner<int32_t> r(&module); | 1593 WasmRunner<int32_t> r(&module); |
1594 module.RandomizeMemory(); | 1594 module.RandomizeMemory(); |
1595 | 1595 |
1596 BUILD(r, | 1596 BUILD(r, |
1597 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index))); | 1597 WASM_LOAD_MEM_OFFSET(MachineType::Int32(), offset, WASM_I8(index))); |
1598 | 1598 |
1599 if ((offset + index) <= static_cast<int>((kMemSize - sizeof(int32_t)))) { | 1599 if ((offset + index) <= static_cast<int>((kMemSize - sizeof(int32_t)))) { |
1600 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call()); | 1600 CHECK_EQ(module.raw_val_at<int32_t>(offset + index), r.Call()); |
1601 } else { | 1601 } else { |
1602 CHECK_TRAP(r.Call()); | 1602 CHECK_TRAP(r.Call()); |
1603 } | 1603 } |
1604 } | 1604 } |
1605 } | 1605 } |
1606 } | 1606 } |
1607 | 1607 |
1608 WASM_EXEC_TEST(LoadMemI32_const_oob) { | 1608 WASM_EXEC_TEST_WITH_TRAP(LoadMemI32_const_oob) { |
1609 const int kMemSize = 24; | 1609 const int kMemSize = 24; |
1610 for (int offset = 0; offset < kMemSize + 5; offset += 4) { | 1610 for (int offset = 0; offset < kMemSize + 5; offset += 4) { |
1611 for (int index = 0; index < kMemSize + 5; index += 4) { | 1611 for (int index = 0; index < kMemSize + 5; index += 4) { |
1612 TestingModule module(execution_mode); | 1612 TestingModule module(execution_mode); |
1613 module.AddMemoryElems<byte>(kMemSize); | 1613 module.AddMemoryElems<byte>(kMemSize); |
1614 | 1614 |
1615 WasmRunner<int32_t> r(&module); | 1615 WasmRunner<int32_t> r(&module); |
1616 module.RandomizeMemory(); | 1616 module.RandomizeMemory(); |
1617 | 1617 |
1618 BUILD(r, | 1618 BUILD(r, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1662 module.WriteMemory(&memory[2], 88888888); | 1662 module.WriteMemory(&memory[2], 88888888); |
1663 module.WriteMemory(&memory[3], 99999999); | 1663 module.WriteMemory(&memory[3], 99999999); |
1664 CHECK_EQ(kWritten, r.Call(i * 4)); | 1664 CHECK_EQ(kWritten, r.Call(i * 4)); |
1665 CHECK_EQ(66666666, module.ReadMemory(&memory[0])); | 1665 CHECK_EQ(66666666, module.ReadMemory(&memory[0])); |
1666 CHECK_EQ(i == 0 ? kWritten : 77777777, module.ReadMemory(&memory[1])); | 1666 CHECK_EQ(i == 0 ? kWritten : 77777777, module.ReadMemory(&memory[1])); |
1667 CHECK_EQ(i == 1 ? kWritten : 88888888, module.ReadMemory(&memory[2])); | 1667 CHECK_EQ(i == 1 ? kWritten : 88888888, module.ReadMemory(&memory[2])); |
1668 CHECK_EQ(i == 2 ? kWritten : 99999999, module.ReadMemory(&memory[3])); | 1668 CHECK_EQ(i == 2 ? kWritten : 99999999, module.ReadMemory(&memory[3])); |
1669 } | 1669 } |
1670 } | 1670 } |
1671 | 1671 |
1672 WASM_EXEC_TEST(StoreMem_offset_oob) { | 1672 WASM_EXEC_TEST_WITH_TRAP(StoreMem_offset_oob) { |
1673 TestingModule module(execution_mode); | 1673 TestingModule module(execution_mode); |
1674 byte* memory = module.AddMemoryElems<byte>(32); | 1674 byte* memory = module.AddMemoryElems<byte>(32); |
1675 | 1675 |
1676 // 64-bit cases are handled in test-run-wasm-64.cc | 1676 // 64-bit cases are handled in test-run-wasm-64.cc |
1677 static const MachineType machineTypes[] = { | 1677 static const MachineType machineTypes[] = { |
1678 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), | 1678 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), |
1679 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), | 1679 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), |
1680 MachineType::Float32(), MachineType::Float64()}; | 1680 MachineType::Float32(), MachineType::Float64()}; |
1681 | 1681 |
1682 for (size_t m = 0; m < arraysize(machineTypes); ++m) { | 1682 for (size_t m = 0; m < arraysize(machineTypes); ++m) { |
(...skipping 921 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2604 WASM_BRV(1, WASM_I8(12))), | 2604 WASM_BRV(1, WASM_I8(12))), |
2605 WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)), | 2605 WASM_IF_ELSE_I(WASM_GET_LOCAL(1), WASM_BRV(0, WASM_I8(13)), |
2606 WASM_BRV(1, WASM_I8(14)))))); | 2606 WASM_BRV(1, WASM_I8(14)))))); |
2607 | 2607 |
2608 CHECK_EQ(11, r.Call(1, 1)); | 2608 CHECK_EQ(11, r.Call(1, 1)); |
2609 CHECK_EQ(12, r.Call(1, 0)); | 2609 CHECK_EQ(12, r.Call(1, 0)); |
2610 CHECK_EQ(13, r.Call(0, 1)); | 2610 CHECK_EQ(13, r.Call(0, 1)); |
2611 CHECK_EQ(14, r.Call(0, 0)); | 2611 CHECK_EQ(14, r.Call(0, 0)); |
2612 } | 2612 } |
2613 | 2613 |
2614 WASM_EXEC_TEST(SimpleCallIndirect) { | 2614 WASM_EXEC_TEST_WITH_TRAP(SimpleCallIndirect) { |
2615 TestSignatures sigs; | 2615 TestSignatures sigs; |
2616 TestingModule module(execution_mode); | 2616 TestingModule module(execution_mode); |
2617 | 2617 |
2618 WasmFunctionCompiler t1(sigs.i_ii(), &module); | 2618 WasmFunctionCompiler t1(sigs.i_ii(), &module); |
2619 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2619 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2620 t1.CompileAndAdd(/*sig_index*/ 1); | 2620 t1.CompileAndAdd(/*sig_index*/ 1); |
2621 | 2621 |
2622 WasmFunctionCompiler t2(sigs.i_ii(), &module); | 2622 WasmFunctionCompiler t2(sigs.i_ii(), &module); |
2623 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2623 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2624 t2.CompileAndAdd(/*sig_index*/ 1); | 2624 t2.CompileAndAdd(/*sig_index*/ 1); |
(...skipping 11 matching lines...) Expand all Loading... |
2636 | 2636 |
2637 // Builder the caller function. | 2637 // Builder the caller function. |
2638 WasmRunner<int32_t> r(&module, MachineType::Int32()); | 2638 WasmRunner<int32_t> r(&module, MachineType::Int32()); |
2639 BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22))); | 2639 BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22))); |
2640 | 2640 |
2641 CHECK_EQ(88, r.Call(0)); | 2641 CHECK_EQ(88, r.Call(0)); |
2642 CHECK_EQ(44, r.Call(1)); | 2642 CHECK_EQ(44, r.Call(1)); |
2643 CHECK_TRAP(r.Call(2)); | 2643 CHECK_TRAP(r.Call(2)); |
2644 } | 2644 } |
2645 | 2645 |
2646 WASM_EXEC_TEST(MultipleCallIndirect) { | 2646 WASM_EXEC_TEST_WITH_TRAP(MultipleCallIndirect) { |
2647 TestSignatures sigs; | 2647 TestSignatures sigs; |
2648 TestingModule module(execution_mode); | 2648 TestingModule module(execution_mode); |
2649 | 2649 |
2650 WasmFunctionCompiler t1(sigs.i_ii(), &module); | 2650 WasmFunctionCompiler t1(sigs.i_ii(), &module); |
2651 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2651 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2652 t1.CompileAndAdd(/*sig_index*/ 1); | 2652 t1.CompileAndAdd(/*sig_index*/ 1); |
2653 | 2653 |
2654 WasmFunctionCompiler t2(sigs.i_ii(), &module); | 2654 WasmFunctionCompiler t2(sigs.i_ii(), &module); |
2655 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2655 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2656 t2.CompileAndAdd(/*sig_index*/ 1); | 2656 t2.CompileAndAdd(/*sig_index*/ 1); |
(...skipping 22 matching lines...) Expand all Loading... |
2679 CHECK_EQ(19, r.Call(0, 1, 9)); | 2679 CHECK_EQ(19, r.Call(0, 1, 9)); |
2680 CHECK_EQ(1, r.Call(1, 0, 2)); | 2680 CHECK_EQ(1, r.Call(1, 0, 2)); |
2681 CHECK_EQ(1, r.Call(1, 0, 9)); | 2681 CHECK_EQ(1, r.Call(1, 0, 9)); |
2682 | 2682 |
2683 CHECK_TRAP(r.Call(0, 2, 1)); | 2683 CHECK_TRAP(r.Call(0, 2, 1)); |
2684 CHECK_TRAP(r.Call(1, 2, 0)); | 2684 CHECK_TRAP(r.Call(1, 2, 0)); |
2685 CHECK_TRAP(r.Call(2, 0, 1)); | 2685 CHECK_TRAP(r.Call(2, 0, 1)); |
2686 CHECK_TRAP(r.Call(2, 1, 0)); | 2686 CHECK_TRAP(r.Call(2, 1, 0)); |
2687 } | 2687 } |
2688 | 2688 |
2689 WASM_EXEC_TEST(CallIndirect_EmptyTable) { | 2689 WASM_EXEC_TEST_WITH_TRAP(CallIndirect_EmptyTable) { |
2690 TestSignatures sigs; | 2690 TestSignatures sigs; |
2691 TestingModule module(execution_mode); | 2691 TestingModule module(execution_mode); |
2692 | 2692 |
2693 // One function. | 2693 // One function. |
2694 WasmFunctionCompiler t1(sigs.i_ii(), &module); | 2694 WasmFunctionCompiler t1(sigs.i_ii(), &module); |
2695 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2695 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2696 t1.CompileAndAdd(/*sig_index*/ 1); | 2696 t1.CompileAndAdd(/*sig_index*/ 1); |
2697 | 2697 |
2698 // Signature table. | 2698 // Signature table. |
2699 module.AddSignature(sigs.f_ff()); | 2699 module.AddSignature(sigs.f_ff()); |
2700 module.AddSignature(sigs.i_ii()); | 2700 module.AddSignature(sigs.i_ii()); |
2701 module.AddIndirectFunctionTable(nullptr, 0); | 2701 module.AddIndirectFunctionTable(nullptr, 0); |
2702 | 2702 |
2703 // Builder the caller function. | 2703 // Builder the caller function. |
2704 WasmRunner<int32_t> r(&module, MachineType::Int32()); | 2704 WasmRunner<int32_t> r(&module, MachineType::Int32()); |
2705 BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22))); | 2705 BUILD(r, WASM_CALL_INDIRECT2(1, WASM_GET_LOCAL(0), WASM_I8(66), WASM_I8(22))); |
2706 | 2706 |
2707 CHECK_TRAP(r.Call(0)); | 2707 CHECK_TRAP(r.Call(0)); |
2708 CHECK_TRAP(r.Call(1)); | 2708 CHECK_TRAP(r.Call(1)); |
2709 CHECK_TRAP(r.Call(2)); | 2709 CHECK_TRAP(r.Call(2)); |
2710 } | 2710 } |
2711 | 2711 |
2712 WASM_EXEC_TEST(CallIndirect_canonical) { | 2712 WASM_EXEC_TEST_WITH_TRAP(CallIndirect_canonical) { |
2713 TestSignatures sigs; | 2713 TestSignatures sigs; |
2714 TestingModule module(execution_mode); | 2714 TestingModule module(execution_mode); |
2715 | 2715 |
2716 WasmFunctionCompiler t1(sigs.i_ii(), &module); | 2716 WasmFunctionCompiler t1(sigs.i_ii(), &module); |
2717 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2717 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2718 t1.CompileAndAdd(/*sig_index*/ 0); | 2718 t1.CompileAndAdd(/*sig_index*/ 0); |
2719 | 2719 |
2720 WasmFunctionCompiler t2(sigs.i_ii(), &module); | 2720 WasmFunctionCompiler t2(sigs.i_ii(), &module); |
2721 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2721 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2722 t2.CompileAndAdd(/*sig_index*/ 1); | 2722 t2.CompileAndAdd(/*sig_index*/ 1); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2844 BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2844 BUILD(r, WASM_F64_MAX(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2845 | 2845 |
2846 FOR_FLOAT64_INPUTS(i) { | 2846 FOR_FLOAT64_INPUTS(i) { |
2847 FOR_FLOAT64_INPUTS(j) { | 2847 FOR_FLOAT64_INPUTS(j) { |
2848 double result = r.Call(*i, *j); | 2848 double result = r.Call(*i, *j); |
2849 CHECK_DOUBLE_EQ(JSMax(*i, *j), result); | 2849 CHECK_DOUBLE_EQ(JSMax(*i, *j), result); |
2850 } | 2850 } |
2851 } | 2851 } |
2852 } | 2852 } |
2853 | 2853 |
2854 WASM_EXEC_TEST(I32SConvertF32) { | 2854 WASM_EXEC_TEST_WITH_TRAP(I32SConvertF32) { |
2855 WasmRunner<int32_t> r(execution_mode, MachineType::Float32()); | 2855 WasmRunner<int32_t> r(execution_mode, MachineType::Float32()); |
2856 BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0))); | 2856 BUILD(r, WASM_I32_SCONVERT_F32(WASM_GET_LOCAL(0))); |
2857 | 2857 |
2858 // The upper bound is (INT32_MAX + 1), which is the lowest float-representable | 2858 // The upper bound is (INT32_MAX + 1), which is the lowest float-representable |
2859 // number above INT32_MAX which cannot be represented as int32. | 2859 // number above INT32_MAX which cannot be represented as int32. |
2860 float upper_bound = 2147483648.0f; | 2860 float upper_bound = 2147483648.0f; |
2861 // We use INT32_MIN as a lower bound because (INT32_MIN - 1) is not | 2861 // We use INT32_MIN as a lower bound because (INT32_MIN - 1) is not |
2862 // representable as float, and no number between (INT32_MIN - 1) and INT32_MIN | 2862 // representable as float, and no number between (INT32_MIN - 1) and INT32_MIN |
2863 // is. | 2863 // is. |
2864 float lower_bound = static_cast<float>(INT32_MIN); | 2864 float lower_bound = static_cast<float>(INT32_MIN); |
2865 FOR_FLOAT32_INPUTS(i) { | 2865 FOR_FLOAT32_INPUTS(i) { |
2866 if (*i < upper_bound && *i >= lower_bound) { | 2866 if (*i < upper_bound && *i >= lower_bound) { |
2867 CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i)); | 2867 CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i)); |
2868 } else { | 2868 } else { |
2869 CHECK_TRAP32(r.Call(*i)); | 2869 CHECK_TRAP32(r.Call(*i)); |
2870 } | 2870 } |
2871 } | 2871 } |
2872 } | 2872 } |
2873 | 2873 |
2874 WASM_EXEC_TEST(I32SConvertF64) { | 2874 WASM_EXEC_TEST_WITH_TRAP(I32SConvertF64) { |
2875 WasmRunner<int32_t> r(execution_mode, MachineType::Float64()); | 2875 WasmRunner<int32_t> r(execution_mode, MachineType::Float64()); |
2876 BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0))); | 2876 BUILD(r, WASM_I32_SCONVERT_F64(WASM_GET_LOCAL(0))); |
2877 | 2877 |
2878 // The upper bound is (INT32_MAX + 1), which is the lowest double- | 2878 // The upper bound is (INT32_MAX + 1), which is the lowest double- |
2879 // representable number above INT32_MAX which cannot be represented as int32. | 2879 // representable number above INT32_MAX which cannot be represented as int32. |
2880 double upper_bound = 2147483648.0; | 2880 double upper_bound = 2147483648.0; |
2881 // The lower bound is (INT32_MIN - 1), which is the greatest double- | 2881 // The lower bound is (INT32_MIN - 1), which is the greatest double- |
2882 // representable number below INT32_MIN which cannot be represented as int32. | 2882 // representable number below INT32_MIN which cannot be represented as int32. |
2883 double lower_bound = -2147483649.0; | 2883 double lower_bound = -2147483649.0; |
2884 FOR_FLOAT64_INPUTS(i) { | 2884 FOR_FLOAT64_INPUTS(i) { |
2885 if (*i<upper_bound&& * i> lower_bound) { | 2885 if (*i<upper_bound&& * i> lower_bound) { |
2886 CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i)); | 2886 CHECK_EQ(static_cast<int32_t>(*i), r.Call(*i)); |
2887 } else { | 2887 } else { |
2888 CHECK_TRAP32(r.Call(*i)); | 2888 CHECK_TRAP32(r.Call(*i)); |
2889 } | 2889 } |
2890 } | 2890 } |
2891 } | 2891 } |
2892 | 2892 |
2893 WASM_EXEC_TEST(I32UConvertF32) { | 2893 WASM_EXEC_TEST_WITH_TRAP(I32UConvertF32) { |
2894 WasmRunner<uint32_t> r(execution_mode, MachineType::Float32()); | 2894 WasmRunner<uint32_t> r(execution_mode, MachineType::Float32()); |
2895 BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0))); | 2895 BUILD(r, WASM_I32_UCONVERT_F32(WASM_GET_LOCAL(0))); |
2896 // The upper bound is (UINT32_MAX + 1), which is the lowest | 2896 // The upper bound is (UINT32_MAX + 1), which is the lowest |
2897 // float-representable number above UINT32_MAX which cannot be represented as | 2897 // float-representable number above UINT32_MAX which cannot be represented as |
2898 // uint32. | 2898 // uint32. |
2899 double upper_bound = 4294967296.0f; | 2899 double upper_bound = 4294967296.0f; |
2900 double lower_bound = -1.0f; | 2900 double lower_bound = -1.0f; |
2901 FOR_FLOAT32_INPUTS(i) { | 2901 FOR_FLOAT32_INPUTS(i) { |
2902 if (*i<upper_bound&& * i> lower_bound) { | 2902 if (*i<upper_bound&& * i> lower_bound) { |
2903 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i)); | 2903 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i)); |
2904 } else { | 2904 } else { |
2905 CHECK_TRAP32(r.Call(*i)); | 2905 CHECK_TRAP32(r.Call(*i)); |
2906 } | 2906 } |
2907 } | 2907 } |
2908 } | 2908 } |
2909 | 2909 |
2910 WASM_EXEC_TEST(I32UConvertF64) { | 2910 WASM_EXEC_TEST_WITH_TRAP(I32UConvertF64) { |
2911 WasmRunner<uint32_t> r(execution_mode, MachineType::Float64()); | 2911 WasmRunner<uint32_t> r(execution_mode, MachineType::Float64()); |
2912 BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0))); | 2912 BUILD(r, WASM_I32_UCONVERT_F64(WASM_GET_LOCAL(0))); |
2913 // The upper bound is (UINT32_MAX + 1), which is the lowest | 2913 // The upper bound is (UINT32_MAX + 1), which is the lowest |
2914 // double-representable number above UINT32_MAX which cannot be represented as | 2914 // double-representable number above UINT32_MAX which cannot be represented as |
2915 // uint32. | 2915 // uint32. |
2916 double upper_bound = 4294967296.0; | 2916 double upper_bound = 4294967296.0; |
2917 double lower_bound = -1.0; | 2917 double lower_bound = -1.0; |
2918 FOR_FLOAT64_INPUTS(i) { | 2918 FOR_FLOAT64_INPUTS(i) { |
2919 if (*i<upper_bound&& * i> lower_bound) { | 2919 if (*i<upper_bound&& * i> lower_bound) { |
2920 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i)); | 2920 CHECK_EQ(static_cast<uint32_t>(*i), r.Call(*i)); |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2972 t.Compile(); | 2972 t.Compile(); |
2973 } | 2973 } |
2974 } | 2974 } |
2975 | 2975 |
2976 TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); } | 2976 TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); } |
2977 | 2977 |
2978 TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); } | 2978 TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); } |
2979 | 2979 |
2980 TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); } | 2980 TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); } |
2981 | 2981 |
2982 WASM_EXEC_TEST(Int32RemS_dead) { | 2982 WASM_EXEC_TEST_WITH_TRAP(Int32RemS_dead) { |
2983 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), | 2983 WasmRunner<int32_t> r(execution_mode, MachineType::Int32(), |
2984 MachineType::Int32()); | 2984 MachineType::Int32()); |
2985 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_DROP, | 2985 BUILD(r, WASM_I32_REMS(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1)), WASM_DROP, |
2986 WASM_ZERO); | 2986 WASM_ZERO); |
2987 const int32_t kMin = std::numeric_limits<int32_t>::min(); | 2987 const int32_t kMin = std::numeric_limits<int32_t>::min(); |
2988 CHECK_EQ(0, r.Call(133, 100)); | 2988 CHECK_EQ(0, r.Call(133, 100)); |
2989 CHECK_EQ(0, r.Call(kMin, -1)); | 2989 CHECK_EQ(0, r.Call(kMin, -1)); |
2990 CHECK_EQ(0, r.Call(0, 1)); | 2990 CHECK_EQ(0, r.Call(0, 1)); |
2991 CHECK_TRAP(r.Call(100, 0)); | 2991 CHECK_TRAP(r.Call(100, 0)); |
2992 CHECK_TRAP(r.Call(-1001, 0)); | 2992 CHECK_TRAP(r.Call(-1001, 0)); |
2993 CHECK_TRAP(r.Call(kMin, 0)); | 2993 CHECK_TRAP(r.Call(kMin, 0)); |
2994 } | 2994 } |
OLD | NEW |