Commit 61833f5b authored by littledan's avatar littledan Committed by Commit bot

Remove class fields desugaring

This patch removes parser code implementing desugaring for ESnext
public and private fields on classes. The desugaring should probably
be implemented in the interpreter instead, and more work needs to go
into optimization and debugger support. The actual parsing of class
fields is left in, as the syntax is relatively stable, and there are
strong cctests for the grammar.

R=marja
BUG=v8:5367

Review-Url: https://codereview.chromium.org/2578893005
Cr-Commit-Position: refs/heads/master@{#41776}
parent b1c148b9
......@@ -291,7 +291,6 @@ class AstValue : public ZoneObject {
F(default, "default") \
F(done, "done") \
F(dot, ".") \
F(dot_class_field_init, ".class-field-init") \
F(dot_for, ".for") \
F(dot_generator_object, ".generator_object") \
F(dot_iterator, ".iterator") \
......
......@@ -2672,21 +2672,6 @@ class FunctionLiteral final : public Expression {
int yield_count() { return yield_count_; }
void set_yield_count(int yield_count) { yield_count_ = yield_count; }
bool requires_class_field_init() {
return RequiresClassFieldInit::decode(bit_field_);
}
void set_requires_class_field_init(bool requires_class_field_init) {
bit_field_ =
RequiresClassFieldInit::update(bit_field_, requires_class_field_init);
}
bool is_class_field_initializer() {
return IsClassFieldInitializer::decode(bit_field_);
}
void set_is_class_field_initializer(bool is_class_field_initializer) {
bit_field_ =
IsClassFieldInitializer::update(bit_field_, is_class_field_initializer);
}
int return_position() {
return std::max(start_position(), end_position() - (has_braces_ ? 1 : 0));
}
......@@ -2721,15 +2706,13 @@ class FunctionLiteral final : public Expression {
raw_inferred_name_(ast_value_factory->empty_string()),
ast_properties_(zone),
function_literal_id_(function_literal_id) {
bit_field_ |=
FunctionTypeBits::encode(function_type) | Pretenure::encode(false) |
HasDuplicateParameters::encode(has_duplicate_parameters ==
kHasDuplicateParameters) |
IsFunction::encode(is_function) |
RequiresClassFieldInit::encode(false) |
ShouldNotBeUsedOnceHintField::encode(false) |
DontOptimizeReasonField::encode(kNoReason) |
IsClassFieldInitializer::encode(false);
bit_field_ |= FunctionTypeBits::encode(function_type) |
Pretenure::encode(false) |
HasDuplicateParameters::encode(has_duplicate_parameters ==
kHasDuplicateParameters) |
IsFunction::encode(is_function) |
ShouldNotBeUsedOnceHintField::encode(false) |
DontOptimizeReasonField::encode(kNoReason);
if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
}
......@@ -2740,12 +2723,9 @@ class FunctionLiteral final : public Expression {
class IsFunction : public BitField<bool, HasDuplicateParameters::kNext, 1> {};
class ShouldNotBeUsedOnceHintField
: public BitField<bool, IsFunction::kNext, 1> {};
class RequiresClassFieldInit
: public BitField<bool, ShouldNotBeUsedOnceHintField::kNext, 1> {};
class IsClassFieldInitializer
: public BitField<bool, RequiresClassFieldInit::kNext, 1> {};
class DontOptimizeReasonField
: public BitField<BailoutReason, IsClassFieldInitializer::kNext, 8> {};
: public BitField<BailoutReason, ShouldNotBeUsedOnceHintField::kNext, 8> {
};
int materialized_literal_count_;
int expected_property_count_;
......@@ -2803,13 +2783,6 @@ class ClassLiteral final : public Expression {
return HasStaticComputedNames::decode(bit_field_);
}
VariableProxy* static_initializer_proxy() const {
return static_initializer_proxy_;
}
void set_static_initializer_proxy(VariableProxy* proxy) {
static_initializer_proxy_ = proxy;
}
// Object literals need one feedback slot for each non-trivial value, as well
// as some slots for home objects.
void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
......@@ -2835,8 +2808,7 @@ class ClassLiteral final : public Expression {
class_variable_proxy_(class_variable_proxy),
extends_(extends),
constructor_(constructor),
properties_(properties),
static_initializer_proxy_(nullptr) {
properties_(properties) {
bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) |
HasStaticComputedNames::encode(has_static_computed_names);
}
......@@ -2848,7 +2820,6 @@ class ClassLiteral final : public Expression {
Expression* extends_;
FunctionLiteral* constructor_;
ZoneList<Property*>* properties_;
VariableProxy* static_initializer_proxy_;
class HasNameStaticProperty
: public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
......
......@@ -14039,9 +14039,6 @@ void SharedFunctionInfo::InitFromFunctionLiteral(
}
shared_info->set_needs_home_object(lit->scope()->NeedsHomeObject());
shared_info->set_asm_function(lit->scope()->asm_function());
shared_info->set_requires_class_field_init(lit->requires_class_field_init());
shared_info->set_is_class_field_initializer(
lit->is_class_field_initializer());
shared_info->set_function_literal_id(lit->function_literal_id());
SetExpectedNofPropertiesFromEstimate(shared_info, lit);
}
......
......@@ -673,19 +673,15 @@ class ParserBase {
: proxy(nullptr),
extends(parser->impl()->EmptyExpression()),
properties(parser->impl()->NewClassPropertyList(4)),
instance_field_initializers(parser->impl()->NewExpressionList(0)),
constructor(parser->impl()->EmptyFunctionLiteral()),
has_seen_constructor(false),
static_initializer_var(nullptr),
has_name_static_property(false),
has_static_computed_names(false) {}
VariableProxy* proxy;
ExpressionT extends;
typename Types::ClassPropertyList properties;
ExpressionListT instance_field_initializers;
FunctionLiteralT constructor;
bool has_seen_constructor;
Variable* static_initializer_var;
bool has_name_static_property;
bool has_static_computed_names;
};
......@@ -2309,7 +2305,6 @@ ParserBase<Impl>::ParseClassFieldForInitializer(bool has_initializer,
FunctionLiteral::kNoDuplicateParameters,
FunctionLiteral::kAnonymousExpression, default_eager_compile_hint_,
initializer_scope->start_position(), true, GetNextFunctionLiteralId());
function_literal->set_is_class_field_initializer(true);
return function_literal;
}
......@@ -3162,7 +3157,6 @@ ParserBase<Impl>::ParseLeftHandSideExpression(bool* ok) {
// Explicit calls to the super constructor using super() perform an
// implicit binding assignment to the 'this' variable.
if (is_super_call) {
result = impl()->RewriteSuperCall(result);
ExpressionT this_expr = impl()->ThisExpression(pos);
result =
factory()->NewAssignment(Token::INIT, this_expr, result, pos);
......
......@@ -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));
......@@ -3345,130 +3273,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) {
......@@ -3488,8 +3292,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,
......@@ -3508,47 +3310,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());
}
......@@ -3558,8 +3320,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
......@@ -3572,22 +3332,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) {
......@@ -3601,11 +3351,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,
......@@ -3613,53 +3358,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);
......
......@@ -476,11 +476,6 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
int function_token_position, FunctionLiteral::FunctionType type,
LanguageMode language_mode, bool* ok);
Expression* InstallHomeObject(Expression* function_literal,
Expression* home_object);
FunctionLiteral* SynthesizeClassFieldInitializer(int count);
FunctionLiteral* InsertClassFieldInitializer(FunctionLiteral* constructor);
// Get odd-ball literals.
Literal* GetLiteralUndefined(int position);
......@@ -523,8 +518,8 @@ class V8_EXPORT_PRIVATE Parser : public NON_EXPORTED_BASE(ParserBase<Parser>) {
// Factory methods.
FunctionLiteral* DefaultConstructor(const AstRawString* name, bool call_super,
bool requires_class_field_init, int pos,
int end_pos, LanguageMode language_mode);
int pos, int end_pos,
LanguageMode language_mode);
// Skip over a lazy function, either using cached data if we have it, or
// by parsing the function with PreParser. Consumes the ending }.
......
......@@ -322,8 +322,6 @@ class PreParserExpression {
int position() const { return kNoSourcePosition; }
void set_function_token_position(int position) {}
void set_is_class_field_initializer(bool is_class_field_initializer) {}
private:
enum Type {
kEmpty,
......@@ -974,11 +972,6 @@ class PreParser : public ParserBase<PreParser> {
PreParserExpressionList args,
int pos);
V8_INLINE PreParserExpression
RewriteSuperCall(PreParserExpression call_expression) {
return call_expression;
}
V8_INLINE void RewriteDestructuringAssignments() {}
V8_INLINE PreParserExpression RewriteExponentiation(PreParserExpression left,
......@@ -1083,23 +1076,13 @@ class PreParser : public ParserBase<PreParser> {
ClassLiteralProperty::Kind kind,
bool is_static, bool is_constructor,
ClassInfo* class_info, bool* ok) {
if (kind == ClassLiteralProperty::FIELD && !is_static && !is_constructor) {
class_info->instance_field_initializers->Add(
PreParserExpression::Default(), zone());
}
}
V8_INLINE PreParserExpression RewriteClassLiteral(PreParserIdentifier name,
ClassInfo* class_info,
int pos, bool* ok) {
bool has_default_constructor = !class_info->has_seen_constructor;
bool has_instance_fields =
class_info->instance_field_initializers->length() > 0;
// Account for the default constructor.
if (has_default_constructor) GetNextFunctionLiteralId();
if (allow_harmony_class_fields() && has_instance_fields) {
// Account for initializer function.
GetNextFunctionLiteralId();
}
return PreParserExpression::Default();
}
......
......@@ -671,38 +671,6 @@ RUNTIME_FUNCTION(Runtime_DefineDataPropertyInLiteral) {
return *object;
}
RUNTIME_FUNCTION(Runtime_DefineDataProperty) {
HandleScope scope(isolate);
DCHECK(args.length() == 5);
CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
CONVERT_ARG_HANDLE_CHECKED(Object, value, 2);
CONVERT_PROPERTY_ATTRIBUTES_CHECKED(attrs, 3);
CONVERT_SMI_ARG_CHECKED(set_function_name, 4);
if (set_function_name) {
DCHECK(value->IsJSFunction());
JSFunction::SetName(Handle<JSFunction>::cast(value), name,
isolate->factory()->empty_string());
}
PropertyDescriptor desc;
desc.set_writable(!(attrs & ReadOnly));
desc.set_enumerable(!(attrs & DontEnum));
desc.set_configurable(!(attrs & DontDelete));
desc.set_value(value);
Maybe<bool> result = JSReceiver::DefineOwnProperty(isolate, receiver, name,
&desc, Object::DONT_THROW);
RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
if (result.IsNothing()) {
DCHECK(isolate->has_pending_exception());
return isolate->heap()->exception();
}
return *receiver;
}
// Return property without being observable by accessors or interceptors.
RUNTIME_FUNCTION(Runtime_GetDataProperty) {
HandleScope scope(isolate);
......
......@@ -412,7 +412,6 @@ namespace internal {
F(IsJSGlobalProxy, 1, 1) \
F(DefineAccessorPropertyUnchecked, 5, 1) \
F(DefineDataPropertyInLiteral, 5, 1) \
F(DefineDataProperty, 5, 1) \
F(GetDataProperty, 2, 1) \
F(GetConstructorName, 1, 1) \
F(HasFastPackedElements, 1, 1) \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment