Chromium Code Reviews| 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_PARSING_PARSER_H_ | 5 #ifndef V8_PARSING_PARSER_H_ |
| 6 #define V8_PARSING_PARSER_H_ | 6 #define V8_PARSING_PARSER_H_ |
| 7 | 7 |
| 8 #include "src/ast/ast.h" | 8 #include "src/ast/ast.h" |
| 9 #include "src/ast/scopes.h" | 9 #include "src/ast/scopes.h" |
| 10 #include "src/parsing/parser-base.h" | 10 #include "src/parsing/parser-base.h" |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 typedef AstNodeFactory Factory; | 168 typedef AstNodeFactory Factory; |
| 169 }; | 169 }; |
| 170 | 170 |
| 171 // TODO(nikolaos): The traits methods should not need to call methods | 171 // TODO(nikolaos): The traits methods should not need to call methods |
| 172 // of the implementation object. | 172 // of the implementation object. |
| 173 Parser* delegate() { return reinterpret_cast<Parser*>(this); } | 173 Parser* delegate() { return reinterpret_cast<Parser*>(this); } |
| 174 const Parser* delegate() const { | 174 const Parser* delegate() const { |
| 175 return reinterpret_cast<const Parser*>(this); | 175 return reinterpret_cast<const Parser*>(this); |
| 176 } | 176 } |
| 177 | 177 |
| 178 // Helper functions for recursive descent. | |
| 179 bool IsEval(const AstRawString* identifier) const; | |
| 180 bool IsArguments(const AstRawString* identifier) const; | |
| 181 bool IsEvalOrArguments(const AstRawString* identifier) const; | |
| 182 bool IsUndefined(const AstRawString* identifier) const; | |
| 183 V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const; | |
| 184 | |
| 185 // Returns true if the expression is of type "this.foo". | |
| 186 static bool IsThisProperty(Expression* expression); | |
| 187 | |
| 188 static bool IsIdentifier(Expression* expression); | |
| 189 | |
| 190 static const AstRawString* AsIdentifier(Expression* expression) { | |
| 191 DCHECK(IsIdentifier(expression)); | |
| 192 return expression->AsVariableProxy()->raw_name(); | |
| 193 } | |
| 194 | |
| 195 bool IsPrototype(const AstRawString* identifier) const; | |
| 196 | |
| 197 bool IsConstructor(const AstRawString* identifier) const; | |
| 198 | |
| 199 bool IsDirectEvalCall(Expression* expression) const { | |
| 200 if (!expression->IsCall()) return false; | |
| 201 expression = expression->AsCall()->expression(); | |
| 202 return IsIdentifier(expression) && IsEval(AsIdentifier(expression)); | |
| 203 } | |
| 204 | |
| 205 static bool IsBoilerplateProperty(ObjectLiteral::Property* property) { | |
| 206 return ObjectLiteral::IsBoilerplateProperty(property); | |
| 207 } | |
| 208 | |
| 209 static bool IsArrayIndex(const AstRawString* string, uint32_t* index) { | |
| 210 return string->AsArrayIndex(index); | |
| 211 } | |
| 212 | |
| 213 static Expression* GetPropertyValue(ObjectLiteral::Property* property) { | |
| 214 return property->value(); | |
| 215 } | |
| 216 | |
| 217 // Functions for encapsulating the differences between parsing and preparsing; | |
| 218 // operations interleaved with the recursive descent. | |
| 219 static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) { | |
| 220 fni->PushLiteralName(id); | |
| 221 } | |
| 222 | |
| 223 void PushPropertyName(FuncNameInferrer* fni, Expression* expression); | |
| 224 | |
| 225 static void InferFunctionName(FuncNameInferrer* fni, | |
| 226 FunctionLiteral* func_to_infer) { | |
| 227 fni->AddFunction(func_to_infer); | |
| 228 } | |
| 229 | |
| 230 // If we assign a function literal to a property we pretenure the | |
| 231 // literal so it can be added as a constant function property. | |
| 232 static void CheckAssigningFunctionLiteralToProperty(Expression* left, | |
| 233 Expression* right); | |
| 234 | |
| 235 // Determine if the expression is a variable proxy and mark it as being used | |
| 236 // in an assignment or with a increment/decrement operator. | |
| 237 static Expression* MarkExpressionAsAssigned(Expression* expression); | |
| 238 | |
| 239 // Returns true if we have a binary expression between two numeric | |
| 240 // literals. In that case, *x will be changed to an expression which is the | |
| 241 // computed value. | |
| 242 bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y, | |
| 243 Token::Value op, int pos, | |
| 244 AstNodeFactory* factory); | |
| 245 | |
| 246 // Rewrites the following types of unary expressions: | 178 // Rewrites the following types of unary expressions: |
| 247 // not <literal> -> true / false | 179 // not <literal> -> true / false |
| 248 // + <numeric literal> -> <numeric literal> | 180 // + <numeric literal> -> <numeric literal> |
| 249 // - <numeric literal> -> <numeric literal with value negated> | 181 // - <numeric literal> -> <numeric literal with value negated> |
| 250 // ! <literal> -> true / false | 182 // ! <literal> -> true / false |
| 251 // The following rewriting rules enable the collection of type feedback | 183 // The following rewriting rules enable the collection of type feedback |
| 252 // without any special stub and the multiplication is removed later in | 184 // without any special stub and the multiplication is removed later in |
| 253 // Crankshaft's canonicalization pass. | 185 // Crankshaft's canonicalization pass. |
| 254 // + foo -> foo * 1 | 186 // + foo -> foo * 1 |
| 255 // - foo -> foo * (-1) | 187 // - foo -> foo * (-1) |
| (...skipping 629 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 885 V8_INLINE Expression* RewriteAwaitExpression(Expression* value, int pos); | 817 V8_INLINE Expression* RewriteAwaitExpression(Expression* value, int pos); |
| 886 | 818 |
| 887 Expression* RewriteYieldStar(Expression* generator, Expression* expression, | 819 Expression* RewriteYieldStar(Expression* generator, Expression* expression, |
| 888 int pos); | 820 int pos); |
| 889 | 821 |
| 890 void ParseArrowFunctionFormalParameters(ParserFormalParameters* parameters, | 822 void ParseArrowFunctionFormalParameters(ParserFormalParameters* parameters, |
| 891 Expression* params, int end_pos, | 823 Expression* params, int end_pos, |
| 892 bool* ok); | 824 bool* ok); |
| 893 void SetFunctionName(Expression* value, const AstRawString* name); | 825 void SetFunctionName(Expression* value, const AstRawString* name); |
| 894 | 826 |
| 827 // Helper functions for recursive descent. | |
|
adamk
2016/08/23 16:03:45
I don't think this comment carries its weight
| |
| 828 V8_INLINE bool IsEval(const AstRawString* identifier) const { | |
| 829 return identifier == ast_value_factory()->eval_string(); | |
| 830 } | |
| 831 | |
| 832 V8_INLINE bool IsArguments(const AstRawString* identifier) const { | |
| 833 return identifier == ast_value_factory()->arguments_string(); | |
| 834 } | |
| 835 | |
| 836 V8_INLINE bool IsEvalOrArguments(const AstRawString* identifier) const { | |
| 837 return IsEval(identifier) || IsArguments(identifier); | |
| 838 } | |
| 839 | |
| 840 V8_INLINE bool IsUndefined(const AstRawString* identifier) const { | |
| 841 return identifier == ast_value_factory()->undefined_string(); | |
| 842 } | |
| 843 | |
| 844 V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const { | |
| 845 return scanner()->IdentifierIsFutureStrictReserved(identifier); | |
| 846 } | |
| 847 | |
| 848 // Returns true if the expression is of type "this.foo". | |
| 849 V8_INLINE static bool IsThisProperty(Expression* expression) { | |
| 850 DCHECK(expression != NULL); | |
| 851 Property* property = expression->AsProperty(); | |
| 852 return property != NULL && property->obj()->IsVariableProxy() && | |
| 853 property->obj()->AsVariableProxy()->is_this(); | |
| 854 } | |
| 855 | |
| 856 V8_INLINE static bool IsIdentifier(Expression* expression) { | |
| 857 VariableProxy* operand = expression->AsVariableProxy(); | |
| 858 return operand != NULL && !operand->is_this(); | |
| 859 } | |
| 860 | |
| 861 V8_INLINE static const AstRawString* AsIdentifier(Expression* expression) { | |
| 862 DCHECK(IsIdentifier(expression)); | |
| 863 return expression->AsVariableProxy()->raw_name(); | |
| 864 } | |
| 865 | |
| 866 V8_INLINE bool IsPrototype(const AstRawString* identifier) const { | |
| 867 return identifier == ast_value_factory()->prototype_string(); | |
| 868 } | |
| 869 | |
| 870 V8_INLINE bool IsConstructor(const AstRawString* identifier) const { | |
| 871 return identifier == ast_value_factory()->constructor_string(); | |
| 872 } | |
| 873 | |
| 874 V8_INLINE bool IsDirectEvalCall(Expression* expression) const { | |
| 875 if (!expression->IsCall()) return false; | |
| 876 expression = expression->AsCall()->expression(); | |
| 877 return IsIdentifier(expression) && IsEval(AsIdentifier(expression)); | |
| 878 } | |
| 879 | |
| 880 V8_INLINE static bool IsBoilerplateProperty( | |
| 881 ObjectLiteral::Property* property) { | |
| 882 return ObjectLiteral::IsBoilerplateProperty(property); | |
| 883 } | |
| 884 | |
| 885 V8_INLINE static bool IsArrayIndex(const AstRawString* string, | |
| 886 uint32_t* index) { | |
| 887 return string->AsArrayIndex(index); | |
| 888 } | |
| 889 | |
| 890 V8_INLINE static Expression* GetPropertyValue( | |
| 891 ObjectLiteral::Property* property) { | |
| 892 return property->value(); | |
| 893 } | |
| 894 | |
| 895 // Functions for encapsulating the differences between parsing and preparsing; | |
| 896 // operations interleaved with the recursive descent. | |
| 897 V8_INLINE static void PushLiteralName(FuncNameInferrer* fni, | |
| 898 const AstRawString* id) { | |
| 899 fni->PushLiteralName(id); | |
| 900 } | |
| 901 | |
| 902 V8_INLINE void PushPropertyName(FuncNameInferrer* fni, | |
| 903 Expression* expression) { | |
| 904 if (expression->IsPropertyName()) { | |
| 905 fni->PushLiteralName(expression->AsLiteral()->AsRawPropertyName()); | |
| 906 } else { | |
| 907 fni->PushLiteralName(ast_value_factory()->anonymous_function_string()); | |
| 908 } | |
| 909 } | |
| 910 | |
| 911 V8_INLINE static void InferFunctionName(FuncNameInferrer* fni, | |
| 912 FunctionLiteral* func_to_infer) { | |
| 913 fni->AddFunction(func_to_infer); | |
| 914 } | |
| 915 | |
| 916 // If we assign a function literal to a property we pretenure the | |
| 917 // literal so it can be added as a constant function property. | |
| 918 V8_INLINE static void CheckAssigningFunctionLiteralToProperty( | |
| 919 Expression* left, Expression* right) { | |
| 920 DCHECK(left != NULL); | |
| 921 if (left->IsProperty() && right->IsFunctionLiteral()) { | |
| 922 right->AsFunctionLiteral()->set_pretenure(); | |
| 923 } | |
| 924 } | |
| 925 | |
| 926 // Determine if the expression is a variable proxy and mark it as being used | |
| 927 // in an assignment or with a increment/decrement operator. | |
| 928 V8_INLINE static Expression* MarkExpressionAsAssigned( | |
| 929 Expression* expression) { | |
| 930 VariableProxy* proxy = | |
| 931 expression != NULL ? expression->AsVariableProxy() : NULL; | |
| 932 if (proxy != NULL) proxy->set_is_assigned(); | |
| 933 return expression; | |
| 934 } | |
| 935 | |
| 936 // Returns true if we have a binary expression between two numeric | |
| 937 // literals. In that case, *x will be changed to an expression which is the | |
| 938 // computed value. | |
| 939 bool ShortcutNumericLiteralBinaryExpression(Expression** x, Expression* y, | |
| 940 Token::Value op, int pos); | |
| 941 | |
| 942 // Parser's private field members. | |
| 943 | |
| 895 Scanner scanner_; | 944 Scanner scanner_; |
| 896 PreParser* reusable_preparser_; | 945 PreParser* reusable_preparser_; |
| 897 Scope* original_scope_; // for ES5 function declarations in sloppy eval | 946 Scope* original_scope_; // for ES5 function declarations in sloppy eval |
| 898 Target* target_stack_; // for break, continue statements | 947 Target* target_stack_; // for break, continue statements |
| 899 ScriptCompiler::CompileOptions compile_options_; | 948 ScriptCompiler::CompileOptions compile_options_; |
| 900 ParseData* cached_parse_data_; | 949 ParseData* cached_parse_data_; |
| 901 | 950 |
| 902 PendingCompilationErrorHandler pending_error_handler_; | 951 PendingCompilationErrorHandler pending_error_handler_; |
| 903 | 952 |
| 904 // Other information which will be stored in Parser and moved to Isolate after | 953 // Other information which will be stored in Parser and moved to Isolate after |
| 905 // parsing. | 954 // parsing. |
| 906 int use_counts_[v8::Isolate::kUseCounterFeatureCount]; | 955 int use_counts_[v8::Isolate::kUseCounterFeatureCount]; |
| 907 int total_preparse_skipped_; | 956 int total_preparse_skipped_; |
| 908 HistogramTimer* pre_parse_timer_; | 957 HistogramTimer* pre_parse_timer_; |
| 909 | 958 |
| 910 bool parsing_on_main_thread_; | 959 bool parsing_on_main_thread_; |
| 911 | 960 |
| 912 #ifdef DEBUG | 961 #ifdef DEBUG |
| 913 void Print(AstNode* node); | 962 void Print(AstNode* node); |
| 914 #endif // DEBUG | 963 #endif // DEBUG |
| 915 }; | 964 }; |
| 916 | 965 |
| 917 bool ParserBaseTraits<Parser>::IsFutureStrictReserved( | |
| 918 const AstRawString* identifier) const { | |
| 919 return delegate()->scanner()->IdentifierIsFutureStrictReserved(identifier); | |
| 920 } | |
| 921 | |
| 922 const AstRawString* ParserBaseTraits<Parser>::EmptyIdentifierString() const { | 966 const AstRawString* ParserBaseTraits<Parser>::EmptyIdentifierString() const { |
| 923 return delegate()->ast_value_factory()->empty_string(); | 967 return delegate()->ast_value_factory()->empty_string(); |
| 924 } | 968 } |
| 925 | 969 |
| 926 | 970 |
| 927 // Support for handling complex values (array and object literals) that | 971 // Support for handling complex values (array and object literals) that |
| 928 // can be fully handled at compile time. | 972 // can be fully handled at compile time. |
| 929 class CompileTimeValue: public AllStatic { | 973 class CompileTimeValue: public AllStatic { |
| 930 public: | 974 public: |
| 931 enum LiteralType { | 975 enum LiteralType { |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1006 if (init_block != nullptr) { | 1050 if (init_block != nullptr) { |
| 1007 body->Add(init_block, delegate()->zone()); | 1051 body->Add(init_block, delegate()->zone()); |
| 1008 } | 1052 } |
| 1009 } | 1053 } |
| 1010 } | 1054 } |
| 1011 | 1055 |
| 1012 } // namespace internal | 1056 } // namespace internal |
| 1013 } // namespace v8 | 1057 } // namespace v8 |
| 1014 | 1058 |
| 1015 #endif // V8_PARSING_PARSER_H_ | 1059 #endif // V8_PARSING_PARSER_H_ |
| OLD | NEW |