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