Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / v8 / test / cctest / compiler / test-loop-assignment-analysis.cc
1 // Copyright 2014 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 "src/compiler/ast-loop-assignment-analyzer.h"
6 #include "src/parser.h"
7 #include "src/rewriter.h"
8 #include "src/scopes.h"
9 #include "test/cctest/cctest.h"
10
11 using namespace v8::internal;
12 using namespace v8::internal::compiler;
13
14 namespace {
15 const int kBufferSize = 1024;
16
17 struct TestHelper : public HandleAndZoneScope {
18   Handle<JSFunction> function;
19   LoopAssignmentAnalysis* result;
20
21   explicit TestHelper(const char* body)
22       : function(Handle<JSFunction>::null()), result(NULL) {
23     ScopedVector<char> program(kBufferSize);
24     SNPrintF(program, "function f(a,b,c) { %s; } f;", body);
25     v8::Local<v8::Value> v = CompileRun(program.start());
26     Handle<Object> obj = v8::Utils::OpenHandle(*v);
27     function = Handle<JSFunction>::cast(obj);
28   }
29
30   void CheckLoopAssignedCount(int expected, const char* var_name) {
31     // TODO(titzer): don't scope analyze every single time.
32     CompilationInfo info(function, main_zone());
33
34     CHECK(Parser::Parse(&info));
35     CHECK(Rewriter::Rewrite(&info));
36     CHECK(Scope::Analyze(&info));
37
38     Scope* scope = info.function()->scope();
39     AstValueFactory* factory = info.ast_value_factory();
40     CHECK_NE(NULL, scope);
41
42     if (result == NULL) {
43       AstLoopAssignmentAnalyzer analyzer(main_zone(), &info);
44       result = analyzer.Analyze();
45       CHECK_NE(NULL, result);
46     }
47
48     const i::AstRawString* name = factory->GetOneByteString(var_name);
49
50     i::Variable* var = scope->Lookup(name);
51     CHECK_NE(NULL, var);
52
53     if (var->location() == Variable::UNALLOCATED) {
54       CHECK_EQ(0, expected);
55     } else {
56       CHECK(var->IsStackAllocated());
57       CHECK_EQ(expected, result->GetAssignmentCountForTesting(scope, var));
58     }
59   }
60 };
61 }
62
63
64 TEST(SimpleLoop1) {
65   TestHelper f("var x = 0; while (x) ;");
66
67   f.CheckLoopAssignedCount(0, "x");
68 }
69
70
71 TEST(SimpleLoop2) {
72   const char* loops[] = {
73       "while (x) { var x = 0; }",            "for(;;) { var x = 0; }",
74       "for(;x;) { var x = 0; }",             "for(;x;x) { var x = 0; }",
75       "for(var i = x; x; x) { var x = 0; }", "for(y in 0) { var x = 0; }",
76       "for(y of 0) { var x = 0; }",          "for(var x = 0; x; x++) { }",
77       "for(var x = 0; x++;) { }",            "var x; for(;x;x++) { }",
78       "var x; do { x = 1; } while (0);",     "do { var x = 1; } while (0);"};
79
80   for (size_t i = 0; i < arraysize(loops); i++) {
81     TestHelper f(loops[i]);
82     f.CheckLoopAssignedCount(1, "x");
83   }
84 }
85
86
87 TEST(ForInOf1) {
88   const char* loops[] = {
89       "for(x in 0) { }", "for(x of 0) { }",
90   };
91
92   for (size_t i = 0; i < arraysize(loops); i++) {
93     TestHelper f(loops[i]);
94     f.CheckLoopAssignedCount(0, "x");
95   }
96 }
97
98
99 TEST(Param1) {
100   TestHelper f("while (1) a = 0;");
101
102   f.CheckLoopAssignedCount(1, "a");
103   f.CheckLoopAssignedCount(0, "b");
104   f.CheckLoopAssignedCount(0, "c");
105 }
106
107
108 TEST(Param2) {
109   TestHelper f("for (;;) b = 0;");
110
111   f.CheckLoopAssignedCount(0, "a");
112   f.CheckLoopAssignedCount(1, "b");
113   f.CheckLoopAssignedCount(0, "c");
114 }
115
116
117 TEST(Param2b) {
118   TestHelper f("a; b; c; for (;;) b = 0;");
119
120   f.CheckLoopAssignedCount(0, "a");
121   f.CheckLoopAssignedCount(1, "b");
122   f.CheckLoopAssignedCount(0, "c");
123 }
124
125
126 TEST(Param3) {
127   TestHelper f("for(x in 0) c = 0;");
128
129   f.CheckLoopAssignedCount(0, "a");
130   f.CheckLoopAssignedCount(0, "b");
131   f.CheckLoopAssignedCount(1, "c");
132 }
133
134
135 TEST(Param3b) {
136   TestHelper f("a; b; c; for(x in 0) c = 0;");
137
138   f.CheckLoopAssignedCount(0, "a");
139   f.CheckLoopAssignedCount(0, "b");
140   f.CheckLoopAssignedCount(1, "c");
141 }
142
143
144 TEST(NestedLoop1) {
145   TestHelper f("while (x) { while (x) { var x = 0; } }");
146
147   f.CheckLoopAssignedCount(2, "x");
148 }
149
150
151 TEST(NestedLoop2) {
152   TestHelper f("while (0) { while (0) { var x = 0; } }");
153
154   f.CheckLoopAssignedCount(2, "x");
155 }
156
157
158 TEST(NestedLoop3) {
159   TestHelper f("while (0) { var y = 1; while (0) { var x = 0; } }");
160
161   f.CheckLoopAssignedCount(2, "x");
162   f.CheckLoopAssignedCount(1, "y");
163 }
164
165
166 TEST(NestedInc1) {
167   const char* loops[] = {
168       "while (1) a(b++);",
169       "while (1) a(0, b++);",
170       "while (1) a(0, 0, b++);",
171       "while (1) a(b++, 1, 1);",
172       "while (1) a(++b);",
173       "while (1) a + (b++);",
174       "while (1) (b++) + a;",
175       "while (1) a + c(b++);",
176       "while (1) throw b++;",
177       "while (1) switch (b++) {} ;",
178       "while (1) switch (a) {case (b++): 0; } ;",
179       "while (1) switch (a) {case b: b++; } ;",
180       "while (1) a == (b++);",
181       "while (1) a === (b++);",
182       "while (1) +(b++);",
183       "while (1) ~(b++);",
184       "while (1) new a(b++);",
185       "while (1) (b++).f;",
186       "while (1) a[b++];",
187       "while (1) (b++)();",
188       "while (1) [b++];",
189       "while (1) [0,b++];",
190       "while (1) var y = [11,b++,12];",
191       "while (1) var y = {f:11,g:(b++),h:12};",
192       "while (1) try {b++;} finally {};",
193       "while (1) try {} finally {b++};",
194       "while (1) try {b++;} catch (e) {};",
195       "while (1) try {} catch (e) {b++};",
196       "while (1) return b++;",
197       "while (1) (b++) ? b : b;",
198       "while (1) b ? (b++) : b;",
199       "while (1) b ? b : (b++);",
200   };
201
202   for (size_t i = 0; i < arraysize(loops); i++) {
203     TestHelper f(loops[i]);
204     f.CheckLoopAssignedCount(1, "b");
205   }
206 }
207
208
209 TEST(NestedAssign1) {
210   const char* loops[] = {
211       "while (1) a(b=1);",
212       "while (1) a(0, b=1);",
213       "while (1) a(0, 0, b=1);",
214       "while (1) a(b=1, 1, 1);",
215       "while (1) a + (b=1);",
216       "while (1) (b=1) + a;",
217       "while (1) a + c(b=1);",
218       "while (1) throw b=1;",
219       "while (1) switch (b=1) {} ;",
220       "while (1) switch (a) {case b=1: 0; } ;",
221       "while (1) switch (a) {case b: b=1; } ;",
222       "while (1) a == (b=1);",
223       "while (1) a === (b=1);",
224       "while (1) +(b=1);",
225       "while (1) ~(b=1);",
226       "while (1) new a(b=1);",
227       "while (1) (b=1).f;",
228       "while (1) a[b=1];",
229       "while (1) (b=1)();",
230       "while (1) [b=1];",
231       "while (1) [0,b=1];",
232       "while (1) var z = [11,b=1,12];",
233       "while (1) var y = {f:11,g:(b=1),h:12};",
234       "while (1) try {b=1;} finally {};",
235       "while (1) try {} finally {b=1};",
236       "while (1) try {b=1;} catch (e) {};",
237       "while (1) try {} catch (e) {b=1};",
238       "while (1) return b=1;",
239       "while (1) (b=1) ? b : b;",
240       "while (1) b ? (b=1) : b;",
241       "while (1) b ? b : (b=1);",
242   };
243
244   for (size_t i = 0; i < arraysize(loops); i++) {
245     TestHelper f(loops[i]);
246     f.CheckLoopAssignedCount(1, "b");
247   }
248 }
249
250
251 TEST(NestedLoops3) {
252   TestHelper f("var x, y, z, w; while (x++) while (y++) while (z++) ; w;");
253
254   f.CheckLoopAssignedCount(1, "x");
255   f.CheckLoopAssignedCount(2, "y");
256   f.CheckLoopAssignedCount(3, "z");
257   f.CheckLoopAssignedCount(0, "w");
258 }
259
260
261 TEST(NestedLoops3b) {
262   TestHelper f(
263       "var x, y, z, w;"
264       "while (1) { x=1; while (1) { y=1; while (1) z=1; } }"
265       "w;");
266
267   f.CheckLoopAssignedCount(1, "x");
268   f.CheckLoopAssignedCount(2, "y");
269   f.CheckLoopAssignedCount(3, "z");
270   f.CheckLoopAssignedCount(0, "w");
271 }
272
273
274 TEST(NestedLoops3c) {
275   TestHelper f(
276       "var x, y, z, w;"
277       "while (1) {"
278       "  x++;"
279       "  while (1) {"
280       "    y++;"
281       "    while (1) z++;"
282       "  }"
283       "  while (1) {"
284       "    y++;"
285       "    while (1) z++;"
286       "  }"
287       "}"
288       "w;");
289
290   f.CheckLoopAssignedCount(1, "x");
291   f.CheckLoopAssignedCount(3, "y");
292   f.CheckLoopAssignedCount(5, "z");
293   f.CheckLoopAssignedCount(0, "w");
294 }