| 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 #include "src/parsing/parser.h" | 5 #include "src/parsing/parser.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/api.h" | 9 #include "src/api.h" |
| 10 #include "src/ast/ast-expression-rewriter.h" | 10 #include "src/ast/ast-expression-rewriter.h" |
| (...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 144 cached_parse_data_ = NULL; | 144 cached_parse_data_ = NULL; |
| 145 } else { | 145 } else { |
| 146 DCHECK(info->cached_data() != NULL); | 146 DCHECK(info->cached_data() != NULL); |
| 147 if (compile_options_ == ScriptCompiler::kConsumeParserCache) { | 147 if (compile_options_ == ScriptCompiler::kConsumeParserCache) { |
| 148 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); | 148 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 } | 151 } |
| 152 | 152 |
| 153 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, | 153 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, |
| 154 bool call_super, int pos, | 154 bool call_super, |
| 155 int end_pos, | 155 bool requires_class_field_init, |
| 156 int pos, int end_pos, |
| 156 LanguageMode language_mode) { | 157 LanguageMode language_mode) { |
| 157 int materialized_literal_count = -1; | 158 int materialized_literal_count = -1; |
| 158 int expected_property_count = -1; | 159 int expected_property_count = -1; |
| 159 int parameter_count = 0; | 160 int parameter_count = 0; |
| 160 if (name == nullptr) name = ast_value_factory()->empty_string(); | 161 if (name == nullptr) name = ast_value_factory()->empty_string(); |
| 161 | 162 |
| 162 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor | 163 FunctionKind kind = call_super ? FunctionKind::kDefaultSubclassConstructor |
| 163 : FunctionKind::kDefaultBaseConstructor; | 164 : FunctionKind::kDefaultBaseConstructor; |
| 164 DeclarationScope* function_scope = NewFunctionScope(kind); | 165 DeclarationScope* function_scope = NewFunctionScope(kind); |
| 165 SetLanguageMode(function_scope, | 166 SetLanguageMode(function_scope, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 expected_property_count = function_state.expected_property_count(); | 215 expected_property_count = function_state.expected_property_count(); |
| 215 } | 216 } |
| 216 | 217 |
| 217 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( | 218 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
| 218 name, function_scope, body, materialized_literal_count, | 219 name, function_scope, body, materialized_literal_count, |
| 219 expected_property_count, parameter_count, | 220 expected_property_count, parameter_count, |
| 220 FunctionLiteral::kNoDuplicateParameters, | 221 FunctionLiteral::kNoDuplicateParameters, |
| 221 FunctionLiteral::kAnonymousExpression, | 222 FunctionLiteral::kAnonymousExpression, |
| 222 FunctionLiteral::kShouldLazyCompile, kind, pos); | 223 FunctionLiteral::kShouldLazyCompile, kind, pos); |
| 223 | 224 |
| 225 function_literal->set_requires_class_field_init(requires_class_field_init); |
| 226 |
| 224 return function_literal; | 227 return function_literal; |
| 225 } | 228 } |
| 226 | 229 |
| 227 | 230 |
| 228 // ---------------------------------------------------------------------------- | 231 // ---------------------------------------------------------------------------- |
| 229 // Target is a support class to facilitate manipulation of the | 232 // Target is a support class to facilitate manipulation of the |
| 230 // Parser's target_stack_ (the stack of potential 'break' and | 233 // Parser's target_stack_ (the stack of potential 'break' and |
| 231 // 'continue' statement targets). Upon construction, a new target is | 234 // 'continue' statement targets). Upon construction, a new target is |
| 232 // added; it is removed upon destruction. | 235 // added; it is removed upon destruction. |
| 233 | 236 |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && | 531 set_allow_tailcalls(FLAG_harmony_tailcalls && !info->is_native() && |
| 529 info->isolate()->is_tail_call_elimination_enabled()); | 532 info->isolate()->is_tail_call_elimination_enabled()); |
| 530 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 533 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
| 531 set_allow_harmony_for_in(FLAG_harmony_for_in); | 534 set_allow_harmony_for_in(FLAG_harmony_for_in); |
| 532 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 535 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
| 533 set_allow_harmony_restrictive_declarations( | 536 set_allow_harmony_restrictive_declarations( |
| 534 FLAG_harmony_restrictive_declarations); | 537 FLAG_harmony_restrictive_declarations); |
| 535 set_allow_harmony_async_await(FLAG_harmony_async_await); | 538 set_allow_harmony_async_await(FLAG_harmony_async_await); |
| 536 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); | 539 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); |
| 537 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); | 540 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); |
| 541 set_allow_harmony_class_fields(FLAG_harmony_class_fields); |
| 538 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 542 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 539 ++feature) { | 543 ++feature) { |
| 540 use_counts_[feature] = 0; | 544 use_counts_[feature] = 0; |
| 541 } | 545 } |
| 542 if (info->ast_value_factory() == NULL) { | 546 if (info->ast_value_factory() == NULL) { |
| 543 // info takes ownership of AstValueFactory. | 547 // info takes ownership of AstValueFactory. |
| 544 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 548 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
| 545 info->set_ast_value_factory_owned(); | 549 info->set_ast_value_factory_owned(); |
| 546 ast_value_factory_ = info->ast_value_factory(); | 550 ast_value_factory_ = info->ast_value_factory(); |
| 547 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 551 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
| (...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 902 result = expression->AsFunctionLiteral(); | 906 result = expression->AsFunctionLiteral(); |
| 903 } else { | 907 } else { |
| 904 ok = false; | 908 ok = false; |
| 905 } | 909 } |
| 906 } | 910 } |
| 907 } | 911 } |
| 908 } else if (info->is_default_constructor()) { | 912 } else if (info->is_default_constructor()) { |
| 909 DCHECK_EQ(scope(), outer); | 913 DCHECK_EQ(scope(), outer); |
| 910 result = DefaultConstructor( | 914 result = DefaultConstructor( |
| 911 raw_name, IsSubclassConstructor(info->function_kind()), | 915 raw_name, IsSubclassConstructor(info->function_kind()), |
| 912 info->start_position(), info->end_position(), info->language_mode()); | 916 info->requires_class_field_init(), info->start_position(), |
| 917 info->end_position(), info->language_mode()); |
| 913 } else { | 918 } else { |
| 914 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), | 919 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), |
| 915 kSkipFunctionNameCheck, | 920 kSkipFunctionNameCheck, |
| 916 info->function_kind(), kNoSourcePosition, | 921 info->function_kind(), kNoSourcePosition, |
| 917 function_type, info->language_mode(), &ok); | 922 function_type, info->language_mode(), &ok); |
| 918 } | 923 } |
| 919 // Make sure the results agree. | 924 // Make sure the results agree. |
| 920 DCHECK(ok == (result != nullptr)); | 925 DCHECK(ok == (result != nullptr)); |
| 921 } | 926 } |
| 922 | 927 |
| (...skipping 3247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4170 NULL, stack_limit_); | 4175 NULL, stack_limit_); |
| 4171 reusable_preparser_->set_allow_lazy(true); | 4176 reusable_preparser_->set_allow_lazy(true); |
| 4172 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4177 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
| 4173 SET_ALLOW(natives); | 4178 SET_ALLOW(natives); |
| 4174 SET_ALLOW(harmony_do_expressions); | 4179 SET_ALLOW(harmony_do_expressions); |
| 4175 SET_ALLOW(harmony_for_in); | 4180 SET_ALLOW(harmony_for_in); |
| 4176 SET_ALLOW(harmony_function_sent); | 4181 SET_ALLOW(harmony_function_sent); |
| 4177 SET_ALLOW(harmony_restrictive_declarations); | 4182 SET_ALLOW(harmony_restrictive_declarations); |
| 4178 SET_ALLOW(harmony_async_await); | 4183 SET_ALLOW(harmony_async_await); |
| 4179 SET_ALLOW(harmony_trailing_commas); | 4184 SET_ALLOW(harmony_trailing_commas); |
| 4185 SET_ALLOW(harmony_class_fields); |
| 4180 #undef SET_ALLOW | 4186 #undef SET_ALLOW |
| 4181 } | 4187 } |
| 4182 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4188 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
| 4183 language_mode(), function_state_->kind(), | 4189 language_mode(), function_state_->kind(), |
| 4184 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, | 4190 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, |
| 4185 logger, may_abort, use_counts_); | 4191 logger, may_abort, use_counts_); |
| 4186 if (pre_parse_timer_ != NULL) { | 4192 if (pre_parse_timer_ != NULL) { |
| 4187 pre_parse_timer_->Stop(); | 4193 pre_parse_timer_->Stop(); |
| 4188 } | 4194 } |
| 4189 return result; | 4195 return result; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4230 CheckNoTailCallExpressions(CHECK_OK); | 4236 CheckNoTailCallExpressions(CHECK_OK); |
| 4231 RewriteNonPattern(CHECK_OK); | 4237 RewriteNonPattern(CHECK_OK); |
| 4232 impl()->AccumulateFormalParameterContainmentErrors(); | 4238 impl()->AccumulateFormalParameterContainmentErrors(); |
| 4233 } else { | 4239 } else { |
| 4234 block_state.set_start_position(scanner()->location().end_pos); | 4240 block_state.set_start_position(scanner()->location().end_pos); |
| 4235 } | 4241 } |
| 4236 | 4242 |
| 4237 | 4243 |
| 4238 ClassLiteralChecker checker(this); | 4244 ClassLiteralChecker checker(this); |
| 4239 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4); | 4245 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4); |
| 4246 ZoneList<Expression*>* instance_field_initializers = |
| 4247 new (zone()) ZoneList<Expression*>(0, zone()); |
| 4240 FunctionLiteral* constructor = nullptr; | 4248 FunctionLiteral* constructor = nullptr; |
| 4241 bool has_seen_constructor = false; | 4249 bool has_seen_constructor = false; |
| 4250 Variable* static_initializer_var = nullptr; |
| 4251 |
| 4252 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); |
| 4253 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); |
| 4254 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); |
| 4242 | 4255 |
| 4243 Expect(Token::LBRACE, CHECK_OK); | 4256 Expect(Token::LBRACE, CHECK_OK); |
| 4244 | 4257 |
| 4245 const bool has_extends = extends != nullptr; | 4258 const bool has_extends = extends != nullptr; |
| 4246 while (peek() != Token::RBRACE) { | 4259 while (peek() != Token::RBRACE) { |
| 4247 if (Check(Token::SEMICOLON)) continue; | 4260 if (Check(Token::SEMICOLON)) continue; |
| 4248 FuncNameInferrer::State fni_state(fni_); | 4261 FuncNameInferrer::State fni_state(fni_); |
| 4249 bool is_computed_name = false; // Classes do not care about computed | 4262 bool is_computed_name = false; // Classes do not care about computed |
| 4250 // property names here. | 4263 // property names here. |
| 4251 ExpressionClassifier property_classifier(this); | 4264 ExpressionClassifier property_classifier(this); |
| 4252 ClassLiteral::Property* property = | 4265 ClassLiteral::Property* property = |
| 4253 ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name, | 4266 ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name, |
| 4254 &has_seen_constructor, CHECK_OK); | 4267 &has_seen_constructor, CHECK_OK); |
| 4255 RewriteNonPattern(CHECK_OK); | 4268 RewriteNonPattern(CHECK_OK); |
| 4256 impl()->AccumulateFormalParameterContainmentErrors(); | 4269 impl()->AccumulateFormalParameterContainmentErrors(); |
| 4257 | 4270 |
| 4258 if (has_seen_constructor && constructor == nullptr) { | 4271 if (has_seen_constructor && constructor == nullptr) { |
| 4259 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 4272 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
| 4260 DCHECK_NOT_NULL(constructor); | 4273 DCHECK_NOT_NULL(constructor); |
| 4261 constructor->set_raw_name( | 4274 constructor->set_raw_name( |
| 4262 name != nullptr ? name : ast_value_factory()->empty_string()); | 4275 name != nullptr ? name : ast_value_factory()->empty_string()); |
| 4263 } else { | 4276 } else { |
| 4277 if (property->kind() == ClassLiteralProperty::FIELD) { |
| 4278 DCHECK(allow_harmony_class_fields()); |
| 4279 continue; // TODO(bakkot) implementation |
| 4280 } |
| 4264 properties->Add(property, zone()); | 4281 properties->Add(property, zone()); |
| 4265 } | 4282 } |
| 4266 | 4283 |
| 4267 DCHECK_NOT_NULL(fni_); | 4284 DCHECK_NOT_NULL(fni_); |
| 4268 fni_->Infer(); | 4285 fni_->Infer(); |
| 4269 } | 4286 } |
| 4270 | 4287 |
| 4271 Expect(Token::RBRACE, CHECK_OK); | 4288 Expect(Token::RBRACE, CHECK_OK); |
| 4272 int end_pos = scanner()->location().end_pos; | 4289 int end_pos = scanner()->location().end_pos; |
| 4273 | 4290 |
| 4274 if (constructor == nullptr) { | 4291 bool has_instance_fields = instance_field_initializers->length() > 0; |
| 4275 constructor = DefaultConstructor(name, has_extends, pos, end_pos, | 4292 DCHECK(!has_instance_fields || allow_harmony_class_fields()); |
| 4276 block_state.language_mode()); | 4293 bool has_default_constructor = constructor == nullptr; |
| 4294 if (has_default_constructor) { |
| 4295 constructor = DefaultConstructor(name, has_extends, has_instance_fields, |
| 4296 pos, end_pos, block_state.language_mode()); |
| 4277 } | 4297 } |
| 4278 | 4298 |
| 4279 // Note that we do not finalize this block scope because it is | 4299 if (has_instance_fields && extends == nullptr) { |
| 4280 // used as a sentinel value indicating an anonymous class. | 4300 constructor->set_requires_class_field_init(true); |
| 4301 } // The derived case is handled by rewriting super calls. |
| 4302 |
| 4281 block_state.set_end_position(end_pos); | 4303 block_state.set_end_position(end_pos); |
| 4282 | 4304 |
| 4283 if (name != nullptr) { | 4305 if (name != nullptr) { |
| 4284 DCHECK_NOT_NULL(proxy); | 4306 DCHECK_NOT_NULL(proxy); |
| 4285 proxy->var()->set_initializer_position(end_pos); | 4307 proxy->var()->set_initializer_position(end_pos); |
| 4286 } | 4308 } |
| 4287 | 4309 |
| 4288 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); | |
| 4289 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); | |
| 4290 do_block->set_scope(block_state.FinalizedBlockScope()); | |
| 4291 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); | |
| 4292 | |
| 4293 ClassLiteral* class_literal = factory()->NewClassLiteral( | 4310 ClassLiteral* class_literal = factory()->NewClassLiteral( |
| 4294 proxy, extends, constructor, properties, pos, end_pos); | 4311 proxy, extends, constructor, properties, pos, end_pos); |
| 4295 | 4312 |
| 4313 if (static_initializer_var != nullptr) { |
| 4314 class_literal->set_static_initializer_proxy( |
| 4315 factory()->NewVariableProxy(static_initializer_var)); |
| 4316 } |
| 4317 |
| 4296 do_block->statements()->Add( | 4318 do_block->statements()->Add( |
| 4297 factory()->NewExpressionStatement(class_literal, pos), zone()); | 4319 factory()->NewExpressionStatement( |
| 4320 factory()->NewAssignment(Token::ASSIGN, |
| 4321 factory()->NewVariableProxy(result_var), |
| 4322 class_literal, kNoSourcePosition), |
| 4323 pos), |
| 4324 zone()); |
| 4325 do_block->set_scope(block_state.FinalizedBlockScope()); |
| 4298 do_expr->set_represented_function(constructor); | 4326 do_expr->set_represented_function(constructor); |
| 4299 Rewriter::Rewrite(this, GetClosureScope(), do_expr, ast_value_factory()); | |
| 4300 | 4327 |
| 4301 return do_expr; | 4328 return do_expr; |
| 4302 } | 4329 } |
| 4303 | 4330 |
| 4304 | 4331 |
| 4305 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 4332 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 4306 // CallRuntime :: | 4333 // CallRuntime :: |
| 4307 // '%' Identifier Arguments | 4334 // '%' Identifier Arguments |
| 4308 | 4335 |
| 4309 int pos = peek_position(); | 4336 int pos = peek_position(); |
| (...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6181 node->Print(Isolate::Current()); | 6208 node->Print(Isolate::Current()); |
| 6182 } | 6209 } |
| 6183 #endif // DEBUG | 6210 #endif // DEBUG |
| 6184 | 6211 |
| 6185 #undef CHECK_OK | 6212 #undef CHECK_OK |
| 6186 #undef CHECK_OK_VOID | 6213 #undef CHECK_OK_VOID |
| 6187 #undef CHECK_FAILED | 6214 #undef CHECK_FAILED |
| 6188 | 6215 |
| 6189 } // namespace internal | 6216 } // namespace internal |
| 6190 } // namespace v8 | 6217 } // namespace v8 |
| OLD | NEW |