| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 #include "lexer/experimental-scanner.h" | 32 #include "lexer/experimental-scanner.h" |
| 33 #include "token.h" | 33 #include "token.h" |
| 34 #include "scanner.h" | 34 #include "scanner.h" |
| 35 | 35 |
| 36 namespace v8 { | 36 namespace v8 { |
| 37 namespace internal { | 37 namespace internal { |
| 38 | 38 |
| 39 // Common base class shared between parser and pre-parser. | 39 // Common base class shared between parser and pre-parser. |
| 40 class ParserBase { | 40 class ParserBase { |
| 41 public: | 41 public: |
| 42 ParserBase(Scanner* scanner, uintptr_t stack_limit) | 42 ParserBase(ScannerBase* scanner, uintptr_t stack_limit) |
| 43 : scanner_(scanner), | 43 : scanner_(scanner), |
| 44 stack_limit_(stack_limit), | 44 stack_limit_(stack_limit), |
| 45 stack_overflow_(false), | 45 stack_overflow_(false), |
| 46 allow_lazy_(false), | 46 allow_lazy_(false), |
| 47 allow_natives_syntax_(false), | 47 allow_natives_syntax_(false), |
| 48 allow_generators_(false), | 48 allow_generators_(false), |
| 49 allow_for_of_(false) { } | 49 allow_for_of_(false) { } |
| 50 // TODO(mstarzinger): Only virtual until message reporting has been unified. | 50 // TODO(mstarzinger): Only virtual until message reporting has been unified. |
| 51 virtual ~ParserBase() { } | 51 virtual ~ParserBase() { } |
| 52 | 52 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 70 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 70 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
| 71 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 71 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
| 72 void set_allow_harmony_scoping(bool allow) { | 72 void set_allow_harmony_scoping(bool allow) { |
| 73 scanner()->SetHarmonyScoping(allow); | 73 scanner()->SetHarmonyScoping(allow); |
| 74 } | 74 } |
| 75 void set_allow_harmony_numeric_literals(bool allow) { | 75 void set_allow_harmony_numeric_literals(bool allow) { |
| 76 scanner()->SetHarmonyNumericLiterals(allow); | 76 scanner()->SetHarmonyNumericLiterals(allow); |
| 77 } | 77 } |
| 78 | 78 |
| 79 protected: | 79 protected: |
| 80 Scanner* scanner() const { return scanner_; } | 80 ScannerBase* scanner() const { return scanner_; } |
| 81 int position() { return scanner_->location().beg_pos; } | 81 int position() { return scanner_->location().beg_pos; } |
| 82 int peek_position() { return scanner_->peek_location().beg_pos; } | 82 int peek_position() { return scanner_->peek_location().beg_pos; } |
| 83 bool stack_overflow() const { return stack_overflow_; } | 83 bool stack_overflow() const { return stack_overflow_; } |
| 84 void set_stack_overflow() { stack_overflow_ = true; } | 84 void set_stack_overflow() { stack_overflow_ = true; } |
| 85 | 85 |
| 86 INLINE(Token::Value peek()) { | 86 INLINE(Token::Value peek()) { |
| 87 if (stack_overflow_) return Token::ILLEGAL; | 87 if (stack_overflow_) return Token::ILLEGAL; |
| 88 return scanner()->peek(); | 88 return scanner()->peek(); |
| 89 } | 89 } |
| 90 | 90 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok); | 132 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok); |
| 133 | 133 |
| 134 // Strict mode octal literal validation. | 134 // Strict mode octal literal validation. |
| 135 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); | 135 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); |
| 136 | 136 |
| 137 // Determine precedence of given token. | 137 // Determine precedence of given token. |
| 138 static int Precedence(Token::Value token, bool accept_IN); | 138 static int Precedence(Token::Value token, bool accept_IN); |
| 139 | 139 |
| 140 // Report syntax errors. | 140 // Report syntax errors. |
| 141 virtual void ReportUnexpectedToken(Token::Value token) = 0; | 141 virtual void ReportUnexpectedToken(Token::Value token) = 0; |
| 142 virtual void ReportMessageAt(Scanner::Location loc, const char* type) = 0; | 142 virtual void ReportMessageAt(ScannerBase::Location loc, const char* type) = 0; |
| 143 | 143 |
| 144 // Used to detect duplicates in object literals. Each of the values | 144 // Used to detect duplicates in object literals. Each of the values |
| 145 // kGetterProperty, kSetterProperty and kValueProperty represents | 145 // kGetterProperty, kSetterProperty and kValueProperty represents |
| 146 // a type of object literal property. When parsing a property, its | 146 // a type of object literal property. When parsing a property, its |
| 147 // type value is stored in the DuplicateFinder for the property name. | 147 // type value is stored in the DuplicateFinder for the property name. |
| 148 // Values are chosen so that having intersection bits means the there is | 148 // Values are chosen so that having intersection bits means the there is |
| 149 // an incompatibility. | 149 // an incompatibility. |
| 150 // I.e., you can add a getter to a property that already has a setter, since | 150 // I.e., you can add a getter to a property that already has a setter, since |
| 151 // kGetterProperty and kSetterProperty doesn't intersect, but not if it | 151 // kGetterProperty and kSetterProperty doesn't intersect, but not if it |
| 152 // already has a getter or a value. Adding the getter to an existing | 152 // already has a getter or a value. Adding the getter to an existing |
| (...skipping 14 matching lines...) Expand all Loading... |
| 167 public: | 167 public: |
| 168 ObjectLiteralChecker(ParserBase* parser, LanguageMode mode) | 168 ObjectLiteralChecker(ParserBase* parser, LanguageMode mode) |
| 169 : parser_(parser), | 169 : parser_(parser), |
| 170 finder_(scanner()->unicode_cache()), | 170 finder_(scanner()->unicode_cache()), |
| 171 language_mode_(mode) { } | 171 language_mode_(mode) { } |
| 172 | 172 |
| 173 void CheckProperty(Token::Value property, PropertyKind type, bool* ok); | 173 void CheckProperty(Token::Value property, PropertyKind type, bool* ok); |
| 174 | 174 |
| 175 private: | 175 private: |
| 176 ParserBase* parser() const { return parser_; } | 176 ParserBase* parser() const { return parser_; } |
| 177 Scanner* scanner() const { return parser_->scanner(); } | 177 ScannerBase* scanner() const { return parser_->scanner(); } |
| 178 | 178 |
| 179 // Checks the type of conflict based on values coming from PropertyType. | 179 // Checks the type of conflict based on values coming from PropertyType. |
| 180 bool HasConflict(PropertyKind type1, PropertyKind type2) { | 180 bool HasConflict(PropertyKind type1, PropertyKind type2) { |
| 181 return (type1 & type2) != 0; | 181 return (type1 & type2) != 0; |
| 182 } | 182 } |
| 183 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) { | 183 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) { |
| 184 return ((type1 & type2) & kValueFlag) != 0; | 184 return ((type1 & type2) & kValueFlag) != 0; |
| 185 } | 185 } |
| 186 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) { | 186 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) { |
| 187 return ((type1 ^ type2) & kValueFlag) != 0; | 187 return ((type1 ^ type2) & kValueFlag) != 0; |
| 188 } | 188 } |
| 189 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) { | 189 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) { |
| 190 return ((type1 | type2) & kValueFlag) == 0; | 190 return ((type1 | type2) & kValueFlag) == 0; |
| 191 } | 191 } |
| 192 | 192 |
| 193 ParserBase* parser_; | 193 ParserBase* parser_; |
| 194 DuplicateFinder finder_; | 194 DuplicateFinder finder_; |
| 195 LanguageMode language_mode_; | 195 LanguageMode language_mode_; |
| 196 }; | 196 }; |
| 197 | 197 |
| 198 ScannerBase* scanner_; |
| 199 |
| 198 private: | 200 private: |
| 199 Scanner* scanner_; | |
| 200 uintptr_t stack_limit_; | 201 uintptr_t stack_limit_; |
| 201 bool stack_overflow_; | 202 bool stack_overflow_; |
| 202 | 203 |
| 203 bool allow_lazy_; | 204 bool allow_lazy_; |
| 204 bool allow_natives_syntax_; | 205 bool allow_natives_syntax_; |
| 205 bool allow_generators_; | 206 bool allow_generators_; |
| 206 bool allow_for_of_; | 207 bool allow_for_of_; |
| 207 }; | 208 }; |
| 208 | 209 |
| 209 | 210 |
| 210 // Preparsing checks a JavaScript program and emits preparse-data that helps | 211 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 211 // a later parsing to be faster. | 212 // a later parsing to be faster. |
| 212 // See preparse-data-format.h for the data format. | 213 // See preparse-data-format.h for the data format. |
| 213 | 214 |
| 214 // The PreParser checks that the syntax follows the grammar for JavaScript, | 215 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| 215 // and collects some information about the program along the way. | 216 // and collects some information about the program along the way. |
| 216 // The grammar check is only performed in order to understand the program | 217 // The grammar check is only performed in order to understand the program |
| 217 // sufficiently to deduce some information about it, that can be used | 218 // sufficiently to deduce some information about it, that can be used |
| 218 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 219 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 219 // rather it is to speed up properly written and correct programs. | 220 // rather it is to speed up properly written and correct programs. |
| 220 // That means that contextual checks (like a label being declared where | 221 // That means that contextual checks (like a label being declared where |
| 221 // it is used) are generally omitted. | 222 // it is used) are generally omitted. |
| 222 class PreParser : public ParserBase { | 223 class PreParser : public ParserBase { |
| 223 public: | 224 public: |
| 224 enum PreParseResult { | 225 enum PreParseResult { |
| 225 kPreParseStackOverflow, | 226 kPreParseStackOverflow, |
| 226 kPreParseSuccess | 227 kPreParseSuccess |
| 227 }; | 228 }; |
| 228 | 229 |
| 229 PreParser(Scanner* scanner, | 230 PreParser(ScannerBase* scanner, |
| 230 ParserRecorder* log, | 231 ParserRecorder* log, |
| 231 uintptr_t stack_limit) | 232 uintptr_t stack_limit) |
| 232 : ParserBase(scanner, stack_limit), | 233 : ParserBase(scanner, stack_limit), |
| 233 log_(log), | 234 log_(log), |
| 234 scope_(NULL), | 235 scope_(NULL), |
| 235 strict_mode_violation_location_(Scanner::Location::invalid()), | 236 strict_mode_violation_location_(ScannerBase::Location::invalid()), |
| 236 strict_mode_violation_type_(NULL), | 237 strict_mode_violation_type_(NULL), |
| 237 parenthesized_function_(false) { } | 238 parenthesized_function_(false) { } |
| 238 | 239 |
| 239 ~PreParser() {} | 240 ~PreParser() {} |
| 240 | 241 |
| 241 // Pre-parse the program from the character stream; returns true on | 242 // Pre-parse the program from the character stream; returns true on |
| 242 // success (even if parsing failed, the pre-parse data successfully | 243 // success (even if parsing failed, the pre-parse data successfully |
| 243 // captured the syntax error), and false if a stack-overflow happened | 244 // captured the syntax error), and false if a stack-overflow happened |
| 244 // during parsing. | 245 // during parsing. |
| 245 PreParseResult PreParseProgram() { | 246 PreParseResult PreParseProgram() { |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 569 const ScopeType type_; | 570 const ScopeType type_; |
| 570 int materialized_literal_count_; | 571 int materialized_literal_count_; |
| 571 int expected_properties_; | 572 int expected_properties_; |
| 572 int with_nesting_count_; | 573 int with_nesting_count_; |
| 573 LanguageMode language_mode_; | 574 LanguageMode language_mode_; |
| 574 bool is_generator_; | 575 bool is_generator_; |
| 575 }; | 576 }; |
| 576 | 577 |
| 577 // Report syntax error | 578 // Report syntax error |
| 578 void ReportUnexpectedToken(Token::Value token); | 579 void ReportUnexpectedToken(Token::Value token); |
| 579 void ReportMessageAt(Scanner::Location location, const char* type) { | 580 void ReportMessageAt(ScannerBase::Location location, const char* type) { |
| 580 ReportMessageAt(location, type, NULL); | 581 ReportMessageAt(location, type, NULL); |
| 581 } | 582 } |
| 582 void ReportMessageAt(Scanner::Location location, | 583 void ReportMessageAt(ScannerBase::Location location, |
| 583 const char* type, | 584 const char* type, |
| 584 const char* name_opt) { | 585 const char* name_opt) { |
| 585 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); | 586 log_->LogMessage(location.beg_pos, location.end_pos, type, name_opt); |
| 586 } | 587 } |
| 587 void ReportMessageAt(int start_pos, | 588 void ReportMessageAt(int start_pos, |
| 588 int end_pos, | 589 int end_pos, |
| 589 const char* type, | 590 const char* type, |
| 590 const char* name_opt) { | 591 const char* name_opt) { |
| 591 log_->LogMessage(start_pos, end_pos, type, name_opt); | 592 log_->LogMessage(start_pos, end_pos, type, name_opt); |
| 592 } | 593 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 663 } | 664 } |
| 664 | 665 |
| 665 bool is_extended_mode() { | 666 bool is_extended_mode() { |
| 666 return scope_->language_mode() == EXTENDED_MODE; | 667 return scope_->language_mode() == EXTENDED_MODE; |
| 667 } | 668 } |
| 668 | 669 |
| 669 LanguageMode language_mode() { return scope_->language_mode(); } | 670 LanguageMode language_mode() { return scope_->language_mode(); } |
| 670 | 671 |
| 671 bool CheckInOrOf(bool accept_OF); | 672 bool CheckInOrOf(bool accept_OF); |
| 672 | 673 |
| 673 void SetStrictModeViolation(Scanner::Location, | 674 void SetStrictModeViolation(ScannerBase::Location, |
| 674 const char* type, | 675 const char* type, |
| 675 bool* ok); | 676 bool* ok); |
| 676 | 677 |
| 677 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); | 678 void CheckDelayedStrictModeViolation(int beg_pos, int end_pos, bool* ok); |
| 678 | 679 |
| 679 void StrictModeIdentifierViolation(Scanner::Location, | 680 void StrictModeIdentifierViolation(ScannerBase::Location, |
| 680 const char* eval_args_type, | 681 const char* eval_args_type, |
| 681 Identifier identifier, | 682 Identifier identifier, |
| 682 bool* ok); | 683 bool* ok); |
| 683 | 684 |
| 684 ParserRecorder* log_; | 685 ParserRecorder* log_; |
| 685 Scope* scope_; | 686 Scope* scope_; |
| 686 Scanner::Location strict_mode_violation_location_; | 687 ScannerBase::Location strict_mode_violation_location_; |
| 687 const char* strict_mode_violation_type_; | 688 const char* strict_mode_violation_type_; |
| 688 bool parenthesized_function_; | 689 bool parenthesized_function_; |
| 689 }; | 690 }; |
| 690 | 691 |
| 691 } } // v8::internal | 692 } } // v8::internal |
| 692 | 693 |
| 693 #endif // V8_PREPARSER_H | 694 #endif // V8_PREPARSER_H |
| OLD | NEW |