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

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