OLD | NEW |
---|---|
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 // typedef ObjectLiteralProperty; | 71 // typedef ObjectLiteralProperty; |
72 // typedef Literal; | 72 // typedef Literal; |
73 // typedef ExpressionList; | 73 // typedef ExpressionList; |
74 // typedef PropertyList; | 74 // typedef PropertyList; |
75 // // For constructing objects returned by the traversing functions. | 75 // // For constructing objects returned by the traversing functions. |
76 // typedef Factory; | 76 // typedef Factory; |
77 // }; | 77 // }; |
78 // // ... | 78 // // ... |
79 // }; | 79 // }; |
80 | 80 |
81 | |
81 template <typename Traits> | 82 template <typename Traits> |
82 class ParserBase : public Traits { | 83 class ParserBase : public Traits { |
83 public: | 84 public: |
84 // Shorten type names defined by Traits. | 85 // Shorten type names defined by Traits. |
85 typedef typename Traits::Type::Expression ExpressionT; | 86 typedef typename Traits::Type::Expression ExpressionT; |
86 typedef typename Traits::Type::Identifier IdentifierT; | 87 typedef typename Traits::Type::Identifier IdentifierT; |
88 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT; | |
87 | 89 |
88 ParserBase(Scanner* scanner, uintptr_t stack_limit, | 90 ParserBase(Scanner* scanner, uintptr_t stack_limit, |
89 v8::Extension* extension, | 91 v8::Extension* extension, |
90 ParserRecorder* log, | 92 ParserRecorder* log, |
91 typename Traits::Type::Zone* zone, | 93 typename Traits::Type::Zone* zone, |
92 typename Traits::Type::Parser this_object) | 94 typename Traits::Type::Parser this_object) |
93 : Traits(this_object), | 95 : Traits(this_object), |
94 parenthesized_function_(false), | 96 parenthesized_function_(false), |
95 scope_(NULL), | 97 scope_(NULL), |
96 function_state_(NULL), | 98 function_state_(NULL), |
97 extension_(extension), | 99 extension_(extension), |
98 fni_(NULL), | 100 fni_(NULL), |
99 log_(log), | 101 log_(log), |
100 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. | 102 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. |
101 scanner_(scanner), | 103 scanner_(scanner), |
102 stack_limit_(stack_limit), | 104 stack_limit_(stack_limit), |
103 stack_overflow_(false), | 105 stack_overflow_(false), |
104 allow_lazy_(false), | 106 allow_lazy_(false), |
105 allow_natives_syntax_(false), | 107 allow_natives_syntax_(false), |
106 allow_generators_(false), | 108 allow_generators_(false), |
107 allow_for_of_(false), | 109 allow_for_of_(false), |
110 allow_arrow_functions_(false), | |
108 zone_(zone) { } | 111 zone_(zone) { } |
109 | 112 |
110 // Getters that indicate whether certain syntactical constructs are | 113 // Getters that indicate whether certain syntactical constructs are |
111 // allowed to be parsed by this instance of the parser. | 114 // allowed to be parsed by this instance of the parser. |
112 bool allow_lazy() const { return allow_lazy_; } | 115 bool allow_lazy() const { return allow_lazy_; } |
113 bool allow_natives_syntax() const { return allow_natives_syntax_; } | 116 bool allow_natives_syntax() const { return allow_natives_syntax_; } |
114 bool allow_generators() const { return allow_generators_; } | 117 bool allow_generators() const { return allow_generators_; } |
115 bool allow_for_of() const { return allow_for_of_; } | 118 bool allow_for_of() const { return allow_for_of_; } |
119 bool allow_arrow_functions() const { return allow_arrow_functions_; } | |
116 bool allow_modules() const { return scanner()->HarmonyModules(); } | 120 bool allow_modules() const { return scanner()->HarmonyModules(); } |
117 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } | 121 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } |
118 bool allow_harmony_numeric_literals() const { | 122 bool allow_harmony_numeric_literals() const { |
119 return scanner()->HarmonyNumericLiterals(); | 123 return scanner()->HarmonyNumericLiterals(); |
120 } | 124 } |
121 | 125 |
122 // Setters that determine whether certain syntactical constructs are | 126 // Setters that determine whether certain syntactical constructs are |
123 // allowed to be parsed by this instance of the parser. | 127 // allowed to be parsed by this instance of the parser. |
124 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 128 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
125 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } | 129 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } |
126 void set_allow_generators(bool allow) { allow_generators_ = allow; } | 130 void set_allow_generators(bool allow) { allow_generators_ = allow; } |
127 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } | 131 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } |
132 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; } | |
128 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } | 133 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } |
129 void set_allow_harmony_scoping(bool allow) { | 134 void set_allow_harmony_scoping(bool allow) { |
130 scanner()->SetHarmonyScoping(allow); | 135 scanner()->SetHarmonyScoping(allow); |
131 } | 136 } |
132 void set_allow_harmony_numeric_literals(bool allow) { | 137 void set_allow_harmony_numeric_literals(bool allow) { |
133 scanner()->SetHarmonyNumericLiterals(allow); | 138 scanner()->SetHarmonyNumericLiterals(allow); |
134 } | 139 } |
135 | 140 |
136 protected: | 141 protected: |
137 enum AllowEvalOrArgumentsAsIdentifier { | 142 enum AllowEvalOrArgumentsAsIdentifier { |
(...skipping 28 matching lines...) Expand all Loading... | |
166 typename Traits::Type::Scope* scope_; | 171 typename Traits::Type::Scope* scope_; |
167 }; | 172 }; |
168 | 173 |
169 class FunctionState BASE_EMBEDDED { | 174 class FunctionState BASE_EMBEDDED { |
170 public: | 175 public: |
171 FunctionState( | 176 FunctionState( |
172 FunctionState** function_state_stack, | 177 FunctionState** function_state_stack, |
173 typename Traits::Type::Scope** scope_stack, | 178 typename Traits::Type::Scope** scope_stack, |
174 typename Traits::Type::Scope* scope, | 179 typename Traits::Type::Scope* scope, |
175 typename Traits::Type::Zone* zone = NULL); | 180 typename Traits::Type::Zone* zone = NULL); |
181 FunctionState( | |
182 FunctionState** function_state_stack, | |
183 typename Traits::Type::Scope** scope_stack, | |
184 typename Traits::Type::Scope** scope, | |
185 typename Traits::Type::Zone* zone = NULL); | |
176 ~FunctionState(); | 186 ~FunctionState(); |
177 | 187 |
178 int NextMaterializedLiteralIndex() { | 188 int NextMaterializedLiteralIndex() { |
179 return next_materialized_literal_index_++; | 189 return next_materialized_literal_index_++; |
180 } | 190 } |
181 int materialized_literal_count() { | 191 int materialized_literal_count() { |
182 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; | 192 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; |
183 } | 193 } |
184 | 194 |
185 int NextHandlerIndex() { return next_handler_index_++; } | 195 int NextHandlerIndex() { return next_handler_index_++; } |
(...skipping 231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 ExpressionT ParseYieldExpression(bool* ok); | 427 ExpressionT ParseYieldExpression(bool* ok); |
418 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 428 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
419 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 429 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
420 ExpressionT ParseUnaryExpression(bool* ok); | 430 ExpressionT ParseUnaryExpression(bool* ok); |
421 ExpressionT ParsePostfixExpression(bool* ok); | 431 ExpressionT ParsePostfixExpression(bool* ok); |
422 ExpressionT ParseLeftHandSideExpression(bool* ok); | 432 ExpressionT ParseLeftHandSideExpression(bool* ok); |
423 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 433 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
424 ExpressionT ParseMemberExpression(bool* ok); | 434 ExpressionT ParseMemberExpression(bool* ok); |
425 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 435 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
426 bool* ok); | 436 bool* ok); |
437 ExpressionT ParseArrowFunctionLiteral(int start_pos, | |
438 ExpressionT params_ast, | |
439 bool* ok); | |
427 | 440 |
428 // Checks if the expression is a valid reference expression (e.g., on the | 441 // Checks if the expression is a valid reference expression (e.g., on the |
429 // left-hand side of assignments). Although ruled out by ECMA as early errors, | 442 // left-hand side of assignments). Although ruled out by ECMA as early errors, |
430 // we allow calls for web compatibility and rewrite them to a runtime throw. | 443 // we allow calls for web compatibility and rewrite them to a runtime throw. |
431 ExpressionT CheckAndRewriteReferenceExpression( | 444 ExpressionT CheckAndRewriteReferenceExpression( |
432 ExpressionT expression, | 445 ExpressionT expression, |
433 Scanner::Location location, const char* message, bool* ok); | 446 Scanner::Location location, const char* message, bool* ok); |
434 | 447 |
435 // Used to detect duplicates in object literals. Each of the values | 448 // Used to detect duplicates in object literals. Each of the values |
436 // kGetterProperty, kSetterProperty and kValueProperty represents | 449 // kGetterProperty, kSetterProperty and kValueProperty represents |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
501 | 514 |
502 private: | 515 private: |
503 Scanner* scanner_; | 516 Scanner* scanner_; |
504 uintptr_t stack_limit_; | 517 uintptr_t stack_limit_; |
505 bool stack_overflow_; | 518 bool stack_overflow_; |
506 | 519 |
507 bool allow_lazy_; | 520 bool allow_lazy_; |
508 bool allow_natives_syntax_; | 521 bool allow_natives_syntax_; |
509 bool allow_generators_; | 522 bool allow_generators_; |
510 bool allow_for_of_; | 523 bool allow_for_of_; |
524 bool allow_arrow_functions_; | |
511 | 525 |
512 typename Traits::Type::Zone* zone_; // Only used by Parser. | 526 typename Traits::Type::Zone* zone_; // Only used by Parser. |
513 }; | 527 }; |
514 | 528 |
515 | 529 |
516 class PreParserIdentifier { | 530 class PreParserIdentifier { |
517 public: | 531 public: |
518 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 532 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
519 static PreParserIdentifier Default() { | 533 static PreParserIdentifier Default(int pos) { |
520 return PreParserIdentifier(kUnknownIdentifier); | 534 return PreParserIdentifier(kUnknownIdentifier, pos); |
521 } | 535 } |
522 static PreParserIdentifier Eval() { | 536 static PreParserIdentifier Eval(int pos) { |
523 return PreParserIdentifier(kEvalIdentifier); | 537 return PreParserIdentifier(kEvalIdentifier, pos); |
524 } | 538 } |
525 static PreParserIdentifier Arguments() { | 539 static PreParserIdentifier Arguments(int pos) { |
526 return PreParserIdentifier(kArgumentsIdentifier); | 540 return PreParserIdentifier(kArgumentsIdentifier, pos); |
527 } | 541 } |
528 static PreParserIdentifier FutureReserved() { | 542 static PreParserIdentifier FutureReserved(int pos) { |
529 return PreParserIdentifier(kFutureReservedIdentifier); | 543 return PreParserIdentifier(kFutureReservedIdentifier, pos); |
530 } | 544 } |
531 static PreParserIdentifier FutureStrictReserved() { | 545 static PreParserIdentifier FutureStrictReserved(int pos) { |
532 return PreParserIdentifier(kFutureStrictReservedIdentifier); | 546 return PreParserIdentifier(kFutureStrictReservedIdentifier, pos); |
533 } | 547 } |
534 static PreParserIdentifier Yield() { | 548 static PreParserIdentifier Yield(int pos) { |
535 return PreParserIdentifier(kYieldIdentifier); | 549 return PreParserIdentifier(kYieldIdentifier, pos); |
536 } | 550 } |
537 bool IsEval() { return type_ == kEvalIdentifier; } | 551 bool IsEval() const { return type_ == kEvalIdentifier; } |
538 bool IsArguments() { return type_ == kArgumentsIdentifier; } | 552 bool IsArguments() const { return type_ == kArgumentsIdentifier; } |
539 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } | 553 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } |
540 bool IsYield() { return type_ == kYieldIdentifier; } | 554 bool IsYield() const { return type_ == kYieldIdentifier; } |
541 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } | 555 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } |
542 bool IsFutureStrictReserved() { | 556 bool IsFutureStrictReserved() { |
543 return type_ == kFutureStrictReservedIdentifier; | 557 return type_ == kFutureStrictReservedIdentifier; |
544 } | 558 } |
545 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } | 559 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } |
546 | 560 |
561 // Allow identifier->name()[->length()] to work | |
562 const PreParserIdentifier* operator->() const { return this; } | |
563 const PreParserIdentifier name() const { return *this; } | |
564 int position() const { return pos_; } | |
565 int length() const { | |
566 if (IsEval()) return 4; | |
567 if (IsArguments()) return 9; | |
568 if (IsYield()) return 5; | |
569 | |
570 // TODO(aperez): Is this correct? | |
571 return 0; | |
572 } | |
573 | |
547 private: | 574 private: |
548 enum Type { | 575 enum Type { |
549 kUnknownIdentifier, | 576 kUnknownIdentifier, |
550 kFutureReservedIdentifier, | 577 kFutureReservedIdentifier, |
551 kFutureStrictReservedIdentifier, | 578 kFutureStrictReservedIdentifier, |
552 kYieldIdentifier, | 579 kYieldIdentifier, |
553 kEvalIdentifier, | 580 kEvalIdentifier, |
554 kArgumentsIdentifier | 581 kArgumentsIdentifier |
555 }; | 582 }; |
556 explicit PreParserIdentifier(Type type) : type_(type) {} | 583 explicit PreParserIdentifier(Type type, int pos) : type_(type), pos_(pos) {} |
557 Type type_; | 584 Type type_; |
585 int pos_; | |
558 | 586 |
559 friend class PreParserExpression; | 587 friend class PreParserExpression; |
560 }; | 588 }; |
561 | 589 |
562 | 590 |
563 // Bits 0 and 1 are used to identify the type of expression: | 591 // Bits 0 and 1 are used to identify the type of expression: |
564 // If bit 0 is set, it's an identifier. | 592 // If bit 0 is set, it's an identifier. |
565 // if bit 1 is set, it's a string literal. | 593 // if bit 1 is set, it's a string literal. |
566 // If neither is set, it's no particular type, and both set isn't | 594 // If neither is set, it's no particular type, and both set isn't |
567 // use yet. | 595 // use yet. |
568 class PreParserExpression { | 596 class PreParserExpression { |
569 public: | 597 public: |
570 static PreParserExpression Default() { | 598 static PreParserExpression Default(int pos = RelocInfo::kNoPosition) { |
571 return PreParserExpression(kUnknownExpression); | 599 return PreParserExpression(kUnknownExpression, pos); |
572 } | 600 } |
573 | 601 |
574 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 602 static PreParserExpression FromIdentifier(PreParserIdentifier id, |
603 int pos = RelocInfo::kNoPosition) { | |
575 return PreParserExpression(kIdentifierFlag | | 604 return PreParserExpression(kIdentifierFlag | |
576 (id.type_ << kIdentifierShift)); | 605 (id.type_ << kIdentifierShift), pos); |
577 } | 606 } |
578 | 607 |
579 static PreParserExpression StringLiteral() { | 608 static PreParserExpression StringLiteral(int pos = RelocInfo::kNoPosition) { |
580 return PreParserExpression(kUnknownStringLiteral); | 609 return PreParserExpression(kUnknownStringLiteral, pos); |
581 } | 610 } |
582 | 611 |
583 static PreParserExpression UseStrictStringLiteral() { | 612 static PreParserExpression UseStrictStringLiteral( |
584 return PreParserExpression(kUseStrictString); | 613 int pos = RelocInfo::kNoPosition) { |
614 return PreParserExpression(kUseStrictString, pos); | |
585 } | 615 } |
586 | 616 |
587 static PreParserExpression This() { | 617 static PreParserExpression This(int pos = RelocInfo::kNoPosition) { |
588 return PreParserExpression(kThisExpression); | 618 return PreParserExpression(kThisExpression, pos); |
589 } | 619 } |
590 | 620 |
591 static PreParserExpression ThisProperty() { | 621 static PreParserExpression ThisProperty(int pos = RelocInfo::kNoPosition) { |
592 return PreParserExpression(kThisPropertyExpression); | 622 return PreParserExpression(kThisPropertyExpression, pos); |
593 } | 623 } |
594 | 624 |
595 static PreParserExpression Property() { | 625 static PreParserExpression Property(int pos = RelocInfo::kNoPosition) { |
596 return PreParserExpression(kPropertyExpression); | 626 return PreParserExpression(kPropertyExpression, pos); |
597 } | 627 } |
598 | 628 |
599 static PreParserExpression Call() { | 629 static PreParserExpression Call(int pos = RelocInfo::kNoPosition) { |
600 return PreParserExpression(kCallExpression); | 630 return PreParserExpression(kCallExpression, pos); |
601 } | 631 } |
602 | 632 |
603 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } | 633 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } |
604 | 634 |
605 PreParserIdentifier AsIdentifier() { | 635 PreParserIdentifier AsIdentifier() { |
606 ASSERT(IsIdentifier()); | 636 ASSERT(IsIdentifier()); |
607 return PreParserIdentifier( | 637 return PreParserIdentifier( |
608 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); | 638 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift), |
639 pos_); | |
609 } | 640 } |
610 | 641 |
611 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } | 642 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } |
612 | 643 |
613 bool IsUseStrictLiteral() { | 644 bool IsUseStrictLiteral() { |
614 return (code_ & kStringLiteralMask) == kUseStrictString; | 645 return (code_ & kStringLiteralMask) == kUseStrictString; |
615 } | 646 } |
616 | 647 |
617 bool IsThis() { return code_ == kThisExpression; } | 648 bool IsThis() { return code_ == kThisExpression; } |
618 | 649 |
619 bool IsThisProperty() { return code_ == kThisPropertyExpression; } | 650 bool IsThisProperty() { return code_ == kThisPropertyExpression; } |
620 | 651 |
621 bool IsProperty() { | 652 bool IsProperty() { |
622 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; | 653 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; |
623 } | 654 } |
624 | 655 |
625 bool IsCall() { return code_ == kCallExpression; } | 656 bool IsCall() { return code_ == kCallExpression; } |
626 | 657 |
627 bool IsValidReferenceExpression() { | 658 bool IsValidReferenceExpression() { |
628 return IsIdentifier() || IsProperty(); | 659 return IsIdentifier() || IsProperty(); |
629 } | 660 } |
630 | 661 |
631 // At the moment PreParser doesn't track these expression types. | 662 // At the moment PreParser doesn't track these expression types. |
632 bool IsFunctionLiteral() const { return false; } | 663 bool IsFunctionLiteral() const { return false; } |
633 bool IsCallNew() const { return false; } | 664 bool IsCallNew() const { return false; } |
634 | 665 |
635 PreParserExpression AsFunctionLiteral() { return *this; } | 666 PreParserExpression AsFunctionLiteral() { return *this; } |
636 | 667 |
668 int position() const { return pos_; } | |
669 | |
637 // Dummy implementation for making expression->somefunc() work in both Parser | 670 // Dummy implementation for making expression->somefunc() work in both Parser |
638 // and PreParser. | 671 // and PreParser. |
639 PreParserExpression* operator->() { return this; } | 672 PreParserExpression* operator->() { return this; } |
640 | 673 |
641 // More dummy implementations of things PreParser doesn't need to track: | 674 // More dummy implementations of things PreParser doesn't need to track: |
642 void set_index(int index) {} // For YieldExpressions | 675 void set_index(int index) {} // For YieldExpressions |
643 void set_parenthesized() {} | 676 void set_parenthesized() {} |
644 | 677 |
678 void set_function_token_position(int position) { pos_ = position; } | |
679 void set_ast_properties(int* ast_properties) {} | |
680 void set_slot_processor(int* slot_processor) {} | |
681 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {} | |
682 | |
683 bool operator==(const PreParserExpression& other) const { | |
684 return code_ == other.code_; | |
685 } | |
686 bool operator!=(const PreParserExpression& other) const { | |
687 return code_ != other.code_; | |
688 } | |
689 | |
645 private: | 690 private: |
646 // Least significant 2 bits are used as flags. Bits 0 and 1 represent | 691 // Least significant 2 bits are used as flags. Bits 0 and 1 represent |
647 // identifiers or strings literals, and are mutually exclusive, but can both | 692 // identifiers or strings literals, and are mutually exclusive, but can both |
648 // be absent. If the expression is an identifier or a string literal, the | 693 // be absent. If the expression is an identifier or a string literal, the |
649 // other bits describe the type (see PreParserIdentifier::Type and string | 694 // other bits describe the type (see PreParserIdentifier::Type and string |
650 // literal constants below). | 695 // literal constants below). |
651 enum { | 696 enum { |
652 kUnknownExpression = 0, | 697 kUnknownExpression = 0, |
653 // Identifiers | 698 // Identifiers |
654 kIdentifierFlag = 1, // Used to detect labels. | 699 kIdentifierFlag = 1, // Used to detect labels. |
655 kIdentifierShift = 3, | 700 kIdentifierShift = 3, |
656 | 701 |
657 kStringLiteralFlag = 2, // Used to detect directive prologue. | 702 kStringLiteralFlag = 2, // Used to detect directive prologue. |
658 kUnknownStringLiteral = kStringLiteralFlag, | 703 kUnknownStringLiteral = kStringLiteralFlag, |
659 kUseStrictString = kStringLiteralFlag | 8, | 704 kUseStrictString = kStringLiteralFlag | 8, |
660 kStringLiteralMask = kUseStrictString, | 705 kStringLiteralMask = kUseStrictString, |
661 | 706 |
662 // Below here applies if neither identifier nor string literal. Reserve the | 707 // Below here applies if neither identifier nor string literal. Reserve the |
663 // 2 least significant bits for flags. | 708 // 2 least significant bits for flags. |
664 kThisExpression = 1 << 2, | 709 kThisExpression = 1 << 2, |
665 kThisPropertyExpression = 2 << 2, | 710 kThisPropertyExpression = 2 << 2, |
666 kPropertyExpression = 3 << 2, | 711 kPropertyExpression = 3 << 2, |
667 kCallExpression = 4 << 2 | 712 kCallExpression = 4 << 2 |
668 }; | 713 }; |
669 | 714 |
670 explicit PreParserExpression(int expression_code) : code_(expression_code) {} | 715 explicit PreParserExpression(int expression_code, int pos) |
716 : code_(expression_code), pos_(pos) {} | |
671 | 717 |
672 int code_; | 718 int code_; |
719 int pos_; | |
673 }; | 720 }; |
674 | 721 |
675 | 722 |
676 // PreParserExpressionList doesn't actually store the expressions because | 723 // PreParserExpressionList doesn't actually store the expressions because |
677 // PreParser doesn't need to. | 724 // PreParser doesn't need to. |
678 class PreParserExpressionList { | 725 class PreParserExpressionList { |
679 public: | 726 public: |
680 // These functions make list->Add(some_expression) work (and do nothing). | 727 // These functions make list->Add(some_expression) work (and do nothing). |
681 PreParserExpressionList() : length_(0) {} | 728 PreParserExpressionList() : length_(0) {} |
682 PreParserExpressionList* operator->() { return this; } | 729 PreParserExpressionList* operator->() { return this; } |
683 void Add(PreParserExpression, void*) { ++length_; } | 730 void Add(PreParserExpression, void*) { ++length_; } |
684 int length() const { return length_; } | 731 int length() const { return length_; } |
685 private: | 732 private: |
686 int length_; | 733 int length_; |
687 }; | 734 }; |
688 | 735 |
736 class PreParserStatement { | |
marja
2014/04/24 08:08:06
I'd be more than willing to take this kind of chan
aperez
2014/04/24 12:38:37
Fortunately I have this locally as a separate comm
| |
737 public: | |
738 static PreParserStatement Default() { | |
739 return PreParserStatement(kUnknownStatement); | |
740 } | |
741 | |
742 static PreParserStatement FunctionDeclaration() { | |
743 return PreParserStatement(kFunctionDeclaration); | |
744 } | |
745 | |
746 // Creates expression statement from expression. | |
747 // Preserves being an unparenthesized string literal, possibly | |
748 // "use strict". | |
749 static PreParserStatement ExpressionStatement( | |
750 PreParserExpression expression) { | |
751 if (expression.IsUseStrictLiteral()) { | |
752 return PreParserStatement(kUseStrictExpressionStatement); | |
753 } | |
754 if (expression.IsStringLiteral()) { | |
755 return PreParserStatement(kStringLiteralExpressionStatement); | |
756 } | |
757 return Default(); | |
758 } | |
759 | |
760 bool IsStringLiteral() { | |
761 return code_ == kStringLiteralExpressionStatement; | |
762 } | |
763 | |
764 bool IsUseStrictLiteral() { | |
765 return code_ == kUseStrictExpressionStatement; | |
766 } | |
767 | |
768 bool IsFunctionDeclaration() { | |
769 return code_ == kFunctionDeclaration; | |
770 } | |
771 | |
772 private: | |
773 enum Type { | |
774 kUnknownStatement, | |
775 kStringLiteralExpressionStatement, | |
776 kUseStrictExpressionStatement, | |
777 kFunctionDeclaration | |
778 }; | |
779 | |
780 explicit PreParserStatement(Type code) : code_(code) {} | |
781 Type code_; | |
782 }; | |
783 | |
784 | |
785 // PreParserStatementList doesn't actually store the statements because | |
786 // PreParser doesn't need to. | |
787 class PreParserStatementList { | |
788 public: | |
789 // These functions make list->Add(some_expression) work (and do nothing). | |
790 PreParserStatementList() {} | |
791 PreParserStatementList* operator->() { return this; } | |
792 void Add(PreParserStatement, void*) {} | |
793 }; | |
794 | |
689 | 795 |
690 class PreParserScope { | 796 class PreParserScope { |
691 public: | 797 public: |
692 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) | 798 explicit PreParserScope(PreParserScope* outer_scope, |
799 ScopeType scope_type, | |
800 void* = NULL) | |
693 : scope_type_(scope_type) { | 801 : scope_type_(scope_type) { |
694 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; | 802 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; |
695 } | 803 } |
696 | 804 |
697 ScopeType type() { return scope_type_; } | 805 ScopeType type() { return scope_type_; } |
698 StrictMode strict_mode() const { return strict_mode_; } | 806 StrictMode strict_mode() const { return strict_mode_; } |
699 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } | 807 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } |
808 bool AllowsLazyCompilation() const { return true; } | |
809 | |
810 void set_start_position(int position) {} | |
811 void set_end_position(int position) {} | |
812 | |
813 bool IsDeclared(const PreParserIdentifier&) const { return false; } | |
814 void DeclareParameter(const PreParserIdentifier&, VariableMode) {} | |
815 | |
816 // Allow scope->Foo() to work. | |
817 PreParserScope* operator->() { return this; } | |
700 | 818 |
701 private: | 819 private: |
702 ScopeType scope_type_; | 820 ScopeType scope_type_; |
703 StrictMode strict_mode_; | 821 StrictMode strict_mode_; |
704 }; | 822 }; |
705 | 823 |
706 | 824 |
707 class PreParserFactory { | 825 class PreParserFactory { |
708 public: | 826 public: |
709 explicit PreParserFactory(void* extra_param) {} | 827 explicit PreParserFactory(void* extra_param) {} |
710 PreParserExpression NewLiteral(PreParserIdentifier identifier, | 828 PreParserExpression NewLiteral(PreParserIdentifier identifier, |
711 int pos) { | 829 int pos) { |
712 return PreParserExpression::Default(); | 830 return PreParserExpression::Default(pos); |
713 } | 831 } |
714 PreParserExpression NewNumberLiteral(double number, | 832 PreParserExpression NewNumberLiteral(double number, |
715 int pos) { | 833 int pos) { |
716 return PreParserExpression::Default(); | 834 return PreParserExpression::Default(pos); |
717 } | 835 } |
718 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, | 836 PreParserExpression NewRegExpLiteral(PreParserIdentifier js_pattern, |
719 PreParserIdentifier js_flags, | 837 PreParserIdentifier js_flags, |
720 int literal_index, | 838 int literal_index, |
721 int pos) { | 839 int pos) { |
722 return PreParserExpression::Default(); | 840 return PreParserExpression::Default(pos); |
723 } | 841 } |
724 PreParserExpression NewArrayLiteral(PreParserExpressionList values, | 842 PreParserExpression NewArrayLiteral(PreParserExpressionList values, |
725 int literal_index, | 843 int literal_index, |
726 int pos) { | 844 int pos) { |
727 return PreParserExpression::Default(); | 845 return PreParserExpression::Default(pos); |
728 } | 846 } |
729 PreParserExpression NewObjectLiteralProperty(bool is_getter, | 847 PreParserExpression NewObjectLiteralProperty(bool is_getter, |
730 PreParserExpression value, | 848 PreParserExpression value, |
731 int pos) { | 849 int pos) { |
732 return PreParserExpression::Default(); | 850 return PreParserExpression::Default(); |
733 } | 851 } |
734 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, | 852 PreParserExpression NewObjectLiteralProperty(PreParserExpression key, |
735 PreParserExpression value) { | 853 PreParserExpression value) { |
736 return PreParserExpression::Default(); | 854 return PreParserExpression::Default(); |
737 } | 855 } |
738 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, | 856 PreParserExpression NewObjectLiteral(PreParserExpressionList properties, |
739 int literal_index, | 857 int literal_index, |
740 int boilerplate_properties, | 858 int boilerplate_properties, |
741 bool has_function, | 859 bool has_function, |
742 int pos) { | 860 int pos) { |
743 return PreParserExpression::Default(); | 861 return PreParserExpression::Default(pos); |
744 } | 862 } |
745 PreParserExpression NewVariableProxy(void* generator_variable) { | 863 PreParserExpression NewVariableProxy(void* generator_variable, int pos) { |
746 return PreParserExpression::Default(); | 864 return PreParserExpression::Default(pos); |
747 } | 865 } |
748 PreParserExpression NewProperty(PreParserExpression obj, | 866 PreParserExpression NewProperty(PreParserExpression obj, |
749 PreParserExpression key, | 867 PreParserExpression key, |
750 int pos) { | 868 int pos) { |
751 if (obj.IsThis()) { | 869 if (obj.IsThis()) { |
752 return PreParserExpression::ThisProperty(); | 870 return PreParserExpression::ThisProperty(pos); |
753 } | 871 } |
754 return PreParserExpression::Property(); | 872 return PreParserExpression::Property(pos); |
755 } | 873 } |
756 PreParserExpression NewUnaryOperation(Token::Value op, | 874 PreParserExpression NewUnaryOperation(Token::Value op, |
757 PreParserExpression expression, | 875 PreParserExpression expression, |
758 int pos) { | 876 int pos) { |
759 return PreParserExpression::Default(); | 877 return PreParserExpression::Default(pos); |
760 } | 878 } |
761 PreParserExpression NewBinaryOperation(Token::Value op, | 879 PreParserExpression NewBinaryOperation(Token::Value op, |
762 PreParserExpression left, | 880 PreParserExpression left, |
763 PreParserExpression right, int pos) { | 881 PreParserExpression right, int pos) { |
764 return PreParserExpression::Default(); | 882 return PreParserExpression::Default(pos); |
765 } | 883 } |
766 PreParserExpression NewCompareOperation(Token::Value op, | 884 PreParserExpression NewCompareOperation(Token::Value op, |
767 PreParserExpression left, | 885 PreParserExpression left, |
768 PreParserExpression right, int pos) { | 886 PreParserExpression right, int pos) { |
769 return PreParserExpression::Default(); | 887 return PreParserExpression::Default(pos); |
770 } | 888 } |
771 PreParserExpression NewAssignment(Token::Value op, | 889 PreParserExpression NewAssignment(Token::Value op, |
772 PreParserExpression left, | 890 PreParserExpression left, |
773 PreParserExpression right, | 891 PreParserExpression right, |
774 int pos) { | 892 int pos) { |
775 return PreParserExpression::Default(); | 893 return PreParserExpression::Default(pos); |
776 } | 894 } |
777 PreParserExpression NewYield(PreParserExpression generator_object, | 895 PreParserExpression NewYield(PreParserExpression generator_object, |
778 PreParserExpression expression, | 896 PreParserExpression expression, |
779 Yield::Kind yield_kind, | 897 Yield::Kind yield_kind, |
780 int pos) { | 898 int pos) { |
781 return PreParserExpression::Default(); | 899 return PreParserExpression::Default(pos); |
782 } | 900 } |
783 PreParserExpression NewConditional(PreParserExpression condition, | 901 PreParserExpression NewConditional(PreParserExpression condition, |
784 PreParserExpression then_expression, | 902 PreParserExpression then_expression, |
785 PreParserExpression else_expression, | 903 PreParserExpression else_expression, |
786 int pos) { | 904 int pos) { |
787 return PreParserExpression::Default(); | 905 return PreParserExpression::Default(pos); |
788 } | 906 } |
789 PreParserExpression NewCountOperation(Token::Value op, | 907 PreParserExpression NewCountOperation(Token::Value op, |
790 bool is_prefix, | 908 bool is_prefix, |
791 PreParserExpression expression, | 909 PreParserExpression expression, |
792 int pos) { | 910 int pos) { |
793 return PreParserExpression::Default(); | 911 return PreParserExpression::Default(pos); |
794 } | 912 } |
795 PreParserExpression NewCall(PreParserExpression expression, | 913 PreParserExpression NewCall(PreParserExpression expression, |
796 PreParserExpressionList arguments, | 914 PreParserExpressionList arguments, |
797 int pos) { | 915 int pos) { |
798 return PreParserExpression::Call(); | 916 return PreParserExpression::Call(pos); |
799 } | 917 } |
800 PreParserExpression NewCallNew(PreParserExpression expression, | 918 PreParserExpression NewCallNew(PreParserExpression expression, |
801 PreParserExpressionList arguments, | 919 PreParserExpressionList arguments, |
802 int pos) { | 920 int pos) { |
803 return PreParserExpression::Default(); | 921 return PreParserExpression::Default(pos); |
804 } | 922 } |
923 PreParserStatement NewReturnStatement(PreParserExpression expression, | |
924 int pos) { | |
925 return PreParserStatement::Default(); | |
926 } | |
927 PreParserExpression | |
928 NewFunctionLiteral(PreParserIdentifier name, | |
929 PreParserScope& scope, | |
930 PreParserStatementList body, | |
931 int materialized_literal_count, | |
932 int expected_property_count, | |
933 int handler_count, | |
934 int parameter_count, | |
935 FunctionLiteral::ParameterFlag has_duplicate_parameters, | |
936 FunctionLiteral::FunctionType function_type, | |
937 FunctionLiteral::IsFunctionFlag is_function, | |
938 FunctionLiteral::IsParenthesizedFlag is_parenthesized, | |
939 FunctionLiteral::IsGeneratorFlag is_generator, | |
marja
2014/04/24 08:08:06
Instead of IsGeneratorFlag and IsArrowFlag you sho
aperez
2014/04/24 12:38:37
Okay.
| |
940 FunctionLiteral::IsArrowFlag is_arrow, | |
941 int position) { | |
942 return PreParserExpression::Default(position); | |
943 } | |
944 | |
945 // Return the object itself as AstVisitor and implement the needed | |
946 // dummy method right in this class. | |
947 PreParserFactory* visitor() { return this; } | |
948 BailoutReason dont_optimize_reason() { return kNoReason; } | |
949 int* ast_properties() { return NULL; } | |
950 int* slot_processor() { return NULL; } | |
805 }; | 951 }; |
806 | 952 |
807 | 953 |
808 class PreParser; | 954 class PreParser; |
809 | 955 |
810 class PreParserTraits { | 956 class PreParserTraits { |
811 public: | 957 public: |
812 struct Type { | 958 struct Type { |
813 // TODO(marja): To be removed. The Traits object should contain all the data | 959 // TODO(marja): To be removed. The Traits object should contain all the data |
814 // it needs. | 960 // it needs. |
815 typedef PreParser* Parser; | 961 typedef PreParser* Parser; |
816 | 962 |
817 // Used by FunctionState and BlockState. | 963 // Used by FunctionState and BlockState. |
818 typedef PreParserScope Scope; | 964 typedef PreParserScope Scope; |
965 typedef PreParserScope ScopePtr; | |
966 | |
819 // PreParser doesn't need to store generator variables. | 967 // PreParser doesn't need to store generator variables. |
820 typedef void GeneratorVariable; | 968 typedef void GeneratorVariable; |
821 // No interaction with Zones. | 969 // No interaction with Zones. |
822 typedef void Zone; | 970 typedef void Zone; |
823 | 971 |
972 typedef int AstProperties; | |
973 typedef int DeferredFeedbackSlotProcessor; | |
974 typedef Vector<const PreParserIdentifier> ParameterIdentifierVector; | |
975 | |
824 // Return types for traversing functions. | 976 // Return types for traversing functions. |
825 typedef PreParserIdentifier Identifier; | 977 typedef PreParserIdentifier Identifier; |
826 typedef PreParserExpression Expression; | 978 typedef PreParserExpression Expression; |
827 typedef PreParserExpression YieldExpression; | 979 typedef PreParserExpression YieldExpression; |
828 typedef PreParserExpression FunctionLiteral; | 980 typedef PreParserExpression FunctionLiteral; |
829 typedef PreParserExpression ObjectLiteralProperty; | 981 typedef PreParserExpression ObjectLiteralProperty; |
830 typedef PreParserExpression Literal; | 982 typedef PreParserExpression Literal; |
831 typedef PreParserExpressionList ExpressionList; | 983 typedef PreParserExpressionList ExpressionList; |
832 typedef PreParserExpressionList PropertyList; | 984 typedef PreParserExpressionList PropertyList; |
985 typedef PreParserStatementList StatementList; | |
833 | 986 |
834 // For constructing objects returned by the traversing functions. | 987 // For constructing objects returned by the traversing functions. |
835 typedef PreParserFactory Factory; | 988 typedef PreParserFactory Factory; |
836 }; | 989 }; |
837 | 990 |
838 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} | 991 explicit PreParserTraits(PreParser* pre_parser) : pre_parser_(pre_parser) {} |
839 | 992 |
840 // Custom operations executed when FunctionStates are created and | 993 // Custom operations executed when FunctionStates are created and |
841 // destructed. (The PreParser doesn't need to do anything.) | 994 // destructed. (The PreParser doesn't need to do anything.) |
842 template<typename FunctionState> | 995 template<typename FunctionState> |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
875 // operations interleaved with the recursive descent. | 1028 // operations interleaved with the recursive descent. |
876 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { | 1029 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { |
877 // PreParser should not use FuncNameInferrer. | 1030 // PreParser should not use FuncNameInferrer. |
878 UNREACHABLE(); | 1031 UNREACHABLE(); |
879 } | 1032 } |
880 static void PushPropertyName(FuncNameInferrer* fni, | 1033 static void PushPropertyName(FuncNameInferrer* fni, |
881 PreParserExpression expression) { | 1034 PreParserExpression expression) { |
882 // PreParser should not use FuncNameInferrer. | 1035 // PreParser should not use FuncNameInferrer. |
883 UNREACHABLE(); | 1036 UNREACHABLE(); |
884 } | 1037 } |
1038 static void InferFunctionName(FuncNameInferrer* fni, | |
1039 PreParserExpression expression) { | |
1040 // PreParser should not use FuncNameInferrer. | |
1041 UNREACHABLE(); | |
1042 } | |
885 | 1043 |
886 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( | 1044 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( |
887 PreParserScope* scope, PreParserExpression value, bool* has_function) {} | 1045 PreParserScope* scope, PreParserExpression value, bool* has_function) {} |
888 | 1046 |
889 static void CheckAssigningFunctionLiteralToProperty( | 1047 static void CheckAssigningFunctionLiteralToProperty( |
890 PreParserExpression left, PreParserExpression right) {} | 1048 PreParserExpression left, PreParserExpression right) {} |
891 | 1049 |
892 // PreParser doesn't need to keep track of eval calls. | 1050 // PreParser doesn't need to keep track of eval calls. |
893 static void CheckPossibleEvalCall(PreParserExpression expression, | 1051 static void CheckPossibleEvalCall(PreParserExpression expression, |
894 PreParserScope* scope) {} | 1052 PreParserScope* scope) {} |
(...skipping 23 matching lines...) Expand all Loading... | |
918 return PreParserExpression::Default(); | 1076 return PreParserExpression::Default(); |
919 } | 1077 } |
920 PreParserExpression NewThrowSyntaxError( | 1078 PreParserExpression NewThrowSyntaxError( |
921 const char* type, Handle<Object> arg, int pos) { | 1079 const char* type, Handle<Object> arg, int pos) { |
922 return PreParserExpression::Default(); | 1080 return PreParserExpression::Default(); |
923 } | 1081 } |
924 PreParserExpression NewThrowTypeError( | 1082 PreParserExpression NewThrowTypeError( |
925 const char* type, Handle<Object> arg, int pos) { | 1083 const char* type, Handle<Object> arg, int pos) { |
926 return PreParserExpression::Default(); | 1084 return PreParserExpression::Default(); |
927 } | 1085 } |
1086 PreParserScope NewScope(PreParserScope* outer_scope, | |
1087 ScopeType scope_type) { | |
1088 return PreParserScope(outer_scope, scope_type); | |
1089 } | |
928 | 1090 |
929 // Reporting errors. | 1091 // Reporting errors. |
930 void ReportMessageAt(Scanner::Location location, | 1092 void ReportMessageAt(Scanner::Location location, |
931 const char* message, | 1093 const char* message, |
932 Vector<const char*> args, | 1094 Vector<const char*> args, |
933 bool is_reference_error = false); | 1095 bool is_reference_error = false); |
934 void ReportMessageAt(Scanner::Location location, | 1096 void ReportMessageAt(Scanner::Location location, |
935 const char* type, | 1097 const char* type, |
936 const char* name_opt, | 1098 const char* name_opt, |
937 bool is_reference_error = false); | 1099 bool is_reference_error = false); |
938 void ReportMessageAt(int start_pos, | 1100 void ReportMessageAt(int start_pos, |
939 int end_pos, | 1101 int end_pos, |
940 const char* type, | 1102 const char* type, |
941 const char* name_opt, | 1103 const char* name_opt, |
942 bool is_reference_error = false); | 1104 bool is_reference_error = false); |
943 | 1105 |
944 // "null" return type creators. | 1106 // "null" return type creators. |
945 static PreParserIdentifier EmptyIdentifier() { | 1107 static PreParserIdentifier EmptyIdentifier() { |
946 return PreParserIdentifier::Default(); | 1108 return PreParserIdentifier::Default(RelocInfo::kNoPosition); |
1109 } | |
1110 static PreParserIdentifier EmptyIdentifierString() { | |
1111 return PreParserIdentifier::Default(RelocInfo::kNoPosition); | |
947 } | 1112 } |
948 static PreParserExpression EmptyExpression() { | 1113 static PreParserExpression EmptyExpression() { |
949 return PreParserExpression::Default(); | 1114 return PreParserExpression::Default(); |
950 } | 1115 } |
951 static PreParserExpression EmptyLiteral() { | 1116 static PreParserExpression EmptyLiteral() { |
952 return PreParserExpression::Default(); | 1117 return PreParserExpression::Default(); |
953 } | 1118 } |
954 static PreParserExpressionList NullExpressionList() { | 1119 static PreParserExpressionList NullExpressionList() { |
955 return PreParserExpressionList(); | 1120 return PreParserExpressionList(); |
956 } | 1121 } |
957 | 1122 |
958 // Odd-ball literal creators. | 1123 // Odd-ball literal creators. |
959 static PreParserExpression GetLiteralTheHole(int position, | 1124 static PreParserExpression GetLiteralTheHole(int position, |
960 PreParserFactory* factory) { | 1125 PreParserFactory* factory) { |
961 return PreParserExpression::Default(); | 1126 return PreParserExpression::Default(); |
962 } | 1127 } |
963 | 1128 |
964 // Producing data during the recursive descent. | 1129 // Producing data during the recursive descent. |
965 PreParserIdentifier GetSymbol(Scanner* scanner); | 1130 PreParserIdentifier GetSymbol(Scanner* scanner); |
966 static PreParserIdentifier NextLiteralString(Scanner* scanner, | 1131 static PreParserIdentifier NextLiteralString(Scanner* scanner, |
967 PretenureFlag tenured) { | 1132 PretenureFlag tenured) { |
968 return PreParserIdentifier::Default(); | 1133 // This is used by the regexp parsing, which does not use the |
1134 // positions of items from the preparser mini-AST. | |
1135 return PreParserIdentifier::Default(RelocInfo::kNoPosition); | |
969 } | 1136 } |
970 | 1137 |
971 static PreParserExpression ThisExpression(PreParserScope* scope, | 1138 static PreParserExpression ThisExpression(PreParserScope* scope, |
972 PreParserFactory* factory) { | 1139 PreParserFactory* factory, |
973 return PreParserExpression::This(); | 1140 int pos = RelocInfo::kNoPosition) { |
1141 return PreParserExpression::This(pos); | |
974 } | 1142 } |
975 | 1143 |
976 static PreParserExpression ExpressionFromLiteral( | 1144 static PreParserExpression ExpressionFromLiteral( |
977 Token::Value token, int pos, Scanner* scanner, | 1145 Token::Value token, int pos, Scanner* scanner, |
978 PreParserFactory* factory) { | 1146 PreParserFactory* factory) { |
979 return PreParserExpression::Default(); | 1147 return PreParserExpression::Default(); |
980 } | 1148 } |
981 | 1149 |
982 static PreParserExpression ExpressionFromIdentifier( | 1150 static PreParserExpression ExpressionFromIdentifier( |
983 PreParserIdentifier name, int pos, PreParserScope* scope, | 1151 PreParserIdentifier name, int pos, PreParserScope* scope, |
984 PreParserFactory* factory) { | 1152 PreParserFactory* factory) { |
985 return PreParserExpression::FromIdentifier(name); | 1153 return PreParserExpression::FromIdentifier(name); |
986 } | 1154 } |
987 | 1155 |
988 PreParserExpression ExpressionFromString(int pos, | 1156 PreParserExpression ExpressionFromString(int pos, |
989 Scanner* scanner, | 1157 Scanner* scanner, |
990 PreParserFactory* factory = NULL); | 1158 PreParserFactory* factory = NULL); |
991 | 1159 |
992 static PreParserExpressionList NewExpressionList(int size, void* zone) { | 1160 static PreParserExpressionList NewExpressionList(int size, void* zone) { |
993 return PreParserExpressionList(); | 1161 return PreParserExpressionList(); |
994 } | 1162 } |
995 | 1163 |
1164 static PreParserStatementList NewStatementList(int size, void* zone) { | |
1165 return PreParserStatementList(); | |
1166 } | |
1167 | |
996 static PreParserExpressionList NewPropertyList(int size, void* zone) { | 1168 static PreParserExpressionList NewPropertyList(int size, void* zone) { |
997 return PreParserExpressionList(); | 1169 return PreParserExpressionList(); |
998 } | 1170 } |
999 | 1171 |
1172 V8_INLINE void SkipLazyFunctionBody( | |
1173 PreParserIdentifier function_name, | |
1174 int* materialized_literal_count, | |
1175 int* expected_property_count, | |
1176 bool* ok); | |
1177 V8_INLINE PreParserStatementList ParseEagerFunctionBody( | |
1178 PreParserIdentifier function_name, | |
1179 int pos, | |
1180 Variable* fvar, | |
1181 Token::Value fvar_init_op, | |
1182 bool is_generator, | |
1183 bool* ok); | |
1184 | |
1185 // Utility functions | |
1186 Vector<const PreParserIdentifier> ParameterListFromExpression( | |
1187 PreParserExpression expression, bool* ok) { | |
1188 return Vector<const PreParserIdentifier>::empty(); | |
marja
2014/04/24 08:08:06
This makes PreParser accept a different language t
aperez
2014/04/24 12:38:37
That is actually a neat idea, I will give it a try
| |
1189 } | |
1190 | |
1191 void CheckConflictingVarDeclarations( | |
1192 PreParserScope scope, | |
1193 bool* ok) {} | |
1194 | |
1000 // Temporary glue; these functions will move to ParserBase. | 1195 // Temporary glue; these functions will move to ParserBase. |
1001 PreParserExpression ParseV8Intrinsic(bool* ok); | 1196 PreParserExpression ParseV8Intrinsic(bool* ok); |
1002 PreParserExpression ParseFunctionLiteral( | 1197 PreParserExpression ParseFunctionLiteral( |
1003 PreParserIdentifier name, | 1198 PreParserIdentifier name, |
1004 Scanner::Location function_name_location, | 1199 Scanner::Location function_name_location, |
1005 bool name_is_strict_reserved, | 1200 bool name_is_strict_reserved, |
1006 bool is_generator, | 1201 bool is_generator, |
1007 int function_token_position, | 1202 int function_token_position, |
1008 FunctionLiteral::FunctionType type, | 1203 FunctionLiteral::FunctionType type, |
1009 bool* ok); | 1204 bool* ok); |
(...skipping 12 matching lines...) Expand all Loading... | |
1022 // The grammar check is only performed in order to understand the program | 1217 // The grammar check is only performed in order to understand the program |
1023 // sufficiently to deduce some information about it, that can be used | 1218 // sufficiently to deduce some information about it, that can be used |
1024 // to speed up later parsing. Finding errors is not the goal of pre-parsing, | 1219 // to speed up later parsing. Finding errors is not the goal of pre-parsing, |
1025 // rather it is to speed up properly written and correct programs. | 1220 // rather it is to speed up properly written and correct programs. |
1026 // That means that contextual checks (like a label being declared where | 1221 // That means that contextual checks (like a label being declared where |
1027 // it is used) are generally omitted. | 1222 // it is used) are generally omitted. |
1028 class PreParser : public ParserBase<PreParserTraits> { | 1223 class PreParser : public ParserBase<PreParserTraits> { |
1029 public: | 1224 public: |
1030 typedef PreParserIdentifier Identifier; | 1225 typedef PreParserIdentifier Identifier; |
1031 typedef PreParserExpression Expression; | 1226 typedef PreParserExpression Expression; |
1227 typedef PreParserStatement Statement; | |
1032 | 1228 |
1033 enum PreParseResult { | 1229 enum PreParseResult { |
1034 kPreParseStackOverflow, | 1230 kPreParseStackOverflow, |
1035 kPreParseSuccess | 1231 kPreParseSuccess |
1036 }; | 1232 }; |
1037 | 1233 |
1038 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) | 1234 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) |
1039 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, | 1235 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, |
1040 this) {} | 1236 this) {} |
1041 | 1237 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1083 kStatement, | 1279 kStatement, |
1084 kForStatement | 1280 kForStatement |
1085 }; | 1281 }; |
1086 | 1282 |
1087 // If a list of variable declarations includes any initializers. | 1283 // If a list of variable declarations includes any initializers. |
1088 enum VariableDeclarationProperties { | 1284 enum VariableDeclarationProperties { |
1089 kHasInitializers, | 1285 kHasInitializers, |
1090 kHasNoInitializers | 1286 kHasNoInitializers |
1091 }; | 1287 }; |
1092 | 1288 |
1093 class Statement { | |
1094 public: | |
1095 static Statement Default() { | |
1096 return Statement(kUnknownStatement); | |
1097 } | |
1098 | |
1099 static Statement FunctionDeclaration() { | |
1100 return Statement(kFunctionDeclaration); | |
1101 } | |
1102 | |
1103 // Creates expression statement from expression. | |
1104 // Preserves being an unparenthesized string literal, possibly | |
1105 // "use strict". | |
1106 static Statement ExpressionStatement(Expression expression) { | |
1107 if (expression.IsUseStrictLiteral()) { | |
1108 return Statement(kUseStrictExpressionStatement); | |
1109 } | |
1110 if (expression.IsStringLiteral()) { | |
1111 return Statement(kStringLiteralExpressionStatement); | |
1112 } | |
1113 return Default(); | |
1114 } | |
1115 | |
1116 bool IsStringLiteral() { | |
1117 return code_ == kStringLiteralExpressionStatement; | |
1118 } | |
1119 | |
1120 bool IsUseStrictLiteral() { | |
1121 return code_ == kUseStrictExpressionStatement; | |
1122 } | |
1123 | |
1124 bool IsFunctionDeclaration() { | |
1125 return code_ == kFunctionDeclaration; | |
1126 } | |
1127 | |
1128 private: | |
1129 enum Type { | |
1130 kUnknownStatement, | |
1131 kStringLiteralExpressionStatement, | |
1132 kUseStrictExpressionStatement, | |
1133 kFunctionDeclaration | |
1134 }; | |
1135 | |
1136 explicit Statement(Type code) : code_(code) {} | |
1137 Type code_; | |
1138 }; | |
1139 | |
1140 enum SourceElements { | 1289 enum SourceElements { |
1141 kUnknownSourceElements | 1290 kUnknownSourceElements |
1142 }; | 1291 }; |
1143 | 1292 |
1144 // All ParseXXX functions take as the last argument an *ok parameter | 1293 // All ParseXXX functions take as the last argument an *ok parameter |
1145 // which is set to false if parsing failed; it is unchanged otherwise. | 1294 // which is set to false if parsing failed; it is unchanged otherwise. |
1146 // By making the 'exception handling' explicit, we are forced to check | 1295 // By making the 'exception handling' explicit, we are forced to check |
1147 // for failure at the call sites. | 1296 // for failure at the call sites. |
1148 Statement ParseSourceElement(bool* ok); | 1297 Statement ParseSourceElement(bool* ok); |
1149 SourceElements ParseSourceElements(int end_token, bool* ok); | 1298 SourceElements ParseSourceElements(int end_token, bool* ok); |
(...skipping 29 matching lines...) Expand all Loading... | |
1179 bool name_is_strict_reserved, | 1328 bool name_is_strict_reserved, |
1180 bool is_generator, | 1329 bool is_generator, |
1181 int function_token_pos, | 1330 int function_token_pos, |
1182 FunctionLiteral::FunctionType function_type, | 1331 FunctionLiteral::FunctionType function_type, |
1183 bool* ok); | 1332 bool* ok); |
1184 void ParseLazyFunctionLiteralBody(bool* ok); | 1333 void ParseLazyFunctionLiteralBody(bool* ok); |
1185 | 1334 |
1186 bool CheckInOrOf(bool accept_OF); | 1335 bool CheckInOrOf(bool accept_OF); |
1187 }; | 1336 }; |
1188 | 1337 |
1338 | |
1339 void PreParserTraits::SkipLazyFunctionBody( | |
1340 PreParserIdentifier function_name, | |
1341 int* materialized_literal_count, | |
1342 int* expected_property_count, | |
1343 bool* ok) { | |
1344 pre_parser_->SkipLazyFunctionBody(function_name, | |
1345 materialized_literal_count, expected_property_count, ok); | |
1346 } | |
1347 | |
1348 | |
1349 PreParserStatementList PreParserTraits::ParseEagerFunctionBody( | |
1350 PreParserIdentifier function_name, | |
1351 int pos, | |
1352 Variable* fvar, | |
1353 Token::Value fvar_init_op, | |
1354 bool is_generator, | |
1355 bool* ok) { | |
1356 return pre_parser_->ParseEagerFunctionBody(function_name, | |
1357 pos, fvar, fvar_init_op, is_generator, ok); | |
1358 } | |
1359 | |
1360 | |
1189 template<class Traits> | 1361 template<class Traits> |
1190 ParserBase<Traits>::FunctionState::FunctionState( | 1362 ParserBase<Traits>::FunctionState::FunctionState( |
1191 FunctionState** function_state_stack, | 1363 FunctionState** function_state_stack, |
1192 typename Traits::Type::Scope** scope_stack, | 1364 typename Traits::Type::Scope** scope_stack, |
1193 typename Traits::Type::Scope* scope, | 1365 typename Traits::Type::Scope* scope, |
1194 typename Traits::Type::Zone* extra_param) | 1366 typename Traits::Type::Zone* extra_param) |
1195 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | 1367 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), |
1196 next_handler_index_(0), | 1368 next_handler_index_(0), |
1197 expected_property_count_(0), | 1369 expected_property_count_(0), |
1198 is_generator_(false), | 1370 is_generator_(false), |
1199 generator_object_variable_(NULL), | 1371 generator_object_variable_(NULL), |
1200 function_state_stack_(function_state_stack), | 1372 function_state_stack_(function_state_stack), |
1201 outer_function_state_(*function_state_stack), | 1373 outer_function_state_(*function_state_stack), |
1202 scope_stack_(scope_stack), | 1374 scope_stack_(scope_stack), |
1203 outer_scope_(*scope_stack), | 1375 outer_scope_(*scope_stack), |
1204 saved_ast_node_id_(0), | 1376 saved_ast_node_id_(0), |
1205 extra_param_(extra_param), | 1377 extra_param_(extra_param), |
1206 factory_(extra_param) { | 1378 factory_(extra_param) { |
1207 *scope_stack_ = scope; | 1379 *scope_stack_ = scope; |
1208 *function_state_stack = this; | 1380 *function_state_stack = this; |
1209 Traits::SetUpFunctionState(this, extra_param); | 1381 Traits::SetUpFunctionState(this, extra_param); |
1210 } | 1382 } |
1211 | 1383 |
1212 | 1384 |
1213 template<class Traits> | 1385 template<class Traits> |
1386 ParserBase<Traits>::FunctionState::FunctionState( | |
1387 FunctionState** function_state_stack, | |
1388 typename Traits::Type::Scope** scope_stack, | |
1389 typename Traits::Type::Scope** scope, | |
1390 typename Traits::Type::Zone* extra_param) | |
1391 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), | |
1392 next_handler_index_(0), | |
1393 expected_property_count_(0), | |
1394 is_generator_(false), | |
1395 generator_object_variable_(NULL), | |
1396 function_state_stack_(function_state_stack), | |
1397 outer_function_state_(*function_state_stack), | |
1398 scope_stack_(scope_stack), | |
1399 outer_scope_(*scope_stack), | |
1400 saved_ast_node_id_(0), | |
1401 extra_param_(extra_param), | |
1402 factory_(extra_param) { | |
1403 *scope_stack_ = *scope; | |
1404 *function_state_stack = this; | |
1405 Traits::SetUpFunctionState(this, extra_param); | |
1406 } | |
1407 | |
1408 | |
1409 template<class Traits> | |
1214 ParserBase<Traits>::FunctionState::~FunctionState() { | 1410 ParserBase<Traits>::FunctionState::~FunctionState() { |
1215 *scope_stack_ = outer_scope_; | 1411 *scope_stack_ = outer_scope_; |
1216 *function_state_stack_ = outer_function_state_; | 1412 *function_state_stack_ = outer_function_state_; |
1217 Traits::TearDownFunctionState(this, extra_param_); | 1413 Traits::TearDownFunctionState(this, extra_param_); |
1218 } | 1414 } |
1219 | 1415 |
1220 | 1416 |
1221 template<class Traits> | 1417 template<class Traits> |
1222 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { | 1418 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { |
1223 Scanner::Location source_location = scanner()->location(); | 1419 Scanner::Location source_location = scanner()->location(); |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1371 // ObjectLiteral | 1567 // ObjectLiteral |
1372 // RegExpLiteral | 1568 // RegExpLiteral |
1373 // '(' Expression ')' | 1569 // '(' Expression ')' |
1374 | 1570 |
1375 int pos = peek_position(); | 1571 int pos = peek_position(); |
1376 ExpressionT result = this->EmptyExpression(); | 1572 ExpressionT result = this->EmptyExpression(); |
1377 Token::Value token = peek(); | 1573 Token::Value token = peek(); |
1378 switch (token) { | 1574 switch (token) { |
1379 case Token::THIS: { | 1575 case Token::THIS: { |
1380 Consume(Token::THIS); | 1576 Consume(Token::THIS); |
1381 result = this->ThisExpression(scope_, factory()); | 1577 result = this->ThisExpression(scope_, factory(), pos); |
1382 break; | 1578 break; |
1383 } | 1579 } |
1384 | 1580 |
1385 case Token::NULL_LITERAL: | 1581 case Token::NULL_LITERAL: |
1386 case Token::TRUE_LITERAL: | 1582 case Token::TRUE_LITERAL: |
1387 case Token::FALSE_LITERAL: | 1583 case Token::FALSE_LITERAL: |
1388 case Token::NUMBER: | 1584 case Token::NUMBER: |
1389 Next(); | 1585 Next(); |
1390 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); | 1586 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); |
1391 break; | 1587 break; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1449 } | 1645 } |
1450 | 1646 |
1451 // Precedence = 1 | 1647 // Precedence = 1 |
1452 template <class Traits> | 1648 template <class Traits> |
1453 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( | 1649 typename ParserBase<Traits>::ExpressionT ParserBase<Traits>::ParseExpression( |
1454 bool accept_IN, bool* ok) { | 1650 bool accept_IN, bool* ok) { |
1455 // Expression :: | 1651 // Expression :: |
1456 // AssignmentExpression | 1652 // AssignmentExpression |
1457 // Expression ',' AssignmentExpression | 1653 // Expression ',' AssignmentExpression |
1458 | 1654 |
1655 if (allow_arrow_functions() && peek() == Token::RPAREN && | |
1656 scanner()->current_token() == Token::LPAREN) { | |
1657 // Empty argument list for arrow functions: () => ... | |
1658 return this->EmptyExpression(); | |
1659 } | |
1660 | |
1459 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 1661 ExpressionT result = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
1460 while (peek() == Token::COMMA) { | 1662 while (peek() == Token::COMMA) { |
1461 Expect(Token::COMMA, CHECK_OK); | 1663 Expect(Token::COMMA, CHECK_OK); |
1462 int pos = position(); | 1664 int pos = position(); |
1463 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); | 1665 ExpressionT right = this->ParseAssignmentExpression(accept_IN, CHECK_OK); |
1464 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); | 1666 result = factory()->NewBinaryOperation(Token::COMMA, result, right, pos); |
1465 } | 1667 } |
1466 return result; | 1668 return result; |
1467 } | 1669 } |
1468 | 1670 |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1689 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 1891 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
1690 return result; | 1892 return result; |
1691 } | 1893 } |
1692 | 1894 |
1693 // Precedence = 2 | 1895 // Precedence = 2 |
1694 template <class Traits> | 1896 template <class Traits> |
1695 typename ParserBase<Traits>::ExpressionT | 1897 typename ParserBase<Traits>::ExpressionT |
1696 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 1898 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
1697 // AssignmentExpression :: | 1899 // AssignmentExpression :: |
1698 // ConditionalExpression | 1900 // ConditionalExpression |
1901 // ArrowFunction | |
1699 // YieldExpression | 1902 // YieldExpression |
1700 // LeftHandSideExpression AssignmentOperator AssignmentExpression | 1903 // LeftHandSideExpression AssignmentOperator AssignmentExpression |
1701 | 1904 |
1702 Scanner::Location lhs_location = scanner()->peek_location(); | 1905 Scanner::Location lhs_location = scanner()->peek_location(); |
1703 | 1906 |
1704 if (peek() == Token::YIELD && is_generator()) { | 1907 if (peek() == Token::YIELD && is_generator()) { |
1705 return this->ParseYieldExpression(ok); | 1908 return this->ParseYieldExpression(ok); |
1706 } | 1909 } |
1707 | 1910 |
1708 if (fni_ != NULL) fni_->Enter(); | 1911 if (fni_ != NULL) fni_->Enter(); |
1709 ExpressionT expression = | 1912 ExpressionT expression = |
1710 this->ParseConditionalExpression(accept_IN, CHECK_OK); | 1913 this->ParseConditionalExpression(accept_IN, CHECK_OK); |
1711 | 1914 |
1915 if (allow_arrow_functions() && peek() == Token::ARROW) | |
1916 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos, | |
1917 expression, | |
1918 CHECK_OK); | |
1919 | |
1712 if (!Token::IsAssignmentOp(peek())) { | 1920 if (!Token::IsAssignmentOp(peek())) { |
1713 if (fni_ != NULL) fni_->Leave(); | 1921 if (fni_ != NULL) fni_->Leave(); |
1714 // Parsed conditional expression only (no assignment). | 1922 // Parsed conditional expression only (no assignment). |
1715 return expression; | 1923 return expression; |
1716 } | 1924 } |
1717 | 1925 |
1718 expression = this->CheckAndRewriteReferenceExpression( | 1926 expression = this->CheckAndRewriteReferenceExpression( |
1719 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); | 1927 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); |
1720 expression = this->MarkExpressionAsLValue(expression); | 1928 expression = this->MarkExpressionAsLValue(expression); |
1721 | 1929 |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1755 template <class Traits> | 1963 template <class Traits> |
1756 typename ParserBase<Traits>::ExpressionT | 1964 typename ParserBase<Traits>::ExpressionT |
1757 ParserBase<Traits>::ParseYieldExpression(bool* ok) { | 1965 ParserBase<Traits>::ParseYieldExpression(bool* ok) { |
1758 // YieldExpression :: | 1966 // YieldExpression :: |
1759 // 'yield' '*'? AssignmentExpression | 1967 // 'yield' '*'? AssignmentExpression |
1760 int pos = peek_position(); | 1968 int pos = peek_position(); |
1761 Expect(Token::YIELD, CHECK_OK); | 1969 Expect(Token::YIELD, CHECK_OK); |
1762 Yield::Kind kind = | 1970 Yield::Kind kind = |
1763 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; | 1971 Check(Token::MUL) ? Yield::DELEGATING : Yield::SUSPEND; |
1764 ExpressionT generator_object = | 1972 ExpressionT generator_object = |
1765 factory()->NewVariableProxy(function_state_->generator_object_variable()); | 1973 factory()->NewVariableProxy(function_state_->generator_object_variable(), |
1974 pos); | |
1766 ExpressionT expression = | 1975 ExpressionT expression = |
1767 ParseAssignmentExpression(false, CHECK_OK); | 1976 ParseAssignmentExpression(false, CHECK_OK); |
1768 typename Traits::Type::YieldExpression yield = | 1977 typename Traits::Type::YieldExpression yield = |
1769 factory()->NewYield(generator_object, expression, kind, pos); | 1978 factory()->NewYield(generator_object, expression, kind, pos); |
1770 if (kind == Yield::DELEGATING) { | 1979 if (kind == Yield::DELEGATING) { |
1771 yield->set_index(function_state_->NextHandlerIndex()); | 1980 yield->set_index(function_state_->NextHandlerIndex()); |
1772 } | 1981 } |
1773 return yield; | 1982 return yield; |
1774 } | 1983 } |
1775 | 1984 |
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2106 } | 2315 } |
2107 default: | 2316 default: |
2108 return expression; | 2317 return expression; |
2109 } | 2318 } |
2110 } | 2319 } |
2111 ASSERT(false); | 2320 ASSERT(false); |
2112 return this->EmptyExpression(); | 2321 return this->EmptyExpression(); |
2113 } | 2322 } |
2114 | 2323 |
2115 | 2324 |
2325 template <class Traits> | |
2326 typename ParserBase<Traits>::ExpressionT | |
2327 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos, | |
2328 ExpressionT params_ast, | |
2329 bool* ok) { | |
2330 // TODO(aperez): Change this to use ARROW_SCOPE | |
2331 typename Traits::Type::ScopePtr scope = | |
2332 this->NewScope(scope_, FUNCTION_SCOPE); | |
2333 | |
2334 typename Traits::Type::StatementList body; | |
2335 typename Traits::Type::AstProperties ast_properties; | |
2336 typename Traits::Type::DeferredFeedbackSlotProcessor* slot_processor; | |
2337 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_ | |
2338 ? FunctionLiteral::kIsParenthesized | |
2339 : FunctionLiteral::kNotParenthesized; | |
2340 FunctionLiteral::ParameterFlag duplicate_parameters; | |
2341 BailoutReason dont_optimize_reason = kNoReason; | |
2342 int materialized_literal_count = -1; | |
2343 int expected_property_count = -1; | |
2344 int handler_count = 0; | |
2345 int num_parameters = 0; | |
2346 | |
2347 { FunctionState function_state(&function_state_, &scope_, &scope, zone()); | |
2348 scope->set_start_position(start_pos); | |
2349 | |
2350 Scanner::Location eval_args_error_loc = Scanner::Location::invalid(); | |
2351 Scanner::Location dupe_error_loc = Scanner::Location::invalid(); | |
2352 Scanner::Location reserved_loc = Scanner::Location::invalid(); | |
2353 | |
2354 if (peek() == Token::ARROW) { | |
2355 // Function parameters are already parsed into an AST | |
2356 typename Traits::Type::ParameterIdentifierVector params = | |
2357 Traits::ParameterListFromExpression(params_ast, CHECK_OK); | |
2358 | |
2359 if ((num_parameters = params.length()) > Code::kMaxArguments) { | |
2360 ReportMessageAt(Scanner::Location(params_ast->position(), position()), | |
2361 "too_many_parameters"); | |
2362 *ok = false; | |
2363 return this->EmptyExpression(); | |
2364 } | |
2365 | |
2366 // The vector has the items in reverse order. | |
2367 for (int i = params.length() - 1; i >= 0; --i) { | |
2368 const IdentifierT param_name = params.at(i)->name(); | |
2369 int param_pos = params.at(i)->position(); | |
2370 | |
2371 // Store locations for possible future error reports. | |
2372 if (!eval_args_error_loc.IsValid() && | |
2373 this->IsEvalOrArguments(param_name)) { | |
2374 eval_args_error_loc = | |
2375 Scanner::Location(param_pos, param_pos + param_name->length()); | |
2376 } | |
2377 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
2378 dupe_error_loc = | |
2379 Scanner::Location(param_pos, param_pos + param_name->length()); | |
2380 } | |
2381 | |
2382 scope_->DeclareParameter(param_name, VAR); | |
2383 } | |
2384 } else { | |
2385 if (peek() == Token::LPAREN) { | |
marja
2014/04/24 08:08:06
Hmm, so this function can be called in two ways, f
aperez
2014/04/24 12:38:37
Correct. In that case we know exactly where the pa
| |
2386 // Parse a parenthesized parameter list. | |
2387 Consume(Token::LPAREN); | |
2388 bool done = (peek() == Token::RPAREN); | |
2389 while (!done) { | |
2390 bool is_strict_reserved = false; | |
2391 IdentifierT param_name = | |
2392 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, | |
2393 CHECK_OK); | |
2394 | |
2395 // Store locations for possible future error reports. | |
2396 if (!eval_args_error_loc.IsValid() && | |
2397 this->IsEvalOrArguments(param_name)) { | |
2398 eval_args_error_loc = scanner()->location(); | |
2399 } | |
2400 if (!reserved_loc.IsValid() && is_strict_reserved) { | |
2401 reserved_loc = scanner()->location(); | |
2402 } | |
2403 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) { | |
2404 dupe_error_loc = scanner()->location(); | |
2405 } | |
2406 | |
2407 scope_->DeclareParameter(param_name, VAR); | |
2408 num_parameters++; | |
2409 if (num_parameters > Code::kMaxArguments) { | |
2410 this->ReportMessageAt(scanner()->location(), "too_many_parameters"); | |
2411 *ok = false; | |
2412 return this->EmptyExpression(); | |
2413 } | |
2414 done = (peek() == Token::RPAREN); | |
2415 if (!done) Expect(Token::COMMA, CHECK_OK); | |
2416 } | |
2417 Expect(Token::RPAREN, CHECK_OK); | |
2418 } else { | |
2419 // Parse a single parameter identifier. | |
2420 bool is_strict_reserved = false; | |
2421 IdentifierT param_name = | |
2422 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK); | |
2423 | |
2424 // Store locations for possible future error reports. | |
2425 if (this->IsEvalOrArguments(param_name)) | |
2426 eval_args_error_loc = scanner()->location(); | |
2427 if (is_strict_reserved) | |
2428 reserved_loc = scanner()->location(); | |
2429 | |
2430 scope_->DeclareParameter(param_name, VAR); | |
2431 } | |
2432 } | |
2433 | |
2434 Expect(Token::ARROW, CHECK_OK); | |
2435 | |
2436 if (peek() == Token::LBRACE) { | |
2437 // Multiple statemente body | |
2438 Consume(Token::LBRACE); | |
2439 | |
2440 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | |
2441 scope_->AllowsLazyCompilation() && | |
2442 !parenthesized_function_); | |
2443 parenthesized_function_ = false; // This Was set for this funciton only. | |
2444 | |
2445 if (is_lazily_parsed) { | |
2446 this->SkipLazyFunctionBody(this->EmptyIdentifier(), | |
2447 &materialized_literal_count, | |
2448 &expected_property_count, | |
2449 CHECK_OK); | |
2450 } else { | |
2451 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(), | |
2452 RelocInfo::kNoPosition, | |
2453 NULL, | |
2454 Token::INIT_VAR, | |
2455 false, // Not a generator. | |
2456 CHECK_OK); | |
2457 materialized_literal_count = | |
2458 function_state.materialized_literal_count(); | |
2459 expected_property_count = function_state.expected_property_count(); | |
2460 handler_count = function_state.handler_count(); | |
2461 } | |
2462 } else { | |
2463 // Single-expression body | |
2464 int pos = position(); | |
2465 parenthesized_function_ = false; | |
2466 ExpressionT expression = ParseAssignmentExpression(true, CHECK_OK); | |
2467 body = this->NewStatementList(1, zone()); | |
2468 body->Add(factory()->NewReturnStatement(expression, pos), zone()); | |
2469 scope->set_end_position(scanner()->location().end_pos); | |
2470 materialized_literal_count = function_state.materialized_literal_count(); | |
2471 expected_property_count = function_state.expected_property_count(); | |
2472 handler_count = function_state.handler_count(); | |
2473 } | |
2474 | |
2475 // Validate strict mode. | |
2476 if (strict_mode() == STRICT) { | |
2477 if (eval_args_error_loc.IsValid()) { | |
2478 this->ReportMessageAt(eval_args_error_loc, "strict_eval_arguments"); | |
2479 *ok = false; | |
2480 return this->EmptyExpression(); | |
2481 } | |
2482 if (dupe_error_loc.IsValid()) { | |
2483 this->ReportMessageAt(dupe_error_loc, "strict_param_dupe"); | |
2484 *ok = false; | |
2485 return this->EmptyExpression(); | |
2486 } | |
2487 if (reserved_loc.IsValid()) { | |
2488 this->ReportMessageAt(reserved_loc, "unexpected_strict_reserved"); | |
2489 *ok = false; | |
2490 return this->EmptyExpression(); | |
2491 } | |
2492 CheckOctalLiteral(start_pos, | |
2493 scanner()->location().end_pos, | |
2494 CHECK_OK); | |
2495 } | |
2496 | |
2497 duplicate_parameters = dupe_error_loc.IsValid() | |
2498 ? FunctionLiteral::kHasDuplicateParameters | |
2499 : FunctionLiteral::kNoDuplicateParameters; | |
2500 ast_properties = *factory()->visitor()->ast_properties(); | |
2501 slot_processor = factory()->visitor()->slot_processor(); | |
2502 dont_optimize_reason = factory()->visitor()->dont_optimize_reason(); | |
2503 } | |
2504 | |
2505 if (allow_harmony_scoping() && strict_mode() == STRICT) | |
2506 this->CheckConflictingVarDeclarations(scope, CHECK_OK); | |
2507 | |
2508 FunctionLiteralT function_literal = | |
2509 factory()->NewFunctionLiteral(this->EmptyIdentifierString(), | |
2510 scope, | |
2511 body, | |
2512 materialized_literal_count, | |
2513 expected_property_count, | |
2514 handler_count, | |
2515 num_parameters, | |
2516 duplicate_parameters, | |
2517 FunctionLiteral::ANONYMOUS_EXPRESSION, | |
2518 FunctionLiteral::kIsFunction, | |
2519 parenthesized, | |
2520 FunctionLiteral::kNotGenerator, | |
2521 FunctionLiteral::kIsArrow, | |
2522 start_pos); | |
2523 function_literal->set_function_token_position(start_pos); | |
2524 function_literal->set_ast_properties(&ast_properties); | |
2525 function_literal->set_slot_processor(slot_processor); | |
2526 function_literal->set_dont_optimize_reason(dont_optimize_reason); | |
2527 | |
2528 if (fni_ != NULL) this->InferFunctionName(fni_, function_literal); | |
2529 | |
2530 return function_literal; | |
2531 } | |
2532 | |
2533 | |
2116 template <typename Traits> | 2534 template <typename Traits> |
2117 typename ParserBase<Traits>::ExpressionT | 2535 typename ParserBase<Traits>::ExpressionT |
2118 ParserBase<Traits>::CheckAndRewriteReferenceExpression( | 2536 ParserBase<Traits>::CheckAndRewriteReferenceExpression( |
2119 ExpressionT expression, | 2537 ExpressionT expression, |
2120 Scanner::Location location, const char* message, bool* ok) { | 2538 Scanner::Location location, const char* message, bool* ok) { |
2121 if (strict_mode() == STRICT && this->IsIdentifier(expression) && | 2539 if (strict_mode() == STRICT && this->IsIdentifier(expression) && |
2122 this->IsEvalOrArguments(this->AsIdentifier(expression))) { | 2540 this->IsEvalOrArguments(this->AsIdentifier(expression))) { |
2123 this->ReportMessageAt(location, "strict_eval_arguments", false); | 2541 this->ReportMessageAt(location, "strict_eval_arguments", false); |
2124 *ok = false; | 2542 *ok = false; |
2125 return this->EmptyExpression(); | 2543 return this->EmptyExpression(); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2172 "accessor_get_set"); | 2590 "accessor_get_set"); |
2173 } | 2591 } |
2174 *ok = false; | 2592 *ok = false; |
2175 } | 2593 } |
2176 } | 2594 } |
2177 | 2595 |
2178 | 2596 |
2179 } } // v8::internal | 2597 } } // v8::internal |
2180 | 2598 |
2181 #endif // V8_PREPARSER_H | 2599 #endif // V8_PREPARSER_H |
OLD | NEW |