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

Side by Side Diff: src/parsing/parser.cc

Issue 1564083002: Add spread rewriting (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase to remove things added in separate CLs Created 4 years, 11 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
« no previous file with comments | « src/parsing/parser.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 5378 matching lines...) Expand 10 before | Expand all | Expand 10 after
5397 return parser_->RewriteExpression(expr); 5398 return parser_->RewriteExpression(expr);
5398 } 5399 }
5399 5400
5400 5401
5401 ObjectLiteralProperty* ParserTraits::RewriteObjectLiteralProperty( 5402 ObjectLiteralProperty* ParserTraits::RewriteObjectLiteralProperty(
5402 ObjectLiteralProperty* property) { 5403 ObjectLiteralProperty* property) {
5403 return parser_->RewriteObjectLiteralProperty(property); 5404 return parser_->RewriteObjectLiteralProperty(property);
5404 } 5405 }
5405 5406
5406 5407
5408 class SpreadRewriter : public AstExpressionRewriter {
5409 public:
5410 SpreadRewriter(uintptr_t stack_limit, Parser* parser)
5411 : AstExpressionRewriter(stack_limit), parser_(parser) {}
5412 ~SpreadRewriter() override {}
5413
5414 private:
5415 bool RewriteExpression(Expression* expr) override {
5416 // Rewrite only what could have been a pattern.
5417 // The actual work is in array literals.
5418 if (expr->IsArrayLiteral()) {
5419 ArrayLiteral* lit = expr->AsArrayLiteral();
5420 VisitExpressions(lit->values());
5421 replacement_ = parser_->RewriteSpreads(lit);
5422 return false;
5423 }
5424 if (expr->IsObjectLiteral()) {
5425 return true;
5426 }
5427 if (expr->IsBinaryOperation() &&
5428 expr->AsBinaryOperation()->op() == Token::COMMA) {
5429 return true;
5430 }
5431 // Everything else does not need rewriting.
5432 return false;
5433 }
5434
5435 Parser* parser_;
5436 };
5437
5438
5407 Expression* Parser::RewriteExpression(Expression* expr) { 5439 Expression* Parser::RewriteExpression(Expression* expr) {
5408 // TODO(nikolaos): For the time being, this does no rewriting at all. 5440 SpreadRewriter rewriter(stack_limit_, this);
5409 return expr; 5441 AstNode* node = rewriter.Rewrite(expr);
5442 DCHECK_NOT_NULL(node);
rossberg 2016/01/11 12:50:14 Nit: having 2 null checks here may be a bit over-d
nickie 2016/01/13 10:15:21 Acknowledged. I will remove the first. It was pr
5443 Expression* result = reinterpret_cast<Expression*>(node);
5444 DCHECK_NOT_NULL(result);
5445 return result;
5410 } 5446 }
5411 5447
5412 5448
5413 ObjectLiteralProperty* Parser::RewriteObjectLiteralProperty( 5449 ObjectLiteralProperty* Parser::RewriteObjectLiteralProperty(
5414 ObjectLiteralProperty* property) { 5450 ObjectLiteralProperty* property) {
5415 if (property != nullptr) { 5451 if (property != nullptr) {
5416 Expression* key = RewriteExpression(property->key()); 5452 Expression* key = RewriteExpression(property->key());
5417 property->set_key(key); 5453 property->set_key(key);
5418 Expression* value = RewriteExpression(property->value()); 5454 Expression* value = RewriteExpression(property->value());
5419 property->set_value(value); 5455 property->set_value(value);
(...skipping 15 matching lines...) Expand all
5435 pair.assignment->AsRewritableAssignmentExpression(); 5471 pair.assignment->AsRewritableAssignmentExpression();
5436 Scope* scope = pair.scope; 5472 Scope* scope = pair.scope;
5437 DCHECK_NOT_NULL(to_rewrite); 5473 DCHECK_NOT_NULL(to_rewrite);
5438 if (!to_rewrite->is_rewritten()) { 5474 if (!to_rewrite->is_rewritten()) {
5439 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope); 5475 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope);
5440 } 5476 }
5441 } 5477 }
5442 } 5478 }
5443 5479
5444 5480
5481 Expression* Parser::RewriteSpreads(ArrayLiteral* lit) {
5482 ZoneList<Expression*>::iterator s = lit->FirstSpread();
5483 if (s == lit->EndValue()) return nullptr;
5484 // TODO(nikolaos): Check and fix the positions for the generated AST.
5485 Variable* result =
5486 scope_->NewTemporary(ast_value_factory()->dot_result_string());
5487 Expression* init_result =
5488 factory()->NewAssignment(Token::INIT, factory()->NewVariableProxy(result),
5489 lit, RelocInfo::kNoPosition);
5490 Block* do_block =
5491 factory()->NewBlock(nullptr, 16, false, RelocInfo::kNoPosition);
5492 do_block->statements()->Add(
5493 factory()->NewExpressionStatement(init_result, RelocInfo::kNoPosition),
5494 zone());
5495 while (s != lit->EndValue()) {
5496 Expression* value = *s++;
5497 Spread* spread = value->AsSpread();
5498 if (spread == nullptr) {
rossberg 2016/01/11 12:50:14 Nit: add comments to both branches of this conditi
nickie 2016/01/13 10:15:21 Acknowledged.
5499 ZoneList<Expression*>* append_element_args = NewExpressionList(2, zone());
5500 append_element_args->Add(factory()->NewVariableProxy(result), zone());
5501 append_element_args->Add(value, zone());
5502 do_block->statements()->Add(
5503 factory()->NewExpressionStatement(
5504 factory()->NewCallRuntime(Runtime::kAppendElement,
5505 append_element_args,
5506 RelocInfo::kNoPosition),
5507 RelocInfo::kNoPosition),
5508 zone());
5509 } else {
5510 Variable* each =
5511 scope_->NewTemporary(ast_value_factory()->dot_for_string());
5512 Expression* subject = spread->expression();
5513 Variable* iterator =
5514 scope_->NewTemporary(ast_value_factory()->dot_iterator_string());
5515 Variable* element =
5516 scope_->NewTemporary(ast_value_factory()->dot_result_string());
5517 // iterator = subject[Symbol.iterator]()
5518 Expression* assign_iterator = factory()->NewAssignment(
5519 Token::ASSIGN, factory()->NewVariableProxy(iterator),
5520 GetIterator(subject, factory(), spread->position()),
5521 spread->position());
5522 // !%_IsJSReceiver(element = iterator.next()) &&
5523 // %ThrowIteratorResultNotAnObject(element)
5524 Expression* next_element;
5525 {
5526 // element = iterator.next()
5527 Expression* iterator_proxy = factory()->NewVariableProxy(iterator);
5528 next_element = BuildIteratorNextResult(iterator_proxy, element,
5529 spread->position());
5530 }
5531 // element.done
5532 Expression* element_done;
5533 {
5534 Expression* done_literal = factory()->NewStringLiteral(
5535 ast_value_factory()->done_string(), RelocInfo::kNoPosition);
5536 Expression* element_proxy = factory()->NewVariableProxy(element);
5537 element_done = factory()->NewProperty(element_proxy, done_literal,
5538 RelocInfo::kNoPosition);
5539 }
5540 // each = element.value
5541 Expression* assign_each;
5542 {
5543 Expression* value_literal = factory()->NewStringLiteral(
5544 ast_value_factory()->value_string(), RelocInfo::kNoPosition);
5545 Expression* element_proxy = factory()->NewVariableProxy(element);
5546 Expression* element_value = factory()->NewProperty(
5547 element_proxy, value_literal, RelocInfo::kNoPosition);
5548 assign_each = factory()->NewAssignment(
5549 Token::ASSIGN, factory()->NewVariableProxy(each), element_value,
5550 RelocInfo::kNoPosition);
5551 }
5552 // append each to the result
5553 Statement* append_body;
5554 {
5555 ZoneList<Expression*>* append_element_args =
5556 NewExpressionList(2, zone());
5557 append_element_args->Add(factory()->NewVariableProxy(result), zone());
5558 append_element_args->Add(factory()->NewVariableProxy(each), zone());
5559 append_body = factory()->NewExpressionStatement(
5560 factory()->NewCallRuntime(Runtime::kAppendElement,
5561 append_element_args,
5562 RelocInfo::kNoPosition),
5563 RelocInfo::kNoPosition);
5564 }
5565 ForEachStatement* loop = factory()->NewForEachStatement(
5566 ForEachStatement::ITERATE, nullptr, spread->position());
5567 ForOfStatement* for_of = loop->AsForOfStatement();
5568 for_of->Initialize(factory()->NewVariableProxy(each), subject,
5569 append_body, assign_iterator, next_element,
5570 element_done, assign_each);
5571 do_block->statements()->Add(for_of, zone());
5572 }
5573 }
5574 lit->RewindSpreads();
rossberg 2016/01/11 12:50:14 Why is this needed?
nickie 2016/01/13 10:15:21 This is very important. Line 5487 initializes the
5575 return factory()->NewDoExpression(do_block, result, lit->position());
5576 }
5577
5578
5445 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { 5579 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) {
5446 DCHECK(expr->IsRewritableAssignmentExpression()); 5580 DCHECK(expr->IsRewritableAssignmentExpression());
5447 parser_->function_state_->AddDestructuringAssignment( 5581 parser_->function_state_->AddDestructuringAssignment(
5448 Parser::DestructuringAssignment(expr, parser_->scope_)); 5582 Parser::DestructuringAssignment(expr, parser_->scope_));
5449 } 5583 }
5450 5584
5451 5585
5452 void ParserTraits::SetFunctionNameFromPropertyName( 5586 void ParserTraits::SetFunctionNameFromPropertyName(
5453 ObjectLiteralProperty* property, const AstRawString* name) { 5587 ObjectLiteralProperty* property, const AstRawString* name) {
5454 Expression* value = property->value(); 5588 Expression* value = property->value();
(...skipping 27 matching lines...) Expand all
5482 auto class_literal = value->AsClassLiteral(); 5616 auto class_literal = value->AsClassLiteral();
5483 if (class_literal->raw_name() == nullptr) { 5617 if (class_literal->raw_name() == nullptr) {
5484 class_literal->set_raw_name(name); 5618 class_literal->set_raw_name(name);
5485 } 5619 }
5486 } 5620 }
5487 } 5621 }
5488 5622
5489 5623
5490 } // namespace internal 5624 } // namespace internal
5491 } // namespace v8 5625 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698