| 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 |