| OLD | NEW |
| 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/v8.h" | 8 #include "src/v8.h" |
| 9 | 9 |
| 10 #include "src/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 zone_(zone), | 83 zone_(zone), |
| 84 scanner_(scanner), | 84 scanner_(scanner), |
| 85 stack_overflow_(false), | 85 stack_overflow_(false), |
| 86 allow_lazy_(false), | 86 allow_lazy_(false), |
| 87 allow_natives_(false), | 87 allow_natives_(false), |
| 88 allow_harmony_arrow_functions_(false), | 88 allow_harmony_arrow_functions_(false), |
| 89 allow_harmony_object_literals_(false), | 89 allow_harmony_object_literals_(false), |
| 90 allow_harmony_sloppy_(false), | 90 allow_harmony_sloppy_(false), |
| 91 allow_harmony_computed_property_names_(false), | 91 allow_harmony_computed_property_names_(false), |
| 92 allow_harmony_rest_params_(false), | 92 allow_harmony_rest_params_(false), |
| 93 allow_harmony_spreadcalls_(false), |
| 93 allow_strong_mode_(false) {} | 94 allow_strong_mode_(false) {} |
| 94 | 95 |
| 95 // Getters that indicate whether certain syntactical constructs are | 96 // Getters that indicate whether certain syntactical constructs are |
| 96 // allowed to be parsed by this instance of the parser. | 97 // allowed to be parsed by this instance of the parser. |
| 97 bool allow_lazy() const { return allow_lazy_; } | 98 bool allow_lazy() const { return allow_lazy_; } |
| 98 bool allow_natives() const { return allow_natives_; } | 99 bool allow_natives() const { return allow_natives_; } |
| 99 bool allow_harmony_arrow_functions() const { | 100 bool allow_harmony_arrow_functions() const { |
| 100 return allow_harmony_arrow_functions_; | 101 return allow_harmony_arrow_functions_; |
| 101 } | 102 } |
| 102 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } | 103 bool allow_harmony_modules() const { return scanner()->HarmonyModules(); } |
| 103 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 104 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
| 104 bool allow_harmony_object_literals() const { | 105 bool allow_harmony_object_literals() const { |
| 105 return allow_harmony_object_literals_; | 106 return allow_harmony_object_literals_; |
| 106 } | 107 } |
| 107 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 108 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
| 108 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 109 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
| 109 bool allow_harmony_computed_property_names() const { | 110 bool allow_harmony_computed_property_names() const { |
| 110 return allow_harmony_computed_property_names_; | 111 return allow_harmony_computed_property_names_; |
| 111 } | 112 } |
| 112 bool allow_harmony_rest_params() const { | 113 bool allow_harmony_rest_params() const { |
| 113 return allow_harmony_rest_params_; | 114 return allow_harmony_rest_params_; |
| 114 } | 115 } |
| 116 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } |
| 115 | 117 |
| 116 bool allow_strong_mode() const { return allow_strong_mode_; } | 118 bool allow_strong_mode() const { return allow_strong_mode_; } |
| 117 | 119 |
| 118 // Setters that determine whether certain syntactical constructs are | 120 // Setters that determine whether certain syntactical constructs are |
| 119 // allowed to be parsed by this instance of the parser. | 121 // allowed to be parsed by this instance of the parser. |
| 120 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 122 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
| 121 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 123 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
| 122 void set_allow_harmony_arrow_functions(bool allow) { | 124 void set_allow_harmony_arrow_functions(bool allow) { |
| 123 allow_harmony_arrow_functions_ = allow; | 125 allow_harmony_arrow_functions_ = allow; |
| 124 } | 126 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 136 } | 138 } |
| 137 void set_allow_harmony_unicode(bool allow) { | 139 void set_allow_harmony_unicode(bool allow) { |
| 138 scanner()->SetHarmonyUnicode(allow); | 140 scanner()->SetHarmonyUnicode(allow); |
| 139 } | 141 } |
| 140 void set_allow_harmony_computed_property_names(bool allow) { | 142 void set_allow_harmony_computed_property_names(bool allow) { |
| 141 allow_harmony_computed_property_names_ = allow; | 143 allow_harmony_computed_property_names_ = allow; |
| 142 } | 144 } |
| 143 void set_allow_harmony_rest_params(bool allow) { | 145 void set_allow_harmony_rest_params(bool allow) { |
| 144 allow_harmony_rest_params_ = allow; | 146 allow_harmony_rest_params_ = allow; |
| 145 } | 147 } |
| 148 void set_allow_harmony_spreadcalls(bool allow) { |
| 149 allow_harmony_spreadcalls_ = allow; |
| 150 } |
| 146 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 151 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
| 147 | 152 |
| 148 protected: | 153 protected: |
| 149 enum AllowEvalOrArgumentsAsIdentifier { | 154 enum AllowEvalOrArgumentsAsIdentifier { |
| 150 kAllowEvalOrArguments, | 155 kAllowEvalOrArguments, |
| 151 kDontAllowEvalOrArguments | 156 kDontAllowEvalOrArguments |
| 152 }; | 157 }; |
| 153 | 158 |
| 154 enum Mode { | 159 enum Mode { |
| 155 PARSE_LAZILY, | 160 PARSE_LAZILY, |
| (...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 572 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 568 ExpressionT ParseArrayLiteral(bool* ok); | 573 ExpressionT ParseArrayLiteral(bool* ok); |
| 569 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 574 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 570 bool* is_static, bool* is_computed_name, | 575 bool* is_static, bool* is_computed_name, |
| 571 bool* ok); | 576 bool* ok); |
| 572 ExpressionT ParseObjectLiteral(bool* ok); | 577 ExpressionT ParseObjectLiteral(bool* ok); |
| 573 ObjectLiteralPropertyT ParsePropertyDefinition( | 578 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 574 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 579 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 575 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 580 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 576 bool* ok); | 581 bool* ok); |
| 577 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 582 typename Traits::Type::ExpressionList ParseArguments( |
| 583 Scanner::Location* first_spread_pos, bool* ok); |
| 578 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 584 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 579 ExpressionT ParseYieldExpression(bool* ok); | 585 ExpressionT ParseYieldExpression(bool* ok); |
| 580 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 586 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 581 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 587 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 582 ExpressionT ParseUnaryExpression(bool* ok); | 588 ExpressionT ParseUnaryExpression(bool* ok); |
| 583 ExpressionT ParsePostfixExpression(bool* ok); | 589 ExpressionT ParsePostfixExpression(bool* ok); |
| 584 ExpressionT ParseLeftHandSideExpression(bool* ok); | 590 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 585 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 591 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 586 ExpressionT ParseMemberExpression(bool* ok); | 592 ExpressionT ParseMemberExpression(bool* ok); |
| 587 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 593 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 Scanner* scanner_; | 685 Scanner* scanner_; |
| 680 bool stack_overflow_; | 686 bool stack_overflow_; |
| 681 | 687 |
| 682 bool allow_lazy_; | 688 bool allow_lazy_; |
| 683 bool allow_natives_; | 689 bool allow_natives_; |
| 684 bool allow_harmony_arrow_functions_; | 690 bool allow_harmony_arrow_functions_; |
| 685 bool allow_harmony_object_literals_; | 691 bool allow_harmony_object_literals_; |
| 686 bool allow_harmony_sloppy_; | 692 bool allow_harmony_sloppy_; |
| 687 bool allow_harmony_computed_property_names_; | 693 bool allow_harmony_computed_property_names_; |
| 688 bool allow_harmony_rest_params_; | 694 bool allow_harmony_rest_params_; |
| 695 bool allow_harmony_spreadcalls_; |
| 689 bool allow_strong_mode_; | 696 bool allow_strong_mode_; |
| 690 }; | 697 }; |
| 691 | 698 |
| 692 | 699 |
| 693 class PreParserIdentifier { | 700 class PreParserIdentifier { |
| 694 public: | 701 public: |
| 695 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 702 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 696 static PreParserIdentifier Default() { | 703 static PreParserIdentifier Default() { |
| 697 return PreParserIdentifier(kUnknownIdentifier); | 704 return PreParserIdentifier(kUnknownIdentifier); |
| 698 } | 705 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 friend class PreParserExpression; | 778 friend class PreParserExpression; |
| 772 }; | 779 }; |
| 773 | 780 |
| 774 | 781 |
| 775 class PreParserExpression { | 782 class PreParserExpression { |
| 776 public: | 783 public: |
| 777 static PreParserExpression Default() { | 784 static PreParserExpression Default() { |
| 778 return PreParserExpression(TypeField::encode(kExpression)); | 785 return PreParserExpression(TypeField::encode(kExpression)); |
| 779 } | 786 } |
| 780 | 787 |
| 788 static PreParserExpression Spread(PreParserExpression expression) { |
| 789 return PreParserExpression(TypeField::encode(kSpreadExpression)); |
| 790 } |
| 791 |
| 781 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 792 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
| 782 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 793 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
| 783 IdentifierTypeField::encode(id.type_)); | 794 IdentifierTypeField::encode(id.type_)); |
| 784 } | 795 } |
| 785 | 796 |
| 786 static PreParserExpression BinaryOperation(PreParserExpression left, | 797 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 787 Token::Value op, | 798 Token::Value op, |
| 788 PreParserExpression right) { | 799 PreParserExpression right) { |
| 789 bool valid_arrow_param_list = | 800 bool valid_arrow_param_list = |
| 790 op == Token::COMMA && !left.is_parenthesized() && | 801 op == Token::COMMA && !left.is_parenthesized() && |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 | 910 |
| 900 // At the moment PreParser doesn't track these expression types. | 911 // At the moment PreParser doesn't track these expression types. |
| 901 bool IsFunctionLiteral() const { return false; } | 912 bool IsFunctionLiteral() const { return false; } |
| 902 bool IsCallNew() const { return false; } | 913 bool IsCallNew() const { return false; } |
| 903 | 914 |
| 904 bool IsNoTemplateTag() const { | 915 bool IsNoTemplateTag() const { |
| 905 return TypeField::decode(code_) == kExpression && | 916 return TypeField::decode(code_) == kExpression && |
| 906 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 917 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
| 907 } | 918 } |
| 908 | 919 |
| 920 bool IsSpreadExpression() const { |
| 921 return TypeField::decode(code_) == kSpreadExpression; |
| 922 } |
| 923 |
| 909 PreParserExpression AsFunctionLiteral() { return *this; } | 924 PreParserExpression AsFunctionLiteral() { return *this; } |
| 910 | 925 |
| 911 bool IsBinaryOperation() const { | 926 bool IsBinaryOperation() const { |
| 912 return TypeField::decode(code_) == kBinaryOperationExpression; | 927 return TypeField::decode(code_) == kBinaryOperationExpression; |
| 913 } | 928 } |
| 914 | 929 |
| 915 bool is_parenthesized() const { | 930 bool is_parenthesized() const { |
| 916 return ParenthesizationField::decode(code_) != kNotParenthesized; | 931 return ParenthesizationField::decode(code_) != kNotParenthesized; |
| 917 } | 932 } |
| 918 | 933 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 931 void set_parenthesized() {} | 946 void set_parenthesized() {} |
| 932 | 947 |
| 933 int position() const { return RelocInfo::kNoPosition; } | 948 int position() const { return RelocInfo::kNoPosition; } |
| 934 void set_function_token_position(int position) {} | 949 void set_function_token_position(int position) {} |
| 935 | 950 |
| 936 private: | 951 private: |
| 937 enum Type { | 952 enum Type { |
| 938 kExpression, | 953 kExpression, |
| 939 kIdentifierExpression, | 954 kIdentifierExpression, |
| 940 kStringLiteralExpression, | 955 kStringLiteralExpression, |
| 941 kBinaryOperationExpression | 956 kBinaryOperationExpression, |
| 957 kSpreadExpression |
| 942 }; | 958 }; |
| 943 | 959 |
| 944 enum Parenthesization { | 960 enum Parenthesization { |
| 945 kNotParenthesized, | 961 kNotParenthesized, |
| 946 kParanthesizedExpression, | 962 kParanthesizedExpression, |
| 947 kMultiParenthesizedExpression | 963 kMultiParenthesizedExpression |
| 948 }; | 964 }; |
| 949 | 965 |
| 950 enum ExpressionType { | 966 enum ExpressionType { |
| 951 kThisExpression, | 967 kThisExpression, |
| 952 kThisPropertyExpression, | 968 kThisPropertyExpression, |
| 953 kPropertyExpression, | 969 kPropertyExpression, |
| 954 kCallExpression, | 970 kCallExpression, |
| 955 kNoTemplateTagExpression | 971 kNoTemplateTagExpression |
| 956 }; | 972 }; |
| 957 | 973 |
| 958 explicit PreParserExpression(uint32_t expression_code) | 974 explicit PreParserExpression(uint32_t expression_code) |
| 959 : code_(expression_code) {} | 975 : code_(expression_code) {} |
| 960 | 976 |
| 961 V8_INLINE bool IsValidArrowParams() const { | 977 V8_INLINE bool IsValidArrowParams() const { |
| 962 return IsBinaryOperation() | 978 return IsBinaryOperation() |
| 963 ? IsValidArrowParamListField::decode(code_) | 979 ? IsValidArrowParamListField::decode(code_) |
| 964 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 980 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); |
| 965 } | 981 } |
| 966 | 982 |
| 967 // The first four bits are for the Type and Parenthesization. | 983 // The first five bits are for the Type and Parenthesization. |
| 968 typedef BitField<Type, 0, 2> TypeField; | 984 typedef BitField<Type, 0, 3> TypeField; |
| 969 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 985 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
| 970 | 986 |
| 971 // The rest of the bits are interpreted depending on the value | 987 // The rest of the bits are interpreted depending on the value |
| 972 // of the Type field, so they can share the storage. | 988 // of the Type field, so they can share the storage. |
| 973 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 989 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
| 974 ExpressionTypeField; | 990 ExpressionTypeField; |
| 975 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 991 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
| 976 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 992 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 977 typedef BitField<bool, ParenthesizationField::kNext, 1> | 993 typedef BitField<bool, ParenthesizationField::kNext, 1> |
| 978 IsValidArrowParamListField; | 994 IsValidArrowParamListField; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1159 PreParserExpression NewCall(PreParserExpression expression, | 1175 PreParserExpression NewCall(PreParserExpression expression, |
| 1160 PreParserExpressionList arguments, | 1176 PreParserExpressionList arguments, |
| 1161 int pos) { | 1177 int pos) { |
| 1162 return PreParserExpression::Call(); | 1178 return PreParserExpression::Call(); |
| 1163 } | 1179 } |
| 1164 PreParserExpression NewCallNew(PreParserExpression expression, | 1180 PreParserExpression NewCallNew(PreParserExpression expression, |
| 1165 PreParserExpressionList arguments, | 1181 PreParserExpressionList arguments, |
| 1166 int pos) { | 1182 int pos) { |
| 1167 return PreParserExpression::Default(); | 1183 return PreParserExpression::Default(); |
| 1168 } | 1184 } |
| 1185 PreParserExpression NewCallRuntime(const AstRawString* name, |
| 1186 const Runtime::Function* function, |
| 1187 PreParserExpressionList arguments, |
| 1188 int pos) { |
| 1189 return PreParserExpression::Default(); |
| 1190 } |
| 1169 PreParserStatement NewReturnStatement(PreParserExpression expression, | 1191 PreParserStatement NewReturnStatement(PreParserExpression expression, |
| 1170 int pos) { | 1192 int pos) { |
| 1171 return PreParserStatement::Default(); | 1193 return PreParserStatement::Default(); |
| 1172 } | 1194 } |
| 1173 PreParserExpression NewFunctionLiteral( | 1195 PreParserExpression NewFunctionLiteral( |
| 1174 PreParserIdentifier name, AstValueFactory* ast_value_factory, | 1196 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
| 1175 Scope* scope, PreParserStatementList body, int materialized_literal_count, | 1197 Scope* scope, PreParserStatementList body, int materialized_literal_count, |
| 1176 int expected_property_count, int handler_count, int parameter_count, | 1198 int expected_property_count, int handler_count, int parameter_count, |
| 1177 FunctionLiteral::ParameterFlag has_duplicate_parameters, | 1199 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
| 1178 FunctionLiteral::FunctionType function_type, | 1200 FunctionLiteral::FunctionType function_type, |
| 1179 FunctionLiteral::IsFunctionFlag is_function, | 1201 FunctionLiteral::IsFunctionFlag is_function, |
| 1180 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, | 1202 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, |
| 1181 int position) { | 1203 int position) { |
| 1182 return PreParserExpression::Default(); | 1204 return PreParserExpression::Default(); |
| 1183 } | 1205 } |
| 1184 | 1206 |
| 1207 PreParserExpression NewSpread(PreParserExpression expression, int pos) { |
| 1208 return PreParserExpression::Spread(expression); |
| 1209 } |
| 1210 |
| 1185 // Return the object itself as AstVisitor and implement the needed | 1211 // Return the object itself as AstVisitor and implement the needed |
| 1186 // dummy method right in this class. | 1212 // dummy method right in this class. |
| 1187 PreParserFactory* visitor() { return this; } | 1213 PreParserFactory* visitor() { return this; } |
| 1188 int* ast_properties() { | 1214 int* ast_properties() { |
| 1189 static int dummy = 42; | 1215 static int dummy = 42; |
| 1190 return &dummy; | 1216 return &dummy; |
| 1191 } | 1217 } |
| 1192 }; | 1218 }; |
| 1193 | 1219 |
| 1194 | 1220 |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1487 PreParserIdentifier name, Scanner::Location function_name_location, | 1513 PreParserIdentifier name, Scanner::Location function_name_location, |
| 1488 bool name_is_strict_reserved, FunctionKind kind, | 1514 bool name_is_strict_reserved, FunctionKind kind, |
| 1489 int function_token_position, FunctionLiteral::FunctionType type, | 1515 int function_token_position, FunctionLiteral::FunctionType type, |
| 1490 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1516 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
| 1491 | 1517 |
| 1492 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1518 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
| 1493 Scanner::Location class_name_location, | 1519 Scanner::Location class_name_location, |
| 1494 bool name_is_strict_reserved, int pos, | 1520 bool name_is_strict_reserved, int pos, |
| 1495 bool* ok); | 1521 bool* ok); |
| 1496 | 1522 |
| 1523 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { |
| 1524 return list; |
| 1525 } |
| 1526 |
| 1527 inline void MaterializeUnspreadArgumentsLiterals(int count); |
| 1528 |
| 1529 inline PreParserExpression SpreadCall(PreParserExpression function, |
| 1530 PreParserExpressionList args, int pos); |
| 1531 |
| 1532 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
| 1533 PreParserExpressionList args, |
| 1534 int pos); |
| 1535 |
| 1497 private: | 1536 private: |
| 1498 PreParser* pre_parser_; | 1537 PreParser* pre_parser_; |
| 1499 }; | 1538 }; |
| 1500 | 1539 |
| 1501 | 1540 |
| 1502 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1541 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 1503 // a later parsing to be faster. | 1542 // a later parsing to be faster. |
| 1504 // See preparse-data-format.h for the data format. | 1543 // See preparse-data-format.h for the data format. |
| 1505 | 1544 |
| 1506 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1545 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1627 bool* ok); | 1666 bool* ok); |
| 1628 }; | 1667 }; |
| 1629 | 1668 |
| 1630 | 1669 |
| 1631 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { | 1670 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { |
| 1632 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1671 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
| 1633 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1672 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
| 1634 } | 1673 } |
| 1635 | 1674 |
| 1636 | 1675 |
| 1676 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { |
| 1677 for (int i = 0; i < count; ++i) { |
| 1678 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
| 1679 } |
| 1680 } |
| 1681 |
| 1682 |
| 1683 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, |
| 1684 PreParserExpressionList args, |
| 1685 int pos) { |
| 1686 return pre_parser_->factory()->NewCall(function, args, pos); |
| 1687 } |
| 1688 |
| 1689 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
| 1690 PreParserExpressionList args, |
| 1691 int pos) { |
| 1692 return pre_parser_->factory()->NewCallNew(function, args, pos); |
| 1693 } |
| 1694 |
| 1695 |
| 1637 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1696 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1638 PreParserIdentifier function_name, int pos, Variable* fvar, | 1697 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1639 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1698 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
| 1640 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1699 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1641 | 1700 |
| 1642 ParseStatementList(Token::RBRACE, ok); | 1701 ParseStatementList(Token::RBRACE, ok); |
| 1643 if (!*ok) return PreParserStatementList(); | 1702 if (!*ok) return PreParserStatementList(); |
| 1644 | 1703 |
| 1645 Expect(Token::RBRACE, ok); | 1704 Expect(Token::RBRACE, ok); |
| 1646 return PreParserStatementList(); | 1705 return PreParserStatementList(); |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2296 return factory()->NewObjectLiteral(properties, | 2355 return factory()->NewObjectLiteral(properties, |
| 2297 literal_index, | 2356 literal_index, |
| 2298 number_of_boilerplate_properties, | 2357 number_of_boilerplate_properties, |
| 2299 has_function, | 2358 has_function, |
| 2300 pos); | 2359 pos); |
| 2301 } | 2360 } |
| 2302 | 2361 |
| 2303 | 2362 |
| 2304 template <class Traits> | 2363 template <class Traits> |
| 2305 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2364 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| 2306 bool* ok) { | 2365 Scanner::Location* first_spread_arg_loc, bool* ok) { |
| 2307 // Arguments :: | 2366 // Arguments :: |
| 2308 // '(' (AssignmentExpression)*[','] ')' | 2367 // '(' (AssignmentExpression)*[','] ')' |
| 2309 | 2368 |
| 2369 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 2310 typename Traits::Type::ExpressionList result = | 2370 typename Traits::Type::ExpressionList result = |
| 2311 this->NewExpressionList(4, zone_); | 2371 this->NewExpressionList(4, zone_); |
| 2312 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2372 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2313 bool done = (peek() == Token::RPAREN); | 2373 bool done = (peek() == Token::RPAREN); |
| 2374 bool was_unspread = false; |
| 2375 int unspread_sequences_count = 0; |
| 2314 while (!done) { | 2376 while (!done) { |
| 2377 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); |
| 2378 int start_pos = peek_position(); |
| 2379 if (is_spread) Consume(Token::ELLIPSIS); |
| 2380 |
| 2315 ExpressionT argument = this->ParseAssignmentExpression( | 2381 ExpressionT argument = this->ParseAssignmentExpression( |
| 2316 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2382 true, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2383 if (is_spread) { |
| 2384 if (!spread_arg.IsValid()) { |
| 2385 spread_arg.beg_pos = start_pos; |
| 2386 spread_arg.end_pos = peek_position(); |
| 2387 } |
| 2388 argument = factory()->NewSpread(argument, start_pos); |
| 2389 } |
| 2317 result->Add(argument, zone_); | 2390 result->Add(argument, zone_); |
| 2391 |
| 2392 // unspread_sequences_count is the number of sequences of parameters which |
| 2393 // are not prefixed with a spread '...' operator. |
| 2394 if (is_spread) { |
| 2395 was_unspread = false; |
| 2396 } else if (!was_unspread) { |
| 2397 was_unspread = true; |
| 2398 unspread_sequences_count++; |
| 2399 } |
| 2400 |
| 2318 if (result->length() > Code::kMaxArguments) { | 2401 if (result->length() > Code::kMaxArguments) { |
| 2319 ReportMessage("too_many_arguments"); | 2402 ReportMessage("too_many_arguments"); |
| 2320 *ok = false; | 2403 *ok = false; |
| 2321 return this->NullExpressionList(); | 2404 return this->NullExpressionList(); |
| 2322 } | 2405 } |
| 2323 done = (peek() != Token::COMMA); | 2406 done = (peek() != Token::COMMA); |
| 2324 if (!done) { | 2407 if (!done) { |
| 2325 Next(); | 2408 Next(); |
| 2326 } | 2409 } |
| 2327 } | 2410 } |
| 2328 Scanner::Location location = scanner_->location(); | 2411 Scanner::Location location = scanner_->location(); |
| 2329 if (Token::RPAREN != Next()) { | 2412 if (Token::RPAREN != Next()) { |
| 2330 ReportMessageAt(location, "unterminated_arg_list"); | 2413 ReportMessageAt(location, "unterminated_arg_list"); |
| 2331 *ok = false; | 2414 *ok = false; |
| 2332 return this->NullExpressionList(); | 2415 return this->NullExpressionList(); |
| 2333 } | 2416 } |
| 2417 *first_spread_arg_loc = spread_arg; |
| 2418 |
| 2419 if (spread_arg.IsValid()) { |
| 2420 // Unspread parameter sequences are translated into array literals in the |
| 2421 // parser. Ensure that the number of materialized literals matches between |
| 2422 // the parser and preparser |
| 2423 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2424 } |
| 2425 |
| 2334 return result; | 2426 return result; |
| 2335 } | 2427 } |
| 2336 | 2428 |
| 2337 // Precedence = 2 | 2429 // Precedence = 2 |
| 2338 template <class Traits> | 2430 template <class Traits> |
| 2339 typename ParserBase<Traits>::ExpressionT | 2431 typename ParserBase<Traits>::ExpressionT |
| 2340 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2432 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2341 // AssignmentExpression :: | 2433 // AssignmentExpression :: |
| 2342 // ConditionalExpression | 2434 // ConditionalExpression |
| 2343 // ArrowFunction | 2435 // ArrowFunction |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2638 // should not point to the closing brace otherwise it will intersect | 2730 // should not point to the closing brace otherwise it will intersect |
| 2639 // with positions recorded for function literal and confuse debugger. | 2731 // with positions recorded for function literal and confuse debugger. |
| 2640 pos = peek_position(); | 2732 pos = peek_position(); |
| 2641 // Also the trailing parenthesis are a hint that the function will | 2733 // Also the trailing parenthesis are a hint that the function will |
| 2642 // be called immediately. If we happen to have parsed a preceding | 2734 // be called immediately. If we happen to have parsed a preceding |
| 2643 // function literal eagerly, we can also compile it eagerly. | 2735 // function literal eagerly, we can also compile it eagerly. |
| 2644 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2736 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2645 result->AsFunctionLiteral()->set_parenthesized(); | 2737 result->AsFunctionLiteral()->set_parenthesized(); |
| 2646 } | 2738 } |
| 2647 } | 2739 } |
| 2648 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); | 2740 Scanner::Location spread_pos; |
| 2741 typename Traits::Type::ExpressionList args = |
| 2742 ParseArguments(&spread_pos, CHECK_OK); |
| 2649 | 2743 |
| 2650 // Keep track of eval() calls since they disable all local variable | 2744 // Keep track of eval() calls since they disable all local variable |
| 2651 // optimizations. | 2745 // optimizations. |
| 2652 // The calls that need special treatment are the | 2746 // The calls that need special treatment are the |
| 2653 // direct eval calls. These calls are all of the form eval(...), with | 2747 // direct eval calls. These calls are all of the form eval(...), with |
| 2654 // no explicit receiver. | 2748 // no explicit receiver. |
| 2655 // These calls are marked as potentially direct eval calls. Whether | 2749 // These calls are marked as potentially direct eval calls. Whether |
| 2656 // they are actually direct calls to eval is determined at run time. | 2750 // they are actually direct calls to eval is determined at run time. |
| 2657 this->CheckPossibleEvalCall(result, scope_); | 2751 this->CheckPossibleEvalCall(result, scope_); |
| 2658 result = factory()->NewCall(result, args, pos); | 2752 |
| 2753 if (spread_pos.IsValid()) { |
| 2754 args = Traits::PrepareSpreadArguments(args); |
| 2755 result = Traits::SpreadCall(result, args, pos); |
| 2756 } else { |
| 2757 result = factory()->NewCall(result, args, pos); |
| 2758 } |
| 2659 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2759 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 2660 break; | 2760 break; |
| 2661 } | 2761 } |
| 2662 | 2762 |
| 2663 case Token::PERIOD: { | 2763 case Token::PERIOD: { |
| 2664 Consume(Token::PERIOD); | 2764 Consume(Token::PERIOD); |
| 2665 int pos = position(); | 2765 int pos = position(); |
| 2666 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2766 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 2667 result = factory()->NewProperty( | 2767 result = factory()->NewProperty( |
| 2668 result, factory()->NewStringLiteral(name, pos), pos); | 2768 result, factory()->NewStringLiteral(name, pos), pos); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2702 int new_pos = position(); | 2802 int new_pos = position(); |
| 2703 ExpressionT result = this->EmptyExpression(); | 2803 ExpressionT result = this->EmptyExpression(); |
| 2704 if (peek() == Token::SUPER) { | 2804 if (peek() == Token::SUPER) { |
| 2705 const bool is_new = true; | 2805 const bool is_new = true; |
| 2706 result = ParseSuperExpression(is_new, CHECK_OK); | 2806 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2707 } else { | 2807 } else { |
| 2708 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2808 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| 2709 } | 2809 } |
| 2710 if (peek() == Token::LPAREN) { | 2810 if (peek() == Token::LPAREN) { |
| 2711 // NewExpression with arguments. | 2811 // NewExpression with arguments. |
| 2812 Scanner::Location spread_pos; |
| 2712 typename Traits::Type::ExpressionList args = | 2813 typename Traits::Type::ExpressionList args = |
| 2713 this->ParseArguments(CHECK_OK); | 2814 this->ParseArguments(&spread_pos, CHECK_OK); |
| 2714 result = factory()->NewCallNew(result, args, new_pos); | 2815 |
| 2816 if (spread_pos.IsValid()) { |
| 2817 args = Traits::PrepareSpreadArguments(args); |
| 2818 result = Traits::SpreadCallNew(result, args, new_pos); |
| 2819 } else { |
| 2820 result = factory()->NewCallNew(result, args, new_pos); |
| 2821 } |
| 2715 // The expression can still continue with . or [ after the arguments. | 2822 // The expression can still continue with . or [ after the arguments. |
| 2716 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2823 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
| 2717 return result; | 2824 return result; |
| 2718 } | 2825 } |
| 2719 // NewExpression without arguments. | 2826 // NewExpression without arguments. |
| 2720 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2827 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
| 2721 new_pos); | 2828 new_pos); |
| 2722 } | 2829 } |
| 2723 // No 'new' or 'super' keyword. | 2830 // No 'new' or 'super' keyword. |
| 2724 return this->ParseMemberExpression(ok); | 2831 return this->ParseMemberExpression(ok); |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3155 *ok = false; | 3262 *ok = false; |
| 3156 return; | 3263 return; |
| 3157 } | 3264 } |
| 3158 has_seen_constructor_ = true; | 3265 has_seen_constructor_ = true; |
| 3159 return; | 3266 return; |
| 3160 } | 3267 } |
| 3161 } | 3268 } |
| 3162 } } // v8::internal | 3269 } } // v8::internal |
| 3163 | 3270 |
| 3164 #endif // V8_PREPARSER_H | 3271 #endif // V8_PREPARSER_H |
| OLD | NEW |