| 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_numeric_literals() const { | 104 bool allow_harmony_numeric_literals() const { |
| 104 return scanner()->HarmonyNumericLiterals(); | 105 return scanner()->HarmonyNumericLiterals(); |
| 105 } | 106 } |
| 106 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } | 107 bool allow_harmony_classes() const { return scanner()->HarmonyClasses(); } |
| 107 bool allow_harmony_object_literals() const { | 108 bool allow_harmony_object_literals() const { |
| 108 return allow_harmony_object_literals_; | 109 return allow_harmony_object_literals_; |
| 109 } | 110 } |
| 110 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } | 111 bool allow_harmony_sloppy() const { return allow_harmony_sloppy_; } |
| 111 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } | 112 bool allow_harmony_unicode() const { return scanner()->HarmonyUnicode(); } |
| 112 bool allow_harmony_computed_property_names() const { | 113 bool allow_harmony_computed_property_names() const { |
| 113 return allow_harmony_computed_property_names_; | 114 return allow_harmony_computed_property_names_; |
| 114 } | 115 } |
| 115 bool allow_harmony_rest_params() const { | 116 bool allow_harmony_rest_params() const { |
| 116 return allow_harmony_rest_params_; | 117 return allow_harmony_rest_params_; |
| 117 } | 118 } |
| 119 bool allow_harmony_spreadcalls() const { return allow_harmony_spreadcalls_; } |
| 118 | 120 |
| 119 bool allow_strong_mode() const { return allow_strong_mode_; } | 121 bool allow_strong_mode() const { return allow_strong_mode_; } |
| 120 | 122 |
| 121 // Setters that determine whether certain syntactical constructs are | 123 // Setters that determine whether certain syntactical constructs are |
| 122 // allowed to be parsed by this instance of the parser. | 124 // allowed to be parsed by this instance of the parser. |
| 123 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } | 125 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } |
| 124 void set_allow_natives(bool allow) { allow_natives_ = allow; } | 126 void set_allow_natives(bool allow) { allow_natives_ = allow; } |
| 125 void set_allow_harmony_arrow_functions(bool allow) { | 127 void set_allow_harmony_arrow_functions(bool allow) { |
| 126 allow_harmony_arrow_functions_ = allow; | 128 allow_harmony_arrow_functions_ = allow; |
| 127 } | 129 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 142 } | 144 } |
| 143 void set_allow_harmony_unicode(bool allow) { | 145 void set_allow_harmony_unicode(bool allow) { |
| 144 scanner()->SetHarmonyUnicode(allow); | 146 scanner()->SetHarmonyUnicode(allow); |
| 145 } | 147 } |
| 146 void set_allow_harmony_computed_property_names(bool allow) { | 148 void set_allow_harmony_computed_property_names(bool allow) { |
| 147 allow_harmony_computed_property_names_ = allow; | 149 allow_harmony_computed_property_names_ = allow; |
| 148 } | 150 } |
| 149 void set_allow_harmony_rest_params(bool allow) { | 151 void set_allow_harmony_rest_params(bool allow) { |
| 150 allow_harmony_rest_params_ = allow; | 152 allow_harmony_rest_params_ = allow; |
| 151 } | 153 } |
| 154 void set_allow_harmony_spreadcalls(bool allow) { |
| 155 allow_harmony_spreadcalls_ = allow; |
| 156 } |
| 152 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } | 157 void set_allow_strong_mode(bool allow) { allow_strong_mode_ = allow; } |
| 153 | 158 |
| 154 protected: | 159 protected: |
| 155 enum AllowEvalOrArgumentsAsIdentifier { | 160 enum AllowEvalOrArgumentsAsIdentifier { |
| 156 kAllowEvalOrArguments, | 161 kAllowEvalOrArguments, |
| 157 kDontAllowEvalOrArguments | 162 kDontAllowEvalOrArguments |
| 158 }; | 163 }; |
| 159 | 164 |
| 160 enum Mode { | 165 enum Mode { |
| 161 PARSE_LAZILY, | 166 PARSE_LAZILY, |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 576 ExpressionT ParseExpression(bool accept_IN, bool* ok); | 581 ExpressionT ParseExpression(bool accept_IN, bool* ok); |
| 577 ExpressionT ParseArrayLiteral(bool* ok); | 582 ExpressionT ParseArrayLiteral(bool* ok); |
| 578 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, | 583 ExpressionT ParsePropertyName(IdentifierT* name, bool* is_get, bool* is_set, |
| 579 bool* is_static, bool* is_computed_name, | 584 bool* is_static, bool* is_computed_name, |
| 580 bool* ok); | 585 bool* ok); |
| 581 ExpressionT ParseObjectLiteral(bool* ok); | 586 ExpressionT ParseObjectLiteral(bool* ok); |
| 582 ObjectLiteralPropertyT ParsePropertyDefinition( | 587 ObjectLiteralPropertyT ParsePropertyDefinition( |
| 583 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, | 588 ObjectLiteralCheckerBase* checker, bool in_class, bool has_extends, |
| 584 bool is_static, bool* is_computed_name, bool* has_seen_constructor, | 589 bool is_static, bool* is_computed_name, bool* has_seen_constructor, |
| 585 bool* ok); | 590 bool* ok); |
| 586 typename Traits::Type::ExpressionList ParseArguments(bool* ok); | 591 typename Traits::Type::ExpressionList ParseArguments( |
| 592 Scanner::Location* first_spread_pos, bool* ok); |
| 587 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 593 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 588 ExpressionT ParseYieldExpression(bool* ok); | 594 ExpressionT ParseYieldExpression(bool* ok); |
| 589 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 595 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 590 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 596 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 591 ExpressionT ParseUnaryExpression(bool* ok); | 597 ExpressionT ParseUnaryExpression(bool* ok); |
| 592 ExpressionT ParsePostfixExpression(bool* ok); | 598 ExpressionT ParsePostfixExpression(bool* ok); |
| 593 ExpressionT ParseLeftHandSideExpression(bool* ok); | 599 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 594 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); | 600 ExpressionT ParseMemberWithNewPrefixesExpression(bool* ok); |
| 595 ExpressionT ParseMemberExpression(bool* ok); | 601 ExpressionT ParseMemberExpression(bool* ok); |
| 596 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 602 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 688 Scanner* scanner_; | 694 Scanner* scanner_; |
| 689 bool stack_overflow_; | 695 bool stack_overflow_; |
| 690 | 696 |
| 691 bool allow_lazy_; | 697 bool allow_lazy_; |
| 692 bool allow_natives_; | 698 bool allow_natives_; |
| 693 bool allow_harmony_arrow_functions_; | 699 bool allow_harmony_arrow_functions_; |
| 694 bool allow_harmony_object_literals_; | 700 bool allow_harmony_object_literals_; |
| 695 bool allow_harmony_sloppy_; | 701 bool allow_harmony_sloppy_; |
| 696 bool allow_harmony_computed_property_names_; | 702 bool allow_harmony_computed_property_names_; |
| 697 bool allow_harmony_rest_params_; | 703 bool allow_harmony_rest_params_; |
| 704 bool allow_harmony_spreadcalls_; |
| 698 bool allow_strong_mode_; | 705 bool allow_strong_mode_; |
| 699 }; | 706 }; |
| 700 | 707 |
| 701 | 708 |
| 702 class PreParserIdentifier { | 709 class PreParserIdentifier { |
| 703 public: | 710 public: |
| 704 PreParserIdentifier() : type_(kUnknownIdentifier) {} | 711 PreParserIdentifier() : type_(kUnknownIdentifier) {} |
| 705 static PreParserIdentifier Default() { | 712 static PreParserIdentifier Default() { |
| 706 return PreParserIdentifier(kUnknownIdentifier); | 713 return PreParserIdentifier(kUnknownIdentifier); |
| 707 } | 714 } |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 780 friend class PreParserExpression; | 787 friend class PreParserExpression; |
| 781 }; | 788 }; |
| 782 | 789 |
| 783 | 790 |
| 784 class PreParserExpression { | 791 class PreParserExpression { |
| 785 public: | 792 public: |
| 786 static PreParserExpression Default() { | 793 static PreParserExpression Default() { |
| 787 return PreParserExpression(TypeField::encode(kExpression)); | 794 return PreParserExpression(TypeField::encode(kExpression)); |
| 788 } | 795 } |
| 789 | 796 |
| 797 static PreParserExpression Spread(PreParserExpression expression) { |
| 798 return PreParserExpression(TypeField::encode(kSpreadExpression)); |
| 799 } |
| 800 |
| 790 static PreParserExpression FromIdentifier(PreParserIdentifier id) { | 801 static PreParserExpression FromIdentifier(PreParserIdentifier id) { |
| 791 return PreParserExpression(TypeField::encode(kIdentifierExpression) | | 802 return PreParserExpression(TypeField::encode(kIdentifierExpression) | |
| 792 IdentifierTypeField::encode(id.type_)); | 803 IdentifierTypeField::encode(id.type_)); |
| 793 } | 804 } |
| 794 | 805 |
| 795 static PreParserExpression BinaryOperation(PreParserExpression left, | 806 static PreParserExpression BinaryOperation(PreParserExpression left, |
| 796 Token::Value op, | 807 Token::Value op, |
| 797 PreParserExpression right) { | 808 PreParserExpression right) { |
| 798 bool valid_arrow_param_list = | 809 bool valid_arrow_param_list = |
| 799 op == Token::COMMA && !left.is_parenthesized() && | 810 op == Token::COMMA && !left.is_parenthesized() && |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 908 | 919 |
| 909 // At the moment PreParser doesn't track these expression types. | 920 // At the moment PreParser doesn't track these expression types. |
| 910 bool IsFunctionLiteral() const { return false; } | 921 bool IsFunctionLiteral() const { return false; } |
| 911 bool IsCallNew() const { return false; } | 922 bool IsCallNew() const { return false; } |
| 912 | 923 |
| 913 bool IsNoTemplateTag() const { | 924 bool IsNoTemplateTag() const { |
| 914 return TypeField::decode(code_) == kExpression && | 925 return TypeField::decode(code_) == kExpression && |
| 915 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; | 926 ExpressionTypeField::decode(code_) == kNoTemplateTagExpression; |
| 916 } | 927 } |
| 917 | 928 |
| 929 bool IsSpreadExpression() const { |
| 930 return TypeField::decode(code_) == kSpreadExpression; |
| 931 } |
| 932 |
| 918 PreParserExpression AsFunctionLiteral() { return *this; } | 933 PreParserExpression AsFunctionLiteral() { return *this; } |
| 919 | 934 |
| 920 bool IsBinaryOperation() const { | 935 bool IsBinaryOperation() const { |
| 921 return TypeField::decode(code_) == kBinaryOperationExpression; | 936 return TypeField::decode(code_) == kBinaryOperationExpression; |
| 922 } | 937 } |
| 923 | 938 |
| 924 bool is_parenthesized() const { | 939 bool is_parenthesized() const { |
| 925 return ParenthesizationField::decode(code_) != kNotParenthesized; | 940 return ParenthesizationField::decode(code_) != kNotParenthesized; |
| 926 } | 941 } |
| 927 | 942 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 940 void set_parenthesized() {} | 955 void set_parenthesized() {} |
| 941 | 956 |
| 942 int position() const { return RelocInfo::kNoPosition; } | 957 int position() const { return RelocInfo::kNoPosition; } |
| 943 void set_function_token_position(int position) {} | 958 void set_function_token_position(int position) {} |
| 944 | 959 |
| 945 private: | 960 private: |
| 946 enum Type { | 961 enum Type { |
| 947 kExpression, | 962 kExpression, |
| 948 kIdentifierExpression, | 963 kIdentifierExpression, |
| 949 kStringLiteralExpression, | 964 kStringLiteralExpression, |
| 950 kBinaryOperationExpression | 965 kBinaryOperationExpression, |
| 966 kSpreadExpression |
| 951 }; | 967 }; |
| 952 | 968 |
| 953 enum Parenthesization { | 969 enum Parenthesization { |
| 954 kNotParenthesized, | 970 kNotParenthesized, |
| 955 kParanthesizedExpression, | 971 kParanthesizedExpression, |
| 956 kMultiParenthesizedExpression | 972 kMultiParenthesizedExpression |
| 957 }; | 973 }; |
| 958 | 974 |
| 959 enum ExpressionType { | 975 enum ExpressionType { |
| 960 kThisExpression, | 976 kThisExpression, |
| 961 kThisPropertyExpression, | 977 kThisPropertyExpression, |
| 962 kPropertyExpression, | 978 kPropertyExpression, |
| 963 kCallExpression, | 979 kCallExpression, |
| 964 kNoTemplateTagExpression | 980 kNoTemplateTagExpression |
| 965 }; | 981 }; |
| 966 | 982 |
| 967 explicit PreParserExpression(uint32_t expression_code) | 983 explicit PreParserExpression(uint32_t expression_code) |
| 968 : code_(expression_code) {} | 984 : code_(expression_code) {} |
| 969 | 985 |
| 970 V8_INLINE bool IsValidArrowParams() const { | 986 V8_INLINE bool IsValidArrowParams() const { |
| 971 return IsBinaryOperation() | 987 return IsBinaryOperation() |
| 972 ? IsValidArrowParamListField::decode(code_) | 988 ? IsValidArrowParamListField::decode(code_) |
| 973 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); | 989 : (IsIdentifier() && AsIdentifier().IsValidArrowParam()); |
| 974 } | 990 } |
| 975 | 991 |
| 976 // The first four bits are for the Type and Parenthesization. | 992 // The first five bits are for the Type and Parenthesization. |
| 977 typedef BitField<Type, 0, 2> TypeField; | 993 typedef BitField<Type, 0, 3> TypeField; |
| 978 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; | 994 typedef BitField<Parenthesization, TypeField::kNext, 2> ParenthesizationField; |
| 979 | 995 |
| 980 // The rest of the bits are interpreted depending on the value | 996 // The rest of the bits are interpreted depending on the value |
| 981 // of the Type field, so they can share the storage. | 997 // of the Type field, so they can share the storage. |
| 982 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> | 998 typedef BitField<ExpressionType, ParenthesizationField::kNext, 3> |
| 983 ExpressionTypeField; | 999 ExpressionTypeField; |
| 984 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; | 1000 typedef BitField<bool, ParenthesizationField::kNext, 1> IsUseStrictField; |
| 985 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; | 1001 typedef BitField<bool, IsUseStrictField::kNext, 1> IsUseStrongField; |
| 986 typedef BitField<bool, ParenthesizationField::kNext, 1> | 1002 typedef BitField<bool, ParenthesizationField::kNext, 1> |
| 987 IsValidArrowParamListField; | 1003 IsValidArrowParamListField; |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 PreParserExpression NewCall(PreParserExpression expression, | 1184 PreParserExpression NewCall(PreParserExpression expression, |
| 1169 PreParserExpressionList arguments, | 1185 PreParserExpressionList arguments, |
| 1170 int pos) { | 1186 int pos) { |
| 1171 return PreParserExpression::Call(); | 1187 return PreParserExpression::Call(); |
| 1172 } | 1188 } |
| 1173 PreParserExpression NewCallNew(PreParserExpression expression, | 1189 PreParserExpression NewCallNew(PreParserExpression expression, |
| 1174 PreParserExpressionList arguments, | 1190 PreParserExpressionList arguments, |
| 1175 int pos) { | 1191 int pos) { |
| 1176 return PreParserExpression::Default(); | 1192 return PreParserExpression::Default(); |
| 1177 } | 1193 } |
| 1194 PreParserExpression NewCallRuntime(const AstRawString* name, |
| 1195 const Runtime::Function* function, |
| 1196 PreParserExpressionList arguments, |
| 1197 int pos) { |
| 1198 return PreParserExpression::Default(); |
| 1199 } |
| 1178 PreParserStatement NewReturnStatement(PreParserExpression expression, | 1200 PreParserStatement NewReturnStatement(PreParserExpression expression, |
| 1179 int pos) { | 1201 int pos) { |
| 1180 return PreParserStatement::Default(); | 1202 return PreParserStatement::Default(); |
| 1181 } | 1203 } |
| 1182 PreParserExpression NewFunctionLiteral( | 1204 PreParserExpression NewFunctionLiteral( |
| 1183 PreParserIdentifier name, AstValueFactory* ast_value_factory, | 1205 PreParserIdentifier name, AstValueFactory* ast_value_factory, |
| 1184 Scope* scope, PreParserStatementList body, int materialized_literal_count, | 1206 Scope* scope, PreParserStatementList body, int materialized_literal_count, |
| 1185 int expected_property_count, int handler_count, int parameter_count, | 1207 int expected_property_count, int handler_count, int parameter_count, |
| 1186 FunctionLiteral::ParameterFlag has_duplicate_parameters, | 1208 FunctionLiteral::ParameterFlag has_duplicate_parameters, |
| 1187 FunctionLiteral::FunctionType function_type, | 1209 FunctionLiteral::FunctionType function_type, |
| 1188 FunctionLiteral::IsFunctionFlag is_function, | 1210 FunctionLiteral::IsFunctionFlag is_function, |
| 1189 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, | 1211 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind, |
| 1190 int position) { | 1212 int position) { |
| 1191 return PreParserExpression::Default(); | 1213 return PreParserExpression::Default(); |
| 1192 } | 1214 } |
| 1193 | 1215 |
| 1216 PreParserExpression NewSpreadOperation(PreParserExpression expression, |
| 1217 int pos) { |
| 1218 return PreParserExpression::Spread(expression); |
| 1219 } |
| 1220 |
| 1194 // Return the object itself as AstVisitor and implement the needed | 1221 // Return the object itself as AstVisitor and implement the needed |
| 1195 // dummy method right in this class. | 1222 // dummy method right in this class. |
| 1196 PreParserFactory* visitor() { return this; } | 1223 PreParserFactory* visitor() { return this; } |
| 1197 int* ast_properties() { | 1224 int* ast_properties() { |
| 1198 static int dummy = 42; | 1225 static int dummy = 42; |
| 1199 return &dummy; | 1226 return &dummy; |
| 1200 } | 1227 } |
| 1201 }; | 1228 }; |
| 1202 | 1229 |
| 1203 | 1230 |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1496 PreParserIdentifier name, Scanner::Location function_name_location, | 1523 PreParserIdentifier name, Scanner::Location function_name_location, |
| 1497 bool name_is_strict_reserved, FunctionKind kind, | 1524 bool name_is_strict_reserved, FunctionKind kind, |
| 1498 int function_token_position, FunctionLiteral::FunctionType type, | 1525 int function_token_position, FunctionLiteral::FunctionType type, |
| 1499 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); | 1526 FunctionLiteral::ArityRestriction arity_restriction, bool* ok); |
| 1500 | 1527 |
| 1501 PreParserExpression ParseClassLiteral(PreParserIdentifier name, | 1528 PreParserExpression ParseClassLiteral(PreParserIdentifier name, |
| 1502 Scanner::Location class_name_location, | 1529 Scanner::Location class_name_location, |
| 1503 bool name_is_strict_reserved, int pos, | 1530 bool name_is_strict_reserved, int pos, |
| 1504 bool* ok); | 1531 bool* ok); |
| 1505 | 1532 |
| 1533 PreParserExpressionList PrepareSpreadArguments(PreParserExpressionList list) { |
| 1534 return list; |
| 1535 } |
| 1536 |
| 1537 inline void MaterializeUnspreadArgumentsLiterals(int count); |
| 1538 |
| 1539 inline PreParserExpression SpreadCall(PreParserExpression function, |
| 1540 PreParserExpressionList args, int pos); |
| 1541 |
| 1542 inline PreParserExpression SpreadCallNew(PreParserExpression function, |
| 1543 PreParserExpressionList args, |
| 1544 int pos); |
| 1545 |
| 1506 private: | 1546 private: |
| 1507 PreParser* pre_parser_; | 1547 PreParser* pre_parser_; |
| 1508 }; | 1548 }; |
| 1509 | 1549 |
| 1510 | 1550 |
| 1511 // Preparsing checks a JavaScript program and emits preparse-data that helps | 1551 // Preparsing checks a JavaScript program and emits preparse-data that helps |
| 1512 // a later parsing to be faster. | 1552 // a later parsing to be faster. |
| 1513 // See preparse-data-format.h for the data format. | 1553 // See preparse-data-format.h for the data format. |
| 1514 | 1554 |
| 1515 // The PreParser checks that the syntax follows the grammar for JavaScript, | 1555 // The PreParser checks that the syntax follows the grammar for JavaScript, |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1635 bool* ok); | 1675 bool* ok); |
| 1636 }; | 1676 }; |
| 1637 | 1677 |
| 1638 | 1678 |
| 1639 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { | 1679 void PreParserTraits::MaterializeTemplateCallsiteLiterals() { |
| 1640 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1680 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
| 1641 pre_parser_->function_state_->NextMaterializedLiteralIndex(); | 1681 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
| 1642 } | 1682 } |
| 1643 | 1683 |
| 1644 | 1684 |
| 1685 void PreParserTraits::MaterializeUnspreadArgumentsLiterals(int count) { |
| 1686 for (int i = 0; i < count; ++i) { |
| 1687 pre_parser_->function_state_->NextMaterializedLiteralIndex(); |
| 1688 } |
| 1689 } |
| 1690 |
| 1691 |
| 1692 PreParserExpression PreParserTraits::SpreadCall(PreParserExpression function, |
| 1693 PreParserExpressionList args, |
| 1694 int pos) { |
| 1695 return pre_parser_->factory()->NewCall(function, args, pos); |
| 1696 } |
| 1697 |
| 1698 PreParserExpression PreParserTraits::SpreadCallNew(PreParserExpression function, |
| 1699 PreParserExpressionList args, |
| 1700 int pos) { |
| 1701 return pre_parser_->factory()->NewCallNew(function, args, pos); |
| 1702 } |
| 1703 |
| 1704 |
| 1645 PreParserStatementList PreParser::ParseEagerFunctionBody( | 1705 PreParserStatementList PreParser::ParseEagerFunctionBody( |
| 1646 PreParserIdentifier function_name, int pos, Variable* fvar, | 1706 PreParserIdentifier function_name, int pos, Variable* fvar, |
| 1647 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { | 1707 Token::Value fvar_init_op, FunctionKind kind, bool* ok) { |
| 1648 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1708 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
| 1649 | 1709 |
| 1650 ParseStatementList(Token::RBRACE, ok); | 1710 ParseStatementList(Token::RBRACE, ok); |
| 1651 if (!*ok) return PreParserStatementList(); | 1711 if (!*ok) return PreParserStatementList(); |
| 1652 | 1712 |
| 1653 Expect(Token::RBRACE, ok); | 1713 Expect(Token::RBRACE, ok); |
| 1654 return PreParserStatementList(); | 1714 return PreParserStatementList(); |
| (...skipping 649 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2304 return factory()->NewObjectLiteral(properties, | 2364 return factory()->NewObjectLiteral(properties, |
| 2305 literal_index, | 2365 literal_index, |
| 2306 number_of_boilerplate_properties, | 2366 number_of_boilerplate_properties, |
| 2307 has_function, | 2367 has_function, |
| 2308 pos); | 2368 pos); |
| 2309 } | 2369 } |
| 2310 | 2370 |
| 2311 | 2371 |
| 2312 template <class Traits> | 2372 template <class Traits> |
| 2313 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( | 2373 typename Traits::Type::ExpressionList ParserBase<Traits>::ParseArguments( |
| 2314 bool* ok) { | 2374 Scanner::Location* first_spread_arg_loc, bool* ok) { |
| 2315 // Arguments :: | 2375 // Arguments :: |
| 2316 // '(' (AssignmentExpression)*[','] ')' | 2376 // '(' (AssignmentExpression)*[','] ')' |
| 2317 | 2377 |
| 2378 Scanner::Location spread_arg = Scanner::Location::invalid(); |
| 2318 typename Traits::Type::ExpressionList result = | 2379 typename Traits::Type::ExpressionList result = |
| 2319 this->NewExpressionList(4, zone_); | 2380 this->NewExpressionList(4, zone_); |
| 2320 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); | 2381 Expect(Token::LPAREN, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2321 bool done = (peek() == Token::RPAREN); | 2382 bool done = (peek() == Token::RPAREN); |
| 2383 bool was_unspread = false; |
| 2384 int unspread_sequences_count = 0; |
| 2322 while (!done) { | 2385 while (!done) { |
| 2386 bool is_spread = allow_harmony_spreadcalls() && (peek() == Token::ELLIPSIS); |
| 2387 int start_pos = peek_position(); |
| 2388 if (is_spread) Consume(Token::ELLIPSIS); |
| 2389 |
| 2323 ExpressionT argument = this->ParseAssignmentExpression( | 2390 ExpressionT argument = this->ParseAssignmentExpression( |
| 2324 true, CHECK_OK_CUSTOM(NullExpressionList)); | 2391 true, CHECK_OK_CUSTOM(NullExpressionList)); |
| 2392 if (is_spread) { |
| 2393 if (!spread_arg.IsValid()) { |
| 2394 spread_arg.beg_pos = start_pos; |
| 2395 spread_arg.end_pos = peek_position(); |
| 2396 } |
| 2397 argument = factory()->NewSpreadOperation(argument, start_pos); |
| 2398 } |
| 2325 result->Add(argument, zone_); | 2399 result->Add(argument, zone_); |
| 2400 |
| 2401 // unspread_sequences_count is the number of sequences of parameters which |
| 2402 // are not prefixed with a spread '...' operator. |
| 2403 if (is_spread) { |
| 2404 was_unspread = false; |
| 2405 } else if (!was_unspread) { |
| 2406 was_unspread = true; |
| 2407 unspread_sequences_count++; |
| 2408 } |
| 2409 |
| 2326 if (result->length() > Code::kMaxArguments) { | 2410 if (result->length() > Code::kMaxArguments) { |
| 2327 ReportMessage("too_many_arguments"); | 2411 ReportMessage("too_many_arguments"); |
| 2328 *ok = false; | 2412 *ok = false; |
| 2329 return this->NullExpressionList(); | 2413 return this->NullExpressionList(); |
| 2330 } | 2414 } |
| 2331 done = (peek() != Token::COMMA); | 2415 done = (peek() != Token::COMMA); |
| 2332 if (!done) { | 2416 if (!done) { |
| 2333 Next(); | 2417 Next(); |
| 2334 } | 2418 } |
| 2335 } | 2419 } |
| 2336 Scanner::Location location = scanner_->location(); | 2420 Scanner::Location location = scanner_->location(); |
| 2337 if (Token::RPAREN != Next()) { | 2421 if (Token::RPAREN != Next()) { |
| 2338 ReportMessageAt(location, "unterminated_arg_list"); | 2422 ReportMessageAt(location, "unterminated_arg_list"); |
| 2339 *ok = false; | 2423 *ok = false; |
| 2340 return this->NullExpressionList(); | 2424 return this->NullExpressionList(); |
| 2341 } | 2425 } |
| 2426 *first_spread_arg_loc = spread_arg; |
| 2427 |
| 2428 if (spread_arg.IsValid()) { |
| 2429 // Unspread parameter sequences are translated into array literals in the |
| 2430 // parser. Ensure that the number of materialized literals matches between |
| 2431 // the parser and preparser |
| 2432 Traits::MaterializeUnspreadArgumentsLiterals(unspread_sequences_count); |
| 2433 } |
| 2434 |
| 2342 return result; | 2435 return result; |
| 2343 } | 2436 } |
| 2344 | 2437 |
| 2345 // Precedence = 2 | 2438 // Precedence = 2 |
| 2346 template <class Traits> | 2439 template <class Traits> |
| 2347 typename ParserBase<Traits>::ExpressionT | 2440 typename ParserBase<Traits>::ExpressionT |
| 2348 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { | 2441 ParserBase<Traits>::ParseAssignmentExpression(bool accept_IN, bool* ok) { |
| 2349 // AssignmentExpression :: | 2442 // AssignmentExpression :: |
| 2350 // ConditionalExpression | 2443 // ConditionalExpression |
| 2351 // ArrowFunction | 2444 // ArrowFunction |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2646 // should not point to the closing brace otherwise it will intersect | 2739 // should not point to the closing brace otherwise it will intersect |
| 2647 // with positions recorded for function literal and confuse debugger. | 2740 // with positions recorded for function literal and confuse debugger. |
| 2648 pos = peek_position(); | 2741 pos = peek_position(); |
| 2649 // Also the trailing parenthesis are a hint that the function will | 2742 // Also the trailing parenthesis are a hint that the function will |
| 2650 // be called immediately. If we happen to have parsed a preceding | 2743 // be called immediately. If we happen to have parsed a preceding |
| 2651 // function literal eagerly, we can also compile it eagerly. | 2744 // function literal eagerly, we can also compile it eagerly. |
| 2652 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { | 2745 if (result->IsFunctionLiteral() && mode() == PARSE_EAGERLY) { |
| 2653 result->AsFunctionLiteral()->set_parenthesized(); | 2746 result->AsFunctionLiteral()->set_parenthesized(); |
| 2654 } | 2747 } |
| 2655 } | 2748 } |
| 2656 typename Traits::Type::ExpressionList args = ParseArguments(CHECK_OK); | 2749 Scanner::Location spread_pos; |
| 2750 typename Traits::Type::ExpressionList args = |
| 2751 ParseArguments(&spread_pos, CHECK_OK); |
| 2657 | 2752 |
| 2658 // Keep track of eval() calls since they disable all local variable | 2753 // Keep track of eval() calls since they disable all local variable |
| 2659 // optimizations. | 2754 // optimizations. |
| 2660 // The calls that need special treatment are the | 2755 // The calls that need special treatment are the |
| 2661 // direct eval calls. These calls are all of the form eval(...), with | 2756 // direct eval calls. These calls are all of the form eval(...), with |
| 2662 // no explicit receiver. | 2757 // no explicit receiver. |
| 2663 // These calls are marked as potentially direct eval calls. Whether | 2758 // These calls are marked as potentially direct eval calls. Whether |
| 2664 // they are actually direct calls to eval is determined at run time. | 2759 // they are actually direct calls to eval is determined at run time. |
| 2665 this->CheckPossibleEvalCall(result, scope_); | 2760 this->CheckPossibleEvalCall(result, scope_); |
| 2666 result = factory()->NewCall(result, args, pos); | 2761 |
| 2762 if (spread_pos.IsValid()) { |
| 2763 args = Traits::PrepareSpreadArguments(args); |
| 2764 result = Traits::SpreadCall(result, args, pos); |
| 2765 } else { |
| 2766 result = factory()->NewCall(result, args, pos); |
| 2767 } |
| 2667 if (fni_ != NULL) fni_->RemoveLastFunction(); | 2768 if (fni_ != NULL) fni_->RemoveLastFunction(); |
| 2668 break; | 2769 break; |
| 2669 } | 2770 } |
| 2670 | 2771 |
| 2671 case Token::PERIOD: { | 2772 case Token::PERIOD: { |
| 2672 Consume(Token::PERIOD); | 2773 Consume(Token::PERIOD); |
| 2673 int pos = position(); | 2774 int pos = position(); |
| 2674 IdentifierT name = ParseIdentifierName(CHECK_OK); | 2775 IdentifierT name = ParseIdentifierName(CHECK_OK); |
| 2675 result = factory()->NewProperty( | 2776 result = factory()->NewProperty( |
| 2676 result, factory()->NewStringLiteral(name, pos), pos); | 2777 result, factory()->NewStringLiteral(name, pos), pos); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2710 int new_pos = position(); | 2811 int new_pos = position(); |
| 2711 ExpressionT result = this->EmptyExpression(); | 2812 ExpressionT result = this->EmptyExpression(); |
| 2712 if (peek() == Token::SUPER) { | 2813 if (peek() == Token::SUPER) { |
| 2713 const bool is_new = true; | 2814 const bool is_new = true; |
| 2714 result = ParseSuperExpression(is_new, CHECK_OK); | 2815 result = ParseSuperExpression(is_new, CHECK_OK); |
| 2715 } else { | 2816 } else { |
| 2716 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); | 2817 result = this->ParseMemberWithNewPrefixesExpression(CHECK_OK); |
| 2717 } | 2818 } |
| 2718 if (peek() == Token::LPAREN) { | 2819 if (peek() == Token::LPAREN) { |
| 2719 // NewExpression with arguments. | 2820 // NewExpression with arguments. |
| 2821 Scanner::Location spread_pos; |
| 2720 typename Traits::Type::ExpressionList args = | 2822 typename Traits::Type::ExpressionList args = |
| 2721 this->ParseArguments(CHECK_OK); | 2823 this->ParseArguments(&spread_pos, CHECK_OK); |
| 2722 result = factory()->NewCallNew(result, args, new_pos); | 2824 |
| 2825 if (spread_pos.IsValid()) { |
| 2826 args = Traits::PrepareSpreadArguments(args); |
| 2827 result = Traits::SpreadCallNew(result, args, new_pos); |
| 2828 } else { |
| 2829 result = factory()->NewCallNew(result, args, new_pos); |
| 2830 } |
| 2723 // The expression can still continue with . or [ after the arguments. | 2831 // The expression can still continue with . or [ after the arguments. |
| 2724 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); | 2832 result = this->ParseMemberExpressionContinuation(result, CHECK_OK); |
| 2725 return result; | 2833 return result; |
| 2726 } | 2834 } |
| 2727 // NewExpression without arguments. | 2835 // NewExpression without arguments. |
| 2728 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), | 2836 return factory()->NewCallNew(result, this->NewExpressionList(0, zone_), |
| 2729 new_pos); | 2837 new_pos); |
| 2730 } | 2838 } |
| 2731 // No 'new' or 'super' keyword. | 2839 // No 'new' or 'super' keyword. |
| 2732 return this->ParseMemberExpression(ok); | 2840 return this->ParseMemberExpression(ok); |
| (...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3163 *ok = false; | 3271 *ok = false; |
| 3164 return; | 3272 return; |
| 3165 } | 3273 } |
| 3166 has_seen_constructor_ = true; | 3274 has_seen_constructor_ = true; |
| 3167 return; | 3275 return; |
| 3168 } | 3276 } |
| 3169 } | 3277 } |
| 3170 } } // v8::internal | 3278 } } // v8::internal |
| 3171 | 3279 |
| 3172 #endif // V8_PREPARSER_H | 3280 #endif // V8_PREPARSER_H |
| OLD | NEW |