OLD | NEW |
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 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 ASSERT(!HasStackOverflow()); \ | 73 ASSERT(!HasStackOverflow()); \ |
74 call; \ | 74 call; \ |
75 if (HasStackOverflow()) return; \ | 75 if (HasStackOverflow()) return; \ |
76 } while (false) | 76 } while (false) |
77 | 77 |
78 | 78 |
79 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) { | 79 void AstTyper::VisitStatements(ZoneList<Statement*>* stmts) { |
80 for (int i = 0; i < stmts->length(); ++i) { | 80 for (int i = 0; i < stmts->length(); ++i) { |
81 Statement* stmt = stmts->at(i); | 81 Statement* stmt = stmts->at(i); |
82 RECURSE(Visit(stmt)); | 82 RECURSE(Visit(stmt)); |
| 83 if (stmt->IsJump()) break; |
83 } | 84 } |
84 } | 85 } |
85 | 86 |
86 | 87 |
87 void AstTyper::VisitBlock(Block* stmt) { | 88 void AstTyper::VisitBlock(Block* stmt) { |
88 RECURSE(VisitStatements(stmt->statements())); | 89 RECURSE(VisitStatements(stmt->statements())); |
89 if (stmt->labels() != NULL) { | 90 if (stmt->labels() != NULL) { |
90 store_.Forget(); // Control may transfer here via 'break l'. | 91 store_.Forget(); // Control may transfer here via 'break l'. |
91 } | 92 } |
92 } | 93 } |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 RECURSE(stmt->expression()); | 145 RECURSE(stmt->expression()); |
145 RECURSE(stmt->statement()); | 146 RECURSE(stmt->statement()); |
146 } | 147 } |
147 | 148 |
148 | 149 |
149 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { | 150 void AstTyper::VisitSwitchStatement(SwitchStatement* stmt) { |
150 RECURSE(Visit(stmt->tag())); | 151 RECURSE(Visit(stmt->tag())); |
151 | 152 |
152 ZoneList<CaseClause*>* clauses = stmt->cases(); | 153 ZoneList<CaseClause*>* clauses = stmt->cases(); |
153 SwitchStatement::SwitchType switch_type = stmt->switch_type(); | 154 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 |
154 for (int i = 0; i < clauses->length(); ++i) { | 158 for (int i = 0; i < clauses->length(); ++i) { |
155 CaseClause* clause = clauses->at(i); | 159 CaseClause* clause = clauses->at(i); |
| 160 Effects clause_effects = EnterEffects(); |
| 161 |
156 if (!clause->is_default()) { | 162 if (!clause->is_default()) { |
157 Expression* label = clause->label(); | 163 Expression* label = clause->label(); |
158 SwitchStatement::SwitchType label_switch_type = | 164 SwitchStatement::SwitchType label_switch_type = |
159 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH : | 165 label->IsSmiLiteral() ? SwitchStatement::SMI_SWITCH : |
160 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH : | 166 label->IsStringLiteral() ? SwitchStatement::STRING_SWITCH : |
161 SwitchStatement::GENERIC_SWITCH; | 167 SwitchStatement::GENERIC_SWITCH; |
162 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) | 168 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) |
163 switch_type = label_switch_type; | 169 switch_type = label_switch_type; |
164 else if (switch_type != label_switch_type) | 170 else if (switch_type != label_switch_type) |
165 switch_type = SwitchStatement::GENERIC_SWITCH; | 171 switch_type = SwitchStatement::GENERIC_SWITCH; |
166 | 172 |
167 RECURSE(Visit(label)); | 173 RECURSE(Visit(label)); |
| 174 if (!clause_effects.IsEmpty()) complex_effects = true; |
168 } | 175 } |
169 RECURSE(VisitStatements(clause->statements())); | 176 |
| 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 } |
170 } | 185 } |
171 | 186 |
172 // TODO(rossberg): handle switch effects | 187 if (complex_effects) { |
173 store_.Forget(); | 188 store_.Forget(); // Reached this in unknown state. |
| 189 } else { |
| 190 store_.Seq(local_effects); |
| 191 } |
174 | 192 |
175 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) | 193 if (switch_type == SwitchStatement::UNKNOWN_SWITCH) |
176 switch_type = SwitchStatement::GENERIC_SWITCH; | 194 switch_type = SwitchStatement::GENERIC_SWITCH; |
177 stmt->set_switch_type(switch_type); | 195 stmt->set_switch_type(switch_type); |
178 | 196 |
179 // Collect type feedback. | 197 // Collect type feedback. |
180 // TODO(rossberg): can we eliminate this special case and extra loop? | 198 // TODO(rossberg): can we eliminate this special case and extra loop? |
181 if (switch_type == SwitchStatement::SMI_SWITCH) { | 199 if (switch_type == SwitchStatement::SMI_SWITCH) { |
182 for (int i = 0; i < clauses->length(); ++i) { | 200 for (int i = 0; i < clauses->length(); ++i) { |
183 CaseClause* clause = clauses->at(i); | 201 CaseClause* clause = clauses->at(i); |
(...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
372 if (!prop->key()->IsPropertyName()) { // i.e., keyed | 390 if (!prop->key()->IsPropertyName()) { // i.e., keyed |
373 expr->RecordTypeFeedback(oracle(), zone()); | 391 expr->RecordTypeFeedback(oracle(), zone()); |
374 } | 392 } |
375 } | 393 } |
376 | 394 |
377 RECURSE(Visit(expr->binary_operation())); | 395 RECURSE(Visit(expr->binary_operation())); |
378 | 396 |
379 NarrowType(expr, expr->binary_operation()->bounds()); | 397 NarrowType(expr, expr->binary_operation()->bounds()); |
380 } else { | 398 } else { |
381 // Collect type feedback. | 399 // Collect type feedback. |
382 if (expr->target()->AsProperty()) { | 400 if (expr->target()->IsProperty()) { |
383 expr->RecordTypeFeedback(oracle(), zone()); | 401 expr->RecordTypeFeedback(oracle(), zone()); |
384 } | 402 } |
385 | 403 |
386 RECURSE(Visit(expr->target())); | 404 RECURSE(Visit(expr->target())); |
387 RECURSE(Visit(expr->value())); | 405 RECURSE(Visit(expr->value())); |
388 | 406 |
389 NarrowType(expr, expr->value()->bounds()); | 407 NarrowType(expr, expr->value()->bounds()); |
390 } | 408 } |
391 | 409 |
392 if (expr->target()->AsVariableProxy()) { | 410 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
393 Variable* var = expr->target()->AsVariableProxy()->var(); | 411 if (proxy != NULL && proxy->var()->IsStackAllocated()) { |
394 if (var->IsStackAllocated()) { | 412 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); |
395 store_.Seq(variable_index(var), Effect(expr->bounds())); | |
396 } | |
397 } | 413 } |
398 } | 414 } |
399 | 415 |
400 | 416 |
401 void AstTyper::VisitYield(Yield* expr) { | 417 void AstTyper::VisitYield(Yield* expr) { |
402 RECURSE(Visit(expr->generator_object())); | 418 RECURSE(Visit(expr->generator_object())); |
403 RECURSE(Visit(expr->expression())); | 419 RECURSE(Visit(expr->expression())); |
404 | 420 |
405 // We don't know anything about the result type. | 421 // We don't know anything about the result type. |
406 } | 422 } |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 expr->RecordTypeFeedback(oracle(), zone()); | 537 expr->RecordTypeFeedback(oracle(), zone()); |
522 Property* prop = expr->expression()->AsProperty(); | 538 Property* prop = expr->expression()->AsProperty(); |
523 if (prop != NULL) { | 539 if (prop != NULL) { |
524 prop->RecordTypeFeedback(oracle(), zone()); | 540 prop->RecordTypeFeedback(oracle(), zone()); |
525 } | 541 } |
526 | 542 |
527 RECURSE(Visit(expr->expression())); | 543 RECURSE(Visit(expr->expression())); |
528 | 544 |
529 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); | 545 NarrowType(expr, Bounds(Type::Smi(), Type::Number(), isolate_)); |
530 | 546 |
531 if (expr->expression()->AsVariableProxy()) { | 547 VariableProxy* proxy = expr->expression()->AsVariableProxy(); |
532 Variable* var = expr->expression()->AsVariableProxy()->var(); | 548 if (proxy != NULL && proxy->var()->IsStackAllocated()) { |
533 if (var->IsStackAllocated()) { | 549 store_.Seq(variable_index(proxy->var()), Effect(expr->bounds())); |
534 store_.Seq(variable_index(var), Effect(expr->bounds())); | |
535 } | |
536 } | 550 } |
537 } | 551 } |
538 | 552 |
539 | 553 |
540 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { | 554 void AstTyper::VisitBinaryOperation(BinaryOperation* expr) { |
541 // Collect type feedback. | 555 // Collect type feedback. |
542 Handle<Type> type, left_type, right_type; | 556 Handle<Type> type, left_type, right_type; |
543 Maybe<int> fixed_right_arg; | 557 Maybe<int> fixed_right_arg; |
544 oracle()->BinaryType(expr->BinaryOperationFeedbackId(), | 558 oracle()->BinaryType(expr->BinaryOperationFeedbackId(), |
545 &left_type, &right_type, &type, &fixed_right_arg); | 559 &left_type, &right_type, &type, &fixed_right_arg); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
694 void AstTyper::VisitModuleUrl(ModuleUrl* module) { | 708 void AstTyper::VisitModuleUrl(ModuleUrl* module) { |
695 } | 709 } |
696 | 710 |
697 | 711 |
698 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { | 712 void AstTyper::VisitModuleStatement(ModuleStatement* stmt) { |
699 RECURSE(Visit(stmt->body())); | 713 RECURSE(Visit(stmt->body())); |
700 } | 714 } |
701 | 715 |
702 | 716 |
703 } } // namespace v8::internal | 717 } } // namespace v8::internal |
OLD | NEW |