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

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

Issue 2316233004: Class fields, part 2 (desugaring) (Closed)
Patch Set: rebase harder 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 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 if (compile_options_ == ScriptCompiler::kNoCompileOptions) { 143 if (compile_options_ == ScriptCompiler::kNoCompileOptions) {
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 Expression* Parser::CallClassFieldInitializer(Scope* scope,
154 Expression* this_expr) {
155 // This produces the expression
156 // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is
157 // the name
158 // of a synthetic variable.
159 // 'this_expr' will be 'this' in a base constructor and the result of calling
160 // 'super' in a derived one.
161 const AstRawString* init_fn_name =
162 ast_value_factory()->dot_class_field_init_string();
163 VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name);
164 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
165 args->Add(init_fn_proxy, zone());
166 args->Add(this_expr, zone());
167 return factory()->NewCallRuntime(Runtime::kInlineCall, args,
168 kNoSourcePosition);
169 }
170
171 Expression* Parser::RewriteSuperCall(Expression* super_call) {
172 // TODO(bakkot) find a way to avoid this for classes without fields.
173 if (!allow_harmony_class_fields()) {
174 return super_call;
175 }
176 // This turns a super call `super()` into a do expression of the form
177 // do {
178 // tmp x = super();
179 // if (.class-field-init)
180 // .class-field-init(x)
181 // x; // This isn't actually present; our do-expression representation
182 // allows specifying that the expression returns x directly.
183 // }
184 Variable* var_tmp =
185 scope()->NewTemporary(ast_value_factory()->empty_string());
186 Block* block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
187 Assignment* assignment = factory()->NewAssignment(
188 Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call,
189 kNoSourcePosition);
190 block->statements()->Add(
191 factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone());
192 const AstRawString* init_fn_name =
193 ast_value_factory()->dot_class_field_init_string();
194 VariableProxy* init_fn_proxy =
195 scope()->NewUnresolved(factory(), init_fn_name);
196 Expression* condition = init_fn_proxy;
197 Statement* initialize = factory()->NewExpressionStatement(
198 CallClassFieldInitializer(scope(), factory()->NewVariableProxy(var_tmp)),
199 kNoSourcePosition);
200 IfStatement* if_statement = factory()->NewIfStatement(
201 condition, initialize, factory()->NewEmptyStatement(kNoSourcePosition),
202 kNoSourcePosition);
203 block->statements()->Add(if_statement, zone());
204 return factory()->NewDoExpression(block, var_tmp, kNoSourcePosition);
205 }
206
153 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, 207 FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name,
154 bool call_super, 208 bool call_super,
155 bool requires_class_field_init, 209 bool requires_class_field_init,
156 int pos, int end_pos, 210 int pos, int end_pos,
157 LanguageMode language_mode) { 211 LanguageMode language_mode) {
158 int materialized_literal_count = -1; 212 int materialized_literal_count = -1;
159 int expected_property_count = -1; 213 int expected_property_count = -1;
160 int parameter_count = 0; 214 int parameter_count = 0;
161 if (name == nullptr) name = ast_value_factory()->empty_string(); 215 if (name == nullptr) name = ast_value_factory()->empty_string();
162 216
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
199 args->Add(super_constructor, zone()); 253 args->Add(super_constructor, zone());
200 Spread* spread_args = factory()->NewSpread( 254 Spread* spread_args = factory()->NewSpread(
201 factory()->NewVariableProxy(constructor_args), pos, pos); 255 factory()->NewVariableProxy(constructor_args), pos, pos);
202 ZoneList<Expression*>* spread_args_expr = 256 ZoneList<Expression*>* spread_args_expr =
203 new (zone()) ZoneList<Expression*>(1, zone()); 257 new (zone()) ZoneList<Expression*>(1, zone());
204 spread_args_expr->Add(spread_args, zone()); 258 spread_args_expr->Add(spread_args, zone());
205 args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone()); 259 args->AddAll(*PrepareSpreadArguments(spread_args_expr), zone());
206 VariableProxy* new_target_proxy = 260 VariableProxy* new_target_proxy =
207 NewUnresolved(ast_value_factory()->new_target_string(), pos); 261 NewUnresolved(ast_value_factory()->new_target_string(), pos);
208 args->Add(new_target_proxy, zone()); 262 args->Add(new_target_proxy, zone());
209 CallRuntime* call = factory()->NewCallRuntime( 263 Expression* call = factory()->NewCallRuntime(
210 Context::REFLECT_CONSTRUCT_INDEX, args, pos); 264 Context::REFLECT_CONSTRUCT_INDEX, args, pos);
265 if (requires_class_field_init) {
266 call = CallClassFieldInitializer(scope(), call);
267 }
211 body->Add(factory()->NewReturnStatement(call, pos), zone()); 268 body->Add(factory()->NewReturnStatement(call, pos), zone());
212 } 269 }
213 270
214 materialized_literal_count = function_state.materialized_literal_count(); 271 materialized_literal_count = function_state.materialized_literal_count();
215 expected_property_count = function_state.expected_property_count(); 272 expected_property_count = function_state.expected_property_count();
216 } 273 }
217 274
218 FunctionLiteral* function_literal = factory()->NewFunctionLiteral( 275 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
219 name, function_scope, body, materialized_literal_count, 276 name, function_scope, body, materialized_literal_count,
220 expected_property_count, parameter_count, 277 expected_property_count, parameter_count,
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 // must produce a FunctionLiteral. 961 // must produce a FunctionLiteral.
905 DCHECK(expression->IsFunctionLiteral()); 962 DCHECK(expression->IsFunctionLiteral());
906 result = expression->AsFunctionLiteral(); 963 result = expression->AsFunctionLiteral();
907 } else { 964 } else {
908 ok = false; 965 ok = false;
909 } 966 }
910 } 967 }
911 } 968 }
912 } else if (info->is_default_constructor()) { 969 } else if (info->is_default_constructor()) {
913 DCHECK_EQ(scope(), outer); 970 DCHECK_EQ(scope(), outer);
971 bool is_subclass_constructor =
972 IsSubclassConstructor(info->function_kind());
914 result = DefaultConstructor( 973 result = DefaultConstructor(
915 raw_name, IsSubclassConstructor(info->function_kind()), 974 raw_name, is_subclass_constructor, info->requires_class_field_init(),
916 info->requires_class_field_init(), info->start_position(), 975 info->start_position(), info->end_position(), info->language_mode());
917 info->end_position(), info->language_mode()); 976 if (!is_subclass_constructor && info->requires_class_field_init()) {
977 result = InsertClassFieldInitializer(result);
978 }
979 } else if (info->is_class_field_initializer()) {
980 Handle<SharedFunctionInfo> shared_info = info->shared_info();
981 DCHECK(!shared_info.is_null());
982 if (shared_info->length() == 0) {
983 result = ParseClassFieldForInitializer(
984 info->start_position() != info->end_position(), &ok);
985 } else {
986 result = SynthesizeClassFieldInitializer(shared_info->length());
987 }
918 } else { 988 } else {
919 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(), 989 result = ParseFunctionLiteral(raw_name, Scanner::Location::invalid(),
920 kSkipFunctionNameCheck, 990 kSkipFunctionNameCheck,
921 info->function_kind(), kNoSourcePosition, 991 info->function_kind(), kNoSourcePosition,
922 function_type, info->language_mode(), &ok); 992 function_type, info->language_mode(), &ok);
993 if (info->requires_class_field_init()) {
994 result = InsertClassFieldInitializer(result);
995 }
923 } 996 }
924 // Make sure the results agree. 997 // Make sure the results agree.
925 DCHECK(ok == (result != nullptr)); 998 DCHECK(ok == (result != nullptr));
926 } 999 }
927 1000
928 // Make sure the target stack is empty. 1001 // Make sure the target stack is empty.
929 DCHECK_NULL(target_stack_); 1002 DCHECK_NULL(target_stack_);
930 return result; 1003 return result;
931 } 1004 }
932 1005
(...skipping 3255 matching lines...) Expand 10 before | Expand all | Expand 10 after
4188 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction( 4261 PreParser::PreParseResult result = reusable_preparser_->PreParseLazyFunction(
4189 language_mode(), function_state_->kind(), 4262 language_mode(), function_state_->kind(),
4190 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_, 4263 scope()->AsDeclarationScope()->has_simple_parameters(), parsing_module_,
4191 logger, may_abort, use_counts_); 4264 logger, may_abort, use_counts_);
4192 if (pre_parse_timer_ != NULL) { 4265 if (pre_parse_timer_ != NULL) {
4193 pre_parse_timer_->Stop(); 4266 pre_parse_timer_->Stop();
4194 } 4267 }
4195 return result; 4268 return result;
4196 } 4269 }
4197 4270
4271 Expression* Parser::InstallHomeObject(Expression* function_literal,
4272 Expression* home_object) {
4273 Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition);
4274 Variable* result_var =
4275 scope()->NewTemporary(ast_value_factory()->empty_string());
4276 DoExpression* do_expr =
4277 factory()->NewDoExpression(do_block, result_var, kNoSourcePosition);
4278 Assignment* init = factory()->NewAssignment(
4279 Token::ASSIGN, factory()->NewVariableProxy(result_var), function_literal,
4280 kNoSourcePosition);
4281 do_block->statements()->Add(
4282 factory()->NewExpressionStatement(init, kNoSourcePosition), zone());
4283 Property* home_object_property = factory()->NewProperty(
4284 factory()->NewVariableProxy(result_var),
4285 factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition),
4286 kNoSourcePosition);
4287 Assignment* assignment = factory()->NewAssignment(
4288 Token::ASSIGN, home_object_property, home_object, kNoSourcePosition);
4289 do_block->statements()->Add(
4290 factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone());
4291 return do_expr;
4292 }
4293
4294 const AstRawString* ClassFieldVariableName(bool is_name,
4295 AstValueFactory* ast_value_factory,
4296 int index) {
4297 std::string name =
4298 ".class-field-" + std::to_string(index) + (is_name ? "-name" : "-func");
4299 return ast_value_factory->GetOneByteString(name.c_str());
4300 }
4301
4302 FunctionLiteral* Parser::SynthesizeClassFieldInitializer(int count) {
4303 DCHECK(count > 0);
4304 // Makes a function which reads the names and initializers for each class
4305 // field out of deterministically named local variables and sets each property
4306 // to the result of evaluating its corresponding initializer in turn.
4307
4308 // This produces a function which looks like
4309 // function () {
4310 // this[.class-field-0-name] = .class-field-0-func();
4311 // this[.class-field-1-name] = .class-field-1-func();
4312 // [...]
4313 // this[.class-field-n-name] = .class-field-n-func();
4314 // return this;
4315 // }
4316 // except that it performs defineProperty, so that instead of '=' it has
4317 // %DefineDataPropertyInLiteral(this, .class-field-0-name,
4318 // .class-field-0-func(),
4319 // DONT_ENUM, false)
4320
4321 RaiseLanguageMode(STRICT);
4322 FunctionKind kind = FunctionKind::kConciseMethod;
4323 DeclarationScope* initializer_scope = NewFunctionScope(kind);
4324 SetLanguageMode(initializer_scope, language_mode());
4325 initializer_scope->set_start_position(scanner()->location().end_pos);
4326 initializer_scope->set_end_position(scanner()->location().end_pos);
4327 FunctionState initializer_state(&function_state_, &scope_state_,
4328 initializer_scope, kind);
4329 ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(count, zone());
4330 for (int i = 0; i < count; ++i) {
4331 const AstRawString* name =
4332 ClassFieldVariableName(true, ast_value_factory(), i);
4333 VariableProxy* name_proxy = scope()->NewUnresolved(factory(), name);
4334 const AstRawString* function_name =
4335 ClassFieldVariableName(false, ast_value_factory(), i);
4336 VariableProxy* function_proxy =
4337 scope()->NewUnresolved(factory(), function_name);
4338 ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone());
4339 args->Add(function_proxy, zone());
4340 args->Add(ThisExpression(kNoSourcePosition), zone());
4341 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args,
4342 kNoSourcePosition);
4343 ZoneList<Expression*>* define_property_args =
4344 new (zone()) ZoneList<Expression*>(5, zone());
4345 define_property_args->Add(ThisExpression(kNoSourcePosition), zone());
4346 define_property_args->Add(name_proxy, zone());
4347 define_property_args->Add(call, zone());
4348 define_property_args->Add(
4349 factory()->NewNumberLiteral(DONT_ENUM, kNoSourcePosition), zone());
4350 define_property_args->Add(
4351 factory()->NewNumberLiteral(
4352 false, // TODO(bakkot) function name inference a la class { x =
4353 // function(){}; static y = function(){}; }
4354 kNoSourcePosition),
4355 zone());
4356 body->Add(factory()->NewExpressionStatement(
4357 factory()->NewCallRuntime(
4358 Runtime::kDefineDataProperty,
4359 define_property_args, // TODO(bakkot) verify that this is
4360 // the same as object_define_property
4361 kNoSourcePosition),
4362 kNoSourcePosition),
4363 zone());
4364 }
4365 body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition),
4366 kNoSourcePosition),
4367 zone());
4368 FunctionLiteral* function_literal = factory()->NewFunctionLiteral(
4369 ast_value_factory()->empty_string(), initializer_scope, body,
4370 initializer_state.materialized_literal_count(),
4371 initializer_state.expected_property_count(), 0,
4372 FunctionLiteral::kNoDuplicateParameters,
4373 FunctionLiteral::kAnonymousExpression,
4374 FunctionLiteral::kShouldLazyCompile, kind,
4375 initializer_scope->start_position());
4376 function_literal->set_is_class_field_initializer(true);
4377 function_literal->scope()->set_arity(count);
4378 return function_literal;
4379 }
4380
4381 FunctionLiteral* Parser::InsertClassFieldInitializer(
4382 FunctionLiteral* constructor) {
4383 Statement* call_initializer = factory()->NewExpressionStatement(
4384 CallClassFieldInitializer(
4385 constructor->scope(),
4386 constructor->scope()->NewUnresolved(
4387 factory(), ast_value_factory()->this_string(), kNoSourcePosition,
4388 kNoSourcePosition + 4, THIS_VARIABLE)),
4389 kNoSourcePosition);
4390 constructor->body()->InsertAt(0, call_initializer, zone());
4391 return constructor;
4392 }
4393
4198 Expression* Parser::ParseClassLiteral(const AstRawString* name, 4394 Expression* Parser::ParseClassLiteral(const AstRawString* name,
4199 Scanner::Location class_name_location, 4395 Scanner::Location class_name_location,
4200 bool name_is_strict_reserved, int pos, 4396 bool name_is_strict_reserved, int pos,
4201 bool* ok) { 4397 bool* ok) {
4202 // All parts of a ClassDeclaration and ClassExpression are strict code. 4398 // All parts of a ClassDeclaration and ClassExpression are strict code.
4203 if (name_is_strict_reserved) { 4399 if (name_is_strict_reserved) {
4204 ReportMessageAt(class_name_location, 4400 ReportMessageAt(class_name_location,
4205 MessageTemplate::kUnexpectedStrictReserved); 4401 MessageTemplate::kUnexpectedStrictReserved);
4206 *ok = false; 4402 *ok = false;
4207 return nullptr; 4403 return nullptr;
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
4269 impl()->AccumulateFormalParameterContainmentErrors(); 4465 impl()->AccumulateFormalParameterContainmentErrors();
4270 4466
4271 if (has_seen_constructor && constructor == nullptr) { 4467 if (has_seen_constructor && constructor == nullptr) {
4272 constructor = GetPropertyValue(property)->AsFunctionLiteral(); 4468 constructor = GetPropertyValue(property)->AsFunctionLiteral();
4273 DCHECK_NOT_NULL(constructor); 4469 DCHECK_NOT_NULL(constructor);
4274 constructor->set_raw_name( 4470 constructor->set_raw_name(
4275 name != nullptr ? name : ast_value_factory()->empty_string()); 4471 name != nullptr ? name : ast_value_factory()->empty_string());
4276 } else { 4472 } else {
4277 if (property->kind() == ClassLiteralProperty::FIELD) { 4473 if (property->kind() == ClassLiteralProperty::FIELD) {
4278 DCHECK(allow_harmony_class_fields()); 4474 DCHECK(allow_harmony_class_fields());
4279 continue; // TODO(bakkot) implementation 4475 if (property->is_static()) {
4476 if (static_initializer_var == nullptr) {
4477 static_initializer_var =
4478 NewTemporary(ast_value_factory()->empty_string());
4479 }
4480 // TODO(bakkot) only do this conditionally
4481 Expression* function = InstallHomeObject(
4482 property->value(),
4483 factory()->NewVariableProxy(static_initializer_var));
4484 ZoneList<Expression*>* args =
4485 new (zone()) ZoneList<Expression*>(2, zone());
4486 args->Add(function, zone());
4487 args->Add(factory()->NewVariableProxy(static_initializer_var),
4488 zone());
4489 Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall,
4490 args, kNoSourcePosition);
4491 property->set_value(call);
4492 } else {
4493 // if (is_computed_name) { // TODO(bakkot) figure out why this is
4494 // necessary for non-computed names in full-codegen
4495 ZoneList<Expression*>* to_name_args =
4496 new (zone()) ZoneList<Expression*>(1, zone());
4497 to_name_args->Add(property->key(), zone());
4498 property->set_key(factory()->NewCallRuntime(
4499 Runtime::kToName, to_name_args, kNoSourcePosition));
4500 //}
4501 const AstRawString* name = ClassFieldVariableName(
4502 true, ast_value_factory(), instance_field_initializers->length());
4503 VariableProxy* name_proxy = NewUnresolved(name);
4504 Declaration* name_declaration = factory()->NewVariableDeclaration(
4505 name_proxy, scope(), kNoSourcePosition);
4506 Variable* name_var =
4507 Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST,
4508 kNeedsInitialization, ok, scope());
4509 DCHECK(ok);
4510 if (!ok) return nullptr;
4511 instance_field_initializers->Add(property->value(), zone());
4512 property->set_value(factory()->NewVariableProxy(name_var));
4513 }
4280 } 4514 }
4281 properties->Add(property, zone()); 4515 properties->Add(property, zone());
4282 } 4516 }
4283 4517
4284 DCHECK_NOT_NULL(fni_); 4518 DCHECK_NOT_NULL(fni_);
4285 fni_->Infer(); 4519 fni_->Infer();
4286 } 4520 }
4287 4521
4288 Expect(Token::RBRACE, CHECK_OK); 4522 Expect(Token::RBRACE, CHECK_OK);
4289 int end_pos = scanner()->location().end_pos; 4523 int end_pos = scanner()->location().end_pos;
4290 4524
4291 bool has_instance_fields = instance_field_initializers->length() > 0; 4525 bool has_instance_fields = instance_field_initializers->length() > 0;
4292 DCHECK(!has_instance_fields || allow_harmony_class_fields()); 4526 DCHECK(!has_instance_fields || allow_harmony_class_fields());
4293 bool has_default_constructor = constructor == nullptr; 4527 bool has_default_constructor = constructor == nullptr;
4294 if (has_default_constructor) { 4528 if (has_default_constructor) {
4295 constructor = DefaultConstructor(name, has_extends, has_instance_fields, 4529 constructor = DefaultConstructor(name, has_extends, has_instance_fields,
4296 pos, end_pos, block_state.language_mode()); 4530 pos, end_pos, block_state.language_mode());
4297 } 4531 }
4298 4532
4299 if (has_instance_fields && extends == nullptr) { 4533 if (has_instance_fields && extends == nullptr) {
4534 constructor = InsertClassFieldInitializer(constructor);
4300 constructor->set_requires_class_field_init(true); 4535 constructor->set_requires_class_field_init(true);
4301 } // The derived case is handled by rewriting super calls. 4536 } // The derived case is handled by rewriting super calls.
4302 4537
4303 block_state.set_end_position(end_pos); 4538 block_state.set_end_position(end_pos);
4304 4539
4305 if (name != nullptr) { 4540 if (name != nullptr) {
4306 DCHECK_NOT_NULL(proxy); 4541 DCHECK_NOT_NULL(proxy);
4307 proxy->var()->set_initializer_position(end_pos); 4542 proxy->var()->set_initializer_position(end_pos);
4308 } 4543 }
4309 4544
4310 ClassLiteral* class_literal = factory()->NewClassLiteral( 4545 ClassLiteral* class_literal = factory()->NewClassLiteral(
4311 proxy, extends, constructor, properties, pos, end_pos); 4546 proxy, extends, constructor, properties, pos, end_pos);
4312 4547
4313 if (static_initializer_var != nullptr) { 4548 if (static_initializer_var != nullptr) {
4314 class_literal->set_static_initializer_proxy( 4549 class_literal->set_static_initializer_proxy(
4315 factory()->NewVariableProxy(static_initializer_var)); 4550 factory()->NewVariableProxy(static_initializer_var));
4316 } 4551 }
4317 4552
4318 do_block->statements()->Add( 4553 do_block->statements()->Add(
4319 factory()->NewExpressionStatement( 4554 factory()->NewExpressionStatement(
4320 factory()->NewAssignment(Token::ASSIGN, 4555 factory()->NewAssignment(Token::ASSIGN,
4321 factory()->NewVariableProxy(result_var), 4556 factory()->NewVariableProxy(result_var),
4322 class_literal, kNoSourcePosition), 4557 class_literal, kNoSourcePosition),
4323 pos), 4558 pos),
4324 zone()); 4559 zone());
4560 if (allow_harmony_class_fields() &&
4561 (has_instance_fields ||
4562 (extends != nullptr && !has_default_constructor))) {
4563 // Default constructors for derived classes without fields will not try to
4564 // read this variable, so there's no need to create it.
4565 const AstRawString* init_fn_name =
4566 ast_value_factory()->dot_class_field_init_string();
4567 Variable* init_fn_var = scope()->DeclareLocal(
4568 init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE);
4569 Expression* initializer =
4570 has_instance_fields
4571 ? static_cast<Expression*>(SynthesizeClassFieldInitializer(
4572 instance_field_initializers->length()))
4573 : factory()->NewBooleanLiteral(false, kNoSourcePosition);
4574 Assignment* assignment = factory()->NewAssignment(
4575 Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer,
4576 kNoSourcePosition);
4577 do_block->statements()->Add(
4578 factory()->NewExpressionStatement(assignment, kNoSourcePosition),
4579 zone());
4580 }
4581 for (int i = 0; i < instance_field_initializers->length(); ++i) {
4582 const AstRawString* function_name =
4583 ClassFieldVariableName(false, ast_value_factory(), i);
4584 VariableProxy* function_proxy = NewUnresolved(function_name);
4585 Declaration* function_declaration = factory()->NewVariableDeclaration(
4586 function_proxy, scope(), kNoSourcePosition);
4587 Variable* function_var =
4588 Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST,
4589 kNeedsInitialization, ok, scope());
4590 DCHECK(ok);
4591 if (!ok) return nullptr;
4592 Property* prototype_property = factory()->NewProperty(
4593 factory()->NewVariableProxy(result_var),
4594 factory()->NewStringLiteral(ast_value_factory()->prototype_string(),
4595 kNoSourcePosition),
4596 kNoSourcePosition);
4597 Expression* function_value = InstallHomeObject(
4598 instance_field_initializers->at(i),
4599 prototype_property); // TODO(bakkot) ideally this would be conditional,
4600 // especially in trivial cases
4601 Assignment* function_assignment = factory()->NewAssignment(
4602 Token::INIT, factory()->NewVariableProxy(function_var), function_value,
4603 kNoSourcePosition);
4604 do_block->statements()->Add(factory()->NewExpressionStatement(
4605 function_assignment, kNoSourcePosition),
4606 zone());
4607 }
4325 do_block->set_scope(block_state.FinalizedBlockScope()); 4608 do_block->set_scope(block_state.FinalizedBlockScope());
4326 do_expr->set_represented_function(constructor); 4609 do_expr->set_represented_function(constructor);
4327 4610
4328 return do_expr; 4611 return do_expr;
4329 } 4612 }
4330 4613
4331 4614
4332 Expression* Parser::ParseV8Intrinsic(bool* ok) { 4615 Expression* Parser::ParseV8Intrinsic(bool* ok) {
4333 // CallRuntime :: 4616 // CallRuntime ::
4334 // '%' Identifier Arguments 4617 // '%' Identifier Arguments
(...skipping 1873 matching lines...) Expand 10 before | Expand all | Expand 10 after
6208 node->Print(Isolate::Current()); 6491 node->Print(Isolate::Current());
6209 } 6492 }
6210 #endif // DEBUG 6493 #endif // DEBUG
6211 6494
6212 #undef CHECK_OK 6495 #undef CHECK_OK
6213 #undef CHECK_OK_VOID 6496 #undef CHECK_OK_VOID
6214 #undef CHECK_FAILED 6497 #undef CHECK_FAILED
6215 6498
6216 } // namespace internal 6499 } // namespace internal
6217 } // namespace v8 6500 } // 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