| 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/parser.h" | 5 #include "src/parser.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/ast-literal-reindexer.h" | 9 #include "src/ast-literal-reindexer.h" |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| 11 #include "src/base/platform/platform.h" | 11 #include "src/base/platform/platform.h" |
| 12 #include "src/bootstrapper.h" | 12 #include "src/bootstrapper.h" |
| 13 #include "src/char-predicates-inl.h" | 13 #include "src/char-predicates-inl.h" |
| 14 #include "src/codegen.h" | 14 #include "src/codegen.h" |
| 15 #include "src/compiler.h" | 15 #include "src/compiler.h" |
| 16 #include "src/messages.h" | 16 #include "src/messages.h" |
| 17 #include "src/parameter-initializer-rewriter.h" | 17 #include "src/parameter-initializer-rewriter.h" |
| 18 #include "src/preparser.h" | 18 #include "src/preparser.h" |
| 19 #include "src/rewriter.h" | 19 #include "src/rewriter.h" |
| 20 #include "src/runtime/runtime.h" | 20 #include "src/runtime/runtime.h" |
| 21 #include "src/scanner-character-streams.h" | 21 #include "src/scanner-character-streams.h" |
| 22 #include "src/scopeinfo.h" | 22 #include "src/scopeinfo.h" |
| 23 #include "src/string-stream.h" | 23 #include "src/string-stream.h" |
| 24 #include "src/ast-expression-visitor.h" |
| 24 | 25 |
| 25 namespace v8 { | 26 namespace v8 { |
| 26 namespace internal { | 27 namespace internal { |
| 27 | 28 |
| 28 ScriptData::ScriptData(const byte* data, int length) | 29 ScriptData::ScriptData(const byte* data, int length) |
| 29 : owns_data_(false), rejected_(false), data_(data), length_(length) { | 30 : owns_data_(false), rejected_(false), data_(data), length_(length) { |
| 30 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { | 31 if (!IsAligned(reinterpret_cast<intptr_t>(data), kPointerAlignment)) { |
| 31 byte* copy = NewArray<byte>(length); | 32 byte* copy = NewArray<byte>(length); |
| 32 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); | 33 DCHECK(IsAligned(reinterpret_cast<intptr_t>(copy), kPointerAlignment)); |
| 33 CopyBytes(copy, data, length); | 34 CopyBytes(copy, data, length); |
| (...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 913 // ParseInfo during background parsing. | 914 // ParseInfo during background parsing. |
| 914 DCHECK(!info->script().is_null() || info->source_stream() != NULL); | 915 DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
| 915 set_allow_lazy(info->allow_lazy_parsing()); | 916 set_allow_lazy(info->allow_lazy_parsing()); |
| 916 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 917 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
| 917 set_allow_harmony_sloppy(FLAG_harmony_sloppy); | 918 set_allow_harmony_sloppy(FLAG_harmony_sloppy); |
| 918 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function); | 919 set_allow_harmony_sloppy_function(FLAG_harmony_sloppy_function); |
| 919 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); | 920 set_allow_harmony_sloppy_let(FLAG_harmony_sloppy_let); |
| 920 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters); | 921 set_allow_harmony_rest_parameters(FLAG_harmony_rest_parameters); |
| 921 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); | 922 set_allow_harmony_default_parameters(FLAG_harmony_default_parameters); |
| 922 set_allow_harmony_destructuring(FLAG_harmony_destructuring); | 923 set_allow_harmony_destructuring(FLAG_harmony_destructuring); |
| 924 set_allow_harmony_destructuring_assignment( |
| 925 FLAG_harmony_destructuring_assignment); |
| 923 set_allow_strong_mode(FLAG_strong_mode); | 926 set_allow_strong_mode(FLAG_strong_mode); |
| 924 set_allow_legacy_const(FLAG_legacy_const); | 927 set_allow_legacy_const(FLAG_legacy_const); |
| 925 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 928 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
| 926 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 929 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 927 ++feature) { | 930 ++feature) { |
| 928 use_counts_[feature] = 0; | 931 use_counts_[feature] = 0; |
| 929 } | 932 } |
| 930 if (info->ast_value_factory() == NULL) { | 933 if (info->ast_value_factory() == NULL) { |
| 931 // info takes ownership of AstValueFactory. | 934 // info takes ownership of AstValueFactory. |
| 932 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 935 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
| (...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 if (body->length() != 1 || | 1086 if (body->length() != 1 || |
| 1084 !body->at(0)->IsExpressionStatement() || | 1087 !body->at(0)->IsExpressionStatement() || |
| 1085 !body->at(0)->AsExpressionStatement()-> | 1088 !body->at(0)->AsExpressionStatement()-> |
| 1086 expression()->IsFunctionLiteral()) { | 1089 expression()->IsFunctionLiteral()) { |
| 1087 ReportMessage(MessageTemplate::kSingleFunctionLiteral); | 1090 ReportMessage(MessageTemplate::kSingleFunctionLiteral); |
| 1088 ok = false; | 1091 ok = false; |
| 1089 } | 1092 } |
| 1090 } | 1093 } |
| 1091 | 1094 |
| 1092 if (ok) { | 1095 if (ok) { |
| 1096 ParserTraits::RewriteDestructuringAssignments(); |
| 1093 result = factory()->NewFunctionLiteral( | 1097 result = factory()->NewFunctionLiteral( |
| 1094 ast_value_factory()->empty_string(), ast_value_factory(), scope_, | 1098 ast_value_factory()->empty_string(), ast_value_factory(), scope_, |
| 1095 body, function_state.materialized_literal_count(), | 1099 body, function_state.materialized_literal_count(), |
| 1096 function_state.expected_property_count(), 0, | 1100 function_state.expected_property_count(), 0, |
| 1097 FunctionLiteral::kNoDuplicateParameters, | 1101 FunctionLiteral::kNoDuplicateParameters, |
| 1098 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, | 1102 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, |
| 1099 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, | 1103 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, |
| 1100 0); | 1104 0); |
| 1101 } | 1105 } |
| 1102 } | 1106 } |
| (...skipping 2288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3391 assign_iterator, | 3395 assign_iterator, |
| 3392 next_result, | 3396 next_result, |
| 3393 result_done, | 3397 result_done, |
| 3394 assign_each); | 3398 assign_each); |
| 3395 } else { | 3399 } else { |
| 3396 stmt->Initialize(each, subject, body); | 3400 stmt->Initialize(each, subject, body); |
| 3397 } | 3401 } |
| 3398 } | 3402 } |
| 3399 | 3403 |
| 3400 | 3404 |
| 3405 Expression* Parser::RewriteDestructuringAssignmentExpression( |
| 3406 Expression* expression) { |
| 3407 return expression; |
| 3408 } |
| 3409 |
| 3410 |
| 3401 Statement* Parser::DesugarLexicalBindingsInForStatement( | 3411 Statement* Parser::DesugarLexicalBindingsInForStatement( |
| 3402 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, | 3412 Scope* inner_scope, bool is_const, ZoneList<const AstRawString*>* names, |
| 3403 ForStatement* loop, Statement* init, Expression* cond, Statement* next, | 3413 ForStatement* loop, Statement* init, Expression* cond, Statement* next, |
| 3404 Statement* body, bool* ok) { | 3414 Statement* body, bool* ok) { |
| 3405 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are | 3415 // ES6 13.7.4.8 specifies that on each loop iteration the let variables are |
| 3406 // copied into a new environment. Moreover, the "next" statement must be | 3416 // copied into a new environment. Moreover, the "next" statement must be |
| 3407 // evaluated not in the environment of the just completed iteration but in | 3417 // evaluated not in the environment of the just completed iteration but in |
| 3408 // that of the upcoming one. We achieve this with the following desugaring. | 3418 // that of the upcoming one. We achieve this with the following desugaring. |
| 3409 // Extra care is needed to preserve the completion value of the original loop. | 3419 // Extra care is needed to preserve the completion value of the original loop. |
| 3410 // | 3420 // |
| (...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4405 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), | 4415 CheckStrictOctalLiteral(scope->start_position(), scope->end_position(), |
| 4406 CHECK_OK); | 4416 CHECK_OK); |
| 4407 } | 4417 } |
| 4408 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) { | 4418 if (is_sloppy(language_mode) && allow_harmony_sloppy_function()) { |
| 4409 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); | 4419 InsertSloppyBlockFunctionVarBindings(scope, CHECK_OK); |
| 4410 } | 4420 } |
| 4411 if (is_strict(language_mode) || allow_harmony_sloppy() || | 4421 if (is_strict(language_mode) || allow_harmony_sloppy() || |
| 4412 allow_harmony_destructuring()) { | 4422 allow_harmony_destructuring()) { |
| 4413 CheckConflictingVarDeclarations(scope, CHECK_OK); | 4423 CheckConflictingVarDeclarations(scope, CHECK_OK); |
| 4414 } | 4424 } |
| 4425 |
| 4426 ParserTraits::RewriteDestructuringAssignments(); |
| 4415 } | 4427 } |
| 4416 | 4428 |
| 4417 bool has_duplicate_parameters = | 4429 bool has_duplicate_parameters = |
| 4418 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); | 4430 !formals_classifier.is_valid_formal_parameter_list_without_duplicates(); |
| 4419 FunctionLiteral::ParameterFlag duplicate_parameters = | 4431 FunctionLiteral::ParameterFlag duplicate_parameters = |
| 4420 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters | 4432 has_duplicate_parameters ? FunctionLiteral::kHasDuplicateParameters |
| 4421 : FunctionLiteral::kNoDuplicateParameters; | 4433 : FunctionLiteral::kNoDuplicateParameters; |
| 4422 | 4434 |
| 4423 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 4435 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
| 4424 function_name, ast_value_factory(), scope, body, | 4436 function_name, ast_value_factory(), scope, body, |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4533 RelocInfo::kNoPosition); | 4545 RelocInfo::kNoPosition); |
| 4534 IfStatement* if_statement = factory()->NewIfStatement( | 4546 IfStatement* if_statement = factory()->NewIfStatement( |
| 4535 condition, factory()->NewExpressionStatement(throw_type_error, | 4547 condition, factory()->NewExpressionStatement(throw_type_error, |
| 4536 RelocInfo::kNoPosition), | 4548 RelocInfo::kNoPosition), |
| 4537 factory()->NewEmptyStatement(RelocInfo::kNoPosition), | 4549 factory()->NewEmptyStatement(RelocInfo::kNoPosition), |
| 4538 RelocInfo::kNoPosition); | 4550 RelocInfo::kNoPosition); |
| 4539 return if_statement; | 4551 return if_statement; |
| 4540 } | 4552 } |
| 4541 | 4553 |
| 4542 | 4554 |
| 4555 class InitializerRewriter : public AstExpressionVisitor { |
| 4556 public: |
| 4557 InitializerRewriter(uintptr_t stack_limit, Expression* root, Parser* parser, |
| 4558 Scope* scope) |
| 4559 : AstExpressionVisitor(stack_limit, root), |
| 4560 parser_(parser), |
| 4561 scope_(scope) {} |
| 4562 |
| 4563 private: |
| 4564 void VisitExpression(Expression* expr) { |
| 4565 if (expr->IsAssignment()) { |
| 4566 Assignment* node = expr->AsAssignment(); |
| 4567 Expression* target = node->target(); |
| 4568 if (node->op() == Token::ASSIGN && target->IsAssignmentPattern() && |
| 4569 !target->AsAssignmentPattern()->is_rewritten()) { |
| 4570 bool ok = true; |
| 4571 Parser::PatternRewriter::RewriteDestructuringAssignment(parser_, node, |
| 4572 scope_, &ok); |
| 4573 DCHECK(ok); |
| 4574 } |
| 4575 } |
| 4576 } |
| 4577 /* |
| 4578 #define NOT_INITIALIZER(T) void Visit##T(T* node) {} |
| 4579 NOT_INITIALIZER(FunctionLiteral) |
| 4580 NOT_INITIALIZER(ClassLiteral) |
| 4581 NOT_INITIALIZER(NativeFunctionLiteral) |
| 4582 NOT_INITIALIZER(Conditional) |
| 4583 NOT_INITIALIZER(VariableProxy) |
| 4584 NOT_INITIALIZER(Literal) |
| 4585 NOT_INITIALIZER(RegExpLiteral) |
| 4586 NOT_INITIALIZER(ObjectLiteral) |
| 4587 NOT_INITIALIZER(ArrayLiteral) |
| 4588 NOT_INITIALIZER(AssignmentPattern) |
| 4589 NOT_INITIALIZER(Yield) |
| 4590 NOT_INITIALIZER(Throw) |
| 4591 NOT_INITIALIZER(Property) |
| 4592 NOT_INITIALIZER(Call) |
| 4593 NOT_INITIALIZER(CallNew) |
| 4594 NOT_INITIALIZER(CallRuntime) |
| 4595 NOT_INITIALIZER(UnaryOperation) |
| 4596 NOT_INITIALIZER(CountOperation) |
| 4597 NOT_INITIALIZER(BinaryOperation) |
| 4598 NOT_INITIALIZER(CompareOperation) |
| 4599 NOT_INITIALIZER(Spread) |
| 4600 NOT_INITIALIZER(ThisFunction) |
| 4601 NOT_INITIALIZER(SuperPropertyReference) |
| 4602 NOT_INITIALIZER(SuperCallReference) |
| 4603 NOT_INITIALIZER(CaseClause) |
| 4604 NOT_INITIALIZER(EmptyParentheses) |
| 4605 NOT_INITIALIZER(DoExpression) |
| 4606 #undef NOT_INITIALIZER*/ |
| 4607 private: |
| 4608 Parser* parser_; |
| 4609 Scope* scope_; |
| 4610 }; |
| 4611 |
| 4612 |
| 4613 void Parser::RewriteParameterInitializer(Expression* expr, Scope* scope) { |
| 4614 InitializerRewriter rewriter(stack_limit_, expr, this, scope); |
| 4615 rewriter.Run(); |
| 4616 } |
| 4617 |
| 4618 |
| 4543 Block* Parser::BuildParameterInitializationBlock( | 4619 Block* Parser::BuildParameterInitializationBlock( |
| 4544 const ParserFormalParameters& parameters, bool* ok) { | 4620 const ParserFormalParameters& parameters, bool* ok) { |
| 4545 DCHECK(!parameters.is_simple); | 4621 DCHECK(!parameters.is_simple); |
| 4546 DCHECK(scope_->is_function_scope()); | 4622 DCHECK(scope_->is_function_scope()); |
| 4547 Block* init_block = | 4623 Block* init_block = |
| 4548 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); | 4624 factory()->NewBlock(NULL, 1, true, RelocInfo::kNoPosition); |
| 4549 for (int i = 0; i < parameters.params.length(); ++i) { | 4625 for (int i = 0; i < parameters.params.length(); ++i) { |
| 4550 auto parameter = parameters.params[i]; | 4626 auto parameter = parameters.params[i]; |
| 4551 DeclarationDescriptor descriptor; | 4627 DeclarationDescriptor descriptor; |
| 4552 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; | 4628 descriptor.declaration_kind = DeclarationDescriptor::PARAMETER; |
| 4553 descriptor.parser = this; | 4629 descriptor.parser = this; |
| 4554 descriptor.declaration_scope = scope_; | 4630 descriptor.declaration_scope = scope_; |
| 4555 descriptor.scope = scope_; | 4631 descriptor.scope = scope_; |
| 4556 descriptor.hoist_scope = nullptr; | 4632 descriptor.hoist_scope = nullptr; |
| 4557 descriptor.mode = LET; | 4633 descriptor.mode = LET; |
| 4558 descriptor.is_const = false; | 4634 descriptor.is_const = false; |
| 4559 descriptor.needs_init = true; | 4635 descriptor.needs_init = true; |
| 4560 descriptor.declaration_pos = parameter.pattern->position(); | 4636 descriptor.declaration_pos = parameter.pattern->position(); |
| 4561 descriptor.initialization_pos = parameter.pattern->position(); | 4637 descriptor.initialization_pos = parameter.pattern->position(); |
| 4562 descriptor.init_op = Token::INIT_LET; | 4638 descriptor.init_op = Token::INIT_LET; |
| 4563 Expression* initial_value = | 4639 Expression* initial_value = |
| 4564 factory()->NewVariableProxy(parameters.scope->parameter(i)); | 4640 factory()->NewVariableProxy(parameters.scope->parameter(i)); |
| 4565 if (parameter.initializer != nullptr) { | 4641 if (parameter.initializer != nullptr) { |
| 4566 // IS_UNDEFINED($param) ? initializer : $param | 4642 // IS_UNDEFINED($param) ? initializer : $param |
| 4567 DCHECK(!parameter.is_rest); | 4643 DCHECK(!parameter.is_rest); |
| 4644 |
| 4645 // Ensure initializer is rewritten |
| 4646 RewriteParameterInitializer(parameter.initializer, scope_); |
| 4647 |
| 4568 auto condition = factory()->NewCompareOperation( | 4648 auto condition = factory()->NewCompareOperation( |
| 4569 Token::EQ_STRICT, | 4649 Token::EQ_STRICT, |
| 4570 factory()->NewVariableProxy(parameters.scope->parameter(i)), | 4650 factory()->NewVariableProxy(parameters.scope->parameter(i)), |
| 4571 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), | 4651 factory()->NewUndefinedLiteral(RelocInfo::kNoPosition), |
| 4572 RelocInfo::kNoPosition); | 4652 RelocInfo::kNoPosition); |
| 4573 initial_value = factory()->NewConditional( | 4653 initial_value = factory()->NewConditional( |
| 4574 condition, parameter.initializer, initial_value, | 4654 condition, parameter.initializer, initial_value, |
| 4575 RelocInfo::kNoPosition); | 4655 RelocInfo::kNoPosition); |
| 4576 descriptor.initialization_pos = parameter.initializer->position(); | 4656 descriptor.initialization_pos = parameter.initializer->position(); |
| 4577 } else if (parameter.is_rest) { | 4657 } else if (parameter.is_rest) { |
| (...skipping 1848 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6426 } | 6506 } |
| 6427 | 6507 |
| 6428 | 6508 |
| 6429 void Parser::RaiseLanguageMode(LanguageMode mode) { | 6509 void Parser::RaiseLanguageMode(LanguageMode mode) { |
| 6430 SetLanguageMode(scope_, | 6510 SetLanguageMode(scope_, |
| 6431 static_cast<LanguageMode>(scope_->language_mode() | mode)); | 6511 static_cast<LanguageMode>(scope_->language_mode() | mode)); |
| 6432 } | 6512 } |
| 6433 | 6513 |
| 6434 } // namespace internal | 6514 } // namespace internal |
| 6435 } // namespace v8 | 6515 } // namespace v8 |
| OLD | NEW |