Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: src/preparser.h

Issue 196133017: Experimental parser: merge r19949 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/preparse-data.cc ('k') | src/preparser.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 10 matching lines...) Expand all
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_PREPARSER_H 28 #ifndef V8_PREPARSER_H
29 #define V8_PREPARSER_H 29 #define V8_PREPARSER_H
30 30
31 #include "func-name-inferrer.h"
31 #include "hashmap.h" 32 #include "hashmap.h"
32 #include "scopes.h" 33 #include "scopes.h"
33 #include "token.h" 34 #include "token.h"
34 #include "scanner.h" 35 #include "scanner.h"
35 #include "lexer/lexer.h" 36 #include "lexer/lexer.h"
36 #include "v8.h" 37 #include "v8.h"
37 38
38 namespace v8 { 39 namespace v8 {
39 namespace internal { 40 namespace internal {
40 41
41 // Common base class shared between parser and pre-parser. 42 // Common base class shared between parser and pre-parser. Traits encapsulate
43 // the differences between Parser and PreParser:
44
45 // - Return types: For example, Parser functions return Expression* and
46 // PreParser functions return PreParserExpression.
47
48 // - Creating parse tree nodes: Parser generates an AST during the recursive
49 // descent. PreParser doesn't create a tree. Instead, it passes around minimal
50 // data objects (PreParserExpression, PreParserIdentifier etc.) which contain
51 // just enough data for the upper layer functions. PreParserFactory is
52 // responsible for creating these dummy objects. It provides a similar kind of
53 // interface as AstNodeFactory, so ParserBase doesn't need to care which one is
54 // used.
55
56 // - Miscellanous other tasks interleaved with the recursive descent. For
57 // example, Parser keeps track of which function literals should be marked as
58 // pretenured, and PreParser doesn't care.
59
60 // The traits are expected to contain the following typedefs:
61 // struct Traits {
62 // // In particular...
63 // struct Type {
64 // // Used by FunctionState and BlockState.
65 // typedef Scope;
66 // typedef GeneratorVariable;
67 // typedef Zone;
68 // // Return types for traversing functions.
69 // typedef Identifier;
70 // typedef Expression;
71 // typedef FunctionLiteral;
72 // typedef ObjectLiteralProperty;
73 // typedef Literal;
74 // typedef ExpressionList;
75 // typedef PropertyList;
76 // // For constructing objects returned by the traversing functions.
77 // typedef Factory;
78 // };
79 // // ...
80 // };
81
42 template <typename Traits> 82 template <typename Traits>
43 class ParserBase : public Traits { 83 class ParserBase : public Traits {
44 public: 84 public:
45 ParserBase(Scanner* scanner, uintptr_t stack_limit, 85 ParserBase(Scanner* scanner, uintptr_t stack_limit,
46 v8::Extension* extension, 86 v8::Extension* extension,
47 typename Traits::Type::Zone* zone, 87 typename Traits::Type::Zone* zone,
48 typename Traits::Type::Parser this_object) 88 typename Traits::Type::Parser this_object)
49 : Traits(this_object), 89 : Traits(this_object),
50 parenthesized_function_(false), 90 parenthesized_function_(false),
51 scope_(NULL), 91 scope_(NULL),
52 function_state_(NULL), 92 function_state_(NULL),
53 extension_(extension), 93 extension_(extension),
94 fni_(NULL),
54 scanner_(scanner), 95 scanner_(scanner),
55 stack_limit_(stack_limit), 96 stack_limit_(stack_limit),
56 stack_overflow_(false), 97 stack_overflow_(false),
57 allow_lazy_(false), 98 allow_lazy_(false),
58 allow_natives_syntax_(false), 99 allow_natives_syntax_(false),
59 allow_generators_(false), 100 allow_generators_(false),
60 allow_for_of_(false), 101 allow_for_of_(false),
61 zone_(zone) { } 102 zone_(zone) { }
62 103
63 // Getters that indicate whether certain syntactical constructs are 104 // Getters that indicate whether certain syntactical constructs are
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
291 static int Precedence(Token::Value token, bool accept_IN) { 332 static int Precedence(Token::Value token, bool accept_IN) {
292 if (token == Token::IN && !accept_IN) 333 if (token == Token::IN && !accept_IN)
293 return 0; // 0 precedence will terminate binary expression parsing 334 return 0; // 0 precedence will terminate binary expression parsing
294 return Token::Precedence(token); 335 return Token::Precedence(token);
295 } 336 }
296 337
297 typename Traits::Type::Factory* factory() { 338 typename Traits::Type::Factory* factory() {
298 return function_state_->factory(); 339 return function_state_->factory();
299 } 340 }
300 341
301 bool is_classic_mode() const { return scope_->is_classic_mode(); } 342 StrictMode strict_mode() { return scope_->strict_mode(); }
302
303 bool is_generator() const { return function_state_->is_generator(); } 343 bool is_generator() const { return function_state_->is_generator(); }
304 344
305 // Report syntax errors. 345 // Report syntax errors.
306 void ReportMessage(const char* message, Vector<const char*> args) { 346 void ReportMessage(const char* message, Vector<const char*> args) {
307 Scanner::Location source_location = scanner()->location(); 347 Scanner::Location source_location = scanner()->location();
308 Traits::ReportMessageAt(source_location, message, args); 348 Traits::ReportMessageAt(source_location, message, args);
309 } 349 }
310 350
311 void ReportMessageAt(Scanner::Location location, const char* message) { 351 void ReportMessageAt(Scanner::Location location, const char* message) {
312 Traits::ReportMessageAt(location, message, Vector<const char*>::empty()); 352 Traits::ReportMessageAt(location, message, Vector<const char*>::empty());
(...skipping 12 matching lines...) Expand all
325 AllowEvalOrArgumentsAsIdentifier, 365 AllowEvalOrArgumentsAsIdentifier,
326 bool* ok); 366 bool* ok);
327 // Parses an identifier or a strict mode future reserved word, and indicate 367 // Parses an identifier or a strict mode future reserved word, and indicate
328 // whether it is strict mode future reserved. 368 // whether it is strict mode future reserved.
329 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord( 369 typename Traits::Type::Identifier ParseIdentifierOrStrictReservedWord(
330 bool* is_strict_reserved, 370 bool* is_strict_reserved,
331 bool* ok); 371 bool* ok);
332 typename Traits::Type::Identifier ParseIdentifierName(bool* ok); 372 typename Traits::Type::Identifier ParseIdentifierName(bool* ok);
333 // Parses an identifier and determines whether or not it is 'get' or 'set'. 373 // Parses an identifier and determines whether or not it is 'get' or 'set'.
334 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get, 374 typename Traits::Type::Identifier ParseIdentifierNameOrGetOrSet(bool* is_get,
335 bool* is_set, 375 bool* is_set,
336 bool* ok); 376 bool* ok);
337 377
338 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal, 378 typename Traits::Type::Expression ParseRegExpLiteral(bool seen_equal,
339 bool* ok); 379 bool* ok);
340 380
341 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok); 381 typename Traits::Type::Expression ParsePrimaryExpression(bool* ok);
342 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok); 382 typename Traits::Type::Expression ParseExpression(bool accept_IN, bool* ok);
343 typename Traits::Type::Expression ParseArrayLiteral(bool* ok); 383 typename Traits::Type::Expression ParseArrayLiteral(bool* ok);
384 typename Traits::Type::Expression ParseObjectLiteral(bool* ok);
385 typename Traits::Type::ExpressionList ParseArguments(bool* ok);
386 typename Traits::Type::Expression ParseAssignmentExpression(bool accept_IN,
387 bool* ok);
388 typename Traits::Type::Expression ParseYieldExpression(bool* ok);
344 389
345 // Used to detect duplicates in object literals. Each of the values 390 // Used to detect duplicates in object literals. Each of the values
346 // kGetterProperty, kSetterProperty and kValueProperty represents 391 // kGetterProperty, kSetterProperty and kValueProperty represents
347 // a type of object literal property. When parsing a property, its 392 // a type of object literal property. When parsing a property, its
348 // type value is stored in the DuplicateFinder for the property name. 393 // type value is stored in the DuplicateFinder for the property name.
349 // Values are chosen so that having intersection bits means the there is 394 // Values are chosen so that having intersection bits means the there is
350 // an incompatibility. 395 // an incompatibility.
351 // I.e., you can add a getter to a property that already has a setter, since 396 // I.e., you can add a getter to a property that already has a setter, since
352 // kGetterProperty and kSetterProperty doesn't intersect, but not if it 397 // kGetterProperty and kSetterProperty doesn't intersect, but not if it
353 // already has a getter or a value. Adding the getter to an existing 398 // already has a getter or a value. Adding the getter to an existing
354 // setter will store the value (kGetterProperty | kSetterProperty), which 399 // setter will store the value (kGetterProperty | kSetterProperty), which
355 // is incompatible with adding any further properties. 400 // is incompatible with adding any further properties.
356 enum PropertyKind { 401 enum PropertyKind {
357 kNone = 0, 402 kNone = 0,
358 // Bit patterns representing different object literal property types. 403 // Bit patterns representing different object literal property types.
359 kGetterProperty = 1, 404 kGetterProperty = 1,
360 kSetterProperty = 2, 405 kSetterProperty = 2,
361 kValueProperty = 7, 406 kValueProperty = 7,
362 // Helper constants. 407 // Helper constants.
363 kValueFlag = 4 408 kValueFlag = 4
364 }; 409 };
365 410
366 // Validation per ECMA 262 - 11.1.5 "Object Initialiser". 411 // Validation per ECMA 262 - 11.1.5 "Object Initialiser".
367 class ObjectLiteralChecker { 412 class ObjectLiteralChecker {
368 public: 413 public:
369 ObjectLiteralChecker(ParserBase* parser, LanguageMode mode) 414 ObjectLiteralChecker(ParserBase* parser, StrictMode strict_mode)
370 : parser_(parser), 415 : parser_(parser),
371 finder_(scanner()->unicode_cache()), 416 finder_(scanner()->unicode_cache()),
372 language_mode_(mode) { } 417 strict_mode_(strict_mode) { }
373 418
374 void CheckProperty(Token::Value property, PropertyKind type, bool* ok); 419 void CheckProperty(Token::Value property, PropertyKind type, bool* ok);
375 420
376 private: 421 private:
377 ParserBase* parser() const { return parser_; } 422 ParserBase* parser() const { return parser_; }
378 Scanner* scanner() const { return parser_->scanner(); } 423 Scanner* scanner() const { return parser_->scanner(); }
379 424
380 // Checks the type of conflict based on values coming from PropertyType. 425 // Checks the type of conflict based on values coming from PropertyType.
381 bool HasConflict(PropertyKind type1, PropertyKind type2) { 426 bool HasConflict(PropertyKind type1, PropertyKind type2) {
382 return (type1 & type2) != 0; 427 return (type1 & type2) != 0;
383 } 428 }
384 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) { 429 bool IsDataDataConflict(PropertyKind type1, PropertyKind type2) {
385 return ((type1 & type2) & kValueFlag) != 0; 430 return ((type1 & type2) & kValueFlag) != 0;
386 } 431 }
387 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) { 432 bool IsDataAccessorConflict(PropertyKind type1, PropertyKind type2) {
388 return ((type1 ^ type2) & kValueFlag) != 0; 433 return ((type1 ^ type2) & kValueFlag) != 0;
389 } 434 }
390 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) { 435 bool IsAccessorAccessorConflict(PropertyKind type1, PropertyKind type2) {
391 return ((type1 | type2) & kValueFlag) == 0; 436 return ((type1 | type2) & kValueFlag) == 0;
392 } 437 }
393 438
394 ParserBase* parser_; 439 ParserBase* parser_;
395 DuplicateFinder finder_; 440 DuplicateFinder finder_;
396 LanguageMode language_mode_; 441 StrictMode strict_mode_;
397 }; 442 };
398 443
399 // If true, the next (and immediately following) function literal is 444 // If true, the next (and immediately following) function literal is
400 // preceded by a parenthesis. 445 // preceded by a parenthesis.
401 // Heuristically that means that the function will be called immediately, 446 // Heuristically that means that the function will be called immediately,
402 // so never lazily compile it. 447 // so never lazily compile it.
403 bool parenthesized_function_; 448 bool parenthesized_function_;
404 449
405 typename Traits::Type::Scope* scope_; // Scope stack. 450 typename Traits::Type::Scope* scope_; // Scope stack.
406 FunctionState* function_state_; // Function state stack. 451 FunctionState* function_state_; // Function state stack.
407 v8::Extension* extension_; 452 v8::Extension* extension_;
453 FuncNameInferrer* fni_;
408 454
409 private: 455 private:
410 Scanner* scanner_; 456 Scanner* scanner_;
411 uintptr_t stack_limit_; 457 uintptr_t stack_limit_;
412 bool stack_overflow_; 458 bool stack_overflow_;
413 459
414 bool allow_lazy_; 460 bool allow_lazy_;
415 bool allow_natives_syntax_; 461 bool allow_natives_syntax_;
416 bool allow_generators_; 462 bool allow_generators_;
417 bool allow_for_of_; 463 bool allow_for_of_;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
515 bool IsUseStrictLiteral() { 561 bool IsUseStrictLiteral() {
516 return (code_ & kStringLiteralMask) == kUseStrictString; 562 return (code_ & kStringLiteralMask) == kUseStrictString;
517 } 563 }
518 564
519 bool IsThis() { return code_ == kThisExpression; } 565 bool IsThis() { return code_ == kThisExpression; }
520 566
521 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 567 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
522 568
523 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; } 569 bool IsStrictFunction() { return code_ == kStrictFunctionExpression; }
524 570
571 // Dummy implementation for making expression->AsCall() work (see below).
572 PreParserExpression* operator->() { return this; }
573
574 // These are only used when doing function name inferring, and PreParser
575 // doesn't do function name inferring.
576 void* AsCall() const { return NULL; }
577 void* AsCallNew() const { return NULL; }
578
579 // More dummy implementations of things PreParser doesn't need to track:
580 void set_index(int index) {} // For YieldExpressions
581
525 private: 582 private:
526 // First two/three bits are used as flags. 583 // First two/three bits are used as flags.
527 // Bit 0 and 1 represent identifiers or strings literals, and are 584 // Bit 0 and 1 represent identifiers or strings literals, and are
528 // mutually exclusive, but can both be absent. 585 // mutually exclusive, but can both be absent.
529 enum { 586 enum {
530 kUnknownExpression = 0, 587 kUnknownExpression = 0,
531 // Identifiers 588 // Identifiers
532 kIdentifierFlag = 1, // Used to detect labels. 589 kIdentifierFlag = 1, // Used to detect labels.
533 kIdentifierShift = 3, 590 kIdentifierShift = 3,
534 591
(...skipping 12 matching lines...) Expand all
547 604
548 int code_; 605 int code_;
549 }; 606 };
550 607
551 608
552 // PreParserExpressionList doesn't actually store the expressions because 609 // PreParserExpressionList doesn't actually store the expressions because
553 // PreParser doesn't need to. 610 // PreParser doesn't need to.
554 class PreParserExpressionList { 611 class PreParserExpressionList {
555 public: 612 public:
556 // These functions make list->Add(some_expression) work (and do nothing). 613 // These functions make list->Add(some_expression) work (and do nothing).
614 PreParserExpressionList() : length_(0) {}
557 PreParserExpressionList* operator->() { return this; } 615 PreParserExpressionList* operator->() { return this; }
558 void Add(PreParserExpression, void*) { } 616 void Add(PreParserExpression, void*) { ++length_; }
617 int length() const { return length_; }
618 private:
619 int length_;
559 }; 620 };
560 621
561 622
562 class PreParserScope { 623 class PreParserScope {
563 public: 624 public:
564 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 625 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type)
565 : scope_type_(scope_type) { 626 : scope_type_(scope_type) {
566 if (outer_scope) { 627 if (outer_scope) {
567 scope_inside_with_ = 628 scope_inside_with_ = outer_scope->scope_inside_with_ || is_with_scope();
568 outer_scope->scope_inside_with_ || is_with_scope(); 629 strict_mode_ = outer_scope->strict_mode();
569 language_mode_ = outer_scope->language_mode();
570 } else { 630 } else {
571 scope_inside_with_ = is_with_scope(); 631 scope_inside_with_ = is_with_scope();
572 language_mode_ = CLASSIC_MODE; 632 strict_mode_ = SLOPPY;
573 } 633 }
574 } 634 }
575 635
576 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; } 636 bool is_with_scope() const { return scope_type_ == WITH_SCOPE; }
577 bool is_classic_mode() const {
578 return language_mode() == CLASSIC_MODE;
579 }
580 bool is_extended_mode() {
581 return language_mode() == EXTENDED_MODE;
582 }
583 bool inside_with() const { 637 bool inside_with() const {
584 return scope_inside_with_; 638 return scope_inside_with_;
585 } 639 }
586 640
587 ScopeType type() { return scope_type_; } 641 ScopeType type() { return scope_type_; }
588 LanguageMode language_mode() const { return language_mode_; } 642 StrictMode strict_mode() const { return strict_mode_; }
589 void SetLanguageMode(LanguageMode language_mode) { 643 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
590 language_mode_ = language_mode;
591 }
592 644
593 private: 645 private:
594 ScopeType scope_type_; 646 ScopeType scope_type_;
595 bool scope_inside_with_; 647 bool scope_inside_with_;
596 LanguageMode language_mode_; 648 StrictMode strict_mode_;
597 }; 649 };
598 650
599 651
600 class PreParserFactory { 652 class PreParserFactory {
601 public: 653 public:
602 explicit PreParserFactory(void* extra_param) {} 654 explicit PreParserFactory(void* extra_param) {}
603 655
604 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, 656 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern,
605 PreParserIdentifier js_flags, 657 PreParserIdentifier js_flags,
606 int literal_index, 658 int literal_index,
607 int pos) { 659 int pos) {
608 return PreParserExpression::Default(); 660 return PreParserExpression::Default();
609 } 661 }
610 PreParserExpression NewBinaryOperation(Token::Value op, 662 PreParserExpression NewBinaryOperation(Token::Value op,
611 PreParserExpression left, 663 PreParserExpression left,
612 PreParserExpression right, int pos) { 664 PreParserExpression right, int pos) {
613 return PreParserExpression::Default(); 665 return PreParserExpression::Default();
614 } 666 }
615 PreParserExpression NewArrayLiteral(PreParserExpressionList values, 667 PreParserExpression NewArrayLiteral(PreParserExpressionList values,
616 int literal_index, 668 int literal_index,
617 int pos) { 669 int pos) {
618 return PreParserExpression::Default(); 670 return PreParserExpression::Default();
619 } 671 }
672
673 PreParserExpression NewObjectLiteralProperty(bool is_getter,
674 PreParserExpression value,
675 int pos) {
676 return PreParserExpression::Default();
677 }
678
679 PreParserExpression NewObjectLiteralProperty(PreParserExpression key,
680 PreParserExpression value) {
681 return PreParserExpression::Default();
682 }
683
684 PreParserExpression NewObjectLiteral(PreParserExpressionList properties,
685 int literal_index,
686 int boilerplate_properties,
687 bool has_function,
688 int pos) {
689 return PreParserExpression::Default();
690 }
691
692 PreParserExpression NewLiteral(PreParserIdentifier identifier,
693 int pos) {
694 return PreParserExpression::Default();
695 }
696
697 PreParserExpression NewNumberLiteral(double number,
698 int pos) {
699 return PreParserExpression::Default();
700 }
701
702 PreParserExpression NewAssignment(Token::Value op,
703 PreParserExpression left,
704 PreParserExpression right,
705 int pos) {
706 return PreParserExpression::Default();
707 }
708
709 PreParserExpression NewVariableProxy(void* generator_variable) {
710 return PreParserExpression::Default();
711 }
712
713 PreParserExpression NewYield(PreParserExpression generator_object,
714 PreParserExpression expression,
715 Yield::Kind yield_kind,
716 int pos) {
717 return PreParserExpression::Default();
718 }
620 }; 719 };
621 720
622 721
623 class PreParser; 722 class PreParser;
624 723
625 class PreParserTraits { 724 class PreParserTraits {
626 public: 725 public:
627 struct Type { 726 struct Type {
727 // TODO(marja): To be removed. The Traits object should contain all the data
728 // it needs.
628 typedef PreParser* Parser; 729 typedef PreParser* Parser;
629 730
630 // Types used by FunctionState and BlockState. 731 // Used by FunctionState and BlockState.
631 typedef PreParserScope Scope; 732 typedef PreParserScope Scope;
632 typedef PreParserFactory Factory;
633 // PreParser doesn't need to store generator variables. 733 // PreParser doesn't need to store generator variables.
634 typedef void GeneratorVariable; 734 typedef void GeneratorVariable;
635 // No interaction with Zones. 735 // No interaction with Zones.
636 typedef void Zone; 736 typedef void Zone;
637 737
638 // Return types for traversing functions. 738 // Return types for traversing functions.
639 typedef PreParserIdentifier Identifier; 739 typedef PreParserIdentifier Identifier;
640 typedef PreParserExpression Expression; 740 typedef PreParserExpression Expression;
741 typedef PreParserExpression YieldExpression;
742 typedef PreParserExpression FunctionLiteral;
743 typedef PreParserExpression ObjectLiteralProperty;
744 typedef PreParserExpression Literal;
641 typedef PreParserExpressionList ExpressionList; 745 typedef PreParserExpressionList ExpressionList;
746 typedef PreParserExpressionList PropertyList;
747
748 // For constructing objects returned by the traversing functions.
749 typedef PreParserFactory Factory;
642 }; 750 };
643 751
644 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} 752 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {}
645 753
646 // Custom operations executed when FunctionStates are created and 754 // Custom operations executed when FunctionStates are created and
647 // destructed. (The PreParser doesn't need to do anything.) 755 // destructed. (The PreParser doesn't need to do anything.)
648 template<typename FunctionState> 756 template<typename FunctionState>
649 static void SetUpFunctionState(FunctionState* function_state, void*) {} 757 static void SetUpFunctionState(FunctionState* function_state, void*) {}
650 template<typename FunctionState> 758 template<typename FunctionState>
651 static void TearDownFunctionState(FunctionState* function_state) {} 759 static void TearDownFunctionState(FunctionState* function_state) {}
652 760
653 // Helper functions for recursive descent. 761 // Helper functions for recursive descent.
654 static bool IsEvalOrArguments(PreParserIdentifier identifier) { 762 static bool IsEvalOrArguments(PreParserIdentifier identifier) {
655 return identifier.IsEvalOrArguments(); 763 return identifier.IsEvalOrArguments();
656 } 764 }
657 765
766 // Returns true if the expression is of type "this.foo".
767 static bool IsThisProperty(PreParserExpression expression) {
768 return expression.IsThisProperty();
769 }
770
771 static bool IsBoilerplateProperty(PreParserExpression property) {
772 // PreParser doesn't count boilerplate properties.
773 return false;
774 }
775
776 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
777 return false;
778 }
779
780 // Functions for encapsulating the differences between parsing and preparsing;
781 // operations interleaved with the recursive descent.
782 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
783 // PreParser should not use FuncNameInferrer.
784 ASSERT(false);
785 }
786
787 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
788 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
789
790 static void CheckAssigningFunctionLiteralToProperty(
791 PreParserExpression left, PreParserExpression right) {}
792
793
794 static PreParserExpression ValidateAssignmentLeftHandSide(
795 PreParserExpression expression) {
796 // Parser generates a runtime error here if the left hand side is not valid.
797 // PreParser doesn't have to.
798 return expression;
799 }
800
801 static PreParserExpression MarkExpressionAsLValue(
802 PreParserExpression expression) {
803 // TODO(marja): To be able to produce the same errors, the preparser needs
804 // to start tracking which expressions are variables and which are lvalues.
805 return expression;
806 }
807
808 // Checks LHS expression for assignment and prefix/postfix increment/decrement
809 // in strict mode.
810 void CheckStrictModeLValue(PreParserExpression expression, bool* ok);
811
812
658 // Reporting errors. 813 // Reporting errors.
659 void ReportMessageAt(Scanner::Location location, 814 void ReportMessageAt(Scanner::Location location,
660 const char* message, 815 const char* message,
661 Vector<const char*> args); 816 Vector<const char*> args);
662 void ReportMessageAt(Scanner::Location location, 817 void ReportMessageAt(Scanner::Location location,
663 const char* type, 818 const char* type,
664 const char* name_opt); 819 const char* name_opt);
665 void ReportMessageAt(int start_pos, 820 void ReportMessageAt(int start_pos,
666 int end_pos, 821 int end_pos,
667 const char* type, 822 const char* type,
668 const char* name_opt); 823 const char* name_opt);
669 824
670 // "null" return type creators. 825 // "null" return type creators.
671 static PreParserIdentifier EmptyIdentifier() { 826 static PreParserIdentifier EmptyIdentifier() {
672 return PreParserIdentifier::Default(); 827 return PreParserIdentifier::Default();
673 } 828 }
674 static PreParserExpression EmptyExpression() { 829 static PreParserExpression EmptyExpression() {
675 return PreParserExpression::Default(); 830 return PreParserExpression::Default();
676 } 831 }
832 static PreParserExpression EmptyLiteral() {
833 return PreParserExpression::Default();
834 }
835 static PreParserExpressionList NullExpressionList() {
836 return PreParserExpressionList();
837 }
677 838
678 // Odd-ball literal creators. 839 // Odd-ball literal creators.
679 static PreParserExpression GetLiteralTheHole(int position, 840 static PreParserExpression GetLiteralTheHole(int position,
680 PreParserFactory* factory) { 841 PreParserFactory* factory) {
681 return PreParserExpression::Default(); 842 return PreParserExpression::Default();
682 } 843 }
683 844
684 // Producing data during the recursive descent. 845 // Producing data during the recursive descent.
685 PreParserIdentifier GetSymbol(Scanner* scanner); 846 PreParserIdentifier GetSymbol(Scanner* scanner);
686 static PreParserIdentifier NextLiteralString(Scanner* scanner, 847 static PreParserIdentifier NextLiteralString(Scanner* scanner,
(...skipping 19 matching lines...) Expand all
706 } 867 }
707 868
708 PreParserExpression ExpressionFromString(int pos, 869 PreParserExpression ExpressionFromString(int pos,
709 Scanner* scanner, 870 Scanner* scanner,
710 PreParserFactory* factory = NULL); 871 PreParserFactory* factory = NULL);
711 872
712 static PreParserExpressionList NewExpressionList(int size, void* zone) { 873 static PreParserExpressionList NewExpressionList(int size, void* zone) {
713 return PreParserExpressionList(); 874 return PreParserExpressionList();
714 } 875 }
715 876
877 static PreParserExpressionList NewPropertyList(int size, void* zone) {
878 return PreParserExpressionList();
879 }
880
716 // Temporary glue; these functions will move to ParserBase. 881 // Temporary glue; these functions will move to ParserBase.
717 PreParserExpression ParseAssignmentExpression(bool accept_IN, bool* ok);
718 PreParserExpression ParseObjectLiteral(bool* ok);
719 PreParserExpression ParseV8Intrinsic(bool* ok); 882 PreParserExpression ParseV8Intrinsic(bool* ok);
883 PreParserExpression ParseFunctionLiteral(
884 PreParserIdentifier name,
885 Scanner::Location function_name_location,
886 bool name_is_strict_reserved,
887 bool is_generator,
888 int function_token_position,
889 FunctionLiteral::FunctionType type,
890 bool* ok);
891 PreParserExpression ParseConditionalExpression(bool accept_IN, bool* ok);
720 892
721 private: 893 private:
722 PreParser* pre_parser_; 894 PreParser* pre_parser_;
723 }; 895 };
724 896
725 897
726 // Preparsing checks a JavaScript program and emits preparse-data that helps 898 // Preparsing checks a JavaScript program and emits preparse-data that helps
727 // a later parsing to be faster. 899 // a later parsing to be faster.
728 // See preparse-data-format.h for the data format. 900 // See preparse-data-format.h for the data format.
729 901
(...skipping 27 matching lines...) Expand all
757 // during parsing. 929 // during parsing.
758 PreParseResult PreParseProgram() { 930 PreParseResult PreParseProgram() {
759 PreParserScope scope(scope_, GLOBAL_SCOPE); 931 PreParserScope scope(scope_, GLOBAL_SCOPE);
760 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); 932 FunctionState top_scope(&function_state_, &scope_, &scope, NULL);
761 bool ok = true; 933 bool ok = true;
762 int start_position = scanner()->peek_location().beg_pos; 934 int start_position = scanner()->peek_location().beg_pos;
763 ParseSourceElements(Token::EOS, &ok); 935 ParseSourceElements(Token::EOS, &ok);
764 if (stack_overflow()) return kPreParseStackOverflow; 936 if (stack_overflow()) return kPreParseStackOverflow;
765 if (!ok) { 937 if (!ok) {
766 ReportUnexpectedToken(scanner()->current_token()); 938 ReportUnexpectedToken(scanner()->current_token());
767 } else if (!scope_->is_classic_mode()) { 939 } else if (scope_->strict_mode() == STRICT) {
768 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 940 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
769 } 941 }
770 return kPreParseSuccess; 942 return kPreParseSuccess;
771 } 943 }
772 944
773 // Parses a single function literal, from the opening parentheses before 945 // Parses a single function literal, from the opening parentheses before
774 // parameters to the closing brace after the body. 946 // parameters to the closing brace after the body.
775 // Returns a FunctionEntry describing the body of the function in enough 947 // Returns a FunctionEntry describing the body of the function in enough
776 // detail that it can be lazily compiled. 948 // detail that it can be lazily compiled.
777 // The scanner is expected to have matched the "function" or "function*" 949 // The scanner is expected to have matched the "function" or "function*"
778 // keyword and parameters, and have consumed the initial '{'. 950 // keyword and parameters, and have consumed the initial '{'.
779 // At return, unless an error occurred, the scanner is positioned before the 951 // At return, unless an error occurred, the scanner is positioned before the
780 // the final '}'. 952 // the final '}'.
781 PreParseResult PreParseLazyFunction(LanguageMode mode, 953 PreParseResult PreParseLazyFunction(StrictMode strict_mode,
782 bool is_generator, 954 bool is_generator,
783 ParserRecorder* log); 955 ParserRecorder* log);
784 956
785 private: 957 private:
786 friend class PreParserTraits; 958 friend class PreParserTraits;
787 959
788 // These types form an algebra over syntactic categories that is just 960 // These types form an algebra over syntactic categories that is just
789 // rich enough to let us recognize and propagate the constructs that 961 // rich enough to let us recognize and propagate the constructs that
790 // are either being counted in the preparser data, or is important 962 // are either being counted in the preparser data, or is important
791 // to throw the correct syntax error exceptions. 963 // to throw the correct syntax error exceptions.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 }; 1018 };
847 1019
848 explicit Statement(Type code) : code_(code) {} 1020 explicit Statement(Type code) : code_(code) {}
849 Type code_; 1021 Type code_;
850 }; 1022 };
851 1023
852 enum SourceElements { 1024 enum SourceElements {
853 kUnknownSourceElements 1025 kUnknownSourceElements
854 }; 1026 };
855 1027
856 typedef int Arguments;
857
858 // All ParseXXX functions take as the last argument an *ok parameter 1028 // All ParseXXX functions take as the last argument an *ok parameter
859 // which is set to false if parsing failed; it is unchanged otherwise. 1029 // which is set to false if parsing failed; it is unchanged otherwise.
860 // By making the 'exception handling' explicit, we are forced to check 1030 // By making the 'exception handling' explicit, we are forced to check
861 // for failure at the call sites. 1031 // for failure at the call sites.
862 Statement ParseSourceElement(bool* ok); 1032 Statement ParseSourceElement(bool* ok);
863 SourceElements ParseSourceElements(int end_token, bool* ok); 1033 SourceElements ParseSourceElements(int end_token, bool* ok);
864 Statement ParseStatement(bool* ok); 1034 Statement ParseStatement(bool* ok);
865 Statement ParseFunctionDeclaration(bool* ok); 1035 Statement ParseFunctionDeclaration(bool* ok);
866 Statement ParseBlock(bool* ok); 1036 Statement ParseBlock(bool* ok);
867 Statement ParseVariableStatement(VariableDeclarationContext var_context, 1037 Statement ParseVariableStatement(VariableDeclarationContext var_context,
868 bool* ok); 1038 bool* ok);
869 Statement ParseVariableDeclarations(VariableDeclarationContext var_context, 1039 Statement ParseVariableDeclarations(VariableDeclarationContext var_context,
870 VariableDeclarationProperties* decl_props, 1040 VariableDeclarationProperties* decl_props,
871 int* num_decl, 1041 int* num_decl,
872 bool* ok); 1042 bool* ok);
873 Statement ParseExpressionOrLabelledStatement(bool* ok); 1043 Statement ParseExpressionOrLabelledStatement(bool* ok);
874 Statement ParseIfStatement(bool* ok); 1044 Statement ParseIfStatement(bool* ok);
875 Statement ParseContinueStatement(bool* ok); 1045 Statement ParseContinueStatement(bool* ok);
876 Statement ParseBreakStatement(bool* ok); 1046 Statement ParseBreakStatement(bool* ok);
877 Statement ParseReturnStatement(bool* ok); 1047 Statement ParseReturnStatement(bool* ok);
878 Statement ParseWithStatement(bool* ok); 1048 Statement ParseWithStatement(bool* ok);
879 Statement ParseSwitchStatement(bool* ok); 1049 Statement ParseSwitchStatement(bool* ok);
880 Statement ParseDoWhileStatement(bool* ok); 1050 Statement ParseDoWhileStatement(bool* ok);
881 Statement ParseWhileStatement(bool* ok); 1051 Statement ParseWhileStatement(bool* ok);
882 Statement ParseForStatement(bool* ok); 1052 Statement ParseForStatement(bool* ok);
883 Statement ParseThrowStatement(bool* ok); 1053 Statement ParseThrowStatement(bool* ok);
884 Statement ParseTryStatement(bool* ok); 1054 Statement ParseTryStatement(bool* ok);
885 Statement ParseDebuggerStatement(bool* ok); 1055 Statement ParseDebuggerStatement(bool* ok);
886
887 Expression ParseAssignmentExpression(bool accept_IN, bool* ok);
888 Expression ParseYieldExpression(bool* ok);
889 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1056 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
890 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 1057 Expression ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
891 Expression ParseUnaryExpression(bool* ok); 1058 Expression ParseUnaryExpression(bool* ok);
892 Expression ParsePostfixExpression(bool* ok); 1059 Expression ParsePostfixExpression(bool* ok);
893 Expression ParseLeftHandSideExpression(bool* ok); 1060 Expression ParseLeftHandSideExpression(bool* ok);
894 Expression ParseMemberExpression(bool* ok); 1061 Expression ParseMemberExpression(bool* ok);
895 Expression ParseMemberExpressionContinuation(PreParserExpression expression, 1062 Expression ParseMemberExpressionContinuation(PreParserExpression expression,
896 bool* ok); 1063 bool* ok);
897 Expression ParseMemberWithNewPrefixesExpression(bool* ok); 1064 Expression ParseMemberWithNewPrefixesExpression(bool* ok);
898 Expression ParseObjectLiteral(bool* ok); 1065 Expression ParseObjectLiteral(bool* ok);
899 Expression ParseV8Intrinsic(bool* ok); 1066 Expression ParseV8Intrinsic(bool* ok);
900 1067
901 Arguments ParseArguments(bool* ok);
902 Expression ParseFunctionLiteral( 1068 Expression ParseFunctionLiteral(
903 Identifier name, 1069 Identifier name,
904 Scanner::Location function_name_location, 1070 Scanner::Location function_name_location,
905 bool name_is_strict_reserved, 1071 bool name_is_strict_reserved,
906 bool is_generator, 1072 bool is_generator,
1073 int function_token_pos,
1074 FunctionLiteral::FunctionType function_type,
907 bool* ok); 1075 bool* ok);
908 void ParseLazyFunctionLiteralBody(bool* ok); 1076 void ParseLazyFunctionLiteralBody(bool* ok);
909 1077
910 // Logs the currently parsed literal as a symbol in the preparser data. 1078 // Logs the currently parsed literal as a symbol in the preparser data.
911 void LogSymbol(); 1079 void LogSymbol();
912 // Log the currently parsed string literal. 1080 // Log the currently parsed string literal.
913 Expression GetStringSymbol(); 1081 Expression GetStringSymbol();
914 1082
915 bool CheckInOrOf(bool accept_OF); 1083 bool CheckInOrOf(bool accept_OF);
916 1084
(...skipping 28 matching lines...) Expand all
945 template<class Traits> 1113 template<class Traits>
946 ParserBase<Traits>::FunctionState::~FunctionState() { 1114 ParserBase<Traits>::FunctionState::~FunctionState() {
947 *scope_stack_ = outer_scope_; 1115 *scope_stack_ = outer_scope_;
948 *function_state_stack_ = outer_function_state_; 1116 *function_state_stack_ = outer_function_state_;
949 Traits::TearDownFunctionState(this); 1117 Traits::TearDownFunctionState(this);
950 } 1118 }
951 1119
952 1120
953 template<class Traits> 1121 template<class Traits>
954 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1122 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
955 // We don't report stack overflows here, to avoid increasing the
956 // stack depth even further. Instead we report it after parsing is
957 // over, in ParseProgram.
958 if (token == Token::ILLEGAL && stack_overflow()) {
959 return;
960 }
961 Scanner::Location source_location = scanner()->location(); 1123 Scanner::Location source_location = scanner()->location();
962 1124
963 // Four of the tokens are treated specially 1125 // Four of the tokens are treated specially
964 switch (token) { 1126 switch (token) {
965 case Token::EOS: 1127 case Token::EOS:
966 return ReportMessageAt(source_location, "unexpected_eos"); 1128 return ReportMessageAt(source_location, "unexpected_eos");
967 case Token::NUMBER: 1129 case Token::NUMBER:
968 return ReportMessageAt(source_location, "unexpected_token_number"); 1130 return ReportMessageAt(source_location, "unexpected_token_number");
969 case Token::STRING: 1131 case Token::STRING:
970 return ReportMessageAt(source_location, "unexpected_token_string"); 1132 return ReportMessageAt(source_location, "unexpected_token_string");
971 case Token::IDENTIFIER: 1133 case Token::IDENTIFIER:
972 return ReportMessageAt(source_location, "unexpected_token_identifier"); 1134 return ReportMessageAt(source_location, "unexpected_token_identifier");
973 case Token::FUTURE_RESERVED_WORD: 1135 case Token::FUTURE_RESERVED_WORD:
974 return ReportMessageAt(source_location, "unexpected_reserved"); 1136 return ReportMessageAt(source_location, "unexpected_reserved");
975 case Token::YIELD: 1137 case Token::YIELD:
976 case Token::FUTURE_STRICT_RESERVED_WORD: 1138 case Token::FUTURE_STRICT_RESERVED_WORD:
977 return ReportMessageAt(source_location, 1139 return ReportMessageAt(source_location, strict_mode() == SLOPPY
978 is_classic_mode() ? "unexpected_token_identifier" 1140 ? "unexpected_token_identifier" : "unexpected_strict_reserved");
979 : "unexpected_strict_reserved");
980 default: 1141 default:
981 const char* name = Token::String(token); 1142 const char* name = Token::String(token);
982 ASSERT(name != NULL); 1143 ASSERT(name != NULL);
983 Traits::ReportMessageAt( 1144 Traits::ReportMessageAt(
984 source_location, "unexpected_token", Vector<const char*>(&name, 1)); 1145 source_location, "unexpected_token", Vector<const char*>(&name, 1));
985 } 1146 }
986 } 1147 }
987 1148
988 1149
989 template<class Traits> 1150 template<class Traits>
990 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier( 1151 typename Traits::Type::Identifier ParserBase<Traits>::ParseIdentifier(
991 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments, 1152 AllowEvalOrArgumentsAsIdentifier allow_eval_or_arguments,
992 bool* ok) { 1153 bool* ok) {
993 Token::Value next = Next(); 1154 Token::Value next = Next();
994 if (next == Token::IDENTIFIER) { 1155 if (next == Token::IDENTIFIER) {
995 typename Traits::Type::Identifier name = this->GetSymbol(scanner()); 1156 typename Traits::Type::Identifier name = this->GetSymbol(scanner());
996 if (allow_eval_or_arguments == kDontAllowEvalOrArguments && 1157 if (allow_eval_or_arguments == kDontAllowEvalOrArguments &&
997 !is_classic_mode() && this->IsEvalOrArguments(name)) { 1158 strict_mode() == STRICT && this->IsEvalOrArguments(name)) {
998 ReportMessageAt(scanner()->location(), "strict_eval_arguments"); 1159 ReportMessageAt(scanner()->location(), "strict_eval_arguments");
999 *ok = false; 1160 *ok = false;
1000 } 1161 }
1001 return name; 1162 return name;
1002 } else if (is_classic_mode() && (next == Token::FUTURE_STRICT_RESERVED_WORD || 1163 } else if (strict_mode() == SLOPPY &&
1003 (next == Token::YIELD && !is_generator()))) { 1164 (next == Token::FUTURE_STRICT_RESERVED_WORD ||
1165 (next == Token::YIELD && !is_generator()))) {
1004 return this->GetSymbol(scanner()); 1166 return this->GetSymbol(scanner());
1005 } else { 1167 } else {
1006 this->ReportUnexpectedToken(next); 1168 this->ReportUnexpectedToken(next);
1007 *ok = false; 1169 *ok = false;
1008 return Traits::EmptyIdentifier(); 1170 return Traits::EmptyIdentifier();
1009 } 1171 }
1010 } 1172 }
1011 1173
1012 1174
1013 template <class Traits> 1175 template <class Traits>
(...skipping 29 matching lines...) Expand all
1043 } 1205 }
1044 1206
1045 1207
1046 template <class Traits> 1208 template <class Traits>
1047 typename Traits::Type::Identifier 1209 typename Traits::Type::Identifier
1048 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get, 1210 ParserBase<Traits>::ParseIdentifierNameOrGetOrSet(bool* is_get,
1049 bool* is_set, 1211 bool* is_set,
1050 bool* ok) { 1212 bool* ok) {
1051 typename Traits::Type::Identifier result = ParseIdentifierName(ok); 1213 typename Traits::Type::Identifier result = ParseIdentifierName(ok);
1052 if (!*ok) return Traits::EmptyIdentifier(); 1214 if (!*ok) return Traits::EmptyIdentifier();
1053 if (scanner()->is_literal_ascii() && 1215 scanner()->IsGetOrSet(is_get, is_set);
1054 scanner()->literal_length() == 3) {
1055 const char* token = scanner()->literal_ascii_string().start();
1056 *is_get = strncmp(token, "get", 3) == 0;
1057 *is_set = !*is_get && strncmp(token, "set", 3) == 0;
1058 }
1059 return result; 1216 return result;
1060 } 1217 }
1061 1218
1062 1219
1063 template <class Traits> 1220 template <class Traits>
1064 typename Traits::Type::Expression 1221 typename Traits::Type::Expression
1065 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) { 1222 ParserBase<Traits>::ParseRegExpLiteral(bool seen_equal, bool* ok) {
1066 int pos = peek_position(); 1223 int pos = peek_position();
1067 if (!scanner()->ScanRegExpPattern(seen_equal)) { 1224 if (!scanner()->ScanRegExpPattern(seen_equal)) {
1068 Next(); 1225 Next();
(...skipping 18 matching lines...) Expand all
1087 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos); 1244 return factory()->NewRegExpLiteral(js_pattern, js_flags, literal_index, pos);
1088 } 1245 }
1089 1246
1090 1247
1091 #define CHECK_OK ok); \ 1248 #define CHECK_OK ok); \
1092 if (!*ok) return this->EmptyExpression(); \ 1249 if (!*ok) return this->EmptyExpression(); \
1093 ((void)0 1250 ((void)0
1094 #define DUMMY ) // to make indentation work 1251 #define DUMMY ) // to make indentation work
1095 #undef DUMMY 1252 #undef DUMMY
1096 1253
1254 // Used in functions where the return type is not Traits::Type::Expression.
1255 #define CHECK_OK_CUSTOM(x) ok); \
1256 if (!*ok) return this->x(); \
1257 ((void)0
1258 #define DUMMY ) // to make indentation work
1259 #undef DUMMY
1260
1097 template <class Traits> 1261 template <class Traits>
1098 typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression( 1262 typename Traits::Type::Expression ParserBase<Traits>::ParsePrimaryExpression(
1099 bool* ok) { 1263 bool* ok) {
1100 // PrimaryExpression :: 1264 // PrimaryExpression ::
1101 // 'this' 1265 // 'this'
1102 // 'null' 1266 // 'null'
1103 // 'true' 1267 // 'true'
1104 // 'false' 1268 // 'false'
1105 // Identifier 1269 // Identifier
1106 // Number 1270 // Number
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1232 } 1396 }
1233 } 1397 }
1234 Expect(Token::RBRACK, CHECK_OK); 1398 Expect(Token::RBRACK, CHECK_OK);
1235 1399
1236 // Update the scope information before the pre-parsing bailout. 1400 // Update the scope information before the pre-parsing bailout.
1237 int literal_index = function_state_->NextMaterializedLiteralIndex(); 1401 int literal_index = function_state_->NextMaterializedLiteralIndex();
1238 1402
1239 return factory()->NewArrayLiteral(values, literal_index, pos); 1403 return factory()->NewArrayLiteral(values, literal_index, pos);
1240 } 1404 }
1241 1405
1406
1407 template <class Traits>
1408 typename Traits::Type::Expression ParserBase<Traits>::ParseObjectLiteral(
1409 bool* ok) {
1410 // ObjectLiteral ::
1411 // '{' ((
1412 // ((IdentifierName | String | Number) ':' AssignmentExpression) |
1413 // (('get' | 'set') (IdentifierName | String | Number) FunctionLiteral)
1414 // ) ',')* '}'
1415 // (Except that trailing comma is not required and not allowed.)
1416
1417 int pos = peek_position();
1418 typename Traits::Type::PropertyList properties =
1419 this->NewPropertyList(4, zone_);
1420 int number_of_boilerplate_properties = 0;
1421 bool has_function = false;
1422
1423 ObjectLiteralChecker checker(this, strict_mode());
1424
1425 Expect(Token::LBRACE, CHECK_OK);
1426
1427 while (peek() != Token::RBRACE) {
1428 if (fni_ != NULL) fni_->Enter();
1429
1430 typename Traits::Type::Literal key = this->EmptyLiteral();
1431 Token::Value next = peek();
1432 int next_pos = peek_position();
1433
1434 switch (next) {
1435 case Token::FUTURE_RESERVED_WORD:
1436 case Token::FUTURE_STRICT_RESERVED_WORD:
1437 case Token::IDENTIFIER: {
1438 bool is_getter = false;
1439 bool is_setter = false;
1440 typename Traits::Type::Identifier id =
1441 ParseIdentifierNameOrGetOrSet(&is_getter, &is_setter, CHECK_OK);
1442 if (fni_ != NULL) this->PushLiteralName(fni_, id);
1443
1444 if ((is_getter || is_setter) && peek() != Token::COLON) {
1445 // Special handling of getter and setter syntax:
1446 // { ... , get foo() { ... }, ... , set foo(v) { ... v ... } , ... }
1447 // We have already read the "get" or "set" keyword.
1448 Token::Value next = Next();
1449 if (next != i::Token::IDENTIFIER &&
1450 next != i::Token::FUTURE_RESERVED_WORD &&
1451 next != i::Token::FUTURE_STRICT_RESERVED_WORD &&
1452 next != i::Token::NUMBER &&
1453 next != i::Token::STRING &&
1454 !Token::IsKeyword(next)) {
1455 ReportUnexpectedToken(next);
1456 *ok = false;
1457 return this->EmptyLiteral();
1458 }
1459 // Validate the property.
1460 PropertyKind type = is_getter ? kGetterProperty : kSetterProperty;
1461 checker.CheckProperty(next, type, CHECK_OK);
1462 typename Traits::Type::Identifier name = this->GetSymbol(scanner_);
1463 typename Traits::Type::FunctionLiteral value =
1464 this->ParseFunctionLiteral(
1465 name, scanner()->location(),
1466 false, // reserved words are allowed here
1467 false, // not a generator
1468 RelocInfo::kNoPosition, FunctionLiteral::ANONYMOUS_EXPRESSION,
1469 CHECK_OK);
1470 // Allow any number of parameters for compatibilty with JSC.
1471 // Specification only allows zero parameters for get and one for set.
1472 typename Traits::Type::ObjectLiteralProperty property =
1473 factory()->NewObjectLiteralProperty(is_getter, value, next_pos);
1474 if (this->IsBoilerplateProperty(property)) {
1475 number_of_boilerplate_properties++;
1476 }
1477 properties->Add(property, zone());
1478 if (peek() != Token::RBRACE) {
1479 // Need {} because of the CHECK_OK macro.
1480 Expect(Token::COMMA, CHECK_OK);
1481 }
1482
1483 if (fni_ != NULL) {
1484 fni_->Infer();
1485 fni_->Leave();
1486 }
1487 continue; // restart the while
1488 }
1489 // Failed to parse as get/set property, so it's just a normal property
1490 // (which might be called "get" or "set" or something else).
1491 key = factory()->NewLiteral(id, next_pos);
1492 break;
1493 }
1494 case Token::STRING: {
1495 Consume(Token::STRING);
1496 typename Traits::Type::Identifier string = this->GetSymbol(scanner_);
1497 if (fni_ != NULL) this->PushLiteralName(fni_, string);
1498 uint32_t index;
1499 if (this->IsArrayIndex(string, &index)) {
1500 key = factory()->NewNumberLiteral(index, next_pos);
1501 break;
1502 }
1503 key = factory()->NewLiteral(string, next_pos);
1504 break;
1505 }
1506 case Token::NUMBER: {
1507 Consume(Token::NUMBER);
1508 key = this->ExpressionFromLiteral(Token::NUMBER, next_pos, scanner_,
1509 factory());
1510 break;
1511 }
1512 default:
1513 if (Token::IsKeyword(next)) {
1514 Consume(next);
1515 typename Traits::Type::Identifier string = this->GetSymbol(scanner_);
1516 key = factory()->NewLiteral(string, next_pos);
1517 } else {
1518 Token::Value next = Next();
1519 ReportUnexpectedToken(next);
1520 *ok = false;
1521 return this->EmptyLiteral();
1522 }
1523 }
1524
1525 // Validate the property
1526 checker.CheckProperty(next, kValueProperty, CHECK_OK);
1527
1528 Expect(Token::COLON, CHECK_OK);
1529 typename Traits::Type::Expression value =
1530 this->ParseAssignmentExpression(true, CHECK_OK);
1531
1532 typename Traits::Type::ObjectLiteralProperty property =
1533 factory()->NewObjectLiteralProperty(key, value);
1534
1535 // Mark top-level object literals that contain function literals and
1536 // pretenure the literal so it can be added as a constant function
1537 // property. (Parser only.)
1538 this->CheckFunctionLiteralInsideTopLevelObjectLiteral(scope_, value,
1539 &has_function);
1540
1541 // Count CONSTANT or COMPUTED properties to maintain the enumeration order.
1542 if (this->IsBoilerplateProperty(property)) {
1543 number_of_boilerplate_properties++;
1544 }
1545 properties->Add(property, zone());
1546
1547 // TODO(1240767): Consider allowing trailing comma.
1548 if (peek() != Token::RBRACE) {
1549 // Need {} because of the CHECK_OK macro.
1550 Expect(Token::COMMA, CHECK_OK);
1551 }
1552
1553 if (fni_ != NULL) {
1554 fni_->Infer();
1555 fni_->Leave();
1556 }
1557 }
1558 Expect(Token::RBRACE, CHECK_OK);
1559
1560 // Computation of literal_index must happen before pre parse bailout.
1561 int literal_index = function_state_->NextMaterializedLiteralIndex();
1562
1563 return factory()->NewObjectLiteral(properties,
1564 literal_index,
1565 number_of_boilerplate_properties,
1566 has_function,
1567 pos);
1568 }
1569
1570
1571 template <class Traits>
1572 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments(
1573 bool* ok) {
1574 // Arguments ::
1575 // '(' (AssignmentExpression)*[','] ')'
1576
1577 typename Traits::Type::ExpressionList result =
1578 this->NewExpressionList(4, zone_);
1579 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1580 bool done = (peek() == Token::RPAREN);
1581 while (!done) {
1582 typename Traits::Type::Expression argument =
1583 this->ParseAssignmentExpression(true,
1584 CHECK_OK_CUSTOM(NullExpressionList));
1585 result->Add(argument, zone_);
1586 if (result->length() > Code::kMaxArguments) {
1587 ReportMessageAt(scanner()->location(), "too_many_arguments");
1588 *ok = false;
1589 return this->NullExpressionList();
1590 }
1591 done = (peek() == Token::RPAREN);
1592 if (!done) {
1593 // Need {} because of the CHECK_OK_CUSTOM macro.
1594 Expect(Token::COMMA, CHECK_OK_CUSTOM(NullExpressionList));
1595 }
1596 }
1597 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1598 return result;
1599 }
1600
1601 // Precedence = 2
1602 template <class Traits>
1603 typename Traits::Type::Expression ParserBase<Traits>::ParseAssignmentExpression(
1604 bool accept_IN, bool* ok) {
1605 // AssignmentExpression ::
1606 // ConditionalExpression
1607 // YieldExpression
1608 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1609
1610 if (peek() == Token::YIELD && is_generator()) {
1611 return this->ParseYieldExpression(ok);
1612 }
1613
1614 if (fni_ != NULL) fni_->Enter();
1615 typename Traits::Type::Expression expression =
1616 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1617
1618 if (!Token::IsAssignmentOp(peek())) {
1619 if (fni_ != NULL) fni_->Leave();
1620 // Parsed conditional expression only (no assignment).
1621 return expression;
1622 }
1623
1624 // Signal a reference error if the expression is an invalid left-hand
1625 // side expression. We could report this as a syntax error here but
1626 // for compatibility with JSC we choose to report the error at
1627 // runtime.
1628 // TODO(ES5): Should change parsing for spec conformance.
1629 expression = this->ValidateAssignmentLeftHandSide(expression);
1630
1631 if (strict_mode() == STRICT) {
1632 // Assignment to eval or arguments is disallowed in strict mode.
1633 this->CheckStrictModeLValue(expression, CHECK_OK);
1634 }
1635 expression = this->MarkExpressionAsLValue(expression);
1636
1637 Token::Value op = Next(); // Get assignment operator.
1638 int pos = position();
1639 typename Traits::Type::Expression right =
1640 this->ParseAssignmentExpression(accept_IN, CHECK_OK);
1641
1642 // TODO(1231235): We try to estimate the set of properties set by
1643 // constructors. We define a new property whenever there is an
1644 // assignment to a property of 'this'. We should probably only add
1645 // properties if we haven't seen them before. Otherwise we'll
1646 // probably overestimate the number of properties.
1647 if (op == Token::ASSIGN && this->IsThisProperty(expression)) {
1648 function_state_->AddProperty();
1649 }
1650
1651 this->CheckAssigningFunctionLiteralToProperty(expression, right);
1652
1653 if (fni_ != NULL) {
1654 // Check if the right hand side is a call to avoid inferring a
1655 // name if we're dealing with "a = function(){...}();"-like
1656 // expression.
1657 if ((op == Token::INIT_VAR
1658 || op == Token::INIT_CONST_LEGACY
1659 || op == Token::ASSIGN)
1660 && (right->AsCall() == NULL && right->AsCallNew() == NULL)) {
1661 fni_->Infer();
1662 } else {
1663 fni_->RemoveLastFunction();
1664 }
1665 fni_->Leave();
1666 }
1667
1668 return factory()->NewAssignment(op, expression, right, pos);
1669 }
1670
1671 template <class Traits>
1672 typename Traits::Type::Expression ParserBase<Traits>::ParseYieldExpression(
1673 bool* ok) {
1674 // YieldExpression ::
1675 // 'yield' '*'? AssignmentExpression
1676 int pos = peek_position();
1677 Expect(Token::YIELD, CHECK_OK);
1678 Yield::Kind kind =
1679 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND;
1680 typename Traits::Type::Expression generator_object =
1681 factory()->NewVariableProxy(function_state_->generator_object_variable());
1682 typename Traits::Type::Expression expression =
1683 ParseAssignmentExpression(false, CHECK_OK);
1684 typename Traits::Type::YieldExpression yield =
1685 factory()->NewYield(generator_object, expression, kind, pos);
1686 if (kind == Yield::DELEGATING) {
1687 yield->set_index(function_state_->NextHandlerIndex());
1688 }
1689 return yield;
1690 }
1691
1692
1242 #undef CHECK_OK 1693 #undef CHECK_OK
1694 #undef CHECK_OK_CUSTOM
1243 1695
1244 1696
1245 template <typename Traits> 1697 template <typename Traits>
1246 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty( 1698 void ParserBase<Traits>::ObjectLiteralChecker::CheckProperty(
1247 Token::Value property, 1699 Token::Value property,
1248 PropertyKind type, 1700 PropertyKind type,
1249 bool* ok) { 1701 bool* ok) {
1250 int old; 1702 int old;
1251 if (property == Token::NUMBER) { 1703 if (property == Token::NUMBER) {
1252 old = finder_.AddNumber(scanner()->literal_ascii_string(), type); 1704 old = scanner()->FindNumber(&finder_, type);
1253 } else if (scanner()->is_literal_ascii()) {
1254 old = finder_.AddAsciiSymbol(scanner()->literal_ascii_string(), type);
1255 } else { 1705 } else {
1256 old = finder_.AddUtf16Symbol(scanner()->literal_utf16_string(), type); 1706 old = scanner()->FindSymbol(&finder_, type);
1257 } 1707 }
1258 PropertyKind old_type = static_cast<PropertyKind>(old); 1708 PropertyKind old_type = static_cast<PropertyKind>(old);
1259 if (HasConflict(old_type, type)) { 1709 if (HasConflict(old_type, type)) {
1260 if (IsDataDataConflict(old_type, type)) { 1710 if (IsDataDataConflict(old_type, type)) {
1261 // Both are data properties. 1711 // Both are data properties.
1262 if (language_mode_ == CLASSIC_MODE) return; 1712 if (strict_mode_ == SLOPPY) return;
1263 parser()->ReportMessageAt(scanner()->location(), 1713 parser()->ReportMessageAt(scanner()->location(),
1264 "strict_duplicate_property"); 1714 "strict_duplicate_property");
1265 } else if (IsDataAccessorConflict(old_type, type)) { 1715 } else if (IsDataAccessorConflict(old_type, type)) {
1266 // Both a data and an accessor property with the same name. 1716 // Both a data and an accessor property with the same name.
1267 parser()->ReportMessageAt(scanner()->location(), 1717 parser()->ReportMessageAt(scanner()->location(),
1268 "accessor_data_property"); 1718 "accessor_data_property");
1269 } else { 1719 } else {
1270 ASSERT(IsAccessorAccessorConflict(old_type, type)); 1720 ASSERT(IsAccessorAccessorConflict(old_type, type));
1271 // Both accessors of the same type. 1721 // Both accessors of the same type.
1272 parser()->ReportMessageAt(scanner()->location(), 1722 parser()->ReportMessageAt(scanner()->location(),
1273 "accessor_get_set"); 1723 "accessor_get_set");
1274 } 1724 }
1275 *ok = false; 1725 *ok = false;
1276 } 1726 }
1277 } 1727 }
1278 1728
1279 1729
1280 } } // v8::internal 1730 } } // v8::internal
1281 1731
1282 #endif // V8_PREPARSER_H 1732 #endif // V8_PREPARSER_H
OLDNEW
« no previous file with comments | « src/preparse-data.cc ('k') | src/preparser.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698