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/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/wasm/wasm-macro-gen.h" | 10 #include "src/wasm/wasm-macro-gen.h" |
11 | 11 |
12 #include "test/cctest/cctest.h" | 12 #include "test/cctest/cctest.h" |
13 #include "test/cctest/compiler/value-helper.h" | 13 #include "test/cctest/compiler/value-helper.h" |
14 #include "test/cctest/wasm/test-signatures.h" | 14 #include "test/cctest/wasm/test-signatures.h" |
15 #include "test/cctest/wasm/wasm-run-utils.h" | 15 #include "test/cctest/wasm/wasm-run-utils.h" |
16 | 16 |
| 17 // If the target architecture is 64-bit, enable all tests. |
| 18 #if !V8_TARGET_ARCH_32_BIT || V8_TARGET_ARCH_X64 |
| 19 #define WASM_64 1 |
| 20 #else |
| 21 #define WASM_64 0 |
| 22 #endif |
| 23 |
17 #define CHECK_TRAP32(x) \ | 24 #define CHECK_TRAP32(x) \ |
18 CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF) | 25 CHECK_EQ(0xdeadbeef, (bit_cast<uint32_t>(x)) & 0xFFFFFFFF) |
19 #define CHECK_TRAP64(x) \ | 26 #define CHECK_TRAP64(x) \ |
20 CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF) | 27 CHECK_EQ(0xdeadbeefdeadbeef, (bit_cast<uint64_t>(x)) & 0xFFFFFFFFFFFFFFFF) |
21 #define CHECK_TRAP(x) CHECK_TRAP32(x) | 28 #define CHECK_TRAP(x) CHECK_TRAP32(x) |
22 | 29 |
23 #define asi64(x) static_cast<int64_t>(x) | 30 #define asi64(x) static_cast<int64_t>(x) |
24 | 31 |
25 #define asu64(x) static_cast<uint64_t>(x) | 32 #define asu64(x) static_cast<uint64_t>(x) |
26 | 33 |
(...skipping 1382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1409 MachineType::Int64()); | 1416 MachineType::Int64()); |
1410 BUILD(r, WASM_I64_ROL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 1417 BUILD(r, WASM_I64_ROL(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
1411 | 1418 |
1412 FOR_UINT64_INPUTS(i) { | 1419 FOR_UINT64_INPUTS(i) { |
1413 FOR_UINT64_INPUTS(j) { | 1420 FOR_UINT64_INPUTS(j) { |
1414 int64_t expected = bits::RotateLeft64(*i, *j & 0x3f); | 1421 int64_t expected = bits::RotateLeft64(*i, *j & 0x3f); |
1415 CHECK_EQ(expected, r.Call(*i, *j)); | 1422 CHECK_EQ(expected, r.Call(*i, *j)); |
1416 } | 1423 } |
1417 } | 1424 } |
1418 } | 1425 } |
| 1426 |
| 1427 WASM_EXEC_TEST(StoreMem_offset_oob_i64) { |
| 1428 TestingModule module(execution_mode); |
| 1429 byte* memory = module.AddMemoryElems<byte>(32); |
| 1430 |
| 1431 static const MachineType machineTypes[] = { |
| 1432 MachineType::Int8(), MachineType::Uint8(), MachineType::Int16(), |
| 1433 MachineType::Uint16(), MachineType::Int32(), MachineType::Uint32(), |
| 1434 MachineType::Int64(), MachineType::Uint64(), MachineType::Float32(), |
| 1435 MachineType::Float64()}; |
| 1436 |
| 1437 for (size_t m = 0; m < arraysize(machineTypes); m++) { |
| 1438 module.RandomizeMemory(1119 + static_cast<int>(m)); |
| 1439 WasmRunner<int32_t> r(&module, MachineType::Uint32()); |
| 1440 |
| 1441 BUILD(r, WASM_STORE_MEM_OFFSET(machineTypes[m], 8, WASM_GET_LOCAL(0), |
| 1442 WASM_LOAD_MEM(machineTypes[m], WASM_ZERO)), |
| 1443 WASM_ZERO); |
| 1444 |
| 1445 byte memsize = WasmOpcodes::MemSize(machineTypes[m]); |
| 1446 uint32_t boundary = 24 - memsize; |
| 1447 CHECK_EQ(0, r.Call(boundary)); // in bounds. |
| 1448 CHECK_EQ(0, memcmp(&memory[0], &memory[8 + boundary], memsize)); |
| 1449 |
| 1450 for (uint32_t offset = boundary + 1; offset < boundary + 19; offset++) { |
| 1451 CHECK_TRAP(r.Call(offset)); // out of bounds. |
| 1452 } |
| 1453 } |
| 1454 } |
| 1455 |
| 1456 #define ADD_CODE(vec, ...) \ |
| 1457 do { \ |
| 1458 byte __buf[] = {__VA_ARGS__}; \ |
| 1459 for (size_t i = 0; i < sizeof(__buf); i++) vec.push_back(__buf[i]); \ |
| 1460 } while (false) |
| 1461 |
| 1462 static void CompileCallIndirectMany(LocalType param) { |
| 1463 // Make sure we don't run out of registers when compiling indirect calls |
| 1464 // with many many parameters. |
| 1465 TestSignatures sigs; |
| 1466 for (byte num_params = 0; num_params < 40; num_params++) { |
| 1467 v8::base::AccountingAllocator allocator; |
| 1468 Zone zone(&allocator); |
| 1469 HandleScope scope(CcTest::InitIsolateOnce()); |
| 1470 TestingModule module(kExecuteCompiled); |
| 1471 FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params); |
| 1472 |
| 1473 module.AddSignature(sig); |
| 1474 module.AddSignature(sig); |
| 1475 module.AddIndirectFunctionTable(nullptr, 0); |
| 1476 |
| 1477 WasmFunctionCompiler t(sig, &module); |
| 1478 |
| 1479 std::vector<byte> code; |
| 1480 ADD_CODE(code, kExprI8Const, 0); |
| 1481 for (byte p = 0; p < num_params; p++) { |
| 1482 ADD_CODE(code, kExprGetLocal, p); |
| 1483 } |
| 1484 ADD_CODE(code, kExprCallIndirect, static_cast<byte>(num_params), 1); |
| 1485 |
| 1486 t.Build(&code[0], &code[0] + code.size()); |
| 1487 t.Compile(); |
| 1488 } |
| 1489 } |
| 1490 |
| 1491 TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); } |
| 1492 |
| 1493 static void Run_WasmMixedCall_N(WasmExecutionMode execution_mode, int start) { |
| 1494 const int kExpected = 6333; |
| 1495 const int kElemSize = 8; |
| 1496 TestSignatures sigs; |
| 1497 |
| 1498 static MachineType mixed[] = { |
| 1499 MachineType::Int32(), MachineType::Float32(), MachineType::Int64(), |
| 1500 MachineType::Float64(), MachineType::Float32(), MachineType::Int64(), |
| 1501 MachineType::Int32(), MachineType::Float64(), MachineType::Float32(), |
| 1502 MachineType::Float64(), MachineType::Int32(), MachineType::Int64(), |
| 1503 MachineType::Int32(), MachineType::Int32()}; |
| 1504 |
| 1505 int num_params = static_cast<int>(arraysize(mixed)) - start; |
| 1506 for (int which = 0; which < num_params; which++) { |
| 1507 v8::base::AccountingAllocator allocator; |
| 1508 Zone zone(&allocator); |
| 1509 TestingModule module(execution_mode); |
| 1510 module.AddMemory(1024); |
| 1511 MachineType* memtypes = &mixed[start]; |
| 1512 MachineType result = memtypes[which]; |
| 1513 |
| 1514 // ========================================================================= |
| 1515 // Build the selector function. |
| 1516 // ========================================================================= |
| 1517 uint32_t index; |
| 1518 FunctionSig::Builder b(&zone, 1, num_params); |
| 1519 b.AddReturn(WasmOpcodes::LocalTypeFor(result)); |
| 1520 for (int i = 0; i < num_params; i++) { |
| 1521 b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i])); |
| 1522 } |
| 1523 WasmFunctionCompiler t(b.Build(), &module); |
| 1524 BUILD(t, WASM_GET_LOCAL(which)); |
| 1525 index = t.CompileAndAdd(); |
| 1526 |
| 1527 // ========================================================================= |
| 1528 // Build the calling function. |
| 1529 // ========================================================================= |
| 1530 WasmRunner<int32_t> r(&module); |
| 1531 std::vector<byte> code; |
| 1532 |
| 1533 // Load the offset for the store. |
| 1534 ADD_CODE(code, WASM_ZERO); |
| 1535 |
| 1536 // Load the arguments. |
| 1537 for (int i = 0; i < num_params; i++) { |
| 1538 int offset = (i + 1) * kElemSize; |
| 1539 ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset))); |
| 1540 } |
| 1541 |
| 1542 // Call the selector function. |
| 1543 ADD_CODE(code, kExprCallFunction, static_cast<byte>(num_params), |
| 1544 static_cast<byte>(index)); |
| 1545 |
| 1546 // Store the result in memory. |
| 1547 ADD_CODE(code, |
| 1548 static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)), |
| 1549 ZERO_ALIGNMENT, ZERO_OFFSET); |
| 1550 |
| 1551 // Return the expected value. |
| 1552 ADD_CODE(code, WASM_I32V_2(kExpected)); |
| 1553 |
| 1554 r.Build(&code[0], &code[0] + code.size()); |
| 1555 |
| 1556 // Run the code. |
| 1557 for (int t = 0; t < 10; t++) { |
| 1558 module.RandomizeMemory(); |
| 1559 CHECK_EQ(kExpected, r.Call()); |
| 1560 |
| 1561 int size = WasmOpcodes::MemSize(result); |
| 1562 for (int i = 0; i < size; i++) { |
| 1563 int base = (which + 1) * kElemSize; |
| 1564 byte expected = module.raw_mem_at<byte>(base + i); |
| 1565 byte result = module.raw_mem_at<byte>(i); |
| 1566 CHECK_EQ(expected, result); |
| 1567 } |
| 1568 } |
| 1569 } |
| 1570 } |
| 1571 |
| 1572 WASM_EXEC_TEST(MixedCall_i64_0) { Run_WasmMixedCall_N(execution_mode, 0); } |
| 1573 WASM_EXEC_TEST(MixedCall_i64_1) { Run_WasmMixedCall_N(execution_mode, 1); } |
| 1574 WASM_EXEC_TEST(MixedCall_i64_2) { Run_WasmMixedCall_N(execution_mode, 2); } |
| 1575 WASM_EXEC_TEST(MixedCall_i64_3) { Run_WasmMixedCall_N(execution_mode, 3); } |
OLD | NEW |