Index: src/parsing/parser.cc |
diff --git a/src/parsing/parser.cc b/src/parsing/parser.cc |
index e9813cc7d7f56e39bb530c97c38078523b4d43f5..ead405da7ac42b74e3109a88a2c106c3e8983248 100644 |
--- a/src/parsing/parser.cc |
+++ b/src/parsing/parser.cc |
@@ -164,63 +164,8 @@ void Parser::SetCachedData(ParseInfo* info) { |
} |
} |
-Expression* Parser::CallClassFieldInitializer(Scope* scope, |
- Expression* this_expr) { |
- // This produces the expression |
- // `.class_field_intializer(this_expr)`, where '.class_field_intializer' is |
- // the name |
- // of a synthetic variable. |
- // 'this_expr' will be 'this' in a base constructor and the result of calling |
- // 'super' in a derived one. |
- const AstRawString* init_fn_name = |
- ast_value_factory()->dot_class_field_init_string(); |
- VariableProxy* init_fn_proxy = scope->NewUnresolved(factory(), init_fn_name); |
- ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
- args->Add(init_fn_proxy, zone()); |
- args->Add(this_expr, zone()); |
- return factory()->NewCallRuntime(Runtime::kInlineCall, args, |
- kNoSourcePosition); |
-} |
- |
-Expression* Parser::RewriteSuperCall(Expression* super_call) { |
- // TODO(bakkot) find a way to avoid this for classes without fields. |
- if (!allow_harmony_class_fields()) { |
- return super_call; |
- } |
- // This turns a super call `super()` into a do expression of the form |
- // do { |
- // tmp x = super(); |
- // if (.class-field-init) |
- // .class-field-init(x) |
- // x; // This isn't actually present; our do-expression representation |
- // allows specifying that the expression returns x directly. |
- // } |
- Variable* var_tmp = |
- scope()->NewTemporary(ast_value_factory()->empty_string()); |
- Block* block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
- Assignment* assignment = factory()->NewAssignment( |
- Token::ASSIGN, factory()->NewVariableProxy(var_tmp), super_call, |
- kNoSourcePosition); |
- block->statements()->Add( |
- factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone()); |
- const AstRawString* init_fn_name = |
- ast_value_factory()->dot_class_field_init_string(); |
- VariableProxy* init_fn_proxy = |
- scope()->NewUnresolved(factory(), init_fn_name); |
- Expression* condition = init_fn_proxy; |
- Statement* initialize = factory()->NewExpressionStatement( |
- CallClassFieldInitializer(scope(), factory()->NewVariableProxy(var_tmp)), |
- kNoSourcePosition); |
- IfStatement* if_statement = factory()->NewIfStatement( |
- condition, initialize, factory()->NewEmptyStatement(kNoSourcePosition), |
- kNoSourcePosition); |
- block->statements()->Add(if_statement, zone()); |
- return factory()->NewDoExpression(block, var_tmp, kNoSourcePosition); |
-} |
- |
FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, |
bool call_super, |
- bool requires_class_field_init, |
int pos, int end_pos, |
LanguageMode language_mode) { |
int materialized_literal_count = -1; |
@@ -275,8 +220,6 @@ FunctionLiteral* Parser::DefaultConstructor(const AstRawString* name, |
FunctionLiteral::kAnonymousExpression, default_eager_compile_hint(), pos, |
true, GetNextFunctionLiteralId()); |
- function_literal->set_requires_class_field_init(requires_class_field_init); |
- |
return function_literal; |
} |
@@ -995,28 +938,13 @@ FunctionLiteral* Parser::DoParseFunction(ParseInfo* info, |
} else if (IsDefaultConstructor(kind)) { |
DCHECK_EQ(scope(), outer); |
bool is_subclass_constructor = IsSubclassConstructor(kind); |
- result = DefaultConstructor( |
- raw_name, is_subclass_constructor, info->requires_class_field_init(), |
- info->start_position(), info->end_position(), info->language_mode()); |
- if (!is_subclass_constructor && info->requires_class_field_init()) { |
- result = InsertClassFieldInitializer(result); |
- } |
- } else if (info->is_class_field_initializer()) { |
- Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
- DCHECK(!shared_info.is_null()); |
- if (shared_info->length() == 0) { |
- result = ParseClassFieldForInitializer( |
- info->start_position() != info->end_position(), &ok); |
- } else { |
- result = SynthesizeClassFieldInitializer(shared_info->length()); |
- } |
+ result = DefaultConstructor(raw_name, is_subclass_constructor, |
+ info->start_position(), info->end_position(), |
+ info->language_mode()); |
} else { |
result = ParseFunctionLiteral( |
raw_name, Scanner::Location::invalid(), kSkipFunctionNameCheck, kind, |
kNoSourcePosition, function_type, info->language_mode(), &ok); |
- if (info->requires_class_field_init()) { |
- result = InsertClassFieldInitializer(result); |
- } |
} |
// Make sure the results agree. |
DCHECK(ok == (result != nullptr)); |
@@ -3338,130 +3266,6 @@ ZoneList<Statement*>* Parser::ParseEagerFunctionBody( |
return result; |
} |
-Expression* Parser::InstallHomeObject(Expression* function_literal, |
- Expression* home_object) { |
- Block* do_block = factory()->NewBlock(nullptr, 1, false, kNoSourcePosition); |
- Variable* result_var = |
- scope()->NewTemporary(ast_value_factory()->empty_string()); |
- DoExpression* do_expr = |
- factory()->NewDoExpression(do_block, result_var, kNoSourcePosition); |
- Assignment* init = factory()->NewAssignment( |
- Token::ASSIGN, factory()->NewVariableProxy(result_var), function_literal, |
- kNoSourcePosition); |
- do_block->statements()->Add( |
- factory()->NewExpressionStatement(init, kNoSourcePosition), zone()); |
- Property* home_object_property = factory()->NewProperty( |
- factory()->NewVariableProxy(result_var), |
- factory()->NewSymbolLiteral("home_object_symbol", kNoSourcePosition), |
- kNoSourcePosition); |
- Assignment* assignment = factory()->NewAssignment( |
- Token::ASSIGN, home_object_property, home_object, kNoSourcePosition); |
- do_block->statements()->Add( |
- factory()->NewExpressionStatement(assignment, kNoSourcePosition), zone()); |
- return do_expr; |
-} |
- |
-const AstRawString* ClassFieldVariableName(bool is_name, |
- AstValueFactory* ast_value_factory, |
- int index) { |
- std::string name = |
- ".class-field-" + std::to_string(index) + (is_name ? "-name" : "-func"); |
- return ast_value_factory->GetOneByteString(name.c_str()); |
-} |
- |
-FunctionLiteral* Parser::SynthesizeClassFieldInitializer(int count) { |
- DCHECK(count > 0); |
- // Makes a function which reads the names and initializers for each class |
- // field out of deterministically named local variables and sets each property |
- // to the result of evaluating its corresponding initializer in turn. |
- |
- // This produces a function which looks like |
- // function () { |
- // this[.class-field-0-name] = .class-field-0-func(); |
- // this[.class-field-1-name] = .class-field-1-func(); |
- // [...] |
- // this[.class-field-n-name] = .class-field-n-func(); |
- // return this; |
- // } |
- // except that it performs defineProperty, so that instead of '=' it has |
- // %DefineDataPropertyInLiteral(this, .class-field-0-name, |
- // .class-field-0-func(), |
- // DONT_ENUM, false) |
- |
- RaiseLanguageMode(STRICT); |
- FunctionKind kind = FunctionKind::kConciseMethod; |
- DeclarationScope* initializer_scope = NewFunctionScope(kind); |
- SetLanguageMode(initializer_scope, language_mode()); |
- initializer_scope->set_start_position(scanner()->location().end_pos); |
- initializer_scope->set_end_position(scanner()->location().end_pos); |
- FunctionState initializer_state(&function_state_, &scope_state_, |
- initializer_scope); |
- ZoneList<Statement*>* body = new (zone()) ZoneList<Statement*>(count, zone()); |
- for (int i = 0; i < count; ++i) { |
- const AstRawString* name = |
- ClassFieldVariableName(true, ast_value_factory(), i); |
- VariableProxy* name_proxy = scope()->NewUnresolved(factory(), name); |
- const AstRawString* function_name = |
- ClassFieldVariableName(false, ast_value_factory(), i); |
- VariableProxy* function_proxy = |
- scope()->NewUnresolved(factory(), function_name); |
- ZoneList<Expression*>* args = new (zone()) ZoneList<Expression*>(2, zone()); |
- args->Add(function_proxy, zone()); |
- args->Add(ThisExpression(kNoSourcePosition), zone()); |
- Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args, |
- kNoSourcePosition); |
- ZoneList<Expression*>* define_property_args = |
- new (zone()) ZoneList<Expression*>(5, zone()); |
- define_property_args->Add(ThisExpression(kNoSourcePosition), zone()); |
- define_property_args->Add(name_proxy, zone()); |
- define_property_args->Add(call, zone()); |
- define_property_args->Add( |
- factory()->NewNumberLiteral(DONT_ENUM, kNoSourcePosition), zone()); |
- define_property_args->Add( |
- factory()->NewNumberLiteral( |
- false, // TODO(bakkot) function name inference a la class { x = |
- // function(){}; static y = function(){}; } |
- kNoSourcePosition), |
- zone()); |
- body->Add(factory()->NewExpressionStatement( |
- factory()->NewCallRuntime( |
- Runtime::kDefineDataProperty, |
- define_property_args, // TODO(bakkot) verify that this is |
- // the same as object_define_property |
- kNoSourcePosition), |
- kNoSourcePosition), |
- zone()); |
- } |
- body->Add(factory()->NewReturnStatement(ThisExpression(kNoSourcePosition), |
- kNoSourcePosition), |
- zone()); |
- FunctionLiteral* function_literal = factory()->NewFunctionLiteral( |
- ast_value_factory()->empty_string(), initializer_scope, body, |
- initializer_state.materialized_literal_count(), |
- initializer_state.expected_property_count(), 0, count, |
- FunctionLiteral::kNoDuplicateParameters, |
- FunctionLiteral::kAnonymousExpression, |
- FunctionLiteral::kShouldLazyCompile, initializer_scope->start_position(), |
- true, GetNextFunctionLiteralId()); |
- function_literal->set_is_class_field_initializer(true); |
- return function_literal; |
-} |
- |
-FunctionLiteral* Parser::InsertClassFieldInitializer( |
- FunctionLiteral* constructor) { |
- Statement* call_initializer = factory()->NewExpressionStatement( |
- CallClassFieldInitializer( |
- constructor->scope(), |
- constructor->scope()->NewUnresolved( |
- factory(), ast_value_factory()->this_string(), kNoSourcePosition, |
- THIS_VARIABLE)), |
- kNoSourcePosition); |
- constructor->body()->InsertAt(0, call_initializer, zone()); |
- return constructor; |
-} |
- |
-// If a class name is specified, this method declares the class variable |
-// and sets class_info->proxy to point to that name. |
void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope, |
ClassInfo* class_info, int class_token_pos, |
bool* ok) { |
@@ -3481,8 +3285,6 @@ void Parser::DeclareClassVariable(const AstRawString* name, Scope* block_scope, |
// This method declares a property of the given class. It updates the |
// following fields of class_info, as appropriate: |
// - constructor |
-// - static_initializer_var |
-// - instance_field_initializers |
// - properties |
void Parser::DeclareClassProperty(const AstRawString* class_name, |
ClassLiteralProperty* property, |
@@ -3501,47 +3303,7 @@ void Parser::DeclareClassProperty(const AstRawString* class_name, |
if (property->kind() == ClassLiteralProperty::FIELD) { |
DCHECK(allow_harmony_class_fields()); |
- if (property->is_static()) { |
- if (class_info->static_initializer_var == nullptr) { |
- class_info->static_initializer_var = |
- NewTemporary(ast_value_factory()->empty_string()); |
- } |
- // TODO(bakkot) only do this conditionally |
- Expression* function = InstallHomeObject( |
- property->value(), |
- factory()->NewVariableProxy(class_info->static_initializer_var)); |
- ZoneList<Expression*>* args = |
- new (zone()) ZoneList<Expression*>(2, zone()); |
- args->Add(function, zone()); |
- args->Add(factory()->NewVariableProxy(class_info->static_initializer_var), |
- zone()); |
- Expression* call = factory()->NewCallRuntime(Runtime::kInlineCall, args, |
- kNoSourcePosition); |
- property->set_value(call); |
- } else { |
- // if (is_computed_name) { // TODO(bakkot) figure out why this is |
- // necessary for non-computed names in full-codegen |
- ZoneList<Expression*>* to_name_args = |
- new (zone()) ZoneList<Expression*>(1, zone()); |
- to_name_args->Add(property->key(), zone()); |
- property->set_key(factory()->NewCallRuntime( |
- Runtime::kToName, to_name_args, kNoSourcePosition)); |
- //} |
- const AstRawString* name = ClassFieldVariableName( |
- true, ast_value_factory(), |
- class_info->instance_field_initializers->length()); |
- VariableProxy* name_proxy = |
- factory()->NewVariableProxy(name, NORMAL_VARIABLE); |
- Declaration* name_declaration = factory()->NewVariableDeclaration( |
- name_proxy, scope(), kNoSourcePosition); |
- Variable* name_var = |
- Declare(name_declaration, DeclarationDescriptor::NORMAL, CONST, |
- kNeedsInitialization, ok, scope()); |
- DCHECK(*ok); |
- if (!*ok) return; |
- class_info->instance_field_initializers->Add(property->value(), zone()); |
- property->set_value(factory()->NewVariableProxy(name_var)); |
- } |
+ // TODO(littledan): Implement class fields |
} |
class_info->properties->Add(property, zone()); |
} |
@@ -3551,8 +3313,6 @@ void Parser::DeclareClassProperty(const AstRawString* class_name, |
// - constructor (if missing, it updates it with a default constructor) |
// - proxy |
// - extends |
-// - static_initializer_var |
-// - instance_field_initializers |
// - properties |
// - has_name_static_property |
// - has_static_computed_names |
@@ -3565,22 +3325,12 @@ Expression* Parser::RewriteClassLiteral(const AstRawString* name, |
DoExpression* do_expr = factory()->NewDoExpression(do_block, result_var, pos); |
bool has_extends = class_info->extends != nullptr; |
- bool has_instance_fields = |
- class_info->instance_field_initializers->length() > 0; |
- DCHECK(!has_instance_fields || allow_harmony_class_fields()); |
bool has_default_constructor = class_info->constructor == nullptr; |
if (has_default_constructor) { |
- class_info->constructor = |
- DefaultConstructor(name, has_extends, has_instance_fields, pos, end_pos, |
- scope()->language_mode()); |
+ class_info->constructor = DefaultConstructor( |
+ name, has_extends, pos, end_pos, scope()->language_mode()); |
} |
- if (has_instance_fields && !has_extends) { |
- class_info->constructor = |
- InsertClassFieldInitializer(class_info->constructor); |
- class_info->constructor->set_requires_class_field_init(true); |
- } // The derived case is handled by rewriting super calls. |
- |
scope()->set_end_position(end_pos); |
if (name != nullptr) { |
@@ -3594,11 +3344,6 @@ Expression* Parser::RewriteClassLiteral(const AstRawString* name, |
class_info->has_name_static_property, |
class_info->has_static_computed_names); |
- if (class_info->static_initializer_var != nullptr) { |
- class_literal->set_static_initializer_proxy( |
- factory()->NewVariableProxy(class_info->static_initializer_var)); |
- } |
- |
do_block->statements()->Add( |
factory()->NewExpressionStatement( |
factory()->NewAssignment(Token::ASSIGN, |
@@ -3606,53 +3351,6 @@ Expression* Parser::RewriteClassLiteral(const AstRawString* name, |
class_literal, kNoSourcePosition), |
pos), |
zone()); |
- if (allow_harmony_class_fields() && |
- (has_instance_fields || (has_extends && !has_default_constructor))) { |
- // Default constructors for derived classes without fields will not try to |
- // read this variable, so there's no need to create it. |
- const AstRawString* init_fn_name = |
- ast_value_factory()->dot_class_field_init_string(); |
- Variable* init_fn_var = scope()->DeclareLocal( |
- init_fn_name, CONST, kCreatedInitialized, NORMAL_VARIABLE); |
- Expression* initializer = |
- has_instance_fields |
- ? static_cast<Expression*>(SynthesizeClassFieldInitializer( |
- class_info->instance_field_initializers->length())) |
- : factory()->NewBooleanLiteral(false, kNoSourcePosition); |
- Assignment* assignment = factory()->NewAssignment( |
- Token::INIT, factory()->NewVariableProxy(init_fn_var), initializer, |
- kNoSourcePosition); |
- do_block->statements()->Add( |
- factory()->NewExpressionStatement(assignment, kNoSourcePosition), |
- zone()); |
- } |
- for (int i = 0; i < class_info->instance_field_initializers->length(); ++i) { |
- const AstRawString* function_name = |
- ClassFieldVariableName(false, ast_value_factory(), i); |
- VariableProxy* function_proxy = |
- factory()->NewVariableProxy(function_name, NORMAL_VARIABLE); |
- Declaration* function_declaration = factory()->NewVariableDeclaration( |
- function_proxy, scope(), kNoSourcePosition); |
- Variable* function_var = |
- Declare(function_declaration, DeclarationDescriptor::NORMAL, CONST, |
- kNeedsInitialization, ok, scope()); |
- if (!*ok) return nullptr; |
- Property* prototype_property = factory()->NewProperty( |
- factory()->NewVariableProxy(result_var), |
- factory()->NewStringLiteral(ast_value_factory()->prototype_string(), |
- kNoSourcePosition), |
- kNoSourcePosition); |
- Expression* function_value = InstallHomeObject( |
- class_info->instance_field_initializers->at(i), |
- prototype_property); // TODO(bakkot) ideally this would be conditional, |
- // especially in trivial cases |
- Assignment* function_assignment = factory()->NewAssignment( |
- Token::INIT, factory()->NewVariableProxy(function_var), function_value, |
- kNoSourcePosition); |
- do_block->statements()->Add(factory()->NewExpressionStatement( |
- function_assignment, kNoSourcePosition), |
- zone()); |
- } |
do_block->set_scope(scope()->FinalizeBlockScope()); |
do_expr->set_represented_function(class_info->constructor); |
AddFunctionForNameInference(class_info->constructor); |