import from UXP: Issue #2142 - Support SuperProperty in field initializers (b187006a)

This commit is contained in:
2023-05-01 14:14:25 +08:00
parent cb4c73a778
commit ebad409f28
5 changed files with 72 additions and 16 deletions
+7
View File
@@ -8039,6 +8039,13 @@ BytecodeEmitter::emitCreateFieldInitializers(ClassEmitter& ce, ListNode* obj)
// [stack] HOMEOBJ HERITAGE? ARRAY LAMBDA
return false;
}
if (initializer->funbox()->needsHomeObject()) {
MOZ_ASSERT(initializer->funbox()->function()->allowSuperProperty());
if (!ce.emitFieldInitializerHomeObject()) {
// [stack] CTOR OBJ ARRAY LAMBDA
return false;
}
}
if (!ce.emitStoreFieldInitializer()) {
// [stack] HOMEOBJ HERITAGE? ARRAY
return false;
+22 -2
View File
@@ -510,9 +510,25 @@ bool ClassEmitter::prepareForFieldInitializers(size_t numFields)
return true;
}
bool ClassEmitter::emitStoreFieldInitializer()
bool ClassEmitter::emitFieldInitializerHomeObject()
{
MOZ_ASSERT(classState_ == ClassState::FieldInitializers);
// [stack] OBJ HERITAGE? ARRAY METHOD
if (!bce_->emit2(JSOP_INITHOMEOBJECT, isDerived_ ? 2 : 1)) {
// [stack] OBJ HERITAGE? ARRAY METHOD
return false;
}
#ifdef DEBUG
classState_ = ClassState::FieldInitializerWithHomeObject;
#endif
return true;
}
bool ClassEmitter::emitStoreFieldInitializer()
{
MOZ_ASSERT(classState_ == ClassState::FieldInitializers ||
classState_ == ClassState::FieldInitializerWithHomeObject);
MOZ_ASSERT(fieldIndex_ < numFields_);
// [stack] HOMEOBJ HERITAGE? ARRAY METHOD
@@ -522,6 +538,9 @@ bool ClassEmitter::emitStoreFieldInitializer()
}
fieldIndex_++;
#ifdef DEBUG
classState_ = ClassState::FieldInitializers;
#endif
return true;
}
@@ -529,7 +548,8 @@ bool ClassEmitter::emitFieldInitializersEnd()
{
MOZ_ASSERT(propertyState_ == PropertyState::Start ||
propertyState_ == PropertyState::Init);
MOZ_ASSERT(classState_ == ClassState::FieldInitializers);
MOZ_ASSERT(classState_ == ClassState::FieldInitializers ||
classState_ == ClassState::FieldInitializerWithHomeObject);
MOZ_ASSERT(fieldIndex_ == numFields_);
if (!initializersAssignment_->emitAssignment()) {
+36 -10
View File
@@ -536,7 +536,7 @@ class MOZ_RAII AutoSaveLocalStrictMode
//
// ce.prepareForFieldInitializers(fields.length());
// for (auto field : fields) {
// emit(field.expr_method());
// emit(field.initializer_method());
// ce.emitStoreFieldInitializer();
// }
// ce.emitFieldInitializersEnd();
@@ -545,6 +545,18 @@ class MOZ_RAII AutoSaveLocalStrictMode
// ce.emitInitConstructor(/* needsHomeObject = */ false);
// ce.emitEnd(ClassEmitter::Kind::Expression);
//
// `class X { field0 = super.method(); ... }`
// // after emitClass/emitDerivedClass
// ce.prepareForFieldInitializers(1);
// for (auto field : fields) {
// emit(field.initializer_method());
// if (field.initializer_contains_super_or_eval()) {
// ce.emitFieldInitializerHomeObject();
// }
// ce.emitStoreFieldInitializer();
// }
// ce.emitFieldInitializersEnd();
//
// `m() {}` in class
// // after emitInitConstructor/emitInitDefaultConstructor
// ce.prepareForPropValue(Some(offset_of_m));
@@ -673,14 +685,24 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter
// |
// +-------------------------------+
// |
// | prepareForFieldInitializers +-------------------+
// +----------------------------->| FieldInitializers |-+
// | +-------------------+ |
// | |
// | +-------------------------------------------------+
// | |
// | | (expr emitStoreFieldInitializer)*
// | |
// | prepareForFieldInitializers
// +-----------------------------+
// | |
// | | +-------------------+
// | +--------------------->+--->| FieldInitializers |-+
// | | +-------------------+ |
// | | |
// | | (emit initializer method) |
// | | +<--------------------------------------------+
// | | |
// | | | emitFieldInitializerHomeObject +--------------------------------+
// | | +-------------------------------->| FieldInitializerWithHomeObject |-+
// | | | +--------------------------------+ |
// | | | |
// | | +------------------------------------------------------------------->+
// | | |
// | | emitStoreFieldInitializer |
// | +<--+<-----------------------------------------------------------------------+
// | |
// | | emitFieldInitializersEnd +----------------------+
// | +-------------------------->| FieldInitializersEnd |-+
@@ -714,9 +736,12 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter
InitConstructor,
// After calling prepareForFieldInitializers
// and 0 or more calls to emitFieldInitializersEnd.
// and 0 or more calls to emitStoreFieldInitializer.
FieldInitializers,
// After calling emitFieldInitializerHomeObject
FieldInitializerWithHomeObject,
// After calling emitFieldInitializersEnd.
FieldInitializersEnd,
@@ -759,6 +784,7 @@ class MOZ_STACK_CLASS ClassEmitter : public PropertyEmitter
const mozilla::Maybe<uint32_t>& classEnd);
MOZ_MUST_USE bool prepareForFieldInitializers(size_t numFields);
MOZ_MUST_USE bool emitFieldInitializerHomeObject();
MOZ_MUST_USE bool emitStoreFieldInitializer();
MOZ_MUST_USE bool emitFieldInitializersEnd();
+1 -1
View File
@@ -626,7 +626,7 @@ enum class FunctionSyntaxKind
Expression, // A non-arrow function expression.
Statement, // A named function appearing as a Statement.
Arrow,
Method,
Method, // Method of a class or object. Field initializers also desugar to methods.
ClassConstructor,
DerivedClassConstructor,
Getter,
+6 -3
View File
@@ -223,7 +223,6 @@ SharedContext::computeAllowSyntax(Scope* scope)
allowSuperProperty_ = fun->allowSuperProperty();
allowSuperCall_ = fun->isDerivedClassConstructor();
if (funScope->isFieldInitializer()) {
allowSuperProperty_ = false;
allowSuperCall_ = false;
allowArguments_ = false;
}
@@ -7981,14 +7980,14 @@ Parser<ParseHandler>::fieldInitializerOpt(HandleAtom propAtom, size_t& numFieldK
// Create the anonymous function object.
RootedFunction fun(context,
newFunction(nullptr, FunctionSyntaxKind::Expression,
newFunction(nullptr, FunctionSyntaxKind::Method,
GeneratorKind::NotGenerator,
FunctionAsyncKind::SyncFunction));
if (!fun)
return null();
// Create the top-level field initializer node.
FunctionNodeType funNode = handler.newFunction(FunctionSyntaxKind::Expression, firstTokenPos);
FunctionNodeType funNode = handler.newFunction(FunctionSyntaxKind::Method, firstTokenPos);
if (!funNode)
return null();
@@ -8123,6 +8122,10 @@ Parser<ParseHandler>::fieldInitializerOpt(HandleAtom propAtom, size_t& numFieldK
handler.setFunctionBody(funNode, initializerBody);
if (pc->superScopeNeedsHomeObject()) {
funbox->setNeedsHomeObject();
}
if (!finishFunction(false, true))
return null();