blob: 958621970c7f6a68febb1d2493e95c8896cc31b6 [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:
26 WasmLoopAssignmentAnalyzerTest() : TestWithZone(), sigs() {
27 init_env(&env, sigs.v_v());
28 }
29
30 TestSignatures sigs;
31 FunctionEnv env;
32
33 static void init_env(FunctionEnv* env, FunctionSig* sig) {
34 env->module = nullptr;
35 env->sig = sig;
36 env->local_i32_count = 0;
37 env->local_i64_count = 0;
38 env->local_f32_count = 0;
39 env->local_f64_count = 0;
40 env->SumLocals();
41 }
42
43 BitVector* Analyze(const byte* start, const byte* end) {
44 return AnalyzeLoopAssignmentForTesting(zone(), &env, start, end);
45 }
46};
47
48
49TEST_F(WasmLoopAssignmentAnalyzerTest, Empty0) {
50 byte code[] = { 0 };
51 BitVector* assigned = Analyze(code, code);
52 CHECK_NULL(assigned);
53}
54
55
56TEST_F(WasmLoopAssignmentAnalyzerTest, Empty1) {
57 byte code[] = {kExprLoop, 0};
58 for (int i = 0; i < 5; i++) {
59 BitVector* assigned = Analyze(code, code + arraysize(code));
60 for (int j = 0; j < assigned->length(); j++) {
61 CHECK_EQ(false, assigned->Contains(j));
62 }
63 env.AddLocals(kAstI32, 1);
64 }
65}
66
67
68TEST_F(WasmLoopAssignmentAnalyzerTest, One) {
69 env.AddLocals(kAstI32, 5);
70 for (int i = 0; i < 5; i++) {
71 byte code[] = {WASM_LOOP(1, WASM_SET_ZERO(i))};
72 BitVector* assigned = Analyze(code, code + arraysize(code));
73 for (int j = 0; j < assigned->length(); j++) {
74 CHECK_EQ(j == i, assigned->Contains(j));
75 }
76 }
77}
78
79
80TEST_F(WasmLoopAssignmentAnalyzerTest, OneBeyond) {
81 env.AddLocals(kAstI32, 5);
82 for (int i = 0; i < 5; i++) {
83 byte code[] = {WASM_LOOP(1, WASM_SET_ZERO(i)), WASM_SET_ZERO(1)};
84 BitVector* assigned = Analyze(code, code + arraysize(code));
85 for (int j = 0; j < assigned->length(); j++) {
86 CHECK_EQ(j == i, assigned->Contains(j));
87 }
88 }
89}
90
91
92TEST_F(WasmLoopAssignmentAnalyzerTest, Two) {
93 env.AddLocals(kAstI32, 5);
94 for (int i = 0; i < 5; i++) {
95 for (int j = 0; j < 5; j++) {
96 byte code[] = {WASM_LOOP(2, WASM_SET_ZERO(i), WASM_SET_ZERO(j))};
97 BitVector* assigned = Analyze(code, code + arraysize(code));
98 for (int k = 0; k < assigned->length(); k++) {
99 bool expected = k == i || k == j;
100 CHECK_EQ(expected, assigned->Contains(k));
101 }
102 }
103 }
104}
105
106
107TEST_F(WasmLoopAssignmentAnalyzerTest, NestedIf) {
108 env.AddLocals(kAstI32, 5);
109 for (int i = 0; i < 5; i++) {
110 byte code[] = {WASM_LOOP(
111 1, WASM_IF_ELSE(WASM_SET_ZERO(0), WASM_SET_ZERO(i), WASM_SET_ZERO(1)))};
112 BitVector* assigned = Analyze(code, code + arraysize(code));
113 for (int j = 0; j < assigned->length(); j++) {
114 bool expected = i == j || j == 0 || j == 1;
115 CHECK_EQ(expected, assigned->Contains(j));
116 }
117 }
118}
119
120
121static byte LEBByte(uint32_t val, byte which) {
122 byte b = (val >> (which * 7)) & 0x7F;
123 if (val >> ((which + 1) * 7)) b |= 0x80;
124 return b;
125}
126
127
128TEST_F(WasmLoopAssignmentAnalyzerTest, BigLocal) {
129 env.AddLocals(kAstI32, 65000);
130 for (int i = 13; i < 65000; i = static_cast<int>(i * 1.5)) {
131 byte code[] = {kExprLoop,
132 1,
133 kExprSetLocal,
134 LEBByte(i, 0),
135 LEBByte(i, 1),
136 LEBByte(i, 2),
137 11,
138 12,
139 13};
140
141 BitVector* assigned = Analyze(code, code + arraysize(code));
142 for (int j = 0; j < assigned->length(); j++) {
143 bool expected = i == j;
144 CHECK_EQ(expected, assigned->Contains(j));
145 }
146 }
147}
148
149
150TEST_F(WasmLoopAssignmentAnalyzerTest, Break) {
151 env.AddLocals(kAstI32, 3);
152 byte code[] = {
153 WASM_LOOP(1, WASM_IF(WASM_GET_LOCAL(0), WASM_BRV(1, WASM_SET_ZERO(1)))),
154 WASM_SET_ZERO(0)};
155
156 BitVector* assigned = Analyze(code, code + arraysize(code));
157 for (int j = 0; j < assigned->length(); j++) {
158 bool expected = j == 1;
159 CHECK_EQ(expected, assigned->Contains(j));
160 }
161}
162
163
164TEST_F(WasmLoopAssignmentAnalyzerTest, Loop1) {
165 env.AddLocals(kAstI32, 5);
166 byte code[] = {
167 WASM_LOOP(1, WASM_IF(WASM_GET_LOCAL(0),
168 WASM_BRV(0, WASM_SET_LOCAL(
169 3, WASM_I32_SUB(WASM_GET_LOCAL(0),
170 WASM_I8(1)))))),
171 WASM_GET_LOCAL(0)};
172
173 BitVector* assigned = Analyze(code, code + arraysize(code));
174 for (int j = 0; j < assigned->length(); j++) {
175 bool expected = j == 3;
176 CHECK_EQ(expected, assigned->Contains(j));
177 }
178}
179
180
181TEST_F(WasmLoopAssignmentAnalyzerTest, Loop2) {
182 env.AddLocals(kAstI32, 3);
183 const byte kIter = 0;
184 env.AddLocals(kAstF32, 3);
185 const byte kSum = 3;
186
187 byte code[] = {WASM_BLOCK(
188 3,
189 WASM_WHILE(
190 WASM_GET_LOCAL(kIter),
191 WASM_BLOCK(2, WASM_SET_LOCAL(
192 kSum, WASM_F32_ADD(
193 WASM_GET_LOCAL(kSum),
194 WASM_LOAD_MEM(MachineType::Float32(),
195 WASM_GET_LOCAL(kIter)))),
196 WASM_SET_LOCAL(kIter, WASM_I32_SUB(WASM_GET_LOCAL(kIter),
197 WASM_I8(4))))),
198 WASM_STORE_MEM(MachineType::Float32(), WASM_ZERO, WASM_GET_LOCAL(kSum)),
199 WASM_GET_LOCAL(kIter))};
200
201 BitVector* assigned = Analyze(code + 2, code + arraysize(code));
202 for (int j = 0; j < assigned->length(); j++) {
203 bool expected = j == kIter || j == kSum;
204 CHECK_EQ(expected, assigned->Contains(j));
205 }
206}
207
208
209} // namespace wasm
210} // namespace internal
211} // namespace v8