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

Side by Side Diff: src/typing.cc

Issue 22546003: Rollback of r16071 in trunk branch. (Closed) Base URL: https://v8.googlecode.com/svn/trunk
Patch Set: Created 7 years, 4 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/version.cc » ('j') | no next file with comments »
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 22 matching lines...) Expand all
33 namespace v8 { 33 namespace v8 {
34 namespace internal { 34 namespace internal {
35 35
36 36
37 AstTyper::AstTyper(CompilationInfo* info) 37 AstTyper::AstTyper(CompilationInfo* info)
38 : info_(info), 38 : info_(info),
39 oracle_( 39 oracle_(
40 Handle<Code>(info->closure()->shared()->code()), 40 Handle<Code>(info->closure()->shared()->code()),
41 Handle<Context>(info->closure()->context()->native_context()), 41 Handle<Context>(info->closure()->context()->native_context()),
42 info->isolate(), 42 info->isolate(),
43 info->zone()), 43 info->zone()) {
44 store_(info->zone()) {
45 InitializeAstVisitor(); 44 InitializeAstVisitor();
46 } 45 }
47 46
48 47
49 #define RECURSE(call) \ 48 #define RECURSE(call) \
50 do { \ 49 do { \
51 ASSERT(!visitor->HasStackOverflow()); \ 50 ASSERT(!visitor->HasStackOverflow()); \
52 call; \ 51 call; \
53 if (visitor->HasStackOverflow()) return; \ 52 if (visitor->HasStackOverflow()) return; \
54 } while (false) 53 } while (false)
(...skipping 18 matching lines...) Expand all
73 ASSERT(!HasStackOverflow()); \ 72 ASSERT(!HasStackOverflow()); \
74 call; \ 73 call; \
75 if (HasStackOverflow()) return; \ 74 if (HasStackOverflow()) return; \
76 } while (false) 75 } while (false)
77 76
78 77
79 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) { 78 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) {
80 for (int i = 0; i < stmts->length(); ++i) { 79 for (int i = 0; i < stmts->length(); ++i) {
81 Statement* stmt = stmts->at(i); 80 Statement* stmt = stmts->at(i);
82 RECURSE(Visit(stmt)); 81 RECURSE(Visit(stmt));
83 if (stmt->IsJump()) break;
84 } 82 }
85 } 83 }
86 84
87 85
88 void AstTyper::VisitBlock(Block* stmt) { 86 void AstTyper::VisitBlock(Block* stmt) {
89 RECURSE(VisitStatements(stmt->statements())); 87 RECURSE(VisitStatements(stmt->statements()));
90 if (stmt->labels() != NULL) {
91 store_.Forget(); // Control may transfer here via 'break l'.
92 }
93 } 88 }
94 89
95 90
96 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) { 91 void AstTyper::VisitExpressionStatement(ExpressionStatement* stmt) {
97 RECURSE(Visit(stmt->expression())); 92 RECURSE(Visit(stmt->expression()));
98 } 93 }
99 94
100 95
101 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) { 96 void AstTyper::VisitEmptyStatement(EmptyStatement* stmt) {
102 } 97 }
103 98
104 99
105 void AstTyper::VisitIfStatement(IfStatement* stmt) { 100 void AstTyper::VisitIfStatement(IfStatement* stmt) {
106 // Collect type feedback. 101 RECURSE(Visit(stmt->condition()));
102 RECURSE(Visit(stmt->then_statement()));
103 RECURSE(Visit(stmt->else_statement()));
104
107 if (!stmt->condition()->ToBooleanIsTrue() && 105 if (!stmt->condition()->ToBooleanIsTrue() &&
108 !stmt->condition()->ToBooleanIsFalse()) { 106 !stmt->condition()->ToBooleanIsFalse()) {
109 stmt->condition()->RecordToBooleanTypeFeedback(oracle()); 107 stmt->condition()->RecordToBooleanTypeFeedback(oracle());
110 } 108 }
111
112 RECURSE(Visit(stmt->condition()));
113 Effects then_effects = EnterEffects();
114 RECURSE(Visit(stmt->then_statement()));
115 ExitEffects();
116 Effects else_effects = EnterEffects();
117 RECURSE(Visit(stmt->else_statement()));
118 ExitEffects();
119 then_effects.Alt(else_effects);
120 store_.Seq(then_effects);
121 } 109 }
122 110
123 111
124 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) { 112 void AstTyper::VisitContinueStatement(ContinueStatement* stmt) {
125 // TODO(rossberg): is it worth having a non-termination effect?
126 } 113 }
127 114
128 115
129 void AstTyper::VisitBreakStatement(BreakStatement* stmt) { 116 void AstTyper::VisitBreakStatement(BreakStatement* stmt) {
130 // TODO(rossberg): is it worth having a non-termination effect?
131 } 117 }
132 118
133 119
134 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) { 120 void AstTyper::VisitReturnStatement(ReturnStatement* stmt) {
135 // Collect type feedback. 121 RECURSE(Visit(stmt->expression()));
122
136 // TODO(rossberg): we only need this for inlining into test contexts... 123 // TODO(rossberg): we only need this for inlining into test contexts...
137 stmt->expression()->RecordToBooleanTypeFeedback(oracle()); 124 stmt->expression()->RecordToBooleanTypeFeedback(oracle());
138
139 RECURSE(Visit(stmt->expression()));
140 // TODO(rossberg): is it worth having a non-termination effect?
141 } 125 }
142 126
143 127
144 void AstTyper::VisitWithStatement(WithStatement* stmt) { 128 void AstTyper::VisitWithStatement(WithStatement* stmt) {
145 RECURSE(stmt->expression()); 129 RECURSE(stmt->expression());
146 RECURSE(stmt->statement()); 130 RECURSE(stmt->statement());
147 } 131 }
148 132
149 133
150 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { 134 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) {
151 RECURSE(Visit(stmt->tag())); 135 RECURSE(Visit(stmt->tag()));
152
153 ZoneList<CaseClause*>* clauses = stmt->cases(); 136 ZoneList<CaseClause*>* clauses = stmt->cases();
154 SwitchStatement::SwitchType switch_type = stmt->switch_type(); 137 SwitchStatement::SwitchType switch_type = stmt->switch_type();
155 Effects local_effects(zone());
156 bool complex_effects = false; // True for label effects or fall-through.
157
158 for (int i = 0; i < clauses->length(); ++i) { 138 for (int i = 0; i < clauses->length(); ++i) {
159 CaseClause* clause = clauses->at(i); 139 CaseClause* clause = clauses->at(i);
160 Effects clause_effects = EnterEffects();
161
162 if (!clause->is_default()) { 140 if (!clause->is_default()) {
163 Expression* label = clause->label(); 141 Expression* label = clause->label();
142 RECURSE(Visit(label));
143
164 SwitchStatement::SwitchType label_switch_type = 144 SwitchStatement::SwitchType label_switch_type =
165 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH : 145 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH :
166 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH : 146 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH :
167 SwitchStatement::GENERIC_SWITCH; 147 SwitchStatement::GENERIC_SWITCH;
168 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) 148 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
169 switch_type = label_switch_type; 149 switch_type = label_switch_type;
170 else if (switch_type != label_switch_type) 150 else if (switch_type != label_switch_type)
171 switch_type = SwitchStatement::GENERIC_SWITCH; 151 switch_type = SwitchStatement::GENERIC_SWITCH;
172
173 RECURSE(Visit(label));
174 if (!clause_effects.IsEmpty()) complex_effects = true;
175 } 152 }
176 153 RECURSE(VisitStatements(clause->statements()));
177 ZoneList<Statement*>* stmts = clause->statements();
178 RECURSE(VisitStatements(stmts));
179 ExitEffects();
180 if (stmts->is_empty() || stmts->last()->IsJump()) {
181 local_effects.Alt(clause_effects);
182 } else {
183 complex_effects = true;
184 }
185 } 154 }
186
187 if (complex_effects) {
188 store_.Forget(); // Reached this in unknown state.
189 } else {
190 store_.Seq(local_effects);
191 }
192
193 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) 155 if (switch_type == SwitchStatement::UNKNOWN_SWITCH)
194 switch_type = SwitchStatement::GENERIC_SWITCH; 156 switch_type = SwitchStatement::GENERIC_SWITCH;
195 stmt->set_switch_type(switch_type); 157 stmt->set_switch_type(switch_type);
196 158
197 // Collect type feedback.
198 // TODO(rossberg): can we eliminate this special case and extra loop? 159 // TODO(rossberg): can we eliminate this special case and extra loop?
199 if (switch_type == SwitchStatement::SMI_SWITCH) { 160 if (switch_type == SwitchStatement::SMI_SWITCH) {
200 for (int i = 0; i < clauses->length(); ++i) { 161 for (int i = 0; i < clauses->length(); ++i) {
201 CaseClause* clause = clauses->at(i); 162 CaseClause* clause = clauses->at(i);
202 if (!clause->is_default()) 163 if (!clause->is_default())
203 clause->RecordTypeFeedback(oracle()); 164 clause->RecordTypeFeedback(oracle());
204 } 165 }
205 } 166 }
206 } 167 }
207 168
208 169
209 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) { 170 void AstTyper::VisitDoWhileStatement(DoWhileStatement* stmt) {
210 // Collect type feedback. 171 RECURSE(Visit(stmt->body()));
172 RECURSE(Visit(stmt->cond()));
173
211 if (!stmt->cond()->ToBooleanIsTrue()) { 174 if (!stmt->cond()->ToBooleanIsTrue()) {
212 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 175 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
213 } 176 }
214
215 // TODO(rossberg): refine the unconditional Forget (here and elsewhere) by
216 // computing the set of variables assigned in only some of the origins of the
217 // control transfer (such as the loop body here).
218 store_.Forget(); // Control may transfer here via looping or 'continue'.
219 RECURSE(Visit(stmt->body()));
220 RECURSE(Visit(stmt->cond()));
221 store_.Forget(); // Control may transfer here via 'break'.
222 } 177 }
223 178
224 179
225 void AstTyper::VisitWhileStatement(WhileStatement* stmt) { 180 void AstTyper::VisitWhileStatement(WhileStatement* stmt) {
226 // Collect type feedback. 181 RECURSE(Visit(stmt->cond()));
182 RECURSE(Visit(stmt->body()));
183
227 if (!stmt->cond()->ToBooleanIsTrue()) { 184 if (!stmt->cond()->ToBooleanIsTrue()) {
228 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 185 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
229 } 186 }
230
231 store_.Forget(); // Control may transfer here via looping or 'continue'.
232 RECURSE(Visit(stmt->cond()));
233 RECURSE(Visit(stmt->body()));
234 store_.Forget(); // Control may transfer here via termination or 'break'.
235 } 187 }
236 188
237 189
238 void AstTyper::VisitForStatement(ForStatement* stmt) { 190 void AstTyper::VisitForStatement(ForStatement* stmt) {
239 if (stmt->init() != NULL) { 191 if (stmt->init() != NULL) {
240 RECURSE(Visit(stmt->init())); 192 RECURSE(Visit(stmt->init()));
241 } 193 }
242 store_.Forget(); // Control may transfer here via looping.
243 if (stmt->cond() != NULL) { 194 if (stmt->cond() != NULL) {
244 // Collect type feedback. 195 RECURSE(Visit(stmt->cond()));
196
245 stmt->cond()->RecordToBooleanTypeFeedback(oracle()); 197 stmt->cond()->RecordToBooleanTypeFeedback(oracle());
246
247 RECURSE(Visit(stmt->cond()));
248 } 198 }
249 RECURSE(Visit(stmt->body())); 199 RECURSE(Visit(stmt->body()));
250 store_.Forget(); // Control may transfer here via 'continue'.
251 if (stmt->next() != NULL) { 200 if (stmt->next() != NULL) {
252 RECURSE(Visit(stmt->next())); 201 RECURSE(Visit(stmt->next()));
253 } 202 }
254 store_.Forget(); // Control may transfer here via termination or 'break'.
255 } 203 }
256 204
257 205
258 void AstTyper::VisitForInStatement(ForInStatement* stmt) { 206 void AstTyper::VisitForInStatement(ForInStatement* stmt) {
259 // Collect type feedback. 207 RECURSE(Visit(stmt->enumerable()));
208 RECURSE(Visit(stmt->body()));
209
260 stmt->RecordTypeFeedback(oracle()); 210 stmt->RecordTypeFeedback(oracle());
261
262 RECURSE(Visit(stmt->enumerable()));
263 store_.Forget(); // Control may transfer here via looping or 'continue'.
264 RECURSE(Visit(stmt->body()));
265 store_.Forget(); // Control may transfer here via 'break'.
266 } 211 }
267 212
268 213
269 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) { 214 void AstTyper::VisitForOfStatement(ForOfStatement* stmt) {
270 RECURSE(Visit(stmt->iterable())); 215 RECURSE(Visit(stmt->iterable()));
271 store_.Forget(); // Control may transfer here via looping or 'continue'.
272 RECURSE(Visit(stmt->body())); 216 RECURSE(Visit(stmt->body()));
273 store_.Forget(); // Control may transfer here via 'break'.
274 } 217 }
275 218
276 219
277 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) { 220 void AstTyper::VisitTryCatchStatement(TryCatchStatement* stmt) {
278 Effects try_effects = EnterEffects();
279 RECURSE(Visit(stmt->try_block())); 221 RECURSE(Visit(stmt->try_block()));
280 ExitEffects();
281 Effects catch_effects = EnterEffects();
282 store_.Forget(); // Control may transfer here via 'throw'.
283 RECURSE(Visit(stmt->catch_block())); 222 RECURSE(Visit(stmt->catch_block()));
284 ExitEffects();
285 try_effects.Alt(catch_effects);
286 store_.Seq(try_effects);
287 // At this point, only variables that were reassigned in the catch block are
288 // still remembered.
289 } 223 }
290 224
291 225
292 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) { 226 void AstTyper::VisitTryFinallyStatement(TryFinallyStatement* stmt) {
293 RECURSE(Visit(stmt->try_block())); 227 RECURSE(Visit(stmt->try_block()));
294 store_.Forget(); // Control may transfer here via 'throw'.
295 RECURSE(Visit(stmt->finally_block())); 228 RECURSE(Visit(stmt->finally_block()));
296 } 229 }
297 230
298 231
299 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) { 232 void AstTyper::VisitDebuggerStatement(DebuggerStatement* stmt) {
300 store_.Forget(); // May do whatever.
301 } 233 }
302 234
303 235
304 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) { 236 void AstTyper::VisitFunctionLiteral(FunctionLiteral* expr) {
305 } 237 }
306 238
307 239
308 void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) { 240 void AstTyper::VisitSharedFunctionInfoLiteral(SharedFunctionInfoLiteral* expr) {
309 } 241 }
310 242
311 243
312 void AstTyper::VisitConditional(Conditional* expr) { 244 void AstTyper::VisitConditional(Conditional* expr) {
313 // Collect type feedback. 245 RECURSE(Visit(expr->condition()));
246 RECURSE(Visit(expr->then_expression()));
247 RECURSE(Visit(expr->else_expression()));
248
314 expr->condition()->RecordToBooleanTypeFeedback(oracle()); 249 expr->condition()->RecordToBooleanTypeFeedback(oracle());
315 250
316 RECURSE(Visit(expr->condition()));
317 Effects then_effects = EnterEffects();
318 RECURSE(Visit(expr->then_expression()));
319 ExitEffects();
320 Effects else_effects = EnterEffects();
321 RECURSE(Visit(expr->else_expression()));
322 ExitEffects();
323 then_effects.Alt(else_effects);
324 store_.Seq(then_effects);
325
326 NarrowType(expr, Bounds::Either( 251 NarrowType(expr, Bounds::Either(
327 expr->then_expression()->bounds(), 252 expr->then_expression()->bounds(),
328 expr->else_expression()->bounds(), isolate_)); 253 expr->else_expression()->bounds(), isolate_));
329 } 254 }
330 255
331 256
332 void AstTyper::VisitVariableProxy(VariableProxy* expr) { 257 void AstTyper::VisitVariableProxy(VariableProxy* expr) {
333 Variable* var = expr->var(); 258 // TODO(rossberg): typing of variables
334 if (var->IsStackAllocated()) {
335 NarrowType(expr, store_.LookupBounds(variable_index(var)));
336 }
337 } 259 }
338 260
339 261
340 void AstTyper::VisitLiteral(Literal* expr) { 262 void AstTyper::VisitLiteral(Literal* expr) {
341 Type* type = Type::Constant(expr->value(), isolate_); 263 Type* type = Type::Constant(expr->value(), isolate_);
342 NarrowType(expr, Bounds(type, isolate_)); 264 NarrowType(expr, Bounds(type, isolate_));
343 } 265 }
344 266
345 267
346 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) { 268 void AstTyper::VisitRegExpLiteral(RegExpLiteral* expr) {
347 NarrowType(expr, Bounds(Type::RegExp(), isolate_)); 269 NarrowType(expr, Bounds(Type::RegExp(), isolate_));
348 } 270 }
349 271
350 272
351 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) { 273 void AstTyper::VisitObjectLiteral(ObjectLiteral* expr) {
352 ZoneList<ObjectLiteral::Property*>* properties = expr->properties(); 274 ZoneList<ObjectLiteral::Property*>* properties = expr->properties();
353 for (int i = 0; i < properties->length(); ++i) { 275 for (int i = 0; i < properties->length(); ++i) {
354 ObjectLiteral::Property* prop = properties->at(i); 276 ObjectLiteral::Property* prop = properties->at(i);
277 RECURSE(Visit(prop->value()));
355 278
356 // Collect type feedback.
357 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL && 279 if ((prop->kind() == ObjectLiteral::Property::MATERIALIZED_LITERAL &&
358 !CompileTimeValue::IsCompileTimeValue(prop->value())) || 280 !CompileTimeValue::IsCompileTimeValue(prop->value())) ||
359 prop->kind() == ObjectLiteral::Property::COMPUTED) { 281 prop->kind() == ObjectLiteral::Property::COMPUTED) {
360 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) { 282 if (prop->key()->value()->IsInternalizedString() && prop->emit_store()) {
361 prop->RecordTypeFeedback(oracle()); 283 prop->RecordTypeFeedback(oracle());
362 } 284 }
363 } 285 }
364
365 RECURSE(Visit(prop->value()));
366 } 286 }
367 287
368 NarrowType(expr, Bounds(Type::Object(), isolate_)); 288 NarrowType(expr, Bounds(Type::Object(), isolate_));
369 } 289 }
370 290
371 291
372 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) { 292 void AstTyper::VisitArrayLiteral(ArrayLiteral* expr) {
373 ZoneList<Expression*>* values = expr->values(); 293 ZoneList<Expression*>* values = expr->values();
374 for (int i = 0; i < values->length(); ++i) { 294 for (int i = 0; i < values->length(); ++i) {
375 Expression* value = values->at(i); 295 Expression* value = values->at(i);
376 RECURSE(Visit(value)); 296 RECURSE(Visit(value));
377 } 297 }
378 298
379 NarrowType(expr, Bounds(Type::Array(), isolate_)); 299 NarrowType(expr, Bounds(Type::Array(), isolate_));
380 } 300 }
381 301
382 302
383 void AstTyper::VisitAssignment(Assignment* expr) { 303 void AstTyper::VisitAssignment(Assignment* expr) {
384 // TODO(rossberg): Can we clean this up? 304 // TODO(rossberg): Can we clean this up?
385 if (expr->is_compound()) { 305 if (expr->is_compound()) {
386 // Collect type feedback. 306 RECURSE(Visit(expr->binary_operation()));
307
387 Expression* target = expr->target(); 308 Expression* target = expr->target();
388 Property* prop = target->AsProperty(); 309 Property* prop = target->AsProperty();
389 if (prop != NULL) { 310 if (prop != NULL) {
390 prop->RecordTypeFeedback(oracle(), zone()); 311 prop->RecordTypeFeedback(oracle(), zone());
391 if (!prop->key()->IsPropertyName()) { // i.e., keyed 312 if (!prop->key()->IsPropertyName()) { // i.e., keyed
392 expr->RecordTypeFeedback(oracle(), zone()); 313 expr->RecordTypeFeedback(oracle(), zone());
393 } 314 }
394 } 315 }
395 316
396 RECURSE(Visit(expr->binary_operation()));
397
398 NarrowType(expr, expr->binary_operation()->bounds()); 317 NarrowType(expr, expr->binary_operation()->bounds());
399 } else { 318 } else {
400 // Collect type feedback. 319 RECURSE(Visit(expr->target()));
401 if (expr->target()->IsProperty()) { 320 RECURSE(Visit(expr->value()));
321
322 if (expr->target()->AsProperty()) {
402 expr->RecordTypeFeedback(oracle(), zone()); 323 expr->RecordTypeFeedback(oracle(), zone());
403 } 324 }
404 325
405 RECURSE(Visit(expr->target()));
406 RECURSE(Visit(expr->value()));
407
408 NarrowType(expr, expr->value()->bounds()); 326 NarrowType(expr, expr->value()->bounds());
409 } 327 }
410 328 // TODO(rossberg): handle target variables
411 VariableProxy* proxy = expr->target()->AsVariableProxy();
412 if (proxy != NULL && proxy->var()->IsStackAllocated()) {
413 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds()));
414 }
415 } 329 }
416 330
417 331
418 void AstTyper::VisitYield(Yield* expr) { 332 void AstTyper::VisitYield(Yield* expr) {
419 RECURSE(Visit(expr->generator_object())); 333 RECURSE(Visit(expr->generator_object()));
420 RECURSE(Visit(expr->expression())); 334 RECURSE(Visit(expr->expression()));
421 335
422 // We don't know anything about the result type. 336 // We don't know anything about the type.
423 } 337 }
424 338
425 339
426 void AstTyper::VisitThrow(Throw* expr) { 340 void AstTyper::VisitThrow(Throw* expr) {
427 RECURSE(Visit(expr->exception())); 341 RECURSE(Visit(expr->exception()));
428 // TODO(rossberg): is it worth having a non-termination effect?
429 342
430 NarrowType(expr, Bounds(Type::None(), isolate_)); 343 NarrowType(expr, Bounds(Type::None(), isolate_));
431 } 344 }
432 345
433 346
434 void AstTyper::VisitProperty(Property* expr) { 347 void AstTyper::VisitProperty(Property* expr) {
435 // Collect type feedback.
436 expr->RecordTypeFeedback(oracle(), zone());
437
438 RECURSE(Visit(expr->obj())); 348 RECURSE(Visit(expr->obj()));
439 RECURSE(Visit(expr->key())); 349 RECURSE(Visit(expr->key()));
440 350
441 // We don't know anything about the result type. 351 expr->RecordTypeFeedback(oracle(), zone());
352
353 // We don't know anything about the type.
442 } 354 }
443 355
444 356
445 void AstTyper::VisitCall(Call* expr) { 357 void AstTyper::VisitCall(Call* expr) {
446 // Collect type feedback.
447 Expression* callee = expr->expression();
448 Property* prop = callee->AsProperty();
449 if (prop != NULL) {
450 if (prop->key()->IsPropertyName())
451 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
452 } else {
453 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
454 }
455
456 RECURSE(Visit(expr->expression())); 358 RECURSE(Visit(expr->expression()));
457 ZoneList<Expression*>* args = expr->arguments(); 359 ZoneList<Expression*>* args = expr->arguments();
458 for (int i = 0; i < args->length(); ++i) { 360 for (int i = 0; i < args->length(); ++i) {
459 Expression* arg = args->at(i); 361 Expression* arg = args->at(i);
460 RECURSE(Visit(arg)); 362 RECURSE(Visit(arg));
461 } 363 }
462 364
463 VariableProxy* proxy = expr->expression()->AsVariableProxy(); 365 Expression* callee = expr->expression();
464 if (proxy != NULL && proxy->var()->is_possibly_eval(isolate())) { 366 Property* prop = callee->AsProperty();
465 store_.Forget(); // Eval could do whatever to local variables. 367 if (prop != NULL) {
368 if (prop->key()->IsPropertyName())
369 expr->RecordTypeFeedback(oracle(), CALL_AS_METHOD);
370 } else {
371 expr->RecordTypeFeedback(oracle(), CALL_AS_FUNCTION);
466 } 372 }
467 373
468 // We don't know anything about the result type. 374 // We don't know anything about the type.
469 } 375 }
470 376
471 377
472 void AstTyper::VisitCallNew(CallNew* expr) { 378 void AstTyper::VisitCallNew(CallNew* expr) {
473 // Collect type feedback.
474 expr->RecordTypeFeedback(oracle());
475
476 RECURSE(Visit(expr->expression())); 379 RECURSE(Visit(expr->expression()));
477 ZoneList<Expression*>* args = expr->arguments(); 380 ZoneList<Expression*>* args = expr->arguments();
478 for (int i = 0; i < args->length(); ++i) { 381 for (int i = 0; i < args->length(); ++i) {
479 Expression* arg = args->at(i); 382 Expression* arg = args->at(i);
480 RECURSE(Visit(arg)); 383 RECURSE(Visit(arg));
481 } 384 }
482 385
483 // We don't know anything about the result type. 386 expr->RecordTypeFeedback(oracle());
387
388 // We don't know anything about the type.
484 } 389 }
485 390
486 391
487 void AstTyper::VisitCallRuntime(CallRuntime* expr) { 392 void AstTyper::VisitCallRuntime(CallRuntime* expr) {
488 ZoneList<Expression*>* args = expr->arguments(); 393 ZoneList<Expression*>* args = expr->arguments();
489 for (int i = 0; i < args->length(); ++i) { 394 for (int i = 0; i < args->length(); ++i) {
490 Expression* arg = args->at(i); 395 Expression* arg = args->at(i);
491 RECURSE(Visit(arg)); 396 RECURSE(Visit(arg));
492 } 397 }
493 398
494 // We don't know anything about the result type. 399 // We don't know anything about the type.
495 } 400 }
496 401
497 402
498 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) { 403 void AstTyper::VisitUnaryOperation(UnaryOperation* expr) {
404 RECURSE(Visit(expr->expression()));
405
499 // Collect type feedback. 406 // Collect type feedback.
500 if (expr->op() == Token::NOT) { 407 if (expr->op() == Token::NOT) {
501 // TODO(rossberg): only do in test or value context. 408 // TODO(rossberg): only do in test or value context.
502 expr->expression()->RecordToBooleanTypeFeedback(oracle()); 409 expr->expression()->RecordToBooleanTypeFeedback(oracle());
503 } 410 }
504 411
505 RECURSE(Visit(expr->expression()));
506
507 switch (expr->op()) { 412 switch (expr->op()) {
508 case Token::NOT: 413 case Token::NOT:
509 case Token::DELETE: 414 case Token::DELETE:
510 NarrowType(expr, Bounds(Type::Boolean(), isolate_)); 415 NarrowType(expr, Bounds(Type::Boolean(), isolate_));
511 break; 416 break;
512 case Token::VOID: 417 case Token::VOID:
513 NarrowType(expr, Bounds(Type::Undefined(), isolate_)); 418 NarrowType(expr, Bounds(Type::Undefined(), isolate_));
514 break; 419 break;
515 case Token::TYPEOF: 420 case Token::TYPEOF:
516 NarrowType(expr, Bounds(Type::InternalizedString(), isolate_)); 421 NarrowType(expr, Bounds(Type::InternalizedString(), isolate_));
517 break; 422 break;
518 default: 423 default:
519 UNREACHABLE(); 424 UNREACHABLE();
520 } 425 }
521 } 426 }
522 427
523 428
524 void AstTyper::VisitCountOperation(CountOperation* expr) { 429 void AstTyper::VisitCountOperation(CountOperation* expr) {
525 // Collect type feedback. 430 RECURSE(Visit(expr->expression()));
431
526 expr->RecordTypeFeedback(oracle(), zone()); 432 expr->RecordTypeFeedback(oracle(), zone());
527 Property* prop = expr->expression()->AsProperty(); 433 Property* prop = expr->expression()->AsProperty();
528 if (prop != NULL) { 434 if (prop != NULL) {
529 prop->RecordTypeFeedback(oracle(), zone()); 435 prop->RecordTypeFeedback(oracle(), zone());
530 } 436 }
531 437
532 RECURSE(Visit(expr->expression()));
533
534 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); 438 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
535
536 VariableProxy* proxy = expr->expression()->AsVariableProxy();
537 if (proxy != NULL && proxy->var()->IsStackAllocated()) {
538 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds()));
539 }
540 } 439 }
541 440
542 441
543 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { 442 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) {
443 RECURSE(Visit(expr->left()));
444 RECURSE(Visit(expr->right()));
445
544 // Collect type feedback. 446 // Collect type feedback.
545 Handle<Type> type, left_type, right_type; 447 Handle<Type> type, left_type, right_type;
546 Maybe<int> fixed_right_arg; 448 Maybe<int> fixed_right_arg;
547 oracle()->BinaryType(expr->BinaryOperationFeedbackId(), 449 oracle()->BinaryType(expr->BinaryOperationFeedbackId(),
548 &left_type, &right_type, &type, &fixed_right_arg); 450 &left_type, &right_type, &type, &fixed_right_arg);
549 NarrowLowerType(expr, type); 451 NarrowLowerType(expr, type);
550 NarrowLowerType(expr->left(), left_type); 452 NarrowLowerType(expr->left(), left_type);
551 NarrowLowerType(expr->right(), right_type); 453 NarrowLowerType(expr->right(), right_type);
552 expr->set_fixed_right_arg(fixed_right_arg); 454 expr->set_fixed_right_arg(fixed_right_arg);
553 if (expr->op() == Token::OR || expr->op() == Token::AND) { 455 if (expr->op() == Token::OR || expr->op() == Token::AND) {
554 expr->left()->RecordToBooleanTypeFeedback(oracle()); 456 expr->left()->RecordToBooleanTypeFeedback(oracle());
555 } 457 }
556 458
557 switch (expr->op()) { 459 switch (expr->op()) {
558 case Token::COMMA: 460 case Token::COMMA:
559 RECURSE(Visit(expr->left()));
560 RECURSE(Visit(expr->right()));
561 NarrowType(expr, expr->right()->bounds()); 461 NarrowType(expr, expr->right()->bounds());
562 break; 462 break;
563 case Token::OR: 463 case Token::OR:
564 case Token::AND: { 464 case Token::AND:
565 Effects left_effects = EnterEffects();
566 RECURSE(Visit(expr->left()));
567 ExitEffects();
568 Effects right_effects = EnterEffects();
569 RECURSE(Visit(expr->right()));
570 ExitEffects();
571 left_effects.Alt(right_effects);
572 store_.Seq(left_effects);
573
574 NarrowType(expr, Bounds::Either( 465 NarrowType(expr, Bounds::Either(
575 expr->left()->bounds(), expr->right()->bounds(), isolate_)); 466 expr->left()->bounds(), expr->right()->bounds(), isolate_));
576 break; 467 break;
577 }
578 case Token::BIT_OR: 468 case Token::BIT_OR:
579 case Token::BIT_AND: { 469 case Token::BIT_AND: {
580 RECURSE(Visit(expr->left()));
581 RECURSE(Visit(expr->right()));
582 Type* upper = Type::Union( 470 Type* upper = Type::Union(
583 expr->left()->bounds().upper, expr->right()->bounds().upper); 471 expr->left()->bounds().upper, expr->right()->bounds().upper);
584 if (!upper->Is(Type::Signed32())) upper = Type::Signed32(); 472 if (!upper->Is(Type::Signed32())) upper = Type::Signed32();
585 NarrowType(expr, Bounds(Type::Smi(), upper, isolate_)); 473 NarrowType(expr, Bounds(Type::Smi(), upper, isolate_));
586 break; 474 break;
587 } 475 }
588 case Token::BIT_XOR: 476 case Token::BIT_XOR:
589 case Token::SHL: 477 case Token::SHL:
590 case Token::SAR: 478 case Token::SAR:
591 RECURSE(Visit(expr->left()));
592 RECURSE(Visit(expr->right()));
593 NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_)); 479 NarrowType(expr, Bounds(Type::Smi(), Type::Signed32(), isolate_));
594 break; 480 break;
595 case Token::SHR: 481 case Token::SHR:
596 RECURSE(Visit(expr->left()));
597 RECURSE(Visit(expr->right()));
598 NarrowType(expr, Bounds(Type::Smi(), Type::Unsigned32(), isolate_)); 482 NarrowType(expr, Bounds(Type::Smi(), Type::Unsigned32(), isolate_));
599 break; 483 break;
600 case Token::ADD: { 484 case Token::ADD: {
601 RECURSE(Visit(expr->left()));
602 RECURSE(Visit(expr->right()));
603 Bounds l = expr->left()->bounds(); 485 Bounds l = expr->left()->bounds();
604 Bounds r = expr->right()->bounds(); 486 Bounds r = expr->right()->bounds();
605 Type* lower = 487 Type* lower =
606 l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ? 488 l.lower->Is(Type::Number()) && r.lower->Is(Type::Number()) ?
607 Type::Smi() : 489 Type::Smi() :
608 l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ? 490 l.lower->Is(Type::String()) || r.lower->Is(Type::String()) ?
609 Type::String() : Type::None(); 491 Type::String() : Type::None();
610 Type* upper = 492 Type* upper =
611 l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ? 493 l.upper->Is(Type::Number()) && r.upper->Is(Type::Number()) ?
612 Type::Number() : 494 Type::Number() :
613 l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ? 495 l.upper->Is(Type::String()) || r.upper->Is(Type::String()) ?
614 Type::String() : Type::NumberOrString(); 496 Type::String() : Type::NumberOrString();
615 NarrowType(expr, Bounds(lower, upper, isolate_)); 497 NarrowType(expr, Bounds(lower, upper, isolate_));
616 break; 498 break;
617 } 499 }
618 case Token::SUB: 500 case Token::SUB:
619 case Token::MUL: 501 case Token::MUL:
620 case Token::DIV: 502 case Token::DIV:
621 case Token::MOD: 503 case Token::MOD:
622 RECURSE(Visit(expr->left()));
623 RECURSE(Visit(expr->right()));
624 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); 504 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_));
625 break; 505 break;
626 default: 506 default:
627 UNREACHABLE(); 507 UNREACHABLE();
628 } 508 }
629 } 509 }
630 510
631 511
632 void AstTyper::VisitCompareOperation(CompareOperation* expr) { 512 void AstTyper::VisitCompareOperation(CompareOperation* expr) {
513 RECURSE(Visit(expr->left()));
514 RECURSE(Visit(expr->right()));
515
633 // Collect type feedback. 516 // Collect type feedback.
634 Handle<Type> left_type, right_type, combined_type; 517 Handle<Type> left_type, right_type, combined_type;
635 oracle()->CompareType(expr->CompareOperationFeedbackId(), 518 oracle()->CompareType(expr->CompareOperationFeedbackId(),
636 &left_type, &right_type, &combined_type); 519 &left_type, &right_type, &combined_type);
637 NarrowLowerType(expr->left(), left_type); 520 NarrowLowerType(expr->left(), left_type);
638 NarrowLowerType(expr->right(), right_type); 521 NarrowLowerType(expr->right(), right_type);
639 expr->set_combined_type(combined_type); 522 expr->set_combined_type(combined_type);
640 523
641 RECURSE(Visit(expr->left()));
642 RECURSE(Visit(expr->right()));
643
644 NarrowType(expr, Bounds(Type::Boolean(), isolate_)); 524 NarrowType(expr, Bounds(Type::Boolean(), isolate_));
645 } 525 }
646 526
647 527
648 void AstTyper::VisitThisFunction(ThisFunction* expr) { 528 void AstTyper::VisitThisFunction(ThisFunction* expr) {
649 } 529 }
650 530
651 531
652 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) { 532 void AstTyper::VisitDeclarations(ZoneList<Declaration*>* decls) {
653 for (int i = 0; i < decls->length(); ++i) { 533 for (int i = 0; i < decls->length(); ++i) {
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
697 void AstTyper::VisitModuleUrl(ModuleUrl* module) { 577 void AstTyper::VisitModuleUrl(ModuleUrl* module) {
698 } 578 }
699 579
700 580
701 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { 581 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) {
702 RECURSE(Visit(stmt->body())); 582 RECURSE(Visit(stmt->body()));
703 } 583 }
704 584
705 585
706 } } // namespace v8::internal 586 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/typing.h ('k') | src/version.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698