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

Side by Side Diff: src/parsing/pattern-rewriter.cc

Issue 1309813007: [es6] implement destructuring assignment (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove facilities for rewriting the expression multiple ways Created 5 years 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/ast/ast.h" 5 #include "src/ast/ast.h"
6 #include "src/messages.h" 6 #include "src/messages.h"
7 #include "src/parsing/parameter-initializer-rewriter.h" 7 #include "src/parsing/parameter-initializer-rewriter.h"
8 #include "src/parsing/parser.h" 8 #include "src/parsing/parser.h"
9 9
10 namespace v8 { 10 namespace v8 {
11 11
12 namespace internal { 12 namespace internal {
13 13
14
15 void Parser::PatternRewriter::DeclareAndInitializeVariables( 14 void Parser::PatternRewriter::DeclareAndInitializeVariables(
16 Block* block, const DeclarationDescriptor* declaration_descriptor, 15 Block* block, const DeclarationDescriptor* declaration_descriptor,
17 const DeclarationParsingResult::Declaration* declaration, 16 const DeclarationParsingResult::Declaration* declaration,
18 ZoneList<const AstRawString*>* names, bool* ok) { 17 ZoneList<const AstRawString*>* names, bool* ok) {
19 PatternRewriter rewriter; 18 PatternRewriter rewriter;
20 19
20 rewriter.scope_ = declaration_descriptor->scope;
21 rewriter.parser_ = declaration_descriptor->parser;
22 rewriter.context_ = BINDING;
21 rewriter.pattern_ = declaration->pattern; 23 rewriter.pattern_ = declaration->pattern;
22 rewriter.initializer_position_ = declaration->initializer_position; 24 rewriter.initializer_position_ = declaration->initializer_position;
23 rewriter.block_ = block; 25 rewriter.block_ = block;
24 rewriter.descriptor_ = declaration_descriptor; 26 rewriter.descriptor_ = declaration_descriptor;
25 rewriter.names_ = names; 27 rewriter.names_ = names;
26 rewriter.ok_ = ok; 28 rewriter.ok_ = ok;
27 29
28 rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer); 30 rewriter.RecurseIntoSubpattern(rewriter.pattern_, declaration->initializer);
29 } 31 }
30 32
31 33
34 void Parser::PatternRewriter::RewriteDestructuringAssignment(
35 Parser* parser, RewritableExpression* to_rewrite, Scope* scope, bool* ok) {
36 PatternRewriter rewriter;
37
38 DCHECK(!to_rewrite->is_rewritten());
39
40 rewriter.scope_ = scope;
41 rewriter.parser_ = parser;
42 rewriter.context_ = ASSIGNMENT;
43 rewriter.pattern_ = to_rewrite;
44 rewriter.block_ = nullptr;
45 rewriter.descriptor_ = nullptr;
46 rewriter.names_ = nullptr;
47 rewriter.ok_ = ok;
48
49 rewriter.RecurseIntoSubpattern(rewriter.pattern_, nullptr);
50 }
51
52
53 bool Parser::PatternRewriter::IsAssignmentContext(PatternContext c) const {
54 return c == ASSIGNMENT || c == ASSIGNMENT_INITIALIZER;
55 }
56
57
58 bool Parser::PatternRewriter::IsBindingContext(PatternContext c) const {
59 return c == BINDING || c == INITIALIZER;
60 }
61
62
63 Parser::PatternRewriter::PatternContext
64 Parser::PatternRewriter::SetAssignmentContextIfNeeded(Expression* node) {
65 PatternContext old_context = context();
66 if (node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN) {
67 set_context(ASSIGNMENT);
68 }
69 return old_context;
70 }
71
72
73 Parser::PatternRewriter::PatternContext
74 Parser::PatternRewriter::SetInitializerContextIfNeeded(Expression* node) {
75 // Set appropriate initializer context for BindingElement and
76 // AssignmentElement nodes
77 PatternContext old_context = context();
78 bool is_destructuring_assignment =
79 node->IsRewritableExpression() &&
80 !node->AsRewritableExpression()->is_rewritten();
81 bool is_assignment =
82 node->IsAssignment() && node->AsAssignment()->op() == Token::ASSIGN;
83 if (is_destructuring_assignment || is_assignment) {
84 switch (old_context) {
85 case BINDING:
86 set_context(INITIALIZER);
87 break;
88 case ASSIGNMENT:
89 set_context(ASSIGNMENT_INITIALIZER);
90 break;
91 default:
92 break;
93 }
94 }
95 return old_context;
96 }
97
98
32 void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) { 99 void Parser::PatternRewriter::VisitVariableProxy(VariableProxy* pattern) {
33 Expression* value = current_value_; 100 Expression* value = current_value_;
101
102 if (IsAssignmentContext()) {
103 // In an assignment context, simply perform the assignment
104 Assignment* assignment = factory()->NewAssignment(
105 Token::ASSIGN, pattern, value, pattern->position());
106 block_->statements()->Add(
107 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
108 zone());
109 return;
110 }
111
34 descriptor_->scope->RemoveUnresolved(pattern); 112 descriptor_->scope->RemoveUnresolved(pattern);
35 113
36 // Declare variable. 114 // Declare variable.
37 // Note that we *always* must treat the initial value via a separate init 115 // Note that we *always* must treat the initial value via a separate init
38 // assignment for variables and constants because the value must be assigned 116 // assignment for variables and constants because the value must be assigned
39 // when the variable is encountered in the source. But the variable/constant 117 // when the variable is encountered in the source. But the variable/constant
40 // is declared (and set to 'undefined') upon entering the function within 118 // is declared (and set to 'undefined') upon entering the function within
41 // which the variable or constant is declared. Only function variables have 119 // which the variable or constant is declared. Only function variables have
42 // an initial value in the declaration (because they are initialized upon 120 // an initial value in the declaration (because they are initialized upon
43 // entering the function). 121 // entering the function).
44 // 122 //
45 // If we have a legacy const declaration, in an inner scope, the proxy 123 // If we have a legacy const declaration, in an inner scope, the proxy
46 // is always bound to the declared variable (independent of possibly 124 // is always bound to the declared variable (independent of possibly
47 // surrounding 'with' statements). 125 // surrounding 'with' statements).
48 // For let/const declarations in harmony mode, we can also immediately 126 // For let/const declarations in harmony mode, we can also immediately
49 // pre-resolve the proxy because it resides in the same scope as the 127 // pre-resolve the proxy because it resides in the same scope as the
50 // declaration. 128 // declaration.
51 Parser* parser = descriptor_->parser;
52 const AstRawString* name = pattern->raw_name(); 129 const AstRawString* name = pattern->raw_name();
53 VariableProxy* proxy = parser->NewUnresolved(name, descriptor_->mode); 130 VariableProxy* proxy = parser_->NewUnresolved(name, descriptor_->mode);
54 Declaration* declaration = factory()->NewVariableDeclaration( 131 Declaration* declaration = factory()->NewVariableDeclaration(
55 proxy, descriptor_->mode, descriptor_->scope, 132 proxy, descriptor_->mode, descriptor_->scope,
56 descriptor_->declaration_pos); 133 descriptor_->declaration_pos);
57 Variable* var = parser->Declare(declaration, descriptor_->declaration_kind, 134 Variable* var =
58 descriptor_->mode != VAR, ok_, 135 parser_->Declare(declaration, descriptor_->declaration_kind,
59 descriptor_->hoist_scope); 136 descriptor_->mode != VAR, ok_, descriptor_->hoist_scope);
60 if (!*ok_) return; 137 if (!*ok_) return;
61 DCHECK_NOT_NULL(var); 138 DCHECK_NOT_NULL(var);
62 DCHECK(!proxy->is_resolved() || proxy->var() == var); 139 DCHECK(!proxy->is_resolved() || proxy->var() == var);
63 var->set_initializer_position(initializer_position_); 140 var->set_initializer_position(initializer_position_);
64 141
65 DCHECK(initializer_position_ != RelocInfo::kNoPosition); 142 DCHECK(initializer_position_ != RelocInfo::kNoPosition);
66 143
67 if (descriptor_->declaration_scope->num_var_or_const() > 144 if (descriptor_->declaration_scope->num_var_or_const() >
68 kMaxNumFunctionLocals) { 145 kMaxNumFunctionLocals) {
69 parser->ReportMessage(MessageTemplate::kTooManyVariables); 146 parser_->ReportMessage(MessageTemplate::kTooManyVariables);
70 *ok_ = false; 147 *ok_ = false;
71 return; 148 return;
72 } 149 }
73 if (names_) { 150 if (names_) {
74 names_->Add(name, zone()); 151 names_->Add(name, zone());
75 } 152 }
76 153
77 // Initialize variables if needed. A 154 // Initialize variables if needed. A
78 // declaration of the form: 155 // declaration of the form:
79 // 156 //
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 Assignment* assignment = factory()->NewAssignment( 284 Assignment* assignment = factory()->NewAssignment(
208 Token::INIT, proxy, value, descriptor_->initialization_pos); 285 Token::INIT, proxy, value, descriptor_->initialization_pos);
209 block_->statements()->Add( 286 block_->statements()->Add(
210 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), 287 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
211 zone()); 288 zone());
212 } 289 }
213 } 290 }
214 291
215 292
216 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) { 293 Variable* Parser::PatternRewriter::CreateTempVar(Expression* value) {
217 auto temp = descriptor_->parser->scope_->NewTemporary( 294 auto temp = scope()->NewTemporary(ast_value_factory()->empty_string());
218 ast_value_factory()->empty_string());
219 if (value != nullptr) { 295 if (value != nullptr) {
220 auto assignment = factory()->NewAssignment( 296 auto assignment = factory()->NewAssignment(
221 Token::ASSIGN, factory()->NewVariableProxy(temp), value, 297 Token::ASSIGN, factory()->NewVariableProxy(temp), value,
222 RelocInfo::kNoPosition); 298 RelocInfo::kNoPosition);
223 299
224 block_->statements()->Add( 300 block_->statements()->Add(
225 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition), 301 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
226 zone()); 302 zone());
227 } 303 }
228 return temp; 304 return temp;
229 } 305 }
230 306
231 307
232 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern) { 308 void Parser::PatternRewriter::VisitRewritableExpression(
233 auto temp = CreateTempVar(current_value_); 309 RewritableExpression* node) {
310 if (IsAssignmentContext() && !node->is_rewritten()) {
311 Assignment* assign = node->expression()->AsAssignment();
312 DCHECK_NOT_NULL(assign);
313 DCHECK_EQ(Token::ASSIGN, assign->op());
234 314
235 block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp), 315 auto initializer = assign->value();
236 zone()); 316 auto value = initializer;
317
318 if (IsInitializerContext()) {
319 // let {<pattern> = <init>} = <value>
320 // becomes
321 // temp = <value>;
322 // <pattern> = temp === undefined ? <init> : temp;
323 auto temp_var = CreateTempVar(current_value_);
324 Expression* is_undefined = factory()->NewCompareOperation(
325 Token::EQ_STRICT, factory()->NewVariableProxy(temp_var),
326 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
327 RelocInfo::kNoPosition);
328 value = factory()->NewConditional(is_undefined, initializer,
329 factory()->NewVariableProxy(temp_var),
330 RelocInfo::kNoPosition);
331 }
332
333 PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
334 int pos = assign->position();
335 Block* old_block = block_;
336 block_ = factory()->NewBlock(nullptr, 8, false, pos);
337 Variable* temp = nullptr;
338 Expression* pattern = assign->target();
339 Expression* old_value = current_value_;
340 current_value_ = value;
341 if (pattern->IsObjectLiteral()) {
342 VisitObjectLiteral(pattern->AsObjectLiteral(), &temp);
343 } else {
344 DCHECK(pattern->IsArrayLiteral());
345 VisitArrayLiteral(pattern->AsArrayLiteral(), &temp);
346 }
347 DCHECK_NOT_NULL(temp);
348 current_value_ = old_value;
349 Expression* expr = factory()->NewDoExpression(block_, temp, pos);
350 node->Rewrite(expr);
351 block_ = old_block;
352 if (block_) {
353 block_->statements()->Add(factory()->NewExpressionStatement(expr, pos),
354 zone());
355 }
356 return set_context(old_context);
357 }
358
359 return node->expression()->Accept(this);
360 }
361
362
363 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* pattern,
364 Variable** temp_var) {
365 auto temp = *temp_var = CreateTempVar(current_value_);
366
367 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
237 368
238 for (ObjectLiteralProperty* property : *pattern->properties()) { 369 for (ObjectLiteralProperty* property : *pattern->properties()) {
370 PatternContext context = SetInitializerContextIfNeeded(property->value());
239 RecurseIntoSubpattern( 371 RecurseIntoSubpattern(
240 property->value(), 372 property->value(),
241 factory()->NewProperty(factory()->NewVariableProxy(temp), 373 factory()->NewProperty(factory()->NewVariableProxy(temp),
242 property->key(), RelocInfo::kNoPosition)); 374 property->key(), RelocInfo::kNoPosition));
375 set_context(context);
243 } 376 }
244 } 377 }
245 378
246 379
247 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) { 380 void Parser::PatternRewriter::VisitObjectLiteral(ObjectLiteral* node) {
248 auto temp = CreateTempVar(current_value_); 381 Variable* temp_var = nullptr;
382 VisitObjectLiteral(node, &temp_var);
383 }
249 384
250 block_->statements()->Add(descriptor_->parser->BuildAssertIsCoercible(temp),
251 zone());
252 385
253 auto iterator = CreateTempVar(descriptor_->parser->GetIterator( 386 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node,
254 factory()->NewVariableProxy(temp), factory())); 387 Variable** temp_var) {
388 auto temp = *temp_var = CreateTempVar(current_value_);
389
390 block_->statements()->Add(parser_->BuildAssertIsCoercible(temp), zone());
391
392 auto iterator = CreateTempVar(
393 parser_->GetIterator(factory()->NewVariableProxy(temp), factory()));
255 auto done = CreateTempVar( 394 auto done = CreateTempVar(
256 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition)); 395 factory()->NewBooleanLiteral(false, RelocInfo::kNoPosition));
257 auto result = CreateTempVar(); 396 auto result = CreateTempVar();
258 auto v = CreateTempVar(); 397 auto v = CreateTempVar();
259 398
260 Spread* spread = nullptr; 399 Spread* spread = nullptr;
261 for (Expression* value : *node->values()) { 400 for (Expression* value : *node->values()) {
262 if (value->IsSpread()) { 401 if (value->IsSpread()) {
263 spread = value->AsSpread(); 402 spread = value->AsSpread();
264 break; 403 break;
265 } 404 }
266 405
406 PatternContext context = SetInitializerContextIfNeeded(value);
267 // if (!done) { 407 // if (!done) {
268 // result = IteratorNext(iterator); 408 // result = IteratorNext(iterator);
269 // v = (done = result.done) ? undefined : result.value; 409 // v = (done = result.done) ? undefined : result.value;
270 // } 410 // }
271 auto next_block = 411 auto next_block =
272 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition); 412 factory()->NewBlock(nullptr, 2, true, RelocInfo::kNoPosition);
273 next_block->statements()->Add( 413 next_block->statements()->Add(factory()->NewExpressionStatement(
274 factory()->NewExpressionStatement( 414 parser_->BuildIteratorNextResult(
275 descriptor_->parser->BuildIteratorNextResult( 415 factory()->NewVariableProxy(iterator),
276 factory()->NewVariableProxy(iterator), result, 416 result, RelocInfo::kNoPosition),
277 RelocInfo::kNoPosition), 417 RelocInfo::kNoPosition),
278 RelocInfo::kNoPosition), 418 zone());
279 zone());
280 419
281 auto assign_to_done = factory()->NewAssignment( 420 auto assign_to_done = factory()->NewAssignment(
282 Token::ASSIGN, factory()->NewVariableProxy(done), 421 Token::ASSIGN, factory()->NewVariableProxy(done),
283 factory()->NewProperty( 422 factory()->NewProperty(
284 factory()->NewVariableProxy(result), 423 factory()->NewVariableProxy(result),
285 factory()->NewStringLiteral(ast_value_factory()->done_string(), 424 factory()->NewStringLiteral(ast_value_factory()->done_string(),
286 RelocInfo::kNoPosition), 425 RelocInfo::kNoPosition),
287 RelocInfo::kNoPosition), 426 RelocInfo::kNoPosition),
288 RelocInfo::kNoPosition); 427 RelocInfo::kNoPosition);
289 auto next_value = factory()->NewConditional( 428 auto next_value = factory()->NewConditional(
(...skipping 16 matching lines...) Expand all
306 factory()->NewUnaryOperation(Token::NOT, 445 factory()->NewUnaryOperation(Token::NOT,
307 factory()->NewVariableProxy(done), 446 factory()->NewVariableProxy(done),
308 RelocInfo::kNoPosition), 447 RelocInfo::kNoPosition),
309 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition), 448 next_block, factory()->NewEmptyStatement(RelocInfo::kNoPosition),
310 RelocInfo::kNoPosition); 449 RelocInfo::kNoPosition);
311 block_->statements()->Add(if_statement, zone()); 450 block_->statements()->Add(if_statement, zone());
312 451
313 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) { 452 if (!(value->IsLiteral() && value->AsLiteral()->raw_value()->IsTheHole())) {
314 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v)); 453 RecurseIntoSubpattern(value, factory()->NewVariableProxy(v));
315 } 454 }
455 set_context(context);
316 } 456 }
317 457
318 if (spread != nullptr) { 458 if (spread != nullptr) {
319 // array = []; 459 // array = [];
320 // if (!done) %concat_iterable_to_array(array, iterator); 460 // if (!done) %concat_iterable_to_array(array, iterator);
321 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone()); 461 auto empty_exprs = new (zone()) ZoneList<Expression*>(0, zone());
322 auto array = CreateTempVar(factory()->NewArrayLiteral( 462 auto array = CreateTempVar(factory()->NewArrayLiteral(
323 empty_exprs, 463 empty_exprs,
324 // Reuse pattern's literal index - it is unused since there is no 464 // Reuse pattern's literal index - it is unused since there is no
325 // actual literal allocated. 465 // actual literal allocated.
326 node->literal_index(), is_strong(descriptor_->parser->language_mode()), 466 node->literal_index(), is_strong(scope()->language_mode()),
327 RelocInfo::kNoPosition)); 467 RelocInfo::kNoPosition));
328 468
329 auto arguments = new (zone()) ZoneList<Expression*>(2, zone()); 469 auto arguments = new (zone()) ZoneList<Expression*>(2, zone());
330 arguments->Add(factory()->NewVariableProxy(array), zone()); 470 arguments->Add(factory()->NewVariableProxy(array), zone());
331 arguments->Add(factory()->NewVariableProxy(iterator), zone()); 471 arguments->Add(factory()->NewVariableProxy(iterator), zone());
332 auto spread_into_array_call = 472 auto spread_into_array_call =
333 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX, 473 factory()->NewCallRuntime(Context::CONCAT_ITERABLE_TO_ARRAY_INDEX,
334 arguments, RelocInfo::kNoPosition); 474 arguments, RelocInfo::kNoPosition);
335 475
336 auto if_statement = factory()->NewIfStatement( 476 auto if_statement = factory()->NewIfStatement(
337 factory()->NewUnaryOperation(Token::NOT, 477 factory()->NewUnaryOperation(Token::NOT,
338 factory()->NewVariableProxy(done), 478 factory()->NewVariableProxy(done),
339 RelocInfo::kNoPosition), 479 RelocInfo::kNoPosition),
340 factory()->NewExpressionStatement(spread_into_array_call, 480 factory()->NewExpressionStatement(spread_into_array_call,
341 RelocInfo::kNoPosition), 481 RelocInfo::kNoPosition),
342 factory()->NewEmptyStatement(RelocInfo::kNoPosition), 482 factory()->NewEmptyStatement(RelocInfo::kNoPosition),
343 RelocInfo::kNoPosition); 483 RelocInfo::kNoPosition);
344 block_->statements()->Add(if_statement, zone()); 484 block_->statements()->Add(if_statement, zone());
345 485
346 RecurseIntoSubpattern(spread->expression(), 486 RecurseIntoSubpattern(spread->expression(),
347 factory()->NewVariableProxy(array)); 487 factory()->NewVariableProxy(array));
348 } 488 }
349 } 489 }
350 490
351 491
492 void Parser::PatternRewriter::VisitArrayLiteral(ArrayLiteral* node) {
493 Variable* temp_var = nullptr;
494 VisitArrayLiteral(node, &temp_var);
495 }
496
497
352 void Parser::PatternRewriter::VisitAssignment(Assignment* node) { 498 void Parser::PatternRewriter::VisitAssignment(Assignment* node) {
353 // let {<pattern> = <init>} = <value> 499 auto initializer = node->value();
354 // becomes 500 auto value = initializer;
355 // temp = <value>; 501 auto temp = CreateTempVar(current_value_);
356 // <pattern> = temp === undefined ? <init> : temp; 502
503 if (IsInitializerContext()) {
504 // let {<pattern> = <init>} = <value>
505 // becomes
506 // temp = <value>;
507 // <pattern> = temp === undefined ? <init> : temp;
508 Expression* is_undefined = factory()->NewCompareOperation(
509 Token::EQ_STRICT, factory()->NewVariableProxy(temp),
510 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
511 RelocInfo::kNoPosition);
512 value = factory()->NewConditional(is_undefined, initializer,
513 factory()->NewVariableProxy(temp),
514 RelocInfo::kNoPosition);
515 }
516
517 PatternContext old_context = SetAssignmentContextIfNeeded(initializer);
357 DCHECK(node->op() == Token::ASSIGN); 518 DCHECK(node->op() == Token::ASSIGN);
358 auto temp = CreateTempVar(current_value_); 519 if (IsBindingContext(old_context) &&
359 Expression* is_undefined = factory()->NewCompareOperation( 520 descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
360 Token::EQ_STRICT, factory()->NewVariableProxy(temp), 521 scope()->is_arrow_scope()) {
361 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition),
362 RelocInfo::kNoPosition);
363 Expression* initializer = node->value();
364 if (descriptor_->declaration_kind == DeclarationDescriptor::PARAMETER &&
365 descriptor_->scope->is_arrow_scope()) {
366 // TODO(adamk): Only call this if necessary. 522 // TODO(adamk): Only call this if necessary.
367 RewriteParameterInitializerScope( 523 RewriteParameterInitializerScope(parser_->stack_limit(), initializer,
368 descriptor_->parser->stack_limit(), initializer, 524 scope()->outer_scope(), scope());
369 descriptor_->scope->outer_scope(), descriptor_->scope);
370 } 525 }
371 Expression* value = factory()->NewConditional(
372 is_undefined, initializer, factory()->NewVariableProxy(temp),
373 RelocInfo::kNoPosition);
374 RecurseIntoSubpattern(node->target(), value); 526 RecurseIntoSubpattern(node->target(), value);
527 set_context(old_context);
375 } 528 }
376 529
377 530
531 // =============== AssignmentPattern only ==================
532
533 void Parser::PatternRewriter::VisitProperty(v8::internal::Property* node) {
534 DCHECK(IsAssignmentContext());
535 auto value = current_value_;
536
537 Assignment* assignment =
538 factory()->NewAssignment(Token::ASSIGN, node, value, node->position());
539
540 block_->statements()->Add(
541 factory()->NewExpressionStatement(assignment, RelocInfo::kNoPosition),
542 zone());
543 }
544
545
378 // =============== UNREACHABLE ============================= 546 // =============== UNREACHABLE =============================
379 547
380 void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); } 548 void Parser::PatternRewriter::Visit(AstNode* node) { UNREACHABLE(); }
381 549
382 #define NOT_A_PATTERN(Node) \ 550 #define NOT_A_PATTERN(Node) \
383 void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \ 551 void Parser::PatternRewriter::Visit##Node(v8::internal::Node*) { \
384 UNREACHABLE(); \ 552 UNREACHABLE(); \
385 } 553 }
386 554
387 NOT_A_PATTERN(BinaryOperation) 555 NOT_A_PATTERN(BinaryOperation)
(...skipping 17 matching lines...) Expand all
405 NOT_A_PATTERN(ExpressionStatement) 573 NOT_A_PATTERN(ExpressionStatement)
406 NOT_A_PATTERN(ForInStatement) 574 NOT_A_PATTERN(ForInStatement)
407 NOT_A_PATTERN(ForOfStatement) 575 NOT_A_PATTERN(ForOfStatement)
408 NOT_A_PATTERN(ForStatement) 576 NOT_A_PATTERN(ForStatement)
409 NOT_A_PATTERN(FunctionDeclaration) 577 NOT_A_PATTERN(FunctionDeclaration)
410 NOT_A_PATTERN(FunctionLiteral) 578 NOT_A_PATTERN(FunctionLiteral)
411 NOT_A_PATTERN(IfStatement) 579 NOT_A_PATTERN(IfStatement)
412 NOT_A_PATTERN(ImportDeclaration) 580 NOT_A_PATTERN(ImportDeclaration)
413 NOT_A_PATTERN(Literal) 581 NOT_A_PATTERN(Literal)
414 NOT_A_PATTERN(NativeFunctionLiteral) 582 NOT_A_PATTERN(NativeFunctionLiteral)
415 NOT_A_PATTERN(Property)
416 NOT_A_PATTERN(RegExpLiteral) 583 NOT_A_PATTERN(RegExpLiteral)
417 NOT_A_PATTERN(ReturnStatement) 584 NOT_A_PATTERN(ReturnStatement)
418 NOT_A_PATTERN(SloppyBlockFunctionStatement) 585 NOT_A_PATTERN(SloppyBlockFunctionStatement)
419 NOT_A_PATTERN(Spread) 586 NOT_A_PATTERN(Spread)
420 NOT_A_PATTERN(SuperPropertyReference) 587 NOT_A_PATTERN(SuperPropertyReference)
421 NOT_A_PATTERN(SuperCallReference) 588 NOT_A_PATTERN(SuperCallReference)
422 NOT_A_PATTERN(SwitchStatement) 589 NOT_A_PATTERN(SwitchStatement)
423 NOT_A_PATTERN(ThisFunction) 590 NOT_A_PATTERN(ThisFunction)
424 NOT_A_PATTERN(Throw) 591 NOT_A_PATTERN(Throw)
425 NOT_A_PATTERN(TryCatchStatement) 592 NOT_A_PATTERN(TryCatchStatement)
426 NOT_A_PATTERN(TryFinallyStatement) 593 NOT_A_PATTERN(TryFinallyStatement)
427 NOT_A_PATTERN(UnaryOperation) 594 NOT_A_PATTERN(UnaryOperation)
428 NOT_A_PATTERN(VariableDeclaration) 595 NOT_A_PATTERN(VariableDeclaration)
429 NOT_A_PATTERN(WhileStatement) 596 NOT_A_PATTERN(WhileStatement)
430 NOT_A_PATTERN(WithStatement) 597 NOT_A_PATTERN(WithStatement)
431 NOT_A_PATTERN(Yield) 598 NOT_A_PATTERN(Yield)
432 599
433 #undef NOT_A_PATTERN 600 #undef NOT_A_PATTERN
434 } // namespace internal 601 } // namespace internal
435 } // namespace v8 602 } // namespace v8
OLDNEW
« src/flag-definitions.h ('K') | « src/parsing/parser.cc ('k') | src/parsing/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698