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 |