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 #ifndef V8_PREPARSER_H | 5 #ifndef V8_PREPARSER_H |
6 #define V8_PREPARSER_H | 6 #define V8_PREPARSER_H |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
143 // used to hold the parser's per-function and per-block state. | 143 // used to hold the parser's per-function and per-block state. |
144 class BlockState BASE_EMBEDDED { | 144 class BlockState BASE_EMBEDDED { |
145 public: | 145 public: |
146 BlockState(typename Traits::Type::Scope** scope_stack, | 146 BlockState(typename Traits::Type::Scope** scope_stack, |
147 typename Traits::Type::Scope* scope) | 147 typename Traits::Type::Scope* scope) |
148 : scope_stack_(scope_stack), | 148 : scope_stack_(scope_stack), |
149 outer_scope_(*scope_stack), | 149 outer_scope_(*scope_stack), |
150 scope_(scope) { | 150 scope_(scope) { |
151 *scope_stack_ = scope_; | 151 *scope_stack_ = scope_; |
152 } | 152 } |
| 153 BlockState(typename Traits::Type::Scope** scope_stack, |
| 154 typename Traits::Type::Scope** scope) |
| 155 : scope_stack_(scope_stack), |
| 156 outer_scope_(*scope_stack), |
| 157 scope_(*scope) { |
| 158 *scope_stack_ = scope_; |
| 159 } |
153 ~BlockState() { *scope_stack_ = outer_scope_; } | 160 ~BlockState() { *scope_stack_ = outer_scope_; } |
154 | 161 |
155 private: | 162 private: |
156 typename Traits::Type::Scope** scope_stack_; | 163 typename Traits::Type::Scope** scope_stack_; |
157 typename Traits::Type::Scope* outer_scope_; | 164 typename Traits::Type::Scope* outer_scope_; |
158 typename Traits::Type::Scope* scope_; | 165 typename Traits::Type::Scope* scope_; |
159 }; | 166 }; |
160 | 167 |
161 class FunctionState BASE_EMBEDDED { | 168 class FunctionState BASE_EMBEDDED { |
162 public: | 169 public: |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1188 | 1195 |
1189 static bool IsBoilerplateProperty(PreParserExpression property) { | 1196 static bool IsBoilerplateProperty(PreParserExpression property) { |
1190 // PreParser doesn't count boilerplate properties. | 1197 // PreParser doesn't count boilerplate properties. |
1191 return false; | 1198 return false; |
1192 } | 1199 } |
1193 | 1200 |
1194 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1201 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
1195 return false; | 1202 return false; |
1196 } | 1203 } |
1197 | 1204 |
| 1205 bool IsConstructorProperty(PreParserExpression property) { return false; } |
| 1206 |
| 1207 static PreParserExpression GetPropertyValue(PreParserExpression property) { |
| 1208 UNREACHABLE(); |
| 1209 return PreParserExpression::Default(); |
| 1210 } |
| 1211 |
1198 // Functions for encapsulating the differences between parsing and preparsing; | 1212 // Functions for encapsulating the differences between parsing and preparsing; |
1199 // operations interleaved with the recursive descent. | 1213 // operations interleaved with the recursive descent. |
1200 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1214 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
1201 // PreParser should not use FuncNameInferrer. | 1215 // PreParser should not use FuncNameInferrer. |
1202 UNREACHABLE(); | 1216 UNREACHABLE(); |
1203 } | 1217 } |
1204 static void PushPropertyName(FuncNameInferrer* fni, | 1218 static void PushPropertyName(FuncNameInferrer* fni, |
1205 PreParserExpression expression) { | 1219 PreParserExpression expression) { |
1206 // PreParser should not use FuncNameInferrer. | 1220 // PreParser should not use FuncNameInferrer. |
1207 UNREACHABLE(); | 1221 UNREACHABLE(); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1313 static PreParserExpression ThisExpression(PreParserScope* scope, | 1327 static PreParserExpression ThisExpression(PreParserScope* scope, |
1314 PreParserFactory* factory) { | 1328 PreParserFactory* factory) { |
1315 return PreParserExpression::This(); | 1329 return PreParserExpression::This(); |
1316 } | 1330 } |
1317 | 1331 |
1318 static PreParserExpression SuperReference(PreParserScope* scope, | 1332 static PreParserExpression SuperReference(PreParserScope* scope, |
1319 PreParserFactory* factory) { | 1333 PreParserFactory* factory) { |
1320 return PreParserExpression::Super(); | 1334 return PreParserExpression::Super(); |
1321 } | 1335 } |
1322 | 1336 |
1323 static PreParserExpression ClassLiteral(PreParserIdentifier name, | 1337 static PreParserExpression ClassExpression(PreParserIdentifier name, |
1324 PreParserExpression extends, | 1338 PreParserExpression extends, |
1325 PreParserExpression constructor, | 1339 PreParserExpression constructor, |
1326 PreParserExpressionList properties, | 1340 PreParserExpressionList properties, |
1327 int position, | 1341 int position, |
1328 PreParserFactory* factory) { | 1342 PreParserFactory* factory) { |
1329 return PreParserExpression::Default(); | 1343 return PreParserExpression::Default(); |
1330 } | 1344 } |
1331 | 1345 |
1332 static PreParserExpression ExpressionFromLiteral( | 1346 static PreParserExpression ExpressionFromLiteral( |
1333 Token::Value token, int pos, Scanner* scanner, | 1347 Token::Value token, int pos, Scanner* scanner, |
1334 PreParserFactory* factory) { | 1348 PreParserFactory* factory) { |
1335 return PreParserExpression::Default(); | 1349 return PreParserExpression::Default(); |
1336 } | 1350 } |
1337 | 1351 |
1338 static PreParserExpression ExpressionFromIdentifier( | 1352 static PreParserExpression ExpressionFromIdentifier( |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1971 | 1985 |
1972 } else if (is_generator || | 1986 } else if (is_generator || |
1973 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 1987 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
1974 // Concise Method | 1988 // Concise Method |
1975 | 1989 |
1976 if (is_static && this->IsPrototype(name)) { | 1990 if (is_static && this->IsPrototype(name)) { |
1977 ReportMessageAt(scanner()->location(), "static_prototype"); | 1991 ReportMessageAt(scanner()->location(), "static_prototype"); |
1978 *ok = false; | 1992 *ok = false; |
1979 return this->EmptyObjectLiteralProperty(); | 1993 return this->EmptyObjectLiteralProperty(); |
1980 } | 1994 } |
1981 if (is_generator && in_class && !is_static && this->IsConstructor(name)) { | |
1982 ReportMessageAt(scanner()->location(), "constructor_special_method"); | |
1983 *ok = false; | |
1984 return this->EmptyObjectLiteralProperty(); | |
1985 } | |
1986 | 1995 |
1987 checker->CheckProperty(name_token, kValueProperty, | |
1988 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
1989 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1996 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod |
1990 : FunctionKind::kConciseMethod; | 1997 : FunctionKind::kConciseMethod; |
1991 | 1998 |
| 1999 if (in_class && !is_static && this->IsConstructor(name)) { |
| 2000 if (is_generator) { |
| 2001 ReportMessageAt(scanner()->location(), "constructor_special_method"); |
| 2002 *ok = false; |
| 2003 return this->EmptyObjectLiteralProperty(); |
| 2004 } |
| 2005 |
| 2006 kind = FunctionKind::kNormalFunction; |
| 2007 } |
| 2008 |
| 2009 checker->CheckProperty(name_token, kValueProperty, |
| 2010 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
| 2011 |
1992 value = this->ParseFunctionLiteral( | 2012 value = this->ParseFunctionLiteral( |
1993 name, scanner()->location(), | 2013 name, scanner()->location(), |
1994 false, // reserved words are allowed here | 2014 false, // reserved words are allowed here |
1995 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 2015 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
1996 FunctionLiteral::NORMAL_ARITY, | 2016 FunctionLiteral::NORMAL_ARITY, |
1997 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2017 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1998 | 2018 |
1999 } else if (in_class && name_is_static && !is_static) { | 2019 } else if (in_class && name_is_static && !is_static) { |
2000 // static MethodDefinition | 2020 // static MethodDefinition |
2001 return ParsePropertyDefinition(checker, true, true, ok); | 2021 return ParsePropertyDefinition(checker, true, true, ok); |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2738 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); | 2758 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
2739 *ok = false; | 2759 *ok = false; |
2740 return this->EmptyExpression(); | 2760 return this->EmptyExpression(); |
2741 } | 2761 } |
2742 if (this->IsEvalOrArguments(name)) { | 2762 if (this->IsEvalOrArguments(name)) { |
2743 ReportMessageAt(class_name_location, "strict_eval_arguments"); | 2763 ReportMessageAt(class_name_location, "strict_eval_arguments"); |
2744 *ok = false; | 2764 *ok = false; |
2745 return this->EmptyExpression(); | 2765 return this->EmptyExpression(); |
2746 } | 2766 } |
2747 | 2767 |
| 2768 ExpressionT extends = this->EmptyExpression(); |
| 2769 if (Check(Token::EXTENDS)) { |
| 2770 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE); |
| 2771 BlockState block_state(&scope_, &scope); |
| 2772 scope_->SetStrictMode(STRICT); |
| 2773 extends = this->ParseLeftHandSideExpression(CHECK_OK); |
| 2774 } |
| 2775 |
2748 // TODO(arv): Implement scopes and name binding in class body only. | 2776 // TODO(arv): Implement scopes and name binding in class body only. |
2749 // TODO(arv): Maybe add CLASS_SCOPE? | 2777 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE); |
2750 typename Traits::Type::ScopePtr extends_scope = | 2778 BlockState block_state(&scope_, &scope); |
2751 this->NewScope(scope_, BLOCK_SCOPE); | |
2752 FunctionState extends_function_state( | |
2753 &function_state_, &scope_, &extends_scope, zone(), | |
2754 this->ast_value_factory(), ast_node_id_gen_); | |
2755 scope_->SetStrictMode(STRICT); | 2779 scope_->SetStrictMode(STRICT); |
2756 scope_->SetScopeName(name); | 2780 scope_->SetScopeName(name); |
2757 | 2781 |
2758 ExpressionT extends = this->EmptyExpression(); | |
2759 if (Check(Token::EXTENDS)) { | |
2760 extends = this->ParseLeftHandSideExpression(CHECK_OK); | |
2761 } | |
2762 | |
2763 ObjectLiteralChecker checker(this, STRICT); | 2782 ObjectLiteralChecker checker(this, STRICT); |
2764 typename Traits::Type::PropertyList properties = | 2783 typename Traits::Type::PropertyList properties = |
2765 this->NewPropertyList(4, zone_); | 2784 this->NewPropertyList(4, zone_); |
2766 FunctionLiteralT constructor = this->EmptyFunctionLiteral(); | 2785 ExpressionT constructor = this->EmptyExpression(); |
2767 | 2786 |
2768 Expect(Token::LBRACE, CHECK_OK); | 2787 Expect(Token::LBRACE, CHECK_OK); |
2769 while (peek() != Token::RBRACE) { | 2788 while (peek() != Token::RBRACE) { |
2770 if (Check(Token::SEMICOLON)) continue; | 2789 if (Check(Token::SEMICOLON)) continue; |
2771 if (fni_ != NULL) fni_->Enter(); | 2790 if (fni_ != NULL) fni_->Enter(); |
2772 | 2791 |
2773 const bool in_class = true; | 2792 const bool in_class = true; |
2774 const bool is_static = false; | 2793 const bool is_static = false; |
2775 ObjectLiteralPropertyT property = | 2794 ObjectLiteralPropertyT property = |
2776 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); | 2795 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); |
2777 | 2796 |
2778 properties->Add(property, zone()); | 2797 if (this->IsConstructorProperty(property)) { |
| 2798 constructor = this->GetPropertyValue(property); |
| 2799 } else { |
| 2800 properties->Add(property, zone()); |
| 2801 } |
2779 | 2802 |
2780 if (fni_ != NULL) { | 2803 if (fni_ != NULL) { |
2781 fni_->Infer(); | 2804 fni_->Infer(); |
2782 fni_->Leave(); | 2805 fni_->Leave(); |
2783 } | 2806 } |
2784 } | 2807 } |
2785 Expect(Token::RBRACE, CHECK_OK); | 2808 Expect(Token::RBRACE, CHECK_OK); |
2786 | 2809 |
2787 return this->ClassLiteral(name, extends, constructor, properties, pos, | 2810 return this->ClassExpression(name, extends, constructor, properties, pos, |
2788 factory()); | 2811 factory()); |
2789 } | 2812 } |
2790 | 2813 |
2791 | 2814 |
2792 template <typename Traits> | 2815 template <typename Traits> |
2793 typename ParserBase<Traits>::ExpressionT | 2816 typename ParserBase<Traits>::ExpressionT |
2794 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2817 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2795 ExpressionT expression, | 2818 ExpressionT expression, |
2796 Scanner::Location location, const char* message, bool* ok) { | 2819 Scanner::Location location, const char* message, bool* ok) { |
2797 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2820 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2798 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2821 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2841 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2864 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2842 // Both accessors of the same type. | 2865 // Both accessors of the same type. |
2843 parser()->ReportMessage("accessor_get_set"); | 2866 parser()->ReportMessage("accessor_get_set"); |
2844 } | 2867 } |
2845 *ok = false; | 2868 *ok = false; |
2846 } | 2869 } |
2847 } | 2870 } |
2848 } } // v8::internal | 2871 } } // v8::internal |
2849 | 2872 |
2850 #endif // V8_PREPARSER_H | 2873 #endif // V8_PREPARSER_H |
OLD | NEW |