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

Unified Diff: src/pattern-rewriter.cc

Issue 1411203002: [es6] implement destructuring assignment [clean diff] (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Completion-value reusing that may not necessarily accomplish anything Created 5 years, 2 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/parser.cc ('k') | test/mjsunit/harmony/destructuring-assignment.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/pattern-rewriter.cc
diff --git a/src/pattern-rewriter.cc b/src/pattern-rewriter.cc
index 090f85dc9c533ad68fcdb0bff435c7440152194d..db114c91b5207eb8464d5ee807eafa20e45ea323 100644
--- a/src/pattern-rewriter.cc
+++ b/src/pattern-rewriter.cc
@@ -17,19 +17,53 @@ void Parser::PatternRewriter::DeclareAndInitializeVariables(
ZoneList<const AstRawString*>* names, bool* ok) {
PatternRewriter rewriter;
+ rewriter.parser_ = declaration_descriptor->parser;
+ rewriter.context_ = BINDING;
rewriter.pattern_ = declaration->pattern;
rewriter.initializer_position_ = declaration->initializer_position;
rewriter.block_ = block;
rewriter.descriptor_ = declaration_descriptor;
rewriter.names_ = names;
rewriter.ok_ = ok;
+ rewriter.rhs_ = nullptr;
rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
}
+Variable* Parser::PatternRewriter::RewriteDestructuringAssignment(
+ Parser* parser, Block* block, Expression* pattern, Expression* value,
+ Variable* result, bool* ok) {
+ PatternRewriter rewriter;
+
+ rewriter.parser_ = parser;
+ rewriter.context_ = ASSIGNMENT;
+ rewriter.pattern_ = pattern;
+ rewriter.block_ = block;
+ rewriter.descriptor_ = nullptr;
+ rewriter.names_ = nullptr;
+ rewriter.ok_ = ok;
+ rewriter.rhs_ = result;
+
+ rewriter.RecurseIntoSubpattern(rewriter.pattern_, value);
+ DCHECK_NOT_NULL(rewriter.rhs_);
+ return rewriter.rhs_;
+}
+
+
void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
Expression* value = current_value_;
+
+ if (context() == ASSIGNMENT) {
+ // In an assignment context, simply perform the assignment
+ Assignment* assignment = factory()->NewAssignment(
+ Token::ASSIGN, pattern, value, pattern->position());
+ block_->statements()->Add(
+ factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
+ zone());
+ return;
+ }
+
descriptor_->scope->RemoveUnresolved(pattern);
// Declare variable.
@@ -47,7 +81,7 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
// For let/const declarations in harmony mode, we can also immediately
// pre-resolve the proxy because it resides in the same scope as the
// declaration.
- Parser* parser = descriptor_->parser;
+ Parser* parser = parser_;
const AstRawString* name = pattern->raw_name();
VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode);
Declaration* declaration = factory()->NewVariableDeclaration(
@@ -213,8 +247,14 @@ void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
- auto temp = descriptor_->parser->scope_->NewTemporary(
- ast_value_factory()->empty_string());
+ if (value && value->IsDoExpression()) {
+ // Re-use completion values from |do-expressions|
+ block_->statements()->Add(
caitp (gmail) 2015/10/19 12:10:50 I was hoping this would help reduce the number of
+ factory()->NewExpressionStatement(value, RelocInfo::kNoPosition),
+ zone());
+ return value->AsDoExpression()->result()->var();
+ }
+ auto temp = parser_scope()->NewTemporary(ast_value_factory()->empty_string());
if (value != nullptr) {
auto assignment = factory()->NewAssignment(
Token::ASSIGN, factory()->NewVariableProxy(temp), value,
@@ -230,9 +270,9 @@ Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) {
auto temp = CreateTempVar(current_value_);
+ if (rhs_ == nullptr) rhs_ = temp;
- block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
- zone());
+ block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
for (ObjectLiteralProperty* property : *pattern->properties()) {
RecurseIntoSubpattern(
@@ -245,12 +285,18 @@ void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) {
void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
auto temp = CreateTempVar(current_value_);
+ if (rhs_ == nullptr) rhs_ = temp;
+
+ Block* outer_block = block_;
- block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
- zone());
+ if (context() == ASSIGNMENT) {
+ block_ = factory()->NewBlock(nullptr, 4, false, node->position());
+ }
- auto iterator = CreateTempVar(descriptor_->parser->GetIterator(
- factory()->NewVariableProxy(temp), factory()));
+ block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
+
+ auto iterator = CreateTempVar(
+ parser_->GetIterator(factory()->NewVariableProxy(temp), factory()));
auto done = CreateTempVar(
factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
auto result = CreateTempVar();
@@ -269,13 +315,12 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
// }
auto next_block =
factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
- next_block->statements()->Add(
- factory()->NewExpressionStatement(
- descriptor_->parser->BuildIteratorNextResult(
- factory()->NewVariableProxy(iterator), result,
- RelocInfo::kNoPosition),
- RelocInfo::kNoPosition),
- zone());
+ next_block->statements()->Add(factory()->NewExpressionStatement(
+ parser_->BuildIteratorNextResult(
+ factory()->NewVariableProxy(iterator),
+ result, RelocInfo::kNoPosition),
+ RelocInfo::kNoPosition),
+ zone());
auto assign_to_done = factory()->NewAssignment(
Token::ASSIGN, factory()->NewVariableProxy(done),
@@ -322,7 +367,7 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
empty_exprs,
// Reuse pattern's literal index - it is unused since there is no
// actual literal allocated.
- node->literal_index(), is_strong(descriptor_->parser->language_mode()),
+ node->literal_index(), is_strong(parser_->language_mode()),
RelocInfo::kNoPosition));
auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
@@ -345,6 +390,14 @@ void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
RecurseIntoSubpattern(spread->expression(),
factory()->NewVariableProxy(array));
}
+
+ if (outer_block != block_) {
+ DoExpression* work =
+ factory()->NewDoExpression(block_, temp, node->position());
+ block_ = outer_block;
+ block_->statements()->Add(
+ factory()->NewExpressionStatement(work, node->position()), zone());
+ }
}
@@ -353,6 +406,12 @@ void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
// becomes
// temp = <value>;
// <pattern> = temp === undefined ? <init> : temp;
+ PatternContext old_context = context();
+ if (old_context == INITIALIZER) {
+ set_context(ASSIGNMENT);
+ } else if (old_context == BINDING) {
+ set_context(INITIALIZER);
+ }
DCHECK(node->op() == Token::ASSIGN);
auto temp = CreateTempVar(current_value_);
Expression* is_undefined = factory()->NewCompareOperation(
@@ -363,6 +422,20 @@ void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
is_undefined, node->value(), factory()->NewVariableProxy(temp),
RelocInfo::kNoPosition);
RecurseIntoSubpattern(node->target(), value);
+ set_context(old_context);
+}
+
+
+// =============== ASSIGNMENT-ONLY =========================
+
+void Parser::PatternRewriter::VisitProperty(v8::internal::Property* pattern) {
+ DCHECK(context() == ASSIGNMENT);
+ Expression* value = current_value_;
+ Assignment* assignment = factory()->NewAssignment(Token::ASSIGN, pattern,
+ value, pattern->position());
+ block_->statements()->Add(
+ factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
+ zone());
}
@@ -403,7 +476,6 @@ NOT_A_PATTERN(IfStatement)
NOT_A_PATTERN(ImportDeclaration)
NOT_A_PATTERN(Literal)
NOT_A_PATTERN(NativeFunctionLiteral)
-NOT_A_PATTERN(Property)
NOT_A_PATTERN(RegExpLiteral)
NOT_A_PATTERN(ReturnStatement)
NOT_A_PATTERN(SloppyBlockFunctionStatement)
« no previous file with comments | « src/parser.cc ('k') | test/mjsunit/harmony/destructuring-assignment.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698