Commit 34657ab3 authored by Sathya Gunasekaran's avatar Sathya Gunasekaran Committed by Commit Bot

[class] Implement super property access in instance fields

Bug: v8:5367
Change-Id: Ic725c5ef22ab05891764d3ebf9a99c0d383e6d90
Reviewed-on: https://chromium-review.googlesource.com/789939Reviewed-by: 's avatarMythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49660}
parent 61367a25
......@@ -1815,13 +1815,15 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr) {
class_literals_.push_back(std::make_pair(expr, class_boilerplate_entry));
VisitDeclarations(expr->scope()->declarations());
Register class_constructor = register_allocator()->NewRegister();
{
RegisterAllocationScope register_scope(this);
RegisterList args = register_allocator()->NewGrowableRegisterList();
Register class_boilerplate = register_allocator()->GrowRegisterList(&args);
Register class_constructor = register_allocator()->GrowRegisterList(&args);
Register class_constructor_in_args =
register_allocator()->GrowRegisterList(&args);
Register super_class = register_allocator()->GrowRegisterList(&args);
DCHECK_EQ(ClassBoilerplate::kFirstDynamicArgumentIndex,
args.register_count());
......@@ -1832,6 +1834,7 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr) {
VisitFunctionLiteral(expr->constructor());
builder()
->StoreAccumulatorInRegister(class_constructor)
.MoveRegister(class_constructor, class_constructor_in_args)
.LoadConstantPoolEntry(class_boilerplate_entry)
.StoreAccumulatorInRegister(class_boilerplate);
......@@ -1875,13 +1878,14 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr) {
builder()->CallRuntime(Runtime::kDefineClass, args);
}
Register class_constructor = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(class_constructor);
Register prototype = register_allocator()->NewRegister();
builder()->StoreAccumulatorInRegister(prototype);
// Assign to class variable.
if (expr->class_variable() != nullptr) {
DCHECK(expr->class_variable()->IsStackLocal() ||
expr->class_variable()->IsContextSlot());
builder()->LoadAccumulatorWithRegister(class_constructor);
BuildVariableAssignment(expr->class_variable(), Token::INIT,
HoleCheckMode::kElided);
}
......@@ -1890,8 +1894,12 @@ void BytecodeGenerator::BuildClassLiteral(ClassLiteral* expr) {
Register initializer =
VisitForRegisterValue(expr->instance_fields_initializer_function());
// TODO(gsathya): Support super property access in instance field
// initializers.
if (FunctionLiteral::NeedsHomeObject(
expr->instance_fields_initializer_function())) {
FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
builder()->LoadAccumulatorWithRegister(prototype).StoreHomeObjectProperty(
initializer, feedback_index(slot), language_mode());
}
FeedbackSlot slot = feedback_spec()->AddStoreICSlot(language_mode());
builder()
......
......@@ -591,7 +591,7 @@ MaybeHandle<Object> DefineClass(Isolate* isolate,
DCHECK(isolate->has_pending_exception());
return MaybeHandle<Object>();
}
return constructor;
return prototype;
}
} // namespace
......
......@@ -12,22 +12,24 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 6
frame size: 7
parameter count: 1
bytecode array length: 31
bytecode array length: 38
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(4),
B(Star), R(5),
B(CreateClosure), U8(1), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
B(CreateClosure), U8(2), U8(1), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4),
B(Star), R(0),
B(Star), R(1),
B(Star), R(6),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
B(Star), R(3),
B(Mov), R(4), R(0),
B(Mov), R(0), R(1),
B(LdaUndefined),
/* 149 S> */ B(Return),
]
......@@ -46,22 +48,24 @@ snippet: "
speak() { console.log(this.name + ' is speaking.'); }
}
"
frame size: 6
frame size: 7
parameter count: 1
bytecode array length: 31
bytecode array length: 38
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(4),
B(Star), R(5),
B(CreateClosure), U8(1), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(2),
B(LdaConstant), U8(0),
B(Star), R(3),
B(CreateClosure), U8(2), U8(1), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4),
B(Star), R(0),
B(Star), R(1),
B(Star), R(6),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
B(Star), R(3),
B(Mov), R(4), R(0),
B(Mov), R(0), R(1),
B(LdaUndefined),
/* 149 S> */ B(Return),
]
......@@ -82,9 +86,9 @@ snippet: "
static [n1]() { return n1; }
}
"
frame size: 10
frame size: 11
parameter count: 1
bytecode array length: 68
bytecode array length: 75
bytecodes: [
B(CreateFunctionContext), U8(2),
B(PushContext), R(2),
......@@ -94,26 +98,28 @@ bytecodes: [
/* 57 S> */ B(LdaConstant), U8(1),
/* 57 E> */ B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(5),
B(Star), R(6),
B(CreateClosure), U8(3), U8(0), U8(2),
B(Star), R(4),
B(LdaConstant), U8(2),
B(Star), R(3),
B(LdaConstant), U8(2),
B(Star), R(4),
B(LdaImmutableCurrentContextSlot), U8(4),
/* 75 E> */ B(ToName), R(6),
/* 75 E> */ B(ToName), R(7),
B(CreateClosure), U8(4), U8(1), U8(2),
B(Star), R(7),
B(Star), R(8),
B(LdaImmutableCurrentContextSlot), U8(5),
/* 106 E> */ B(ToName), R(8),
/* 106 E> */ B(ToName), R(9),
B(LdaConstant), U8(5),
B(TestEqualStrictNoFeedback), R(8),
B(TestEqualStrictNoFeedback), R(9),
B(Mov), R(3), R(5),
B(JumpIfFalse), U8(7),
B(CallRuntime), U16(Runtime::kThrowStaticPrototypeError), R(0), U8(0),
B(CreateClosure), U8(6), U8(2), U8(2),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(7),
B(Star), R(0),
B(Star), R(1),
B(Star), R(10),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(7),
B(Star), R(4),
B(Mov), R(3), R(0),
B(Mov), R(0), R(1),
B(LdaUndefined),
/* 129 S> */ B(Return),
]
......@@ -135,9 +141,9 @@ snippet: "
class C { constructor() { count++; }}
return new C();
"
frame size: 6
frame size: 7
parameter count: 1
bytecode array length: 36
bytecode array length: 45
bytecodes: [
B(CreateFunctionContext), U8(1),
B(PushContext), R(2),
......@@ -145,15 +151,18 @@ bytecodes: [
/* 46 S> */ B(LdaZero),
/* 46 E> */ B(StaCurrentContextSlot), U8(4),
B(LdaTheHole),
B(Star), R(5),
B(Star), R(6),
B(CreateClosure), U8(1), U8(0), U8(2),
B(Star), R(4),
B(LdaConstant), U8(0),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(0),
B(Star), R(1),
/* 94 S> */ B(Construct), R(1), R(0), U8(0), U8(1),
B(LdaConstant), U8(0),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Mov), R(5), R(0),
B(Mov), R(0), R(1),
/* 87 S> */ B(Ldar), R(1),
/* 94 E> */ B(Construct), R(3), R(0), U8(0), U8(1),
/* 102 S> */ B(Return),
]
constant pool: [
......@@ -168,29 +177,33 @@ snippet: "
(class {})
class E { static name () {}}
"
frame size: 6
frame size: 7
parameter count: 1
bytecode array length: 49
bytecode array length: 61
bytecodes: [
/* 30 E> */ B(StackCheck),
/* 34 S> */ B(LdaTheHole),
B(Star), R(4),
B(Star), R(5),
B(CreateClosure), U8(1), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(3),
B(LdaConstant), U8(0),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(LdaTheHole),
B(Star), R(4),
B(Star), R(5),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(3),
B(LdaConstant), U8(2),
B(Star), R(2),
B(LdaConstant), U8(2),
B(Star), R(3),
B(CreateClosure), U8(4), U8(2), U8(2),
B(Star), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(4),
B(Star), R(0),
B(Star), R(1),
B(Star), R(6),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(4),
B(Star), R(3),
B(Mov), R(4), R(0),
B(Mov), R(0), R(1),
B(LdaUndefined),
/* 74 S> */ B(Return),
]
......
......@@ -35,73 +35,85 @@ snippet: "
new C;
}
"
frame size: 12
frame size: 14
parameter count: 1
bytecode array length: 204
bytecode array length: 240
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(11),
B(Star), R(13),
B(CreateClosure), U8(2), U8(0), U8(2),
B(Star), R(10),
B(LdaConstant), U8(1),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(8),
B(Star), R(11),
B(Mov), R(10), R(12),
B(CallRuntime), U16(Runtime::kDefineClass), R(11), U8(3),
B(Star), R(11),
B(CreateClosure), U8(3), U8(1), U8(2),
B(Star), R(7),
B(LdaConstant), U8(0),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(2),
B(CreateClosure), U8(4), U8(2), U8(2),
B(LdaConstant), U8(0),
B(Star), R(7),
B(Mov), R(6), R(8),
B(Mov), R(12), R(9),
B(CallRuntime), U16(Runtime::kDefineClass), R(7), U8(3),
B(Star), R(7),
B(StaNamedProperty), R(2), U8(5), U8(3),
B(Mov), R(8), R(2),
B(CreateClosure), U8(4), U8(2), U8(2),
B(Star), R(8),
B(StaNamedProperty), R(6), U8(5), U8(3),
B(CreateClosure), U8(6), U8(5), U8(2),
B(Star), R(9),
B(CallProperty0), R(9), R(2), U8(6),
B(Star), R(10),
B(CallProperty0), R(10), R(2), U8(6),
B(Mov), R(2), R(3),
B(LdaTheHole),
B(Star), R(11),
B(Star), R(13),
/* 38 E> */ B(CreateClosure), U8(9), U8(8), U8(2),
B(Star), R(10),
B(LdaConstant), U8(8),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(8),
B(Star), R(11),
B(Mov), R(10), R(12),
B(CallRuntime), U16(Runtime::kDefineClass), R(11), U8(3),
B(Star), R(11),
B(CreateClosure), U8(10), U8(9), U8(2),
B(Star), R(7),
B(LdaConstant), U8(7),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(1),
B(CreateClosure), U8(11), U8(10), U8(2),
B(LdaConstant), U8(7),
B(Star), R(7),
B(Mov), R(6), R(8),
B(Mov), R(12), R(9),
B(CallRuntime), U16(Runtime::kDefineClass), R(7), U8(3),
B(Star), R(7),
B(StaNamedProperty), R(1), U8(5), U8(11),
B(Mov), R(8), R(1),
B(CreateClosure), U8(11), U8(10), U8(2),
B(Star), R(8),
B(StaNamedProperty), R(6), U8(5), U8(11),
B(CreateClosure), U8(12), U8(13), U8(2),
B(Star), R(9),
B(CallProperty0), R(9), R(1), U8(14),
B(Star), R(10),
B(CallProperty0), R(10), R(1), U8(14),
B(Mov), R(1), R(4),
B(LdaTheHole),
B(Star), R(11),
B(Star), R(13),
/* 93 E> */ B(CreateClosure), U8(15), U8(16), U8(2),
B(Star), R(10),
B(LdaConstant), U8(14),
B(Star), R(9),
B(CallRuntime), U16(Runtime::kDefineClass), R(9), U8(3),
B(Star), R(8),
B(Star), R(11),
B(Mov), R(10), R(12),
B(CallRuntime), U16(Runtime::kDefineClass), R(11), U8(3),
B(Star), R(11),
B(CreateClosure), U8(16), U8(17), U8(2),
B(Star), R(7),
B(LdaConstant), U8(13),
B(Star), R(6),
B(CallRuntime), U16(Runtime::kDefineClass), R(6), U8(3),
B(Star), R(0),
B(CreateClosure), U8(17), U8(18), U8(2),
B(LdaConstant), U8(13),
B(Star), R(7),
B(StaNamedProperty), R(0), U8(5), U8(19),
B(Mov), R(6), R(8),
B(Mov), R(12), R(9),
B(CallRuntime), U16(Runtime::kDefineClass), R(7), U8(3),
B(Star), R(7),
B(Mov), R(8), R(0),
B(CreateClosure), U8(17), U8(18), U8(2),
B(Star), R(8),
B(StaNamedProperty), R(6), U8(5), U8(19),
B(CreateClosure), U8(18), U8(21), U8(2),
B(Star), R(9),
B(CallProperty0), R(9), R(0), U8(22),
B(Star), R(10),
B(CallProperty0), R(10), R(0), U8(22),
B(Mov), R(0), R(5),
/* 311 S> */ B(Ldar), R(2),
/* 311 E> */ B(Construct), R(2), R(0), U8(0), U8(24),
......
......@@ -505,9 +505,9 @@ handlers: [
snippet: "
export default (class {});
"
frame size: 6
frame size: 7
parameter count: 2
bytecode array length: 121
bytecode array length: 128
bytecodes: [
B(Ldar), R(1),
B(JumpIfUndefined), U8(18),
......@@ -549,12 +549,15 @@ bytecodes: [
B(Ldar), R(3),
B(StaCurrentContextSlot), U8(5),
B(LdaTheHole),
B(Star), R(5),
B(Star), R(6),
B(CreateClosure), U8(5), U8(0), U8(0),
B(Star), R(4),
B(LdaConstant), U8(4),
B(Star), R(3),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(LdaConstant), U8(4),
B(Star), R(4),
B(Mov), R(3), R(5),
B(CallRuntime), U16(Runtime::kDefineClass), R(4), U8(3),
B(Star), R(4),
B(Ldar), R(5),
B(StaModuleVariable), I8(1), U8(0),
B(LdaCurrentContextSlot), U8(5),
/* 26 S> */ B(Return),
......
......@@ -10,24 +10,26 @@ snippet: "
class A { constructor(...args) { this.args = args; } }
new A(...[1, 2, 3]);
"
frame size: 5
frame size: 6
parameter count: 1
bytecode array length: 38
bytecode array length: 45
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(4),
B(Star), R(5),
B(CreateClosure), U8(1), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(3),
B(Star), R(0),
B(Star), R(1),
B(LdaConstant), U8(0),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(Mov), R(4), R(0),
B(Mov), R(0), R(1),
/* 89 S> */ B(CreateArrayLiteral), U8(2), U8(1), U8(37),
B(Star), R(3),
B(Ldar), R(1),
/* 89 E> */ B(ConstructWithSpread), R(1), R(3), U8(1), U8(2),
/* 89 E> */ B(ConstructWithSpread), R(2), R(3), U8(1), U8(2),
B(LdaUndefined),
/* 110 S> */ B(Return),
]
......@@ -44,26 +46,28 @@ snippet: "
class A { constructor(...args) { this.args = args; } }
new A(0, ...[1, 2, 3]);
"
frame size: 5
frame size: 6
parameter count: 1
bytecode array length: 41
bytecode array length: 48
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(4),
B(Star), R(5),
B(CreateClosure), U8(1), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(3),
B(Star), R(0),
B(Star), R(1),
B(LdaConstant), U8(0),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(Mov), R(4), R(0),
B(Mov), R(0), R(1),
/* 89 S> */ B(LdaZero),
B(Star), R(3),
B(CreateArrayLiteral), U8(2), U8(1), U8(37),
B(Star), R(4),
B(Ldar), R(1),
/* 89 E> */ B(ConstructWithSpread), R(1), R(3), U8(2), U8(2),
/* 89 E> */ B(ConstructWithSpread), R(2), R(3), U8(2), U8(2),
B(LdaUndefined),
/* 113 S> */ B(Return),
]
......@@ -82,18 +86,20 @@ snippet: "
"
frame size: 6
parameter count: 1
bytecode array length: 62
bytecode array length: 66
bytecodes: [
/* 30 E> */ B(StackCheck),
B(LdaTheHole),
B(Star), R(4),
B(Star), R(5),
B(CreateClosure), U8(1), U8(0), U8(2),
B(Star), R(3),
B(LdaConstant), U8(0),
B(Star), R(2),
B(CallRuntime), U16(Runtime::kDefineClass), R(2), U8(3),
B(Star), R(0),
B(Star), R(1),
B(LdaConstant), U8(0),
B(Star), R(3),
B(Mov), R(2), R(4),
B(CallRuntime), U16(Runtime::kDefineClass), R(3), U8(3),
B(Star), R(3),
B(Mov), R(4), R(0),
B(Mov), R(0), R(1),
/* 89 S> */ B(CreateArrayLiteral), U8(2), U8(1), U8(37),
B(Star), R(3),
B(CreateArrayLiteral), U8(3), U8(2), U8(37),
......@@ -104,7 +110,6 @@ bytecodes: [
B(Star), R(5),
B(CallJSRuntime), U8(%spread_arguments), R(3), U8(3),
B(Star), R(3),
B(Mov), R(1), R(2),
B(CallJSRuntime), U8(%reflect_construct), R(2), U8(2),
B(LdaUndefined),
/* 116 S> */ B(Return),
......
......@@ -600,6 +600,30 @@ x();
assertEquals(1, x.c);
}
{
class A {
a() { return 1; }
}
class C extends A {
b = super.a();
c = () => super.a;
d = () => super.a();
e = super.a;
f = super.b;
}
let c = new C;
assertEquals(1, c.a());
assertEquals(1, c.b);
assertEquals(1, c.c()());
assertEquals(1, c.d());
assertEquals(1, c.e());
assertFalse(Object.hasOwnProperty(c, 'a'));
assertEquals(c.a, c.e);
assertEquals(undefined, c.f);
}
{
function t() {
return class {
......
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