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

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

Powered by Google App Engine
This is Rietveld 408576698