blob: c134de890d22ff73bc42944e45c75d1b5613155f [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001// Copyright 2016 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "test/unittests/test-utils.h"
6
7#include "src/v8.h"
8
9#include "test/cctest/wasm/test-signatures.h"
10
11#include "src/bit-vector.h"
12#include "src/objects.h"
13
14#include "src/wasm/ast-decoder.h"
15#include "src/wasm/wasm-macro-gen.h"
16#include "src/wasm/wasm-module.h"
17
18#define WASM_SET_ZERO(i) WASM_SET_LOCAL(i, WASM_ZERO)
19
20namespace v8 {
21namespace internal {
22namespace wasm {
23
24class WasmLoopAssignmentAnalyzerTest : public TestWithZone {
25 public:
Ben Murdochda12d292016-06-02 14:46:10 +010026 WasmLoopAssignmentAnalyzerTest() : num_locals(0) {}
Ben Murdoch097c5b22016-05-18 11:27:45 +010027 TestSignatures sigs;
Ben Murdochda12d292016-06-02 14:46:10 +010028 uint32_t num_locals;
Ben Murdoch097c5b22016-05-18 11:27:45 +010029
30 BitVector* Analyze(const byte* start, const byte* end) {
Ben Murdochda12d292016-06-02 14:46:10 +010031 return AnalyzeLoopAssignmentForTesting(zone(), num_locals, start, end);
Ben Murdoch097c5b22016-05-18 11:27:45 +010032 }
33};
34
Ben Murdoch097c5b22016-05-18 11:27:45 +010035TEST_F(WasmLoopAssignmentAnalyzerTest, Empty0) {
36 byte code[] = { 0 };
37 BitVector* assigned = Analyze(code, code);
38 CHECK_NULL(assigned);
39}
40
Ben Murdoch097c5b22016-05-18 11:27:45 +010041TEST_F(WasmLoopAssignmentAnalyzerTest, Empty1) {
42 byte code[] = {kExprLoop, 0};
43 for (int i = 0; i < 5; i++) {
44 BitVector* assigned = Analyze(code, code + arraysize(code));
45 for (int j = 0; j < assigned->length(); j++) {
46 CHECK_EQ(false, assigned->Contains(j));
47 }
Ben Murdochda12d292016-06-02 14:46:10 +010048 num_locals++;
Ben Murdoch097c5b22016-05-18 11:27:45 +010049 }
50}
51
Ben Murdoch097c5b22016-05-18 11:27:45 +010052TEST_F(WasmLoopAssignmentAnalyzerTest, One) {
Ben Murdochda12d292016-06-02 14:46:10 +010053 num_locals = 5;
Ben Murdoch097c5b22016-05-18 11:27:45 +010054 for (int i = 0; i < 5; i++) {
55 byte code[] = {WASM_LOOP(1, WASM_SET_ZERO(i))};
56 BitVector* assigned = Analyze(code, code + arraysize(code));
57 for (int j = 0; j < assigned->length(); j++) {
58 CHECK_EQ(j == i, assigned->Contains(j));
59 }
60 }
61}
62
Ben Murdoch097c5b22016-05-18 11:27:45 +010063TEST_F(WasmLoopAssignmentAnalyzerTest, OneBeyond) {
Ben Murdochda12d292016-06-02 14:46:10 +010064 num_locals = 5;
Ben Murdoch097c5b22016-05-18 11:27:45 +010065 for (int i = 0; i < 5; i++) {
66 byte code[] = {WASM_LOOP(1, WASM_SET_ZERO(i)), WASM_SET_ZERO(1)};
67 BitVector* assigned = Analyze(code, code + arraysize(code));
68 for (int j = 0; j < assigned->length(); j++) {
69 CHECK_EQ(j == i, assigned->Contains(j));
70 }
71 }
72}
73
Ben Murdoch097c5b22016-05-18 11:27:45 +010074TEST_F(WasmLoopAssignmentAnalyzerTest, Two) {
Ben Murdochda12d292016-06-02 14:46:10 +010075 num_locals = 5;
Ben Murdoch097c5b22016-05-18 11:27:45 +010076 for (int i = 0; i < 5; i++) {
77 for (int j = 0; j < 5; j++) {
78 byte code[] = {WASM_LOOP(2, WASM_SET_ZERO(i), WASM_SET_ZERO(j))};
79 BitVector* assigned = Analyze(code, code + arraysize(code));
80 for (int k = 0; k < assigned->length(); k++) {
81 bool expected = k == i || k == j;
82 CHECK_EQ(expected, assigned->Contains(k));
83 }
84 }
85 }
86}
87
Ben Murdoch097c5b22016-05-18 11:27:45 +010088TEST_F(WasmLoopAssignmentAnalyzerTest, NestedIf) {
Ben Murdochda12d292016-06-02 14:46:10 +010089 num_locals = 5;
Ben Murdoch097c5b22016-05-18 11:27:45 +010090 for (int i = 0; i < 5; i++) {
91 byte code[] = {WASM_LOOP(
92 1, WASM_IF_ELSE(WASM_SET_ZERO(0), WASM_SET_ZERO(i), WASM_SET_ZERO(1)))};
93 BitVector* assigned = Analyze(code, code + arraysize(code));
94 for (int j = 0; j < assigned->length(); j++) {
95 bool expected = i == j || j == 0 || j == 1;
96 CHECK_EQ(expected, assigned->Contains(j));
97 }
98 }
99}
100
Ben Murdoch097c5b22016-05-18 11:27:45 +0100101static byte LEBByte(uint32_t val, byte which) {
102 byte b = (val >> (which * 7)) & 0x7F;
103 if (val >> ((which + 1) * 7)) b |= 0x80;
104 return b;
105}
106
Ben Murdoch097c5b22016-05-18 11:27:45 +0100107TEST_F(WasmLoopAssignmentAnalyzerTest, BigLocal) {
Ben Murdochda12d292016-06-02 14:46:10 +0100108 num_locals = 65000;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100109 for (int i = 13; i < 65000; i = static_cast<int>(i * 1.5)) {
110 byte code[] = {kExprLoop,
111 1,
112 kExprSetLocal,
113 LEBByte(i, 0),
114 LEBByte(i, 1),
115 LEBByte(i, 2),
116 11,
117 12,
118 13};
119
120 BitVector* assigned = Analyze(code, code + arraysize(code));
121 for (int j = 0; j < assigned->length(); j++) {
122 bool expected = i == j;
123 CHECK_EQ(expected, assigned->Contains(j));
124 }
125 }
126}
127
Ben Murdoch097c5b22016-05-18 11:27:45 +0100128TEST_F(WasmLoopAssignmentAnalyzerTest, Break) {
Ben Murdochda12d292016-06-02 14:46:10 +0100129 num_locals = 3;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100130 byte code[] = {
131 WASM_LOOP(1, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_SET_ZERO(1)))),
132 WASM_SET_ZERO(0)};
133
134 BitVector* assigned = Analyze(code, code + arraysize(code));
135 for (int j = 0; j < assigned->length(); j++) {
136 bool expected = j == 1;
137 CHECK_EQ(expected, assigned->Contains(j));
138 }
139}
140
Ben Murdoch097c5b22016-05-18 11:27:45 +0100141TEST_F(WasmLoopAssignmentAnalyzerTest, Loop1) {
Ben Murdochda12d292016-06-02 14:46:10 +0100142 num_locals = 5;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100143 byte code[] = {
144 WASM_LOOP(1, WASM_IF(WASM_GET_LOCAL(0),
145 WASM_BRV(0, WASM_SET_LOCAL(
146 3, WASM_I32_SUB(WASM_GET_LOCAL(0),
147 WASM_I8(1)))))),
148 WASM_GET_LOCAL(0)};
149
150 BitVector* assigned = Analyze(code, code + arraysize(code));
151 for (int j = 0; j < assigned->length(); j++) {
152 bool expected = j == 3;
153 CHECK_EQ(expected, assigned->Contains(j));
154 }
155}
156
Ben Murdoch097c5b22016-05-18 11:27:45 +0100157TEST_F(WasmLoopAssignmentAnalyzerTest, Loop2) {
Ben Murdochda12d292016-06-02 14:46:10 +0100158 num_locals = 6;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100159 const byte kIter = 0;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100160 const byte kSum = 3;
161
162 byte code[] = {WASM_BLOCK(
163 3,
164 WASM_WHILE(
165 WASM_GET_LOCAL(kIter),
166 WASM_BLOCK(2, WASM_SET_LOCAL(
167 kSum, WASM_F32_ADD(
168 WASM_GET_LOCAL(kSum),
169 WASM_LOAD_MEM(MachineType::Float32(),
170 WASM_GET_LOCAL(kIter)))),
171 WASM_SET_LOCAL(kIter, WASM_I32_SUB(WASM_GET_LOCAL(kIter),
172 WASM_I8(4))))),
173 WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, WASM_GET_LOCAL(kSum)),
174 WASM_GET_LOCAL(kIter))};
175
Ben Murdochc5610432016-08-08 18:44:38 +0100176 BitVector* assigned = Analyze(code + 1, code + arraysize(code));
Ben Murdoch097c5b22016-05-18 11:27:45 +0100177 for (int j = 0; j < assigned->length(); j++) {
178 bool expected = j == kIter || j == kSum;
179 CHECK_EQ(expected, assigned->Contains(j));
180 }
181}
182
Ben Murdoch61f157c2016-09-16 13:49:30 +0100183TEST_F(WasmLoopAssignmentAnalyzerTest, Malformed) {
184 byte code[] = {kExprLoop, kExprF32Neg, kExprBrTable, 0x0e, 'h', 'e',
185 'l', 'l', 'o', ',', ' ', 'w',
186 'o', 'r', 'l', 'd', '!'};
187 BitVector* assigned = Analyze(code, code + arraysize(code));
188 CHECK_NULL(assigned);
189}
190
Ben Murdoch097c5b22016-05-18 11:27:45 +0100191} // namespace wasm
192} // namespace internal
193} // namespace v8