OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 }; | 111 }; |
112 | 112 |
113 ~PreParser() {} | 113 ~PreParser() {} |
114 | 114 |
115 // Pre-parse the program from the character stream; returns true on | 115 // Pre-parse the program from the character stream; returns true on |
116 // success (even if parsing failed, the pre-parse data successfully | 116 // success (even if parsing failed, the pre-parse data successfully |
117 // captured the syntax error), and false if a stack-overflow happened | 117 // captured the syntax error), and false if a stack-overflow happened |
118 // during parsing. | 118 // during parsing. |
119 static PreParseResult PreParseProgram(i::JavaScriptScanner* scanner, | 119 static PreParseResult PreParseProgram(i::JavaScriptScanner* scanner, |
120 i::ParserRecorder* log, | 120 i::ParserRecorder* log, |
121 bool allow_lazy, | 121 int flags, |
122 uintptr_t stack_limit) { | 122 uintptr_t stack_limit) { |
123 return PreParser(scanner, log, stack_limit, allow_lazy).PreParse(); | 123 bool allow_lazy = (flags & i::kAllowLazy) != 0; |
| 124 bool allow_natives_syntax = (flags & i::kAllowNativesSyntax) != 0; |
| 125 return PreParser(scanner, log, stack_limit, |
| 126 allow_lazy, allow_natives_syntax).PreParse(); |
124 } | 127 } |
125 | 128 |
126 private: | 129 private: |
127 // Used to detect duplicates in object literals. Each of the values | 130 // Used to detect duplicates in object literals. Each of the values |
128 // kGetterProperty, kSetterProperty and kValueProperty represents | 131 // kGetterProperty, kSetterProperty and kValueProperty represents |
129 // a type of object literal property. When parsing a property, its | 132 // a type of object literal property. When parsing a property, its |
130 // type value is stored in the DuplicateFinder for the property name. | 133 // type value is stored in the DuplicateFinder for the property name. |
131 // Values are chosen so that having intersection bits means the there is | 134 // Values are chosen so that having intersection bits means the there is |
132 // an incompatibility. | 135 // an incompatibility. |
133 // I.e., you can add a getter to a property that already has a setter, since | 136 // I.e., you can add a getter to a property that already has a setter, since |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 kTopLevelScope, | 175 kTopLevelScope, |
173 kFunctionScope | 176 kFunctionScope |
174 }; | 177 }; |
175 | 178 |
176 enum VariableDeclarationContext { | 179 enum VariableDeclarationContext { |
177 kSourceElement, | 180 kSourceElement, |
178 kStatement, | 181 kStatement, |
179 kForStatement | 182 kForStatement |
180 }; | 183 }; |
181 | 184 |
| 185 // If a list of variable declarations includes any initializers. |
| 186 enum VariableDeclarationProperties { |
| 187 kHasInitializers, |
| 188 kHasNoInitializers |
| 189 }; |
| 190 |
182 class Expression; | 191 class Expression; |
183 | 192 |
184 class Identifier { | 193 class Identifier { |
185 public: | 194 public: |
186 static Identifier Default() { | 195 static Identifier Default() { |
187 return Identifier(kUnknownIdentifier); | 196 return Identifier(kUnknownIdentifier); |
188 } | 197 } |
189 static Identifier Eval() { | 198 static Identifier Eval() { |
190 return Identifier(kEvalIdentifier); | 199 return Identifier(kEvalIdentifier); |
191 } | 200 } |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
392 explicit Statement(Type code) : code_(code) {} | 401 explicit Statement(Type code) : code_(code) {} |
393 Type code_; | 402 Type code_; |
394 }; | 403 }; |
395 | 404 |
396 enum SourceElements { | 405 enum SourceElements { |
397 kUnknownSourceElements | 406 kUnknownSourceElements |
398 }; | 407 }; |
399 | 408 |
400 typedef int Arguments; | 409 typedef int Arguments; |
401 | 410 |
| 411 // The Strict Mode (ECMA-262 5th edition, 4.2.2). |
| 412 enum StrictModeFlag { |
| 413 kNonStrictMode, |
| 414 kStrictMode, |
| 415 // This value is never used, but is needed to prevent GCC 4.5 from failing |
| 416 // to compile when we assert that a flag is either kNonStrictMode or |
| 417 // kStrictMode. |
| 418 kInvalidStrictFlag |
| 419 }; |
| 420 |
402 class Scope { | 421 class Scope { |
403 public: | 422 public: |
404 Scope(Scope** variable, ScopeType type) | 423 Scope(Scope** variable, ScopeType type) |
405 : variable_(variable), | 424 : variable_(variable), |
406 prev_(*variable), | 425 prev_(*variable), |
407 type_(type), | 426 type_(type), |
408 materialized_literal_count_(0), | 427 materialized_literal_count_(0), |
409 expected_properties_(0), | 428 expected_properties_(0), |
410 with_nesting_count_(0), | 429 with_nesting_count_(0), |
411 strict_((prev_ != NULL) && prev_->is_strict()) { | 430 strict_mode_flag_((prev_ != NULL) ? prev_->strict_mode_flag() |
| 431 : kNonStrictMode) { |
412 *variable = this; | 432 *variable = this; |
413 } | 433 } |
414 ~Scope() { *variable_ = prev_; } | 434 ~Scope() { *variable_ = prev_; } |
415 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } | 435 void NextMaterializedLiteralIndex() { materialized_literal_count_++; } |
416 void AddProperty() { expected_properties_++; } | 436 void AddProperty() { expected_properties_++; } |
417 ScopeType type() { return type_; } | 437 ScopeType type() { return type_; } |
418 int expected_properties() { return expected_properties_; } | 438 int expected_properties() { return expected_properties_; } |
419 int materialized_literal_count() { return materialized_literal_count_; } | 439 int materialized_literal_count() { return materialized_literal_count_; } |
420 bool IsInsideWith() { return with_nesting_count_ != 0; } | 440 bool IsInsideWith() { return with_nesting_count_ != 0; } |
421 bool is_strict() { return strict_; } | 441 bool is_strict_mode() { return strict_mode_flag_ == kStrictMode; } |
422 void set_strict() { strict_ = true; } | 442 StrictModeFlag strict_mode_flag() { |
| 443 return strict_mode_flag_; |
| 444 } |
| 445 void set_strict_mode_flag(StrictModeFlag strict_mode_flag) { |
| 446 strict_mode_flag_ = strict_mode_flag; |
| 447 } |
423 void EnterWith() { with_nesting_count_++; } | 448 void EnterWith() { with_nesting_count_++; } |
424 void LeaveWith() { with_nesting_count_--; } | 449 void LeaveWith() { with_nesting_count_--; } |
425 | 450 |
426 private: | 451 private: |
427 Scope** const variable_; | 452 Scope** const variable_; |
428 Scope* const prev_; | 453 Scope* const prev_; |
429 const ScopeType type_; | 454 const ScopeType type_; |
430 int materialized_literal_count_; | 455 int materialized_literal_count_; |
431 int expected_properties_; | 456 int expected_properties_; |
432 int with_nesting_count_; | 457 int with_nesting_count_; |
433 bool strict_; | 458 StrictModeFlag strict_mode_flag_; |
434 }; | 459 }; |
435 | 460 |
436 // Private constructor only used in PreParseProgram. | 461 // Private constructor only used in PreParseProgram. |
437 PreParser(i::JavaScriptScanner* scanner, | 462 PreParser(i::JavaScriptScanner* scanner, |
438 i::ParserRecorder* log, | 463 i::ParserRecorder* log, |
439 uintptr_t stack_limit, | 464 uintptr_t stack_limit, |
440 bool allow_lazy) | 465 bool allow_lazy, |
| 466 bool allow_natives_syntax) |
441 : scanner_(scanner), | 467 : scanner_(scanner), |
442 log_(log), | 468 log_(log), |
443 scope_(NULL), | 469 scope_(NULL), |
444 stack_limit_(stack_limit), | 470 stack_limit_(stack_limit), |
445 strict_mode_violation_location_(i::Scanner::Location::invalid()), | 471 strict_mode_violation_location_(i::Scanner::Location::invalid()), |
446 strict_mode_violation_type_(NULL), | 472 strict_mode_violation_type_(NULL), |
447 stack_overflow_(false), | 473 stack_overflow_(false), |
448 allow_lazy_(true), | 474 allow_lazy_(allow_lazy), |
| 475 allow_natives_syntax_(allow_natives_syntax), |
449 parenthesized_function_(false), | 476 parenthesized_function_(false), |
450 harmony_scoping_(scanner->HarmonyScoping()) { } | 477 harmony_scoping_(scanner->HarmonyScoping()) { } |
451 | 478 |
452 // Preparse the program. Only called in PreParseProgram after creating | 479 // Preparse the program. Only called in PreParseProgram after creating |
453 // the instance. | 480 // the instance. |
454 PreParseResult PreParse() { | 481 PreParseResult PreParse() { |
455 Scope top_scope(&scope_, kTopLevelScope); | 482 Scope top_scope(&scope_, kTopLevelScope); |
456 bool ok = true; | 483 bool ok = true; |
457 int start_position = scanner_->peek_location().beg_pos; | 484 int start_position = scanner_->peek_location().beg_pos; |
458 ParseSourceElements(i::Token::EOS, &ok); | 485 ParseSourceElements(i::Token::EOS, &ok); |
459 if (stack_overflow_) return kPreParseStackOverflow; | 486 if (stack_overflow_) return kPreParseStackOverflow; |
460 if (!ok) { | 487 if (!ok) { |
461 ReportUnexpectedToken(scanner_->current_token()); | 488 ReportUnexpectedToken(scanner_->current_token()); |
462 } else if (scope_->is_strict()) { | 489 } else if (scope_->is_strict_mode()) { |
463 CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok); | 490 CheckOctalLiteral(start_position, scanner_->location().end_pos, &ok); |
464 } | 491 } |
465 return kPreParseSuccess; | 492 return kPreParseSuccess; |
466 } | 493 } |
467 | 494 |
468 // Report syntax error | 495 // Report syntax error |
469 void ReportUnexpectedToken(i::Token::Value token); | 496 void ReportUnexpectedToken(i::Token::Value token); |
470 void ReportMessageAt(i::Scanner::Location location, | 497 void ReportMessageAt(i::Scanner::Location location, |
471 const char* type, | 498 const char* type, |
472 const char* name_opt) { | 499 const char* name_opt) { |
(...skipping 13 matching lines...) Expand all Loading... |
486 // By making the 'exception handling' explicit, we are forced to check | 513 // By making the 'exception handling' explicit, we are forced to check |
487 // for failure at the call sites. | 514 // for failure at the call sites. |
488 Statement ParseSourceElement(bool* ok); | 515 Statement ParseSourceElement(bool* ok); |
489 SourceElements ParseSourceElements(int end_token, bool* ok); | 516 SourceElements ParseSourceElements(int end_token, bool* ok); |
490 Statement ParseStatement(bool* ok); | 517 Statement ParseStatement(bool* ok); |
491 Statement ParseFunctionDeclaration(bool* ok); | 518 Statement ParseFunctionDeclaration(bool* ok); |
492 Statement ParseBlock(bool* ok); | 519 Statement ParseBlock(bool* ok); |
493 Statement ParseVariableStatement(VariableDeclarationContext var_context, | 520 Statement ParseVariableStatement(VariableDeclarationContext var_context, |
494 bool* ok); | 521 bool* ok); |
495 Statement ParseVariableDeclarations(VariableDeclarationContext var_context, | 522 Statement ParseVariableDeclarations(VariableDeclarationContext var_context, |
| 523 VariableDeclarationProperties* decl_props, |
496 int* num_decl, | 524 int* num_decl, |
497 bool* ok); | 525 bool* ok); |
498 Statement ParseExpressionOrLabelledStatement(bool* ok); | 526 Statement ParseExpressionOrLabelledStatement(bool* ok); |
499 Statement ParseIfStatement(bool* ok); | 527 Statement ParseIfStatement(bool* ok); |
500 Statement ParseContinueStatement(bool* ok); | 528 Statement ParseContinueStatement(bool* ok); |
501 Statement ParseBreakStatement(bool* ok); | 529 Statement ParseBreakStatement(bool* ok); |
502 Statement ParseReturnStatement(bool* ok); | 530 Statement ParseReturnStatement(bool* ok); |
503 Statement ParseWithStatement(bool* ok); | 531 Statement ParseWithStatement(bool* ok); |
504 Statement ParseSwitchStatement(bool* ok); | 532 Statement ParseSwitchStatement(bool* ok); |
505 Statement ParseDoWhileStatement(bool* ok); | 533 Statement ParseDoWhileStatement(bool* ok); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
556 // have been seen using peek. | 584 // have been seen using peek. |
557 stack_overflow_ = true; | 585 stack_overflow_ = true; |
558 } | 586 } |
559 } | 587 } |
560 return scanner_->Next(); | 588 return scanner_->Next(); |
561 } | 589 } |
562 | 590 |
563 bool peek_any_identifier(); | 591 bool peek_any_identifier(); |
564 | 592 |
565 void set_strict_mode() { | 593 void set_strict_mode() { |
566 scope_->set_strict(); | 594 scope_->set_strict_mode_flag(kStrictMode); |
567 } | 595 } |
568 | 596 |
569 bool strict_mode() { return scope_->is_strict(); } | 597 bool strict_mode() { return scope_->strict_mode_flag() == kStrictMode; } |
570 | 598 |
571 void Consume(i::Token::Value token) { Next(); } | 599 void Consume(i::Token::Value token) { Next(); } |
572 | 600 |
573 void Expect(i::Token::Value token, bool* ok) { | 601 void Expect(i::Token::Value token, bool* ok) { |
574 if (Next() != token) { | 602 if (Next() != token) { |
575 *ok = false; | 603 *ok = false; |
576 } | 604 } |
577 } | 605 } |
578 | 606 |
579 bool Check(i::Token::Value token) { | 607 bool Check(i::Token::Value token) { |
(...skipping 20 matching lines...) Expand all Loading... |
600 bool* ok); | 628 bool* ok); |
601 | 629 |
602 i::JavaScriptScanner* scanner_; | 630 i::JavaScriptScanner* scanner_; |
603 i::ParserRecorder* log_; | 631 i::ParserRecorder* log_; |
604 Scope* scope_; | 632 Scope* scope_; |
605 uintptr_t stack_limit_; | 633 uintptr_t stack_limit_; |
606 i::Scanner::Location strict_mode_violation_location_; | 634 i::Scanner::Location strict_mode_violation_location_; |
607 const char* strict_mode_violation_type_; | 635 const char* strict_mode_violation_type_; |
608 bool stack_overflow_; | 636 bool stack_overflow_; |
609 bool allow_lazy_; | 637 bool allow_lazy_; |
| 638 bool allow_natives_syntax_; |
610 bool parenthesized_function_; | 639 bool parenthesized_function_; |
611 bool harmony_scoping_; | 640 bool harmony_scoping_; |
612 }; | 641 }; |
613 } } // v8::preparser | 642 } } // v8::preparser |
614 | 643 |
615 #endif // V8_PREPARSER_H | 644 #endif // V8_PREPARSER_H |
OLD | NEW |