| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/parsing/rewriter.h" | 5 #include "src/parsing/rewriter.h" |
| 6 | 6 |
| 7 #include "src/ast/ast.h" | 7 #include "src/ast/ast.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/parsing/parser.h" | 9 #include "src/parsing/parser.h" |
| 10 | 10 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 44 | 44 |
| 45 Zone* zone() { return zone_; } | 45 Zone* zone() { return zone_; } |
| 46 Scope* scope() { return scope_; } | 46 Scope* scope() { return scope_; } |
| 47 AstNodeFactory* factory() { return &factory_; } | 47 AstNodeFactory* factory() { return &factory_; } |
| 48 | 48 |
| 49 // Returns ".result = value" | 49 // Returns ".result = value" |
| 50 Expression* SetResult(Expression* value) { | 50 Expression* SetResult(Expression* value) { |
| 51 result_assigned_ = true; | 51 result_assigned_ = true; |
| 52 VariableProxy* result_proxy = factory()->NewVariableProxy(result_); | 52 VariableProxy* result_proxy = factory()->NewVariableProxy(result_); |
| 53 return factory()->NewAssignment(Token::ASSIGN, result_proxy, value, | 53 return factory()->NewAssignment(Token::ASSIGN, result_proxy, value, |
| 54 RelocInfo::kNoPosition); | 54 kNoSourcePosition); |
| 55 } | 55 } |
| 56 | 56 |
| 57 // Inserts '.result = undefined' in front of the given statement. | 57 // Inserts '.result = undefined' in front of the given statement. |
| 58 Statement* AssignUndefinedBefore(Statement* s); | 58 Statement* AssignUndefinedBefore(Statement* s); |
| 59 | 59 |
| 60 private: | 60 private: |
| 61 Variable* result_; | 61 Variable* result_; |
| 62 | 62 |
| 63 // We are not tracking result usage via the result_'s use | 63 // We are not tracking result usage via the result_'s use |
| 64 // counts (we leave the accurate computation to the | 64 // counts (we leave the accurate computation to the |
| (...skipping 21 matching lines...) Expand all Loading... |
| 86 #undef DEF_VISIT | 86 #undef DEF_VISIT |
| 87 | 87 |
| 88 void VisitIterationStatement(IterationStatement* stmt); | 88 void VisitIterationStatement(IterationStatement* stmt); |
| 89 | 89 |
| 90 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); | 90 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); |
| 91 }; | 91 }; |
| 92 | 92 |
| 93 | 93 |
| 94 Statement* Processor::AssignUndefinedBefore(Statement* s) { | 94 Statement* Processor::AssignUndefinedBefore(Statement* s) { |
| 95 Expression* result_proxy = factory()->NewVariableProxy(result_); | 95 Expression* result_proxy = factory()->NewVariableProxy(result_); |
| 96 Expression* undef = factory()->NewUndefinedLiteral(RelocInfo::kNoPosition); | 96 Expression* undef = factory()->NewUndefinedLiteral(kNoSourcePosition); |
| 97 Expression* assignment = factory()->NewAssignment( | 97 Expression* assignment = factory()->NewAssignment(Token::ASSIGN, result_proxy, |
| 98 Token::ASSIGN, result_proxy, undef, RelocInfo::kNoPosition); | 98 undef, kNoSourcePosition); |
| 99 Block* b = factory()->NewBlock(NULL, 2, false, RelocInfo::kNoPosition); | 99 Block* b = factory()->NewBlock(NULL, 2, false, kNoSourcePosition); |
| 100 b->statements()->Add( | 100 b->statements()->Add( |
| 101 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), | 101 factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone()); |
| 102 zone()); | |
| 103 b->statements()->Add(s, zone()); | 102 b->statements()->Add(s, zone()); |
| 104 return b; | 103 return b; |
| 105 } | 104 } |
| 106 | 105 |
| 107 | 106 |
| 108 void Processor::Process(ZoneList<Statement*>* statements) { | 107 void Processor::Process(ZoneList<Statement*>* statements) { |
| 109 for (int i = statements->length() - 1; i >= 0; --i) { | 108 for (int i = statements->length() - 1; i >= 0; --i) { |
| 110 Visit(statements->at(i)); | 109 Visit(statements->at(i)); |
| 111 statements->Set(i, replacement_); | 110 statements->Set(i, replacement_); |
| 112 } | 111 } |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 { // Save .result value at the beginning of the finally block and restore it | 224 { // Save .result value at the beginning of the finally block and restore it |
| 226 // at the end again: ".backup = .result; ...; .result = .backup" | 225 // at the end again: ".backup = .result; ...; .result = .backup" |
| 227 // This is necessary because the finally block does not normally contribute | 226 // This is necessary because the finally block does not normally contribute |
| 228 // to the completion value. | 227 // to the completion value. |
| 229 CHECK(scope() != nullptr); | 228 CHECK(scope() != nullptr); |
| 230 Variable* backup = scope()->NewTemporary( | 229 Variable* backup = scope()->NewTemporary( |
| 231 factory()->ast_value_factory()->dot_result_string()); | 230 factory()->ast_value_factory()->dot_result_string()); |
| 232 Expression* backup_proxy = factory()->NewVariableProxy(backup); | 231 Expression* backup_proxy = factory()->NewVariableProxy(backup); |
| 233 Expression* result_proxy = factory()->NewVariableProxy(result_); | 232 Expression* result_proxy = factory()->NewVariableProxy(result_); |
| 234 Expression* save = factory()->NewAssignment( | 233 Expression* save = factory()->NewAssignment( |
| 235 Token::ASSIGN, backup_proxy, result_proxy, RelocInfo::kNoPosition); | 234 Token::ASSIGN, backup_proxy, result_proxy, kNoSourcePosition); |
| 236 Expression* restore = factory()->NewAssignment( | 235 Expression* restore = factory()->NewAssignment( |
| 237 Token::ASSIGN, result_proxy, backup_proxy, RelocInfo::kNoPosition); | 236 Token::ASSIGN, result_proxy, backup_proxy, kNoSourcePosition); |
| 238 node->finally_block()->statements()->InsertAt( | 237 node->finally_block()->statements()->InsertAt( |
| 239 0, factory()->NewExpressionStatement(save, RelocInfo::kNoPosition), | 238 0, factory()->NewExpressionStatement(save, kNoSourcePosition), zone()); |
| 240 zone()); | |
| 241 node->finally_block()->statements()->Add( | 239 node->finally_block()->statements()->Add( |
| 242 factory()->NewExpressionStatement(restore, RelocInfo::kNoPosition), | 240 factory()->NewExpressionStatement(restore, kNoSourcePosition), zone()); |
| 243 zone()); | |
| 244 } | 241 } |
| 245 is_set_ = set_after; | 242 is_set_ = set_after; |
| 246 Visit(node->try_block()); | 243 Visit(node->try_block()); |
| 247 node->set_try_block(replacement_->AsBlock()); | 244 node->set_try_block(replacement_->AsBlock()); |
| 248 replacement_ = node; | 245 replacement_ = node; |
| 249 | 246 |
| 250 if (!is_set_) { | 247 if (!is_set_) { |
| 251 is_set_ = true; | 248 is_set_ = true; |
| 252 replacement_ = AssignUndefinedBefore(node); | 249 replacement_ = AssignUndefinedBefore(node); |
| 253 } | 250 } |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 Variable* result = | 345 Variable* result = |
| 349 scope->NewTemporary(info->ast_value_factory()->dot_result_string()); | 346 scope->NewTemporary(info->ast_value_factory()->dot_result_string()); |
| 350 // The name string must be internalized at this point. | 347 // The name string must be internalized at this point. |
| 351 DCHECK(!result->name().is_null()); | 348 DCHECK(!result->name().is_null()); |
| 352 Processor processor(info->isolate(), scope, result, | 349 Processor processor(info->isolate(), scope, result, |
| 353 info->ast_value_factory()); | 350 info->ast_value_factory()); |
| 354 processor.Process(body); | 351 processor.Process(body); |
| 355 if (processor.HasStackOverflow()) return false; | 352 if (processor.HasStackOverflow()) return false; |
| 356 | 353 |
| 357 if (processor.result_assigned()) { | 354 if (processor.result_assigned()) { |
| 358 int pos = RelocInfo::kNoPosition; | 355 int pos = kNoSourcePosition; |
| 359 VariableProxy* result_proxy = | 356 VariableProxy* result_proxy = |
| 360 processor.factory()->NewVariableProxy(result, pos); | 357 processor.factory()->NewVariableProxy(result, pos); |
| 361 Statement* result_statement = | 358 Statement* result_statement = |
| 362 processor.factory()->NewReturnStatement(result_proxy, pos); | 359 processor.factory()->NewReturnStatement(result_proxy, pos); |
| 363 body->Add(result_statement, info->zone()); | 360 body->Add(result_statement, info->zone()); |
| 364 } | 361 } |
| 365 } | 362 } |
| 366 | 363 |
| 367 return true; | 364 return true; |
| 368 } | 365 } |
| 369 | 366 |
| 370 | 367 |
| 371 bool Rewriter::Rewrite(Parser* parser, DoExpression* expr, | 368 bool Rewriter::Rewrite(Parser* parser, DoExpression* expr, |
| 372 AstValueFactory* factory) { | 369 AstValueFactory* factory) { |
| 373 Block* block = expr->block(); | 370 Block* block = expr->block(); |
| 374 Scope* scope = block->scope(); | 371 Scope* scope = block->scope(); |
| 375 ZoneList<Statement*>* body = block->statements(); | 372 ZoneList<Statement*>* body = block->statements(); |
| 376 VariableProxy* result = expr->result(); | 373 VariableProxy* result = expr->result(); |
| 377 Variable* result_var = result->var(); | 374 Variable* result_var = result->var(); |
| 378 | 375 |
| 379 if (!body->is_empty()) { | 376 if (!body->is_empty()) { |
| 380 Processor processor(parser, scope, result_var, factory); | 377 Processor processor(parser, scope, result_var, factory); |
| 381 processor.Process(body); | 378 processor.Process(body); |
| 382 if (processor.HasStackOverflow()) return false; | 379 if (processor.HasStackOverflow()) return false; |
| 383 | 380 |
| 384 if (!processor.result_assigned()) { | 381 if (!processor.result_assigned()) { |
| 385 AstNodeFactory* node_factory = processor.factory(); | 382 AstNodeFactory* node_factory = processor.factory(); |
| 386 Expression* undef = | 383 Expression* undef = node_factory->NewUndefinedLiteral(kNoSourcePosition); |
| 387 node_factory->NewUndefinedLiteral(RelocInfo::kNoPosition); | |
| 388 Statement* completion = node_factory->NewExpressionStatement( | 384 Statement* completion = node_factory->NewExpressionStatement( |
| 389 processor.SetResult(undef), expr->position()); | 385 processor.SetResult(undef), expr->position()); |
| 390 body->Add(completion, factory->zone()); | 386 body->Add(completion, factory->zone()); |
| 391 } | 387 } |
| 392 } | 388 } |
| 393 return true; | 389 return true; |
| 394 } | 390 } |
| 395 | 391 |
| 396 | 392 |
| 397 } // namespace internal | 393 } // namespace internal |
| 398 } // namespace v8 | 394 } // namespace v8 |
| OLD | NEW |