OLD | NEW |
1 // Copyright 2006-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 |
11 // with the distribution. | 11 // with the distribution. |
12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
15 // | 15 // |
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
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_PARSER_H_ | 28 #ifndef V8_PARSER_H_ |
29 #define V8_PARSER_H_ | 29 #define V8_PARSER_H_ |
30 | 30 |
| 31 #include "allocation.h" |
31 #include "scanner.h" | 32 #include "scanner.h" |
32 #include "allocation.h" | |
33 | 33 |
34 namespace v8 { | 34 namespace v8 { |
35 namespace internal { | 35 namespace internal { |
36 | 36 |
| 37 class FuncNameInferrer; |
| 38 class ParserFactory; |
| 39 class ParserLog; |
| 40 class PositionStack; |
| 41 class Target; |
| 42 class TemporaryScope; |
| 43 |
| 44 template <typename T> class ZoneListWrapper; |
| 45 |
37 | 46 |
38 class ParserMessage : public Malloced { | 47 class ParserMessage : public Malloced { |
39 public: | 48 public: |
40 ParserMessage(Scanner::Location loc, const char* message, | 49 ParserMessage(Scanner::Location loc, const char* message, |
41 Vector<const char*> args) | 50 Vector<const char*> args) |
42 : loc_(loc), | 51 : loc_(loc), |
43 message_(message), | 52 message_(message), |
44 args_(args) { } | 53 args_(args) { } |
45 ~ParserMessage(); | 54 ~ParserMessage(); |
46 Scanner::Location location() { return loc_; } | 55 Scanner::Location location() { return loc_; } |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
159 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned))); | 168 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned))); |
160 } | 169 } |
161 | 170 |
162 // Read strings written by ParserRecorder::WriteString. | 171 // Read strings written by ParserRecorder::WriteString. |
163 static const char* ReadString(unsigned* start, int* chars); | 172 static const char* ReadString(unsigned* start, int* chars); |
164 | 173 |
165 friend class ScriptData; | 174 friend class ScriptData; |
166 }; | 175 }; |
167 | 176 |
168 | 177 |
169 // The parser: Takes a script and and context information, and builds a | 178 class Parser { |
170 // FunctionLiteral AST node. Returns NULL and deallocates any allocated | 179 public: |
171 // AST nodes if parsing failed. | 180 Parser(Handle<Script> script, bool allow_natives_syntax, |
172 FunctionLiteral* MakeAST(bool compile_in_global_context, | 181 v8::Extension* extension, ParserMode is_pre_parsing, |
173 Handle<Script> script, | 182 ParserFactory* factory, ParserLog* log, ScriptDataImpl* pre_data); |
174 v8::Extension* extension, | 183 virtual ~Parser() { } |
175 ScriptDataImpl* pre_data, | 184 |
176 bool is_json = false); | 185 // Takes a script and and context information, and builds a |
177 | 186 // FunctionLiteral AST node. Returns NULL and deallocates any allocated |
178 // Generic preparser generating full preparse data. | 187 // AST nodes if parsing failed. |
179 ScriptDataImpl* PreParse(Handle<String> source, | 188 static FunctionLiteral* MakeAST(bool compile_in_global_context, |
180 unibrow::CharacterStream* stream, | 189 Handle<Script> script, |
181 v8::Extension* extension); | 190 v8::Extension* extension, |
182 | 191 ScriptDataImpl* pre_data, |
183 // Preparser that only does preprocessing that makes sense if only used | 192 bool is_json = false); |
184 // immediately after. | 193 |
185 ScriptDataImpl* PartialPreParse(Handle<String> source, | 194 // Support for doing lazy compilation. |
186 unibrow::CharacterStream* stream, | 195 static FunctionLiteral* MakeLazyAST(Handle<SharedFunctionInfo> info); |
187 v8::Extension* extension); | 196 |
188 | 197 // Generic preparser generating full preparse data. |
189 | 198 static ScriptDataImpl* PreParse(Handle<String> source, |
190 bool ParseRegExp(FlatStringReader* input, | 199 unibrow::CharacterStream* stream, |
191 bool multiline, | 200 v8::Extension* extension); |
192 RegExpCompileData* result); | 201 |
193 | 202 // Preparser that only does preprocessing that makes sense if only used |
194 | 203 // immediately after. |
195 // Support for doing lazy compilation. | 204 static ScriptDataImpl* PartialPreParse(Handle<String> source, |
196 FunctionLiteral* MakeLazyAST(Handle<SharedFunctionInfo> info); | 205 unibrow::CharacterStream* stream, |
| 206 v8::Extension* extension); |
| 207 |
| 208 static bool ParseRegExp(FlatStringReader* input, |
| 209 bool multiline, |
| 210 RegExpCompileData* result); |
| 211 |
| 212 // Pre-parse the program from the character stream; returns true on |
| 213 // success, false if a stack-overflow happened during parsing. |
| 214 bool PreParseProgram(Handle<String> source, unibrow::CharacterStream* stream); |
| 215 |
| 216 void ReportMessage(const char* message, Vector<const char*> args); |
| 217 virtual void ReportMessageAt(Scanner::Location loc, |
| 218 const char* message, |
| 219 Vector<const char*> args) = 0; |
| 220 |
| 221 |
| 222 // Returns NULL if parsing failed. |
| 223 FunctionLiteral* ParseProgram(Handle<String> source, |
| 224 bool in_global_context); |
| 225 FunctionLiteral* ParseLazy(Handle<SharedFunctionInfo> info); |
| 226 FunctionLiteral* ParseJson(Handle<String> source); |
| 227 |
| 228 // The minimum number of contiguous assignment that will |
| 229 // be treated as an initialization block. Benchmarks show that |
| 230 // the overhead exceeds the savings below this limit. |
| 231 static const int kMinInitializationBlock = 3; |
| 232 |
| 233 protected: |
| 234 |
| 235 enum Mode { |
| 236 PARSE_LAZILY, |
| 237 PARSE_EAGERLY |
| 238 }; |
| 239 |
| 240 // Report syntax error |
| 241 void ReportUnexpectedToken(Token::Value token); |
| 242 void ReportInvalidPreparseData(Handle<String> name, bool* ok); |
| 243 |
| 244 Handle<Script> script_; |
| 245 Scanner scanner_; |
| 246 |
| 247 Scope* top_scope_; |
| 248 int with_nesting_level_; |
| 249 |
| 250 TemporaryScope* temp_scope_; |
| 251 Mode mode_; |
| 252 |
| 253 Target* target_stack_; // for break, continue statements |
| 254 bool allow_natives_syntax_; |
| 255 v8::Extension* extension_; |
| 256 ParserFactory* factory_; |
| 257 ParserLog* log_; |
| 258 bool is_pre_parsing_; |
| 259 ScriptDataImpl* pre_data_; |
| 260 FuncNameInferrer* fni_; |
| 261 |
| 262 bool inside_with() const { return with_nesting_level_ > 0; } |
| 263 ParserFactory* factory() const { return factory_; } |
| 264 ParserLog* log() const { return log_; } |
| 265 Scanner& scanner() { return scanner_; } |
| 266 Mode mode() const { return mode_; } |
| 267 ScriptDataImpl* pre_data() const { return pre_data_; } |
| 268 |
| 269 // All ParseXXX functions take as the last argument an *ok parameter |
| 270 // which is set to false if parsing failed; it is unchanged otherwise. |
| 271 // By making the 'exception handling' explicit, we are forced to check |
| 272 // for failure at the call sites. |
| 273 void* ParseSourceElements(ZoneListWrapper<Statement>* processor, |
| 274 int end_token, bool* ok); |
| 275 Statement* ParseStatement(ZoneStringList* labels, bool* ok); |
| 276 Statement* ParseFunctionDeclaration(bool* ok); |
| 277 Statement* ParseNativeDeclaration(bool* ok); |
| 278 Block* ParseBlock(ZoneStringList* labels, bool* ok); |
| 279 Block* ParseVariableStatement(bool* ok); |
| 280 Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok); |
| 281 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels, |
| 282 bool* ok); |
| 283 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok); |
| 284 Statement* ParseContinueStatement(bool* ok); |
| 285 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok); |
| 286 Statement* ParseReturnStatement(bool* ok); |
| 287 Block* WithHelper(Expression* obj, |
| 288 ZoneStringList* labels, |
| 289 bool is_catch_block, |
| 290 bool* ok); |
| 291 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok); |
| 292 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok); |
| 293 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok); |
| 294 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok); |
| 295 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok); |
| 296 Statement* ParseForStatement(ZoneStringList* labels, bool* ok); |
| 297 Statement* ParseThrowStatement(bool* ok); |
| 298 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value); |
| 299 TryStatement* ParseTryStatement(bool* ok); |
| 300 DebuggerStatement* ParseDebuggerStatement(bool* ok); |
| 301 |
| 302 Expression* ParseExpression(bool accept_IN, bool* ok); |
| 303 Expression* ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 304 Expression* ParseConditionalExpression(bool accept_IN, bool* ok); |
| 305 Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 306 Expression* ParseUnaryExpression(bool* ok); |
| 307 Expression* ParsePostfixExpression(bool* ok); |
| 308 Expression* ParseLeftHandSideExpression(bool* ok); |
| 309 Expression* ParseNewExpression(bool* ok); |
| 310 Expression* ParseMemberExpression(bool* ok); |
| 311 Expression* ParseNewPrefix(PositionStack* stack, bool* ok); |
| 312 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, |
| 313 bool* ok); |
| 314 Expression* ParsePrimaryExpression(bool* ok); |
| 315 Expression* ParseArrayLiteral(bool* ok); |
| 316 Expression* ParseObjectLiteral(bool* ok); |
| 317 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok); |
| 318 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); |
| 319 |
| 320 Expression* NewCompareNode(Token::Value op, |
| 321 Expression* x, |
| 322 Expression* y, |
| 323 int position); |
| 324 |
| 325 // Populate the constant properties fixed array for a materialized object |
| 326 // literal. |
| 327 void BuildObjectLiteralConstantProperties( |
| 328 ZoneList<ObjectLiteral::Property*>* properties, |
| 329 Handle<FixedArray> constants, |
| 330 bool* is_simple, |
| 331 bool* fast_elements, |
| 332 int* depth); |
| 333 |
| 334 // Populate the literals fixed array for a materialized array literal. |
| 335 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties, |
| 336 Handle<FixedArray> constants, |
| 337 bool* is_simple, |
| 338 int* depth); |
| 339 |
| 340 // Decide if a property should be in the object boilerplate. |
| 341 bool IsBoilerplateProperty(ObjectLiteral::Property* property); |
| 342 // If the expression is a literal, return the literal value; |
| 343 // if the expression is a materialized literal and is simple return a |
| 344 // compile time value as encoded by CompileTimeValue::GetValue(). |
| 345 // Otherwise, return undefined literal as the placeholder |
| 346 // in the object literal boilerplate. |
| 347 Handle<Object> GetBoilerplateValue(Expression* expression); |
| 348 |
| 349 enum FunctionLiteralType { |
| 350 EXPRESSION, |
| 351 DECLARATION, |
| 352 NESTED |
| 353 }; |
| 354 |
| 355 ZoneList<Expression*>* ParseArguments(bool* ok); |
| 356 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name, |
| 357 int function_token_position, |
| 358 FunctionLiteralType type, |
| 359 bool* ok); |
| 360 |
| 361 |
| 362 // Magical syntax support. |
| 363 Expression* ParseV8Intrinsic(bool* ok); |
| 364 |
| 365 INLINE(Token::Value peek()) { return scanner_.peek(); } |
| 366 INLINE(Token::Value Next()) { return scanner_.Next(); } |
| 367 INLINE(void Consume(Token::Value token)); |
| 368 void Expect(Token::Value token, bool* ok); |
| 369 bool Check(Token::Value token); |
| 370 void ExpectSemicolon(bool* ok); |
| 371 |
| 372 Handle<String> GetSymbol(bool* ok); |
| 373 |
| 374 // Get odd-ball literals. |
| 375 Literal* GetLiteralUndefined(); |
| 376 Literal* GetLiteralTheHole(); |
| 377 Literal* GetLiteralNumber(double value); |
| 378 |
| 379 Handle<String> ParseIdentifier(bool* ok); |
| 380 Handle<String> ParseIdentifierName(bool* ok); |
| 381 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get, |
| 382 bool* is_set, |
| 383 bool* ok); |
| 384 |
| 385 // Parser support |
| 386 virtual VariableProxy* Declare(Handle<String> name, Variable::Mode mode, |
| 387 FunctionLiteral* fun, |
| 388 bool resolve, |
| 389 bool* ok) = 0; |
| 390 |
| 391 bool TargetStackContainsLabel(Handle<String> label); |
| 392 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok); |
| 393 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok); |
| 394 |
| 395 void RegisterTargetUse(BreakTarget* target, Target* stop); |
| 396 |
| 397 // Create a number literal. |
| 398 Literal* NewNumberLiteral(double value); |
| 399 |
| 400 // Generate AST node that throw a ReferenceError with the given type. |
| 401 Expression* NewThrowReferenceError(Handle<String> type); |
| 402 |
| 403 // Generate AST node that throw a SyntaxError with the given |
| 404 // type. The first argument may be null (in the handle sense) in |
| 405 // which case no arguments are passed to the constructor. |
| 406 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first); |
| 407 |
| 408 // Generate AST node that throw a TypeError with the given |
| 409 // type. Both arguments must be non-null (in the handle sense). |
| 410 Expression* NewThrowTypeError(Handle<String> type, |
| 411 Handle<Object> first, |
| 412 Handle<Object> second); |
| 413 |
| 414 // Generic AST generator for throwing errors from compiled code. |
| 415 Expression* NewThrowError(Handle<String> constructor, |
| 416 Handle<String> type, |
| 417 Vector< Handle<Object> > arguments); |
| 418 |
| 419 // JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5 |
| 420 // specification section 15.12.1 (and appendix A.8). |
| 421 // The grammar is given section 15.12.1.2 (and appendix A.8.2). |
| 422 |
| 423 // Parse JSON input as a single JSON value. |
| 424 Expression* ParseJson(bool* ok); |
| 425 |
| 426 // Parse a single JSON value from input (grammar production JSONValue). |
| 427 // A JSON value is either a (double-quoted) string literal, a number literal, |
| 428 // one of "true", "false", or "null", or an object or array literal. |
| 429 Expression* ParseJsonValue(bool* ok); |
| 430 // Parse a JSON object literal (grammar production JSONObject). |
| 431 // An object literal is a squiggly-braced and comma separated sequence |
| 432 // (possibly empty) of key/value pairs, where the key is a JSON string |
| 433 // literal, the value is a JSON value, and the two are spearated by a colon. |
| 434 // A JavaScript object also allows numbers and identifiers as keys. |
| 435 Expression* ParseJsonObject(bool* ok); |
| 436 // Parses a JSON array literal (grammar production JSONArray). An array |
| 437 // literal is a square-bracketed and comma separated sequence (possibly empty) |
| 438 // of JSON values. |
| 439 // A JavaScript array allows leaving out values from the sequence. |
| 440 Expression* ParseJsonArray(bool* ok); |
| 441 |
| 442 friend class Target; |
| 443 friend class TargetScope; |
| 444 friend class LexicalScope; |
| 445 friend class TemporaryScope; |
| 446 }; |
197 | 447 |
198 | 448 |
199 // Support for handling complex values (array and object literals) that | 449 // Support for handling complex values (array and object literals) that |
200 // can be fully handled at compile time. | 450 // can be fully handled at compile time. |
201 class CompileTimeValue: public AllStatic { | 451 class CompileTimeValue: public AllStatic { |
202 public: | 452 public: |
203 enum Type { | 453 enum Type { |
204 OBJECT_LITERAL_FAST_ELEMENTS, | 454 OBJECT_LITERAL_FAST_ELEMENTS, |
205 OBJECT_LITERAL_SLOW_ELEMENTS, | 455 OBJECT_LITERAL_SLOW_ELEMENTS, |
206 ARRAY_LITERAL | 456 ARRAY_LITERAL |
(...skipping 16 matching lines...) Expand all Loading... |
223 static const int kTypeSlot = 0; | 473 static const int kTypeSlot = 0; |
224 static const int kElementsSlot = 1; | 474 static const int kElementsSlot = 1; |
225 | 475 |
226 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); | 476 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); |
227 }; | 477 }; |
228 | 478 |
229 | 479 |
230 } } // namespace v8::internal | 480 } } // namespace v8::internal |
231 | 481 |
232 #endif // V8_PARSER_H_ | 482 #endif // V8_PARSER_H_ |
OLD | NEW |