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 5378 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |