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. |
| 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 |