Line data Source code
1 : // 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/bit-vector.h"
8 : #include "src/objects-inl.h"
9 : #include "src/objects.h"
10 : #include "src/v8.h"
11 : #include "src/wasm/function-body-decoder.h"
12 : #include "src/wasm/wasm-module.h"
13 :
14 : #include "test/common/wasm/test-signatures.h"
15 : #include "test/common/wasm/wasm-macro-gen.h"
16 :
17 : namespace v8 {
18 : namespace internal {
19 : namespace wasm {
20 :
21 : #define WASM_SET_ZERO(i) WASM_SET_LOCAL(i, WASM_ZERO)
22 :
23 13 : class WasmLoopAssignmentAnalyzerTest : public TestWithZone {
24 : public:
25 13 : WasmLoopAssignmentAnalyzerTest() : num_locals(0) {}
26 : TestSignatures sigs;
27 : uint32_t num_locals;
28 :
29 : BitVector* Analyze(const byte* start, const byte* end) {
30 78 : return AnalyzeLoopAssignmentForTesting(zone(), num_locals, start, end);
31 : }
32 : };
33 :
34 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, Empty0) {
35 1 : byte code[] = { 0 };
36 : BitVector* assigned = Analyze(code, code);
37 1 : CHECK_NULL(assigned);
38 1 : }
39 :
40 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, Empty1) {
41 1 : byte code[] = {kExprLoop, kLocalVoid, 0};
42 6 : for (int i = 0; i < 5; i++) {
43 15 : BitVector* assigned = Analyze(code, code + arraysize(code));
44 30 : for (int j = 0; j < assigned->length(); j++) {
45 10 : CHECK_EQ(false, assigned->Contains(j));
46 : }
47 5 : num_locals++;
48 : }
49 1 : }
50 :
51 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, One) {
52 1 : num_locals = 5;
53 6 : for (int i = 0; i < 5; i++) {
54 5 : byte code[] = {WASM_LOOP(WASM_SET_ZERO(i))};
55 30 : BitVector* assigned = Analyze(code, code + arraysize(code));
56 60 : for (int j = 0; j < assigned->length(); j++) {
57 25 : CHECK_EQ(j == i, assigned->Contains(j));
58 : }
59 : }
60 1 : }
61 :
62 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, TeeOne) {
63 1 : num_locals = 5;
64 6 : for (int i = 0; i < 5; i++) {
65 5 : byte code[] = {WASM_LOOP(WASM_TEE_LOCAL(i, WASM_ZERO))};
66 30 : BitVector* assigned = Analyze(code, code + arraysize(code));
67 60 : for (int j = 0; j < assigned->length(); j++) {
68 25 : CHECK_EQ(j == i, assigned->Contains(j));
69 : }
70 : }
71 1 : }
72 :
73 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, OneBeyond) {
74 1 : num_locals = 5;
75 6 : for (int i = 0; i < 5; i++) {
76 5 : byte code[] = {WASM_LOOP(WASM_SET_ZERO(i)), WASM_SET_ZERO(1)};
77 30 : BitVector* assigned = Analyze(code, code + arraysize(code));
78 60 : for (int j = 0; j < assigned->length(); j++) {
79 25 : CHECK_EQ(j == i, assigned->Contains(j));
80 : }
81 : }
82 1 : }
83 :
84 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, Two) {
85 1 : num_locals = 5;
86 6 : for (int i = 0; i < 5; i++) {
87 25 : for (int j = 0; j < 5; j++) {
88 25 : byte code[] = {WASM_LOOP(WASM_SET_ZERO(i), WASM_SET_ZERO(j))};
89 150 : BitVector* assigned = Analyze(code, code + arraysize(code));
90 300 : for (int k = 0; k < assigned->length(); k++) {
91 125 : bool expected = k == i || k == j;
92 125 : CHECK_EQ(expected, assigned->Contains(k));
93 : }
94 : }
95 : }
96 1 : }
97 :
98 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, NestedIf) {
99 1 : num_locals = 5;
100 6 : for (int i = 0; i < 5; i++) {
101 : byte code[] = {WASM_LOOP(
102 5 : WASM_IF_ELSE(WASM_SET_ZERO(0), WASM_SET_ZERO(i), WASM_SET_ZERO(1)))};
103 30 : BitVector* assigned = Analyze(code, code + arraysize(code));
104 60 : for (int j = 0; j < assigned->length(); j++) {
105 25 : bool expected = i == j || j == 0 || j == 1;
106 25 : CHECK_EQ(expected, assigned->Contains(j));
107 : }
108 : }
109 1 : }
110 :
111 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, BigLocal) {
112 1 : num_locals = 65000;
113 23 : for (int i = 13; i < 65000; i = static_cast<int>(i * 1.5)) {
114 22 : byte code[] = {WASM_LOOP(WASM_I32V_1(11), kExprSetLocal, U32V_3(i))};
115 :
116 1430022 : BitVector* assigned = Analyze(code, code + arraysize(code));
117 2860044 : for (int j = 0; j < assigned->length(); j++) {
118 1430000 : bool expected = i == j;
119 1430000 : CHECK_EQ(expected, assigned->Contains(j));
120 : }
121 : }
122 1 : }
123 :
124 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, Break) {
125 1 : num_locals = 3;
126 : byte code[] = {
127 : WASM_LOOP(WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_SET_ZERO(1)))),
128 1 : WASM_SET_ZERO(0)};
129 :
130 4 : BitVector* assigned = Analyze(code, code + arraysize(code));
131 8 : for (int j = 0; j < assigned->length(); j++) {
132 3 : bool expected = j == 1;
133 3 : CHECK_EQ(expected, assigned->Contains(j));
134 : }
135 1 : }
136 :
137 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, Loop1) {
138 1 : num_locals = 5;
139 : byte code[] = {
140 : WASM_LOOP(WASM_IF(
141 : WASM_GET_LOCAL(0),
142 : WASM_BRV(0, WASM_SET_LOCAL(3, WASM_I32_SUB(WASM_GET_LOCAL(0),
143 : WASM_I32V_1(1)))))),
144 1 : WASM_GET_LOCAL(0)};
145 :
146 6 : BitVector* assigned = Analyze(code, code + arraysize(code));
147 12 : for (int j = 0; j < assigned->length(); j++) {
148 5 : bool expected = j == 3;
149 5 : CHECK_EQ(expected, assigned->Contains(j));
150 : }
151 1 : }
152 :
153 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, Loop2) {
154 1 : num_locals = 6;
155 : const byte kIter = 0;
156 : const byte kSum = 3;
157 :
158 2 : byte code[] = {WASM_BLOCK(
159 : WASM_WHILE(
160 : WASM_GET_LOCAL(kIter),
161 : WASM_BLOCK(
162 : WASM_SET_LOCAL(
163 : kSum, WASM_F32_ADD(WASM_GET_LOCAL(kSum),
164 : WASM_LOAD_MEM(MachineType::Float32(),
165 : WASM_GET_LOCAL(kIter)))),
166 : WASM_SET_LOCAL(
167 : kIter, WASM_I32_SUB(WASM_GET_LOCAL(kIter), WASM_I32V_1(4))))),
168 : WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, WASM_GET_LOCAL(kSum)),
169 3 : WASM_GET_LOCAL(kIter))};
170 :
171 7 : BitVector* assigned = Analyze(code + 2, code + arraysize(code));
172 14 : for (int j = 0; j < assigned->length(); j++) {
173 6 : bool expected = j == kIter || j == kSum;
174 6 : CHECK_EQ(expected, assigned->Contains(j));
175 : }
176 1 : }
177 :
178 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, Malformed) {
179 : byte code[] = {kExprLoop, kLocalVoid, kExprF32Neg, kExprBrTable, 0x0E, 'h',
180 : 'e', 'l', 'l', 'o', ',', ' ',
181 1 : 'w', 'o', 'r', 'l', 'd', '!'};
182 : BitVector* assigned = Analyze(code, code + arraysize(code));
183 1 : CHECK_NULL(assigned);
184 1 : }
185 :
186 15190 : TEST_F(WasmLoopAssignmentAnalyzerTest, regress_642867) {
187 : static const byte code[] = {
188 : WASM_LOOP(WASM_ZERO, kExprSetLocal, 0xFA, 0xFF, 0xFF, 0xFF,
189 : 0x0F)}; // local index LEB128 0xFFFFFFFA
190 : // Just make sure that the analysis does not crash.
191 : Analyze(code, code + arraysize(code));
192 1 : }
193 :
194 : #undef WASM_SET_ZERO
195 :
196 : } // namespace wasm
197 : } // namespace internal
198 9111 : } // namespace v8
|