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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
156 ast_value_factory()->GetOneByteString(".class-field-initializer"); | 156 ast_value_factory()->GetOneByteString(".class-field-initializer"); |
157 VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name); | 157 VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name); |
158 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); | 158 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
159 args->Add(init_fn_proxy, zone()); | 159 args->Add(init_fn_proxy, zone()); |
160 args->Add(this_expr, zone()); | 160 args->Add(this_expr, zone()); |
161 return factory()->NewCallRuntime(Runtime::kInlineCall, args, | 161 return factory()->NewCallRuntime(Runtime::kInlineCall, args, |
162 kNoSourcePosition); | 162 kNoSourcePosition); |
163 } | 163 } |
164 | 164 |
165 Expression* Parser::RewriteSuperCall(Expression* super_call) { | 165 Expression* Parser::RewriteSuperCall(Expression* super_call) { |
166 if (!allow_harmony_class_fields()) { | 166 if (!(allow_harmony_class_fields() || allow_harmony_private_class_fields())) { |
167 return super_call; | 167 return super_call; |
168 } | 168 } |
169 // TODO(bakkot) The whole charade with the do expression can be replaced by a | 169 // TODO(bakkot) The whole charade with the do expression can be replaced by a |
170 // ternary conditional, except that the optimizer does not like it if you use | 170 // ternary conditional, except that the optimizer does not like it if you use |
171 // an AST node (at least, one containing a variable proxy) in two places. | 171 // an AST node (at least, one containing a variable proxy) in two places. |
172 Variable* var_tmp = | 172 Variable* var_tmp = |
173 scope()->NewTemporary(ast_value_factory()->empty_string()); | 173 scope()->NewTemporary(ast_value_factory()->empty_string()); |
174 Block* block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); | 174 Block* block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
175 Assignment* assignment = factory()->NewAssignment( | 175 Assignment* assignment = factory()->NewAssignment( |
176 Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call, | 176 Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call, |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
577 info->isolate()->is_tail_call_elimination_enabled()); | 577 info->isolate()->is_tail_call_elimination_enabled()); |
578 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); | 578 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); |
579 set_allow_harmony_for_in(FLAG_harmony_for_in); | 579 set_allow_harmony_for_in(FLAG_harmony_for_in); |
580 set_allow_harmony_function_sent(FLAG_harmony_function_sent); | 580 set_allow_harmony_function_sent(FLAG_harmony_function_sent); |
581 set_allow_harmony_restrictive_declarations( | 581 set_allow_harmony_restrictive_declarations( |
582 FLAG_harmony_restrictive_declarations); | 582 FLAG_harmony_restrictive_declarations); |
583 set_allow_harmony_async_await(FLAG_harmony_async_await); | 583 set_allow_harmony_async_await(FLAG_harmony_async_await); |
584 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); | 584 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); |
585 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); | 585 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); |
586 set_allow_harmony_class_fields(FLAG_harmony_class_fields); | 586 set_allow_harmony_class_fields(FLAG_harmony_class_fields); |
587 set_allow_harmony_private_class_fields(FLAG_harmony_private_class_fields); | |
587 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 588 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
588 ++feature) { | 589 ++feature) { |
589 use_counts_[feature] = 0; | 590 use_counts_[feature] = 0; |
590 } | 591 } |
591 if (info->ast_value_factory() == NULL) { | 592 if (info->ast_value_factory() == NULL) { |
592 // info takes ownership of AstValueFactory. | 593 // info takes ownership of AstValueFactory. |
593 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); | 594 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); |
594 info->set_ast_value_factory_owned(); | 595 info->set_ast_value_factory_owned(); |
595 ast_value_factory_ = info->ast_value_factory(); | 596 ast_value_factory_ = info->ast_value_factory(); |
596 ast_node_factory_.set_ast_value_factory(ast_value_factory_); | 597 ast_node_factory_.set_ast_value_factory(ast_value_factory_); |
(...skipping 2761 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3358 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); | 3359 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); |
3359 Block* block = ParseBlock(nullptr, CHECK_OK); | 3360 Block* block = ParseBlock(nullptr, CHECK_OK); |
3360 DoExpression* expr = factory()->NewDoExpression(block, result, pos); | 3361 DoExpression* expr = factory()->NewDoExpression(block, result, pos); |
3361 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { | 3362 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { |
3362 *ok = false; | 3363 *ok = false; |
3363 return nullptr; | 3364 return nullptr; |
3364 } | 3365 } |
3365 return expr; | 3366 return expr; |
3366 } | 3367 } |
3367 | 3368 |
3369 const AstRawString* ClassPrivateFieldVariableName( | |
3370 AstValueFactory* ast_value_factory, const AstRawString* raw_name) { | |
3371 std::string name(reinterpret_cast<const char*>(raw_name->raw_data()), | |
3372 raw_name->length()); // TODO(bakkot) check complicated names | |
Dan Ehrenberg
2016/09/10 04:30:28
What's the issue here? Non-latin1 names?
bakkot
2016/09/13 01:05:38
Non-one-byte names, in particular, although it loo
| |
3373 name = "#" + name; | |
Dan Ehrenberg
2016/09/10 04:30:28
We don't concatenate strings in the parser like th
bakkot
2016/09/13 01:05:38
I'm not sure it can be avoided; we need an AstRawS
| |
3374 return ast_value_factory->GetOneByteString( | |
3375 name.c_str()); // TODO(bakkot) sometimes two-byte probably, though maybe | |
3376 // doesn't matter | |
Dan Ehrenberg
2016/09/10 04:30:28
Yeah, you can in fact have identifier characters w
bakkot
2016/09/13 01:05:38
The reason I think it might not matter is that the
| |
3377 } | |
3378 | |
3379 Property* Parser::ParsePrivateFieldReference(Expression* base, bool* ok) { | |
3380 // PrimaryExpression :: | |
3381 // PrivateName | |
3382 int pos = peek_position(); | |
3383 | |
3384 Expect(Token::HASH, CHECK_OK); | |
3385 const AstRawString* property_name = | |
3386 ParseIdentifierName(CHECK_OK); // TODO(bakkot) more complex names | |
3387 const AstRawString* symbol_var_name = | |
3388 ClassPrivateFieldVariableName(ast_value_factory(), property_name); | |
3389 | |
3390 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); | |
3391 args->Add(base, zone()); | |
3392 args->Add(NewUnresolved(symbol_var_name), zone()); | |
3393 Expression* call = factory()->NewCallRuntime( | |
3394 Runtime::kThrowIfMissingPrivateField, args, pos); | |
3395 | |
3396 Expression* prop = NewUnresolved(symbol_var_name); | |
3397 return factory()->NewProperty(call, prop, pos); | |
Dan Ehrenberg
2016/09/10 04:30:28
Great logic here, ends up being very elegant, but
bakkot
2016/09/13 01:05:38
Added a TODO.
| |
3398 } | |
3399 | |
3368 void Parser::ParseArrowFunctionFormalParameterList( | 3400 void Parser::ParseArrowFunctionFormalParameterList( |
3369 ParserFormalParameters* parameters, Expression* expr, | 3401 ParserFormalParameters* parameters, Expression* expr, |
3370 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, | 3402 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, |
3371 const Scope::Snapshot& scope_snapshot, bool* ok) { | 3403 const Scope::Snapshot& scope_snapshot, bool* ok) { |
3372 if (expr->IsEmptyParentheses()) return; | 3404 if (expr->IsEmptyParentheses()) return; |
3373 | 3405 |
3374 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, | 3406 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, |
3375 CHECK_OK_VOID); | 3407 CHECK_OK_VOID); |
3376 | 3408 |
3377 scope_snapshot.Reparent(parameters->scope); | 3409 scope_snapshot.Reparent(parameters->scope); |
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4237 reusable_preparser_->set_allow_lazy(true); | 4269 reusable_preparser_->set_allow_lazy(true); |
4238 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); | 4270 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); |
4239 SET_ALLOW(natives); | 4271 SET_ALLOW(natives); |
4240 SET_ALLOW(harmony_do_expressions); | 4272 SET_ALLOW(harmony_do_expressions); |
4241 SET_ALLOW(harmony_for_in); | 4273 SET_ALLOW(harmony_for_in); |
4242 SET_ALLOW(harmony_function_sent); | 4274 SET_ALLOW(harmony_function_sent); |
4243 SET_ALLOW(harmony_restrictive_declarations); | 4275 SET_ALLOW(harmony_restrictive_declarations); |
4244 SET_ALLOW(harmony_async_await); | 4276 SET_ALLOW(harmony_async_await); |
4245 SET_ALLOW(harmony_trailing_commas); | 4277 SET_ALLOW(harmony_trailing_commas); |
4246 SET_ALLOW(harmony_class_fields); | 4278 SET_ALLOW(harmony_class_fields); |
4279 SET_ALLOW(harmony_private_class_fields); | |
4247 #undef SET_ALLOW | 4280 #undef SET_ALLOW |
4248 } | 4281 } |
4249 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( | 4282 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( |
4250 language_mode(), function_state_->kind(), | 4283 language_mode(), function_state_->kind(), |
4251 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, | 4284 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, |
4252 logger, may_abort, use_counts_); | 4285 logger, may_abort, use_counts_); |
4253 if (pre_parse_timer_ != NULL) { | 4286 if (pre_parse_timer_ != NULL) { |
4254 pre_parse_timer_->Stop(); | 4287 pre_parse_timer_->Stop(); |
4255 } | 4288 } |
4256 return result; | 4289 return result; |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4408 impl()->AccumulateFormalParameterContainmentErrors(); | 4441 impl()->AccumulateFormalParameterContainmentErrors(); |
4409 } else { | 4442 } else { |
4410 block_state.set_start_position(scanner()->location().end_pos); | 4443 block_state.set_start_position(scanner()->location().end_pos); |
4411 } | 4444 } |
4412 | 4445 |
4413 | 4446 |
4414 ClassLiteralChecker checker(this); | 4447 ClassLiteralChecker checker(this); |
4415 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4); | 4448 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4); |
4416 ZoneList<Expression*>* instance_field_initializers = | 4449 ZoneList<Expression*>* instance_field_initializers = |
4417 new (zone()) ZoneList<Expression*>(0, zone()); | 4450 new (zone()) ZoneList<Expression*>(0, zone()); |
4451 ZoneList<Variable*>* private_field_symbol_vars = | |
4452 new (zone()) ZoneList<Variable*>(0, zone()); | |
4453 ZoneList<Variable*>* private_field_name_vars = | |
4454 new (zone()) ZoneList<Variable*>(0, zone()); | |
4418 FunctionLiteral* constructor = nullptr; | 4455 FunctionLiteral* constructor = nullptr; |
4419 bool has_seen_constructor = false; | 4456 bool has_seen_constructor = false; |
4420 Variable* static_initializer_var = nullptr; | 4457 Variable* static_initializer_var = nullptr; |
4421 | 4458 |
4422 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); | 4459 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); |
4423 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); | 4460 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); |
4424 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); | 4461 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); |
4425 | 4462 |
4426 Expect(Token::LBRACE, CHECK_OK); | 4463 Expect(Token::LBRACE, CHECK_OK); |
4427 | 4464 |
4428 const bool has_extends = extends != nullptr; | 4465 const bool has_extends = extends != nullptr; |
4429 while (peek() != Token::RBRACE) { | 4466 while (peek() != Token::RBRACE) { |
4430 if (Check(Token::SEMICOLON)) continue; | 4467 if (Check(Token::SEMICOLON)) continue; |
4431 FuncNameInferrer::State fni_state(fni_); | 4468 FuncNameInferrer::State fni_state(fni_); |
4469 const AstRawString* private_name = nullptr; | |
4432 bool is_computed_name = false; // Classes do not care about computed | 4470 bool is_computed_name = false; // Classes do not care about computed |
4433 // property names here. | 4471 // property names here. |
4434 ExpressionClassifier property_classifier(this); | 4472 ExpressionClassifier property_classifier(this); |
4435 ClassLiteral::Property* property = | 4473 ClassLiteral::Property* property = ParseClassPropertyDefinition( |
4436 ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name, | 4474 &checker, has_extends, &private_name, &is_computed_name, |
4437 &has_seen_constructor, CHECK_OK); | 4475 &has_seen_constructor, CHECK_OK); |
4438 RewriteNonPattern(CHECK_OK); | 4476 RewriteNonPattern(CHECK_OK); |
4439 impl()->AccumulateFormalParameterContainmentErrors(); | 4477 impl()->AccumulateFormalParameterContainmentErrors(); |
4440 | 4478 |
4441 if (has_seen_constructor && constructor == nullptr) { | 4479 if (has_seen_constructor && constructor == nullptr) { |
4442 constructor = GetPropertyValue(property)->AsFunctionLiteral(); | 4480 constructor = GetPropertyValue(property)->AsFunctionLiteral(); |
4443 DCHECK_NOT_NULL(constructor); | 4481 DCHECK_NOT_NULL(constructor); |
4444 constructor->set_raw_name( | 4482 constructor->set_raw_name( |
4445 name != nullptr ? name : ast_value_factory()->empty_string()); | 4483 name != nullptr ? name : ast_value_factory()->empty_string()); |
4446 } else { | 4484 } else { |
4447 if (property->kind() == ClassLiteralProperty::FIELD) { | 4485 if (property->kind() == ClassLiteralProperty::FIELD) { |
4448 DCHECK(allow_harmony_class_fields()); | 4486 if (private_name != nullptr) { |
4449 if (property->is_static()) { | 4487 DCHECK(allow_harmony_private_class_fields()); |
4488 DCHECK(property->key() == nullptr); | |
4489 DCHECK(!property->is_static()); | |
4490 | |
4491 const AstRawString* symbol_var_name = | |
4492 ClassPrivateFieldVariableName(ast_value_factory(), private_name); | |
4493 Variable* symbol_var = scope()->DeclareLocal( | |
4494 symbol_var_name, CONST, kCreatedInitialized, | |
4495 Variable::NORMAL); // TODO(bakkot) flags, Declare vs DeclareLocal | |
Dan Ehrenberg
2016/09/10 04:30:28
I'm confused, where's the actual declaration AST n
bakkot
2016/09/13 01:05:38
Switched to that. This has the side effect of maki
| |
4496 private_field_symbol_vars->Add(symbol_var, zone()); | |
4497 | |
4498 const AstRawString* name_var_name = ClassFieldVariableName( | |
4499 true, ast_value_factory(), instance_field_initializers->length()); | |
4500 Variable* name_var = scope()->DeclareLocal( | |
4501 name_var_name, CONST, kCreatedInitialized, | |
4502 Variable::NORMAL); // TODO(bakkot) flags, Declare vs DeclareLocal | |
4503 private_field_name_vars->Add(name_var, zone()); | |
4504 | |
4505 instance_field_initializers->Add(property->value(), zone()); | |
4506 | |
4507 // Does not add to properties because no action is required from the | |
4508 // backend during class definition. | |
4509 } else if (property->is_static()) { | |
4510 DCHECK(allow_harmony_class_fields()); | |
4450 if (static_initializer_var == nullptr) { | 4511 if (static_initializer_var == nullptr) { |
4451 static_initializer_var = | 4512 static_initializer_var = |
4452 NewTemporary(ast_value_factory()->empty_string()); | 4513 NewTemporary(ast_value_factory()->empty_string()); |
4453 } | 4514 } |
4454 // TODO(bakkot) only do this conditionally | 4515 // TODO(bakkot) only do this conditionally |
4455 Expression* function = InstallHomeObject( | 4516 Expression* function = InstallHomeObject( |
4456 property->value(), | 4517 property->value(), |
4457 factory()->NewVariableProxy(static_initializer_var)); | 4518 factory()->NewVariableProxy(static_initializer_var)); |
4458 ZoneList<Expression*>* args = | 4519 ZoneList<Expression*>* args = |
4459 new (zone()) ZoneList<Expression*>(2, zone()); | 4520 new (zone()) ZoneList<Expression*>(2, zone()); |
4460 args->Add(function, zone()); | 4521 args->Add(function, zone()); |
4461 args->Add(factory()->NewVariableProxy(static_initializer_var), | 4522 args->Add(factory()->NewVariableProxy(static_initializer_var), |
4462 zone()); | 4523 zone()); |
4463 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, | 4524 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, |
4464 args, kNoSourcePosition); | 4525 args, kNoSourcePosition); |
4465 property->set_value(call); | 4526 property->set_value(call); |
4527 properties->Add(property, zone()); | |
4466 } else { | 4528 } else { |
4529 DCHECK(allow_harmony_class_fields()); | |
4467 // if (is_computed_name) { // TODO(bakkot) figure out why this is | 4530 // if (is_computed_name) { // TODO(bakkot) figure out why this is |
4468 // necessary for non-computed names in full-codegen | 4531 // necessary for non-computed names in full-codegen |
4469 ZoneList<Expression*>* to_name_args = | 4532 ZoneList<Expression*>* to_name_args = |
4470 new (zone()) ZoneList<Expression*>(1, zone()); | 4533 new (zone()) ZoneList<Expression*>(1, zone()); |
4471 to_name_args->Add(property->key(), zone()); | 4534 to_name_args->Add(property->key(), zone()); |
4472 property->set_key(factory()->NewCallRuntime( | 4535 property->set_key(factory()->NewCallRuntime( |
4473 Runtime::kToName, to_name_args, kNoSourcePosition)); | 4536 Runtime::kToName, to_name_args, kNoSourcePosition)); |
4474 //} | 4537 //} |
4475 const AstRawString* name = ClassFieldVariableName( | 4538 const AstRawString* name = ClassFieldVariableName( |
4476 true, ast_value_factory(), instance_field_initializers->length()); | 4539 true, ast_value_factory(), instance_field_initializers->length()); |
4477 VariableProxy* name_proxy = NewUnresolved(name); | 4540 VariableProxy* name_proxy = NewUnresolved(name); |
4478 Declaration* name_declaration = | 4541 Declaration* name_declaration = |
4479 factory() | 4542 factory() |
4480 ->NewVariableDeclaration( // TODO(bakkot) DeclareLocal? not | 4543 ->NewVariableDeclaration( // TODO(bakkot) DeclareLocal? not |
4481 // clear on the difference... | 4544 // clear on the difference... |
4482 name_proxy, scope(), kNoSourcePosition); | 4545 name_proxy, scope(), kNoSourcePosition); |
4483 Variable* name_var = | 4546 Variable* name_var = |
4484 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST, | 4547 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST, |
4485 kNeedsInitialization, ok, scope()); | 4548 kNeedsInitialization, ok, scope()); |
4486 DCHECK(ok); | 4549 DCHECK(ok); |
4487 if (!ok) return nullptr; | 4550 if (!ok) return nullptr; |
4488 instance_field_initializers->Add(property->value(), zone()); | 4551 instance_field_initializers->Add(property->value(), zone()); |
4489 property->set_value(factory()->NewVariableProxy(name_var)); | 4552 property->set_value(factory()->NewVariableProxy(name_var)); |
4553 properties->Add(property, zone()); | |
4490 } | 4554 } |
4555 } else { | |
4556 properties->Add(property, zone()); | |
4491 } | 4557 } |
4492 properties->Add(property, zone()); | |
4493 } | 4558 } |
4494 | 4559 |
4495 DCHECK_NOT_NULL(fni_); | 4560 DCHECK_NOT_NULL(fni_); |
4496 fni_->Infer(); | 4561 fni_->Infer(); |
4497 } | 4562 } |
4498 | 4563 |
4499 Expect(Token::RBRACE, CHECK_OK); | 4564 Expect(Token::RBRACE, CHECK_OK); |
4500 int end_pos = scanner()->location().end_pos; | 4565 int end_pos = scanner()->location().end_pos; |
4501 | 4566 |
4502 bool has_instance_fields = instance_field_initializers->length() > 0; | 4567 bool has_instance_fields = instance_field_initializers->length() > 0; |
4503 DCHECK(!has_instance_fields || allow_harmony_class_fields()); | 4568 DCHECK(!has_instance_fields || allow_harmony_class_fields() || |
4569 allow_harmony_private_class_fields()); | |
4504 bool has_default_constructor = constructor == nullptr; | 4570 bool has_default_constructor = constructor == nullptr; |
4505 if (has_default_constructor) { | 4571 if (has_default_constructor) { |
4506 constructor = DefaultConstructor(name, has_extends, has_instance_fields, | 4572 constructor = DefaultConstructor(name, has_extends, has_instance_fields, |
4507 pos, end_pos, block_state.language_mode()); | 4573 pos, end_pos, block_state.language_mode()); |
4508 } | 4574 } |
4509 | 4575 |
4510 if (has_instance_fields && extends == nullptr) { | 4576 if (has_instance_fields && extends == nullptr) { |
4511 constructor = InsertClassFieldInitializer(constructor); | 4577 constructor = InsertClassFieldInitializer(constructor); |
4512 constructor->set_requires_class_field_init(true); | 4578 constructor->set_requires_class_field_init(true); |
4513 } // The derived case is handled by rewriting super calls. | 4579 } // The derived case is handled by rewriting super calls. |
4514 | 4580 |
4515 block_state.set_end_position(end_pos); | 4581 block_state.set_end_position(end_pos); |
4516 | 4582 |
4517 if (name != nullptr) { | 4583 if (name != nullptr) { |
4518 DCHECK_NOT_NULL(proxy); | 4584 DCHECK_NOT_NULL(proxy); |
4519 proxy->var()->set_initializer_position(end_pos); | 4585 proxy->var()->set_initializer_position(end_pos); |
4520 } | 4586 } |
4521 | 4587 |
4588 DCHECK(private_field_symbol_vars->length() == | |
4589 private_field_name_vars->length()); | |
4590 DCHECK(!allow_harmony_private_class_fields() || | |
4591 private_field_symbol_vars->length() == 0); | |
4592 for (int i = 0; i < private_field_symbol_vars->length(); ++i) { | |
Dan Ehrenberg
2016/09/10 04:30:28
A comment explaining the desugaring you're doing?
bakkot
2016/09/13 01:05:38
Done.
| |
4593 VariableProxy* symbol_var_proxy = | |
4594 factory()->NewVariableProxy(private_field_symbol_vars->at(i)); | |
4595 VariableProxy* name_var_proxy = | |
4596 factory()->NewVariableProxy(private_field_name_vars->at(i)); | |
4597 | |
4598 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone()); | |
4599 args->Add(factory()->NewUndefinedLiteral(kNoSourcePosition), | |
4600 zone()); // TODO(bakkot) name | |
4601 Expression* name = | |
4602 factory()->NewCallRuntime(Runtime::kCreatePrivateSymbol, args, pos); | |
4603 | |
4604 Assignment* inner_assignment = factory()->NewAssignment( | |
4605 Token::INIT, name_var_proxy, name, kNoSourcePosition); | |
4606 Assignment* outer_assignment = factory()->NewAssignment( | |
4607 Token::INIT, symbol_var_proxy, inner_assignment, kNoSourcePosition); | |
4608 do_block->statements()->Add( | |
4609 factory()->NewExpressionStatement(outer_assignment, kNoSourcePosition), | |
4610 zone()); | |
4611 } | |
4612 | |
4522 ClassLiteral* class_literal = factory()->NewClassLiteral( | 4613 ClassLiteral* class_literal = factory()->NewClassLiteral( |
4523 proxy, extends, constructor, properties, pos, end_pos); | 4614 proxy, extends, constructor, properties, pos, end_pos); |
4524 | 4615 |
4525 if (static_initializer_var != nullptr) { | 4616 if (static_initializer_var != nullptr) { |
4526 class_literal->set_static_initializer_proxy( | 4617 class_literal->set_static_initializer_proxy( |
4527 factory()->NewVariableProxy(static_initializer_var)); | 4618 factory()->NewVariableProxy(static_initializer_var)); |
4528 } | 4619 } |
4529 | 4620 |
4530 do_block->statements()->Add( | 4621 do_block->statements()->Add( |
4531 factory()->NewExpressionStatement( | 4622 factory()->NewExpressionStatement( |
4532 factory()->NewAssignment(Token::ASSIGN, | 4623 factory()->NewAssignment(Token::ASSIGN, |
4533 factory()->NewVariableProxy(result_var), | 4624 factory()->NewVariableProxy(result_var), |
4534 class_literal, kNoSourcePosition), | 4625 class_literal, kNoSourcePosition), |
4535 pos), | 4626 pos), |
4536 zone()); | 4627 zone()); |
4537 if (allow_harmony_class_fields() && | 4628 if ((allow_harmony_class_fields() || allow_harmony_private_class_fields()) && |
4538 (has_instance_fields || | 4629 (has_instance_fields || |
4539 (extends != nullptr && !has_default_constructor))) { | 4630 (extends != nullptr && !has_default_constructor))) { |
4540 // Default constructors for derived classes without fields will not try to | 4631 // Default constructors for derived classes without fields will not try to |
4541 // read this variable, so there's no need to create it. | 4632 // read this variable, so there's no need to create it. |
4542 const AstRawString* init_fn_name = | 4633 const AstRawString* init_fn_name = |
4543 ast_value_factory()->GetOneByteString(".class-field-initializer"); | 4634 ast_value_factory()->GetOneByteString(".class-field-initializer"); |
4544 Variable* init_fn_var = | 4635 Variable* init_fn_var = |
4545 scope()->DeclareLocal(init_fn_name, CONST, kCreatedInitialized, | 4636 scope()->DeclareLocal(init_fn_name, CONST, kCreatedInitialized, |
4546 Variable::NORMAL); // TODO(bakkot) flags | 4637 Variable::NORMAL); // TODO(bakkot) flags |
4547 Expression* initializer = | 4638 Expression* initializer = |
(...skipping 1922 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6470 node->Print(Isolate::Current()); | 6561 node->Print(Isolate::Current()); |
6471 } | 6562 } |
6472 #endif // DEBUG | 6563 #endif // DEBUG |
6473 | 6564 |
6474 #undef CHECK_OK | 6565 #undef CHECK_OK |
6475 #undef CHECK_OK_VOID | 6566 #undef CHECK_OK_VOID |
6476 #undef CHECK_FAILED | 6567 #undef CHECK_FAILED |
6477 | 6568 |
6478 } // namespace internal | 6569 } // namespace internal |
6479 } // namespace v8 | 6570 } // namespace v8 |
OLD | NEW |