Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: src/parsing/parser.cc

Issue 2329703002: Private fields
Patch Set: some comments Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name); 163 VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name);
164 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); 164 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
165 args->Add(init_fn_proxy, zone()); 165 args->Add(init_fn_proxy, zone());
166 args->Add(this_expr, zone()); 166 args->Add(this_expr, zone());
167 return factory()->NewCallRuntime(Runtime::kInlineCall, args, 167 return factory()->NewCallRuntime(Runtime::kInlineCall, args,
168 kNoSourcePosition); 168 kNoSourcePosition);
169 } 169 }
170 170
171 Expression* Parser::RewriteSuperCall(Expression* super_call) { 171 Expression* Parser::RewriteSuperCall(Expression* super_call) {
172 // TODO(bakkot) find a way to avoid this for classes without fields. 172 // TODO(bakkot) find a way to avoid this for classes without fields.
173 if (!allow_harmony_class_fields()) { 173 if (!(allow_harmony_class_fields() || allow_harmony_private_class_fields())) {
174 return super_call; 174 return super_call;
175 } 175 }
176 // This turns a super call `super()` into a do expression of the form 176 // This turns a super call `super()` into a do expression of the form
177 // do { 177 // do {
178 // tmp x = super(); 178 // tmp x = super();
179 // if (.class-field-init) 179 // if (.class-field-init)
180 // .class-field-init(x) 180 // .class-field-init(x)
181 // x; // This isn't actually present; our do-expression representation 181 // x; // This isn't actually present; our do-expression representation
182 // allows specifying that the expression returns x directly. 182 // allows specifying that the expression returns x directly.
183 // } 183 // }
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 info->isolate()->is_tail_call_elimination_enabled()); 589 info->isolate()->is_tail_call_elimination_enabled());
590 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions); 590 set_allow_harmony_do_expressions(FLAG_harmony_do_expressions);
591 set_allow_harmony_for_in(FLAG_harmony_for_in); 591 set_allow_harmony_for_in(FLAG_harmony_for_in);
592 set_allow_harmony_function_sent(FLAG_harmony_function_sent); 592 set_allow_harmony_function_sent(FLAG_harmony_function_sent);
593 set_allow_harmony_restrictive_declarations( 593 set_allow_harmony_restrictive_declarations(
594 FLAG_harmony_restrictive_declarations); 594 FLAG_harmony_restrictive_declarations);
595 set_allow_harmony_async_await(FLAG_harmony_async_await); 595 set_allow_harmony_async_await(FLAG_harmony_async_await);
596 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators); 596 set_allow_harmony_restrictive_generators(FLAG_harmony_restrictive_generators);
597 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas); 597 set_allow_harmony_trailing_commas(FLAG_harmony_trailing_commas);
598 set_allow_harmony_class_fields(FLAG_harmony_class_fields); 598 set_allow_harmony_class_fields(FLAG_harmony_class_fields);
599 set_allow_harmony_private_class_fields(FLAG_harmony_private_class_fields);
599 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; 600 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount;
600 ++feature) { 601 ++feature) {
601 use_counts_[feature] = 0; 602 use_counts_[feature] = 0;
602 } 603 }
603 if (info->ast_value_factory() == NULL) { 604 if (info->ast_value_factory() == NULL) {
604 // info takes ownership of AstValueFactory. 605 // info takes ownership of AstValueFactory.
605 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed())); 606 info->set_ast_value_factory(new AstValueFactory(zone(), info->hash_seed()));
606 info->set_ast_value_factory_owned(); 607 info->set_ast_value_factory_owned();
607 ast_value_factory_ = info->ast_value_factory(); 608 ast_value_factory_ = info->ast_value_factory();
608 ast_node_factory_.set_ast_value_factory(ast_value_factory_); 609 ast_node_factory_.set_ast_value_factory(ast_value_factory_);
(...skipping 2761 matching lines...) Expand 10 before | Expand all | Expand 10 after
3370 Variable* result = NewTemporary(ast_value_factory()->dot_result_string()); 3371 Variable* result = NewTemporary(ast_value_factory()->dot_result_string());
3371 Block* block = ParseBlock(nullptr, CHECK_OK); 3372 Block* block = ParseBlock(nullptr, CHECK_OK);
3372 DoExpression* expr = factory()->NewDoExpression(block, result, pos); 3373 DoExpression* expr = factory()->NewDoExpression(block, result, pos);
3373 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) { 3374 if (!Rewriter::Rewrite(this, GetClosureScope(), expr, ast_value_factory())) {
3374 *ok = false; 3375 *ok = false;
3375 return nullptr; 3376 return nullptr;
3376 } 3377 }
3377 return expr; 3378 return expr;
3378 } 3379 }
3379 3380
3381 const AstRawString* ClassPrivateFieldVariableName(
3382 AstValueFactory* ast_value_factory, const AstRawString* raw_name) {
3383 // Prepends '#'
3384 return ast_value_factory->ConcatStrings(
3385 ast_value_factory->number_sign_string(), raw_name);
3386 }
3387
3388 Property* Parser::ParsePrivateFieldReference(Expression* base, bool* ok) {
3389 // PrimaryExpression ::
3390 // PrivateName
3391
3392 // This desugars a private field reference like `#a` or `obj.#a` into
3393 // %ThrowIfMissingPrivateField(obj, #a)[#a]
3394 // Here #a is a variable which will resolve to a private symbol when inside of
3395 // a class which defines a private field named #a (otherwise attempting to
3396 // resolve it will throw a reference error).
3397
3398 int pos = peek_position();
3399
3400 Expect(Token::HASH, CHECK_OK);
3401 const AstRawString* property_name =
3402 ParseIdentifierName(CHECK_OK); // TODO(bakkot) more complex names
3403 const AstRawString* symbol_var_name =
3404 ClassPrivateFieldVariableName(ast_value_factory(), property_name);
3405
3406 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
3407 args->Add(base, zone());
3408 args->Add(NewUnresolved(symbol_var_name), zone());
3409 Expression* call = factory()->NewCallRuntime(
3410 Runtime::kThrowIfMissingPrivateField, args, pos);
3411 // TODO(bakkot) ideally we'd avoid this runtime function, either by adding a
3412 // flag to the load/store IC or by adding a code stub for it. Currently it
3413 // means that every private field access requires this runtime call, which is
3414 // a slowdown we'd prefer to avoid.
3415
3416 Expression* prop = NewUnresolved(symbol_var_name);
3417 return factory()->NewProperty(call, prop, pos);
3418 }
3419
3380 void Parser::ParseArrowFunctionFormalParameterList( 3420 void Parser::ParseArrowFunctionFormalParameterList(
3381 ParserFormalParameters* parameters, Expression* expr, 3421 ParserFormalParameters* parameters, Expression* expr,
3382 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc, 3422 const Scanner::Location& params_loc, Scanner::Location* duplicate_loc,
3383 const Scope::Snapshot& scope_snapshot, bool* ok) { 3423 const Scope::Snapshot& scope_snapshot, bool* ok) {
3384 if (expr->IsEmptyParentheses()) return; 3424 if (expr->IsEmptyParentheses()) return;
3385 3425
3386 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos, 3426 ParseArrowFunctionFormalParameters(parameters, expr, params_loc.end_pos,
3387 CHECK_OK_VOID); 3427 CHECK_OK_VOID);
3388 3428
3389 scope_snapshot.Reparent(parameters->scope); 3429 scope_snapshot.Reparent(parameters->scope);
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
4249 reusable_preparser_->set_allow_lazy(true); 4289 reusable_preparser_->set_allow_lazy(true);
4250 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name()); 4290 #define SET_ALLOW(name) reusable_preparser_->set_allow_##name(allow_##name());
4251 SET_ALLOW(natives); 4291 SET_ALLOW(natives);
4252 SET_ALLOW(harmony_do_expressions); 4292 SET_ALLOW(harmony_do_expressions);
4253 SET_ALLOW(harmony_for_in); 4293 SET_ALLOW(harmony_for_in);
4254 SET_ALLOW(harmony_function_sent); 4294 SET_ALLOW(harmony_function_sent);
4255 SET_ALLOW(harmony_restrictive_declarations); 4295 SET_ALLOW(harmony_restrictive_declarations);
4256 SET_ALLOW(harmony_async_await); 4296 SET_ALLOW(harmony_async_await);
4257 SET_ALLOW(harmony_trailing_commas); 4297 SET_ALLOW(harmony_trailing_commas);
4258 SET_ALLOW(harmony_class_fields); 4298 SET_ALLOW(harmony_class_fields);
4299 SET_ALLOW(harmony_private_class_fields);
4259 #undef SET_ALLOW 4300 #undef SET_ALLOW
4260 } 4301 }
4261 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4302 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4262 language_mode(), function_state_->kind(), 4303 language_mode(), function_state_->kind(),
4263 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, 4304 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_,
4264 logger, may_abort, use_counts_); 4305 logger, may_abort, use_counts_);
4265 if (pre_parse_timer_ != NULL) { 4306 if (pre_parse_timer_ != NULL) {
4266 pre_parse_timer_->Stop(); 4307 pre_parse_timer_->Stop();
4267 } 4308 }
4268 return result; 4309 return result;
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
4434 impl()->AccumulateFormalParameterContainmentErrors(); 4475 impl()->AccumulateFormalParameterContainmentErrors();
4435 } else { 4476 } else {
4436 block_state.set_start_position(scanner()->location().end_pos); 4477 block_state.set_start_position(scanner()->location().end_pos);
4437 } 4478 }
4438 4479
4439 4480
4440 ClassLiteralChecker checker(this); 4481 ClassLiteralChecker checker(this);
4441 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4); 4482 ZoneList<ClassLiteral::Property*>* properties = NewClassPropertyList(4);
4442 ZoneList<Expression*>* instance_field_initializers = 4483 ZoneList<Expression*>* instance_field_initializers =
4443 new (zone()) ZoneList<Expression*>(0, zone()); 4484 new (zone()) ZoneList<Expression*>(0, zone());
4485 ZoneList<Variable*>* private_field_symbol_vars =
4486 new (zone()) ZoneList<Variable*>(0, zone());
4487 ZoneList<Variable*>* private_field_index_vars =
4488 new (zone()) ZoneList<Variable*>(0, zone());
4444 FunctionLiteral* constructor = nullptr; 4489 FunctionLiteral* constructor = nullptr;
4445 bool has_seen_constructor = false; 4490 bool has_seen_constructor = false;
4446 Variable* static_initializer_var = nullptr; 4491 Variable* static_initializer_var = nullptr;
4447 4492
4448 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos); 4493 Block* do_block = factory()->NewBlock(nullptr, 1, false, pos);
4449 Variable* result_var = NewTemporary(ast_value_factory()->empty_string()); 4494 Variable* result_var = NewTemporary(ast_value_factory()->empty_string());
4450 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); 4495 DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos);
4451 4496
4452 Expect(Token::LBRACE, CHECK_OK); 4497 Expect(Token::LBRACE, CHECK_OK);
4453 4498
4454 const bool has_extends = extends != nullptr; 4499 const bool has_extends = extends != nullptr;
4455 while (peek() != Token::RBRACE) { 4500 while (peek() != Token::RBRACE) {
4456 if (Check(Token::SEMICOLON)) continue; 4501 if (Check(Token::SEMICOLON)) continue;
4457 FuncNameInferrer::State fni_state(fni_); 4502 FuncNameInferrer::State fni_state(fni_);
4503 const AstRawString* private_name = nullptr;
4458 bool is_computed_name = false; // Classes do not care about computed 4504 bool is_computed_name = false; // Classes do not care about computed
4459 // property names here. 4505 // property names here.
4460 ExpressionClassifier property_classifier(this); 4506 ExpressionClassifier property_classifier(this);
4461 ClassLiteral::Property* property = 4507 ClassLiteral::Property* property = ParseClassPropertyDefinition(
4462 ParseClassPropertyDefinition(&checker, has_extends, &is_computed_name, 4508 &checker, has_extends, &private_name, &is_computed_name,
4463 &has_seen_constructor, CHECK_OK); 4509 &has_seen_constructor, CHECK_OK);
4464 RewriteNonPattern(CHECK_OK); 4510 RewriteNonPattern(CHECK_OK);
4465 impl()->AccumulateFormalParameterContainmentErrors(); 4511 impl()->AccumulateFormalParameterContainmentErrors();
4466 4512
4467 if (has_seen_constructor && constructor == nullptr) { 4513 if (has_seen_constructor && constructor == nullptr) {
4468 constructor = GetPropertyValue(property)->AsFunctionLiteral(); 4514 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4469 DCHECK_NOT_NULL(constructor); 4515 DCHECK_NOT_NULL(constructor);
4470 constructor->set_raw_name( 4516 constructor->set_raw_name(
4471 name != nullptr ? name : ast_value_factory()->empty_string()); 4517 name != nullptr ? name : ast_value_factory()->empty_string());
4472 } else { 4518 } else {
4473 if (property->kind() == ClassLiteralProperty::FIELD) { 4519 if (property->kind() == ClassLiteralProperty::FIELD) {
4474 DCHECK(allow_harmony_class_fields()); 4520 if (private_name != nullptr) {
4475 if (property->is_static()) { 4521 DCHECK(allow_harmony_private_class_fields());
4522 DCHECK(property->key() == nullptr);
4523 DCHECK(!property->is_static());
4524
4525 const AstRawString* symbol_var_name =
4526 ClassPrivateFieldVariableName(ast_value_factory(), private_name);
4527 VariableProxy* symbol_var_proxy = NewUnresolved(symbol_var_name);
4528 Declaration* symbol_var_declaration =
4529 factory()->NewVariableDeclaration(symbol_var_proxy, scope(),
4530 kNoSourcePosition);
4531 Variable* symbol_var =
4532 Declare(symbol_var_declaration, DeclarationDescriptor::NORMAL,
4533 CONST, kCreatedInitialized, ok, scope());
4534 private_field_symbol_vars->Add(symbol_var, zone());
4535
4536 const AstRawString* index_var_name = ClassFieldVariableName(
4537 true, ast_value_factory(), instance_field_initializers->length());
4538 VariableProxy* index_var_proxy = NewUnresolved(index_var_name);
4539 Declaration* index_var_declaration =
4540 factory()->NewVariableDeclaration(index_var_proxy, scope(),
4541 kNoSourcePosition);
4542 Variable* index_var =
4543 Declare(index_var_declaration, DeclarationDescriptor::NORMAL,
4544 CONST, kCreatedInitialized, ok, scope());
4545 private_field_index_vars->Add(index_var, zone());
4546
4547 instance_field_initializers->Add(property->value(), zone());
4548
4549 // Does not add to properties because no action is required from the
4550 // backend during class definition.
4551 } else if (property->is_static()) {
4552 DCHECK(allow_harmony_class_fields());
4476 if (static_initializer_var == nullptr) { 4553 if (static_initializer_var == nullptr) {
4477 static_initializer_var = 4554 static_initializer_var =
4478 NewTemporary(ast_value_factory()->empty_string()); 4555 NewTemporary(ast_value_factory()->empty_string());
4479 } 4556 }
4480 // TODO(bakkot) only do this conditionally 4557 // TODO(bakkot) only do this conditionally
4481 Expression* function = InstallHomeObject( 4558 Expression* function = InstallHomeObject(
4482 property->value(), 4559 property->value(),
4483 factory()->NewVariableProxy(static_initializer_var)); 4560 factory()->NewVariableProxy(static_initializer_var));
4484 ZoneList<Expression*>* args = 4561 ZoneList<Expression*>* args =
4485 new (zone()) ZoneList<Expression*>(2, zone()); 4562 new (zone()) ZoneList<Expression*>(2, zone());
4486 args->Add(function, zone()); 4563 args->Add(function, zone());
4487 args->Add(factory()->NewVariableProxy(static_initializer_var), 4564 args->Add(factory()->NewVariableProxy(static_initializer_var),
4488 zone()); 4565 zone());
4489 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, 4566 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall,
4490 args, kNoSourcePosition); 4567 args, kNoSourcePosition);
4491 property->set_value(call); 4568 property->set_value(call);
4569 properties->Add(property, zone());
4492 } else { 4570 } else {
4571 DCHECK(allow_harmony_class_fields());
4493 // if (is_computed_name) { // TODO(bakkot) figure out why this is 4572 // if (is_computed_name) { // TODO(bakkot) figure out why this is
4494 // necessary for non-computed names in full-codegen 4573 // necessary for non-computed names in full-codegen
4495 ZoneList<Expression*>* to_name_args = 4574 ZoneList<Expression*>* to_name_args =
4496 new (zone()) ZoneList<Expression*>(1, zone()); 4575 new (zone()) ZoneList<Expression*>(1, zone());
4497 to_name_args->Add(property->key(), zone()); 4576 to_name_args->Add(property->key(), zone());
4498 property->set_key(factory()->NewCallRuntime( 4577 property->set_key(factory()->NewCallRuntime(
4499 Runtime::kToName, to_name_args, kNoSourcePosition)); 4578 Runtime::kToName, to_name_args, kNoSourcePosition));
4500 //} 4579 //}
4501 const AstRawString* name = ClassFieldVariableName( 4580 const AstRawString* name = ClassFieldVariableName(
4502 true, ast_value_factory(), instance_field_initializers->length()); 4581 true, ast_value_factory(), instance_field_initializers->length());
4503 VariableProxy* name_proxy = NewUnresolved(name); 4582 VariableProxy* name_proxy = NewUnresolved(name);
4504 Declaration* name_declaration = factory()->NewVariableDeclaration( 4583 Declaration* name_declaration = factory()->NewVariableDeclaration(
4505 name_proxy, scope(), kNoSourcePosition); 4584 name_proxy, scope(), kNoSourcePosition);
4506 Variable* name_var = 4585 Variable* name_var =
4507 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST, 4586 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
4508 kNeedsInitialization, ok, scope()); 4587 kNeedsInitialization, ok, scope());
4509 DCHECK(ok); 4588 DCHECK(ok);
4510 if (!ok) return nullptr; 4589 if (!ok) return nullptr;
4511 instance_field_initializers->Add(property->value(), zone()); 4590 instance_field_initializers->Add(property->value(), zone());
4512 property->set_value(factory()->NewVariableProxy(name_var)); 4591 property->set_value(factory()->NewVariableProxy(name_var));
4592 properties->Add(property, zone());
4513 } 4593 }
4594 } else {
4595 properties->Add(property, zone());
4514 } 4596 }
4515 properties->Add(property, zone());
4516 } 4597 }
4517 4598
4518 DCHECK_NOT_NULL(fni_); 4599 DCHECK_NOT_NULL(fni_);
4519 fni_->Infer(); 4600 fni_->Infer();
4520 } 4601 }
4521 4602
4522 Expect(Token::RBRACE, CHECK_OK); 4603 Expect(Token::RBRACE, CHECK_OK);
4523 int end_pos = scanner()->location().end_pos; 4604 int end_pos = scanner()->location().end_pos;
4524 4605
4525 bool has_instance_fields = instance_field_initializers->length() > 0; 4606 bool has_instance_fields = instance_field_initializers->length() > 0;
4526 DCHECK(!has_instance_fields || allow_harmony_class_fields()); 4607 DCHECK(!has_instance_fields || allow_harmony_class_fields() ||
4608 allow_harmony_private_class_fields());
4527 bool has_default_constructor = constructor == nullptr; 4609 bool has_default_constructor = constructor == nullptr;
4528 if (has_default_constructor) { 4610 if (has_default_constructor) {
4529 constructor = DefaultConstructor(name, has_extends, has_instance_fields, 4611 constructor = DefaultConstructor(name, has_extends, has_instance_fields,
4530 pos, end_pos, block_state.language_mode()); 4612 pos, end_pos, block_state.language_mode());
4531 } 4613 }
4532 4614
4533 if (has_instance_fields && extends == nullptr) { 4615 if (has_instance_fields && extends == nullptr) {
4534 constructor = InsertClassFieldInitializer(constructor); 4616 constructor = InsertClassFieldInitializer(constructor);
4535 constructor->set_requires_class_field_init(true); 4617 constructor->set_requires_class_field_init(true);
4536 } // The derived case is handled by rewriting super calls. 4618 } // The derived case is handled by rewriting super calls.
4537 4619
4538 block_state.set_end_position(end_pos); 4620 block_state.set_end_position(end_pos);
4539 4621
4540 if (name != nullptr) { 4622 if (name != nullptr) {
4541 DCHECK_NOT_NULL(proxy); 4623 DCHECK_NOT_NULL(proxy);
4542 proxy->var()->set_initializer_position(end_pos); 4624 proxy->var()->set_initializer_position(end_pos);
4543 } 4625 }
4544 4626
4627 // The parser creates two variables for every private field, both of which
4628 // store the private symbol which serves as the key for that field. One of
4629 // them, 'symbol_var', is used when referencing private fields with '#a' in
4630 // normal code. The other, 'index_var', is used when initializing the field.
4631 // The later variable is necessary because the synthetic field initialization
4632 // function has available to it *only* the number of fields in the class.
4633 // The desugaring looks something like this:
4634 //
4635 // class C {
4636 // #foo = 0;
4637 // baz;
4638 // m(){
4639 // this.#bar = 'a';
4640 // #foo = 1;
4641 // }
4642 // #bar;
4643 // }
4644 // -- becomes --
4645 // do {
4646 // class C {
4647 // m(){
4648 // %ThrowIfMissingPrivateField(this, .bar-symbol)[.bar-symbol] = 'a';
4649 // %ThrowIfMissingPrivateField(this, .foo-symbol)[.foo-symbol] = 1;
4650 // }
4651 // constructor(){
4652 // .initialize.call(this);
4653 // }
4654 // }
4655 //
4656 // let .foo-symbol, .name-0, .init-0;
4657 // .foo-symbol = .name-0 = PrivateSymbol();
4658 // .init-0 = ()=>0;
4659 //
4660 // let .name-1, .init-1;
4661 // // .name-1 is given value 'baz' by the backends during class definition
4662 // .init-1 = ()=>undefined;
4663 //
4664 // let .bar-symbol, .name-2, .init-2;
4665 // .bar-symbol = .name-2 = PrivateSymbol();
4666 // .init-2 = ()=>undefined;
4667 //
4668 // .initialize() {
4669 // this[.name-0] = .init-0(); // Actually this is defineOwnProperty not =
4670 // this[.name-1] = .init-1();
4671 // this[.name-2] = .init-2();
4672 // }
4673 //
4674 // C;
4675 // }
4676 DCHECK(private_field_symbol_vars->length() ==
4677 private_field_index_vars->length());
4678 DCHECK(allow_harmony_private_class_fields() ||
4679 private_field_symbol_vars->length() == 0);
4680 for (int i = 0; i < private_field_symbol_vars->length(); ++i) {
4681 VariableProxy* symbol_var_proxy =
4682 factory()->NewVariableProxy(private_field_symbol_vars->at(i));
4683 VariableProxy* index_var_proxy =
4684 factory()->NewVariableProxy(private_field_index_vars->at(i));
4685
4686 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(1, zone());
4687 args->Add(factory()->NewUndefinedLiteral(kNoSourcePosition), zone());
4688 Expression* name =
4689 factory()->NewCallRuntime(Runtime::kCreatePrivateSymbol, args, pos);
4690
4691 Assignment* inner_assignment = factory()->NewAssignment(
4692 Token::INIT, index_var_proxy, name, kNoSourcePosition);
4693 Assignment* outer_assignment = factory()->NewAssignment(
4694 Token::INIT, symbol_var_proxy, inner_assignment, kNoSourcePosition);
4695 do_block->statements()->Add(
4696 factory()->NewExpressionStatement(outer_assignment, kNoSourcePosition),
4697 zone());
4698 }
4699
4545 ClassLiteral* class_literal = factory()->NewClassLiteral( 4700 ClassLiteral* class_literal = factory()->NewClassLiteral(
4546 proxy, extends, constructor, properties, pos, end_pos); 4701 proxy, extends, constructor, properties, pos, end_pos);
4547 4702
4548 if (static_initializer_var != nullptr) { 4703 if (static_initializer_var != nullptr) {
4549 class_literal->set_static_initializer_proxy( 4704 class_literal->set_static_initializer_proxy(
4550 factory()->NewVariableProxy(static_initializer_var)); 4705 factory()->NewVariableProxy(static_initializer_var));
4551 } 4706 }
4552 4707
4553 do_block->statements()->Add( 4708 do_block->statements()->Add(
4554 factory()->NewExpressionStatement( 4709 factory()->NewExpressionStatement(
4555 factory()->NewAssignment(Token::ASSIGN, 4710 factory()->NewAssignment(Token::ASSIGN,
4556 factory()->NewVariableProxy(result_var), 4711 factory()->NewVariableProxy(result_var),
4557 class_literal, kNoSourcePosition), 4712 class_literal, kNoSourcePosition),
4558 pos), 4713 pos),
4559 zone()); 4714 zone());
4560 if (allow_harmony_class_fields() && 4715 if ((allow_harmony_class_fields() || allow_harmony_private_class_fields()) &&
4561 (has_instance_fields || 4716 (has_instance_fields ||
4562 (extends != nullptr && !has_default_constructor))) { 4717 (extends != nullptr && !has_default_constructor))) {
4563 // Default constructors for derived classes without fields will not try to 4718 // Default constructors for derived classes without fields will not try to
4564 // read this variable, so there's no need to create it. 4719 // read this variable, so there's no need to create it.
4565 const AstRawString* init_fn_name = 4720 const AstRawString* init_fn_name =
4566 ast_value_factory()->dot_class_field_init_string(); 4721 ast_value_factory()->dot_class_field_init_string();
4567 Variable* init_fn_var = scope()->DeclareLocal( 4722 Variable* init_fn_var = scope()->DeclareLocal(
4568 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE); 4723 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE);
4569 Expression* initializer = 4724 Expression* initializer =
4570 has_instance_fields 4725 has_instance_fields
(...skipping 1920 matching lines...) Expand 10 before | Expand all | Expand 10 after
6491 node->Print(Isolate::Current()); 6646 node->Print(Isolate::Current());
6492 } 6647 }
6493 #endif // DEBUG 6648 #endif // DEBUG
6494 6649
6495 #undef CHECK_OK 6650 #undef CHECK_OK
6496 #undef CHECK_OK_VOID 6651 #undef CHECK_OK_VOID
6497 #undef CHECK_FAILED 6652 #undef CHECK_FAILED
6498 6653
6499 } // namespace internal 6654 } // namespace internal
6500 } // namespace v8 6655 } // namespace v8
OLDNEW
« no previous file with comments | « src/parsing/parser.h ('k') | src/parsing/parser-base.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698