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-rewriter.h" | 9 #include "src/ast/ast-expression-rewriter.h" |
10 #include "src/ast/ast-expression-visitor.h" | 10 #include "src/ast/ast-expression-visitor.h" |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 if (compile_options_ == ScriptCompiler::kNoCompileOptions) { | 172 if (compile_options_ == ScriptCompiler::kNoCompileOptions) { |
173 cached_parse_data_ = NULL; | 173 cached_parse_data_ = NULL; |
174 } else { | 174 } else { |
175 DCHECK(info->cached_data() != NULL); | 175 DCHECK(info->cached_data() != NULL); |
176 if (compile_options_ == ScriptCompiler::kConsumeParserCache) { | 176 if (compile_options_ == ScriptCompiler::kConsumeParserCache) { |
177 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); | 177 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); |
178 } | 178 } |
179 } | 179 } |
180 } | 180 } |
181 | 181 |
182 | 182 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, |
183 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, | 183 bool call_super, Scope* scope, |
184 int pos, int end_pos, | 184 int pos, int end_pos, |
185 LanguageMode language_mode) { | 185 LanguageMode language_mode) { |
186 int materialized_literal_count = -1; | 186 int materialized_literal_count = -1; |
187 int expected_property_count = -1; | 187 int expected_property_count = -1; |
188 int parameter_count = 0; | 188 int parameter_count = 0; |
189 const AstRawString* name = ast_value_factory()->empty_string(); | 189 if (name == nullptr) name = ast_value_factory()->empty_string(); |
190 | |
191 | 190 |
192 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor | 191 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor |
193 : FunctionKind::kDefaultBaseConstructor; | 192 : FunctionKind::kDefaultBaseConstructor; |
194 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind); | 193 Scope* function_scope = NewScope(scope, FUNCTION_SCOPE, kind); |
195 SetLanguageMode(function_scope, | 194 SetLanguageMode(function_scope, |
196 static_cast<LanguageMode>(language_mode | STRICT)); | 195 static_cast<LanguageMode>(language_mode | STRICT)); |
197 // Set start and end position to the same value | 196 // Set start and end position to the same value |
198 function_scope->set_start_position(pos); | 197 function_scope->set_start_position(pos); |
199 function_scope->set_end_position(pos); | 198 function_scope->set_end_position(pos); |
200 ZoneList<Statement*>* body = NULL; | 199 ZoneList<Statement*>* body = NULL; |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 // We desugar function.sent into %GeneratorGetInput(generator). | 648 // We desugar function.sent into %GeneratorGetInput(generator). |
650 Zone* zone = parser_->zone(); | 649 Zone* zone = parser_->zone(); |
651 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone); | 650 ZoneList<Expression*>* args = new (zone) ZoneList<Expression*>(1, zone); |
652 VariableProxy* generator = factory->NewVariableProxy( | 651 VariableProxy* generator = factory->NewVariableProxy( |
653 parser_->function_state_->generator_object_variable()); | 652 parser_->function_state_->generator_object_variable()); |
654 args->Add(generator, zone); | 653 args->Add(generator, zone); |
655 return factory->NewCallRuntime(Runtime::kGeneratorGetInput, args, pos); | 654 return factory->NewCallRuntime(Runtime::kGeneratorGetInput, args, pos); |
656 } | 655 } |
657 | 656 |
658 | 657 |
659 Expression* ParserTraits::DefaultConstructor(bool call_super, Scope* scope, | |
660 int pos, int end_pos, | |
661 LanguageMode mode) { | |
662 return parser_->DefaultConstructor(call_super, scope, pos, end_pos, mode); | |
663 } | |
664 | |
665 | |
666 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos, | 658 Literal* ParserTraits::ExpressionFromLiteral(Token::Value token, int pos, |
667 Scanner* scanner, | 659 Scanner* scanner, |
668 AstNodeFactory* factory) { | 660 AstNodeFactory* factory) { |
669 switch (token) { | 661 switch (token) { |
670 case Token::NULL_LITERAL: | 662 case Token::NULL_LITERAL: |
671 return factory->NewNullLiteral(pos); | 663 return factory->NewNullLiteral(pos); |
672 case Token::TRUE_LITERAL: | 664 case Token::TRUE_LITERAL: |
673 return factory->NewBooleanLiteral(true, pos); | 665 return factory->NewBooleanLiteral(true, pos); |
674 case Token::FALSE_LITERAL: | 666 case Token::FALSE_LITERAL: |
675 return factory->NewBooleanLiteral(false, pos); | 667 return factory->NewBooleanLiteral(false, pos); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1103 // The pre-parser saw an arrow function here, so the full parser | 1095 // The pre-parser saw an arrow function here, so the full parser |
1104 // must produce a FunctionLiteral. | 1096 // must produce a FunctionLiteral. |
1105 DCHECK(expression->IsFunctionLiteral()); | 1097 DCHECK(expression->IsFunctionLiteral()); |
1106 result = expression->AsFunctionLiteral(); | 1098 result = expression->AsFunctionLiteral(); |
1107 } else { | 1099 } else { |
1108 ok = false; | 1100 ok = false; |
1109 } | 1101 } |
1110 } | 1102 } |
1111 } | 1103 } |
1112 } else if (shared_info->is_default_constructor()) { | 1104 } else if (shared_info->is_default_constructor()) { |
1113 result = DefaultConstructor(IsSubclassConstructor(shared_info->kind()), | 1105 result = DefaultConstructor( |
1114 scope, shared_info->start_position(), | 1106 raw_name, IsSubclassConstructor(shared_info->kind()), scope, |
1115 shared_info->end_position(), | 1107 shared_info->start_position(), shared_info->end_position(), |
1116 shared_info->language_mode()); | 1108 shared_info->language_mode()); |
1117 } else { | 1109 } else { |
1118 result = ParseFunctionLiteral( | 1110 result = ParseFunctionLiteral( |
1119 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, | 1111 raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, |
1120 shared_info->kind(), RelocInfo::kNoPosition, function_type, | 1112 shared_info->kind(), RelocInfo::kNoPosition, function_type, |
1121 FunctionLiteral::kNormalArity, shared_info->language_mode(), &ok); | 1113 FunctionLiteral::kNormalArity, shared_info->language_mode(), &ok); |
1122 } | 1114 } |
1123 // Make sure the results agree. | 1115 // Make sure the results agree. |
1124 DCHECK(ok == (result != NULL)); | 1116 DCHECK(ok == (result != NULL)); |
1125 } | 1117 } |
1126 | 1118 |
(...skipping 1343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2470 // Don't infer if it is "a = function(){...}();"-like expression. | 2462 // Don't infer if it is "a = function(){...}();"-like expression. |
2471 if (single_name) { | 2463 if (single_name) { |
2472 if (fni_ != NULL && value->AsCall() == NULL && | 2464 if (fni_ != NULL && value->AsCall() == NULL && |
2473 value->AsCallNew() == NULL) { | 2465 value->AsCallNew() == NULL) { |
2474 fni_->Infer(); | 2466 fni_->Infer(); |
2475 } else { | 2467 } else { |
2476 fni_->RemoveLastFunction(); | 2468 fni_->RemoveLastFunction(); |
2477 } | 2469 } |
2478 } | 2470 } |
2479 | 2471 |
2480 if (allow_harmony_function_name() && single_name) { | 2472 if (allow_harmony_function_name()) { |
2481 if (value->IsFunctionLiteral()) { | 2473 ParserTraits::SetFunctionNameFromIdentifierRef(value, pattern); |
2482 auto function_literal = value->AsFunctionLiteral(); | |
2483 if (function_literal->is_anonymous()) { | |
2484 function_literal->set_raw_name(single_name); | |
2485 } | |
2486 } else if (value->IsClassLiteral()) { | |
2487 auto class_literal = value->AsClassLiteral(); | |
2488 if (class_literal->raw_name() == nullptr) { | |
2489 class_literal->set_raw_name(single_name); | |
2490 } | |
2491 } | |
2492 } | 2474 } |
2493 | 2475 |
2494 // End position of the initializer is after the assignment expression. | 2476 // End position of the initializer is after the assignment expression. |
2495 initializer_position = scanner()->location().end_pos; | 2477 initializer_position = scanner()->location().end_pos; |
2496 } else { | 2478 } else { |
2497 if ((parsing_result->descriptor.mode == CONST || is_pattern) && | 2479 if ((parsing_result->descriptor.mode == CONST || is_pattern) && |
2498 !is_for_iteration_variable) { | 2480 !is_for_iteration_variable) { |
2499 ParserTraits::ReportMessageAt( | 2481 ParserTraits::ReportMessageAt( |
2500 Scanner::Location(decl_pos, scanner()->location().end_pos), | 2482 Scanner::Location(decl_pos, scanner()->location().end_pos), |
2501 MessageTemplate::kDeclarationMissingInitializer, | 2483 MessageTemplate::kDeclarationMissingInitializer, |
(...skipping 2387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4889 | 4871 |
4890 const bool has_extends = extends != nullptr; | 4872 const bool has_extends = extends != nullptr; |
4891 while (peek() != Token::RBRACE) { | 4873 while (peek() != Token::RBRACE) { |
4892 if (Check(Token::SEMICOLON)) continue; | 4874 if (Check(Token::SEMICOLON)) continue; |
4893 FuncNameInferrer::State fni_state(fni_); | 4875 FuncNameInferrer::State fni_state(fni_); |
4894 const bool in_class = true; | 4876 const bool in_class = true; |
4895 const bool is_static = false; | 4877 const bool is_static = false; |
4896 bool is_computed_name = false; // Classes do not care about computed | 4878 bool is_computed_name = false; // Classes do not care about computed |
4897 // property names here. | 4879 // property names here. |
4898 ExpressionClassifier classifier; | 4880 ExpressionClassifier classifier; |
4899 const AstRawString* name = nullptr; | 4881 const AstRawString* property_name = nullptr; |
4900 ObjectLiteral::Property* property = ParsePropertyDefinition( | 4882 ObjectLiteral::Property* property = ParsePropertyDefinition( |
4901 &checker, in_class, has_extends, is_static, &is_computed_name, | 4883 &checker, in_class, has_extends, is_static, &is_computed_name, |
4902 &has_seen_constructor, &classifier, &name, CHECK_OK); | 4884 &has_seen_constructor, &classifier, &property_name, CHECK_OK); |
4903 property = ParserTraits::RewriteNonPatternObjectLiteralProperty( | 4885 property = ParserTraits::RewriteNonPatternObjectLiteralProperty( |
4904 property, &classifier, CHECK_OK); | 4886 property, &classifier, CHECK_OK); |
4905 | 4887 |
4906 if (has_seen_constructor && constructor == NULL) { | 4888 if (has_seen_constructor && constructor == NULL) { |
4907 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 4889 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
4908 DCHECK_NOT_NULL(constructor); | 4890 DCHECK_NOT_NULL(constructor); |
| 4891 constructor->set_raw_name( |
| 4892 name != nullptr ? name : ast_value_factory()->empty_string()); |
4909 } else { | 4893 } else { |
4910 properties->Add(property, zone()); | 4894 properties->Add(property, zone()); |
4911 } | 4895 } |
4912 | 4896 |
4913 if (fni_ != NULL) fni_->Infer(); | 4897 if (fni_ != NULL) fni_->Infer(); |
4914 | 4898 |
4915 if (allow_harmony_function_name()) { | 4899 if (allow_harmony_function_name() && |
4916 SetFunctionNameFromPropertyName(property, name); | 4900 property_name != ast_value_factory()->constructor_string()) { |
| 4901 SetFunctionNameFromPropertyName(property, property_name); |
4917 } | 4902 } |
4918 } | 4903 } |
4919 | 4904 |
4920 Expect(Token::RBRACE, CHECK_OK); | 4905 Expect(Token::RBRACE, CHECK_OK); |
4921 int end_pos = scanner()->location().end_pos; | 4906 int end_pos = scanner()->location().end_pos; |
4922 | 4907 |
4923 if (constructor == NULL) { | 4908 if (constructor == NULL) { |
4924 constructor = DefaultConstructor(extends != NULL, block_scope, pos, end_pos, | 4909 constructor = DefaultConstructor(name, extends != NULL, block_scope, pos, |
4925 block_scope->language_mode()); | 4910 end_pos, block_scope->language_mode()); |
4926 } | 4911 } |
4927 | 4912 |
4928 // Note that we do not finalize this block scope because strong | 4913 // Note that we do not finalize this block scope because strong |
4929 // mode uses it as a sentinel value indicating an anonymous class. | 4914 // mode uses it as a sentinel value indicating an anonymous class. |
4930 block_scope->set_end_position(end_pos); | 4915 block_scope->set_end_position(end_pos); |
4931 | 4916 |
4932 if (name != NULL) { | 4917 if (name != NULL) { |
4933 DCHECK_NOT_NULL(proxy); | 4918 DCHECK_NOT_NULL(proxy); |
4934 proxy->var()->set_initializer_position(end_pos); | 4919 proxy->var()->set_initializer_position(end_pos); |
4935 } | 4920 } |
4936 | 4921 |
4937 return factory()->NewClassLiteral(name, block_scope, proxy, extends, | 4922 return factory()->NewClassLiteral(block_scope, proxy, extends, constructor, |
4938 constructor, properties, pos, end_pos); | 4923 properties, pos, end_pos); |
4939 } | 4924 } |
4940 | 4925 |
4941 | 4926 |
4942 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4927 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
4943 // CallRuntime :: | 4928 // CallRuntime :: |
4944 // '%' Identifier Arguments | 4929 // '%' Identifier Arguments |
4945 | 4930 |
4946 int pos = peek_position(); | 4931 int pos = peek_position(); |
4947 Expect(Token::MOD, CHECK_OK); | 4932 Expect(Token::MOD, CHECK_OK); |
4948 // Allow "eval" or "arguments" for backward compatibility. | 4933 // Allow "eval" or "arguments" for backward compatibility. |
(...skipping 783 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5732 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { | 5717 void ParserTraits::QueueDestructuringAssignmentForRewriting(Expression* expr) { |
5733 DCHECK(expr->IsRewritableAssignmentExpression()); | 5718 DCHECK(expr->IsRewritableAssignmentExpression()); |
5734 parser_->function_state_->AddDestructuringAssignment( | 5719 parser_->function_state_->AddDestructuringAssignment( |
5735 Parser::DestructuringAssignment(expr, parser_->scope_)); | 5720 Parser::DestructuringAssignment(expr, parser_->scope_)); |
5736 } | 5721 } |
5737 | 5722 |
5738 | 5723 |
5739 void ParserTraits::SetFunctionNameFromPropertyName( | 5724 void ParserTraits::SetFunctionNameFromPropertyName( |
5740 ObjectLiteralProperty* property, const AstRawString* name) { | 5725 ObjectLiteralProperty* property, const AstRawString* name) { |
5741 Expression* value = property->value(); | 5726 Expression* value = property->value(); |
5742 if (!value->IsFunctionLiteral() && !value->IsClassLiteral()) return; | 5727 if (!value->IsAnonymousFunctionDefinition()) return; |
5743 | 5728 |
5744 // TODO(adamk): Support computed names. | 5729 // TODO(adamk): Support computed names. |
5745 if (property->is_computed_name()) return; | 5730 if (property->is_computed_name()) return; |
5746 DCHECK_NOT_NULL(name); | 5731 DCHECK_NOT_NULL(name); |
5747 | 5732 |
5748 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]] | 5733 // Ignore "__proto__" as a name when it's being used to set the [[Prototype]] |
5749 // of an object literal. | 5734 // of an object literal. |
5750 if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return; | 5735 if (property->kind() == ObjectLiteralProperty::PROTOTYPE) return; |
5751 | 5736 |
5752 if (value->IsFunctionLiteral()) { | 5737 auto function = value->AsFunctionLiteral(); |
5753 auto function = value->AsFunctionLiteral(); | 5738 if (function != nullptr) { |
5754 if (function->is_anonymous()) { | 5739 if (property->kind() == ObjectLiteralProperty::GETTER) { |
5755 if (property->kind() == ObjectLiteralProperty::GETTER) { | 5740 function->set_raw_name(parser_->ast_value_factory()->NewConsString( |
5756 function->set_raw_name(parser_->ast_value_factory()->NewConsString( | 5741 parser_->ast_value_factory()->get_space_string(), name)); |
5757 parser_->ast_value_factory()->get_space_string(), name)); | 5742 } else if (property->kind() == ObjectLiteralProperty::SETTER) { |
5758 } else if (property->kind() == ObjectLiteralProperty::SETTER) { | 5743 function->set_raw_name(parser_->ast_value_factory()->NewConsString( |
5759 function->set_raw_name(parser_->ast_value_factory()->NewConsString( | 5744 parser_->ast_value_factory()->set_space_string(), name)); |
5760 parser_->ast_value_factory()->set_space_string(), name)); | 5745 } else { |
5761 } else { | 5746 function->set_raw_name(name); |
5762 function->set_raw_name(name); | 5747 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); |
5763 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); | |
5764 } | |
5765 } | 5748 } |
5766 } else { | 5749 } else { |
5767 DCHECK(value->IsClassLiteral()); | 5750 DCHECK(value->IsClassLiteral()); |
5768 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); | 5751 DCHECK_EQ(ObjectLiteralProperty::COMPUTED, property->kind()); |
5769 auto class_literal = value->AsClassLiteral(); | 5752 value->AsClassLiteral()->constructor()->set_raw_name(name); |
5770 if (class_literal->raw_name() == nullptr) { | |
5771 class_literal->set_raw_name(name); | |
5772 } | |
5773 } | 5753 } |
5774 } | 5754 } |
5775 | 5755 |
5776 | 5756 |
5777 void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value, | 5757 void ParserTraits::SetFunctionNameFromIdentifierRef(Expression* value, |
5778 Expression* identifier) { | 5758 Expression* identifier) { |
5779 if (!value->IsFunctionLiteral() && !value->IsClassLiteral()) return; | 5759 if (!value->IsAnonymousFunctionDefinition()) return; |
5780 if (!identifier->IsVariableProxy()) return; | 5760 if (!identifier->IsVariableProxy()) return; |
5781 | 5761 |
5782 auto name = identifier->AsVariableProxy()->raw_name(); | 5762 auto name = identifier->AsVariableProxy()->raw_name(); |
5783 DCHECK_NOT_NULL(name); | 5763 DCHECK_NOT_NULL(name); |
5784 | 5764 |
5785 if (value->IsFunctionLiteral()) { | 5765 auto function = value->AsFunctionLiteral(); |
5786 auto function = value->AsFunctionLiteral(); | 5766 if (function != nullptr) { |
5787 if (function->is_anonymous()) { | 5767 function->set_raw_name(name); |
5788 function->set_raw_name(name); | |
5789 } | |
5790 } else { | 5768 } else { |
5791 DCHECK(value->IsClassLiteral()); | 5769 DCHECK(value->IsClassLiteral()); |
5792 auto class_literal = value->AsClassLiteral(); | 5770 value->AsClassLiteral()->constructor()->set_raw_name(name); |
5793 if (class_literal->raw_name() == nullptr) { | |
5794 class_literal->set_raw_name(name); | |
5795 } | |
5796 } | 5771 } |
5797 } | 5772 } |
5798 | 5773 |
5799 | 5774 |
5800 } // namespace internal | 5775 } // namespace internal |
5801 } // namespace v8 | 5776 } // namespace v8 |
OLD | NEW |