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" |
| 10 |
9 #include "src/wasm/wasm-macro-gen.h" | 11 #include "src/wasm/wasm-macro-gen.h" |
10 | 12 |
11 #include "test/cctest/cctest.h" | 13 #include "test/cctest/cctest.h" |
12 #include "test/cctest/compiler/value-helper.h" | 14 #include "test/cctest/compiler/value-helper.h" |
13 #include "test/cctest/wasm/test-signatures.h" | 15 #include "test/cctest/wasm/test-signatures.h" |
14 #include "test/cctest/wasm/wasm-run-utils.h" | 16 #include "test/cctest/wasm/wasm-run-utils.h" |
15 | 17 |
16 using namespace v8::base; | 18 using namespace v8::base; |
17 using namespace v8::internal; | 19 using namespace v8::internal; |
18 using namespace v8::internal::compiler; | 20 using namespace v8::internal::compiler; |
19 using namespace v8::internal::wasm; | 21 using namespace v8::internal::wasm; |
20 | 22 |
21 // for even shorter tests. | 23 // for even shorter tests. |
22 #define B2(a, b) kExprBlock, 2, a, b | 24 #define B2(a, b) kExprBlock, a, b, kExprEnd |
23 #define B1(a) kExprBlock, 1, a | 25 #define B1(a) kExprBlock, a, kExprEnd |
24 #define RET(x) kExprReturn, x | 26 #define RET(x) x, kExprReturn |
25 #define RET_I8(x) kExprReturn, kExprI8Const, x | 27 #define RET_I8(x) kExprI8Const, x, kExprReturn |
26 | 28 |
27 TEST(Run_WasmInt8Const) { | 29 TEST(Run_WasmInt8Const) { |
28 WasmRunner<int32_t> r; | 30 WasmRunner<int32_t> r; |
29 const byte kExpectedValue = 121; | 31 const byte kExpectedValue = 121; |
30 // return(kExpectedValue) | 32 // return(kExpectedValue) |
31 BUILD(r, WASM_I8(kExpectedValue)); | 33 BUILD(r, WASM_I8(kExpectedValue)); |
32 CHECK_EQ(kExpectedValue, r.Call()); | 34 CHECK_EQ(kExpectedValue, r.Call()); |
33 } | 35 } |
34 | 36 |
35 | 37 |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
588 // if (p0) return 11; else return 22; | 590 // if (p0) return 11; else return 22; |
589 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // -- | 591 BUILD(r, WASM_IF_ELSE(WASM_GET_LOCAL(0), // -- |
590 WASM_I8(11), // -- | 592 WASM_I8(11), // -- |
591 WASM_I8(22))); // -- | 593 WASM_I8(22))); // -- |
592 FOR_INT32_INPUTS(i) { | 594 FOR_INT32_INPUTS(i) { |
593 int32_t expected = *i ? 11 : 22; | 595 int32_t expected = *i ? 11 : 22; |
594 CHECK_EQ(expected, r.Call(*i)); | 596 CHECK_EQ(expected, r.Call(*i)); |
595 } | 597 } |
596 } | 598 } |
597 | 599 |
| 600 TEST(Run_Wasm_If_chain) { |
| 601 WasmRunner<int32_t> r(MachineType::Int32()); |
| 602 // if (p0) 13; if (p0) 14; 15 |
| 603 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_I8(13)), |
| 604 WASM_IF(WASM_GET_LOCAL(0), WASM_I8(14)), WASM_I8(15)); |
| 605 FOR_INT32_INPUTS(i) { CHECK_EQ(15, r.Call(*i)); } |
| 606 } |
| 607 |
| 608 TEST(Run_Wasm_If_chain_set) { |
| 609 WasmRunner<int32_t> r(MachineType::Int32(), MachineType::Int32()); |
| 610 // if (p0) p1 = 73; if (p0) p1 = 74; p1 |
| 611 BUILD(r, WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(73))), |
| 612 WASM_IF(WASM_GET_LOCAL(0), WASM_SET_LOCAL(1, WASM_I8(74))), |
| 613 WASM_GET_LOCAL(1)); |
| 614 FOR_INT32_INPUTS(i) { |
| 615 int32_t expected = *i ? 74 : *i; |
| 616 CHECK_EQ(expected, r.Call(*i, *i)); |
| 617 } |
| 618 } |
598 | 619 |
599 TEST(Run_Wasm_IfElse_Unreachable1) { | 620 TEST(Run_Wasm_IfElse_Unreachable1) { |
600 WasmRunner<int32_t> r; | 621 WasmRunner<int32_t> r; |
601 // if (0) unreachable; else return 22; | 622 // if (0) unreachable; else return 22; |
602 BUILD(r, WASM_IF_ELSE(WASM_ZERO, // -- | 623 BUILD(r, WASM_IF_ELSE(WASM_ZERO, // -- |
603 WASM_UNREACHABLE, // -- | 624 WASM_UNREACHABLE, // -- |
604 WASM_I8(27))); // -- | 625 WASM_I8(27))); // -- |
605 CHECK_EQ(27, r.Call()); | 626 CHECK_EQ(27, r.Call()); |
606 } | 627 } |
607 | 628 |
(...skipping 822 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1430 } | 1451 } |
1431 } | 1452 } |
1432 | 1453 |
1433 | 1454 |
1434 TEST(Run_Wasm_CheckMachIntsZero) { | 1455 TEST(Run_Wasm_CheckMachIntsZero) { |
1435 const int kNumElems = 55; | 1456 const int kNumElems = 55; |
1436 TestingModule module; | 1457 TestingModule module; |
1437 module.AddMemoryElems<uint32_t>(kNumElems); | 1458 module.AddMemoryElems<uint32_t>(kNumElems); |
1438 WasmRunner<uint32_t> r(&module, MachineType::Int32()); | 1459 WasmRunner<uint32_t> r(&module, MachineType::Int32()); |
1439 | 1460 |
1440 BUILD(r, kExprBlock, 2, kExprLoop, 1, kExprIf, kExprGetLocal, 0, kExprBr, 0, | 1461 BUILD(r, kExprLoop, kExprGetLocal, 0, kExprIf, kExprGetLocal, 0, |
1441 kExprIfElse, kExprI32LoadMem, ZERO_ALIGNMENT, ZERO_OFFSET, | 1462 kExprI32LoadMem, 0, 0, kExprIf, kExprI8Const, 255, kExprReturn, |
1442 kExprGetLocal, 0, kExprBr, 2, kExprI8Const, 255, kExprSetLocal, 0, | 1463 kExprEnd, kExprGetLocal, 0, kExprI8Const, 4, kExprI32Sub, kExprSetLocal, |
1443 kExprI32Sub, kExprGetLocal, 0, kExprI8Const, 4, kExprI8Const, 0); | 1464 0, kExprBr, 0, kExprEnd, kExprEnd, kExprI8Const, 0); |
1444 | 1465 |
1445 module.BlankMemory(); | 1466 module.BlankMemory(); |
1446 CHECK_EQ(0, r.Call((kNumElems - 1) * 4)); | 1467 CHECK_EQ(0, r.Call((kNumElems - 1) * 4)); |
1447 } | 1468 } |
1448 | 1469 |
1449 | 1470 |
1450 TEST(Run_Wasm_MemF32_Sum) { | 1471 TEST(Run_Wasm_MemF32_Sum) { |
1451 const int kSize = 5; | 1472 const int kSize = 5; |
1452 TestingModule module; | 1473 TestingModule module; |
1453 module.AddMemoryElems<float>(kSize); | 1474 module.AddMemoryElems<float>(kSize); |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1628 HandleScope scope(isolate); | 1649 HandleScope scope(isolate); |
1629 // Enable all optional operators. | 1650 // Enable all optional operators. |
1630 CommonOperatorBuilder common(&zone); | 1651 CommonOperatorBuilder common(&zone); |
1631 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(), | 1652 MachineOperatorBuilder machine(&zone, MachineType::PointerRepresentation(), |
1632 MachineOperatorBuilder::kAllOptionalOps); | 1653 MachineOperatorBuilder::kAllOptionalOps); |
1633 Graph graph(&zone); | 1654 Graph graph(&zone); |
1634 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); | 1655 JSGraph jsgraph(isolate, &graph, &common, nullptr, nullptr, &machine); |
1635 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 1656 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
1636 | 1657 |
1637 if (sig->parameter_count() == 1) { | 1658 if (sig->parameter_count() == 1) { |
1638 byte code[] = {WASM_NO_LOCALS, static_cast<byte>(opcode), kExprGetLocal, 0}; | 1659 byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, static_cast<byte>(opcode)}; |
1639 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code, | 1660 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code, |
1640 code + arraysize(code)); | 1661 code + arraysize(code)); |
1641 } else { | 1662 } else { |
1642 CHECK_EQ(2, sig->parameter_count()); | 1663 CHECK_EQ(2, sig->parameter_count()); |
1643 byte code[] = {WASM_NO_LOCALS, static_cast<byte>(opcode), | 1664 byte code[] = {WASM_NO_LOCALS, kExprGetLocal, 0, kExprGetLocal, 1, |
1644 kExprGetLocal, 0, | 1665 static_cast<byte>(opcode)}; |
1645 kExprGetLocal, 1}; | |
1646 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code, | 1666 TestBuildingGraph(&zone, &jsgraph, nullptr, sig, code, |
1647 code + arraysize(code)); | 1667 code + arraysize(code)); |
1648 } | 1668 } |
1649 } | 1669 } |
1650 | 1670 |
1651 | 1671 |
1652 TEST(Build_Wasm_SimpleExprs) { | 1672 TEST(Build_Wasm_SimpleExprs) { |
1653 // Test that the decoder can build a graph for all supported simple expressions. | 1673 // Test that the decoder can build a graph for all supported simple expressions. |
1654 #define GRAPH_BUILD_TEST(name, opcode, sig) \ | 1674 #define GRAPH_BUILD_TEST(name, opcode, sig) \ |
1655 TestBuildGraphForSimpleExpression(kExpr##name); | 1675 TestBuildGraphForSimpleExpression(kExpr##name); |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2067 b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i])); | 2087 b.AddParam(WasmOpcodes::LocalTypeFor(memtypes[i])); |
2068 } | 2088 } |
2069 WasmFunctionCompiler t(b.Build(), &module); | 2089 WasmFunctionCompiler t(b.Build(), &module); |
2070 BUILD(t, WASM_GET_LOCAL(which)); | 2090 BUILD(t, WASM_GET_LOCAL(which)); |
2071 index = t.CompileAndAdd(); | 2091 index = t.CompileAndAdd(); |
2072 | 2092 |
2073 // ========================================================================= | 2093 // ========================================================================= |
2074 // Build the calling function. | 2094 // Build the calling function. |
2075 // ========================================================================= | 2095 // ========================================================================= |
2076 WasmRunner<int32_t> r(&module); | 2096 WasmRunner<int32_t> r(&module); |
| 2097 std::vector<byte> code; |
2077 | 2098 |
2078 std::vector<byte> code; | 2099 // Load the offset for the store. |
2079 ADD_CODE(code, | |
2080 static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)), | |
2081 ZERO_ALIGNMENT, ZERO_OFFSET); | |
2082 ADD_CODE(code, WASM_ZERO); | 2100 ADD_CODE(code, WASM_ZERO); |
2083 ADD_CODE(code, kExprCallFunction, static_cast<byte>(index)); | |
2084 | 2101 |
| 2102 // Load the arguments. |
2085 for (int i = 0; i < num_params; i++) { | 2103 for (int i = 0; i < num_params; i++) { |
2086 int offset = (i + 1) * kElemSize; | 2104 int offset = (i + 1) * kElemSize; |
2087 ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset))); | 2105 ADD_CODE(code, WASM_LOAD_MEM(memtypes[i], WASM_I8(offset))); |
2088 } | 2106 } |
2089 | 2107 |
| 2108 // Call the selector function. |
| 2109 ADD_CODE(code, kExprCallFunction, static_cast<byte>(index)); |
| 2110 |
| 2111 // Store the result in memory. |
| 2112 ADD_CODE(code, |
| 2113 static_cast<byte>(WasmOpcodes::LoadStoreOpcodeOf(result, true)), |
| 2114 ZERO_ALIGNMENT, ZERO_OFFSET); |
| 2115 |
| 2116 // Return the expected value. |
2090 ADD_CODE(code, WASM_I32V_2(kExpected)); | 2117 ADD_CODE(code, WASM_I32V_2(kExpected)); |
2091 size_t end = code.size(); | 2118 |
2092 code.push_back(0); | 2119 r.Build(&code[0], &code[0] + code.size()); |
2093 r.Build(&code[0], &code[end]); | |
2094 | 2120 |
2095 // Run the code. | 2121 // Run the code. |
2096 for (int t = 0; t < 10; t++) { | 2122 for (int t = 0; t < 10; t++) { |
2097 module.RandomizeMemory(); | 2123 module.RandomizeMemory(); |
2098 CHECK_EQ(kExpected, r.Call()); | 2124 CHECK_EQ(kExpected, r.Call()); |
2099 | 2125 |
2100 int size = WasmOpcodes::MemSize(result); | 2126 int size = WasmOpcodes::MemSize(result); |
2101 for (int i = 0; i < size; i++) { | 2127 for (int i = 0; i < size; i++) { |
2102 int base = (which + 1) * kElemSize; | 2128 int base = (which + 1) * kElemSize; |
2103 byte expected = module.raw_mem_at<byte>(base + i); | 2129 byte expected = module.raw_mem_at<byte>(base + i); |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2284 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)), | 2310 WASM_IF_ELSE(WASM_GET_LOCAL(1), WASM_BRV(1, WASM_I8(13)), |
2285 WASM_BRV(1, WASM_I8(14)))))); | 2311 WASM_BRV(1, WASM_I8(14)))))); |
2286 | 2312 |
2287 | 2313 |
2288 CHECK_EQ(11, r.Call(1, 1)); | 2314 CHECK_EQ(11, r.Call(1, 1)); |
2289 CHECK_EQ(12, r.Call(1, 0)); | 2315 CHECK_EQ(12, r.Call(1, 0)); |
2290 CHECK_EQ(13, r.Call(0, 1)); | 2316 CHECK_EQ(13, r.Call(0, 1)); |
2291 CHECK_EQ(14, r.Call(0, 0)); | 2317 CHECK_EQ(14, r.Call(0, 0)); |
2292 } | 2318 } |
2293 | 2319 |
2294 | |
2295 TEST(Run_Wasm_SimpleCallIndirect) { | 2320 TEST(Run_Wasm_SimpleCallIndirect) { |
2296 TestSignatures sigs; | 2321 TestSignatures sigs; |
2297 TestingModule module; | 2322 TestingModule module; |
2298 | 2323 |
2299 WasmFunctionCompiler t1(sigs.i_ii(), &module); | 2324 WasmFunctionCompiler t1(sigs.i_ii(), &module); |
2300 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2325 BUILD(t1, WASM_I32_ADD(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
2301 t1.CompileAndAdd(/*sig_index*/ 1); | 2326 t1.CompileAndAdd(/*sig_index*/ 1); |
2302 | 2327 |
2303 WasmFunctionCompiler t2(sigs.i_ii(), &module); | 2328 WasmFunctionCompiler t2(sigs.i_ii(), &module); |
2304 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); | 2329 BUILD(t2, WASM_I32_SUB(WASM_GET_LOCAL(0), WASM_GET_LOCAL(1))); |
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2706 TestingModule module; | 2731 TestingModule module; |
2707 FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params); | 2732 FunctionSig* sig = sigs.many(&zone, kAstStmt, param, num_params); |
2708 | 2733 |
2709 module.AddSignature(sig); | 2734 module.AddSignature(sig); |
2710 module.AddSignature(sig); | 2735 module.AddSignature(sig); |
2711 module.AddIndirectFunctionTable(nullptr, 0); | 2736 module.AddIndirectFunctionTable(nullptr, 0); |
2712 | 2737 |
2713 WasmFunctionCompiler t(sig, &module); | 2738 WasmFunctionCompiler t(sig, &module); |
2714 | 2739 |
2715 std::vector<byte> code; | 2740 std::vector<byte> code; |
2716 ADD_CODE(code, kExprCallIndirect, 1); | |
2717 ADD_CODE(code, kExprI8Const, 0); | 2741 ADD_CODE(code, kExprI8Const, 0); |
2718 for (byte p = 0; p < num_params; p++) { | 2742 for (byte p = 0; p < num_params; p++) { |
2719 ADD_CODE(code, kExprGetLocal, p); | 2743 ADD_CODE(code, kExprGetLocal, p); |
2720 } | 2744 } |
| 2745 ADD_CODE(code, kExprCallIndirect, 1); |
2721 | 2746 |
2722 t.Build(&code[0], &code[0] + code.size()); | 2747 t.Build(&code[0], &code[0] + code.size()); |
2723 t.Compile(); | 2748 t.Compile(); |
2724 } | 2749 } |
2725 } | 2750 } |
2726 | 2751 |
2727 | 2752 |
2728 TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); } | 2753 TEST(Compile_Wasm_CallIndirect_Many_i32) { CompileCallIndirectMany(kAstI32); } |
2729 | 2754 |
2730 | 2755 |
2731 #if WASM_64 | 2756 #if WASM_64 |
2732 TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); } | 2757 TEST(Compile_Wasm_CallIndirect_Many_i64) { CompileCallIndirectMany(kAstI64); } |
2733 #endif | 2758 #endif |
2734 | 2759 |
2735 | 2760 |
2736 TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); } | 2761 TEST(Compile_Wasm_CallIndirect_Many_f32) { CompileCallIndirectMany(kAstF32); } |
2737 | 2762 |
2738 | 2763 |
2739 TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); } | 2764 TEST(Compile_Wasm_CallIndirect_Many_f64) { CompileCallIndirectMany(kAstF64); } |
OLD | NEW |