• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/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 
20 namespace v8 {
21 namespace internal {
22 namespace wasm {
23 
24 class WasmLoopAssignmentAnalyzerTest : public TestWithZone {
25  public:
WasmLoopAssignmentAnalyzerTest()26   WasmLoopAssignmentAnalyzerTest() : num_locals(0) {}
27   TestSignatures sigs;
28   uint32_t num_locals;
29 
Analyze(const byte * start,const byte * end)30   BitVector* Analyze(const byte* start, const byte* end) {
31     return AnalyzeLoopAssignmentForTesting(zone(), num_locals, start, end);
32   }
33 };
34 
TEST_F(WasmLoopAssignmentAnalyzerTest,Empty0)35 TEST_F(WasmLoopAssignmentAnalyzerTest, Empty0) {
36   byte code[] = { 0 };
37   BitVector* assigned = Analyze(code, code);
38   CHECK_NULL(assigned);
39 }
40 
TEST_F(WasmLoopAssignmentAnalyzerTest,Empty1)41 TEST_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     }
48     num_locals++;
49   }
50 }
51 
TEST_F(WasmLoopAssignmentAnalyzerTest,One)52 TEST_F(WasmLoopAssignmentAnalyzerTest, One) {
53   num_locals = 5;
54   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 
TEST_F(WasmLoopAssignmentAnalyzerTest,OneBeyond)63 TEST_F(WasmLoopAssignmentAnalyzerTest, OneBeyond) {
64   num_locals = 5;
65   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 
TEST_F(WasmLoopAssignmentAnalyzerTest,Two)74 TEST_F(WasmLoopAssignmentAnalyzerTest, Two) {
75   num_locals = 5;
76   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 
TEST_F(WasmLoopAssignmentAnalyzerTest,NestedIf)88 TEST_F(WasmLoopAssignmentAnalyzerTest, NestedIf) {
89   num_locals = 5;
90   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 
LEBByte(uint32_t val,byte which)101 static 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 
TEST_F(WasmLoopAssignmentAnalyzerTest,BigLocal)107 TEST_F(WasmLoopAssignmentAnalyzerTest, BigLocal) {
108   num_locals = 65000;
109   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 
TEST_F(WasmLoopAssignmentAnalyzerTest,Break)128 TEST_F(WasmLoopAssignmentAnalyzerTest, Break) {
129   num_locals = 3;
130   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 
TEST_F(WasmLoopAssignmentAnalyzerTest,Loop1)141 TEST_F(WasmLoopAssignmentAnalyzerTest, Loop1) {
142   num_locals = 5;
143   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 
TEST_F(WasmLoopAssignmentAnalyzerTest,Loop2)157 TEST_F(WasmLoopAssignmentAnalyzerTest, Loop2) {
158   num_locals = 6;
159   const byte kIter = 0;
160   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 
176   BitVector* assigned = Analyze(code + 1, code + arraysize(code));
177   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 
TEST_F(WasmLoopAssignmentAnalyzerTest,Malformed)183 TEST_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 
191 }  // namespace wasm
192 }  // namespace internal
193 }  // namespace v8
194