зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1591209 - Add JSFunction::baseScript() accessor. r=jandem
Add a baseScript() accessor to use in cases where to accessor properties through a JSFunction that are defined for both lazy and non-lazy scripts. Differential Revision: https://phabricator.services.mozilla.com/D50526 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
cc2ee58041
Коммит
cfd6179906
|
@ -36,9 +36,7 @@ FunctionEmitter::FunctionEmitter(BytecodeEmitter* bce, FunctionBox* funbox,
|
|||
fun_(bce_->cx, funbox_->function()),
|
||||
name_(bce_->cx, fun_->explicitName()),
|
||||
syntaxKind_(syntaxKind),
|
||||
isHoisted_(isHoisted) {
|
||||
MOZ_ASSERT_IF(fun_->isInterpretedLazy(), fun_->lazyScript());
|
||||
}
|
||||
isHoisted_(isHoisted) {}
|
||||
|
||||
bool FunctionEmitter::interpretedCommon() {
|
||||
// Mark as singletons any function which will only be executed once, or
|
||||
|
@ -116,7 +114,7 @@ bool FunctionEmitter::emitLazy() {
|
|||
if (bce_->emittingRunOnceLambda) {
|
||||
// NOTE: The 'funbox' is only partially initialized so we defer checking
|
||||
// the shouldSuppressRunOnce condition until delazification.
|
||||
fun_->lazyScript()->setTreatAsRunOnce();
|
||||
fun_->baseScript()->setTreatAsRunOnce();
|
||||
}
|
||||
|
||||
if (!emitFunction()) {
|
||||
|
|
|
@ -516,7 +516,7 @@ bool ParseContext::declareFunctionThis(const UsedNameTracker& usedNames,
|
|||
|
||||
bool declareThis;
|
||||
if (canSkipLazyClosedOverBindings) {
|
||||
declareThis = funbox->function()->lazyScript()->hasThisBinding();
|
||||
declareThis = funbox->function()->baseScript()->hasThisBinding();
|
||||
} else {
|
||||
declareThis =
|
||||
hasUsedFunctionSpecialName(usedNames, dotThis) ||
|
||||
|
@ -551,7 +551,7 @@ bool ParseContext::declareFunctionArgumentsObject(
|
|||
bool tryDeclareArguments;
|
||||
if (canSkipLazyClosedOverBindings) {
|
||||
tryDeclareArguments =
|
||||
funbox->function()->lazyScript()->shouldDeclareArguments();
|
||||
funbox->function()->baseScript()->shouldDeclareArguments();
|
||||
} else {
|
||||
tryDeclareArguments = hasUsedFunctionSpecialName(usedNames, argumentsName);
|
||||
}
|
||||
|
|
|
@ -2623,14 +2623,14 @@ bool Parser<FullParseHandler, Unit>::skipLazyInnerFunction(
|
|||
return false;
|
||||
}
|
||||
|
||||
LazyScript* lazy = fun->lazyScript();
|
||||
if (lazy->needsHomeObject()) {
|
||||
BaseScript* base = fun->baseScript();
|
||||
if (base->needsHomeObject()) {
|
||||
funbox->setNeedsHomeObject();
|
||||
}
|
||||
|
||||
PropagateTransitiveParseFlags(lazy, pc_->sc());
|
||||
PropagateTransitiveParseFlags(base, pc_->sc());
|
||||
|
||||
if (!tokenStream.advance(fun->lazyScript()->sourceEnd())) {
|
||||
if (!tokenStream.advance(base->sourceEnd())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -7212,11 +7212,15 @@ bool GeneralParser<ParseHandler, Unit>::finishClassConstructor(
|
|||
|
||||
// Set the same information, but on the lazyScript.
|
||||
if (ctorbox->isInterpretedLazy()) {
|
||||
ctorbox->function()->lazyScript()->setToStringEnd(classEndOffset);
|
||||
ctorbox->function()->baseScript()->setToStringEnd(classEndOffset);
|
||||
|
||||
if (numFields > 0) {
|
||||
ctorbox->function()->lazyScript()->setHasThisBinding();
|
||||
ctorbox->function()->baseScript()->setHasThisBinding();
|
||||
}
|
||||
} else {
|
||||
// There should not be any non-lazy script yet.
|
||||
MOZ_ASSERT_IF(ctorbox->hasObject(),
|
||||
ctorbox->function()->hasUncompletedScript());
|
||||
}
|
||||
|
||||
if (numFields == 0) {
|
||||
|
|
|
@ -203,14 +203,15 @@ FunctionBox::FunctionBox(JSContext* cx, TraceListNode* traceListHead,
|
|||
}
|
||||
|
||||
void FunctionBox::initFromLazyFunction(JSFunction* fun) {
|
||||
if (fun->lazyScript()->isDerivedClassConstructor()) {
|
||||
LazyScript* lazy = fun->lazyScript();
|
||||
if (lazy->isDerivedClassConstructor()) {
|
||||
setDerivedClassConstructor();
|
||||
}
|
||||
if (fun->lazyScript()->needsHomeObject()) {
|
||||
if (lazy->needsHomeObject()) {
|
||||
setNeedsHomeObject();
|
||||
}
|
||||
if (fun->lazyScript()->hasEnclosingScope()) {
|
||||
enclosingScope_ = fun->lazyScript()->enclosingScope();
|
||||
if (lazy->hasEnclosingScope()) {
|
||||
enclosingScope_ = lazy->enclosingScope();
|
||||
} else {
|
||||
enclosingScope_ = nullptr;
|
||||
}
|
||||
|
|
|
@ -6744,8 +6744,7 @@ struct LambdaFunctionInfo {
|
|||
: fun_(fun),
|
||||
flags(fun->flags().toRaw()),
|
||||
nargs(fun->nargs()),
|
||||
scriptOrLazyScript(fun->hasScript() ? (gc::Cell*)fun->nonLazyScript()
|
||||
: (gc::Cell*)fun->lazyScript()),
|
||||
scriptOrLazyScript(fun->baseScript()),
|
||||
singletonType(fun->isSingleton()),
|
||||
useSingletonForClone(ObjectGroup::useSingletonForClone(fun)) {
|
||||
// If this assert fails, make sure CodeGenerator::visitLambda does the
|
||||
|
|
|
@ -793,12 +793,9 @@ static JSFunction* MaybeConstructorFromType(TypeSet::Type ty) {
|
|||
static void InterpretedFunctionFilenameAndLineNumber(JSFunction* fun,
|
||||
const char** filename,
|
||||
Maybe<unsigned>* lineno) {
|
||||
if (fun->hasScript()) {
|
||||
*filename = fun->nonLazyScript()->maybeForwardedScriptSource()->filename();
|
||||
*lineno = Some((unsigned)fun->nonLazyScript()->lineno());
|
||||
} else if (fun->hasLazyScript()) {
|
||||
*filename = fun->lazyScript()->maybeForwardedScriptSource()->filename();
|
||||
*lineno = Some((unsigned)fun->lazyScript()->lineno());
|
||||
if (fun->hasBaseScript()) {
|
||||
*filename = fun->baseScript()->maybeForwardedScriptSource()->filename();
|
||||
*lineno = Some((unsigned)fun->baseScript()->lineno());
|
||||
} else {
|
||||
*filename = "(self-hosted builtin)";
|
||||
*lineno = Nothing();
|
||||
|
|
|
@ -32,22 +32,18 @@ inline bool CanReuseFunctionForClone(JSContext* cx, HandleFunction fun) {
|
|||
if (!fun->isSingleton()) {
|
||||
return false;
|
||||
}
|
||||
if (fun->isInterpretedLazy()) {
|
||||
LazyScript* lazy = fun->lazyScript();
|
||||
if (lazy->hasBeenCloned()) {
|
||||
return false;
|
||||
}
|
||||
lazy->setHasBeenCloned();
|
||||
} else {
|
||||
JSScript* script = fun->nonLazyScript();
|
||||
if (script->hasBeenCloned()) {
|
||||
return false;
|
||||
}
|
||||
script->setHasBeenCloned();
|
||||
if (LazyScript* lazy = script->maybeLazyScript()) {
|
||||
|
||||
if (fun->baseScript()->hasBeenCloned()) {
|
||||
return false;
|
||||
}
|
||||
fun->baseScript()->setHasBeenCloned();
|
||||
|
||||
if (fun->hasScript()) {
|
||||
if (LazyScript* lazy = fun->nonLazyScript()->maybeLazyScript()) {
|
||||
lazy->setHasBeenCloned();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -1216,22 +1216,19 @@ const JSClass* const js::FunctionClassPtr = &JSFunction::class_;
|
|||
|
||||
bool JSFunction::isDerivedClassConstructor() {
|
||||
bool derived;
|
||||
if (isInterpretedLazy()) {
|
||||
if (hasSelfHostedLazyScript()) {
|
||||
// There is only one plausible lazy self-hosted derived
|
||||
// constructor.
|
||||
if (isSelfHostedBuiltin()) {
|
||||
JSAtom* name = GetClonedSelfHostedFunctionName(this);
|
||||
JSAtom* name = GetClonedSelfHostedFunctionName(this);
|
||||
|
||||
// This function is called from places without access to a
|
||||
// JSContext. Trace some plumbing to get what we want.
|
||||
derived = name == compartment()
|
||||
->runtimeFromAnyThread()
|
||||
->commonNames->DefaultDerivedClassConstructor;
|
||||
} else {
|
||||
derived = lazyScript()->isDerivedClassConstructor();
|
||||
}
|
||||
} else {
|
||||
derived = nonLazyScript()->isDerivedClassConstructor();
|
||||
// This function is called from places without access to a
|
||||
// JSContext. Trace some plumbing to get what we want.
|
||||
derived = name == compartment()
|
||||
->runtimeFromAnyThread()
|
||||
->commonNames->DefaultDerivedClassConstructor;
|
||||
}
|
||||
if (hasBaseScript()) {
|
||||
derived = baseScript()->isDerivedClassConstructor();
|
||||
}
|
||||
MOZ_ASSERT_IF(derived, isClassConstructor());
|
||||
return derived;
|
||||
|
@ -2164,8 +2161,7 @@ bool js::CanReuseScriptForClone(JS::Realm* realm, HandleFunction fun,
|
|||
|
||||
// We need to clone the script if we're not already marked as having a
|
||||
// non-syntactic scope.
|
||||
return fun->hasScript() ? fun->nonLazyScript()->hasNonSyntacticScope()
|
||||
: fun->lazyScript()->hasNonSyntacticScope();
|
||||
return fun->baseScript()->hasNonSyntacticScope();
|
||||
}
|
||||
|
||||
static inline JSFunction* NewFunctionClone(JSContext* cx, HandleFunction fun,
|
||||
|
|
|
@ -470,6 +470,7 @@ class JSFunction : public js::NativeObject {
|
|||
bool hasSelfHostedLazyScript() const {
|
||||
return flags_.hasSelfHostedLazyScript();
|
||||
}
|
||||
bool hasBaseScript() const { return hasScript() || hasLazyScript(); }
|
||||
|
||||
// Arrow functions store their lexical new.target in the first extended slot.
|
||||
bool isArrow() const { return flags_.isArrow(); }
|
||||
|
@ -514,11 +515,7 @@ class JSFunction : public js::NativeObject {
|
|||
bool needsPrototypeProperty();
|
||||
|
||||
/* Returns the strictness of this function, which must be interpreted. */
|
||||
bool strict() const {
|
||||
MOZ_ASSERT(isInterpreted());
|
||||
return isInterpretedLazy() ? lazyScript()->strict()
|
||||
: nonLazyScript()->strict();
|
||||
}
|
||||
bool strict() const { return baseScript()->strict(); }
|
||||
|
||||
void setFlags(uint16_t flags) { flags_ = FunctionFlags(flags); }
|
||||
void setFlags(FunctionFlags flags) { flags_ = flags; }
|
||||
|
@ -767,17 +764,20 @@ class JSFunction : public js::NativeObject {
|
|||
return u.scripted.s.selfHostedLazy_;
|
||||
}
|
||||
|
||||
js::GeneratorKind generatorKind() const {
|
||||
if (!isInterpreted()) {
|
||||
return js::GeneratorKind::NotGenerator;
|
||||
}
|
||||
// Access fields defined on both lazy and non-lazy scripts. This should
|
||||
// optimize away the branch since the union arms are compatible.
|
||||
js::BaseScript* baseScript() const {
|
||||
if (hasScript()) {
|
||||
return nonLazyScript()->generatorKind();
|
||||
return nonLazyScript();
|
||||
}
|
||||
if (hasLazyScript()) {
|
||||
return lazyScript()->generatorKind();
|
||||
MOZ_ASSERT(hasLazyScript());
|
||||
return lazyScript();
|
||||
}
|
||||
|
||||
js::GeneratorKind generatorKind() const {
|
||||
if (hasBaseScript()) {
|
||||
return baseScript()->generatorKind();
|
||||
}
|
||||
MOZ_ASSERT(isSelfHostedBuiltin());
|
||||
return js::GeneratorKind::NotGenerator;
|
||||
}
|
||||
|
||||
|
@ -786,16 +786,9 @@ class JSFunction : public js::NativeObject {
|
|||
}
|
||||
|
||||
js::FunctionAsyncKind asyncKind() const {
|
||||
if (!isInterpreted()) {
|
||||
return js::FunctionAsyncKind::SyncFunction;
|
||||
if (hasBaseScript()) {
|
||||
return baseScript()->asyncKind();
|
||||
}
|
||||
if (hasScript()) {
|
||||
return nonLazyScript()->asyncKind();
|
||||
}
|
||||
if (hasLazyScript()) {
|
||||
return lazyScript()->asyncKind();
|
||||
}
|
||||
MOZ_ASSERT(isSelfHostedBuiltin());
|
||||
return js::FunctionAsyncKind::SyncFunction;
|
||||
}
|
||||
|
||||
|
|
|
@ -1656,6 +1656,12 @@ class BaseScript : public gc::TenuredCell {
|
|||
uint32_t toStringStart() const { return toStringStart_; }
|
||||
uint32_t toStringEnd() const { return toStringEnd_; }
|
||||
|
||||
void setToStringEnd(uint32_t toStringEnd) {
|
||||
MOZ_ASSERT(toStringStart_ <= toStringEnd);
|
||||
MOZ_ASSERT(toStringEnd_ >= sourceEnd_);
|
||||
toStringEnd_ = toStringEnd;
|
||||
}
|
||||
|
||||
uint32_t lineno() const { return lineno_; }
|
||||
uint32_t column() const { return column_; }
|
||||
|
||||
|
@ -3412,12 +3418,6 @@ class LazyScript : public BaseScript {
|
|||
return lazyData_->fieldInitializers_;
|
||||
}
|
||||
|
||||
void setToStringEnd(uint32_t toStringEnd) {
|
||||
MOZ_ASSERT(toStringStart_ <= toStringEnd);
|
||||
MOZ_ASSERT(toStringEnd_ >= sourceEnd_);
|
||||
toStringEnd_ = toStringEnd;
|
||||
}
|
||||
|
||||
// Returns true if the enclosing script has ever been compiled.
|
||||
// Once the enclosing script is compiled, the scope chain is created.
|
||||
// This LazyScript is delazify-able as long as it has the enclosing scope,
|
||||
|
|
|
@ -173,20 +173,11 @@ bool ObjectGroup::useSingletonForClone(JSFunction* fun) {
|
|||
* instance a singleton type and clone the underlying script.
|
||||
*/
|
||||
|
||||
uint32_t begin, end;
|
||||
if (fun->hasScript()) {
|
||||
if (!fun->nonLazyScript()->isLikelyConstructorWrapper()) {
|
||||
return false;
|
||||
}
|
||||
begin = fun->nonLazyScript()->sourceStart();
|
||||
end = fun->nonLazyScript()->sourceEnd();
|
||||
} else {
|
||||
if (!fun->lazyScript()->isLikelyConstructorWrapper()) {
|
||||
return false;
|
||||
}
|
||||
begin = fun->lazyScript()->sourceStart();
|
||||
end = fun->lazyScript()->sourceEnd();
|
||||
if (!fun->baseScript()->isLikelyConstructorWrapper()) {
|
||||
return false;
|
||||
}
|
||||
uint32_t begin = fun->baseScript()->sourceStart();
|
||||
uint32_t end = fun->baseScript()->sourceEnd();
|
||||
|
||||
return end - begin <= 100;
|
||||
}
|
||||
|
|
|
@ -354,21 +354,12 @@ AutoXDRTree::Key XDRIncrementalEncoder::getTopLevelTreeKey() const {
|
|||
}
|
||||
|
||||
AutoXDRTree::Key XDRIncrementalEncoder::getTreeKey(JSFunction* fun) const {
|
||||
if (fun->isInterpretedLazy()) {
|
||||
static_assert(
|
||||
sizeof(fun->lazyScript()->sourceStart()) == 4 ||
|
||||
sizeof(fun->lazyScript()->sourceEnd()) == 4,
|
||||
"AutoXDRTree key requires LazyScripts positions to be uint32");
|
||||
return uint64_t(fun->lazyScript()->sourceStart()) << 32 |
|
||||
fun->lazyScript()->sourceEnd();
|
||||
}
|
||||
|
||||
if (fun->isInterpreted()) {
|
||||
static_assert(sizeof(fun->nonLazyScript()->sourceStart()) == 4 ||
|
||||
sizeof(fun->nonLazyScript()->sourceEnd()) == 4,
|
||||
"AutoXDRTree key requires JSScripts positions to be uint32");
|
||||
return uint64_t(fun->nonLazyScript()->sourceStart()) << 32 |
|
||||
fun->nonLazyScript()->sourceEnd();
|
||||
if (fun->hasBaseScript()) {
|
||||
static_assert(sizeof(fun->baseScript()->sourceStart()) == 4 &&
|
||||
sizeof(fun->baseScript()->sourceEnd()) == 4,
|
||||
"AutoXDRTree key requires BaseScript positions to be uint32");
|
||||
return uint64_t(fun->baseScript()->sourceStart()) << 32 |
|
||||
fun->baseScript()->sourceEnd();
|
||||
}
|
||||
|
||||
return AutoXDRTree::noKey;
|
||||
|
|
Загрузка…
Ссылка в новой задаче