426f411fff8697a42ebae9e3169b80269180202c
[platform/upstream/v8.git] / test / cctest / test-typing-reset.cc
1 // Copyright 2015 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 // TODO(mythria): Remove this define after this flag is turned on globally
6 #define V8_IMMINENT_DEPRECATION_WARNINGS
7
8 #include <stdlib.h>
9
10 #include "src/v8.h"
11
12 #include "src/ast.h"
13 #include "src/ast-expression-visitor.h"
14 #include "src/parser.h"
15 #include "src/rewriter.h"
16 #include "src/scopes.h"
17 #include "src/typing-reset.h"
18 #include "test/cctest/cctest.h"
19 #include "test/cctest/compiler/function-tester.h"
20 #include "test/cctest/expression-type-collector.h"
21 #include "test/cctest/expression-type-collector-macros.h"
22
23 #define INT32_TYPE Bounds(Type::Signed32(), Type::Signed32())
24
25 using namespace v8::internal;
26
27 namespace {
28
29 class TypeSetter : public AstExpressionVisitor {
30  public:
31   TypeSetter(Isolate* isolate, Zone* zone, FunctionLiteral* root)
32       : AstExpressionVisitor(isolate, zone, root) {}
33
34  protected:
35   void VisitExpression(Expression* expression) {
36     expression->set_bounds(INT32_TYPE);
37   }
38 };
39
40
41 void CheckAllSame(ZoneVector<ExpressionTypeEntry>& types,
42                   Bounds expected_type) {
43   CHECK_TYPES_BEGIN {
44     // function logSum
45     CHECK_EXPR(FunctionLiteral, expected_type) {
46       CHECK_EXPR(FunctionLiteral, expected_type) {
47         CHECK_EXPR(Assignment, expected_type) {
48           CHECK_VAR(start, expected_type);
49           CHECK_EXPR(BinaryOperation, expected_type) {
50             CHECK_VAR(start, expected_type);
51             CHECK_EXPR(Literal, expected_type);
52           }
53         }
54         CHECK_EXPR(Assignment, expected_type) {
55           CHECK_VAR(end, expected_type);
56           CHECK_EXPR(BinaryOperation, expected_type) {
57             CHECK_VAR(end, expected_type);
58             CHECK_EXPR(Literal, expected_type);
59           }
60         }
61         CHECK_EXPR(Assignment, expected_type) {
62           CHECK_VAR(sum, expected_type);
63           CHECK_EXPR(Literal, expected_type);
64         }
65         CHECK_EXPR(Assignment, expected_type) {
66           CHECK_VAR(p, expected_type);
67           CHECK_EXPR(Literal, expected_type);
68         }
69         CHECK_EXPR(Assignment, expected_type) {
70           CHECK_VAR(q, expected_type);
71           CHECK_EXPR(Literal, expected_type);
72         }
73         // for (p = start << 3, q = end << 3;
74         CHECK_EXPR(BinaryOperation, expected_type) {
75           CHECK_EXPR(Assignment, expected_type) {
76             CHECK_VAR(p, expected_type);
77             CHECK_EXPR(BinaryOperation, expected_type) {
78               CHECK_VAR(start, expected_type);
79               CHECK_EXPR(Literal, expected_type);
80             }
81           }
82           CHECK_EXPR(Assignment, expected_type) {
83             CHECK_VAR(q, expected_type);
84             CHECK_EXPR(BinaryOperation, expected_type) {
85               CHECK_VAR(end, expected_type);
86               CHECK_EXPR(Literal, expected_type);
87             }
88           }
89         }
90         // (p|0) < (q|0);
91         CHECK_EXPR(CompareOperation, expected_type) {
92           CHECK_EXPR(BinaryOperation, expected_type) {
93             CHECK_VAR(p, expected_type);
94             CHECK_EXPR(Literal, expected_type);
95           }
96           CHECK_EXPR(BinaryOperation, expected_type) {
97             CHECK_VAR(q, expected_type);
98             CHECK_EXPR(Literal, expected_type);
99           }
100         }
101         // p = (p + 8)|0) {\n"
102         CHECK_EXPR(Assignment, expected_type) {
103           CHECK_VAR(p, expected_type);
104           CHECK_EXPR(BinaryOperation, expected_type) {
105             CHECK_EXPR(BinaryOperation, expected_type) {
106               CHECK_VAR(p, expected_type);
107               CHECK_EXPR(Literal, expected_type);
108             }
109             CHECK_EXPR(Literal, expected_type);
110           }
111         }
112         // sum = sum + +log(values[p>>3]);
113         CHECK_EXPR(Assignment, expected_type) {
114           CHECK_VAR(sum, expected_type);
115           CHECK_EXPR(BinaryOperation, expected_type) {
116             CHECK_VAR(sum, expected_type);
117             CHECK_EXPR(BinaryOperation, expected_type) {
118               CHECK_EXPR(Call, expected_type) {
119                 CHECK_VAR(log, expected_type);
120                 CHECK_EXPR(Property, expected_type) {
121                   CHECK_VAR(values, expected_type);
122                   CHECK_EXPR(BinaryOperation, expected_type) {
123                     CHECK_VAR(p, expected_type);
124                     CHECK_EXPR(Literal, expected_type);
125                   }
126                 }
127               }
128               CHECK_EXPR(Literal, expected_type);
129             }
130           }
131         }
132         // return +sum;
133         CHECK_EXPR(BinaryOperation, expected_type) {
134           CHECK_VAR(sum, expected_type);
135           CHECK_EXPR(Literal, expected_type);
136         }
137       }
138       // function geometricMean
139       CHECK_EXPR(FunctionLiteral, expected_type) {
140         CHECK_EXPR(Assignment, expected_type) {
141           CHECK_VAR(start, expected_type);
142           CHECK_EXPR(BinaryOperation, expected_type) {
143             CHECK_VAR(start, expected_type);
144             CHECK_EXPR(Literal, expected_type);
145           }
146         }
147         CHECK_EXPR(Assignment, expected_type) {
148           CHECK_VAR(end, expected_type);
149           CHECK_EXPR(BinaryOperation, expected_type) {
150             CHECK_VAR(end, expected_type);
151             CHECK_EXPR(Literal, expected_type);
152           }
153         }
154         // return +exp(+logSum(start, end) / +((end - start)|0));
155         CHECK_EXPR(BinaryOperation, expected_type) {
156           CHECK_EXPR(Call, expected_type) {
157             CHECK_VAR(exp, expected_type);
158             CHECK_EXPR(BinaryOperation, expected_type) {
159               CHECK_EXPR(BinaryOperation, expected_type) {
160                 CHECK_EXPR(Call, expected_type) {
161                   CHECK_VAR(logSum, expected_type);
162                   CHECK_VAR(start, expected_type);
163                   CHECK_VAR(end, expected_type);
164                 }
165                 CHECK_EXPR(Literal, expected_type);
166               }
167               CHECK_EXPR(BinaryOperation, expected_type) {
168                 CHECK_EXPR(BinaryOperation, expected_type) {
169                   CHECK_EXPR(BinaryOperation, expected_type) {
170                     CHECK_VAR(end, expected_type);
171                     CHECK_VAR(start, expected_type);
172                   }
173                   CHECK_EXPR(Literal, expected_type);
174                 }
175                 CHECK_EXPR(Literal, expected_type);
176               }
177             }
178           }
179           CHECK_EXPR(Literal, expected_type);
180         }
181       }
182       // "use asm";
183       CHECK_EXPR(Literal, expected_type);
184       // var exp = stdlib.Math.exp;
185       CHECK_EXPR(Assignment, expected_type) {
186         CHECK_VAR(exp, expected_type);
187         CHECK_EXPR(Property, expected_type) {
188           CHECK_EXPR(Property, expected_type) {
189             CHECK_VAR(stdlib, expected_type);
190             CHECK_EXPR(Literal, expected_type);
191           }
192           CHECK_EXPR(Literal, expected_type);
193         }
194       }
195       // var log = stdlib.Math.log;
196       CHECK_EXPR(Assignment, expected_type) {
197         CHECK_VAR(log, expected_type);
198         CHECK_EXPR(Property, expected_type) {
199           CHECK_EXPR(Property, expected_type) {
200             CHECK_VAR(stdlib, expected_type);
201             CHECK_EXPR(Literal, expected_type);
202           }
203           CHECK_EXPR(Literal, expected_type);
204         }
205       }
206       // var values = new stdlib.Float64Array(buffer);
207       CHECK_EXPR(Assignment, expected_type) {
208         CHECK_VAR(values, expected_type);
209         CHECK_EXPR(CallNew, expected_type) {
210           CHECK_EXPR(Property, expected_type) {
211             CHECK_VAR(stdlib, expected_type);
212             CHECK_EXPR(Literal, expected_type);
213           }
214           CHECK_VAR(buffer, expected_type);
215         }
216       }
217       // return { geometricMean: geometricMean };
218       CHECK_EXPR(ObjectLiteral, expected_type) {
219         CHECK_VAR(geometricMean, expected_type);
220       }
221     }
222   }
223   CHECK_TYPES_END
224 }
225 }
226
227
228 TEST(ResetTypingInfo) {
229   const char test_function[] =
230       "function GeometricMean(stdlib, foreign, buffer) {\n"
231       "  \"use asm\";\n"
232       "\n"
233       "  var exp = stdlib.Math.exp;\n"
234       "  var log = stdlib.Math.log;\n"
235       "  var values = new stdlib.Float64Array(buffer);\n"
236       "\n"
237       "  function logSum(start, end) {\n"
238       "    start = start|0;\n"
239       "    end = end|0;\n"
240       "\n"
241       "    var sum = 0.0, p = 0, q = 0;\n"
242       "\n"
243       "    // asm.js forces byte addressing of the heap by requiring shifting "
244       "by 3\n"
245       "    for (p = start << 3, q = end << 3; (p|0) < (q|0); p = (p + 8)|0) {\n"
246       "      sum = sum + +log(values[p>>3]);\n"
247       "    }\n"
248       "\n"
249       "    return +sum;\n"
250       "  }\n"
251       "\n"
252       " function geometricMean(start, end) {\n"
253       "    start = start|0;\n"
254       "    end = end|0;\n"
255       "\n"
256       "    return +exp(+logSum(start, end) / +((end - start)|0));\n"
257       "  }\n"
258       "\n"
259       "  return { geometricMean: geometricMean };\n"
260       "}\n";
261
262   v8::V8::Initialize();
263   HandleAndZoneScope handles;
264
265   i::Isolate* isolate = CcTest::i_isolate();
266   i::Factory* factory = isolate->factory();
267
268   i::Handle<i::String> source_code =
269       factory->NewStringFromUtf8(i::CStrVector(test_function))
270           .ToHandleChecked();
271
272   i::Handle<i::Script> script = factory->NewScript(source_code);
273
274   i::ParseInfo info(handles.main_zone(), script);
275   i::Parser parser(&info);
276   parser.set_allow_harmony_arrow_functions(true);
277   parser.set_allow_harmony_sloppy(true);
278   info.set_global();
279   info.set_lazy(false);
280   info.set_allow_lazy_parsing(false);
281   info.set_toplevel(true);
282
283   CHECK(i::Compiler::ParseAndAnalyze(&info));
284   FunctionLiteral* root =
285       info.scope()->declarations()->at(0)->AsFunctionDeclaration()->fun();
286
287   // Core of the test.
288   ZoneVector<ExpressionTypeEntry> types(handles.main_zone());
289   ExpressionTypeCollector(isolate, handles.main_zone(), root, &types).Run();
290   CheckAllSame(types, Bounds::Unbounded());
291
292   TypeSetter(isolate, handles.main_zone(), root).Run();
293
294   ExpressionTypeCollector(isolate, handles.main_zone(), root, &types).Run();
295   CheckAllSame(types, INT32_TYPE);
296
297   TypingReseter(isolate, handles.main_zone(), root).Run();
298
299   ExpressionTypeCollector(isolate, handles.main_zone(), root, &types).Run();
300   CheckAllSame(types, Bounds::Unbounded());
301 }