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

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