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 // The parser's current scope is in scope_. BlockState and FunctionState | 143 // The parser's current scope is in scope_. BlockState and FunctionState |
144 // constructors push on the scope stack and the destructors pop. They are also | 144 // constructors push on the scope stack and the destructors pop. They are also |
145 // used to hold the parser's per-function and per-block state. | 145 // used to hold the parser's per-function and per-block state. |
146 class BlockState BASE_EMBEDDED { | 146 class BlockState BASE_EMBEDDED { |
147 public: | 147 public: |
148 BlockState(typename Traits::Type::Scope** scope_stack, | 148 BlockState(typename Traits::Type::Scope** scope_stack, |
149 typename Traits::Type::Scope* scope) | 149 typename Traits::Type::Scope* scope) |
150 : scope_stack_(scope_stack), | 150 : scope_stack_(scope_stack), |
151 outer_scope_(*scope_stack), | 151 outer_scope_(*scope_stack), |
152 scope_(scope) { | 152 scope_(scope) { |
153 *scope_stack_ = scope_; | 153 *scope_stack_ = scope_; |
Dmitry Lomov (no reviews)
2014/10/07 10:28:32
Why do you need this constructor?
arv (Not doing code reviews)
2014/10/07 14:47:09
This is due to how parser and preparser typedef Sc
Dmitry Lomov (no reviews)
2014/10/07 15:09:37
Could we investigate the possibility of removing t
arv (Not doing code reviews)
2014/10/07 15:16:52
I agree that this is confusing. I struggled quite
| |
154 } | 154 } |
155 BlockState(typename Traits::Type::Scope** scope_stack, | |
156 typename Traits::Type::Scope** scope) | |
157 : scope_stack_(scope_stack), | |
158 outer_scope_(*scope_stack), | |
159 scope_(*scope) { | |
160 *scope_stack_ = scope_; | |
161 } | |
155 ~BlockState() { *scope_stack_ = outer_scope_; } | 162 ~BlockState() { *scope_stack_ = outer_scope_; } |
156 | 163 |
157 private: | 164 private: |
158 typename Traits::Type::Scope** scope_stack_; | 165 typename Traits::Type::Scope** scope_stack_; |
159 typename Traits::Type::Scope* outer_scope_; | 166 typename Traits::Type::Scope* outer_scope_; |
160 typename Traits::Type::Scope* scope_; | 167 typename Traits::Type::Scope* scope_; |
161 }; | 168 }; |
162 | 169 |
163 class FunctionState BASE_EMBEDDED { | 170 class FunctionState BASE_EMBEDDED { |
164 public: | 171 public: |
(...skipping 1017 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1182 | 1189 |
1183 static bool IsBoilerplateProperty(PreParserExpression property) { | 1190 static bool IsBoilerplateProperty(PreParserExpression property) { |
1184 // PreParser doesn't count boilerplate properties. | 1191 // PreParser doesn't count boilerplate properties. |
1185 return false; | 1192 return false; |
1186 } | 1193 } |
1187 | 1194 |
1188 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { | 1195 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { |
1189 return false; | 1196 return false; |
1190 } | 1197 } |
1191 | 1198 |
1199 bool IsConstructorProperty(PreParserExpression property) { return false; } | |
1200 | |
1201 static PreParserExpression GetPropertyValue(PreParserExpression property) { | |
1202 UNREACHABLE(); | |
1203 return PreParserExpression::Default(); | |
1204 } | |
1205 | |
1192 // Functions for encapsulating the differences between parsing and preparsing; | 1206 // Functions for encapsulating the differences between parsing and preparsing; |
1193 // operations interleaved with the recursive descent. | 1207 // operations interleaved with the recursive descent. |
1194 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1208 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
1195 // PreParser should not use FuncNameInferrer. | 1209 // PreParser should not use FuncNameInferrer. |
1196 UNREACHABLE(); | 1210 UNREACHABLE(); |
1197 } | 1211 } |
1198 static void PushPropertyName(FuncNameInferrer* fni, | 1212 static void PushPropertyName(FuncNameInferrer* fni, |
1199 PreParserExpression expression) { | 1213 PreParserExpression expression) { |
1200 // PreParser should not use FuncNameInferrer. | 1214 // PreParser should not use FuncNameInferrer. |
1201 UNREACHABLE(); | 1215 UNREACHABLE(); |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1307 static PreParserExpression ThisExpression(PreParserScope* scope, | 1321 static PreParserExpression ThisExpression(PreParserScope* scope, |
1308 PreParserFactory* factory) { | 1322 PreParserFactory* factory) { |
1309 return PreParserExpression::This(); | 1323 return PreParserExpression::This(); |
1310 } | 1324 } |
1311 | 1325 |
1312 static PreParserExpression SuperReference(PreParserScope* scope, | 1326 static PreParserExpression SuperReference(PreParserScope* scope, |
1313 PreParserFactory* factory) { | 1327 PreParserFactory* factory) { |
1314 return PreParserExpression::Super(); | 1328 return PreParserExpression::Super(); |
1315 } | 1329 } |
1316 | 1330 |
1317 static PreParserExpression ClassLiteral(PreParserIdentifier name, | 1331 static PreParserExpression ClassExpression(PreParserIdentifier name, |
1318 PreParserExpression extends, | 1332 PreParserExpression extends, |
1319 PreParserExpression constructor, | 1333 PreParserExpression constructor, |
1320 PreParserExpressionList properties, | 1334 PreParserExpressionList properties, |
1321 int position, | 1335 int position, |
1322 PreParserFactory* factory) { | 1336 PreParserFactory* factory) { |
1323 return PreParserExpression::Default(); | 1337 return PreParserExpression::Default(); |
1324 } | 1338 } |
1325 | 1339 |
1326 static PreParserExpression ExpressionFromLiteral( | 1340 static PreParserExpression ExpressionFromLiteral( |
1327 Token::Value token, int pos, Scanner* scanner, | 1341 Token::Value token, int pos, Scanner* scanner, |
1328 PreParserFactory* factory) { | 1342 PreParserFactory* factory) { |
1329 return PreParserExpression::Default(); | 1343 return PreParserExpression::Default(); |
1330 } | 1344 } |
1331 | 1345 |
1332 static PreParserExpression ExpressionFromIdentifier( | 1346 static PreParserExpression ExpressionFromIdentifier( |
(...skipping 632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1965 | 1979 |
1966 } else if (is_generator || | 1980 } else if (is_generator || |
1967 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { | 1981 (allow_harmony_object_literals_ && peek() == Token::LPAREN)) { |
1968 // Concise Method | 1982 // Concise Method |
1969 | 1983 |
1970 if (is_static && this->IsPrototype(name)) { | 1984 if (is_static && this->IsPrototype(name)) { |
1971 ReportMessageAt(scanner()->location(), "static_prototype"); | 1985 ReportMessageAt(scanner()->location(), "static_prototype"); |
1972 *ok = false; | 1986 *ok = false; |
1973 return this->EmptyObjectLiteralProperty(); | 1987 return this->EmptyObjectLiteralProperty(); |
1974 } | 1988 } |
1975 if (is_generator && in_class && !is_static && this->IsConstructor(name)) { | |
1976 ReportMessageAt(scanner()->location(), "constructor_special_method"); | |
1977 *ok = false; | |
1978 return this->EmptyObjectLiteralProperty(); | |
1979 } | |
1980 | 1989 |
1981 checker->CheckProperty(name_token, kValueProperty, | |
1982 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
1983 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod | 1990 FunctionKind kind = is_generator ? FunctionKind::kConciseGeneratorMethod |
1984 : FunctionKind::kConciseMethod; | 1991 : FunctionKind::kConciseMethod; |
1985 | 1992 |
1993 if (in_class && !is_static && this->IsConstructor(name)) { | |
1994 if (is_generator) { | |
1995 ReportMessageAt(scanner()->location(), "constructor_special_method"); | |
1996 *ok = false; | |
1997 return this->EmptyObjectLiteralProperty(); | |
1998 } | |
1999 | |
2000 kind = FunctionKind::kConstructorMethod; | |
2001 } | |
2002 | |
2003 checker->CheckProperty(name_token, kValueProperty, | |
2004 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | |
2005 | |
1986 value = this->ParseFunctionLiteral( | 2006 value = this->ParseFunctionLiteral( |
1987 name, scanner()->location(), | 2007 name, scanner()->location(), |
1988 false, // reserved words are allowed here | 2008 false, // reserved words are allowed here |
1989 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, | 2009 kind, RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION, |
1990 FunctionLiteral::NORMAL_ARITY, | 2010 FunctionLiteral::NORMAL_ARITY, |
1991 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); | 2011 CHECK_OK_CUSTOM(EmptyObjectLiteralProperty)); |
1992 | 2012 |
1993 } else if (in_class && name_is_static && !is_static) { | 2013 } else if (in_class && name_is_static && !is_static) { |
1994 // static MethodDefinition | 2014 // static MethodDefinition |
1995 return ParsePropertyDefinition(checker, true, true, ok); | 2015 return ParsePropertyDefinition(checker, true, true, ok); |
(...skipping 736 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2732 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); | 2752 ReportMessageAt(class_name_location, "unexpected_strict_reserved"); |
2733 *ok = false; | 2753 *ok = false; |
2734 return this->EmptyExpression(); | 2754 return this->EmptyExpression(); |
2735 } | 2755 } |
2736 if (this->IsEvalOrArguments(name)) { | 2756 if (this->IsEvalOrArguments(name)) { |
2737 ReportMessageAt(class_name_location, "strict_eval_arguments"); | 2757 ReportMessageAt(class_name_location, "strict_eval_arguments"); |
2738 *ok = false; | 2758 *ok = false; |
2739 return this->EmptyExpression(); | 2759 return this->EmptyExpression(); |
2740 } | 2760 } |
2741 | 2761 |
2762 ExpressionT extends = this->EmptyExpression(); | |
2763 if (Check(Token::EXTENDS)) { | |
2764 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE); | |
2765 BlockState block_state(&scope_, &scope); | |
Dmitry Lomov (no reviews)
2014/10/07 10:28:32
Seems like BlockState block_state(&scope_, scope)
arv (Not doing code reviews)
2014/10/07 14:47:09
That works with PreParser but not with Parser.
| |
2766 scope_->SetStrictMode(STRICT); | |
2767 extends = this->ParseLeftHandSideExpression(CHECK_OK); | |
2768 } | |
2769 | |
2742 // TODO(arv): Implement scopes and name binding in class body only. | 2770 // TODO(arv): Implement scopes and name binding in class body only. |
2743 // TODO(arv): Maybe add CLASS_SCOPE? | 2771 typename Traits::Type::ScopePtr scope = this->NewScope(scope_, BLOCK_SCOPE); |
2744 typename Traits::Type::ScopePtr extends_scope = | 2772 BlockState block_state(&scope_, &scope); |
2745 this->NewScope(scope_, BLOCK_SCOPE); | |
2746 FunctionState extends_function_state( | |
2747 &function_state_, &scope_, &extends_scope, zone(), | |
2748 this->ast_value_factory(), ast_node_id_gen_); | |
2749 scope_->SetStrictMode(STRICT); | 2773 scope_->SetStrictMode(STRICT); |
2750 scope_->SetScopeName(name); | 2774 scope_->SetScopeName(name); |
2751 | 2775 |
2752 ExpressionT extends = this->EmptyExpression(); | |
2753 if (Check(Token::EXTENDS)) { | |
2754 extends = this->ParseLeftHandSideExpression(CHECK_OK); | |
2755 } | |
2756 | |
2757 ObjectLiteralChecker checker(this, STRICT); | 2776 ObjectLiteralChecker checker(this, STRICT); |
2758 typename Traits::Type::PropertyList properties = | 2777 typename Traits::Type::PropertyList properties = |
2759 this->NewPropertyList(4, zone_); | 2778 this->NewPropertyList(4, zone_); |
2760 FunctionLiteralT constructor = this->EmptyFunctionLiteral(); | 2779 ExpressionT constructor = this->EmptyExpression(); |
2761 | 2780 |
2762 Expect(Token::LBRACE, CHECK_OK); | 2781 Expect(Token::LBRACE, CHECK_OK); |
2763 while (peek() != Token::RBRACE) { | 2782 while (peek() != Token::RBRACE) { |
2764 if (Check(Token::SEMICOLON)) continue; | 2783 if (Check(Token::SEMICOLON)) continue; |
2765 if (fni_ != NULL) fni_->Enter(); | 2784 if (fni_ != NULL) fni_->Enter(); |
2766 | 2785 |
2767 const bool in_class = true; | 2786 const bool in_class = true; |
2768 const bool is_static = false; | 2787 const bool is_static = false; |
2769 ObjectLiteralPropertyT property = | 2788 ObjectLiteralPropertyT property = |
2770 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); | 2789 this->ParsePropertyDefinition(&checker, in_class, is_static, CHECK_OK); |
2771 | 2790 |
2772 properties->Add(property, zone()); | 2791 if (this->IsConstructorProperty(property)) { |
2792 constructor = this->GetPropertyValue(property); | |
2793 } else { | |
2794 properties->Add(property, zone()); | |
2795 } | |
2773 | 2796 |
2774 if (fni_ != NULL) { | 2797 if (fni_ != NULL) { |
2775 fni_->Infer(); | 2798 fni_->Infer(); |
2776 fni_->Leave(); | 2799 fni_->Leave(); |
2777 } | 2800 } |
2778 } | 2801 } |
2779 Expect(Token::RBRACE, CHECK_OK); | 2802 Expect(Token::RBRACE, CHECK_OK); |
2780 | 2803 |
2781 return this->ClassLiteral(name, extends, constructor, properties, pos, | 2804 return this->ClassExpression(name, extends, constructor, properties, pos, |
2782 factory()); | 2805 factory()); |
2783 } | 2806 } |
2784 | 2807 |
2785 | 2808 |
2786 template <typename Traits> | 2809 template <typename Traits> |
2787 typename ParserBase<Traits>::ExpressionT | 2810 typename ParserBase<Traits>::ExpressionT |
2788 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2811 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2789 ExpressionT expression, | 2812 ExpressionT expression, |
2790 Scanner::Location location, const char* message, bool* ok) { | 2813 Scanner::Location location, const char* message, bool* ok) { |
2791 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2814 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2792 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2815 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2835 DCHECK(IsAccessorAccessorConflict(old_type, type)); | 2858 DCHECK(IsAccessorAccessorConflict(old_type, type)); |
2836 // Both accessors of the same type. | 2859 // Both accessors of the same type. |
2837 parser()->ReportMessage("accessor_get_set"); | 2860 parser()->ReportMessage("accessor_get_set"); |
2838 } | 2861 } |
2839 *ok = false; | 2862 *ok = false; |
2840 } | 2863 } |
2841 } | 2864 } |
2842 } } // v8::internal | 2865 } } // v8::internal |
2843 | 2866 |
2844 #endif // V8_PREPARSER_H | 2867 #endif // V8_PREPARSER_H |
OLD | NEW |