Commit abf4c01d authored by rmcilroy's avatar rmcilroy Committed by Commit bot

[fullcodegen] Remove deprecated support for class literals.

This code is no longer used in full-codegen or ast-graph-builder since all
functions which have class literals go through Ignition first.

BUG=v8:5657

Review-Url: https://codereview.chromium.org/2534463002
Cr-Commit-Position: refs/heads/master@{#41282}
parent 485067c6
......@@ -1329,107 +1329,7 @@ void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) {
ast_context()->ProduceValue(expr, value);
}
void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) {
VisitForValueOrTheHole(expr->extends());
VisitForValue(expr->constructor());
// Create node to instantiate a new class.
Node* constructor = environment()->Pop();
Node* extends = environment()->Pop();
Node* start = jsgraph()->Constant(expr->start_position());
Node* end = jsgraph()->Constant(expr->end_position());
const Operator* opc = javascript()->CallRuntime(Runtime::kDefineClass);
Node* literal = NewNode(opc, extends, constructor, start, end);
PrepareFrameState(literal, expr->CreateLiteralId(),
OutputFrameStateCombine::Push());
environment()->Push(literal);
// Load the "prototype" from the constructor.
PrepareEagerCheckpoint(expr->CreateLiteralId());
Handle<Name> name = isolate()->factory()->prototype_string();
VectorSlotPair pair = CreateVectorSlotPair(expr->PrototypeSlot());
Node* prototype = BuildNamedLoad(literal, name, pair);
PrepareFrameState(prototype, expr->PrototypeId(),
OutputFrameStateCombine::Push());
environment()->Push(prototype);
// Create nodes to store method values into the literal.
for (int i = 0; i < expr->properties()->length(); i++) {
ClassLiteral::Property* property = expr->properties()->at(i);
environment()->Push(environment()->Peek(property->is_static() ? 1 : 0));
VisitForValue(property->key());
Node* name = BuildToName(environment()->Pop(), expr->GetIdForProperty(i));
environment()->Push(name);
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
Node* check = BuildThrowIfStaticPrototype(environment()->Pop(),
expr->GetIdForProperty(i));
environment()->Push(check);
}
VisitForValue(property->value());
Node* value = environment()->Pop();
Node* key = environment()->Pop();
Node* receiver = environment()->Pop();
BuildSetHomeObject(value, receiver, property);
switch (property->kind()) {
case ClassLiteral::Property::METHOD: {
Node* attr = jsgraph()->Constant(DONT_ENUM);
Node* set_function_name =
jsgraph()->Constant(property->NeedsSetFunctionName());
const Operator* op =
javascript()->CallRuntime(Runtime::kDefineDataPropertyInLiteral);
Node* call = NewNode(op, receiver, key, value, attr, set_function_name);
PrepareFrameState(call, BailoutId::None());
break;
}
case ClassLiteral::Property::GETTER: {
Node* attr = jsgraph()->Constant(DONT_ENUM);
const Operator* op = javascript()->CallRuntime(
Runtime::kDefineGetterPropertyUnchecked, 4);
NewNode(op, receiver, key, value, attr);
break;
}
case ClassLiteral::Property::SETTER: {
Node* attr = jsgraph()->Constant(DONT_ENUM);
const Operator* op = javascript()->CallRuntime(
Runtime::kDefineSetterPropertyUnchecked, 4);
NewNode(op, receiver, key, value, attr);
break;
}
case ClassLiteral::Property::FIELD: {
UNREACHABLE();
break;
}
}
}
// Set the constructor to have fast properties.
prototype = environment()->Pop();
literal = environment()->Pop();
const Operator* op = javascript()->CallRuntime(Runtime::kToFastProperties);
literal = NewNode(op, literal);
// Assign to class variable.
if (expr->class_variable_proxy() != nullptr) {
Variable* var = expr->class_variable_proxy()->var();
VectorSlotPair feedback = CreateVectorSlotPair(
expr->NeedsProxySlot() ? expr->ProxySlot()
: FeedbackVectorSlot::Invalid());
BuildVariableAssignment(var, literal, Token::INIT, feedback,
BailoutId::None());
}
ast_context()->ProduceValue(expr, literal);
}
void AstGraphBuilder::VisitClassLiteral(ClassLiteral* expr) { UNREACHABLE(); }
void AstGraphBuilder::VisitNativeFunctionLiteral(NativeFunctionLiteral* expr) {
UNREACHABLE();
......@@ -2975,25 +2875,6 @@ Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable,
return environment()->Pop();
}
Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name,
BailoutId bailout_id) {
IfBuilder prototype_check(this);
Node* prototype_string =
jsgraph()->Constant(isolate()->factory()->prototype_string());
Node* check = NewNode(javascript()->StrictEqual(CompareOperationHint::kAny),
name, prototype_string);
prototype_check.If(check);
prototype_check.Then();
Node* error = BuildThrowStaticPrototypeError(bailout_id);
environment()->Push(error);
prototype_check.Else();
environment()->Push(name);
prototype_check.End();
return environment()->Pop();
}
Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
BailoutId bailout_id,
const VectorSlotPair& feedback,
......@@ -3368,18 +3249,6 @@ Node* AstGraphBuilder::BuildThrowConstAssignError(BailoutId bailout_id) {
return call;
}
Node* AstGraphBuilder::BuildThrowStaticPrototypeError(BailoutId bailout_id) {
const Operator* op =
javascript()->CallRuntime(Runtime::kThrowStaticPrototypeError);
Node* call = NewNode(op);
PrepareFrameState(call, bailout_id);
Node* control = NewNode(common()->Throw(), call);
UpdateControlDependencyToLeaveFunction(control);
return call;
}
Node* AstGraphBuilder::BuildThrowUnsupportedSuperError(BailoutId bailout_id) {
const Operator* op =
javascript()->CallRuntime(Runtime::kThrowUnsupportedSuperError);
......
......@@ -335,7 +335,6 @@ class AstGraphBuilder : public AstVisitor<AstGraphBuilder> {
Node* BuildThrowError(Node* exception, BailoutId bailout_id);
Node* BuildThrowReferenceError(Variable* var, BailoutId bailout_id);
Node* BuildThrowConstAssignError(BailoutId bailout_id);
Node* BuildThrowStaticPrototypeError(BailoutId bailout_id);
Node* BuildThrowUnsupportedSuperError(BailoutId bailout_id);
// Builders for dynamic hole-checks at runtime.
......@@ -344,9 +343,6 @@ class AstGraphBuilder : public AstVisitor<AstGraphBuilder> {
Node* BuildHoleCheckElseThrow(Node* value, Variable* var, Node* for_hole,
BailoutId bailout_id);
// Builders for conditional errors.
Node* BuildThrowIfStaticPrototype(Node* name, BailoutId bailout_id);
// Builders for non-local control flow.
Node* BuildReturn(Node* return_value);
Node* BuildThrow(Node* exception_value);
......
......@@ -1780,60 +1780,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
context()->Plug(r0);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
Register scratch = r1;
if (property->is_static()) {
__ ldr(scratch, MemOperand(sp, kPointerSize)); // constructor
} else {
__ ldr(scratch, MemOperand(sp, 0)); // prototype
}
PushOperand(scratch);
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ push(r0);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
default:
UNREACHABLE();
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
PopOperand(r1);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
......
......@@ -1729,60 +1729,6 @@ void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
context()->Plug(x0);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
Register scratch = x1;
if (property->is_static()) {
__ Peek(scratch, kPointerSize); // constructor
} else {
__ Peek(scratch, 0); // prototype
}
PushOperand(scratch);
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ Push(x0);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
default:
UNREACHABLE();
}
}
}
void FullCodeGenerator::EmitAssignment(Expression* expr,
FeedbackVectorSlot slot) {
DCHECK(expr->IsValidReferenceExpressionOrThis());
......
......@@ -1387,41 +1387,8 @@ void FullCodeGenerator::VisitFunctionLiteral(FunctionLiteral* expr) {
void FullCodeGenerator::VisitClassLiteral(ClassLiteral* lit) {
Comment cmnt(masm_, "[ ClassLiteral");
if (lit->extends() != NULL) {
VisitForStackValue(lit->extends());
} else {
PushOperand(isolate()->factory()->the_hole_value());
}
VisitForStackValue(lit->constructor());
PushOperand(Smi::FromInt(lit->start_position()));
PushOperand(Smi::FromInt(lit->end_position()));
CallRuntimeWithOperands(Runtime::kDefineClass);
PrepareForBailoutForId(lit->CreateLiteralId(), BailoutState::TOS_REGISTER);
PushOperand(result_register());
// Load the "prototype" from the constructor.
__ Move(LoadDescriptor::ReceiverRegister(), result_register());
CallLoadIC(lit->PrototypeSlot(), isolate()->factory()->prototype_string());
PrepareForBailoutForId(lit->PrototypeId(), BailoutState::TOS_REGISTER);
PushOperand(result_register());
EmitClassDefineProperties(lit);
DropOperands(1);
// Set the constructor to have fast properties.
CallRuntimeWithOperands(Runtime::kToFastProperties);
if (lit->class_variable_proxy() != nullptr) {
EmitVariableAssignment(lit->class_variable_proxy()->var(), Token::INIT,
lit->ProxySlot(), HoleCheckMode::kElided);
}
context()->Plug(result_register());
// Unsupported
UNREACHABLE();
}
void FullCodeGenerator::VisitRegExpLiteral(RegExpLiteral* expr) {
......
......@@ -478,11 +478,6 @@ class FullCodeGenerator final : public AstVisitor<FullCodeGenerator> {
// The receiver and the key is left on the stack by the IC.
void EmitKeyedPropertyLoad(Property* expr);
// Adds the properties to the class (function) object and to its prototype.
// Expects the class (function) in the accumulator. The class (function) is
// in the accumulator after installing all the properties.
void EmitClassDefineProperties(ClassLiteral* lit);
// Pushes the property key as a Name on the stack.
void EmitPropertyKey(LiteralProperty* property, BailoutId bailout_id);
......
......@@ -1697,58 +1697,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
context()->Plug(eax);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
if (property->is_static()) {
PushOperand(Operand(esp, kPointerSize)); // constructor
} else {
PushOperand(Operand(esp, 0)); // prototype
}
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ push(eax);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
UNREACHABLE();
break;
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
PopOperand(edx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
......
......@@ -1789,60 +1789,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
context()->Plug(v0);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
Register scratch = a1;
if (property->is_static()) {
__ lw(scratch, MemOperand(sp, kPointerSize)); // constructor
} else {
__ lw(scratch, MemOperand(sp, 0)); // prototype
}
PushOperand(scratch);
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ push(v0);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
default:
UNREACHABLE();
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ mov(a0, result_register());
PopOperand(a1);
......
......@@ -1789,60 +1789,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
context()->Plug(v0);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
Register scratch = a1;
if (property->is_static()) {
__ ld(scratch, MemOperand(sp, kPointerSize)); // constructor
} else {
__ ld(scratch, MemOperand(sp, 0)); // prototype
}
PushOperand(scratch);
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ push(v0);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
default:
UNREACHABLE();
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
__ mov(a0, result_register());
PopOperand(a1);
......
......@@ -1792,60 +1792,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
context()->Plug(r3);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
Register scratch = r4;
if (property->is_static()) {
__ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor
} else {
__ LoadP(scratch, MemOperand(sp, 0)); // prototype
}
PushOperand(scratch);
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ push(r3);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
default:
UNREACHABLE();
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
PopOperand(r4);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
......
......@@ -1755,58 +1755,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
context()->Plug(r2);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
Register scratch = r3;
if (property->is_static()) {
__ LoadP(scratch, MemOperand(sp, kPointerSize)); // constructor
} else {
__ LoadP(scratch, MemOperand(sp, 0)); // prototype
}
PushOperand(scratch);
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ push(r2);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
default:
UNREACHABLE();
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
PopOperand(r3);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
......
......@@ -1689,57 +1689,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
if (property->is_static()) {
PushOperand(Operand(rsp, kPointerSize)); // constructor
} else {
PushOperand(Operand(rsp, 0)); // prototype
}
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ Push(rax);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
default:
UNREACHABLE();
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
PopOperand(rdx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
......
......@@ -1689,58 +1689,6 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
context()->Plug(eax);
}
void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
for (int i = 0; i < lit->properties()->length(); i++) {
ClassLiteral::Property* property = lit->properties()->at(i);
Expression* value = property->value();
if (property->is_static()) {
PushOperand(Operand(esp, kPointerSize)); // constructor
} else {
PushOperand(Operand(esp, 0)); // prototype
}
EmitPropertyKey(property, lit->GetIdForProperty(i));
// The static prototype property is read only. We handle the non computed
// property name case in the parser. Since this is the only case where we
// need to check for an own read only property we special case this so we do
// not need to do this for every property.
if (property->is_static() && property->is_computed_name()) {
__ CallRuntime(Runtime::kThrowIfStaticPrototype);
__ push(eax);
}
VisitForStackValue(value);
if (NeedsHomeObject(value)) {
EmitSetHomeObject(value, 2, property->GetSlot());
}
switch (property->kind()) {
case ClassLiteral::Property::METHOD:
PushOperand(Smi::FromInt(DONT_ENUM));
PushOperand(Smi::FromInt(property->NeedsSetFunctionName()));
CallRuntimeWithOperands(Runtime::kDefineDataPropertyInLiteral);
break;
case ClassLiteral::Property::GETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineGetterPropertyUnchecked);
break;
case ClassLiteral::Property::SETTER:
PushOperand(Smi::FromInt(DONT_ENUM));
CallRuntimeWithOperands(Runtime::kDefineSetterPropertyUnchecked);
break;
case ClassLiteral::Property::FIELD:
UNREACHABLE();
break;
}
}
}
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
PopOperand(edx);
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
......
......@@ -51,31 +51,13 @@ RUNTIME_FUNCTION(Runtime_ThrowArrayNotSubclassableError) {
isolate, NewTypeError(MessageTemplate::kArrayNotSubclassable));
}
static Object* ThrowStaticPrototypeError(Isolate* isolate) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kStaticPrototype));
}
RUNTIME_FUNCTION(Runtime_ThrowStaticPrototypeError) {
HandleScope scope(isolate);
DCHECK(args.length() == 0);
return ThrowStaticPrototypeError(isolate);
}
RUNTIME_FUNCTION(Runtime_ThrowIfStaticPrototype) {
HandleScope scope(isolate);
DCHECK(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(Name, name, 0);
if (Name::Equals(name, isolate->factory()->prototype_string())) {
return ThrowStaticPrototypeError(isolate);
}
return *name;
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewTypeError(MessageTemplate::kStaticPrototype));
}
RUNTIME_FUNCTION(Runtime_HomeObjectSymbol) {
DCHECK(args.length() == 0);
return isolate->heap()->home_object_symbol();
......
......@@ -81,7 +81,6 @@ namespace internal {
F(ThrowConstructorNonCallableError, 1, 1) \
F(ThrowArrayNotSubclassableError, 0, 1) \
F(ThrowStaticPrototypeError, 0, 1) \
F(ThrowIfStaticPrototype, 1, 1) \
F(HomeObjectSymbol, 0, 1) \
F(DefineClass, 4, 1) \
F(LoadFromSuper, 3, 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