зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 2 changesets (bug 1688327) as per request.
Backed out changeset 991388ec272d (bug 1688327) Backed out changeset 6648750ced7e (bug 1688327)
This commit is contained in:
Родитель
16c72b6507
Коммит
3337733df4
|
@ -5806,9 +5806,13 @@ bool BytecodeEmitter::emitFor(ForNode* forNode,
|
|||
}
|
||||
|
||||
MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction(
|
||||
FunctionNode* funNode, bool needsProto /* = false */) {
|
||||
FunctionNode* funNode, bool needsProto /* = false */,
|
||||
ListNode* classContentsIfConstructor /* = nullptr */) {
|
||||
FunctionBox* funbox = funNode->funbox();
|
||||
|
||||
MOZ_ASSERT((classContentsIfConstructor != nullptr) ==
|
||||
funbox->isClassConstructor());
|
||||
|
||||
// [stack]
|
||||
|
||||
FunctionEmitter fe(this, funbox, funNode->syntaxKind(),
|
||||
|
@ -5829,6 +5833,21 @@ MOZ_NEVER_INLINE bool BytecodeEmitter::emitFunction(
|
|||
}
|
||||
|
||||
if (funbox->isInterpreted()) {
|
||||
// Compute the field initializers data and update the funbox.
|
||||
//
|
||||
// NOTE: For a lazy function, this will be applied to any existing function
|
||||
// in UpdateEmittedInnerFunctions().
|
||||
if (classContentsIfConstructor) {
|
||||
mozilla::Maybe<MemberInitializers> memberInitializers =
|
||||
setupMemberInitializers(classContentsIfConstructor,
|
||||
FieldPlacement::Instance);
|
||||
if (!memberInitializers) {
|
||||
ReportAllocationOverflow(cx);
|
||||
return false;
|
||||
}
|
||||
funbox->setMemberInitializers(*memberInitializers);
|
||||
}
|
||||
|
||||
if (!funbox->emitBytecode) {
|
||||
return fe.emitLazy();
|
||||
// [stack] FUN?
|
||||
|
@ -10364,7 +10383,7 @@ bool BytecodeEmitter::emitClass(
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!emitFunction(ctor, isDerived)) {
|
||||
if (!emitFunction(ctor, isDerived, classMembers)) {
|
||||
// [stack] HOMEOBJ CTOR
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -475,8 +475,9 @@ struct MOZ_STACK_CLASS BytecodeEmitter {
|
|||
JSOp op);
|
||||
MOZ_MUST_USE bool emitRegExp(GCThingIndex index);
|
||||
|
||||
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitFunction(FunctionNode* funNode,
|
||||
bool needsProto = false);
|
||||
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitFunction(
|
||||
FunctionNode* funNode, bool needsProto = false,
|
||||
ListNode* classContentsIfConstructor = nullptr);
|
||||
MOZ_NEVER_INLINE MOZ_MUST_USE bool emitObject(ListNode* objNode);
|
||||
|
||||
MOZ_MUST_USE bool emitHoistedFunctionsInList(ListNode* stmtList);
|
||||
|
|
|
@ -2806,6 +2806,8 @@ bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
|
|||
// lazy functions. Instead that info will be updated when we finish our
|
||||
// compilation.
|
||||
MOZ_ASSERT(fun->baseScript()->hasEnclosingScript());
|
||||
MOZ_ASSERT_IF(fun->isClassConstructor(),
|
||||
!fun->baseScript()->getMemberInitializers().valid);
|
||||
|
||||
PropagateTransitiveParseFlags(funbox, pc_->sc());
|
||||
|
||||
|
@ -7497,9 +7499,11 @@ bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
|
|||
// Fields cannot re-use the constructor obtained via JSOp::ClassConstructor or
|
||||
// JSOp::DerivedConstructor due to needing to emit calls to the field
|
||||
// initializers in the constructor. So, synthesize a new one.
|
||||
size_t numMemberInitializers = classInitializedMembers.privateMethods +
|
||||
classInitializedMembers.instanceFields;
|
||||
if (classStmt.constructorBox == nullptr && numMemberInitializers) {
|
||||
size_t numPrivateMethods = classInitializedMembers.privateMethods;
|
||||
size_t numFields = classInitializedMembers.instanceFields;
|
||||
|
||||
if (classStmt.constructorBox == nullptr &&
|
||||
numFields + numPrivateMethods > 0) {
|
||||
MOZ_ASSERT(!options().selfHostingMode);
|
||||
// Unconditionally create the scope here, because it's always the
|
||||
// constructor.
|
||||
|
@ -7551,11 +7555,7 @@ bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
|
|||
// finished parsing the class.
|
||||
ctorbox->setCtorToStringEnd(classEndOffset);
|
||||
|
||||
// Now that we have full set of initializers, update the constructor.
|
||||
MemberInitializers initializers(numMemberInitializers);
|
||||
ctorbox->setMemberInitializers(initializers);
|
||||
|
||||
if (numMemberInitializers) {
|
||||
if (numFields + numPrivateMethods > 0) {
|
||||
// Field initialization need access to `this`.
|
||||
ctorbox->setCtorFunctionHasThisBinding();
|
||||
}
|
||||
|
|
|
@ -416,8 +416,8 @@ void FunctionBox::copyScriptFields(ScriptStencil& script) {
|
|||
|
||||
SharedContext::copyScriptFields(script);
|
||||
|
||||
if (hasMemberInitializers()) {
|
||||
script.setHasMemberInitializers();
|
||||
if (memberInitializers_) {
|
||||
script.setMemberInitializers(*memberInitializers_);
|
||||
}
|
||||
|
||||
isScriptFieldCopiedToStencil = true;
|
||||
|
@ -443,10 +443,6 @@ void FunctionBox::copyFunctionFields(ScriptStencil& script) {
|
|||
}
|
||||
|
||||
void FunctionBox::copyFunctionExtraFields(ScriptStencilExtra& scriptExtra) {
|
||||
if (hasMemberInitializers()) {
|
||||
scriptExtra.setMemberInitializers(memberInitializers());
|
||||
}
|
||||
|
||||
scriptExtra.nargs = nargs_;
|
||||
}
|
||||
|
||||
|
@ -463,16 +459,9 @@ void FunctionBox::copyUpdatedExtent() {
|
|||
}
|
||||
|
||||
void FunctionBox::copyUpdatedMemberInitializers() {
|
||||
if (hasMemberInitializers()) {
|
||||
ScriptStencil& script = functionStencil();
|
||||
script.setHasMemberInitializers();
|
||||
if (hasFunctionExtraStencil()) {
|
||||
ScriptStencilExtra& scriptExtra = functionExtraStencil();
|
||||
scriptExtra.setMemberInitializers(memberInitializers());
|
||||
} else {
|
||||
// We are delazifying and the original PrivateScriptData has the member
|
||||
// initializer information already. See: JSScript::fullyInitFromStencil.
|
||||
}
|
||||
ScriptStencil& script = functionStencil();
|
||||
if (memberInitializers_) {
|
||||
script.setMemberInitializers(*memberInitializers_);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -158,10 +158,6 @@ static bool CreateLazyScript(JSContext* cx, CompilationInput& input,
|
|||
}
|
||||
}
|
||||
|
||||
if (script.hasMemberInitializers()) {
|
||||
lazy->setMemberInitializers(scriptExtra.memberInitializers());
|
||||
}
|
||||
|
||||
function->initScript(lazy);
|
||||
|
||||
return true;
|
||||
|
@ -568,6 +564,10 @@ static void UpdateEmittedInnerFunctions(JSContext* cx, CompilationInput& input,
|
|||
Scope* scope = gcOutput.scopes[index];
|
||||
script->setEnclosingScope(scope);
|
||||
|
||||
if (scriptStencil.hasMemberInitializers()) {
|
||||
script->setMemberInitializers(scriptStencil.memberInitializers());
|
||||
}
|
||||
|
||||
// Inferred and Guessed names are computed by BytecodeEmitter and so may
|
||||
// need to be applied to existing JSFunctions during delazification.
|
||||
if (fun->displayAtom() == nullptr) {
|
||||
|
@ -1828,6 +1828,10 @@ void ScriptStencil::dump(js::JSONPrinter& json,
|
|||
|
||||
void ScriptStencil::dumpFields(js::JSONPrinter& json,
|
||||
BaseCompilationStencil* stencil) {
|
||||
if (hasMemberInitializers()) {
|
||||
json.property("memberInitializers", memberInitializers_);
|
||||
}
|
||||
|
||||
json.formatProperty("gcThingsOffset", "CompilationGCThingIndex(%u)",
|
||||
gcThingsOffset.index);
|
||||
json.property("gcThingsLength", gcThingsLength);
|
||||
|
@ -1900,8 +1904,6 @@ void ScriptStencilExtra::dumpFields(js::JSONPrinter& json) {
|
|||
json.property("column", extent.column);
|
||||
json.endObject();
|
||||
|
||||
json.property("memberInitializers", memberInitializers_);
|
||||
|
||||
json.property("nargs", nargs);
|
||||
}
|
||||
|
||||
|
|
|
@ -719,6 +719,8 @@ class ScriptStencil {
|
|||
// * non-lazy Function (except asm.js module)
|
||||
// * lazy Function (cannot be asm.js module)
|
||||
|
||||
uint32_t memberInitializers_ = 0;
|
||||
|
||||
// GCThings are stored into
|
||||
// {CompilationState,BaseCompilationStencil}.gcThingData, in [gcThingsOffset,
|
||||
// gcThingsOffset + gcThingsLength) range.
|
||||
|
@ -762,13 +764,7 @@ class ScriptStencil {
|
|||
static constexpr uint16_t HasSharedDataFlag = 1 << 2;
|
||||
|
||||
// Set if this script has member initializer.
|
||||
// - Member initializer data is computed during initial parse for all
|
||||
// scripts.
|
||||
// - ScriptStencilExtra::memberInitializers_ is only valid when this flag is
|
||||
// also set.
|
||||
// - During delazification this flag must still be set to same values as the
|
||||
// initial parse. In that case, the member initializer data is read from
|
||||
// the existing BaseScript and preserved in delazification.
|
||||
// `memberInitializers_` is valid only if this flag is set.
|
||||
static constexpr uint16_t HasMemberInitializersFlag = 1 << 3;
|
||||
|
||||
// True if this script is lazy function and has enclosing scope.
|
||||
|
@ -809,8 +805,20 @@ class ScriptStencil {
|
|||
return flags_ & HasMemberInitializersFlag;
|
||||
}
|
||||
|
||||
private:
|
||||
void setHasMemberInitializers() { flags_ |= HasMemberInitializersFlag; }
|
||||
|
||||
public:
|
||||
void setMemberInitializers(MemberInitializers member) {
|
||||
memberInitializers_ = member.serialize();
|
||||
setHasMemberInitializers();
|
||||
}
|
||||
|
||||
MemberInitializers memberInitializers() const {
|
||||
MOZ_ASSERT(hasMemberInitializers());
|
||||
return MemberInitializers(memberInitializers_);
|
||||
}
|
||||
|
||||
bool hasLazyFunctionEnclosingScopeIndex() const {
|
||||
return flags_ & HasLazyFunctionEnclosingScopeIndexFlag;
|
||||
}
|
||||
|
@ -847,10 +855,6 @@ class ScriptStencilExtra {
|
|||
// The location of this script in the source.
|
||||
SourceExtent extent;
|
||||
|
||||
// See `PrivateScriptData::memberInitializers_`.
|
||||
// This data only valid when `ScriptStencil::hasMemberInitializers` is true.
|
||||
uint32_t memberInitializers_ = 0;
|
||||
|
||||
// See `JSFunction::nargs_`.
|
||||
uint16_t nargs = 0;
|
||||
|
||||
|
@ -863,14 +867,6 @@ class ScriptStencilExtra {
|
|||
return immutableFlags.hasFlag(ImmutableScriptFlagsEnum::IsModule);
|
||||
}
|
||||
|
||||
void setMemberInitializers(MemberInitializers member) {
|
||||
memberInitializers_ = member.serialize();
|
||||
}
|
||||
|
||||
MemberInitializers memberInitializers() const {
|
||||
return MemberInitializers(memberInitializers_);
|
||||
}
|
||||
|
||||
#if defined(DEBUG) || defined(JS_JITSPEW)
|
||||
void dump();
|
||||
void dump(JSONPrinter& json);
|
||||
|
|
|
@ -3751,6 +3751,10 @@ bool PrivateScriptData::InitFromStencil(
|
|||
}
|
||||
}
|
||||
|
||||
if (scriptStencil.hasMemberInitializers()) {
|
||||
script->setMemberInitializers(scriptStencil.memberInitializers());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -3891,20 +3895,6 @@ bool JSScript::fullyInitFromStencil(
|
|||
return false;
|
||||
}
|
||||
|
||||
// Member-initializer data is computed in initial parse only. If we are
|
||||
// delazifying, make sure to copy it off the `lazyData` before we throw it
|
||||
// away.
|
||||
if (scriptStencil.hasMemberInitializers()) {
|
||||
if (stencil.isInitialStencil()) {
|
||||
MemberInitializers initializers(stencil.asCompilationStencil()
|
||||
.scriptExtra[scriptIndex]
|
||||
.memberInitializers());
|
||||
script->setMemberInitializers(initializers);
|
||||
} else {
|
||||
script->setMemberInitializers(lazyData.get()->getMemberInitializers());
|
||||
}
|
||||
}
|
||||
|
||||
script->initSharedData(stencil.sharedData.get(scriptIndex));
|
||||
|
||||
// NOTE: JSScript is now constructed and should be linked in.
|
||||
|
|
Загрузка…
Ссылка в новой задаче