OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/ast-expression-visitor.h" |
9 #include "src/ast/ast-literal-reindexer.h" | 10 #include "src/ast/ast-literal-reindexer.h" |
10 #include "src/ast/scopeinfo.h" | 11 #include "src/ast/scopeinfo.h" |
11 #include "src/bailout-reason.h" | 12 #include "src/bailout-reason.h" |
12 #include "src/base/platform/platform.h" | 13 #include "src/base/platform/platform.h" |
13 #include "src/bootstrapper.h" | 14 #include "src/bootstrapper.h" |
14 #include "src/char-predicates-inl.h" | 15 #include "src/char-predicates-inl.h" |
15 #include "src/codegen.h" | 16 #include "src/codegen.h" |
16 #include "src/compiler.h" | 17 #include "src/compiler.h" |
17 #include "src/messages.h" | 18 #include "src/messages.h" |
18 #include "src/parsing/parameter-initializer-rewriter.h" | 19 #include "src/parsing/parameter-initializer-rewriter.h" |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 // ParseInfo during background parsing. | 917 // ParseInfo during background parsing. |
917 DCHECK(!info->script().is_null() || info->source_stream() != NULL); | 918 DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
918 set_allow_lazy(info->allow_lazy_parsing()); | 919 set_allow_lazy(info->allow_lazy_parsing()); |
919 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 920 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
920 set_allow_harmony_sloppy(FLAG_harmony_sloppy); | 921 set_allow_harmony_sloppy(FLAG_harmony_sloppy); |
921 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function); | 922 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function); |
922 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); | 923 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); |
923 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters); | 924 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters); |
924 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); | 925 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); |
925 set_allow_harmony_destructuring_bind(FLAG_harmony_destructuring_bind); | 926 set_allow_harmony_destructuring_bind(FLAG_harmony_destructuring_bind); |
| 927 set_allow_harmony_destructuring_assignment( |
| 928 FLAG_harmony_destructuring_assignment); |
926 set_allow_strong_mode(FLAG_strong_mode); | 929 set_allow_strong_mode(FLAG_strong_mode); |
927 set_allow_legacy_const(FLAG_legacy_const); | 930 set_allow_legacy_const(FLAG_legacy_const); |
928 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 931 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
929 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 932 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
930 ++feature) { | 933 ++feature) { |
931 use_counts_[feature] = 0; | 934 use_counts_[feature] = 0; |
932 } | 935 } |
933 if (info->ast_value_factory() == NULL) { | 936 if (info->ast_value_factory() == NULL) { |
934 // info takes ownership of AstValueFactory. | 937 // info takes ownership of AstValueFactory. |
935 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 938 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1086 if (body->length() != 1 || | 1089 if (body->length() != 1 || |
1087 !body->at(0)->IsExpressionStatement() || | 1090 !body->at(0)->IsExpressionStatement() || |
1088 !body->at(0)->AsExpressionStatement()-> | 1091 !body->at(0)->AsExpressionStatement()-> |
1089 expression()->IsFunctionLiteral()) { | 1092 expression()->IsFunctionLiteral()) { |
1090 ReportMessage(MessageTemplate::kSingleFunctionLiteral); | 1093 ReportMessage(MessageTemplate::kSingleFunctionLiteral); |
1091 ok = false; | 1094 ok = false; |
1092 } | 1095 } |
1093 } | 1096 } |
1094 | 1097 |
1095 if (ok) { | 1098 if (ok) { |
| 1099 ParserTraits::RewriteDestructuringAssignments(); |
1096 result = factory()->NewFunctionLiteral( | 1100 result = factory()->NewFunctionLiteral( |
1097 ast_value_factory()->empty_string(), ast_value_factory(), scope_, | 1101 ast_value_factory()->empty_string(), ast_value_factory(), scope_, |
1098 body, function_state.materialized_literal_count(), | 1102 body, function_state.materialized_literal_count(), |
1099 function_state.expected_property_count(), 0, | 1103 function_state.expected_property_count(), 0, |
1100 FunctionLiteral::kNoDuplicateParameters, | 1104 FunctionLiteral::kNoDuplicateParameters, |
1101 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, | 1105 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, |
1102 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, | 1106 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, |
1103 0); | 1107 0); |
1104 } | 1108 } |
1105 } | 1109 } |
(...skipping 3291 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4397 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 4401 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
4398 CHECK_OK); | 4402 CHECK_OK); |
4399 } | 4403 } |
4400 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) { | 4404 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) { |
4401 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); | 4405 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); |
4402 } | 4406 } |
4403 if (is_strict(language_mode) || allow_harmony_sloppy() || | 4407 if (is_strict(language_mode) || allow_harmony_sloppy() || |
4404 allow_harmony_destructuring_bind()) { | 4408 allow_harmony_destructuring_bind()) { |
4405 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4409 CheckConflictingVarDeclarations(scope, CHECK_OK); |
4406 } | 4410 } |
| 4411 |
| 4412 if (body) { |
| 4413 // If body can be inspected, rewrite queued destructuring assignments |
| 4414 ParserTraits::RewriteDestructuringAssignments(); |
| 4415 } |
4407 } | 4416 } |
4408 | 4417 |
4409 bool has_duplicate_parameters = | 4418 bool has_duplicate_parameters = |
4410 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); | 4419 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); |
4411 FunctionLiteral::ParameterFlag duplicate_parameters = | 4420 FunctionLiteral::ParameterFlag duplicate_parameters = |
4412 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters | 4421 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters |
4413 : FunctionLiteral::kNoDuplicateParameters; | 4422 : FunctionLiteral::kNoDuplicateParameters; |
4414 | 4423 |
4415 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 4424 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
4416 function_name, ast_value_factory(), scope, body, | 4425 function_name, ast_value_factory(), scope, body, |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4525 RelocInfo::kNoPosition); | 4534 RelocInfo::kNoPosition); |
4526 IfStatement* if_statement = factory()->NewIfStatement( | 4535 IfStatement* if_statement = factory()->NewIfStatement( |
4527 condition, factory()->NewExpressionStatement(throw_type_error, | 4536 condition, factory()->NewExpressionStatement(throw_type_error, |
4528 RelocInfo::kNoPosition), | 4537 RelocInfo::kNoPosition), |
4529 factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 4538 factory()->NewEmptyStatement(RelocInfo::kNoPosition), |
4530 RelocInfo::kNoPosition); | 4539 RelocInfo::kNoPosition); |
4531 return if_statement; | 4540 return if_statement; |
4532 } | 4541 } |
4533 | 4542 |
4534 | 4543 |
| 4544 class InitializerRewriter : public AstExpressionVisitor { |
| 4545 public: |
| 4546 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser, |
| 4547 Scope* scope) |
| 4548 : AstExpressionVisitor(stack_limit, root), |
| 4549 parser_(parser), |
| 4550 scope_(scope) {} |
| 4551 |
| 4552 private: |
| 4553 void VisitExpression(Expression* expr) { |
| 4554 RewritableAssignmentExpression* to_rewrite = |
| 4555 expr->AsRewritableAssignmentExpression(); |
| 4556 if (to_rewrite == nullptr || to_rewrite->is_rewritten()) return; |
| 4557 |
| 4558 bool ok = true; |
| 4559 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, to_rewrite, |
| 4560 scope_, &ok); |
| 4561 DCHECK(ok); |
| 4562 } |
| 4563 |
| 4564 private: |
| 4565 Parser* parser_; |
| 4566 Scope* scope_; |
| 4567 }; |
| 4568 |
| 4569 |
| 4570 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { |
| 4571 InitializerRewriter rewriter(stack_limit_, expr, this, scope); |
| 4572 rewriter.Run(); |
| 4573 } |
| 4574 |
| 4575 |
4535 Block* Parser::BuildParameterInitializationBlock( | 4576 Block* Parser::BuildParameterInitializationBlock( |
4536 const ParserFormalParameters& parameters, bool* ok) { | 4577 const ParserFormalParameters& parameters, bool* ok) { |
4537 DCHECK(!parameters.is_simple); | 4578 DCHECK(!parameters.is_simple); |
4538 DCHECK(scope_->is_function_scope()); | 4579 DCHECK(scope_->is_function_scope()); |
4539 Block* init_block = | 4580 Block* init_block = |
4540 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 4581 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
4541 for (int i = 0; i < parameters.params.length(); ++i) { | 4582 for (int i = 0; i < parameters.params.length(); ++i) { |
4542 auto parameter = parameters.params[i]; | 4583 auto parameter = parameters.params[i]; |
4543 DeclarationDescriptor descriptor; | 4584 DeclarationDescriptor descriptor; |
4544 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; | 4585 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; |
(...skipping 10 matching lines...) Expand all Loading... |
4555 // it's just copying from a temp var to the real param var? | 4596 // it's just copying from a temp var to the real param var? |
4556 descriptor.initialization_pos = parameter.pattern->position(); | 4597 descriptor.initialization_pos = parameter.pattern->position(); |
4557 // The initializer position which will end up in, | 4598 // The initializer position which will end up in, |
4558 // Variable::initializer_position(), used for hole check elimination. | 4599 // Variable::initializer_position(), used for hole check elimination. |
4559 int initializer_position = parameter.pattern->position(); | 4600 int initializer_position = parameter.pattern->position(); |
4560 Expression* initial_value = | 4601 Expression* initial_value = |
4561 factory()->NewVariableProxy(parameters.scope->parameter(i)); | 4602 factory()->NewVariableProxy(parameters.scope->parameter(i)); |
4562 if (parameter.initializer != nullptr) { | 4603 if (parameter.initializer != nullptr) { |
4563 // IS_UNDEFINED($param) ? initializer : $param | 4604 // IS_UNDEFINED($param) ? initializer : $param |
4564 DCHECK(!parameter.is_rest); | 4605 DCHECK(!parameter.is_rest); |
| 4606 |
| 4607 // Ensure initializer is rewritten |
| 4608 RewriteParameterInitializer(parameter.initializer, scope_); |
| 4609 |
4565 auto condition = factory()->NewCompareOperation( | 4610 auto condition = factory()->NewCompareOperation( |
4566 Token::EQ_STRICT, | 4611 Token::EQ_STRICT, |
4567 factory()->NewVariableProxy(parameters.scope->parameter(i)), | 4612 factory()->NewVariableProxy(parameters.scope->parameter(i)), |
4568 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 4613 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), |
4569 RelocInfo::kNoPosition); | 4614 RelocInfo::kNoPosition); |
4570 initial_value = factory()->NewConditional( | 4615 initial_value = factory()->NewConditional( |
4571 condition, parameter.initializer, initial_value, | 4616 condition, parameter.initializer, initial_value, |
4572 RelocInfo::kNoPosition); | 4617 RelocInfo::kNoPosition); |
4573 descriptor.initialization_pos = parameter.initializer->position(); | 4618 descriptor.initialization_pos = parameter.initializer->position(); |
4574 initializer_position = parameter.initializer_end_position; | 4619 initializer_position = parameter.initializer_end_position; |
(...skipping 1883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6458 ++use_counts_[feature]; | 6503 ++use_counts_[feature]; |
6459 scope->SetLanguageMode(mode); | 6504 scope->SetLanguageMode(mode); |
6460 } | 6505 } |
6461 | 6506 |
6462 | 6507 |
6463 void Parser::RaiseLanguageMode(LanguageMode mode) { | 6508 void Parser::RaiseLanguageMode(LanguageMode mode) { |
6464 SetLanguageMode(scope_, | 6509 SetLanguageMode(scope_, |
6465 static_cast<LanguageMode>(scope_->language_mode() | mode)); | 6510 static_cast<LanguageMode>(scope_->language_mode() | mode)); |
6466 } | 6511 } |
6467 | 6512 |
| 6513 |
| 6514 void ParserTraits::RewriteDestructuringAssignments() { |
| 6515 parser_->RewriteDestructuringAssignments(); |
| 6516 } |
| 6517 |
| 6518 |
| 6519 void Parser::RewriteDestructuringAssignments() { |
| 6520 FunctionState* func = function_state_; |
| 6521 if (!allow_harmony_destructuring_assignment()) return; |
| 6522 const List<DestructuringAssignment>& assignments = |
| 6523 func->destructuring_assignments_to_rewrite(); |
| 6524 for (int i = assignments.length() - 1; i >= 0; --i) { |
| 6525 // Rewrite list in reverse, so that nested assignment patterns are rewritten |
| 6526 // correctly. |
| 6527 DestructuringAssignment pair = assignments.at(i); |
| 6528 RewritableAssignmentExpression* to_rewrite = |
| 6529 pair.assignment->AsRewritableAssignmentExpression(); |
| 6530 Scope* scope = pair.scope; |
| 6531 DCHECK_NOT_NULL(to_rewrite); |
| 6532 if (!to_rewrite->is_rewritten()) { |
| 6533 bool ok = true; |
| 6534 PatternRewriter::RewriteDestructuringAssignment(this, to_rewrite, scope, |
| 6535 &ok); |
| 6536 DCHECK(ok); |
| 6537 } |
| 6538 } |
| 6539 } |
| 6540 |
| 6541 |
| 6542 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
| 6543 DCHECK(expr->IsRewritableAssignmentExpression()); |
| 6544 parser_->function_state_->AddDestructuringAssignment( |
| 6545 Parser::DestructuringAssignment(expr, parser_->scope_)); |
| 6546 } |
| 6547 |
| 6548 |
6468 } // namespace internal | 6549 } // namespace internal |
6469 } // namespace v8 | 6550 } // namespace v8 |
OLD | NEW |