Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: src/typing.cc

Issue 18901003: Compute expected type for variables (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/typing.h ('k') | src/variables.h » ('j') | src/variables.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 67
68 #undef RECURSE 68 #undef RECURSE
69 69
70 #define RECURSE(call) \ 70 #define RECURSE(call) \
71 do { \ 71 do { \
72 ASSERT(!HasStackOverflow()); \ 72 ASSERT(!HasStackOverflow()); \
73 call; \ 73 call; \
74 if (HasStackOverflow()) return; \ 74 if (HasStackOverflow()) return; \
75 } while (false) 75 } while (false)
76 76
77 #define RECURSE_EXPR(call, expected_type) \
78 do { \
79 Handle<Type> save = expected_type_; \
80 expected_type_ = handle(expected_type, isolate_); \
81 RECURSE(call); \
82 expected_type_ = save; \
83 } while (false)
84
77 85
78 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) { 86 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) {
79 for (int i = 0; i < stmts->length(); ++i) { 87 for (int i = 0; i < stmts->length(); ++i) {
80 Statement* stmt = stmts->at(i); 88 Statement* stmt = stmts->at(i);
81 RECURSE(Visit(stmt)); 89 RECURSE(Visit(stmt));
82 } 90 }
83 } 91 }
84 92
85 93
86 void AstTyper::VisitBlock(Block* stmt) { 94 void AstTyper::VisitBlock(Block* stmt) {
87 RECURSE(VisitStatements(stmt->statements())); 95 RECURSE(VisitStatements(stmt->statements()));
88 } 96 }
89 97
90 98
91 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) { 99 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
92 RECURSE(Visit(stmt->expression())); 100 RECURSE_EXPR(Visit(stmt->expression()), Type::Any());
93 } 101 }
94 102
95 103
96 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) { 104 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) {
97 } 105 }
98 106
99 107
100 void AstTyper::VisitIfStatement(IfStatement* stmt) { 108 void AstTyper::VisitIfStatement(IfStatement* stmt) {
101 RECURSE(Visit(stmt->condition())); 109 // Collect type feedback.
102 RECURSE(Visit(stmt->then_statement()));
103 RECURSE(Visit(stmt->else_statement()));
104
105 if (!stmt->condition()->ToBooleanIsTrue() && 110 if (!stmt->condition()->ToBooleanIsTrue() &&
106 !stmt->condition()->ToBooleanIsFalse()) { 111 !stmt->condition()->ToBooleanIsFalse()) {
107 stmt->condition()->RecordToBooleanTypeFeedback(oracle()); 112 stmt->condition()->RecordToBooleanTypeFeedback(oracle());
108 } 113 }
114
115 RECURSE_EXPR(Visit(stmt->condition()), Type::Boolean());
116 RECURSE(Visit(stmt->then_statement()));
117 RECURSE(Visit(stmt->else_statement()));
109 } 118 }
110 119
111 120
112 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) { 121 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
113 } 122 }
114 123
115 124
116 void AstTyper::VisitBreakStatement(BreakStatement* stmt) { 125 void AstTyper::VisitBreakStatement(BreakStatement* stmt) {
117 } 126 }
118 127
119 128
120 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) { 129 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
121 RECURSE(Visit(stmt->expression())); 130 // Collect type feedback.
122
123 // TODO(rossberg): we only need this for inlining into test contexts... 131 // TODO(rossberg): we only need this for inlining into test contexts...
124 stmt->expression()->RecordToBooleanTypeFeedback(oracle()); 132 stmt->expression()->RecordToBooleanTypeFeedback(oracle());
133
134 RECURSE_EXPR(Visit(stmt->expression()), Type::Any());
125 } 135 }
126 136
127 137
128 void AstTyper::VisitWithStatement(WithStatement* stmt) { 138 void AstTyper::VisitWithStatement(WithStatement* stmt) {
129 RECURSE(stmt->expression()); 139 RECURSE_EXPR(stmt->expression(), Type::Receiver());
130 RECURSE(stmt->statement()); 140 RECURSE(stmt->statement());
131 } 141 }
132 142
133 143
134 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { 144 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
135 RECURSE(Visit(stmt->tag())); 145 RECURSE_EXPR(Visit(stmt->tag()), Type::Any());
136 ZoneList<CaseClause*>* clauses = stmt->cases(); 146 ZoneList<CaseClause*>* clauses = stmt->cases();
137 SwitchStatement::SwitchType switch_type = stmt->switch_type(); 147 SwitchStatement::SwitchType switch_type = stmt->switch_type();
138 for (int i = 0; i < clauses->length(); ++i) { 148 for (int i = 0; i < clauses->length(); ++i) {
139 CaseClause* clause = clauses->at(i); 149 CaseClause* clause = clauses->at(i);
140 if (!clause->is_default()) { 150 if (!clause->is_default()) {
141 Expression* label = clause->label(); 151 Expression* label = clause->label();
142 RECURSE(Visit(label)); 152 RECURSE_EXPR(Visit(label), *stmt->tag()->upper_type());
143 153
144 SwitchStatement::SwitchType label_switch_type = 154 SwitchStatement::SwitchType label_switch_type =
145 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH : 155 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH :
146 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH : 156 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH :
147 SwitchStatement::GENERIC_SWITCH; 157 SwitchStatement::GENERIC_SWITCH;
148 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) 158 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
149 switch_type = label_switch_type; 159 switch_type = label_switch_type;
150 else if (switch_type != label_switch_type) 160 else if (switch_type != label_switch_type)
151 switch_type = SwitchStatement::GENERIC_SWITCH; 161 switch_type = SwitchStatement::GENERIC_SWITCH;
152 } 162 }
153 RECURSE(VisitStatements(clause->statements())); 163 RECURSE(VisitStatements(clause->statements()));
154 } 164 }
155 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) 165 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
156 switch_type = SwitchStatement::GENERIC_SWITCH; 166 switch_type = SwitchStatement::GENERIC_SWITCH;
157 stmt->set_switch_type(switch_type); 167 stmt->set_switch_type(switch_type);
158 168
169 // Collect type feedback.
159 // TODO(rossberg): can we eliminate this special case and extra loop? 170 // TODO(rossberg): can we eliminate this special case and extra loop?
160 if (switch_type == SwitchStatement::SMI_SWITCH) { 171 if (switch_type == SwitchStatement::SMI_SWITCH) {
161 for (int i = 0; i < clauses->length(); ++i) { 172 for (int i = 0; i < clauses->length(); ++i) {
162 CaseClause* clause = clauses->at(i); 173 CaseClause* clause = clauses->at(i);
163 if (!clause->is_default()) 174 if (!clause->is_default())
164 clause->RecordTypeFeedback(oracle()); 175 clause->RecordTypeFeedback(oracle());
165 } 176 }
166 } 177 }
167 } 178 }
168 179
169 180
170 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) { 181 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
171 RECURSE(Visit(stmt->body())); 182 // Collect type feedback.
172 RECURSE(Visit(stmt->cond()));
173
174 if (!stmt->cond()->ToBooleanIsTrue()) { 183 if (!stmt->cond()->ToBooleanIsTrue()) {
175 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 184 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
176 } 185 }
186
187 RECURSE(Visit(stmt->body()));
188 RECURSE_EXPR(Visit(stmt->cond()), Type::Boolean());
177 } 189 }
178 190
179 191
180 void AstTyper::VisitWhileStatement(WhileStatement* stmt) { 192 void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
181 RECURSE(Visit(stmt->cond())); 193 // Collect type feedback.
182 RECURSE(Visit(stmt->body()));
183
184 if (!stmt->cond()->ToBooleanIsTrue()) { 194 if (!stmt->cond()->ToBooleanIsTrue()) {
185 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 195 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
186 } 196 }
197
198 RECURSE_EXPR(Visit(stmt->cond()), Type::Boolean());
199 RECURSE(Visit(stmt->body()));
187 } 200 }
188 201
189 202
190 void AstTyper::VisitForStatement(ForStatement* stmt) { 203 void AstTyper::VisitForStatement(ForStatement* stmt) {
191 if (stmt->init() != NULL) { 204 if (stmt->init() != NULL) {
192 RECURSE(Visit(stmt->init())); 205 RECURSE(Visit(stmt->init()));
193 } 206 }
194 if (stmt->cond() != NULL) { 207 if (stmt->cond() != NULL) {
195 RECURSE(Visit(stmt->cond())); 208 // Collect type feedback.
209 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
196 210
197 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 211 RECURSE_EXPR(Visit(stmt->cond()), Type::Boolean());
198 } 212 }
199 RECURSE(Visit(stmt->body())); 213 RECURSE(Visit(stmt->body()));
200 if (stmt->next() != NULL) { 214 if (stmt->next() != NULL) {
201 RECURSE(Visit(stmt->next())); 215 RECURSE(Visit(stmt->next()));
202 } 216 }
203 } 217 }
204 218
205 219
206 void AstTyper::VisitForInStatement(ForInStatement* stmt) { 220 void AstTyper::VisitForInStatement(ForInStatement* stmt) {
207 RECURSE(Visit(stmt->enumerable())); 221 // Collect type feedback.
222 stmt->RecordTypeFeedback(oracle());
223
224 RECURSE_EXPR(Visit(stmt->enumerable()), Type::Receiver());
208 RECURSE(Visit(stmt->body())); 225 RECURSE(Visit(stmt->body()));
209
210 stmt->RecordTypeFeedback(oracle());
211 } 226 }
212 227
213 228
214 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) { 229 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {
215 RECURSE(Visit(stmt->iterable())); 230 RECURSE_EXPR(Visit(stmt->iterable()), Type::Receiver());
216 RECURSE(Visit(stmt->body())); 231 RECURSE(Visit(stmt->body()));
217 } 232 }
218 233
219 234
220 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) { 235 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
221 RECURSE(Visit(stmt->try_block())); 236 RECURSE(Visit(stmt->try_block()));
222 RECURSE(Visit(stmt->catch_block())); 237 RECURSE(Visit(stmt->catch_block()));
223 } 238 }
224 239
225 240
226 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 241 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
227 RECURSE(Visit(stmt->try_block())); 242 RECURSE(Visit(stmt->try_block()));
228 RECURSE(Visit(stmt->finally_block())); 243 RECURSE(Visit(stmt->finally_block()));
229 } 244 }
230 245
231 246
232 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) { 247 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
233 } 248 }
234 249
235 250
236 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) { 251 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
237 } 252 }
238 253
239 254
240 void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) { 255 void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) {
241 } 256 }
242 257
243 258
244 void AstTyper::VisitConditional(Conditional* expr) { 259 void AstTyper::VisitConditional(Conditional* expr) {
245 RECURSE(Visit(expr->condition())); 260 // Collect type feedback.
261 expr->condition()->RecordToBooleanTypeFeedback(oracle());
262
263 RECURSE_EXPR(Visit(expr->condition()), Type::Boolean());
246 RECURSE(Visit(expr->then_expression())); 264 RECURSE(Visit(expr->then_expression()));
247 RECURSE(Visit(expr->else_expression())); 265 RECURSE(Visit(expr->else_expression()));
248 266
249 expr->condition()->RecordToBooleanTypeFeedback(oracle());
250
251 MergeLowerType(expr, Type::Intersect( 267 MergeLowerType(expr, Type::Intersect(
252 expr->then_expression()->lower_type(), 268 expr->then_expression()->lower_type(),
253 expr->else_expression()->lower_type())); 269 expr->else_expression()->lower_type()));
254 MergeUpperType(expr, Type::Union( 270 MergeUpperType(expr, Type::Union(
255 expr->then_expression()->upper_type(), 271 expr->then_expression()->upper_type(),
256 expr->else_expression()->upper_type())); 272 expr->else_expression()->upper_type()));
257 } 273 }
258 274
259 275
260 void AstTyper::VisitVariableProxy(VariableProxy* expr) { 276 void AstTyper::VisitVariableProxy(VariableProxy* expr) {
261 // TODO(rossberg): typing of variables 277 // TODO(rossberg): typing of variables
278
279 Variable* var = expr->var();
280 var->set_expected_type(handle(
281 Type::Intersect(var->expected_type(), expected_type_), isolate_));
Jakob Kummerow 2013/07/09 16:01:50 As discussed offline, I still think a Union would
262 } 282 }
263 283
264 284
265 void AstTyper::VisitLiteral(Literal* expr) { 285 void AstTyper::VisitLiteral(Literal* expr) {
266 Type* type = Type::Constant(expr->value(), isolate_); 286 Type* type = Type::Constant(expr->value(), isolate_);
267 MergeLowerType(expr, type); 287 MergeLowerType(expr, type);
268 MergeUpperType(expr, type); 288 MergeUpperType(expr, type);
269 } 289 }
270 290
271 291
272 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { 292 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
273 MergeLowerType(expr, Type::RegExp()); 293 MergeLowerType(expr, Type::RegExp());
274 MergeUpperType(expr, Type::RegExp()); 294 MergeUpperType(expr, Type::RegExp());
275 } 295 }
276 296
277 297
278 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { 298 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
279 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); 299 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
280 for (int i = 0; i < properties->length(); ++i) { 300 for (int i = 0; i < properties->length(); ++i) {
281 ObjectLiteral::Property* prop = properties->at(i); 301 ObjectLiteral::Property* prop = properties->at(i);
282 RECURSE(Visit(prop->value()));
283 302
303 // Collect type feedback.
284 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && 304 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
285 !CompileTimeValue::IsCompileTimeValue(prop->value())) || 305 !CompileTimeValue::IsCompileTimeValue(prop->value())) ||
286 prop->kind() == ObjectLiteral::Property::COMPUTED) { 306 prop->kind() == ObjectLiteral::Property::COMPUTED) {
287 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) { 307 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) {
288 prop->RecordTypeFeedback(oracle()); 308 prop->RecordTypeFeedback(oracle());
289 } 309 }
290 } 310 }
311
312 RECURSE_EXPR(Visit(prop->value()), Type::Any());
291 } 313 }
292 314
293 MergeLowerType(expr, Type::Object()); 315 MergeLowerType(expr, Type::Object());
294 MergeUpperType(expr, Type::Object()); 316 MergeUpperType(expr, Type::Object());
295 } 317 }
296 318
297 319
298 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { 320 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
299 ZoneList<Expression*>* values = expr->values(); 321 ZoneList<Expression*>* values = expr->values();
300 for (int i = 0; i < values->length(); ++i) { 322 for (int i = 0; i < values->length(); ++i) {
301 Expression* value = values->at(i); 323 Expression* value = values->at(i);
302 RECURSE(Visit(value)); 324 RECURSE_EXPR(Visit(value), Type::Any());
303 } 325 }
304 326
305 MergeLowerType(expr, Type::Array()); 327 MergeLowerType(expr, Type::Array());
306 MergeUpperType(expr, Type::Array()); 328 MergeUpperType(expr, Type::Array());
307 } 329 }
308 330
309 331
310 void AstTyper::VisitAssignment(Assignment* expr) { 332 void AstTyper::VisitAssignment(Assignment* expr) {
311 // TODO(rossberg): Can we clean this up? 333 // TODO(rossberg): Can we clean this up?
312 if (expr->is_compound()) { 334 if (expr->is_compound()) {
313 RECURSE(Visit(expr->binary_operation())); 335 // Collect type feedback.
314
315 Expression* target = expr->target(); 336 Expression* target = expr->target();
316 Property* prop = target->AsProperty(); 337 Property* prop = target->AsProperty();
317 if (prop != NULL) { 338 if (prop != NULL) {
318 prop->RecordTypeFeedback(oracle(), zone()); 339 prop->RecordTypeFeedback(oracle(), zone());
319 if (!prop->key()->IsPropertyName()) { // i.e., keyed 340 if (!prop->key()->IsPropertyName()) { // i.e., keyed
320 expr->RecordTypeFeedback(oracle(), zone()); 341 expr->RecordTypeFeedback(oracle(), zone());
321 } 342 }
322 } 343 }
344
345 RECURSE_EXPR(Visit(expr->binary_operation()), Type::Any());
346 MergeLowerType(expr, expr->binary_operation()->lower_type());
347 MergeUpperType(expr, expr->binary_operation()->upper_type());
323 } else { 348 } else {
324 RECURSE(Visit(expr->target())); 349 // Collect type feedback.
325 RECURSE(Visit(expr->value()));
326
327 if (expr->target()->AsProperty()) { 350 if (expr->target()->AsProperty()) {
328 expr->RecordTypeFeedback(oracle(), zone()); 351 expr->RecordTypeFeedback(oracle(), zone());
329 } 352 }
330 353
354 RECURSE(Visit(expr->target()));
355 RECURSE(Visit(expr->value()));
Jakob Kummerow 2013/07/09 16:01:50 Shouldn't this be RECURSE_EXPR(_, Type::Any())?
331 MergeLowerType(expr, expr->value()->lower_type()); 356 MergeLowerType(expr, expr->value()->lower_type());
332 MergeUpperType(expr, expr->value()->upper_type()); 357 MergeUpperType(expr, expr->value()->upper_type());
333 } 358 }
334 // TODO(rossberg): handle target variables 359 // TODO(rossberg): handle target variables
335 } 360 }
336 361
337 362
338 void AstTyper::VisitYield(Yield* expr) { 363 void AstTyper::VisitYield(Yield* expr) {
339 RECURSE(Visit(expr->generator_object())); 364 RECURSE_EXPR(Visit(expr->generator_object()), Type::Receiver());
340 RECURSE(Visit(expr->expression())); 365 RECURSE_EXPR(Visit(expr->expression()), Type::Any());
341 366
342 // We don't know anything about the type. 367 // We don't know anything about the result type.
343 } 368 }
344 369
345 370
346 void AstTyper::VisitThrow(Throw* expr) { 371 void AstTyper::VisitThrow(Throw* expr) {
347 RECURSE(Visit(expr->exception())); 372 RECURSE_EXPR(Visit(expr->exception()), Type::Any());
348 373
349 // Lower type is None already. 374 // Lower type is None already.
350 MergeUpperType(expr, Type::None()); 375 MergeUpperType(expr, Type::None());
351 } 376 }
352 377
353 378
354 void AstTyper::VisitProperty(Property* expr) { 379 void AstTyper::VisitProperty(Property* expr) {
355 RECURSE(Visit(expr->obj())); 380 // Collect type feedback.
356 RECURSE(Visit(expr->key()));
357
358 expr->RecordTypeFeedback(oracle(), zone()); 381 expr->RecordTypeFeedback(oracle(), zone());
359 382
360 // We don't know anything about the type. 383 RECURSE_EXPR(Visit(expr->obj()), Type::Receiver());
384 RECURSE_EXPR(Visit(expr->key()), Type::Name());
Jakob Kummerow 2013/07/09 16:01:50 I'm pretty sure that the key can also be a number.
385
386 // We don't know anything about the result type.
361 } 387 }
362 388
363 389
364 void AstTyper::VisitCall(Call* expr) { 390 void AstTyper::VisitCall(Call* expr) {
365 RECURSE(Visit(expr->expression())); 391 // Collect type feedback.
366 ZoneList<Expression*>* args = expr->arguments();
367 for (int i = 0; i < args->length(); ++i) {
368 Expression* arg = args->at(i);
369 RECURSE(Visit(arg));
370 }
371
372 Expression* callee = expr->expression(); 392 Expression* callee = expr->expression();
373 Property* prop = callee->AsProperty(); 393 Property* prop = callee->AsProperty();
374 if (prop != NULL) { 394 if (prop != NULL) {
375 if (prop->key()->IsPropertyName()) 395 if (prop->key()->IsPropertyName())
376 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD); 396 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
377 } else { 397 } else {
378 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION); 398 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
379 } 399 }
380 400
381 // We don't know anything about the type. 401 RECURSE_EXPR(Visit(expr->expression()), Type::Function());
402 ZoneList<Expression*>* args = expr->arguments();
403 for (int i = 0; i < args->length(); ++i) {
404 Expression* arg = args->at(i);
405 RECURSE_EXPR(Visit(arg), Type::Any());
406 }
407
408 // We don't know anything about the result type.
382 } 409 }
383 410
384 411
385 void AstTyper::VisitCallNew(CallNew* expr) { 412 void AstTyper::VisitCallNew(CallNew* expr) {
386 RECURSE(Visit(expr->expression())); 413 // Collect type feedback.
414 expr->RecordTypeFeedback(oracle());
415
416 RECURSE_EXPR(Visit(expr->expression()), Type::Function());
387 ZoneList<Expression*>* args = expr->arguments(); 417 ZoneList<Expression*>* args = expr->arguments();
388 for (int i = 0; i < args->length(); ++i) { 418 for (int i = 0; i < args->length(); ++i) {
389 Expression* arg = args->at(i); 419 Expression* arg = args->at(i);
390 RECURSE(Visit(arg)); 420 RECURSE_EXPR(Visit(arg), Type::Any());
391 } 421 }
392 422
393 expr->RecordTypeFeedback(oracle()); 423 // We don't know anything about the result type.
394
395 // We don't know anything about the type.
396 } 424 }
397 425
398 426
399 void AstTyper::VisitCallRuntime(CallRuntime* expr) { 427 void AstTyper::VisitCallRuntime(CallRuntime* expr) {
400 ZoneList<Expression*>* args = expr->arguments(); 428 ZoneList<Expression*>* args = expr->arguments();
401 for (int i = 0; i < args->length(); ++i) { 429 for (int i = 0; i < args->length(); ++i) {
402 Expression* arg = args->at(i); 430 Expression* arg = args->at(i);
403 RECURSE(Visit(arg)); 431 RECURSE_EXPR(Visit(arg), Type::Any());
404 } 432 }
405 433
406 // We don't know anything about the type. 434 // We don't know anything about the result type.
407 } 435 }
408 436
409 437
410 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { 438 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
411 RECURSE(Visit(expr->expression()));
412
413 // Collect type feedback. 439 // Collect type feedback.
414 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId()); 440 Handle<Type> op_type = oracle()->UnaryType(expr->UnaryOperationFeedbackId());
415 MergeLowerType(expr->expression(), op_type); 441 MergeLowerType(expr->expression(), op_type);
416 if (expr->op() == Token::NOT) { 442 if (expr->op() == Token::NOT) {
417 // TODO(rossberg): only do in test or value context. 443 // TODO(rossberg): only do in test or value context.
418 expr->expression()->RecordToBooleanTypeFeedback(oracle()); 444 expr->expression()->RecordToBooleanTypeFeedback(oracle());
419 } 445 }
420 446
421 switch (expr->op()) { 447 switch (expr->op()) {
422 case Token::NOT: 448 case Token::NOT:
449 RECURSE_EXPR(Visit(expr->expression()), Type::Boolean());
450 MergeLowerType(expr, Type::Boolean());
451 MergeUpperType(expr, Type::Boolean());
452 break;
423 case Token::DELETE: 453 case Token::DELETE:
454 RECURSE_EXPR(Visit(expr->expression()), Type::Any());
424 MergeLowerType(expr, Type::Boolean()); 455 MergeLowerType(expr, Type::Boolean());
425 MergeUpperType(expr, Type::Boolean()); 456 MergeUpperType(expr, Type::Boolean());
426 break; 457 break;
427 case Token::VOID: 458 case Token::VOID:
459 RECURSE_EXPR(Visit(expr->expression()), Type::Any());
428 MergeLowerType(expr, Type::Undefined()); 460 MergeLowerType(expr, Type::Undefined());
429 MergeUpperType(expr, Type::Undefined()); 461 MergeUpperType(expr, Type::Undefined());
430 break; 462 break;
431 case Token::ADD: 463 case Token::ADD:
432 case Token::SUB: { 464 case Token::SUB: {
465 RECURSE_EXPR(Visit(expr->expression()), Type::Number());
433 MergeLowerType(expr, Type::Smi()); 466 MergeLowerType(expr, Type::Smi());
434 Type* upper = *expr->expression()->upper_type(); 467 Type* upper = *expr->expression()->upper_type();
435 MergeUpperType(expr, upper->Is(Type::Number()) ? upper : Type::Number()); 468 MergeUpperType(expr, upper->Is(Type::Number()) ? upper : Type::Number());
436 break; 469 break;
437 } 470 }
438 case Token::BIT_NOT: 471 case Token::BIT_NOT:
472 RECURSE_EXPR(Visit(expr->expression()), Type::Signed32());
439 MergeLowerType(expr, Type::Smi()); 473 MergeLowerType(expr, Type::Smi());
440 MergeUpperType(expr, Type::Signed32()); 474 MergeUpperType(expr, Type::Signed32());
441 break; 475 break;
442 case Token::TYPEOF: 476 case Token::TYPEOF:
477 RECURSE_EXPR(Visit(expr->expression()), Type::Any());
443 MergeLowerType(expr, Type::InternalizedString()); 478 MergeLowerType(expr, Type::InternalizedString());
444 MergeUpperType(expr, Type::InternalizedString()); 479 MergeUpperType(expr, Type::InternalizedString());
445 break; 480 break;
446 default: 481 default:
447 UNREACHABLE(); 482 UNREACHABLE();
448 } 483 }
449 } 484 }
450 485
451 486
452 void AstTyper::VisitCountOperation(CountOperation* expr) { 487 void AstTyper::VisitCountOperation(CountOperation* expr) {
453 RECURSE(Visit(expr->expression())); 488 // Collect type feedback.
454
455 expr->RecordTypeFeedback(oracle(), zone()); 489 expr->RecordTypeFeedback(oracle(), zone());
456 Property* prop = expr->expression()->AsProperty(); 490 Property* prop = expr->expression()->AsProperty();
457 if (prop != NULL) { 491 if (prop != NULL) {
458 prop->RecordTypeFeedback(oracle(), zone()); 492 prop->RecordTypeFeedback(oracle(), zone());
459 } 493 }
460 494
495 RECURSE_EXPR(Visit(expr->expression()), Type::Number());
461 MergeLowerType(expr, Type::Smi()); 496 MergeLowerType(expr, Type::Smi());
462 MergeUpperType(expr, Type::Number()); 497 MergeUpperType(expr, Type::Number());
463 } 498 }
464 499
465 500
466 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { 501 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
467 RECURSE(Visit(expr->left()));
468 RECURSE(Visit(expr->right()));
469
470 // Collect type feedback. 502 // Collect type feedback.
471 Handle<Type> type, left_type, right_type; 503 Handle<Type> type, left_type, right_type;
472 Maybe<int> fixed_right_arg; 504 Maybe<int> fixed_right_arg;
473 oracle()->BinaryType(expr->BinaryOperationFeedbackId(), 505 oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
474 &left_type, &right_type, &type, &fixed_right_arg); 506 &left_type, &right_type, &type, &fixed_right_arg);
475 MergeLowerType(expr, type); 507 MergeLowerType(expr, type);
476 MergeLowerType(expr->left(), left_type); 508 MergeLowerType(expr->left(), left_type);
477 MergeLowerType(expr->right(), right_type); 509 MergeLowerType(expr->right(), right_type);
478 expr->set_fixed_right_arg(fixed_right_arg); 510 expr->set_fixed_right_arg(fixed_right_arg);
479 if (expr->op() == Token::OR || expr->op() == Token::AND) { 511 if (expr->op() == Token::OR || expr->op() == Token::AND) {
480 expr->left()->RecordToBooleanTypeFeedback(oracle()); 512 expr->left()->RecordToBooleanTypeFeedback(oracle());
481 } 513 }
482 514
483 switch (expr->op()) { 515 switch (expr->op()) {
484 case Token::COMMA: 516 case Token::COMMA:
517 RECURSE_EXPR(Visit(expr->left()), Type::Any());
518 RECURSE_EXPR(Visit(expr->right()), Type::Any());
485 MergeLowerType(expr, expr->right()->lower_type()); 519 MergeLowerType(expr, expr->right()->lower_type());
486 MergeUpperType(expr, expr->right()->upper_type()); 520 MergeUpperType(expr, expr->right()->upper_type());
487 break; 521 break;
488 case Token::OR: 522 case Token::OR:
489 case Token::AND: 523 case Token::AND:
524 RECURSE_EXPR(Visit(expr->left()), Type::Any());
525 RECURSE_EXPR(Visit(expr->right()), Type::Any());
490 MergeLowerType(expr, Type::Intersect( 526 MergeLowerType(expr, Type::Intersect(
491 expr->left()->lower_type(), expr->right()->lower_type())); 527 expr->left()->lower_type(), expr->right()->lower_type()));
492 MergeUpperType(expr, Type::Union( 528 MergeUpperType(expr, Type::Union(
493 expr->left()->upper_type(), expr->right()->upper_type())); 529 expr->left()->upper_type(), expr->right()->upper_type()));
494 break; 530 break;
495 case Token::BIT_OR: 531 case Token::BIT_OR:
496 case Token::BIT_AND: { 532 case Token::BIT_AND: {
533 RECURSE_EXPR(Visit(expr->left()), Type::Signed32());
534 RECURSE_EXPR(Visit(expr->right()), Type::Signed32());
497 MergeLowerType(expr, Type::Smi()); 535 MergeLowerType(expr, Type::Smi());
498 Type* upper = 536 Type* upper =
499 Type::Union(expr->left()->upper_type(), expr->right()->upper_type()); 537 Type::Union(expr->left()->upper_type(), expr->right()->upper_type());
500 MergeUpperType(expr, 538 MergeUpperType(expr,
501 upper->Is(Type::Signed32()) ? upper : Type::Signed32()); 539 upper->Is(Type::Signed32()) ? upper : Type::Signed32());
502 break; 540 break;
503 } 541 }
504 case Token::BIT_XOR: 542 case Token::BIT_XOR:
543 RECURSE_EXPR(Visit(expr->left()), Type::Signed32());
544 RECURSE_EXPR(Visit(expr->right()), Type::Signed32());
545 MergeLowerType(expr, Type::Smi());
546 MergeUpperType(expr, Type::Signed32());
547 break;
505 case Token::SHL: 548 case Token::SHL:
506 case Token::SAR: 549 case Token::SAR:
550 RECURSE_EXPR(Visit(expr->left()), Type::Signed32());
551 RECURSE_EXPR(Visit(expr->right()), Type::Unsigned32());
507 MergeLowerType(expr, Type::Smi()); 552 MergeLowerType(expr, Type::Smi());
508 MergeUpperType(expr, Type::Signed32()); 553 MergeUpperType(expr, Type::Signed32());
509 break; 554 break;
510 case Token::SHR: 555 case Token::SHR:
556 RECURSE_EXPR(Visit(expr->left()), Type::Unsigned32());
557 RECURSE_EXPR(Visit(expr->right()), Type::Unsigned32());
511 MergeLowerType(expr, Type::Smi()); 558 MergeLowerType(expr, Type::Smi());
512 MergeUpperType(expr, Type::Unsigned32()); 559 MergeUpperType(expr, Type::Unsigned32());
513 break; 560 break;
514 case Token::ADD: { 561 case Token::ADD: {
562 RECURSE_EXPR(Visit(expr->left()), Type::NumberOrString());
563 RECURSE_EXPR(Visit(expr->right()), Type::NumberOrString());
515 Handle<Type> l = expr->left()->lower_type(); 564 Handle<Type> l = expr->left()->lower_type();
516 Handle<Type> r = expr->right()->lower_type(); 565 Handle<Type> r = expr->right()->lower_type();
517 MergeLowerType(expr, 566 MergeLowerType(expr,
518 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Smi() : 567 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Smi() :
519 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() : 568 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() :
520 Type::None()); 569 Type::None());
521 l = expr->left()->upper_type(); 570 l = expr->left()->upper_type();
522 r = expr->right()->upper_type(); 571 r = expr->right()->upper_type();
523 MergeUpperType(expr, 572 MergeUpperType(expr,
524 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Number() : 573 l->Is(Type::Number()) && r->Is(Type::Number()) ? Type::Number() :
525 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() : 574 l->Is(Type::String()) || r->Is(Type::String()) ? Type::String() :
526 Type::NumberOrString()); 575 Type::NumberOrString());
527 break; 576 break;
528 } 577 }
529 case Token::SUB: 578 case Token::SUB:
530 case Token::MUL: 579 case Token::MUL:
531 case Token::DIV: 580 case Token::DIV:
532 case Token::MOD: 581 case Token::MOD:
582 RECURSE_EXPR(Visit(expr->left()), Type::Number());
583 RECURSE_EXPR(Visit(expr->right()), Type::Number());
533 MergeLowerType(expr, Type::Smi()); 584 MergeLowerType(expr, Type::Smi());
534 MergeUpperType(expr, Type::Number()); 585 MergeUpperType(expr, Type::Number());
535 break; 586 break;
536 default: 587 default:
537 UNREACHABLE(); 588 UNREACHABLE();
538 } 589 }
539 } 590 }
540 591
541 592
542 void AstTyper::VisitCompareOperation(CompareOperation* expr) { 593 void AstTyper::VisitCompareOperation(CompareOperation* expr) {
543 RECURSE(Visit(expr->left()));
544 RECURSE(Visit(expr->right()));
545
546 // Collect type feedback. 594 // Collect type feedback.
547 Handle<Type> left_type, right_type, combined_type; 595 Handle<Type> left_type, right_type, combined_type;
548 oracle()->CompareType(expr->CompareOperationFeedbackId(), 596 oracle()->CompareType(expr->CompareOperationFeedbackId(),
549 &left_type, &right_type, &combined_type); 597 &left_type, &right_type, &combined_type);
550 MergeLowerType(expr->left(), left_type); 598 MergeLowerType(expr->left(), left_type);
551 MergeLowerType(expr->right(), right_type); 599 MergeLowerType(expr->right(), right_type);
552 expr->set_combined_type(combined_type); 600 expr->set_combined_type(combined_type);
553 601
602 switch (expr->op()) {
603 case Token::EQ:
604 case Token::NE:
605 case Token::EQ_STRICT:
606 case Token::NE_STRICT:
607 RECURSE_EXPR(Visit(expr->left()), Type::Any());
608 RECURSE_EXPR(Visit(expr->right()), Type::Any());
609 break;
610 case Token::LT:
611 case Token::GT:
612 case Token::LTE:
613 case Token::GTE:
614 RECURSE_EXPR(Visit(expr->left()), Type::NumberOrString());
615 RECURSE_EXPR(Visit(expr->right()), Type::NumberOrString());
616 break;
617 case Token::INSTANCEOF:
618 RECURSE_EXPR(Visit(expr->left()), Type::Receiver());
619 RECURSE_EXPR(Visit(expr->right()), Type::Function());
620 break;
621 case Token::IN:
622 RECURSE_EXPR(Visit(expr->left()), Type::Name());
623 RECURSE_EXPR(Visit(expr->right()), Type::Receiver());
624 break;
625 default:
626 UNREACHABLE();
627 }
554 MergeLowerType(expr, Type::Boolean()); 628 MergeLowerType(expr, Type::Boolean());
555 MergeUpperType(expr, Type::Boolean()); 629 MergeUpperType(expr, Type::Boolean());
556 } 630 }
557 631
558 632
559 void AstTyper::VisitThisFunction(ThisFunction* expr) { 633 void AstTyper::VisitThisFunction(ThisFunction* expr) {
560 } 634 }
561 635
562 636
563 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { 637 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
608 void AstTyper::VisitModuleUrl(ModuleUrl* module) { 682 void AstTyper::VisitModuleUrl(ModuleUrl* module) {
609 } 683 }
610 684
611 685
612 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { 686 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) {
613 RECURSE(Visit(stmt->body())); 687 RECURSE(Visit(stmt->body()));
614 } 688 }
615 689
616 690
617 } } // namespace v8::internal 691 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/typing.h ('k') | src/variables.h » ('j') | src/variables.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698