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_BASE_H | 5 #ifndef V8_PARSING_PARSER_BASE_H |
| 6 #define V8_PARSING_PARSER_BASE_H | 6 #define V8_PARSING_PARSER_BASE_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/bailout-reason.h" | 10 #include "src/bailout-reason.h" |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 ast_node_factory_(ast_value_factory), | 202 ast_node_factory_(ast_value_factory), |
| 203 runtime_call_stats_(runtime_call_stats), | 203 runtime_call_stats_(runtime_call_stats), |
| 204 parsing_on_main_thread_(parsing_on_main_thread), | 204 parsing_on_main_thread_(parsing_on_main_thread), |
| 205 parsing_module_(false), | 205 parsing_module_(false), |
| 206 stack_limit_(stack_limit), | 206 stack_limit_(stack_limit), |
| 207 zone_(zone), | 207 zone_(zone), |
| 208 classifier_(nullptr), | 208 classifier_(nullptr), |
| 209 scanner_(scanner), | 209 scanner_(scanner), |
| 210 stack_overflow_(false), | 210 stack_overflow_(false), |
| 211 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), | 211 default_eager_compile_hint_(FunctionLiteral::kShouldLazyCompile), |
| 212 function_literal_num_(0), | |
| 212 allow_natives_(false), | 213 allow_natives_(false), |
| 213 allow_tailcalls_(false), | 214 allow_tailcalls_(false), |
| 214 allow_harmony_do_expressions_(false), | 215 allow_harmony_do_expressions_(false), |
| 215 allow_harmony_function_sent_(false), | 216 allow_harmony_function_sent_(false), |
| 216 allow_harmony_async_await_(false), | 217 allow_harmony_async_await_(false), |
| 217 allow_harmony_restrictive_generators_(false), | 218 allow_harmony_restrictive_generators_(false), |
| 218 allow_harmony_trailing_commas_(false), | 219 allow_harmony_trailing_commas_(false), |
| 219 allow_harmony_class_fields_(false) {} | 220 allow_harmony_class_fields_(false) {} |
| 220 | 221 |
| 221 #define ALLOW_ACCESSORS(name) \ | 222 #define ALLOW_ACCESSORS(name) \ |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 239 | 240 |
| 240 void set_default_eager_compile_hint( | 241 void set_default_eager_compile_hint( |
| 241 FunctionLiteral::EagerCompileHint eager_compile_hint) { | 242 FunctionLiteral::EagerCompileHint eager_compile_hint) { |
| 242 default_eager_compile_hint_ = eager_compile_hint; | 243 default_eager_compile_hint_ = eager_compile_hint; |
| 243 } | 244 } |
| 244 | 245 |
| 245 FunctionLiteral::EagerCompileHint default_eager_compile_hint() const { | 246 FunctionLiteral::EagerCompileHint default_eager_compile_hint() const { |
| 246 return default_eager_compile_hint_; | 247 return default_eager_compile_hint_; |
| 247 } | 248 } |
| 248 | 249 |
| 250 int GetNextFunctionLiteralNum() { return ++function_literal_num_; } | |
| 251 | |
| 252 void SkipFunctionLiterals(int delta) { function_literal_num_ += delta; } | |
| 253 | |
| 254 void ResetFunctionLiteralNum() { function_literal_num_ = 0; } | |
| 255 | |
| 249 Zone* zone() const { return zone_; } | 256 Zone* zone() const { return zone_; } |
| 250 | 257 |
| 251 protected: | 258 protected: |
| 252 friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>; | 259 friend class v8::internal::ExpressionClassifier<ParserTypes<Impl>>; |
| 253 | 260 |
| 254 enum AllowRestrictedIdentifiers { | 261 enum AllowRestrictedIdentifiers { |
| 255 kAllowRestrictedIdentifiers, | 262 kAllowRestrictedIdentifiers, |
| 256 kDontAllowRestrictedIdentifiers | 263 kDontAllowRestrictedIdentifiers |
| 257 }; | 264 }; |
| 258 | 265 |
| (...skipping 888 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1147 }; | 1154 }; |
| 1148 | 1155 |
| 1149 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); | 1156 bool SetPropertyKindFromToken(Token::Value token, PropertyKind* kind); |
| 1150 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, | 1157 ExpressionT ParsePropertyName(IdentifierT* name, PropertyKind* kind, |
| 1151 bool* is_generator, bool* is_get, bool* is_set, | 1158 bool* is_generator, bool* is_get, bool* is_set, |
| 1152 bool* is_async, bool* is_computed_name, | 1159 bool* is_async, bool* is_computed_name, |
| 1153 bool* ok); | 1160 bool* ok); |
| 1154 ExpressionT ParseObjectLiteral(bool* ok); | 1161 ExpressionT ParseObjectLiteral(bool* ok); |
| 1155 ClassLiteralPropertyT ParseClassPropertyDefinition( | 1162 ClassLiteralPropertyT ParseClassPropertyDefinition( |
| 1156 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, | 1163 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
| 1157 bool* has_seen_constructor, bool* ok); | 1164 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, |
| 1165 bool* is_static, bool* ok); | |
| 1158 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, | 1166 FunctionLiteralT ParseClassFieldForInitializer(bool has_initializer, |
| 1159 bool* ok); | 1167 bool* ok); |
| 1160 ObjectLiteralPropertyT ParseObjectPropertyDefinition( | 1168 ObjectLiteralPropertyT ParseObjectPropertyDefinition( |
| 1161 ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok); | 1169 ObjectLiteralChecker* checker, bool* is_computed_name, bool* ok); |
| 1162 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1170 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
| 1163 bool maybe_arrow, bool* ok); | 1171 bool maybe_arrow, bool* ok); |
| 1164 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, | 1172 ExpressionListT ParseArguments(Scanner::Location* first_spread_pos, |
| 1165 bool* ok) { | 1173 bool* ok) { |
| 1166 return ParseArguments(first_spread_pos, false, ok); | 1174 return ParseArguments(first_spread_pos, false, ok); |
| 1167 } | 1175 } |
| 1168 | 1176 |
| 1169 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); | 1177 ExpressionT ParseAssignmentExpression(bool accept_IN, bool* ok); |
| 1170 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); | 1178 ExpressionT ParseYieldExpression(bool accept_IN, bool* ok); |
| 1171 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); | 1179 ExpressionT ParseConditionalExpression(bool accept_IN, bool* ok); |
| 1172 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); | 1180 ExpressionT ParseBinaryExpression(int prec, bool accept_IN, bool* ok); |
| 1173 ExpressionT ParseUnaryExpression(bool* ok); | 1181 ExpressionT ParseUnaryExpression(bool* ok); |
| 1174 ExpressionT ParsePostfixExpression(bool* ok); | 1182 ExpressionT ParsePostfixExpression(bool* ok); |
| 1175 ExpressionT ParseLeftHandSideExpression(bool* ok); | 1183 ExpressionT ParseLeftHandSideExpression(bool* ok); |
| 1176 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok); | 1184 ExpressionT ParseMemberWithNewPrefixesExpression(bool* is_async, bool* ok); |
| 1177 ExpressionT ParseMemberExpression(bool* is_async, bool* ok); | 1185 ExpressionT ParseMemberExpression(bool* is_async, bool* ok); |
| 1178 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, | 1186 ExpressionT ParseMemberExpressionContinuation(ExpressionT expression, |
| 1179 bool* is_async, bool* ok); | 1187 bool* is_async, bool* ok); |
| 1180 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, | 1188 ExpressionT ParseArrowFunctionLiteral(bool accept_IN, |
| 1181 const FormalParametersT& parameters, | 1189 const FormalParametersT& parameters, |
| 1182 bool* ok); | 1190 int function_literal_num, bool* ok); |
| 1183 void ParseAsyncFunctionBody(Scope* scope, StatementListT body, | 1191 void ParseAsyncFunctionBody(Scope* scope, StatementListT body, |
| 1184 FunctionKind kind, FunctionBodyType type, | 1192 FunctionKind kind, FunctionBodyType type, |
| 1185 bool accept_IN, int pos, bool* ok); | 1193 bool accept_IN, int pos, bool* ok); |
| 1186 ExpressionT ParseAsyncFunctionLiteral(bool* ok); | 1194 ExpressionT ParseAsyncFunctionLiteral(bool* ok); |
| 1187 ExpressionT ParseClassLiteral(IdentifierT name, | 1195 ExpressionT ParseClassLiteral(IdentifierT name, |
| 1188 Scanner::Location class_name_location, | 1196 Scanner::Location class_name_location, |
| 1189 bool name_is_strict_reserved, | 1197 bool name_is_strict_reserved, |
| 1190 int class_token_pos, bool* ok); | 1198 int class_token_pos, bool* ok); |
| 1191 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); | 1199 ExpressionT ParseTemplateLiteral(ExpressionT tag, int start, bool* ok); |
| 1192 ExpressionT ParseSuperExpression(bool is_new, bool* ok); | 1200 ExpressionT ParseSuperExpression(bool is_new, bool* ok); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1431 | 1439 |
| 1432 private: | 1440 private: |
| 1433 Zone* zone_; | 1441 Zone* zone_; |
| 1434 ExpressionClassifier* classifier_; | 1442 ExpressionClassifier* classifier_; |
| 1435 | 1443 |
| 1436 Scanner* scanner_; | 1444 Scanner* scanner_; |
| 1437 bool stack_overflow_; | 1445 bool stack_overflow_; |
| 1438 | 1446 |
| 1439 FunctionLiteral::EagerCompileHint default_eager_compile_hint_; | 1447 FunctionLiteral::EagerCompileHint default_eager_compile_hint_; |
| 1440 | 1448 |
| 1449 int function_literal_num_; | |
| 1450 | |
| 1441 bool allow_natives_; | 1451 bool allow_natives_; |
| 1442 bool allow_tailcalls_; | 1452 bool allow_tailcalls_; |
| 1443 bool allow_harmony_do_expressions_; | 1453 bool allow_harmony_do_expressions_; |
| 1444 bool allow_harmony_function_sent_; | 1454 bool allow_harmony_function_sent_; |
| 1445 bool allow_harmony_async_await_; | 1455 bool allow_harmony_async_await_; |
| 1446 bool allow_harmony_restrictive_generators_; | 1456 bool allow_harmony_restrictive_generators_; |
| 1447 bool allow_harmony_trailing_commas_; | 1457 bool allow_harmony_trailing_commas_; |
| 1448 bool allow_harmony_class_fields_; | 1458 bool allow_harmony_class_fields_; |
| 1449 | 1459 |
| 1450 friend class DiscardableZoneScope; | 1460 friend class DiscardableZoneScope; |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2107 impl()->PushLiteralName(*name); | 2117 impl()->PushLiteralName(*name); |
| 2108 | 2118 |
| 2109 uint32_t index; | 2119 uint32_t index; |
| 2110 return impl()->IsArrayIndex(*name, &index) | 2120 return impl()->IsArrayIndex(*name, &index) |
| 2111 ? factory()->NewNumberLiteral(index, pos) | 2121 ? factory()->NewNumberLiteral(index, pos) |
| 2112 : factory()->NewStringLiteral(*name, pos); | 2122 : factory()->NewStringLiteral(*name, pos); |
| 2113 } | 2123 } |
| 2114 | 2124 |
| 2115 template <typename Impl> | 2125 template <typename Impl> |
| 2116 typename ParserBase<Impl>::ClassLiteralPropertyT | 2126 typename ParserBase<Impl>::ClassLiteralPropertyT |
| 2117 ParserBase<Impl>::ParseClassPropertyDefinition(ClassLiteralChecker* checker, | 2127 ParserBase<Impl>::ParseClassPropertyDefinition( |
| 2118 bool has_extends, | 2128 ClassLiteralChecker* checker, bool has_extends, bool* is_computed_name, |
| 2119 bool* is_computed_name, | 2129 bool* has_seen_constructor, ClassLiteralProperty::Kind* property_kind, |
| 2120 bool* has_seen_constructor, | 2130 bool* is_static, bool* ok) { |
| 2121 bool* ok) { | |
| 2122 DCHECK(has_seen_constructor != nullptr); | 2131 DCHECK(has_seen_constructor != nullptr); |
| 2123 bool is_get = false; | 2132 bool is_get = false; |
| 2124 bool is_set = false; | 2133 bool is_set = false; |
| 2125 bool is_generator = false; | 2134 bool is_generator = false; |
| 2126 bool is_async = false; | 2135 bool is_async = false; |
| 2127 bool is_static = false; | 2136 *is_static = false; |
| 2137 *property_kind = ClassLiteralProperty::METHOD; | |
| 2128 PropertyKind kind = PropertyKind::kNotSet; | 2138 PropertyKind kind = PropertyKind::kNotSet; |
| 2129 | 2139 |
| 2130 Token::Value name_token = peek(); | 2140 Token::Value name_token = peek(); |
| 2131 | 2141 |
| 2132 IdentifierT name = impl()->EmptyIdentifier(); | 2142 IdentifierT name = impl()->EmptyIdentifier(); |
| 2133 ExpressionT name_expression; | 2143 ExpressionT name_expression; |
| 2134 if (name_token == Token::STATIC) { | 2144 if (name_token == Token::STATIC) { |
| 2135 Consume(Token::STATIC); | 2145 Consume(Token::STATIC); |
| 2136 if (peek() == Token::LPAREN) { | 2146 if (peek() == Token::LPAREN) { |
| 2137 kind = PropertyKind::kMethodProperty; | 2147 kind = PropertyKind::kMethodProperty; |
| 2138 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2148 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
| 2139 name_expression = factory()->NewStringLiteral(name, position()); | 2149 name_expression = factory()->NewStringLiteral(name, position()); |
| 2140 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || | 2150 } else if (peek() == Token::ASSIGN || peek() == Token::SEMICOLON || |
| 2141 peek() == Token::RBRACE) { | 2151 peek() == Token::RBRACE) { |
| 2142 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' | 2152 name = impl()->GetSymbol(); // TODO(bakkot) specialize on 'static' |
| 2143 name_expression = factory()->NewStringLiteral(name, position()); | 2153 name_expression = factory()->NewStringLiteral(name, position()); |
| 2144 } else { | 2154 } else { |
| 2145 is_static = true; | 2155 *is_static = true; |
| 2146 name_expression = ParsePropertyName( | 2156 name_expression = ParsePropertyName( |
| 2147 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2157 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
| 2148 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2158 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2149 } | 2159 } |
| 2150 } else { | 2160 } else { |
| 2151 name_expression = ParsePropertyName( | 2161 name_expression = ParsePropertyName( |
| 2152 &name, &kind, &is_generator, &is_get, &is_set, &is_async, | 2162 &name, &kind, &is_generator, &is_get, &is_set, &is_async, |
| 2153 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2163 is_computed_name, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2154 } | 2164 } |
| 2155 | 2165 |
| 2156 switch (kind) { | 2166 switch (kind) { |
| 2157 case PropertyKind::kClassField: | 2167 case PropertyKind::kClassField: |
| 2158 case PropertyKind::kNotSet: // This case is a name followed by a name or | 2168 case PropertyKind::kNotSet: // This case is a name followed by a name or |
| 2159 // other property. Here we have to assume | 2169 // other property. Here we have to assume |
| 2160 // that's an uninitialized field followed by a | 2170 // that's an uninitialized field followed by a |
| 2161 // linebreak followed by a property, with ASI | 2171 // linebreak followed by a property, with ASI |
| 2162 // adding the semicolon. If not, there will be | 2172 // adding the semicolon. If not, there will be |
| 2163 // a syntax error after parsing the first name | 2173 // a syntax error after parsing the first name |
| 2164 // as an uninitialized field. | 2174 // as an uninitialized field. |
| 2165 case PropertyKind::kShorthandProperty: | 2175 case PropertyKind::kShorthandProperty: |
| 2166 case PropertyKind::kValueProperty: | 2176 case PropertyKind::kValueProperty: |
| 2167 if (allow_harmony_class_fields()) { | 2177 if (allow_harmony_class_fields()) { |
| 2168 bool has_initializer = Check(Token::ASSIGN); | 2178 bool has_initializer = Check(Token::ASSIGN); |
| 2169 ExpressionT function_literal = ParseClassFieldForInitializer( | 2179 ExpressionT function_literal = ParseClassFieldForInitializer( |
| 2170 has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2180 has_initializer, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2171 ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2181 ExpectSemicolon(CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2182 *property_kind = ClassLiteralProperty::FIELD; | |
| 2172 return factory()->NewClassLiteralProperty( | 2183 return factory()->NewClassLiteralProperty( |
| 2173 name_expression, function_literal, ClassLiteralProperty::FIELD, | 2184 name_expression, function_literal, *property_kind, *is_static, |
| 2174 is_static, *is_computed_name); | 2185 *is_computed_name); |
| 2175 } else { | 2186 } else { |
| 2176 ReportUnexpectedToken(Next()); | 2187 ReportUnexpectedToken(Next()); |
| 2177 *ok = false; | 2188 *ok = false; |
| 2178 return impl()->EmptyClassLiteralProperty(); | 2189 return impl()->EmptyClassLiteralProperty(); |
| 2179 } | 2190 } |
| 2180 | 2191 |
| 2181 case PropertyKind::kMethodProperty: { | 2192 case PropertyKind::kMethodProperty: { |
| 2182 DCHECK(!is_get && !is_set); | 2193 DCHECK(!is_get && !is_set); |
| 2183 | 2194 |
| 2184 // MethodDefinition | 2195 // MethodDefinition |
| 2185 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2196 // PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2186 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' | 2197 // '*' PropertyName '(' StrictFormalParameters ')' '{' FunctionBody '}' |
| 2187 | 2198 |
| 2188 if (!*is_computed_name) { | 2199 if (!*is_computed_name) { |
| 2189 checker->CheckClassMethodName( | 2200 checker->CheckClassMethodName( |
| 2190 name_token, PropertyKind::kMethodProperty, is_generator, is_async, | 2201 name_token, PropertyKind::kMethodProperty, is_generator, is_async, |
| 2191 is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2202 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2192 } | 2203 } |
| 2193 | 2204 |
| 2194 FunctionKind kind = is_generator | 2205 FunctionKind kind = is_generator |
| 2195 ? FunctionKind::kConciseGeneratorMethod | 2206 ? FunctionKind::kConciseGeneratorMethod |
| 2196 : is_async ? FunctionKind::kAsyncConciseMethod | 2207 : is_async ? FunctionKind::kAsyncConciseMethod |
| 2197 : FunctionKind::kConciseMethod; | 2208 : FunctionKind::kConciseMethod; |
| 2198 | 2209 |
| 2199 if (!is_static && impl()->IsConstructor(name)) { | 2210 if (!*is_static && impl()->IsConstructor(name)) { |
| 2200 *has_seen_constructor = true; | 2211 *has_seen_constructor = true; |
| 2201 kind = has_extends ? FunctionKind::kSubclassConstructor | 2212 kind = has_extends ? FunctionKind::kSubclassConstructor |
| 2202 : FunctionKind::kBaseConstructor; | 2213 : FunctionKind::kBaseConstructor; |
| 2203 } | 2214 } |
| 2204 | 2215 |
| 2205 ExpressionT value = impl()->ParseFunctionLiteral( | 2216 ExpressionT value = impl()->ParseFunctionLiteral( |
| 2206 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2217 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 2207 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2218 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| 2208 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2219 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2209 | 2220 |
| 2221 *property_kind = ClassLiteralProperty::METHOD; | |
| 2210 return factory()->NewClassLiteralProperty(name_expression, value, | 2222 return factory()->NewClassLiteralProperty(name_expression, value, |
| 2211 ClassLiteralProperty::METHOD, | 2223 *property_kind, *is_static, |
| 2212 is_static, *is_computed_name); | 2224 *is_computed_name); |
| 2213 } | 2225 } |
| 2214 | 2226 |
| 2215 case PropertyKind::kAccessorProperty: { | 2227 case PropertyKind::kAccessorProperty: { |
| 2216 DCHECK((is_get || is_set) && !is_generator && !is_async); | 2228 DCHECK((is_get || is_set) && !is_generator && !is_async); |
| 2217 | 2229 |
| 2218 if (!*is_computed_name) { | 2230 if (!*is_computed_name) { |
| 2219 checker->CheckClassMethodName( | 2231 checker->CheckClassMethodName( |
| 2220 name_token, PropertyKind::kAccessorProperty, false, false, | 2232 name_token, PropertyKind::kAccessorProperty, false, false, |
| 2221 is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2233 *is_static, CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2222 // Make sure the name expression is a string since we need a Name for | 2234 // Make sure the name expression is a string since we need a Name for |
| 2223 // Runtime_DefineAccessorPropertyUnchecked and since we can determine | 2235 // Runtime_DefineAccessorPropertyUnchecked and since we can determine |
| 2224 // this statically we can skip the extra runtime check. | 2236 // this statically we can skip the extra runtime check. |
| 2225 name_expression = | 2237 name_expression = |
| 2226 factory()->NewStringLiteral(name, name_expression->position()); | 2238 factory()->NewStringLiteral(name, name_expression->position()); |
| 2227 } | 2239 } |
| 2228 | 2240 |
| 2229 FunctionKind kind = is_get ? FunctionKind::kGetterFunction | 2241 FunctionKind kind = is_get ? FunctionKind::kGetterFunction |
| 2230 : FunctionKind::kSetterFunction; | 2242 : FunctionKind::kSetterFunction; |
| 2231 | 2243 |
| 2232 FunctionLiteralT value = impl()->ParseFunctionLiteral( | 2244 FunctionLiteralT value = impl()->ParseFunctionLiteral( |
| 2233 name, scanner()->location(), kSkipFunctionNameCheck, kind, | 2245 name, scanner()->location(), kSkipFunctionNameCheck, kind, |
| 2234 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, | 2246 kNoSourcePosition, FunctionLiteral::kAccessorOrMethod, |
| 2235 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); | 2247 language_mode(), CHECK_OK_CUSTOM(EmptyClassLiteralProperty)); |
| 2236 | 2248 |
| 2237 if (!*is_computed_name) { | 2249 if (!*is_computed_name) { |
| 2238 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); | 2250 impl()->AddAccessorPrefixToFunctionName(is_get, value, name); |
| 2239 } | 2251 } |
| 2240 | 2252 |
| 2241 return factory()->NewClassLiteralProperty( | 2253 *property_kind = |
| 2242 name_expression, value, | 2254 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER; |
| 2243 is_get ? ClassLiteralProperty::GETTER : ClassLiteralProperty::SETTER, | 2255 return factory()->NewClassLiteralProperty(name_expression, value, |
| 2244 is_static, *is_computed_name); | 2256 *property_kind, *is_static, |
| 2257 *is_computed_name); | |
| 2245 } | 2258 } |
| 2246 } | 2259 } |
| 2247 UNREACHABLE(); | 2260 UNREACHABLE(); |
| 2248 return impl()->EmptyClassLiteralProperty(); | 2261 return impl()->EmptyClassLiteralProperty(); |
| 2249 } | 2262 } |
| 2250 | 2263 |
| 2251 template <typename Impl> | 2264 template <typename Impl> |
| 2252 typename ParserBase<Impl>::FunctionLiteralT | 2265 typename ParserBase<Impl>::FunctionLiteralT |
| 2253 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, | 2266 ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer, |
| 2254 bool* ok) { | 2267 bool* ok) { |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 2272 } | 2285 } |
| 2273 initializer_scope->set_end_position(scanner()->location().end_pos); | 2286 initializer_scope->set_end_position(scanner()->location().end_pos); |
| 2274 typename Types::StatementList body = impl()->NewStatementList(1); | 2287 typename Types::StatementList body = impl()->NewStatementList(1); |
| 2275 body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone()); | 2288 body->Add(factory()->NewReturnStatement(value, kNoSourcePosition), zone()); |
| 2276 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 2289 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 2277 impl()->EmptyIdentifierString(), initializer_scope, body, | 2290 impl()->EmptyIdentifierString(), initializer_scope, body, |
| 2278 initializer_state.materialized_literal_count(), | 2291 initializer_state.materialized_literal_count(), |
| 2279 initializer_state.expected_property_count(), 0, 0, | 2292 initializer_state.expected_property_count(), 0, 0, |
| 2280 FunctionLiteral::kNoDuplicateParameters, | 2293 FunctionLiteral::kNoDuplicateParameters, |
| 2281 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, | 2294 FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_, |
| 2282 initializer_scope->start_position(), true); | 2295 initializer_scope->start_position(), true, GetNextFunctionLiteralNum()); |
| 2283 function_literal->set_is_class_field_initializer(true); | 2296 function_literal->set_is_class_field_initializer(true); |
| 2284 return function_literal; | 2297 return function_literal; |
| 2285 } | 2298 } |
| 2286 | 2299 |
| 2287 template <typename Impl> | 2300 template <typename Impl> |
| 2288 typename ParserBase<Impl>::ObjectLiteralPropertyT | 2301 typename ParserBase<Impl>::ObjectLiteralPropertyT |
| 2289 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, | 2302 ParserBase<Impl>::ParseObjectPropertyDefinition(ObjectLiteralChecker* checker, |
| 2290 bool* is_computed_name, | 2303 bool* is_computed_name, |
| 2291 bool* ok) { | 2304 bool* ok) { |
| 2292 bool is_get = false; | 2305 bool is_get = false; |
| (...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2609 Checkpoint checkpoint(this); | 2622 Checkpoint checkpoint(this); |
| 2610 ExpressionClassifier arrow_formals_classifier( | 2623 ExpressionClassifier arrow_formals_classifier( |
| 2611 this, classifier()->duplicate_finder()); | 2624 this, classifier()->duplicate_finder()); |
| 2612 | 2625 |
| 2613 Scope::Snapshot scope_snapshot(scope()); | 2626 Scope::Snapshot scope_snapshot(scope()); |
| 2614 | 2627 |
| 2615 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && | 2628 bool is_async = allow_harmony_async_await() && peek() == Token::ASYNC && |
| 2616 !scanner()->HasAnyLineTerminatorAfterNext() && | 2629 !scanner()->HasAnyLineTerminatorAfterNext() && |
| 2617 IsValidArrowFormalParametersStart(PeekAhead()); | 2630 IsValidArrowFormalParametersStart(PeekAhead()); |
| 2618 | 2631 |
| 2632 int function_literal_num = GetNextFunctionLiteralNum(); | |
| 2633 | |
| 2619 bool parenthesized_formals = peek() == Token::LPAREN; | 2634 bool parenthesized_formals = peek() == Token::LPAREN; |
| 2620 if (!is_async && !parenthesized_formals) { | 2635 if (!is_async && !parenthesized_formals) { |
| 2621 ArrowFormalParametersUnexpectedToken(); | 2636 ArrowFormalParametersUnexpectedToken(); |
| 2622 } | 2637 } |
| 2623 | 2638 |
| 2624 // Parse a simple, faster sub-grammar (primary expression) if it's evident | 2639 // Parse a simple, faster sub-grammar (primary expression) if it's evident |
| 2625 // that we have only a trivial expression to parse. | 2640 // that we have only a trivial expression to parse. |
| 2626 ExpressionT expression; | 2641 ExpressionT expression; |
| 2627 if (IsTrivialExpression()) { | 2642 if (IsTrivialExpression()) { |
| 2628 expression = ParsePrimaryExpression(&is_async, CHECK_OK); | 2643 expression = ParsePrimaryExpression(&is_async, CHECK_OK); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2673 | 2688 |
| 2674 checkpoint.Restore(¶meters.materialized_literals_count); | 2689 checkpoint.Restore(¶meters.materialized_literals_count); |
| 2675 | 2690 |
| 2676 scope->set_start_position(lhs_beg_pos); | 2691 scope->set_start_position(lhs_beg_pos); |
| 2677 Scanner::Location duplicate_loc = Scanner::Location::invalid(); | 2692 Scanner::Location duplicate_loc = Scanner::Location::invalid(); |
| 2678 impl()->DeclareArrowFunctionFormalParameters(¶meters, expression, loc, | 2693 impl()->DeclareArrowFunctionFormalParameters(¶meters, expression, loc, |
| 2679 &duplicate_loc, CHECK_OK); | 2694 &duplicate_loc, CHECK_OK); |
| 2680 if (duplicate_loc.IsValid()) { | 2695 if (duplicate_loc.IsValid()) { |
| 2681 classifier()->RecordDuplicateFormalParameterError(duplicate_loc); | 2696 classifier()->RecordDuplicateFormalParameterError(duplicate_loc); |
| 2682 } | 2697 } |
| 2683 expression = ParseArrowFunctionLiteral(accept_IN, parameters, CHECK_OK); | 2698 expression = ParseArrowFunctionLiteral(accept_IN, parameters, |
| 2699 function_literal_num, CHECK_OK); | |
| 2684 impl()->Discard(); | 2700 impl()->Discard(); |
| 2685 classifier()->RecordPatternError(arrow_loc, | 2701 classifier()->RecordPatternError(arrow_loc, |
| 2686 MessageTemplate::kUnexpectedToken, | 2702 MessageTemplate::kUnexpectedToken, |
| 2687 Token::String(Token::ARROW)); | 2703 Token::String(Token::ARROW)); |
| 2688 | 2704 |
| 2689 if (fni_ != nullptr) fni_->Infer(); | 2705 if (fni_ != nullptr) fni_->Infer(); |
| 2690 | 2706 |
| 2691 return expression; | 2707 return expression; |
| 2692 } | 2708 } |
| 2693 | 2709 |
| 2710 // Reset function_literal_num_ if we didn't parse an arrow function, and | |
| 2711 // the expression didn't contain other functions either. | |
| 2712 if (function_literal_num == function_literal_num_) { | |
|
marja
2016/11/18 10:48:04
Looks like we could just put the function literal
jochen (gone - plz use gerrit)
2016/11/21 08:03:47
I changed the code to not allocate a function lite
| |
| 2713 --function_literal_num_; | |
| 2714 } | |
| 2715 | |
| 2694 // "expression" was not itself an arrow function parameter list, but it might | 2716 // "expression" was not itself an arrow function parameter list, but it might |
| 2695 // form part of one. Propagate speculative formal parameter error locations | 2717 // form part of one. Propagate speculative formal parameter error locations |
| 2696 // (including those for binding patterns, since formal parameters can | 2718 // (including those for binding patterns, since formal parameters can |
| 2697 // themselves contain binding patterns). | 2719 // themselves contain binding patterns). |
| 2698 unsigned productions = ExpressionClassifier::AllProductions & | 2720 unsigned productions = ExpressionClassifier::AllProductions & |
| 2699 ~ExpressionClassifier::ArrowFormalParametersProduction; | 2721 ~ExpressionClassifier::ArrowFormalParametersProduction; |
| 2700 | 2722 |
| 2701 // Parenthesized identifiers and property references are allowed as part | 2723 // Parenthesized identifiers and property references are allowed as part |
| 2702 // of a larger assignment pattern, even though parenthesized patterns | 2724 // of a larger assignment pattern, even though parenthesized patterns |
| 2703 // themselves are not allowed, e.g., "[(x)] = []". Only accumulate | 2725 // themselves are not allowed, e.g., "[(x)] = []". Only accumulate |
| (...skipping 1178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3882 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { | 3904 peek_ahead == Token::SEMICOLON || peek_ahead == Token::RBRACK) { |
| 3883 return true; | 3905 return true; |
| 3884 } | 3906 } |
| 3885 } | 3907 } |
| 3886 return false; | 3908 return false; |
| 3887 } | 3909 } |
| 3888 | 3910 |
| 3889 template <typename Impl> | 3911 template <typename Impl> |
| 3890 typename ParserBase<Impl>::ExpressionT | 3912 typename ParserBase<Impl>::ExpressionT |
| 3891 ParserBase<Impl>::ParseArrowFunctionLiteral( | 3913 ParserBase<Impl>::ParseArrowFunctionLiteral( |
| 3892 bool accept_IN, const FormalParametersT& formal_parameters, bool* ok) { | 3914 bool accept_IN, const FormalParametersT& formal_parameters, |
| 3915 int function_literal_num, bool* ok) { | |
| 3893 const RuntimeCallStats::CounterId counters[2][2] = { | 3916 const RuntimeCallStats::CounterId counters[2][2] = { |
| 3894 {&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral, | 3917 {&RuntimeCallStats::ParseBackgroundArrowFunctionLiteral, |
| 3895 &RuntimeCallStats::ParseArrowFunctionLiteral}, | 3918 &RuntimeCallStats::ParseArrowFunctionLiteral}, |
| 3896 {&RuntimeCallStats::PreParseBackgroundArrowFunctionLiteral, | 3919 {&RuntimeCallStats::PreParseBackgroundArrowFunctionLiteral, |
| 3897 &RuntimeCallStats::PreParseArrowFunctionLiteral}}; | 3920 &RuntimeCallStats::PreParseArrowFunctionLiteral}}; |
| 3898 RuntimeCallTimerScope runtime_timer( | 3921 RuntimeCallTimerScope runtime_timer( |
| 3899 runtime_call_stats_, | 3922 runtime_call_stats_, |
| 3900 counters[Impl::IsPreParser()][parsing_on_main_thread_]); | 3923 counters[Impl::IsPreParser()][parsing_on_main_thread_]); |
| 3901 | 3924 |
| 3902 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { | 3925 if (peek() == Token::ARROW && scanner_->HasAnyLineTerminatorBeforeNext()) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4041 PrintF(" [%s]: %i-%i (arrow function)\n", | 4064 PrintF(" [%s]: %i-%i (arrow function)\n", |
| 4042 is_lazy_top_level_function ? "Preparse no-resolution" : "Full parse", | 4065 is_lazy_top_level_function ? "Preparse no-resolution" : "Full parse", |
| 4043 scope->start_position(), scope->end_position()); | 4066 scope->start_position(), scope->end_position()); |
| 4044 } | 4067 } |
| 4045 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( | 4068 FunctionLiteralT function_literal = factory()->NewFunctionLiteral( |
| 4046 impl()->EmptyIdentifierString(), formal_parameters.scope, body, | 4069 impl()->EmptyIdentifierString(), formal_parameters.scope, body, |
| 4047 materialized_literal_count, expected_property_count, | 4070 materialized_literal_count, expected_property_count, |
| 4048 formal_parameters.num_parameters(), formal_parameters.function_length, | 4071 formal_parameters.num_parameters(), formal_parameters.function_length, |
| 4049 FunctionLiteral::kNoDuplicateParameters, | 4072 FunctionLiteral::kNoDuplicateParameters, |
| 4050 FunctionLiteral::kAnonymousExpression, eager_compile_hint, | 4073 FunctionLiteral::kAnonymousExpression, eager_compile_hint, |
| 4051 formal_parameters.scope->start_position(), has_braces); | 4074 formal_parameters.scope->start_position(), has_braces, |
| 4075 function_literal_num); | |
| 4052 | 4076 |
| 4053 function_literal->set_function_token_position( | 4077 function_literal->set_function_token_position( |
| 4054 formal_parameters.scope->start_position()); | 4078 formal_parameters.scope->start_position()); |
| 4055 if (should_be_used_once_hint) { | 4079 if (should_be_used_once_hint) { |
| 4056 function_literal->set_should_be_used_once_hint(); | 4080 function_literal->set_should_be_used_once_hint(); |
| 4057 } | 4081 } |
| 4058 | 4082 |
| 4059 impl()->AddFunctionForNameInference(function_literal); | 4083 impl()->AddFunctionForNameInference(function_literal); |
| 4060 | 4084 |
| 4061 return function_literal; | 4085 return function_literal; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4099 ClassLiteralChecker checker(this); | 4123 ClassLiteralChecker checker(this); |
| 4100 | 4124 |
| 4101 Expect(Token::LBRACE, CHECK_OK); | 4125 Expect(Token::LBRACE, CHECK_OK); |
| 4102 | 4126 |
| 4103 const bool has_extends = !impl()->IsEmptyExpression(class_info.extends); | 4127 const bool has_extends = !impl()->IsEmptyExpression(class_info.extends); |
| 4104 while (peek() != Token::RBRACE) { | 4128 while (peek() != Token::RBRACE) { |
| 4105 if (Check(Token::SEMICOLON)) continue; | 4129 if (Check(Token::SEMICOLON)) continue; |
| 4106 FuncNameInferrer::State fni_state(fni_); | 4130 FuncNameInferrer::State fni_state(fni_); |
| 4107 bool is_computed_name = false; // Classes do not care about computed | 4131 bool is_computed_name = false; // Classes do not care about computed |
| 4108 // property names here. | 4132 // property names here. |
| 4133 bool is_static; | |
| 4134 ClassLiteralProperty::Kind property_kind; | |
| 4109 ExpressionClassifier property_classifier(this); | 4135 ExpressionClassifier property_classifier(this); |
| 4110 ClassLiteralPropertyT property = ParseClassPropertyDefinition( | 4136 ClassLiteralPropertyT property = ParseClassPropertyDefinition( |
| 4111 &checker, has_extends, &is_computed_name, | 4137 &checker, has_extends, &is_computed_name, |
| 4112 &class_info.has_seen_constructor, CHECK_OK); | 4138 &class_info.has_seen_constructor, &property_kind, &is_static, CHECK_OK); |
| 4113 impl()->RewriteNonPattern(CHECK_OK); | 4139 impl()->RewriteNonPattern(CHECK_OK); |
| 4114 impl()->AccumulateFormalParameterContainmentErrors(); | 4140 impl()->AccumulateFormalParameterContainmentErrors(); |
| 4115 | 4141 |
| 4116 impl()->DeclareClassProperty(name, property, &class_info, CHECK_OK); | 4142 impl()->DeclareClassProperty(name, property, property_kind, is_static, |
| 4143 &class_info, CHECK_OK); | |
| 4117 impl()->InferFunctionName(); | 4144 impl()->InferFunctionName(); |
| 4118 } | 4145 } |
| 4119 | 4146 |
| 4120 Expect(Token::RBRACE, CHECK_OK); | 4147 Expect(Token::RBRACE, CHECK_OK); |
| 4121 return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok); | 4148 return impl()->RewriteClassLiteral(name, &class_info, class_token_pos, ok); |
| 4122 } | 4149 } |
| 4123 | 4150 |
| 4124 template <typename Impl> | 4151 template <typename Impl> |
| 4125 void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body, | 4152 void ParserBase<Impl>::ParseAsyncFunctionBody(Scope* scope, StatementListT body, |
| 4126 FunctionKind kind, | 4153 FunctionKind kind, |
| (...skipping 1331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5458 has_seen_constructor_ = true; | 5485 has_seen_constructor_ = true; |
| 5459 return; | 5486 return; |
| 5460 } | 5487 } |
| 5461 } | 5488 } |
| 5462 | 5489 |
| 5463 | 5490 |
| 5464 } // namespace internal | 5491 } // namespace internal |
| 5465 } // namespace v8 | 5492 } // namespace v8 |
| 5466 | 5493 |
| 5467 #endif // V8_PARSING_PARSER_BASE_H | 5494 #endif // V8_PARSING_PARSER_BASE_H |
| OLD | NEW |