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