mirror of
https://github.com/roytam1/basilisk55.git
synced 2026-05-26 15:02:46 +00:00
import from UXP: Issue #2142 - Support SuperProperty in field initializers (b187006a)
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user