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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 : FormalParametersBase(scope), params(4, scope->zone()) {} | 133 : FormalParametersBase(scope), params(4, scope->zone()) {} |
134 ZoneList<Parameter> params; | 134 ZoneList<Parameter> params; |
135 | 135 |
136 int Arity() const { return params.length(); } | 136 int Arity() const { return params.length(); } |
137 const Parameter& at(int i) const { return params[i]; } | 137 const Parameter& at(int i) const { return params[i]; } |
138 }; | 138 }; |
139 | 139 |
140 template <> | 140 template <> |
141 class ParserBaseTraits<Parser> { | 141 class ParserBaseTraits<Parser> { |
142 public: | 142 public: |
143 typedef ParserBaseTraits<Parser> ParserTraits; | 143 struct Type { |
144 typedef ParserBase<Parser> Base; | |
145 typedef Parser Impl; | |
144 | 146 |
145 struct Type { | |
146 typedef Variable GeneratorVariable; | 147 typedef Variable GeneratorVariable; |
147 | 148 |
148 typedef v8::internal::AstProperties AstProperties; | 149 typedef v8::internal::AstProperties AstProperties; |
149 | 150 |
150 typedef v8::internal::ExpressionClassifier<ParserTraits> | 151 typedef v8::internal::ExpressionClassifier<ParserBaseTraits<Parser>> |
151 ExpressionClassifier; | 152 ExpressionClassifier; |
152 | 153 |
153 // Return types for traversing functions. | 154 // Return types for traversing functions. |
154 typedef const AstRawString* Identifier; | 155 typedef const AstRawString* Identifier; |
155 typedef v8::internal::Expression* Expression; | 156 typedef v8::internal::Expression* Expression; |
156 typedef Yield* YieldExpression; | 157 typedef Yield* YieldExpression; |
157 typedef v8::internal::FunctionLiteral* FunctionLiteral; | 158 typedef v8::internal::FunctionLiteral* FunctionLiteral; |
158 typedef v8::internal::ClassLiteral* ClassLiteral; | 159 typedef v8::internal::ClassLiteral* ClassLiteral; |
159 typedef v8::internal::Literal* Literal; | 160 typedef v8::internal::Literal* Literal; |
160 typedef ObjectLiteral::Property* ObjectLiteralProperty; | 161 typedef ObjectLiteral::Property* ObjectLiteralProperty; |
161 typedef ZoneList<v8::internal::Expression*>* ExpressionList; | 162 typedef ZoneList<v8::internal::Expression*>* ExpressionList; |
162 typedef ZoneList<ObjectLiteral::Property*>* PropertyList; | 163 typedef ZoneList<ObjectLiteral::Property*>* PropertyList; |
163 typedef ParserFormalParameters::Parameter FormalParameter; | 164 typedef ParserFormalParameters::Parameter FormalParameter; |
164 typedef ParserFormalParameters FormalParameters; | 165 typedef ParserFormalParameters FormalParameters; |
165 typedef ZoneList<v8::internal::Statement*>* StatementList; | 166 typedef ZoneList<v8::internal::Statement*>* StatementList; |
166 | 167 |
167 // For constructing objects returned by the traversing functions. | 168 // For constructing objects returned by the traversing functions. |
168 typedef AstNodeFactory Factory; | 169 typedef AstNodeFactory Factory; |
169 }; | 170 }; |
170 | |
171 // TODO(nikolaos): The traits methods should not need to call methods | |
172 // of the implementation object. | |
173 Parser* delegate() { return reinterpret_cast<Parser*>(this); } | |
174 const Parser* delegate() const { | |
175 return reinterpret_cast<const Parser*>(this); | |
176 } | |
177 | |
178 V8_INLINE void AddParameterInitializationBlock( | |
179 const ParserFormalParameters& parameters, | |
180 ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok); | |
181 | |
182 V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters, | |
183 Expression* pattern, | |
184 Expression* initializer, | |
185 int initializer_end_position, bool is_rest); | |
186 V8_INLINE void DeclareFormalParameter( | |
187 DeclarationScope* scope, | |
188 const ParserFormalParameters::Parameter& parameter, | |
189 Type::ExpressionClassifier* classifier); | |
190 void ParseArrowFunctionFormalParameterList( | |
191 ParserFormalParameters* parameters, Expression* params, | |
192 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | |
193 const Scope::Snapshot& scope_snapshot, bool* ok); | |
194 | |
195 void ReindexLiterals(const ParserFormalParameters& parameters); | |
196 | |
197 V8_INLINE Expression* NoTemplateTag() { return NULL; } | |
198 V8_INLINE static bool IsTaggedTemplate(const Expression* tag) { | |
199 return tag != NULL; | |
200 } | |
201 | |
202 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {} | |
203 | |
204 Expression* ExpressionListToExpression(ZoneList<Expression*>* args); | |
205 | |
206 void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property, | |
207 const AstRawString* name); | |
208 | |
209 void SetFunctionNameFromIdentifierRef(Expression* value, | |
210 Expression* identifier); | |
211 | |
212 V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>* | |
213 GetReportedErrorList() const; | |
214 V8_INLINE Zone* zone() const; | |
215 | |
216 V8_INLINE ZoneList<Expression*>* GetNonPatternList() const; | |
217 }; | 171 }; |
218 | 172 |
219 class Parser : public ParserBase<Parser> { | 173 class Parser : public ParserBase<Parser> { |
220 public: | 174 public: |
221 explicit Parser(ParseInfo* info); | 175 explicit Parser(ParseInfo* info); |
222 ~Parser() { | 176 ~Parser() { |
223 delete reusable_preparser_; | 177 delete reusable_preparser_; |
224 reusable_preparser_ = NULL; | 178 reusable_preparser_ = NULL; |
225 delete cached_parse_data_; | 179 delete cached_parse_data_; |
226 cached_parse_data_ = NULL; | 180 cached_parse_data_ = NULL; |
227 } | 181 } |
228 | 182 |
229 // Parses the source code represented by the compilation info and sets its | 183 // Parses the source code represented by the compilation info and sets its |
230 // function literal. Returns false (and deallocates any allocated AST | 184 // function literal. Returns false (and deallocates any allocated AST |
231 // nodes) if parsing failed. | 185 // nodes) if parsing failed. |
232 static bool ParseStatic(ParseInfo* info); | 186 static bool ParseStatic(ParseInfo* info); |
233 bool Parse(ParseInfo* info); | 187 bool Parse(ParseInfo* info); |
234 void ParseOnBackground(ParseInfo* info); | 188 void ParseOnBackground(ParseInfo* info); |
235 | 189 |
236 void DeserializeScopeChain(ParseInfo* info, Handle<Context> context, | 190 void DeserializeScopeChain(ParseInfo* info, Handle<Context> context, |
237 Scope::DeserializationMode deserialization_mode); | 191 Scope::DeserializationMode deserialization_mode); |
238 | 192 |
239 // Handle errors detected during parsing, move statistics to Isolate, | 193 // Handle errors detected during parsing, move statistics to Isolate, |
240 // internalize strings (move them to the heap). | 194 // internalize strings (move them to the heap). |
241 void Internalize(Isolate* isolate, Handle<Script> script, bool error); | 195 void Internalize(Isolate* isolate, Handle<Script> script, bool error); |
242 void HandleSourceURLComments(Isolate* isolate, Handle<Script> script); | 196 void HandleSourceURLComments(Isolate* isolate, Handle<Script> script); |
243 | 197 |
244 private: | 198 private: |
245 friend class ParserBase<Parser>; | 199 friend class ParserBase<Parser>; |
246 // TODO(nikolaos): This should not be necessary. It will be removed | 200 friend class v8::internal::ExpressionClassifier<ParserBaseTraits<Parser>>; |
marja
2016/08/25 07:33:56
Pls add a "TODO: remove this, pass the needed data
| |
247 // when the traits object stops delegating to the implementation object. | |
248 friend class ParserBaseTraits<Parser>; | |
249 | 201 |
250 // Runtime encoding of different completion modes. | 202 // Runtime encoding of different completion modes. |
251 enum CompletionKind { | 203 enum CompletionKind { |
252 kNormalCompletion, | 204 kNormalCompletion, |
253 kThrowCompletion, | 205 kThrowCompletion, |
254 kAbruptCompletion | 206 kAbruptCompletion |
255 }; | 207 }; |
256 | 208 |
257 enum class FunctionBodyType { kNormal, kSingleExpression }; | 209 enum class FunctionBodyType { kNormal, kSingleExpression }; |
258 | 210 |
(...skipping 738 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
997 } | 949 } |
998 V8_INLINE ZoneList<ObjectLiteral::Property*>* NewPropertyList( | 950 V8_INLINE ZoneList<ObjectLiteral::Property*>* NewPropertyList( |
999 int size) const { | 951 int size) const { |
1000 return new (zone()) ZoneList<ObjectLiteral::Property*>(size, zone()); | 952 return new (zone()) ZoneList<ObjectLiteral::Property*>(size, zone()); |
1001 } | 953 } |
1002 V8_INLINE ZoneList<v8::internal::Statement*>* NewStatementList( | 954 V8_INLINE ZoneList<v8::internal::Statement*>* NewStatementList( |
1003 int size) const { | 955 int size) const { |
1004 return new (zone()) ZoneList<v8::internal::Statement*>(size, zone()); | 956 return new (zone()) ZoneList<v8::internal::Statement*>(size, zone()); |
1005 } | 957 } |
1006 | 958 |
959 V8_INLINE void AddParameterInitializationBlock( | |
960 const ParserFormalParameters& parameters, | |
961 ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok) { | |
962 if (parameters.is_simple) return; | |
963 auto* init_block = BuildParameterInitializationBlock(parameters, ok); | |
964 if (!*ok) return; | |
965 if (is_async) init_block = BuildRejectPromiseOnException(init_block); | |
966 if (init_block != nullptr) body->Add(init_block, zone()); | |
967 } | |
968 | |
969 V8_INLINE void AddFormalParameter(ParserFormalParameters* parameters, | |
970 Expression* pattern, | |
971 Expression* initializer, | |
972 int initializer_end_position, | |
973 bool is_rest) { | |
974 bool is_simple = pattern->IsVariableProxy() && initializer == nullptr; | |
975 const AstRawString* name = is_simple | |
976 ? pattern->AsVariableProxy()->raw_name() | |
977 : ast_value_factory()->empty_string(); | |
978 parameters->params.Add( | |
979 ParserFormalParameters::Parameter(name, pattern, initializer, | |
980 initializer_end_position, is_rest), | |
981 parameters->scope->zone()); | |
982 } | |
983 | |
984 V8_INLINE void DeclareFormalParameter( | |
adamk
2016/08/24 18:19:40
Hmm, surprised that this and the above were alread
| |
985 DeclarationScope* scope, | |
986 const ParserFormalParameters::Parameter& parameter, | |
987 Type::ExpressionClassifier* classifier) { | |
988 bool is_duplicate = false; | |
989 bool is_simple = classifier->is_simple_parameter_list(); | |
990 auto name = is_simple || parameter.is_rest | |
991 ? parameter.name | |
992 : ast_value_factory()->empty_string(); | |
993 auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY; | |
994 if (!is_simple) scope->SetHasNonSimpleParameters(); | |
995 bool is_optional = parameter.initializer != nullptr; | |
996 Variable* var = | |
997 scope->DeclareParameter(name, mode, is_optional, parameter.is_rest, | |
998 &is_duplicate, ast_value_factory()); | |
999 if (is_duplicate) { | |
1000 classifier->RecordDuplicateFormalParameterError(scanner()->location()); | |
1001 } | |
1002 if (is_sloppy(scope->language_mode())) { | |
1003 // TODO(sigurds) Mark every parameter as maybe assigned. This is a | |
1004 // conservative approximation necessary to account for parameters | |
1005 // that are assigned via the arguments array. | |
1006 var->set_maybe_assigned(); | |
1007 } | |
1008 } | |
1009 | |
1010 void ParseArrowFunctionFormalParameterList( | |
1011 ParserFormalParameters* parameters, Expression* params, | |
1012 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | |
1013 const Scope::Snapshot& scope_snapshot, bool* ok); | |
1014 | |
1015 void ReindexLiterals(const ParserFormalParameters& parameters); | |
1016 | |
1017 V8_INLINE Expression* NoTemplateTag() { return NULL; } | |
1018 V8_INLINE static bool IsTaggedTemplate(const Expression* tag) { | |
1019 return tag != NULL; | |
1020 } | |
1021 | |
1022 V8_INLINE void MaterializeUnspreadArgumentsLiterals(int count) {} | |
1023 | |
1024 Expression* ExpressionListToExpression(ZoneList<Expression*>* args); | |
1025 | |
1026 void SetFunctionNameFromPropertyName(ObjectLiteralProperty* property, | |
1027 const AstRawString* name); | |
1028 | |
1029 void SetFunctionNameFromIdentifierRef(Expression* value, | |
1030 Expression* identifier); | |
1031 | |
1032 V8_INLINE ZoneList<typename Type::ExpressionClassifier::Error>* | |
1033 GetReportedErrorList() const { | |
1034 return function_state_->GetReportedErrorList(); | |
1035 } | |
1036 | |
1037 V8_INLINE ZoneList<Expression*>* GetNonPatternList() const { | |
1038 return function_state_->non_patterns_to_rewrite(); | |
1039 } | |
1040 | |
1007 // Parser's private field members. | 1041 // Parser's private field members. |
1008 | 1042 |
1009 Scanner scanner_; | 1043 Scanner scanner_; |
1010 PreParser* reusable_preparser_; | 1044 PreParser* reusable_preparser_; |
1011 Scope* original_scope_; // for ES5 function declarations in sloppy eval | 1045 Scope* original_scope_; // for ES5 function declarations in sloppy eval |
1012 Target* target_stack_; // for break, continue statements | 1046 Target* target_stack_; // for break, continue statements |
1013 ScriptCompiler::CompileOptions compile_options_; | 1047 ScriptCompiler::CompileOptions compile_options_; |
1014 ParseData* cached_parse_data_; | 1048 ParseData* cached_parse_data_; |
1015 | 1049 |
1016 PendingCompilationErrorHandler pending_error_handler_; | 1050 PendingCompilationErrorHandler pending_error_handler_; |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1050 // Get the elements array of a compile time value returned by GetValue(). | 1084 // Get the elements array of a compile time value returned by GetValue(). |
1051 static Handle<FixedArray> GetElements(Handle<FixedArray> value); | 1085 static Handle<FixedArray> GetElements(Handle<FixedArray> value); |
1052 | 1086 |
1053 private: | 1087 private: |
1054 static const int kLiteralTypeSlot = 0; | 1088 static const int kLiteralTypeSlot = 0; |
1055 static const int kElementsSlot = 1; | 1089 static const int kElementsSlot = 1; |
1056 | 1090 |
1057 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); | 1091 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); |
1058 }; | 1092 }; |
1059 | 1093 |
1060 void ParserBaseTraits<Parser>::AddFormalParameter( | |
1061 ParserFormalParameters* parameters, Expression* pattern, | |
1062 Expression* initializer, int initializer_end_position, bool is_rest) { | |
1063 bool is_simple = pattern->IsVariableProxy() && initializer == nullptr; | |
1064 const AstRawString* name = | |
1065 is_simple ? pattern->AsVariableProxy()->raw_name() | |
1066 : delegate()->ast_value_factory()->empty_string(); | |
1067 parameters->params.Add( | |
1068 ParserFormalParameters::Parameter(name, pattern, initializer, | |
1069 initializer_end_position, is_rest), | |
1070 parameters->scope->zone()); | |
1071 } | |
1072 | |
1073 void ParserBaseTraits<Parser>::DeclareFormalParameter( | |
1074 DeclarationScope* scope, const ParserFormalParameters::Parameter& parameter, | |
1075 Type::ExpressionClassifier* classifier) { | |
1076 bool is_duplicate = false; | |
1077 bool is_simple = classifier->is_simple_parameter_list(); | |
1078 auto name = is_simple || parameter.is_rest | |
1079 ? parameter.name | |
1080 : delegate()->ast_value_factory()->empty_string(); | |
1081 auto mode = is_simple || parameter.is_rest ? VAR : TEMPORARY; | |
1082 if (!is_simple) scope->SetHasNonSimpleParameters(); | |
1083 bool is_optional = parameter.initializer != nullptr; | |
1084 Variable* var = | |
1085 scope->DeclareParameter(name, mode, is_optional, parameter.is_rest, | |
1086 &is_duplicate, delegate()->ast_value_factory()); | |
1087 if (is_duplicate) { | |
1088 classifier->RecordDuplicateFormalParameterError( | |
1089 delegate()->scanner()->location()); | |
1090 } | |
1091 if (is_sloppy(scope->language_mode())) { | |
1092 // TODO(sigurds) Mark every parameter as maybe assigned. This is a | |
1093 // conservative approximation necessary to account for parameters | |
1094 // that are assigned via the arguments array. | |
1095 var->set_maybe_assigned(); | |
1096 } | |
1097 } | |
1098 | |
1099 void ParserBaseTraits<Parser>::AddParameterInitializationBlock( | |
1100 const ParserFormalParameters& parameters, | |
1101 ZoneList<v8::internal::Statement*>* body, bool is_async, bool* ok) { | |
1102 if (!parameters.is_simple) { | |
1103 auto* init_block = | |
1104 delegate()->BuildParameterInitializationBlock(parameters, ok); | |
1105 if (!*ok) return; | |
1106 | |
1107 if (is_async) { | |
1108 init_block = delegate()->BuildRejectPromiseOnException(init_block); | |
1109 } | |
1110 | |
1111 if (init_block != nullptr) { | |
1112 body->Add(init_block, delegate()->zone()); | |
1113 } | |
1114 } | |
1115 } | |
1116 | |
1117 } // namespace internal | 1094 } // namespace internal |
1118 } // namespace v8 | 1095 } // namespace v8 |
1119 | 1096 |
1120 #endif // V8_PARSING_PARSER_H_ | 1097 #endif // V8_PARSING_PARSER_H_ |
OLD | NEW |