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

Side by Side Diff: src/preparser.h

Issue 160073006: Implement handling of arrow functions in the parser (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Version with parsing code only, tests into test-parsing.cc Created 6 years, 6 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef V8_PREPARSER_H 5 #ifndef V8_PREPARSER_H
6 #define V8_PREPARSER_H 6 #define V8_PREPARSER_H
7 7
8 #include "src/func-name-inferrer.h" 8 #include "src/func-name-inferrer.h"
9 #include "src/hashmap.h" 9 #include "src/hashmap.h"
10 #include "src/scopes.h" 10 #include "src/scopes.h"
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
54 // }; 54 // };
55 // // ... 55 // // ...
56 // }; 56 // };
57 57
58 template <typename Traits> 58 template <typename Traits>
59 class ParserBase : public Traits { 59 class ParserBase : public Traits {
60 public: 60 public:
61 // Shorten type names defined by Traits. 61 // Shorten type names defined by Traits.
62 typedef typename Traits::Type::Expression ExpressionT; 62 typedef typename Traits::Type::Expression ExpressionT;
63 typedef typename Traits::Type::Identifier IdentifierT; 63 typedef typename Traits::Type::Identifier IdentifierT;
64 typedef typename Traits::Type::FunctionLiteral FunctionLiteralT;
64 65
65 ParserBase(Scanner* scanner, uintptr_t stack_limit, 66 ParserBase(Scanner* scanner, uintptr_t stack_limit,
66 v8::Extension* extension, 67 v8::Extension* extension,
67 ParserRecorder* log, 68 ParserRecorder* log,
68 typename Traits::Type::Zone* zone, 69 typename Traits::Type::Zone* zone,
69 typename Traits::Type::Parser this_object) 70 typename Traits::Type::Parser this_object)
70 : Traits(this_object), 71 : Traits(this_object),
71 parenthesized_function_(false), 72 parenthesized_function_(false),
72 scope_(NULL), 73 scope_(NULL),
73 function_state_(NULL), 74 function_state_(NULL),
74 extension_(extension), 75 extension_(extension),
75 fni_(NULL), 76 fni_(NULL),
76 log_(log), 77 log_(log),
77 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly. 78 mode_(PARSE_EAGERLY), // Lazy mode must be set explicitly.
78 scanner_(scanner), 79 scanner_(scanner),
79 stack_limit_(stack_limit), 80 stack_limit_(stack_limit),
80 stack_overflow_(false), 81 stack_overflow_(false),
81 allow_lazy_(false), 82 allow_lazy_(false),
82 allow_natives_syntax_(false), 83 allow_natives_syntax_(false),
83 allow_generators_(false), 84 allow_generators_(false),
84 allow_for_of_(false), 85 allow_for_of_(false),
86 allow_arrow_functions_(false),
85 zone_(zone) { } 87 zone_(zone) { }
86 88
87 // Getters that indicate whether certain syntactical constructs are 89 // Getters that indicate whether certain syntactical constructs are
88 // allowed to be parsed by this instance of the parser. 90 // allowed to be parsed by this instance of the parser.
89 bool allow_lazy() const { return allow_lazy_; } 91 bool allow_lazy() const { return allow_lazy_; }
90 bool allow_natives_syntax() const { return allow_natives_syntax_; } 92 bool allow_natives_syntax() const { return allow_natives_syntax_; }
91 bool allow_generators() const { return allow_generators_; } 93 bool allow_generators() const { return allow_generators_; }
92 bool allow_for_of() const { return allow_for_of_; } 94 bool allow_for_of() const { return allow_for_of_; }
95 bool allow_arrow_functions() const { return allow_arrow_functions_; }
93 bool allow_modules() const { return scanner()->HarmonyModules(); } 96 bool allow_modules() const { return scanner()->HarmonyModules(); }
94 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); } 97 bool allow_harmony_scoping() const { return scanner()->HarmonyScoping(); }
95 bool allow_harmony_numeric_literals() const { 98 bool allow_harmony_numeric_literals() const {
96 return scanner()->HarmonyNumericLiterals(); 99 return scanner()->HarmonyNumericLiterals();
97 } 100 }
98 101
99 // Setters that determine whether certain syntactical constructs are 102 // Setters that determine whether certain syntactical constructs are
100 // allowed to be parsed by this instance of the parser. 103 // allowed to be parsed by this instance of the parser.
101 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 104 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
102 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 105 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
103 void set_allow_generators(bool allow) { allow_generators_ = allow; } 106 void set_allow_generators(bool allow) { allow_generators_ = allow; }
104 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 107 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
108 void set_allow_arrow_functions(bool allow) { allow_arrow_functions_ = allow; }
105 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); } 109 void set_allow_modules(bool allow) { scanner()->SetHarmonyModules(allow); }
106 void set_allow_harmony_scoping(bool allow) { 110 void set_allow_harmony_scoping(bool allow) {
107 scanner()->SetHarmonyScoping(allow); 111 scanner()->SetHarmonyScoping(allow);
108 } 112 }
109 void set_allow_harmony_numeric_literals(bool allow) { 113 void set_allow_harmony_numeric_literals(bool allow) {
110 scanner()->SetHarmonyNumericLiterals(allow); 114 scanner()->SetHarmonyNumericLiterals(allow);
111 } 115 }
112 116
113 protected: 117 protected:
114 enum AllowEvalOrArgumentsAsIdentifier { 118 enum AllowEvalOrArgumentsAsIdentifier {
(...skipping 29 matching lines...) Expand all
144 }; 148 };
145 149
146 class FunctionState BASE_EMBEDDED { 150 class FunctionState BASE_EMBEDDED {
147 public: 151 public:
148 FunctionState( 152 FunctionState(
149 FunctionState** function_state_stack, 153 FunctionState** function_state_stack,
150 typename Traits::Type::Scope** scope_stack, 154 typename Traits::Type::Scope** scope_stack,
151 typename Traits::Type::Scope* scope, 155 typename Traits::Type::Scope* scope,
152 typename Traits::Type::Zone* zone = NULL, 156 typename Traits::Type::Zone* zone = NULL,
153 AstValueFactory* ast_value_factory = NULL); 157 AstValueFactory* ast_value_factory = NULL);
158 FunctionState(
159 FunctionState** function_state_stack,
160 typename Traits::Type::Scope** scope_stack,
161 typename Traits::Type::Scope** scope,
162 typename Traits::Type::Zone* zone,
163 AstValueFactory* ast_value_factory);
154 ~FunctionState(); 164 ~FunctionState();
155 165
156 int NextMaterializedLiteralIndex() { 166 int NextMaterializedLiteralIndex() {
157 return next_materialized_literal_index_++; 167 return next_materialized_literal_index_++;
158 } 168 }
159 int materialized_literal_count() { 169 int materialized_literal_count() {
160 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 170 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
161 } 171 }
162 172
163 int NextHandlerIndex() { return next_handler_index_++; } 173 int NextHandlerIndex() { return next_handler_index_++; }
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) { 337 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok) {
328 Scanner::Location octal = scanner()->octal_position(); 338 Scanner::Location octal = scanner()->octal_position();
329 if (octal.IsValid() && beg_pos <= octal.beg_pos && 339 if (octal.IsValid() && beg_pos <= octal.beg_pos &&
330 octal.end_pos <= end_pos) { 340 octal.end_pos <= end_pos) {
331 ReportMessageAt(octal, "strict_octal_literal"); 341 ReportMessageAt(octal, "strict_octal_literal");
332 scanner()->clear_octal_position(); 342 scanner()->clear_octal_position();
333 *ok = false; 343 *ok = false;
334 } 344 }
335 } 345 }
336 346
347 // Validates strict mode for function parameter lists. This has to be
348 // done after parsing the function, since the function can declare
349 // itself strict.
350 void CheckStrictFunctionNameAndParameters(
351 IdentifierT function_name,
352 bool function_name_is_strict_reserved,
353 const Scanner::Location& function_name_loc,
354 const Scanner::Location& eval_args_error_loc,
355 const Scanner::Location& dupe_error_loc,
356 const Scanner::Location& reserved_loc,
357 bool* ok) {
358 if (this->IsEvalOrArguments(function_name)) {
359 Traits::ReportMessageAt(function_name_loc, "strict_eval_arguments");
360 *ok = false;
361 return;
362 }
363 if (function_name_is_strict_reserved) {
364 Traits::ReportMessageAt(function_name_loc, "unexpected_strict_reserved");
365 *ok = false;
366 return;
367 }
368 if (eval_args_error_loc.IsValid()) {
369 Traits::ReportMessageAt(eval_args_error_loc, "strict_eval_arguments");
370 *ok = false;
371 return;
372 }
373 if (dupe_error_loc.IsValid()) {
374 Traits::ReportMessageAt(dupe_error_loc, "strict_param_dupe");
375 *ok = false;
376 return;
377 }
378 if (reserved_loc.IsValid()) {
379 Traits::ReportMessageAt(reserved_loc, "unexpected_strict_reserved");
380 *ok = false;
381 return;
382 }
383 }
384
337 // Determine precedence of given token. 385 // Determine precedence of given token.
338 static int Precedence(Token::Value token, bool accept_IN) { 386 static int Precedence(Token::Value token, bool accept_IN) {
339 if (token == Token::IN && !accept_IN) 387 if (token == Token::IN && !accept_IN)
340 return 0; // 0 precedence will terminate binary expression parsing 388 return 0; // 0 precedence will terminate binary expression parsing
341 return Token::Precedence(token); 389 return Token::Precedence(token);
342 } 390 }
343 391
344 typename Traits::Type::Factory* factory() { 392 typename Traits::Type::Factory* factory() {
345 return function_state_->factory(); 393 return function_state_->factory();
346 } 394 }
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); 445 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok);
398 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 446 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
399 ExpressionT ParseUnaryExpression(bool* ok); 447 ExpressionT ParseUnaryExpression(bool* ok);
400 ExpressionT ParsePostfixExpression(bool* ok); 448 ExpressionT ParsePostfixExpression(bool* ok);
401 ExpressionT ParseLeftHandSideExpression(bool* ok); 449 ExpressionT ParseLeftHandSideExpression(bool* ok);
402 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); 450 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok);
403 ExpressionT ParseMemberExpression(bool* ok); 451 ExpressionT ParseMemberExpression(bool* ok);
404 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, 452 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression,
405 bool* ok); 453 bool* ok);
406 454
455 // There are two ways of parsing arrow functions: if the beginning of an
456 // arrow function can be determined prior to process the parameter list
457 // (e.g. the current scanning position is known to be an arrow function
458 // and not an AssignmentExpression) then the first version is used. In
459 // most cases, we parse the parameter list as an AssignmentExpression
460 // and interpret the AST when the arrow "=>" token is found, using the
461 // second version.
462 // The overloaded ParseArrowFunctionLiteral() functions mainly deal with
463 // parsing/interpreting the parameter list, and then they both call
464 // ParseArrowFunctionLiteralBody() before consuming the arrow token.
465 ExpressionT ParseArrowFunctionLiteral(bool* ok);
466 ExpressionT ParseArrowFunctionLiteral(int start_pos,
467 ExpressionT params_ast,
468 bool* ok);
469 ExpressionT ParseArrowFunctionLiteralBody(
470 FunctionState* function_state,
471 typename Traits::Type::ScopePtr scope,
472 int num_parameters,
473 const Scanner::Location& eval_args_error_loc,
474 const Scanner::Location& dupe_error_loc,
475 const Scanner::Location& reserved_loc,
476 FunctionLiteral::IsParenthesizedFlag parenthesized,
477 int start_pos,
478 bool* ok);
479
407 // Checks if the expression is a valid reference expression (e.g., on the 480 // Checks if the expression is a valid reference expression (e.g., on the
408 // left-hand side of assignments). Although ruled out by ECMA as early errors, 481 // left-hand side of assignments). Although ruled out by ECMA as early errors,
409 // we allow calls for web compatibility and rewrite them to a runtime throw. 482 // we allow calls for web compatibility and rewrite them to a runtime throw.
410 ExpressionT CheckAndRewriteReferenceExpression( 483 ExpressionT CheckAndRewriteReferenceExpression(
411 ExpressionT expression, 484 ExpressionT expression,
412 Scanner::Location location, const char* message, bool* ok); 485 Scanner::Location location, const char* message, bool* ok);
413 486
414 // Used to detect duplicates in object literals. Each of the values 487 // Used to detect duplicates in object literals. Each of the values
415 // kGetterProperty, kSetterProperty and kValueProperty represents 488 // kGetterProperty, kSetterProperty and kValueProperty represents
416 // a type of object literal property. When parsing a property, its 489 // a type of object literal property. When parsing a property, its
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 553
481 private: 554 private:
482 Scanner* scanner_; 555 Scanner* scanner_;
483 uintptr_t stack_limit_; 556 uintptr_t stack_limit_;
484 bool stack_overflow_; 557 bool stack_overflow_;
485 558
486 bool allow_lazy_; 559 bool allow_lazy_;
487 bool allow_natives_syntax_; 560 bool allow_natives_syntax_;
488 bool allow_generators_; 561 bool allow_generators_;
489 bool allow_for_of_; 562 bool allow_for_of_;
563 bool allow_arrow_functions_;
490 564
491 typename Traits::Type::Zone* zone_; // Only used by Parser. 565 typename Traits::Type::Zone* zone_; // Only used by Parser.
492 }; 566 };
493 567
494 568
495 class PreParserIdentifier { 569 class PreParserIdentifier {
496 public: 570 public:
497 PreParserIdentifier() : type_(kUnknownIdentifier) {} 571 PreParserIdentifier() : type_(kUnknownIdentifier) {}
498 static PreParserIdentifier Default() { 572 static PreParserIdentifier Default() {
499 return PreParserIdentifier(kUnknownIdentifier); 573 return PreParserIdentifier(kUnknownIdentifier);
500 } 574 }
501 static PreParserIdentifier Eval() { 575 static PreParserIdentifier Eval() {
502 return PreParserIdentifier(kEvalIdentifier); 576 return PreParserIdentifier(kEvalIdentifier);
503 } 577 }
504 static PreParserIdentifier Arguments() { 578 static PreParserIdentifier Arguments() {
505 return PreParserIdentifier(kArgumentsIdentifier); 579 return PreParserIdentifier(kArgumentsIdentifier);
506 } 580 }
507 static PreParserIdentifier FutureReserved() { 581 static PreParserIdentifier FutureReserved() {
508 return PreParserIdentifier(kFutureReservedIdentifier); 582 return PreParserIdentifier(kFutureReservedIdentifier);
509 } 583 }
510 static PreParserIdentifier FutureStrictReserved() { 584 static PreParserIdentifier FutureStrictReserved() {
511 return PreParserIdentifier(kFutureStrictReservedIdentifier); 585 return PreParserIdentifier(kFutureStrictReservedIdentifier);
512 } 586 }
513 static PreParserIdentifier Yield() { 587 static PreParserIdentifier Yield() {
514 return PreParserIdentifier(kYieldIdentifier); 588 return PreParserIdentifier(kYieldIdentifier);
515 } 589 }
516 bool IsEval() { return type_ == kEvalIdentifier; } 590 bool IsEval() const { return type_ == kEvalIdentifier; }
517 bool IsArguments() { return type_ == kArgumentsIdentifier; } 591 bool IsArguments() const { return type_ == kArgumentsIdentifier; }
518 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; } 592 bool IsEvalOrArguments() { return type_ >= kEvalIdentifier; }
519 bool IsYield() { return type_ == kYieldIdentifier; } 593 bool IsYield() const { return type_ == kYieldIdentifier; }
520 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; } 594 bool IsFutureReserved() { return type_ == kFutureReservedIdentifier; }
521 bool IsFutureStrictReserved() { 595 bool IsFutureStrictReserved() const {
522 return type_ == kFutureStrictReservedIdentifier; 596 return type_ == kFutureStrictReservedIdentifier;
523 } 597 }
524 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; } 598 bool IsValidStrictVariable() { return type_ == kUnknownIdentifier; }
525 599
600 // Allow identifier->name()[->length()] to work. The preparser
601 // does not need the actual positions/lengths of the identifiers.
602 const PreParserIdentifier* operator->() const { return this; }
603 const PreParserIdentifier raw_name() const { return *this; }
604
605 int position() const {
606 return 0;
607 }
608
609 int length() const {
610 if (IsEval()) return 4;
611 if (IsArguments()) return 9;
612 if (IsYield()) return 5;
613 return 0;
614 }
615
526 private: 616 private:
527 enum Type { 617 enum Type {
528 kUnknownIdentifier, 618 kUnknownIdentifier,
529 kFutureReservedIdentifier, 619 kFutureReservedIdentifier,
530 kFutureStrictReservedIdentifier, 620 kFutureStrictReservedIdentifier,
531 kYieldIdentifier, 621 kYieldIdentifier,
532 kEvalIdentifier, 622 kEvalIdentifier,
533 kArgumentsIdentifier 623 kArgumentsIdentifier
534 }; 624 };
535 explicit PreParserIdentifier(Type type) : type_(type) {} 625 explicit PreParserIdentifier(Type type) : type_(type) {}
536 Type type_; 626 Type type_;
537 627
538 friend class PreParserExpression; 628 friend class PreParserExpression;
629 friend class PreParserScope;
539 }; 630 };
540 631
541 632
542 // Bits 0 and 1 are used to identify the type of expression: 633 // Bits 0 and 1 are used to identify the type of expression:
543 // If bit 0 is set, it's an identifier. 634 // If bit 0 is set, it's an identifier.
544 // if bit 1 is set, it's a string literal. 635 // if bit 1 is set, it's a string literal.
545 // If neither is set, it's no particular type, and both set isn't 636 // If neither is set, it's no particular type, and both set isn't
546 // use yet. 637 // use yet.
547 class PreParserExpression { 638 class PreParserExpression {
548 public: 639 public:
549 static PreParserExpression Default() { 640 static PreParserExpression Default() {
550 return PreParserExpression(kUnknownExpression); 641 return PreParserExpression(kUnknownExpression);
551 } 642 }
552 643
553 static PreParserExpression FromIdentifier(PreParserIdentifier id) { 644 static PreParserExpression FromIdentifier(PreParserIdentifier id) {
554 return PreParserExpression(kIdentifierFlag | 645 return PreParserExpression(kTypeIdentifier |
555 (id.type_ << kIdentifierShift)); 646 (id.type_ << kIdentifierShift));
556 } 647 }
557 648
649 static PreParserExpression BinaryOperation(PreParserExpression left,
650 PreParserExpression right) {
651 int left_bits = left.BinaryOperationBits();
652 int right_bits = right.BinaryOperationBits();
653
654 int code = left_bits | right_bits;
655 if (left_bits & right_bits & kBinaryOperationHasEval)
656 code |= kBinaryOperationHasDuplicatedIdentifier;
657 else if (left_bits & right_bits & kBinaryOperationHasArguments)
658 code |= kBinaryOperationHasDuplicatedIdentifier;
659 // TODO(aperezdc): Handle other duplicate identifier
660
661 return PreParserExpression(kTypeBinaryOperation | code);
662 }
663
558 static PreParserExpression StringLiteral() { 664 static PreParserExpression StringLiteral() {
559 return PreParserExpression(kUnknownStringLiteral); 665 return PreParserExpression(kUnknownStringLiteral);
560 } 666 }
561 667
562 static PreParserExpression UseStrictStringLiteral() { 668 static PreParserExpression UseStrictStringLiteral() {
563 return PreParserExpression(kUseStrictString); 669 return PreParserExpression(kUseStrictString);
564 } 670 }
565 671
566 static PreParserExpression This() { 672 static PreParserExpression This() {
567 return PreParserExpression(kThisExpression); 673 return PreParserExpression(kThisExpression);
568 } 674 }
569 675
570 static PreParserExpression ThisProperty() { 676 static PreParserExpression ThisProperty() {
571 return PreParserExpression(kThisPropertyExpression); 677 return PreParserExpression(kThisPropertyExpression);
572 } 678 }
573 679
574 static PreParserExpression Property() { 680 static PreParserExpression Property() {
575 return PreParserExpression(kPropertyExpression); 681 return PreParserExpression(kPropertyExpression);
576 } 682 }
577 683
578 static PreParserExpression Call() { 684 static PreParserExpression Call() {
579 return PreParserExpression(kCallExpression); 685 return PreParserExpression(kCallExpression);
580 } 686 }
581 687
582 bool IsIdentifier() { return (code_ & kIdentifierFlag) != 0; } 688 bool IsIdentifier() const {
689 return (code_ & kTypeMask) == kTypeIdentifier;
690 }
583 691
584 PreParserIdentifier AsIdentifier() { 692 PreParserIdentifier AsIdentifier() const {
585 ASSERT(IsIdentifier()); 693 ASSERT(IsIdentifier());
586 return PreParserIdentifier( 694 return PreParserIdentifier(
587 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift)); 695 static_cast<PreParserIdentifier::Type>(code_ >> kIdentifierShift));
588 } 696 }
589 697
590 bool IsStringLiteral() { return (code_ & kStringLiteralFlag) != 0; } 698 bool IsStringLiteral() const {
699 return (code_ & kTypeMask) == kTypeStringLiteral;
700 }
591 701
592 bool IsUseStrictLiteral() { 702 bool IsUseStrictLiteral() {
593 return (code_ & kStringLiteralMask) == kUseStrictString; 703 return (code_ & kUseStrictString) == kUseStrictString;
594 } 704 }
595 705
596 bool IsThis() { return code_ == kThisExpression; } 706 bool IsThis() { return code_ == kThisExpression; }
597 707
598 bool IsThisProperty() { return code_ == kThisPropertyExpression; } 708 bool IsThisProperty() { return code_ == kThisPropertyExpression; }
599 709
600 bool IsProperty() { 710 bool IsProperty() {
601 return code_ == kPropertyExpression || code_ == kThisPropertyExpression; 711 return code_ == kPropertyExpression || code_ == kThisPropertyExpression;
602 } 712 }
603 713
604 bool IsCall() { return code_ == kCallExpression; } 714 bool IsCall() { return code_ == kCallExpression; }
605 715
606 bool IsValidReferenceExpression() { 716 bool IsValidReferenceExpression() {
607 return IsIdentifier() || IsProperty(); 717 return IsIdentifier() || IsProperty();
608 } 718 }
609 719
610 // At the moment PreParser doesn't track these expression types. 720 // At the moment PreParser doesn't track these expression types.
611 bool IsFunctionLiteral() const { return false; } 721 bool IsFunctionLiteral() const { return false; }
612 bool IsCallNew() const { return false; } 722 bool IsCallNew() const { return false; }
613 723
614 PreParserExpression AsFunctionLiteral() { return *this; } 724 PreParserExpression AsFunctionLiteral() { return *this; }
615 725
726 bool IsBinaryOperation() const {
727 return (code_ & kTypeMask) == kTypeBinaryOperation;
728 }
729
616 // Dummy implementation for making expression->somefunc() work in both Parser 730 // Dummy implementation for making expression->somefunc() work in both Parser
617 // and PreParser. 731 // and PreParser.
618 PreParserExpression* operator->() { return this; } 732 PreParserExpression* operator->() { return this; }
619 733
620 // More dummy implementations of things PreParser doesn't need to track: 734 // More dummy implementations of things PreParser doesn't need to track:
621 void set_index(int index) {} // For YieldExpressions 735 void set_index(int index) {} // For YieldExpressions
622 void set_parenthesized() {} 736 void set_parenthesized() {}
623 737
738 int position() const { return RelocInfo::kNoPosition; }
739 void set_function_token_position(int position) {}
740 void set_ast_properties(int* ast_properties) {}
741 void set_dont_optimize_reason(BailoutReason dont_optimize_reason) {}
742
743 bool HasEval() const {
744 if (IsBinaryOperation()) return (code_ & kBinaryOperationHasEval) != 0;
745 if (IsIdentifier()) return AsIdentifier().IsEval();
746 return false;
747 }
748
749 bool HasArguments() const {
750 if (IsBinaryOperation()) return (code_ & kBinaryOperationHasArguments) != 0;
751 if (IsIdentifier()) return AsIdentifier().IsArguments();
752 return false;
753 }
754
755 bool HasFutureStrictReserved() const {
756 if (IsBinaryOperation())
757 return (code_ & kBinaryOperationHasFutureStrictReserved) != 0;
758 if (IsIdentifier())
759 return (AsIdentifier().IsFutureStrictReserved() ||
760 AsIdentifier().IsYield());
761 return false;
762 }
763 bool HasDuplicatedIdentifier() const {
764 return IsBinaryOperation() &&
765 (code_ & kBinaryOperationHasDuplicatedIdentifier) != 0;
766 }
767
768 bool operator==(const PreParserExpression& other) const {
769 return code_ == other.code_;
770 }
771 bool operator!=(const PreParserExpression& other) const {
772 return code_ != other.code_;
773 }
774
624 private: 775 private:
625 // Least significant 2 bits are used as flags. Bits 0 and 1 represent 776 // Least significant 2 bits are used as expression type. If the expression
626 // identifiers or strings literals, and are mutually exclusive, but can both 777 // is an identifier or a string literal, the other bits describe the type
627 // be absent. If the expression is an identifier or a string literal, the 778 // (see PreParserIdentifier::Type and string literal constants below). For
628 // other bits describe the type (see PreParserIdentifier::Type and string 779 // binary operations, the other bits are flags which further describe the
629 // literal constants below). 780 // contents of the expression.
630 enum { 781 enum {
631 kUnknownExpression = 0, 782 kUnknownExpression = 0,
783
784 kTypeMask = 1 | 2,
785
632 // Identifiers 786 // Identifiers
633 kIdentifierFlag = 1, // Used to detect labels. 787 kTypeIdentifier = 1, // Used to detect labels.
634 kIdentifierShift = 3, 788 kIdentifierShift = 3,
635 789
636 kStringLiteralFlag = 2, // Used to detect directive prologue. 790 kTypeStringLiteral = 2, // Used to detect directive prologue.
637 kUnknownStringLiteral = kStringLiteralFlag, 791 kUnknownStringLiteral = kTypeStringLiteral,
638 kUseStrictString = kStringLiteralFlag | 8, 792 kUseStrictString = kTypeStringLiteral | 8,
639 kStringLiteralMask = kUseStrictString, 793 kStringLiteralMask = kUseStrictString,
640 794
795 // Binary operations. Those are needed to detect certain keywords and
796 // duplicated identifier in parameter lists for arrow functions, because
797 // they are initially parsed as comma-separated expressions.
798 kTypeBinaryOperation = 3,
799 kBinaryOperationHasEval = 1 << 2,
800 kBinaryOperationHasArguments = 2 << 2,
801 kBinaryOperationHasFutureStrictReserved = 4 << 2,
802 kBinaryOperationHasDuplicatedIdentifier = 8 << 2,
803
641 // Below here applies if neither identifier nor string literal. Reserve the 804 // Below here applies if neither identifier nor string literal. Reserve the
642 // 2 least significant bits for flags. 805 // 2 least significant bits for flags.
643 kThisExpression = 1 << 2, 806 kThisExpression = 1 << 2,
644 kThisPropertyExpression = 2 << 2, 807 kThisPropertyExpression = 2 << 2,
645 kPropertyExpression = 3 << 2, 808 kPropertyExpression = 3 << 2,
646 kCallExpression = 4 << 2 809 kCallExpression = 4 << 2
647 }; 810 };
648 811
649 explicit PreParserExpression(int expression_code) : code_(expression_code) {} 812 explicit PreParserExpression(int expression_code) : code_(expression_code) {}
650 813
814 V8_INLINE int BinaryOperationBits() const {
815 if (IsBinaryOperation()) return code_;
816 if (IsIdentifier()) {
817 const PreParserIdentifier ident = AsIdentifier();
818 if (ident.IsEval()) return kBinaryOperationHasEval;
819 if (ident.IsArguments()) return kBinaryOperationHasArguments;
820 if (ident.IsYield() || ident.IsFutureStrictReserved())
821 return kBinaryOperationHasFutureStrictReserved;
822 }
823 return 0;
824 }
825
651 int code_; 826 int code_;
652 }; 827 };
653 828
654 829
655 // PreParserExpressionList doesn't actually store the expressions because 830 // PreParserExpressionList doesn't actually store the expressions because
656 // PreParser doesn't need to. 831 // PreParser doesn't need to.
657 class PreParserExpressionList { 832 class PreParserExpressionList {
658 public: 833 public:
659 // These functions make list->Add(some_expression) work (and do nothing). 834 // These functions make list->Add(some_expression) work (and do nothing).
660 PreParserExpressionList() : length_(0) {} 835 PreParserExpressionList() : length_(0) {}
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
722 public: 897 public:
723 // These functions make list->Add(some_expression) work as no-ops. 898 // These functions make list->Add(some_expression) work as no-ops.
724 PreParserStatementList() {} 899 PreParserStatementList() {}
725 PreParserStatementList* operator->() { return this; } 900 PreParserStatementList* operator->() { return this; }
726 void Add(PreParserStatement, void*) {} 901 void Add(PreParserStatement, void*) {}
727 }; 902 };
728 903
729 904
730 class PreParserScope { 905 class PreParserScope {
731 public: 906 public:
732 explicit PreParserScope(PreParserScope* outer_scope, ScopeType scope_type) 907 explicit PreParserScope(PreParserScope* outer_scope,
733 : scope_type_(scope_type) { 908 ScopeType scope_type,
909 void* = NULL)
910 : scope_type_(scope_type), declared_parameters_(0) {
734 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY; 911 strict_mode_ = outer_scope ? outer_scope->strict_mode() : SLOPPY;
735 } 912 }
736 913
737 ScopeType type() { return scope_type_; } 914 ScopeType type() { return scope_type_; }
738 StrictMode strict_mode() const { return strict_mode_; } 915 StrictMode strict_mode() const { return strict_mode_; }
739 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; } 916 void SetStrictMode(StrictMode strict_mode) { strict_mode_ = strict_mode; }
740 917
918 // TODO(aperezdc): Would allowing lazy compilation in preparser make sense?
919 bool AllowsLazyCompilation() const { return false; }
920
921 void set_start_position(int position) {}
922 void set_end_position(int position) {}
923
924 bool IsDeclared(const PreParserIdentifier& identifier) const {
925 return (declared_parameters_ & (1 << identifier.type_)) != 0;
926 }
927
928 void DeclareParameter(const PreParserIdentifier& identifier, VariableMode) {
929 declared_parameters_ |= (1 << identifier.type_);
930 }
931
932 // Allow scope->Foo() to work.
933 PreParserScope* operator->() { return this; }
934
741 private: 935 private:
742 ScopeType scope_type_; 936 ScopeType scope_type_;
743 StrictMode strict_mode_; 937 StrictMode strict_mode_;
938 int declared_parameters_;
744 }; 939 };
745 940
746 941
747 class PreParserFactory { 942 class PreParserFactory {
748 public: 943 public:
749 explicit PreParserFactory(void* extra_param1, void* extra_param2) {} 944 explicit PreParserFactory(void* extra_param1, void* extra_param2) {}
750 PreParserExpression NewStringLiteral(PreParserIdentifier identifier, 945 PreParserExpression NewStringLiteral(PreParserIdentifier identifier,
751 int pos) { 946 int pos) {
752 return PreParserExpression::Default(); 947 return PreParserExpression::Default();
753 } 948 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 return PreParserExpression::Property(); 989 return PreParserExpression::Property();
795 } 990 }
796 PreParserExpression NewUnaryOperation(Token::Value op, 991 PreParserExpression NewUnaryOperation(Token::Value op,
797 PreParserExpression expression, 992 PreParserExpression expression,
798 int pos) { 993 int pos) {
799 return PreParserExpression::Default(); 994 return PreParserExpression::Default();
800 } 995 }
801 PreParserExpression NewBinaryOperation(Token::Value op, 996 PreParserExpression NewBinaryOperation(Token::Value op,
802 PreParserExpression left, 997 PreParserExpression left,
803 PreParserExpression right, int pos) { 998 PreParserExpression right, int pos) {
804 return PreParserExpression::Default(); 999 return PreParserExpression::BinaryOperation(left, right);
805 } 1000 }
806 PreParserExpression NewCompareOperation(Token::Value op, 1001 PreParserExpression NewCompareOperation(Token::Value op,
807 PreParserExpression left, 1002 PreParserExpression left,
808 PreParserExpression right, int pos) { 1003 PreParserExpression right, int pos) {
809 return PreParserExpression::Default(); 1004 return PreParserExpression::Default();
810 } 1005 }
811 PreParserExpression NewAssignment(Token::Value op, 1006 PreParserExpression NewAssignment(Token::Value op,
812 PreParserExpression left, 1007 PreParserExpression left,
813 PreParserExpression right, 1008 PreParserExpression right,
814 int pos) { 1009 int pos) {
(...skipping 20 matching lines...) Expand all
835 PreParserExpression NewCall(PreParserExpression expression, 1030 PreParserExpression NewCall(PreParserExpression expression,
836 PreParserExpressionList arguments, 1031 PreParserExpressionList arguments,
837 int pos) { 1032 int pos) {
838 return PreParserExpression::Call(); 1033 return PreParserExpression::Call();
839 } 1034 }
840 PreParserExpression NewCallNew(PreParserExpression expression, 1035 PreParserExpression NewCallNew(PreParserExpression expression,
841 PreParserExpressionList arguments, 1036 PreParserExpressionList arguments,
842 int pos) { 1037 int pos) {
843 return PreParserExpression::Default(); 1038 return PreParserExpression::Default();
844 } 1039 }
1040 PreParserStatement NewReturnStatement(PreParserExpression expression,
1041 int pos) {
1042 return PreParserStatement::Default();
1043 }
1044 PreParserExpression
1045 NewFunctionLiteral(PreParserIdentifier name,
1046 AstValueFactory* ast_value_factory,
1047 PreParserScope& scope,
1048 PreParserStatementList body,
1049 int materialized_literal_count,
1050 int expected_property_count,
1051 int handler_count,
1052 int parameter_count,
1053 FunctionLiteral::ParameterFlag has_duplicate_parameters,
1054 FunctionLiteral::FunctionType function_type,
1055 FunctionLiteral::IsFunctionFlag is_function,
1056 FunctionLiteral::IsParenthesizedFlag is_parenthesized,
1057 FunctionLiteral::IsGeneratorFlag is_generator,
1058 int position) {
1059 return PreParserExpression::Default();
1060 }
1061
1062 // Return the object itself as AstVisitor and implement the needed
1063 // dummy method right in this class.
1064 PreParserFactory* visitor() { return this; }
1065 BailoutReason dont_optimize_reason() { return kNoReason; }
1066 int* ast_properties() { static int dummy = 42; return &dummy; }
845 }; 1067 };
846 1068
847 1069
848 class PreParser; 1070 class PreParser;
849 1071
850 class PreParserTraits { 1072 class PreParserTraits {
851 public: 1073 public:
852 struct Type { 1074 struct Type {
853 // TODO(marja): To be removed. The Traits object should contain all the data 1075 // TODO(marja): To be removed. The Traits object should contain all the data
854 // it needs. 1076 // it needs.
855 typedef PreParser* Parser; 1077 typedef PreParser* Parser;
856 1078
857 // Used by FunctionState and BlockState. 1079 // Used by FunctionState and BlockState.
858 typedef PreParserScope Scope; 1080 typedef PreParserScope Scope;
1081 typedef PreParserScope ScopePtr;
1082
859 // PreParser doesn't need to store generator variables. 1083 // PreParser doesn't need to store generator variables.
860 typedef void GeneratorVariable; 1084 typedef void GeneratorVariable;
861 // No interaction with Zones. 1085 // No interaction with Zones.
862 typedef void Zone; 1086 typedef void Zone;
863 1087
1088 typedef int AstProperties;
1089 typedef Vector<PreParserIdentifier> ParameterIdentifierVector;
1090
864 // Return types for traversing functions. 1091 // Return types for traversing functions.
865 typedef PreParserIdentifier Identifier; 1092 typedef PreParserIdentifier Identifier;
866 typedef PreParserExpression Expression; 1093 typedef PreParserExpression Expression;
867 typedef PreParserExpression YieldExpression; 1094 typedef PreParserExpression YieldExpression;
868 typedef PreParserExpression FunctionLiteral; 1095 typedef PreParserExpression FunctionLiteral;
869 typedef PreParserExpression ObjectLiteralProperty; 1096 typedef PreParserExpression ObjectLiteralProperty;
870 typedef PreParserExpression Literal; 1097 typedef PreParserExpression Literal;
871 typedef PreParserExpressionList ExpressionList; 1098 typedef PreParserExpressionList ExpressionList;
872 typedef PreParserExpressionList PropertyList; 1099 typedef PreParserExpressionList PropertyList;
873 typedef PreParserStatementList StatementList; 1100 typedef PreParserStatementList StatementList;
(...skipping 22 matching lines...) Expand all
896 } 1123 }
897 1124
898 static bool IsIdentifier(PreParserExpression expression) { 1125 static bool IsIdentifier(PreParserExpression expression) {
899 return expression.IsIdentifier(); 1126 return expression.IsIdentifier();
900 } 1127 }
901 1128
902 static PreParserIdentifier AsIdentifier(PreParserExpression expression) { 1129 static PreParserIdentifier AsIdentifier(PreParserExpression expression) {
903 return expression.AsIdentifier(); 1130 return expression.AsIdentifier();
904 } 1131 }
905 1132
1133 static bool IsFutureStrictReserved(PreParserIdentifier identifier) {
1134 return identifier.IsYield() || identifier.IsFutureStrictReserved();
1135 }
1136
906 static bool IsBoilerplateProperty(PreParserExpression property) { 1137 static bool IsBoilerplateProperty(PreParserExpression property) {
907 // PreParser doesn't count boilerplate properties. 1138 // PreParser doesn't count boilerplate properties.
908 return false; 1139 return false;
909 } 1140 }
910 1141
911 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) { 1142 static bool IsArrayIndex(PreParserIdentifier string, uint32_t* index) {
912 return false; 1143 return false;
913 } 1144 }
914 1145
915 // Functions for encapsulating the differences between parsing and preparsing; 1146 // Functions for encapsulating the differences between parsing and preparsing;
916 // operations interleaved with the recursive descent. 1147 // operations interleaved with the recursive descent.
917 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) { 1148 static void PushLiteralName(FuncNameInferrer* fni, PreParserIdentifier id) {
918 // PreParser should not use FuncNameInferrer. 1149 // PreParser should not use FuncNameInferrer.
919 UNREACHABLE(); 1150 UNREACHABLE();
920 } 1151 }
921 static void PushPropertyName(FuncNameInferrer* fni, 1152 static void PushPropertyName(FuncNameInferrer* fni,
922 PreParserExpression expression) { 1153 PreParserExpression expression) {
923 // PreParser should not use FuncNameInferrer. 1154 // PreParser should not use FuncNameInferrer.
924 UNREACHABLE(); 1155 UNREACHABLE();
925 } 1156 }
1157 static void InferFunctionName(FuncNameInferrer* fni,
1158 PreParserExpression expression) {
1159 // PreParser should not use FuncNameInferrer.
1160 UNREACHABLE();
1161 }
926 1162
927 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 1163 static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
928 PreParserScope* scope, PreParserExpression value, bool* has_function) {} 1164 PreParserScope* scope, PreParserExpression value, bool* has_function) {}
929 1165
930 static void CheckAssigningFunctionLiteralToProperty( 1166 static void CheckAssigningFunctionLiteralToProperty(
931 PreParserExpression left, PreParserExpression right) {} 1167 PreParserExpression left, PreParserExpression right) {}
932 1168
933 // PreParser doesn't need to keep track of eval calls. 1169 // PreParser doesn't need to keep track of eval calls.
934 static void CheckPossibleEvalCall(PreParserExpression expression, 1170 static void CheckPossibleEvalCall(PreParserExpression expression,
935 PreParserScope* scope) {} 1171 PreParserScope* scope) {}
936 1172
937 static PreParserExpression MarkExpressionAsLValue( 1173 static PreParserExpression MarkExpressionAsLValue(
938 PreParserExpression expression) { 1174 PreParserExpression expression) {
939 // TODO(marja): To be able to produce the same errors, the preparser needs 1175 // TODO(marja): To be able to produce the same errors, the preparser needs
940 // to start tracking which expressions are variables and which are lvalues. 1176 // to start tracking which expressions are variables and which are lvalues.
941 return expression; 1177 return expression;
942 } 1178 }
943 1179
1180 static AstValueFactory* ast_value_factory() { return NULL; }
1181
944 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x, 1182 bool ShortcutNumericLiteralBinaryExpression(PreParserExpression* x,
945 PreParserExpression y, 1183 PreParserExpression y,
946 Token::Value op, 1184 Token::Value op,
947 int pos, 1185 int pos,
948 PreParserFactory* factory) { 1186 PreParserFactory* factory) {
949 return false; 1187 return false;
950 } 1188 }
951 1189
952 PreParserExpression BuildUnaryExpression(PreParserExpression expression, 1190 PreParserExpression BuildUnaryExpression(PreParserExpression expression,
953 Token::Value op, int pos, 1191 Token::Value op, int pos,
954 PreParserFactory* factory) { 1192 PreParserFactory* factory) {
955 return PreParserExpression::Default(); 1193 return PreParserExpression::Default();
956 } 1194 }
957 1195
958 PreParserExpression NewThrowReferenceError(const char* type, int pos) { 1196 PreParserExpression NewThrowReferenceError(const char* type, int pos) {
959 return PreParserExpression::Default(); 1197 return PreParserExpression::Default();
960 } 1198 }
961 PreParserExpression NewThrowSyntaxError( 1199 PreParserExpression NewThrowSyntaxError(
962 const char* type, Handle<Object> arg, int pos) { 1200 const char* type, Handle<Object> arg, int pos) {
963 return PreParserExpression::Default(); 1201 return PreParserExpression::Default();
964 } 1202 }
965 PreParserExpression NewThrowTypeError( 1203 PreParserExpression NewThrowTypeError(
966 const char* type, Handle<Object> arg, int pos) { 1204 const char* type, Handle<Object> arg, int pos) {
967 return PreParserExpression::Default(); 1205 return PreParserExpression::Default();
968 } 1206 }
1207 PreParserScope NewScope(PreParserScope* outer_scope,
1208 ScopeType scope_type) {
1209 return PreParserScope(outer_scope, scope_type);
1210 }
969 1211
970 // Reporting errors. 1212 // Reporting errors.
971 void ReportMessageAt(Scanner::Location location, 1213 void ReportMessageAt(Scanner::Location location,
972 const char* message, 1214 const char* message,
973 const char* arg = NULL, 1215 const char* arg = NULL,
974 bool is_reference_error = false); 1216 bool is_reference_error = false);
975 void ReportMessageAt(int start_pos, 1217 void ReportMessageAt(int start_pos,
976 int end_pos, 1218 int end_pos,
977 const char* message, 1219 const char* message,
978 const char* arg = NULL, 1220 const char* arg = NULL,
979 bool is_reference_error = false); 1221 bool is_reference_error = false);
980 1222
981 // "null" return type creators. 1223 // "null" return type creators.
982 static PreParserIdentifier EmptyIdentifier() { 1224 static PreParserIdentifier EmptyIdentifier() {
983 return PreParserIdentifier::Default(); 1225 return PreParserIdentifier::Default();
984 } 1226 }
1227 static PreParserIdentifier EmptyIdentifierString() {
1228 return PreParserIdentifier::Default();
1229 }
985 static PreParserExpression EmptyExpression() { 1230 static PreParserExpression EmptyExpression() {
986 return PreParserExpression::Default(); 1231 return PreParserExpression::Default();
987 } 1232 }
988 static PreParserExpression EmptyLiteral() { 1233 static PreParserExpression EmptyLiteral() {
989 return PreParserExpression::Default(); 1234 return PreParserExpression::Default();
990 } 1235 }
991 static PreParserExpressionList NullExpressionList() { 1236 static PreParserExpressionList NullExpressionList() {
992 return PreParserExpressionList(); 1237 return PreParserExpressionList();
993 } 1238 }
994 1239
995 // Odd-ball literal creators. 1240 // Odd-ball literal creators.
996 static PreParserExpression GetLiteralTheHole(int position, 1241 static PreParserExpression GetLiteralTheHole(int position,
997 PreParserFactory* factory) { 1242 PreParserFactory* factory) {
998 return PreParserExpression::Default(); 1243 return PreParserExpression::Default();
999 } 1244 }
1000 1245
1001 // Producing data during the recursive descent. 1246 // Producing data during the recursive descent.
1002 PreParserIdentifier GetSymbol(Scanner* scanner); 1247 PreParserIdentifier GetSymbol(Scanner* scanner);
1003 1248
1004 static PreParserIdentifier GetNextSymbol(Scanner* scanner) { 1249 static PreParserIdentifier GetNextSymbol(Scanner* scanner) {
1005 return PreParserIdentifier::Default(); 1250 return PreParserIdentifier::Default();
1006 } 1251 }
1007 1252
1008 static PreParserExpression ThisExpression(PreParserScope* scope, 1253 static PreParserExpression ThisExpression(PreParserScope* scope,
1009 PreParserFactory* factory) { 1254 PreParserFactory* factory,
1255 int pos) {
1010 return PreParserExpression::This(); 1256 return PreParserExpression::This();
1011 } 1257 }
1012 1258
1013 static PreParserExpression ExpressionFromLiteral( 1259 static PreParserExpression ExpressionFromLiteral(
1014 Token::Value token, int pos, Scanner* scanner, 1260 Token::Value token, int pos, Scanner* scanner,
1015 PreParserFactory* factory) { 1261 PreParserFactory* factory) {
1016 return PreParserExpression::Default(); 1262 return PreParserExpression::Default();
1017 } 1263 }
1018 1264
1019 static PreParserExpression ExpressionFromIdentifier( 1265 static PreParserExpression ExpressionFromIdentifier(
(...skipping 11 matching lines...) Expand all
1031 } 1277 }
1032 1278
1033 static PreParserStatementList NewStatementList(int size, void* zone) { 1279 static PreParserStatementList NewStatementList(int size, void* zone) {
1034 return PreParserStatementList(); 1280 return PreParserStatementList();
1035 } 1281 }
1036 1282
1037 static PreParserExpressionList NewPropertyList(int size, void* zone) { 1283 static PreParserExpressionList NewPropertyList(int size, void* zone) {
1038 return PreParserExpressionList(); 1284 return PreParserExpressionList();
1039 } 1285 }
1040 1286
1287 V8_INLINE void SkipLazyFunctionBody(
1288 PreParserIdentifier function_name,
1289 int* materialized_literal_count,
1290 int* expected_property_count,
1291 bool* ok) {
1292 UNREACHABLE();
1293 }
1294
1295 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1296 PreParserIdentifier function_name,
1297 int pos,
1298 Variable* fvar,
1299 Token::Value fvar_init_op,
1300 bool is_generator,
1301 bool* ok);
1302
1303 // Utility functions
1304 V8_INLINE Vector<PreParserIdentifier> ParameterListFromExpression(
1305 PreParserExpression expression, bool* ok);
1306
1307 void CheckConflictingVarDeclarations(
1308 PreParserScope scope,
1309 bool* ok) {}
1310
1041 // Temporary glue; these functions will move to ParserBase. 1311 // Temporary glue; these functions will move to ParserBase.
1042 PreParserExpression ParseV8Intrinsic(bool* ok); 1312 PreParserExpression ParseV8Intrinsic(bool* ok);
1043 PreParserExpression ParseFunctionLiteral( 1313 PreParserExpression ParseFunctionLiteral(
1044 PreParserIdentifier name, 1314 PreParserIdentifier name,
1045 Scanner::Location function_name_location, 1315 Scanner::Location function_name_location,
1046 bool name_is_strict_reserved, 1316 bool name_is_strict_reserved,
1047 bool is_generator, 1317 bool is_generator,
1048 int function_token_position, 1318 int function_token_position,
1049 FunctionLiteral::FunctionType type, 1319 FunctionLiteral::FunctionType type,
1050 bool* ok); 1320 bool* ok);
(...skipping 29 matching lines...) Expand all
1080 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit) 1350 PreParser(Scanner* scanner, ParserRecorder* log, uintptr_t stack_limit)
1081 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL, 1351 : ParserBase<PreParserTraits>(scanner, stack_limit, NULL, log, NULL,
1082 this) {} 1352 this) {}
1083 1353
1084 // Pre-parse the program from the character stream; returns true on 1354 // Pre-parse the program from the character stream; returns true on
1085 // success (even if parsing failed, the pre-parse data successfully 1355 // success (even if parsing failed, the pre-parse data successfully
1086 // captured the syntax error), and false if a stack-overflow happened 1356 // captured the syntax error), and false if a stack-overflow happened
1087 // during parsing. 1357 // during parsing.
1088 PreParseResult PreParseProgram() { 1358 PreParseResult PreParseProgram() {
1089 PreParserScope scope(scope_, GLOBAL_SCOPE); 1359 PreParserScope scope(scope_, GLOBAL_SCOPE);
1090 FunctionState top_scope(&function_state_, &scope_, &scope, NULL); 1360 FunctionState top_scope(&function_state_, &scope_, &scope, NULL, NULL);
1091 bool ok = true; 1361 bool ok = true;
1092 int start_position = scanner()->peek_location().beg_pos; 1362 int start_position = scanner()->peek_location().beg_pos;
1093 ParseSourceElements(Token::EOS, &ok); 1363 ParseSourceElements(Token::EOS, &ok);
1094 if (stack_overflow()) return kPreParseStackOverflow; 1364 if (stack_overflow()) return kPreParseStackOverflow;
1095 if (!ok) { 1365 if (!ok) {
1096 ReportUnexpectedToken(scanner()->current_token()); 1366 ReportUnexpectedToken(scanner()->current_token());
1097 } else if (scope_->strict_mode() == STRICT) { 1367 } else if (scope_->strict_mode() == STRICT) {
1098 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok); 1368 CheckOctalLiteral(start_position, scanner()->location().end_pos, &ok);
1099 } 1369 }
1100 return kPreParseSuccess; 1370 return kPreParseSuccess;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 Statement ParseDoWhileStatement(bool* ok); 1432 Statement ParseDoWhileStatement(bool* ok);
1163 Statement ParseWhileStatement(bool* ok); 1433 Statement ParseWhileStatement(bool* ok);
1164 Statement ParseForStatement(bool* ok); 1434 Statement ParseForStatement(bool* ok);
1165 Statement ParseThrowStatement(bool* ok); 1435 Statement ParseThrowStatement(bool* ok);
1166 Statement ParseTryStatement(bool* ok); 1436 Statement ParseTryStatement(bool* ok);
1167 Statement ParseDebuggerStatement(bool* ok); 1437 Statement ParseDebuggerStatement(bool* ok);
1168 Expression ParseConditionalExpression(bool accept_IN, bool* ok); 1438 Expression ParseConditionalExpression(bool accept_IN, bool* ok);
1169 Expression ParseObjectLiteral(bool* ok); 1439 Expression ParseObjectLiteral(bool* ok);
1170 Expression ParseV8Intrinsic(bool* ok); 1440 Expression ParseV8Intrinsic(bool* ok);
1171 1441
1442 V8_INLINE void SkipLazyFunctionBody(
1443 PreParserIdentifier function_name,
1444 int* materialized_literal_count,
1445 int* expected_property_count,
1446 bool* ok);
1447 V8_INLINE PreParserStatementList ParseEagerFunctionBody(
1448 PreParserIdentifier function_name,
1449 int pos,
1450 Variable* fvar,
1451 Token::Value fvar_init_op,
1452 bool is_generator,
1453 bool* ok);
1454
1172 Expression ParseFunctionLiteral( 1455 Expression ParseFunctionLiteral(
1173 Identifier name, 1456 Identifier name,
1174 Scanner::Location function_name_location, 1457 Scanner::Location function_name_location,
1175 bool name_is_strict_reserved, 1458 bool name_is_strict_reserved,
1176 bool is_generator, 1459 bool is_generator,
1177 int function_token_pos, 1460 int function_token_pos,
1178 FunctionLiteral::FunctionType function_type, 1461 FunctionLiteral::FunctionType function_type,
1179 bool* ok); 1462 bool* ok);
1180 void ParseLazyFunctionLiteralBody(bool* ok); 1463 void ParseLazyFunctionLiteralBody(bool* ok);
1181 1464
1182 bool CheckInOrOf(bool accept_OF); 1465 bool CheckInOrOf(bool accept_OF);
1183 }; 1466 };
1184 1467
1468
1469 PreParserStatementList PreParser::ParseEagerFunctionBody(
1470 PreParserIdentifier function_name,
1471 int pos,
1472 Variable* fvar,
1473 Token::Value fvar_init_op,
1474 bool is_generator,
1475 bool* ok) {
1476 ParsingModeScope parsing_mode(this, PARSE_EAGERLY);
1477
1478 ParseSourceElements(Token::RBRACE, ok);
1479 if (!*ok) return PreParserStatementList();
1480
1481 Expect(Token::RBRACE, ok);
1482 return PreParserStatementList();
1483 }
1484
1485
1486 PreParserStatementList PreParserTraits::ParseEagerFunctionBody(
1487 PreParserIdentifier function_name,
1488 int pos,
1489 Variable* fvar,
1490 Token::Value fvar_init_op,
1491 bool is_generator,
1492 bool* ok) {
1493 return pre_parser_->ParseEagerFunctionBody(function_name,
1494 pos, fvar, fvar_init_op, is_generator, ok);
1495 }
1496
1497
1498 Vector<PreParserIdentifier> PreParserTraits::ParameterListFromExpression(
1499 PreParserExpression expression, bool* ok) {
1500 Collector<PreParserIdentifier> collector;
1501
1502 if (expression.HasEval())
1503 collector.Add(PreParserIdentifier::Eval());
1504 if (expression.HasArguments())
1505 collector.Add(PreParserIdentifier::Arguments());
1506 if (expression.HasFutureStrictReserved())
1507 collector.Add(PreParserIdentifier::FutureStrictReserved());
1508
1509 if (expression.HasDuplicatedIdentifier() ||
1510 pre_parser_->scanner()->parameter_list()->HasDuplicateIdentifiers()) {
1511 collector.Add(PreParserIdentifier::Default());
1512 collector.Add(PreParserIdentifier::Default());
1513 }
1514
1515 return collector.ToVector();
1516 }
1517
1518
1185 template<class Traits> 1519 template<class Traits>
1186 ParserBase<Traits>::FunctionState::FunctionState( 1520 ParserBase<Traits>::FunctionState::FunctionState(
1187 FunctionState** function_state_stack, 1521 FunctionState** function_state_stack,
1188 typename Traits::Type::Scope** scope_stack, 1522 typename Traits::Type::Scope** scope_stack,
1189 typename Traits::Type::Scope* scope, 1523 typename Traits::Type::Scope* scope,
1190 typename Traits::Type::Zone* extra_param, 1524 typename Traits::Type::Zone* extra_param,
1191 AstValueFactory* ast_value_factory) 1525 AstValueFactory* ast_value_factory)
1192 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize), 1526 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1193 next_handler_index_(0), 1527 next_handler_index_(0),
1194 expected_property_count_(0), 1528 expected_property_count_(0),
1195 is_generator_(false), 1529 is_generator_(false),
1196 generator_object_variable_(NULL), 1530 generator_object_variable_(NULL),
1197 function_state_stack_(function_state_stack), 1531 function_state_stack_(function_state_stack),
1198 outer_function_state_(*function_state_stack), 1532 outer_function_state_(*function_state_stack),
1199 scope_stack_(scope_stack), 1533 scope_stack_(scope_stack),
1200 outer_scope_(*scope_stack), 1534 outer_scope_(*scope_stack),
1201 saved_ast_node_id_(0), 1535 saved_ast_node_id_(0),
1202 extra_param_(extra_param), 1536 extra_param_(extra_param),
1203 factory_(extra_param, ast_value_factory) { 1537 factory_(extra_param, ast_value_factory) {
1204 *scope_stack_ = scope; 1538 *scope_stack_ = scope;
1205 *function_state_stack = this; 1539 *function_state_stack = this;
1206 Traits::SetUpFunctionState(this, extra_param); 1540 Traits::SetUpFunctionState(this, extra_param);
1207 } 1541 }
1208 1542
1209 1543
1210 template<class Traits> 1544 template<class Traits>
1545 ParserBase<Traits>::FunctionState::FunctionState(
1546 FunctionState** function_state_stack,
1547 typename Traits::Type::Scope** scope_stack,
1548 typename Traits::Type::Scope** scope,
1549 typename Traits::Type::Zone* extra_param,
1550 AstValueFactory* ast_value_factory)
1551 : next_materialized_literal_index_(JSFunction::kLiteralsPrefixSize),
1552 next_handler_index_(0),
1553 expected_property_count_(0),
1554 is_generator_(false),
1555 generator_object_variable_(NULL),
1556 function_state_stack_(function_state_stack),
1557 outer_function_state_(*function_state_stack),
1558 scope_stack_(scope_stack),
1559 outer_scope_(*scope_stack),
1560 saved_ast_node_id_(0),
1561 extra_param_(extra_param),
1562 factory_(extra_param, ast_value_factory) {
1563 *scope_stack_ = *scope;
1564 *function_state_stack = this;
1565 Traits::SetUpFunctionState(this, extra_param);
1566 }
1567
1568
1569 template<class Traits>
1211 ParserBase<Traits>::FunctionState::~FunctionState() { 1570 ParserBase<Traits>::FunctionState::~FunctionState() {
1212 *scope_stack_ = outer_scope_; 1571 *scope_stack_ = outer_scope_;
1213 *function_state_stack_ = outer_function_state_; 1572 *function_state_stack_ = outer_function_state_;
1214 Traits::TearDownFunctionState(this, extra_param_); 1573 Traits::TearDownFunctionState(this, extra_param_);
1215 } 1574 }
1216 1575
1217 1576
1218 template<class Traits> 1577 template<class Traits>
1219 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) { 1578 void ParserBase<Traits>::ReportUnexpectedToken(Token::Value token) {
1220 Scanner::Location source_location = scanner()->location(); 1579 Scanner::Location source_location = scanner()->location();
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after
1367 // ObjectLiteral 1726 // ObjectLiteral
1368 // RegExpLiteral 1727 // RegExpLiteral
1369 // '(' Expression ')' 1728 // '(' Expression ')'
1370 1729
1371 int pos = peek_position(); 1730 int pos = peek_position();
1372 ExpressionT result = this->EmptyExpression(); 1731 ExpressionT result = this->EmptyExpression();
1373 Token::Value token = peek(); 1732 Token::Value token = peek();
1374 switch (token) { 1733 switch (token) {
1375 case Token::THIS: { 1734 case Token::THIS: {
1376 Consume(Token::THIS); 1735 Consume(Token::THIS);
1377 result = this->ThisExpression(scope_, factory()); 1736 result = this->ThisExpression(scope_, factory(), position());
1378 break; 1737 break;
1379 } 1738 }
1380 1739
1381 case Token::NULL_LITERAL: 1740 case Token::NULL_LITERAL:
1382 case Token::TRUE_LITERAL: 1741 case Token::TRUE_LITERAL:
1383 case Token::FALSE_LITERAL: 1742 case Token::FALSE_LITERAL:
1384 case Token::NUMBER: 1743 case Token::NUMBER:
1385 Next(); 1744 Next();
1386 result = this->ExpressionFromLiteral(token, pos, scanner(), factory()); 1745 result = this->ExpressionFromLiteral(token, pos, scanner(), factory());
1387 break; 1746 break;
(...skipping 24 matching lines...) Expand all
1412 case Token::LBRACK: 1771 case Token::LBRACK:
1413 result = this->ParseArrayLiteral(CHECK_OK); 1772 result = this->ParseArrayLiteral(CHECK_OK);
1414 break; 1773 break;
1415 1774
1416 case Token::LBRACE: 1775 case Token::LBRACE:
1417 result = this->ParseObjectLiteral(CHECK_OK); 1776 result = this->ParseObjectLiteral(CHECK_OK);
1418 break; 1777 break;
1419 1778
1420 case Token::LPAREN: 1779 case Token::LPAREN:
1421 Consume(Token::LPAREN); 1780 Consume(Token::LPAREN);
1422 // Heuristically try to detect immediately called functions before 1781 if (allow_arrow_functions() && peek() == Token::RPAREN) {
1423 // seeing the call parentheses. 1782 // Arrow functions are the only expression type constructions
1424 parenthesized_function_ = (peek() == Token::FUNCTION); 1783 // for which an empty parameter list "()" is valid input.
1425 result = this->ParseExpression(true, CHECK_OK); 1784 Consume(Token::RPAREN);
1426 Expect(Token::RPAREN, CHECK_OK); 1785 return this->ParseArrowFunctionLiteral(pos,
1786 this->EmptyExpression(),
1787 CHECK_OK);
1788 } else {
1789 // Heuristically try to detect immediately called functions before
1790 // seeing the call parentheses.
1791 parenthesized_function_ = (peek() == Token::FUNCTION);
1792 result = this->ParseExpression(true, CHECK_OK);
1793 Expect(Token::RPAREN, CHECK_OK);
1794 }
1427 break; 1795 break;
1428 1796
1429 case Token::MOD: 1797 case Token::MOD:
1430 if (allow_natives_syntax() || extension_ != NULL) { 1798 if (allow_natives_syntax() || extension_ != NULL) {
1431 result = this->ParseV8Intrinsic(CHECK_OK); 1799 result = this->ParseV8Intrinsic(CHECK_OK);
1432 break; 1800 break;
1433 } 1801 }
1434 // If we're not allowing special syntax we fall-through to the 1802 // If we're not allowing special syntax we fall-through to the
1435 // default case. 1803 // default case.
1436 1804
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1685 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList)); 2053 Expect(Token::RPAREN, CHECK_OK_CUSTOM(NullExpressionList));
1686 return result; 2054 return result;
1687 } 2055 }
1688 2056
1689 // Precedence = 2 2057 // Precedence = 2
1690 template <class Traits> 2058 template <class Traits>
1691 typename ParserBase<Traits>::ExpressionT 2059 typename ParserBase<Traits>::ExpressionT
1692 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { 2060 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) {
1693 // AssignmentExpression :: 2061 // AssignmentExpression ::
1694 // ConditionalExpression 2062 // ConditionalExpression
2063 // ArrowFunction
1695 // YieldExpression 2064 // YieldExpression
1696 // LeftHandSideExpression AssignmentOperator AssignmentExpression 2065 // LeftHandSideExpression AssignmentOperator AssignmentExpression
1697 2066
1698 Scanner::Location lhs_location = scanner()->peek_location(); 2067 Scanner::Location lhs_location = scanner()->peek_location();
1699 2068
1700 if (peek() == Token::YIELD && is_generator()) { 2069 if (peek() == Token::YIELD && is_generator()) {
1701 return this->ParseYieldExpression(ok); 2070 return this->ParseYieldExpression(ok);
1702 } 2071 }
1703 2072
1704 if (fni_ != NULL) fni_->Enter(); 2073 if (fni_ != NULL) fni_->Enter();
1705 ExpressionT expression = 2074 ExpressionT expression =
1706 this->ParseConditionalExpression(accept_IN, CHECK_OK); 2075 this->ParseConditionalExpression(accept_IN, CHECK_OK);
1707 2076
2077 if (allow_arrow_functions() && peek() == Token::ARROW)
2078 return this->ParseArrowFunctionLiteral(lhs_location.beg_pos,
2079 expression,
2080 CHECK_OK);
2081
1708 if (!Token::IsAssignmentOp(peek())) { 2082 if (!Token::IsAssignmentOp(peek())) {
1709 if (fni_ != NULL) fni_->Leave(); 2083 if (fni_ != NULL) fni_->Leave();
1710 // Parsed conditional expression only (no assignment). 2084 // Parsed conditional expression only (no assignment).
1711 return expression; 2085 return expression;
1712 } 2086 }
1713 2087
1714 expression = this->CheckAndRewriteReferenceExpression( 2088 expression = this->CheckAndRewriteReferenceExpression(
1715 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK); 2089 expression, lhs_location, "invalid_lhs_in_assignment", CHECK_OK);
1716 expression = this->MarkExpressionAsLValue(expression); 2090 expression = this->MarkExpressionAsLValue(expression);
1717 2091
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
2102 } 2476 }
2103 default: 2477 default:
2104 return expression; 2478 return expression;
2105 } 2479 }
2106 } 2480 }
2107 ASSERT(false); 2481 ASSERT(false);
2108 return this->EmptyExpression(); 2482 return this->EmptyExpression();
2109 } 2483 }
2110 2484
2111 2485
2486 template <class Traits>
2487 typename ParserBase<Traits>::ExpressionT
2488 ParserBase<Traits>::ParseArrowFunctionLiteralBody(
2489 FunctionState* function_state,
2490 typename Traits::Type::ScopePtr scope,
2491 int num_parameters,
2492 const Scanner::Location& eval_args_error_loc,
2493 const Scanner::Location& dupe_error_loc,
2494 const Scanner::Location& reserved_loc,
2495 FunctionLiteral::IsParenthesizedFlag parenthesized,
2496 int start_pos,
2497 bool* ok) {
2498
2499 typename Traits::Type::StatementList body;
2500 int materialized_literal_count = -1;
2501 int expected_property_count = -1;
2502
2503 Expect(Token::ARROW, CHECK_OK);
2504
2505 if (peek() == Token::LBRACE) {
2506 // Multiple statemente body
2507 Consume(Token::LBRACE);
2508
2509 bool is_lazily_parsed = (mode() == PARSE_LAZILY &&
2510 scope_->AllowsLazyCompilation() &&
2511 !parenthesized_function_);
2512 parenthesized_function_ = false; // This Was set for this funciton only.
2513
2514 if (is_lazily_parsed) {
2515 this->SkipLazyFunctionBody(this->EmptyIdentifier(),
2516 &materialized_literal_count,
2517 &expected_property_count,
2518 CHECK_OK);
2519 } else {
2520 body = this->ParseEagerFunctionBody(this->EmptyIdentifier(),
2521 RelocInfo::kNoPosition,
2522 NULL,
2523 Token::INIT_VAR,
2524 false, // Not a generator.
2525 CHECK_OK);
2526 }
2527 } else {
2528 // Single-expression body
2529 parenthesized_function_ = false;
2530 ParseAssignmentExpression(true, CHECK_OK);
2531 }
2532
2533 scope->set_start_position(start_pos);
2534 scope->set_end_position(scanner()->location().end_pos);
2535
2536 // Validate strict mode.
2537 if (strict_mode() == STRICT) {
2538 CheckStrictFunctionNameAndParameters(this->EmptyIdentifierString(),
2539 false,
2540 Scanner::Location::invalid(),
2541 eval_args_error_loc,
2542 dupe_error_loc,
2543 reserved_loc,
2544 CHECK_OK);
2545 CheckOctalLiteral(start_pos,
2546 scanner()->location().end_pos,
2547 CHECK_OK);
2548 }
2549
2550 if (allow_harmony_scoping() && strict_mode() == STRICT)
2551 this->CheckConflictingVarDeclarations(scope, CHECK_OK);
2552
2553 return this->EmptyExpression();
2554 }
2555
2556
2557 template <class Traits>
2558 typename ParserBase<Traits>::ExpressionT
2559 ParserBase<Traits>::ParseArrowFunctionLiteral(bool* ok) {
2560 // TODO(aperez): Change this to use ARROW_SCOPE
2561 typename Traits::Type::ScopePtr scope =
2562 this->NewScope(scope_, FUNCTION_SCOPE);
2563
2564 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2565 ? FunctionLiteral::kIsParenthesized
2566 : FunctionLiteral::kNotParenthesized;
2567 parenthesized_function_ = false;
2568
2569 int start_pos = position();
2570 int num_parameters = 0;
2571 FunctionState function_state(&function_state_, &scope_, &scope, zone(),
2572 this->ast_value_factory());
2573
2574 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2575 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2576 Scanner::Location reserved_loc = Scanner::Location::invalid();
2577
2578 if (peek() == Token::LPAREN) {
2579 // Parse a parenthesized parameter list.
2580 Consume(Token::LPAREN);
2581 bool done = (peek() == Token::RPAREN);
2582 while (!done) {
2583 bool is_strict_reserved = false;
2584 IdentifierT param_name =
2585 ParseIdentifierOrStrictReservedWord(&is_strict_reserved,
2586 CHECK_OK);
2587
2588 // Store locations for possible future error reports.
2589 if (!eval_args_error_loc.IsValid() &&
2590 this->IsEvalOrArguments(param_name)) {
2591 eval_args_error_loc = scanner()->location();
2592 }
2593 if (!reserved_loc.IsValid() && is_strict_reserved) {
2594 reserved_loc = scanner()->location();
2595 }
2596 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2597 dupe_error_loc = scanner()->location();
2598 }
2599
2600 scope_->DeclareParameter(param_name, VAR);
2601 num_parameters++;
2602 if (num_parameters > Code::kMaxArguments) {
2603 this->ReportMessageAt(scanner()->location(), "too_many_parameters");
2604 *ok = false;
2605 return this->EmptyExpression();
2606 }
2607 done = (peek() == Token::RPAREN);
2608 if (!done) Expect(Token::COMMA, CHECK_OK);
2609 }
2610 Expect(Token::RPAREN, CHECK_OK);
2611 } else {
2612 // Parse a single parameter identifier.
2613 bool is_strict_reserved = false;
2614 IdentifierT param_name =
2615 ParseIdentifierOrStrictReservedWord(&is_strict_reserved, CHECK_OK);
2616
2617 // Store locations for possible future error reports.
2618 if (this->IsEvalOrArguments(param_name))
2619 eval_args_error_loc = scanner()->location();
2620 if (is_strict_reserved)
2621 reserved_loc = scanner()->location();
2622
2623 scope_->DeclareParameter(param_name, VAR);
2624 }
2625
2626 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state,
2627 scope,
2628 num_parameters,
2629 eval_args_error_loc,
2630 dupe_error_loc,
2631 reserved_loc,
2632 parenthesized,
2633 start_pos,
2634 CHECK_OK);
2635 return literal;
2636 }
2637
2638
2639 template <class Traits>
2640 typename ParserBase<Traits>::ExpressionT
2641 ParserBase<Traits>::ParseArrowFunctionLiteral(int start_pos,
2642 ExpressionT params_ast,
2643 bool* ok) {
2644 // TODO(aperez): Change this to use ARROW_SCOPE
2645 typename Traits::Type::ScopePtr scope =
2646 this->NewScope(scope_, FUNCTION_SCOPE);
2647
2648 FunctionLiteral::IsParenthesizedFlag parenthesized = parenthesized_function_
2649 ? FunctionLiteral::kIsParenthesized
2650 : FunctionLiteral::kNotParenthesized;
2651 parenthesized_function_ = false;
2652
2653 FunctionState function_state(&function_state_, &scope_, &scope, zone(),
2654 this->ast_value_factory());
2655
2656 Scanner::Location eval_args_error_loc = Scanner::Location::invalid();
2657 Scanner::Location dupe_error_loc = Scanner::Location::invalid();
2658 Scanner::Location reserved_loc = Scanner::Location::invalid();
2659
2660 if (!scanner()->parameter_list()->IsValid(start_pos)) {
2661 ReportMessageAt(Scanner::Location(start_pos, position()),
2662 "malformed_parameter_list");
2663 *ok = false;
2664 return this->EmptyExpression();
2665 }
2666
2667 // Function parameters are already parsed into an AST
2668 typename Traits::Type::ParameterIdentifierVector params =
2669 Traits::ParameterListFromExpression(params_ast, CHECK_OK);
2670
2671 if (params.length() > Code::kMaxArguments) {
2672 ReportMessageAt(Scanner::Location(params_ast->position(), position()),
2673 "too_many_parameters");
2674 *ok = false;
2675 return this->EmptyExpression();
2676 }
2677
2678 // The vector has the items in reverse order.
2679 for (int i = params.length() - 1; i >= 0; --i) {
2680 IdentifierT param_name = params.at(i)->raw_name();
2681 int param_pos = params.at(i)->position();
2682
2683 // Store locations for possible future error reports.
2684 if (!eval_args_error_loc.IsValid() && this->IsEvalOrArguments(param_name)) {
2685 eval_args_error_loc =
2686 Scanner::Location(param_pos, param_pos + param_name->length());
2687 }
2688 if (!dupe_error_loc.IsValid() && scope_->IsDeclared(param_name)) {
2689 dupe_error_loc =
2690 Scanner::Location(param_pos, param_pos + param_name->length());
2691 }
2692 if (!reserved_loc.IsValid() && this->IsFutureStrictReserved(param_name)) {
2693 reserved_loc =
2694 Scanner::Location(param_pos, param_pos + param_name->length());
2695 }
2696
2697 scope_->DeclareParameter(param_name, VAR);
2698 }
2699
2700 ExpressionT literal = ParseArrowFunctionLiteralBody(&function_state,
2701 scope,
2702 params.length(),
2703 eval_args_error_loc,
2704 dupe_error_loc,
2705 reserved_loc,
2706 parenthesized,
2707 start_pos,
2708 CHECK_OK);
2709 return literal;
2710 }
2711
2712
2112 template <typename Traits> 2713 template <typename Traits>
2113 typename ParserBase<Traits>::ExpressionT 2714 typename ParserBase<Traits>::ExpressionT
2114 ParserBase<Traits>::CheckAndRewriteReferenceExpression( 2715 ParserBase<Traits>::CheckAndRewriteReferenceExpression(
2115 ExpressionT expression, 2716 ExpressionT expression,
2116 Scanner::Location location, const char* message, bool* ok) { 2717 Scanner::Location location, const char* message, bool* ok) {
2117 if (strict_mode() == STRICT && this->IsIdentifier(expression) && 2718 if (strict_mode() == STRICT && this->IsIdentifier(expression) &&
2118 this->IsEvalOrArguments(this->AsIdentifier(expression))) { 2719 this->IsEvalOrArguments(this->AsIdentifier(expression))) {
2119 this->ReportMessageAt(location, "strict_eval_arguments", false); 2720 this->ReportMessageAt(location, "strict_eval_arguments", false);
2120 *ok = false; 2721 *ok = false;
2121 return this->EmptyExpression(); 2722 return this->EmptyExpression();
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 parser()->ReportMessage("accessor_get_set"); 2766 parser()->ReportMessage("accessor_get_set");
2166 } 2767 }
2167 *ok = false; 2768 *ok = false;
2168 } 2769 }
2169 } 2770 }
2170 2771
2171 2772
2172 } } // v8::internal 2773 } } // v8::internal
2173 2774
2174 #endif // V8_PREPARSER_H 2775 #endif // V8_PREPARSER_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698