Chromium Code Reviews| 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/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/ast-expression-rewriter.h" | |
| 9 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
| 10 #include "src/ast/ast-literal-reindexer.h" | 11 #include "src/ast/ast-literal-reindexer.h" |
| 11 #include "src/ast/scopeinfo.h" | 12 #include "src/ast/scopeinfo.h" |
| 12 #include "src/bailout-reason.h" | 13 #include "src/bailout-reason.h" |
| 13 #include "src/base/platform/platform.h" | 14 #include "src/base/platform/platform.h" |
| 14 #include "src/bootstrapper.h" | 15 #include "src/bootstrapper.h" |
| 15 #include "src/char-predicates-inl.h" | 16 #include "src/char-predicates-inl.h" |
| 16 #include "src/codegen.h" | 17 #include "src/codegen.h" |
| 17 #include "src/compiler.h" | 18 #include "src/compiler.h" |
| 18 #include "src/messages.h" | 19 #include "src/messages.h" |
| (...skipping 6487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6506 return parser_->RewriteExpression(expr); | 6507 return parser_->RewriteExpression(expr); |
| 6507 } | 6508 } |
| 6508 | 6509 |
| 6509 | 6510 |
| 6510 ObjectLiteralProperty* ParserTraits::RewriteObjectLiteralProperty( | 6511 ObjectLiteralProperty* ParserTraits::RewriteObjectLiteralProperty( |
| 6511 ObjectLiteralProperty* property) { | 6512 ObjectLiteralProperty* property) { |
| 6512 return parser_->RewriteObjectLiteralProperty(property); | 6513 return parser_->RewriteObjectLiteralProperty(property); |
| 6513 } | 6514 } |
| 6514 | 6515 |
| 6515 | 6516 |
| 6517 class SpreadRewriter : public AstExpressionRewriter { | |
|
nickie
2016/01/07 16:58:11
For the time being, this just rewrites spreads in
| |
| 6518 public: | |
| 6519 SpreadRewriter(uintptr_t stack_limit, Parser* parser) | |
| 6520 : AstExpressionRewriter(stack_limit), parser_(parser) {} | |
| 6521 ~SpreadRewriter() override {} | |
| 6522 | |
| 6523 private: | |
| 6524 bool RewriteExpression(Expression* expr) override { | |
| 6525 // Rewrite only what could have been a pattern. | |
| 6526 // The actual work is in array literals. | |
| 6527 if (expr->IsArrayLiteral()) { | |
| 6528 ArrayLiteral* lit = expr->AsArrayLiteral(); | |
| 6529 VisitExpressions(lit->values()); | |
| 6530 replacement_ = parser_->RewriteSpreads(lit); | |
| 6531 return false; | |
| 6532 } | |
| 6533 if (expr->IsObjectLiteral()) { | |
| 6534 return true; | |
| 6535 } | |
| 6536 if (expr->IsBinaryOperation() && | |
| 6537 expr->AsBinaryOperation()->op() == Token::COMMA) { | |
| 6538 return true; | |
| 6539 } | |
| 6540 // Everything else does not need rewriting. | |
| 6541 return false; | |
| 6542 } | |
| 6543 | |
| 6544 Parser* parser_; | |
| 6545 }; | |
| 6546 | |
| 6547 | |
| 6516 Expression* Parser::RewriteExpression(Expression* expr) { | 6548 Expression* Parser::RewriteExpression(Expression* expr) { |
| 6517 // TODO(nikolaos): For the time being, this does no rewriting at all. | 6549 SpreadRewriter rewriter(stack_limit_, this); |
| 6518 return expr; | 6550 AstNode* node = rewriter.Rewrite(expr); |
| 6551 DCHECK_NOT_NULL(node); | |
| 6552 Expression* result = reinterpret_cast<Expression*>(node); | |
| 6553 DCHECK_NOT_NULL(result); | |
| 6554 return result; | |
| 6519 } | 6555 } |
| 6520 | 6556 |
| 6521 | 6557 |
| 6522 ObjectLiteralProperty* Parser::RewriteObjectLiteralProperty( | 6558 ObjectLiteralProperty* Parser::RewriteObjectLiteralProperty( |
| 6523 ObjectLiteralProperty* property) { | 6559 ObjectLiteralProperty* property) { |
| 6524 if (property != nullptr) { | 6560 if (property != nullptr) { |
| 6525 Expression* key = RewriteExpression(property->key()); | 6561 Expression* key = RewriteExpression(property->key()); |
| 6526 property->set_key(key); | 6562 property->set_key(key); |
| 6527 Expression* value = RewriteExpression(property->value()); | 6563 Expression* value = RewriteExpression(property->value()); |
| 6528 property->set_value(value); | 6564 property->set_value(value); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 6544 pair.assignment->AsRewritableAssignmentExpression(); | 6580 pair.assignment->AsRewritableAssignmentExpression(); |
| 6545 Scope* scope = pair.scope; | 6581 Scope* scope = pair.scope; |
| 6546 DCHECK_NOT_NULL(to_rewrite); | 6582 DCHECK_NOT_NULL(to_rewrite); |
| 6547 if (!to_rewrite->is_rewritten()) { | 6583 if (!to_rewrite->is_rewritten()) { |
| 6548 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope); | 6584 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope); |
| 6549 } | 6585 } |
| 6550 } | 6586 } |
| 6551 } | 6587 } |
| 6552 | 6588 |
| 6553 | 6589 |
| 6590 Expression* Parser::RewriteSpreads(ArrayLiteral* lit) { | |
| 6591 ZoneList<Expression*>::iterator s = lit->FirstSpread(); | |
| 6592 if (s == lit->EndValue()) return nullptr; | |
| 6593 // TODO(nikolaos): Check and fix the positions for the generated AST. | |
| 6594 Variable* result = | |
| 6595 scope_->NewTemporary(ast_value_factory()->dot_result_string()); | |
| 6596 Expression* init_result = | |
| 6597 factory()->NewAssignment(Token::INIT, factory()->NewVariableProxy(result), | |
| 6598 lit, RelocInfo::kNoPosition); | |
| 6599 Block* do_block = | |
| 6600 factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition); | |
| 6601 do_block->statements()->Add( | |
| 6602 factory()->NewExpressionStatement(init_result, RelocInfo::kNoPosition), | |
| 6603 zone()); | |
| 6604 while (s != lit->EndValue()) { | |
| 6605 Expression* value = *s++; | |
| 6606 Spread* spread = value->AsSpread(); | |
| 6607 if (spread == nullptr) { | |
| 6608 ZoneList<Expression*>* append_element_args = NewExpressionList(2, zone()); | |
| 6609 append_element_args->Add(factory()->NewVariableProxy(result), zone()); | |
| 6610 append_element_args->Add(value, zone()); | |
| 6611 do_block->statements()->Add( | |
| 6612 factory()->NewExpressionStatement( | |
| 6613 factory()->NewCallRuntime(Runtime::kAppendElement, | |
| 6614 append_element_args, | |
| 6615 RelocInfo::kNoPosition), | |
| 6616 RelocInfo::kNoPosition), | |
| 6617 zone()); | |
| 6618 } else { | |
| 6619 Variable* each = | |
| 6620 scope_->NewTemporary(ast_value_factory()->dot_for_string()); | |
| 6621 Expression* subject = spread->expression(); | |
| 6622 Variable* iterator = | |
| 6623 scope_->NewTemporary(ast_value_factory()->dot_iterator_string()); | |
| 6624 Variable* element = | |
| 6625 scope_->NewTemporary(ast_value_factory()->dot_result_string()); | |
| 6626 // iterator = subject[Symbol.iterator]() | |
| 6627 Expression* assign_iterator = factory()->NewAssignment( | |
| 6628 Token::ASSIGN, factory()->NewVariableProxy(iterator), | |
| 6629 GetIterator(subject, factory(), spread->position()), | |
| 6630 spread->position()); | |
| 6631 // !%_IsJSReceiver(element = iterator.next()) && | |
| 6632 // %ThrowIteratorResultNotAnObject(element) | |
| 6633 Expression* next_element; | |
| 6634 { | |
| 6635 // element = iterator.next() | |
| 6636 Expression* iterator_proxy = factory()->NewVariableProxy(iterator); | |
| 6637 next_element = BuildIteratorNextResult(iterator_proxy, element, | |
| 6638 spread->position()); | |
| 6639 } | |
| 6640 // element.done | |
| 6641 Expression* element_done; | |
| 6642 { | |
| 6643 Expression* done_literal = factory()->NewStringLiteral( | |
| 6644 ast_value_factory()->done_string(), RelocInfo::kNoPosition); | |
| 6645 Expression* element_proxy = factory()->NewVariableProxy(element); | |
| 6646 element_done = factory()->NewProperty(element_proxy, done_literal, | |
| 6647 RelocInfo::kNoPosition); | |
| 6648 } | |
| 6649 // each = element.value | |
| 6650 Expression* assign_each; | |
| 6651 { | |
| 6652 Expression* value_literal = factory()->NewStringLiteral( | |
| 6653 ast_value_factory()->value_string(), RelocInfo::kNoPosition); | |
| 6654 Expression* element_proxy = factory()->NewVariableProxy(element); | |
| 6655 Expression* element_value = factory()->NewProperty( | |
| 6656 element_proxy, value_literal, RelocInfo::kNoPosition); | |
| 6657 assign_each = factory()->NewAssignment( | |
| 6658 Token::ASSIGN, factory()->NewVariableProxy(each), element_value, | |
| 6659 RelocInfo::kNoPosition); | |
| 6660 } | |
| 6661 // append each to the result | |
| 6662 Statement* append_body; | |
| 6663 { | |
| 6664 ZoneList<Expression*>* append_element_args = | |
| 6665 NewExpressionList(2, zone()); | |
| 6666 append_element_args->Add(factory()->NewVariableProxy(result), zone()); | |
| 6667 append_element_args->Add(factory()->NewVariableProxy(each), zone()); | |
| 6668 append_body = factory()->NewExpressionStatement( | |
| 6669 factory()->NewCallRuntime(Runtime::kAppendElement, | |
| 6670 append_element_args, | |
| 6671 RelocInfo::kNoPosition), | |
| 6672 RelocInfo::kNoPosition); | |
| 6673 } | |
| 6674 ForEachStatement* loop = factory()->NewForEachStatement( | |
| 6675 ForEachStatement::ITERATE, nullptr, spread->position()); | |
| 6676 ForOfStatement* for_of = loop->AsForOfStatement(); | |
| 6677 for_of->Initialize(factory()->NewVariableProxy(each), subject, | |
| 6678 append_body, assign_iterator, next_element, | |
| 6679 element_done, assign_each); | |
| 6680 do_block->statements()->Add(for_of, zone()); | |
| 6681 } | |
| 6682 } | |
| 6683 lit->RewindSpreads(); | |
| 6684 return factory()->NewDoExpression(do_block, result, lit->position()); | |
| 6685 } | |
| 6686 | |
| 6687 | |
| 6554 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 6688 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
| 6555 DCHECK(expr->IsRewritableAssignmentExpression()); | 6689 DCHECK(expr->IsRewritableAssignmentExpression()); |
| 6556 parser_->function_state_->AddDestructuringAssignment( | 6690 parser_->function_state_->AddDestructuringAssignment( |
| 6557 Parser::DestructuringAssignment(expr, parser_->scope_)); | 6691 Parser::DestructuringAssignment(expr, parser_->scope_)); |
| 6558 } | 6692 } |
| 6559 | 6693 |
| 6560 | 6694 |
| 6561 void ParserTraits::SetFunctionNameFromPropertyName( | 6695 void ParserTraits::SetFunctionNameFromPropertyName( |
| 6562 ObjectLiteralProperty* property, const AstRawString* name) { | 6696 ObjectLiteralProperty* property, const AstRawString* name) { |
| 6563 Expression* value = property->value(); | 6697 Expression* value = property->value(); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 6591 auto class_literal = value->AsClassLiteral(); | 6725 auto class_literal = value->AsClassLiteral(); |
| 6592 if (class_literal->raw_name() == nullptr) { | 6726 if (class_literal->raw_name() == nullptr) { |
| 6593 class_literal->set_raw_name(name); | 6727 class_literal->set_raw_name(name); |
| 6594 } | 6728 } |
| 6595 } | 6729 } |
| 6596 } | 6730 } |
| 6597 | 6731 |
| 6598 | 6732 |
| 6599 } // namespace internal | 6733 } // namespace internal |
| 6600 } // namespace v8 | 6734 } // namespace v8 |
| OLD | NEW |