| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 15 matching lines...) Expand all Loading... |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_PREPARSER_H | 28 #ifndef V8_PREPARSER_H |
| 29 #define V8_PREPARSER_H | 29 #define V8_PREPARSER_H |
| 30 | 30 |
| 31 namespace v8 { | 31 namespace v8 { |
| 32 namespace preparser { | 32 namespace preparser { |
| 33 | 33 |
| 34 // Preparsing checks a JavaScript program and emits preparse-data that helps | 34 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 35 // a later parsing to be faster. | 35 // a later parsing to be faster. |
| 36 // See preparse-data.h for the data. | 36 // See preparse-data-format.h for the data format. |
| 37 | 37 |
| 38 // The PreParser checks that the syntax follows the grammar for JavaScript, | 38 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| 39 // and collects some information about the program along the way. | 39 // and collects some information about the program along the way. |
| 40 // The grammar check is only performed in order to understand the program | 40 // The grammar check is only performed in order to understand the program |
| 41 // sufficiently to deduce some information about it, that can be used | 41 // sufficiently to deduce some information about it, that can be used |
| 42 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 42 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
| 43 // rather it is to speed up properly written and correct programs. | 43 // rather it is to speed up properly written and correct programs. |
| 44 // That means that contextual checks (like a label being declared where | 44 // That means that contextual checks (like a label being declared where |
| 45 // it is used) are generally omitted. | 45 // it is used) are generally omitted. |
| 46 | 46 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 73 }; | 73 }; |
| 74 | 74 |
| 75 // Types that allow us to recognize simple this-property assignments. | 75 // Types that allow us to recognize simple this-property assignments. |
| 76 // A simple this-property assignment is a statement on the form | 76 // A simple this-property assignment is a statement on the form |
| 77 // "this.propertyName = {primitive constant or function parameter name);" | 77 // "this.propertyName = {primitive constant or function parameter name);" |
| 78 // where propertyName isn't "__proto__". | 78 // where propertyName isn't "__proto__". |
| 79 // The result is only relevant if the function body contains only | 79 // The result is only relevant if the function body contains only |
| 80 // simple this-property assignments. | 80 // simple this-property assignments. |
| 81 | 81 |
| 82 enum StatementType { | 82 enum StatementType { |
| 83 kUnknownStatement | 83 kUnknownStatement, |
| 84 kStringLiteralExpressionStatement, |
| 85 kUseStrictExpressionStatement |
| 84 }; | 86 }; |
| 85 | 87 |
| 86 enum ExpressionType { | 88 enum ExpressionType { |
| 87 kUnknownExpression, | 89 kUnknownExpression, |
| 88 kIdentifierExpression, // Used to detect labels. | 90 kIdentifierExpression, // Used to detect labels. |
| 89 kThisExpression, | 91 kThisExpression, |
| 90 kThisPropertyExpression | 92 kThisPropertyExpression, |
| 93 kStringLiteralExpression, |
| 94 kUseStrictString |
| 91 }; | 95 }; |
| 92 | 96 |
| 93 enum IdentifierType { | 97 enum IdentifierType { |
| 94 kUnknownIdentifier | 98 kUnknownIdentifier |
| 95 }; | 99 }; |
| 96 | 100 |
| 97 enum SourceElementTypes { | 101 enum SourceElementTypes { |
| 98 kUnknownSourceElements | 102 kUnknownSourceElements, |
| 103 kDirectivePrologue, |
| 104 kUseStrictDirective |
| 99 }; | 105 }; |
| 100 | 106 |
| 101 typedef int SourceElements; | 107 typedef int SourceElements; |
| 102 typedef int Expression; | 108 typedef int Expression; |
| 103 typedef int Statement; | 109 typedef int Statement; |
| 104 typedef int Identifier; | 110 typedef int Identifier; |
| 105 typedef int Arguments; | 111 typedef int Arguments; |
| 106 | 112 |
| 107 class Scope { | 113 class Scope { |
| 108 public: | 114 public: |
| 109 Scope(Scope** variable, ScopeType type) | 115 Scope(Scope** variable, ScopeType type) |
| 110 : variable_(variable), | 116 : variable_(variable), |
| 111 prev_(*variable), | 117 prev_(*variable), |
| 112 type_(type), | 118 type_(type), |
| 113 materialized_literal_count_(0), | 119 materialized_literal_count_(0), |
| 114 expected_properties_(0), | 120 expected_properties_(0), |
| 115 with_nesting_count_(0) { | 121 with_nesting_count_(0), |
| 122 strict_((prev_ != NULL) && prev_->is_strict()) { |
| 116 *variable = this; | 123 *variable = this; |
| 117 } | 124 } |
| 118 ~Scope() { *variable_ = prev_; } | 125 ~Scope() { *variable_ = prev_; } |
| 119 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } | 126 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } |
| 120 void AddProperty() { expected_properties_++; } | 127 void AddProperty() { expected_properties_++; } |
| 121 ScopeType type() { return type_; } | 128 ScopeType type() { return type_; } |
| 122 int expected_properties() { return expected_properties_; } | 129 int expected_properties() { return expected_properties_; } |
| 123 int materialized_literal_count() { return materialized_literal_count_; } | 130 int materialized_literal_count() { return materialized_literal_count_; } |
| 124 bool IsInsideWith() { return with_nesting_count_ != 0; } | 131 bool IsInsideWith() { return with_nesting_count_ != 0; } |
| 132 bool is_strict() { return strict_; } |
| 133 void set_strict() { strict_ = true; } |
| 125 void EnterWith() { with_nesting_count_++; } | 134 void EnterWith() { with_nesting_count_++; } |
| 126 void LeaveWith() { with_nesting_count_--; } | 135 void LeaveWith() { with_nesting_count_--; } |
| 127 | 136 |
| 128 private: | 137 private: |
| 129 Scope** const variable_; | 138 Scope** const variable_; |
| 130 Scope* const prev_; | 139 Scope* const prev_; |
| 131 const ScopeType type_; | 140 const ScopeType type_; |
| 132 int materialized_literal_count_; | 141 int materialized_literal_count_; |
| 133 int expected_properties_; | 142 int expected_properties_; |
| 134 int with_nesting_count_; | 143 int with_nesting_count_; |
| 144 bool strict_; |
| 135 }; | 145 }; |
| 136 | 146 |
| 137 // Private constructor only used in PreParseProgram. | 147 // Private constructor only used in PreParseProgram. |
| 138 PreParser(i::JavaScriptScanner* scanner, | 148 PreParser(i::JavaScriptScanner* scanner, |
| 139 i::ParserRecorder* log, | 149 i::ParserRecorder* log, |
| 140 uintptr_t stack_limit, | 150 uintptr_t stack_limit, |
| 141 bool allow_lazy) | 151 bool allow_lazy) |
| 142 : scanner_(scanner), | 152 : scanner_(scanner), |
| 143 log_(log), | 153 log_(log), |
| 144 scope_(NULL), | 154 scope_(NULL), |
| 145 stack_limit_(stack_limit), | 155 stack_limit_(stack_limit), |
| 146 stack_overflow_(false), | 156 stack_overflow_(false), |
| 147 allow_lazy_(true), | 157 allow_lazy_(true), |
| 148 parenthesized_function_(false) { } | 158 parenthesized_function_(false) { } |
| 149 | 159 |
| 150 // Preparse the program. Only called in PreParseProgram after creating | 160 // Preparse the program. Only called in PreParseProgram after creating |
| 151 // the instance. | 161 // the instance. |
| 152 PreParseResult PreParse() { | 162 PreParseResult PreParse() { |
| 153 Scope top_scope(&scope_, kTopLevelScope); | 163 Scope top_scope(&scope_, kTopLevelScope); |
| 154 bool ok = true; | 164 bool ok = true; |
| 165 int start_position = scanner_->peek_location().beg_pos; |
| 155 ParseSourceElements(i::Token::EOS, &ok); | 166 ParseSourceElements(i::Token::EOS, &ok); |
| 156 if (stack_overflow_) return kPreParseStackOverflow; | 167 if (stack_overflow_) return kPreParseStackOverflow; |
| 157 if (!ok) { | 168 if (!ok) { |
| 158 ReportUnexpectedToken(scanner_->current_token()); | 169 ReportUnexpectedToken(scanner_->current_token()); |
| 170 } else if (scope_->is_strict()) { |
| 171 CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok); |
| 159 } | 172 } |
| 160 return kPreParseSuccess; | 173 return kPreParseSuccess; |
| 161 } | 174 } |
| 162 | 175 |
| 163 // Report syntax error | 176 // Report syntax error |
| 164 void ReportUnexpectedToken(i::Token::Value token); | 177 void ReportUnexpectedToken(i::Token::Value token); |
| 165 void ReportMessageAt(int start_pos, | 178 void ReportMessageAt(int start_pos, |
| 166 int end_pos, | 179 int end_pos, |
| 167 const char* type, | 180 const char* type, |
| 168 const char* name_opt) { | 181 const char* name_opt) { |
| 169 log_->LogMessage(start_pos, end_pos, type, name_opt); | 182 log_->LogMessage(start_pos, end_pos, type, name_opt); |
| 170 } | 183 } |
| 171 | 184 |
| 185 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); |
| 186 |
| 172 // All ParseXXX functions take as the last argument an *ok parameter | 187 // All ParseXXX functions take as the last argument an *ok parameter |
| 173 // which is set to false if parsing failed; it is unchanged otherwise. | 188 // which is set to false if parsing failed; it is unchanged otherwise. |
| 174 // By making the 'exception handling' explicit, we are forced to check | 189 // By making the 'exception handling' explicit, we are forced to check |
| 175 // for failure at the call sites. | 190 // for failure at the call sites. |
| 176 SourceElements ParseSourceElements(int end_token, bool* ok); | 191 SourceElements ParseSourceElements(int end_token, bool* ok); |
| 177 Statement ParseStatement(bool* ok); | 192 Statement ParseStatement(bool* ok); |
| 178 Statement ParseFunctionDeclaration(bool* ok); | 193 Statement ParseFunctionDeclaration(bool* ok); |
| 179 Statement ParseNativeDeclaration(bool* ok); | 194 Statement ParseNativeDeclaration(bool* ok); |
| 180 Statement ParseBlock(bool* ok); | 195 Statement ParseBlock(bool* ok); |
| 181 Statement ParseVariableStatement(bool* ok); | 196 Statement ParseVariableStatement(bool* ok); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 // The current one will still be returned. It might already | 253 // The current one will still be returned. It might already |
| 239 // have been seen using peek. | 254 // have been seen using peek. |
| 240 stack_overflow_ = true; | 255 stack_overflow_ = true; |
| 241 } | 256 } |
| 242 } | 257 } |
| 243 return scanner_->Next(); | 258 return scanner_->Next(); |
| 244 } | 259 } |
| 245 | 260 |
| 246 bool peek_any_identifier(); | 261 bool peek_any_identifier(); |
| 247 | 262 |
| 263 void set_strict_mode() { |
| 264 scope_->set_strict(); |
| 265 } |
| 266 |
| 267 bool is_strict_mode() { return scope_->is_strict(); } |
| 268 |
| 248 void Consume(i::Token::Value token) { Next(); } | 269 void Consume(i::Token::Value token) { Next(); } |
| 249 | 270 |
| 250 void Expect(i::Token::Value token, bool* ok) { | 271 void Expect(i::Token::Value token, bool* ok) { |
| 251 if (Next() != token) { | 272 if (Next() != token) { |
| 252 *ok = false; | 273 *ok = false; |
| 253 } | 274 } |
| 254 } | 275 } |
| 255 | 276 |
| 256 bool Check(i::Token::Value token) { | 277 bool Check(i::Token::Value token) { |
| 257 i::Token::Value next = peek(); | 278 i::Token::Value next = peek(); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 269 i::ParserRecorder* log_; | 290 i::ParserRecorder* log_; |
| 270 Scope* scope_; | 291 Scope* scope_; |
| 271 uintptr_t stack_limit_; | 292 uintptr_t stack_limit_; |
| 272 bool stack_overflow_; | 293 bool stack_overflow_; |
| 273 bool allow_lazy_; | 294 bool allow_lazy_; |
| 274 bool parenthesized_function_; | 295 bool parenthesized_function_; |
| 275 }; | 296 }; |
| 276 } } // v8::preparser | 297 } } // v8::preparser |
| 277 | 298 |
| 278 #endif // V8_PREPARSER_H | 299 #endif // V8_PREPARSER_H |
| OLD | NEW |