[class] Use CreateDataProperty runtime call

StoreDataPropertyInLiteral doesn't throw (because the previous uses of
this didn't throw), but class fields can throw on defining the
property which means we can't use this. Changing to CreateDataProperty
runtime call instead.

Bug: v8:5367
Change-Id: I1ab45413b121972dd18fe2b35a0cedd8efe0e0bf
Reviewed-on: https://chromium-review.googlesource.com/757824
Commit-Queue: Sathya Gunasekaran <gsathya@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Reviewed-by: Mythri Alle <mythria@chromium.org>
Cr-Commit-Position: refs/heads/master@{#49239}
This commit is contained in:
Sathya Gunasekaran 2017-11-08 10:52:09 -08:00 committed by Commit Bot
parent 299b296037
commit 24b26a0cfc
3 changed files with 21 additions and 8 deletions

View File

@ -1941,9 +1941,9 @@ void BytecodeGenerator::VisitClassLiteralProperties(ClassLiteral* expr,
void BytecodeGenerator::VisitInitializeClassFieldsStatement(
InitializeClassFieldsStatement* expr) {
Register constructor(builder()->Receiver());
Register key = register_allocator()->NewRegister();
Register value = register_allocator()->NewRegister();
RegisterList args = register_allocator()->NewRegisterList(3);
Register constructor = args[0], key = args[1], value = args[2];
builder()->MoveRegister(builder()->Receiver(), constructor);
for (int i = 0; i < expr->fields()->length(); i++) {
ClassLiteral::Property* property = expr->fields()->at(i);
@ -1959,14 +1959,10 @@ void BytecodeGenerator::VisitInitializeClassFieldsStatement(
BuildLoadPropertyKey(property, key);
}
DataPropertyInLiteralFlags flags = DataPropertyInLiteralFlag::kNoFlags;
FeedbackSlot slot = feedback_spec()->AddStoreDataPropertyInLiteralICSlot();
VisitForRegisterValue(property->value(), value);
VisitSetHomeObject(value, constructor, property);
builder()->LoadAccumulatorWithRegister(value).StoreDataPropertyInLiteral(
constructor, key, flags, feedback_index(slot));
builder()->CallRuntime(Runtime::kCreateDataProperty, args);
}
}

View File

@ -46,6 +46,14 @@
assertEquals(1, c.hasOwnProperty());
}
{
class C {
x = Object.freeze(this);
c = 42;
}
assertThrows(() => { new C; }, TypeError);
}
{
class C {
c = this;

View File

@ -42,6 +42,15 @@
assertEquals(undefined, c.c);
}
{
assertThrows(() => {
class C {
static x = Object.freeze(this);
static c = 42;
}
}, TypeError);
}
{
class C {
static c = this;