зеркало из https://github.com/mozilla/gecko-dev.git
backout Bug 1221144 for perf regression
MozReview-Commit-ID: Aete3iN6i3r
This commit is contained in:
Родитель
1674c865bc
Коммит
bf2ce4db2f
|
@ -287,7 +287,7 @@ EvalKernel(JSContext* cx, const CallArgs& args, EvalType evalType, AbstractFrame
|
|||
if (maybeScript && maybeScript->scriptSource()->introducerFilename())
|
||||
introducerFilename = maybeScript->scriptSource()->introducerFilename();
|
||||
|
||||
Rooted<StaticScope*> enclosing(cx);
|
||||
RootedObject enclosing(cx);
|
||||
if (evalType == DIRECT_EVAL)
|
||||
enclosing = callerScript->innermostStaticScope(pc);
|
||||
else
|
||||
|
@ -373,7 +373,7 @@ js::DirectEvalStringFromIon(JSContext* cx,
|
|||
if (maybeScript && maybeScript->scriptSource()->introducerFilename())
|
||||
introducerFilename = maybeScript->scriptSource()->introducerFilename();
|
||||
|
||||
Rooted<StaticScope*> enclosing(cx, callerScript->innermostStaticScope(pc));
|
||||
RootedObject enclosing(cx, callerScript->innermostStaticScope(pc));
|
||||
Rooted<StaticEvalScope*> staticScope(cx, StaticEvalScope::create(cx, enclosing));
|
||||
if (!staticScope)
|
||||
return false;
|
||||
|
@ -475,8 +475,7 @@ js::ExecuteInGlobalAndReturnScope(JSContext* cx, HandleObject global, HandleScri
|
|||
|
||||
// Unlike the non-syntactic scope chain API used by the subscript loader,
|
||||
// this API creates a fresh block scope each time.
|
||||
Rooted<StaticNonSyntacticScope*> enclosingStaticScope(cx,
|
||||
&script->enclosingStaticScope()->as<StaticNonSyntacticScope>());
|
||||
RootedObject enclosingStaticScope(cx, script->enclosingStaticScope());
|
||||
scope = ClonedBlockObject::createNonSyntactic(cx, enclosingStaticScope, scope);
|
||||
if (!scope)
|
||||
return false;
|
||||
|
|
|
@ -566,7 +566,7 @@ ModuleObject::isInstance(HandleValue value)
|
|||
}
|
||||
|
||||
/* static */ ModuleObject*
|
||||
ModuleObject::create(ExclusiveContext* cx, Handle<StaticScope*> enclosingStaticScope)
|
||||
ModuleObject::create(ExclusiveContext* cx, HandleObject enclosingStaticScope)
|
||||
{
|
||||
RootedObject proto(cx, cx->global()->getModulePrototype());
|
||||
RootedObject obj(cx, NewObjectWithGivenProto(cx, &class_, proto));
|
||||
|
@ -574,11 +574,7 @@ ModuleObject::create(ExclusiveContext* cx, Handle<StaticScope*> enclosingStaticS
|
|||
return nullptr;
|
||||
|
||||
RootedModuleObject self(cx, &obj->as<ModuleObject>());
|
||||
Rooted<StaticModuleScope*> scope(cx, StaticModuleScope::create(cx, self,
|
||||
enclosingStaticScope));
|
||||
if (!scope)
|
||||
return nullptr;
|
||||
self->initReservedSlot(StaticScopeSlot, ObjectOrNullValue(scope));
|
||||
self->initReservedSlot(StaticScopeSlot, ObjectOrNullValue(enclosingStaticScope));
|
||||
|
||||
Zone* zone = cx->zone();
|
||||
IndirectBindingMap* bindings = zone->new_<IndirectBindingMap>(zone);
|
||||
|
@ -727,10 +723,10 @@ ModuleObject::initialEnvironment() const
|
|||
return getReservedSlot(InitialEnvironmentSlot).toObject().as<ModuleEnvironmentObject>();
|
||||
}
|
||||
|
||||
StaticModuleScope*
|
||||
ModuleObject::staticScope() const
|
||||
JSObject*
|
||||
ModuleObject::enclosingStaticScope() const
|
||||
{
|
||||
return &getReservedSlot(StaticScopeSlot).toObject().as<StaticModuleScope>();
|
||||
return getReservedSlot(StaticScopeSlot).toObjectOrNull();
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
|
|
@ -21,8 +21,6 @@ namespace js {
|
|||
|
||||
class ModuleEnvironmentObject;
|
||||
class ModuleObject;
|
||||
class StaticScope;
|
||||
class StaticModuleScope;
|
||||
|
||||
namespace frontend {
|
||||
class ParseNode;
|
||||
|
@ -226,7 +224,7 @@ class ModuleObject : public NativeObject
|
|||
|
||||
static bool isInstance(HandleValue value);
|
||||
|
||||
static ModuleObject* create(ExclusiveContext* cx, Handle<StaticScope*> enclosingStaticScope);
|
||||
static ModuleObject* create(ExclusiveContext* cx, HandleObject enclosingStaticScope);
|
||||
void init(HandleScript script);
|
||||
void setInitialEnvironment(Handle<ModuleEnvironmentObject*> initialEnvironment);
|
||||
void initImportExportData(HandleArrayObject requestedModules,
|
||||
|
@ -236,7 +234,7 @@ class ModuleObject : public NativeObject
|
|||
HandleArrayObject starExportEntries);
|
||||
|
||||
JSScript* script() const;
|
||||
StaticModuleScope* staticScope() const;
|
||||
JSObject* enclosingStaticScope() const;
|
||||
ModuleEnvironmentObject& initialEnvironment() const;
|
||||
ModuleEnvironmentObject* environment() const;
|
||||
ModuleNamespaceObject* namespace_();
|
||||
|
|
|
@ -72,7 +72,7 @@ class MOZ_STACK_CLASS BytecodeCompiler
|
|||
bool canLazilyParse();
|
||||
bool createParser();
|
||||
bool createSourceAndParser();
|
||||
bool createScript(Handle<StaticScope*> staticScope, bool savedCallerFun = false);
|
||||
bool createScript(HandleObject staticScope, bool savedCallerFun = false);
|
||||
bool createEmitter(SharedContext* sharedContext, HandleScript evalCaller = nullptr,
|
||||
bool insideNonGlobalEval = false);
|
||||
bool isEvalCompilationUnit();
|
||||
|
@ -255,7 +255,7 @@ BytecodeCompiler::createSourceAndParser()
|
|||
}
|
||||
|
||||
bool
|
||||
BytecodeCompiler::createScript(Handle<StaticScope*> staticScope, bool savedCallerFun)
|
||||
BytecodeCompiler::createScript(HandleObject staticScope, bool savedCallerFun)
|
||||
{
|
||||
script = JSScript::Create(cx, staticScope, savedCallerFun, options,
|
||||
sourceObject, /* sourceStart = */ 0, sourceBuffer.length());
|
||||
|
@ -284,8 +284,11 @@ BytecodeCompiler::isEvalCompilationUnit()
|
|||
bool
|
||||
BytecodeCompiler::isNonGlobalEvalCompilationUnit()
|
||||
{
|
||||
return isEvalCompilationUnit() &&
|
||||
!IsStaticGlobalLexicalScope(enclosingStaticScope->enclosingScope());
|
||||
if (!isEvalCompilationUnit())
|
||||
return false;
|
||||
StaticEvalScope& eval = enclosingStaticScope->as<StaticEvalScope>();
|
||||
JSObject* enclosing = eval.enclosingScopeForStaticScopeIter();
|
||||
return !IsStaticGlobalLexicalScope(enclosing);
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -559,8 +562,7 @@ BytecodeCompiler::compileScript(HandleObject scopeChain, HandleScript evalCaller
|
|||
return script;
|
||||
}
|
||||
|
||||
ModuleObject*
|
||||
BytecodeCompiler::compileModule()
|
||||
ModuleObject* BytecodeCompiler::compileModule()
|
||||
{
|
||||
if (!createSourceAndParser())
|
||||
return nullptr;
|
||||
|
@ -569,8 +571,7 @@ BytecodeCompiler::compileModule()
|
|||
if (!module)
|
||||
return nullptr;
|
||||
|
||||
Rooted<StaticModuleScope*> moduleScope(cx, module->staticScope());
|
||||
if (!createScript(moduleScope))
|
||||
if (!createScript(module))
|
||||
return nullptr;
|
||||
|
||||
module->init(script);
|
||||
|
@ -650,8 +651,7 @@ BytecodeCompiler::compileFunctionBody(MutableHandleFunction fun,
|
|||
if (fn->pn_funbox->function()->isInterpreted()) {
|
||||
MOZ_ASSERT(fun == fn->pn_funbox->function());
|
||||
|
||||
Rooted<StaticScope*> scope(cx, fn->pn_funbox->staticScope());
|
||||
if (!createScript(scope))
|
||||
if (!createScript(enclosingStaticScope))
|
||||
return false;
|
||||
|
||||
script->bindings = fn->pn_funbox->bindings;
|
||||
|
@ -803,12 +803,11 @@ frontend::CompileLazyFunction(JSContext* cx, Handle<LazyScript*> lazy, const cha
|
|||
if (!NameFunctions(cx, pn))
|
||||
return false;
|
||||
|
||||
Rooted<StaticScope*> staticScope(cx, pn->pn_funbox->staticScope());
|
||||
MOZ_ASSERT(staticScope);
|
||||
RootedObject enclosingScope(cx, lazy->enclosingScope());
|
||||
RootedScriptSource sourceObject(cx, lazy->sourceObject());
|
||||
MOZ_ASSERT(sourceObject);
|
||||
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx, staticScope, false, options,
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
|
||||
sourceObject, lazy->begin(), lazy->end()));
|
||||
if (!script)
|
||||
return false;
|
||||
|
|
|
@ -733,7 +733,7 @@ BytecodeEmitter::pushLoopStatement(LoopStmtInfo* stmt, StmtType type, ptrdiff_t
|
|||
}
|
||||
}
|
||||
|
||||
StaticScope*
|
||||
JSObject*
|
||||
BytecodeEmitter::innermostStaticScope() const
|
||||
{
|
||||
if (StmtInfoBCE* stmt = innermostScopeStmt())
|
||||
|
@ -1362,7 +1362,9 @@ BytecodeEmitter::atBodyLevel(StmtInfoBCE* stmt) const
|
|||
if (sc->staticScope()->is<StaticEvalScope>()) {
|
||||
bool bl = !stmt->enclosing;
|
||||
MOZ_ASSERT_IF(bl, stmt->type == StmtType::BLOCK);
|
||||
MOZ_ASSERT_IF(bl, stmt->staticScope->enclosingScope() == sc->staticScope());
|
||||
MOZ_ASSERT_IF(bl, stmt->staticScope
|
||||
->as<StaticBlockScope>()
|
||||
.enclosingStaticScope() == sc->staticScope());
|
||||
return bl;
|
||||
}
|
||||
return !stmt;
|
||||
|
@ -1465,8 +1467,8 @@ BytecodeEmitter::computeDefinitionIsAliased(BytecodeEmitter* bceOfDef, Definitio
|
|||
// object. Aliased block bindings do not need adjusting; see
|
||||
// computeAliasedSlots.
|
||||
uint32_t slot = dn->pn_scopecoord.slot();
|
||||
if (blockScopeOfDef(dn)->is<StaticFunctionScope>() ||
|
||||
blockScopeOfDef(dn)->is<StaticModuleScope>())
|
||||
if (blockScopeOfDef(dn)->is<JSFunction>() ||
|
||||
blockScopeOfDef(dn)->is<ModuleObject>())
|
||||
{
|
||||
MOZ_ASSERT(IsArgOp(*op) || slot < bceOfDef->script->bindings.numBodyLevelLocals());
|
||||
MOZ_ALWAYS_TRUE(bceOfDef->lookupAliasedName(bceOfDef->script, dn->name(), &slot));
|
||||
|
@ -1567,11 +1569,8 @@ BytecodeEmitter::tryConvertFreeName(ParseNode* pn)
|
|||
// Look up for name in function and block scopes.
|
||||
if (ssi.type() == StaticScopeIter<NoGC>::Function) {
|
||||
RootedScript funScript(cx, ssi.funScript());
|
||||
if (funScript->funHasExtensibleScope() ||
|
||||
ssi.fun().function().atom() == pn->pn_atom)
|
||||
{
|
||||
if (funScript->funHasExtensibleScope() || ssi.fun().atom() == pn->pn_atom)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip the current function, since we're trying to convert a
|
||||
// free name.
|
||||
|
@ -1583,7 +1582,7 @@ BytecodeEmitter::tryConvertFreeName(ParseNode* pn)
|
|||
}
|
||||
}
|
||||
} else if (ssi.type() == StaticScopeIter<NoGC>::Module) {
|
||||
RootedScript moduleScript(cx, ssi.module().script());
|
||||
RootedScript moduleScript(cx, ssi.moduleScript());
|
||||
uint32_t slot_;
|
||||
if (lookupAliasedName(moduleScript, name, &slot_, pn)) {
|
||||
slot = Some(slot_);
|
||||
|
@ -1591,8 +1590,7 @@ BytecodeEmitter::tryConvertFreeName(ParseNode* pn)
|
|||
}
|
||||
|
||||
// Convert module import accesses to use JSOP_GETIMPORT.
|
||||
RootedModuleEnvironmentObject env(cx, &ssi.module().moduleObject()
|
||||
.initialEnvironment());
|
||||
RootedModuleEnvironmentObject env(cx, &ssi.module().initialEnvironment());
|
||||
RootedPropertyName propName(cx, name);
|
||||
MOZ_ASSERT(env);
|
||||
if (env->hasImportBinding(propName)) {
|
||||
|
@ -1835,11 +1833,12 @@ BytecodeEmitter::bindNameToSlotHelper(ParseNode* pn)
|
|||
* Currently, the ALIASEDVAR ops do not support accessing the
|
||||
* callee of a DeclEnvObject, so use NAME.
|
||||
*/
|
||||
if (blockScopeOfDef(dn) != sc->asFunctionBox()->staticScope())
|
||||
JSFunction* fun = sc->asFunctionBox()->function();
|
||||
if (blockScopeOfDef(dn) != fun)
|
||||
return true;
|
||||
|
||||
MOZ_ASSERT(sc->asFunctionBox()->function()->isLambda());
|
||||
MOZ_ASSERT(pn->pn_atom == sc->asFunctionBox()->function()->atom());
|
||||
MOZ_ASSERT(fun->isLambda());
|
||||
MOZ_ASSERT(pn->pn_atom == fun->atom());
|
||||
|
||||
/*
|
||||
* Leave pn->isOp(JSOP_GETNAME) if this->fun needs a CallObject to
|
||||
|
@ -3539,9 +3538,9 @@ BytecodeEmitter::emitSetThis(ParseNode* pn)
|
|||
}
|
||||
|
||||
static bool
|
||||
IsModuleOnScopeChain(StaticScope* scope)
|
||||
IsModuleOnScopeChain(JSObject* obj)
|
||||
{
|
||||
for (StaticScopeIter<NoGC> ssi(scope); !ssi.done(); ssi++) {
|
||||
for (StaticScopeIter<NoGC> ssi(obj); !ssi.done(); ssi++) {
|
||||
if (ssi.type() == StaticScopeIter<NoGC>::Module)
|
||||
return true;
|
||||
}
|
||||
|
@ -6391,21 +6390,14 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
SharedContext* outersc = sc;
|
||||
if (fun->isInterpretedLazy()) {
|
||||
if (!fun->lazyScript()->sourceObject()) {
|
||||
// Two cases that can arise during parsing can cause the static
|
||||
// scope chain to be incorrectly linked up: (1) the
|
||||
// transformation of blocks from non-scopeful to scopeful when
|
||||
// the first block-scoped declaration is found; (2) legacy
|
||||
// comprehension expression transplantation. The
|
||||
// setEnclosingScope call below fixes these cases.
|
||||
Rooted<StaticScope*> enclosingScope(cx, innermostStaticScope());
|
||||
fun->lazyScript()->staticScope()->setEnclosingScope(enclosingScope);
|
||||
|
||||
JSObject* scope = innermostStaticScope();
|
||||
JSObject* source = script->sourceObject();
|
||||
fun->lazyScript()->initSource(&source->as<ScriptSourceObject>());
|
||||
fun->lazyScript()->setParent(scope, &source->as<ScriptSourceObject>());
|
||||
}
|
||||
if (emittingRunOnceLambda)
|
||||
fun->lazyScript()->setTreatAsRunOnce();
|
||||
} else {
|
||||
|
||||
if (outersc->isFunctionBox() && outersc->asFunctionBox()->mightAliasLocals())
|
||||
funbox->setMightAliasLocals(); // inherit mightAliasLocals from parent
|
||||
MOZ_ASSERT_IF(outersc->strict(), funbox->strictScript);
|
||||
|
@ -6418,13 +6410,9 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
const TransitiveCompileOptions& transitiveOptions = parser->options();
|
||||
CompileOptions options(cx, transitiveOptions);
|
||||
|
||||
// See comment above regarding funScope->setEnclosingScope().
|
||||
Rooted<StaticScope*> funScope(cx, funbox->staticScope());
|
||||
Rooted<StaticScope*> enclosingScope(cx, innermostStaticScope());
|
||||
funScope->setEnclosingScope(enclosingScope);
|
||||
|
||||
Rooted<JSObject*> enclosingScope(cx, innermostStaticScope());
|
||||
Rooted<JSObject*> sourceObject(cx, script->sourceObject());
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx, funScope, false, options,
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false, options,
|
||||
sourceObject,
|
||||
funbox->bufStart, funbox->bufEnd));
|
||||
if (!script)
|
||||
|
@ -6438,6 +6426,8 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
insideNonGlobalEval, lineNum, emitterMode);
|
||||
if (!bce2.init())
|
||||
return false;
|
||||
|
||||
/* We measured the max scope depth when we parsed the function. */
|
||||
if (!bce2.emitFunctionScript(pn->pn_body))
|
||||
return false;
|
||||
|
||||
|
|
|
@ -247,9 +247,9 @@ struct BytecodeEmitter
|
|||
|
||||
StmtInfoBCE* innermostStmt() const { return stmtStack.innermost(); }
|
||||
StmtInfoBCE* innermostScopeStmt() const { return stmtStack.innermostScopeStmt(); }
|
||||
StaticScope* innermostStaticScope() const;
|
||||
StaticScope* blockScopeOfDef(Definition* dn) const {
|
||||
return &parser->blockScopes[dn->pn_blockid].get()->as<StaticScope>();
|
||||
JSObject* innermostStaticScope() const;
|
||||
JSObject* blockScopeOfDef(Definition* dn) const {
|
||||
return parser->blockScopes[dn->pn_blockid];
|
||||
}
|
||||
|
||||
bool atBodyLevel(StmtInfoBCE* stmt) const;
|
||||
|
|
|
@ -1193,8 +1193,8 @@ FunctionBox::trace(JSTracer* trc)
|
|||
{
|
||||
ObjectBox::trace(trc);
|
||||
bindings.trace(trc);
|
||||
if (staticScope_)
|
||||
TraceRoot(trc, &staticScope_, "funbox-staticScope");
|
||||
if (enclosingStaticScope_)
|
||||
TraceRoot(trc, &enclosingStaticScope_, "funbox-enclosingStaticScope");
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -57,9 +57,9 @@ JSFunction::AutoParseUsingFunctionBox::AutoParseUsingFunctionBox(ExclusiveContex
|
|||
{
|
||||
fun_->unsetEnvironment();
|
||||
fun_->setFunctionBox(funbox);
|
||||
funbox->computeAllowSyntax(funbox->staticScope_);
|
||||
funbox->computeInWith(funbox->staticScope_);
|
||||
funbox->computeThisBinding(funbox->staticScope_);
|
||||
funbox->computeAllowSyntax(fun_);
|
||||
funbox->computeInWith(fun_);
|
||||
funbox->computeThisBinding(fun_);
|
||||
}
|
||||
|
||||
JSFunction::AutoParseUsingFunctionBox::~AutoParseUsingFunctionBox()
|
||||
|
@ -119,18 +119,18 @@ MarkUsesAsHoistedLexical(ParseNode* pn)
|
|||
}
|
||||
|
||||
void
|
||||
SharedContext::computeAllowSyntax(StaticScope* staticScope)
|
||||
SharedContext::computeAllowSyntax(JSObject* staticScope)
|
||||
{
|
||||
for (StaticScopeIter<CanGC> it(context, staticScope); !it.done(); it++) {
|
||||
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().function().isArrow()) {
|
||||
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().isArrow()) {
|
||||
// Any function supports new.target.
|
||||
allowNewTarget_ = true;
|
||||
allowSuperProperty_ = it.fun().function().allowSuperProperty();
|
||||
allowSuperProperty_ = it.fun().allowSuperProperty();
|
||||
if (it.maybeFunctionBox()) {
|
||||
superScopeAlreadyNeedsHomeObject_ = it.maybeFunctionBox()->needsHomeObject();
|
||||
allowSuperCall_ = it.maybeFunctionBox()->isDerivedClassConstructor();
|
||||
} else {
|
||||
allowSuperCall_ = it.fun().function().isDerivedClassConstructor();
|
||||
allowSuperCall_ = it.fun().isDerivedClassConstructor();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ SharedContext::computeAllowSyntax(StaticScope* staticScope)
|
|||
}
|
||||
|
||||
void
|
||||
SharedContext::computeThisBinding(StaticScope* staticScope)
|
||||
SharedContext::computeThisBinding(JSObject* staticScope)
|
||||
{
|
||||
for (StaticScopeIter<CanGC> it(context, staticScope); !it.done(); it++) {
|
||||
if (it.type() == StaticScopeIter<CanGC>::Module) {
|
||||
|
@ -147,10 +147,9 @@ SharedContext::computeThisBinding(StaticScope* staticScope)
|
|||
}
|
||||
|
||||
if (it.type() == StaticScopeIter<CanGC>::Function) {
|
||||
RootedFunction fun(context, &it.fun().function());
|
||||
// Arrow functions and generator expression lambdas don't have
|
||||
// their own `this` binding.
|
||||
if (fun->isArrow())
|
||||
if (it.fun().isArrow())
|
||||
continue;
|
||||
bool isDerived;
|
||||
if (it.maybeFunctionBox()) {
|
||||
|
@ -158,9 +157,9 @@ SharedContext::computeThisBinding(StaticScope* staticScope)
|
|||
continue;
|
||||
isDerived = it.maybeFunctionBox()->isDerivedClassConstructor();
|
||||
} else {
|
||||
if (fun->nonLazyScript()->isGeneratorExp())
|
||||
if (it.fun().nonLazyScript()->isGeneratorExp())
|
||||
continue;
|
||||
isDerived = fun->isDerivedClassConstructor();
|
||||
isDerived = it.fun().isDerivedClassConstructor();
|
||||
}
|
||||
|
||||
// Derived class constructors (including nested arrow functions and
|
||||
|
@ -177,7 +176,7 @@ SharedContext::computeThisBinding(StaticScope* staticScope)
|
|||
}
|
||||
|
||||
void
|
||||
SharedContext::computeInWith(StaticScope* staticScope)
|
||||
SharedContext::computeInWith(JSObject* staticScope)
|
||||
{
|
||||
for (StaticScopeIter<CanGC> it(context, staticScope); !it.done(); it++) {
|
||||
if (it.type() == StaticScopeIter<CanGC>::With) {
|
||||
|
@ -196,8 +195,8 @@ SharedContext::markSuperScopeNeedsHomeObject()
|
|||
return;
|
||||
|
||||
for (StaticScopeIter<CanGC> it(context, staticScope()); !it.done(); it++) {
|
||||
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().function().isArrow()) {
|
||||
MOZ_ASSERT(it.fun().function().allowSuperProperty());
|
||||
if (it.type() == StaticScopeIter<CanGC>::Function && !it.fun().isArrow()) {
|
||||
MOZ_ASSERT(it.fun().allowSuperProperty());
|
||||
// If we are still emitting the outer function that needs a home
|
||||
// object, mark it as needing one. Otherwise, we must be emitting
|
||||
// an eval script, and the outer function must already be marked
|
||||
|
@ -205,7 +204,7 @@ SharedContext::markSuperScopeNeedsHomeObject()
|
|||
if (it.maybeFunctionBox())
|
||||
it.maybeFunctionBox()->setNeedsHomeObject();
|
||||
else
|
||||
MOZ_ASSERT(it.funScript()->needsHomeObject());
|
||||
MOZ_ASSERT(it.fun().nonLazyScript()->needsHomeObject());
|
||||
superScopeAlreadyNeedsHomeObject_ = true;
|
||||
return;
|
||||
}
|
||||
|
@ -770,12 +769,12 @@ Parser<ParseHandler>::newObjectBox(JSObject* obj)
|
|||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
||||
ParseContext<ParseHandler>* outerpc,
|
||||
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* outerpc,
|
||||
Directives directives, bool extraWarnings, GeneratorKind generatorKind)
|
||||
: ObjectBox(fun, traceListHead),
|
||||
SharedContext(cx, directives, extraWarnings),
|
||||
bindings(),
|
||||
staticScope_(nullptr),
|
||||
enclosingStaticScope_(enclosingStaticScope),
|
||||
bufStart(0),
|
||||
bufEnd(0),
|
||||
startLine(1),
|
||||
|
@ -798,21 +797,13 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
|
|||
MOZ_ASSERT(fun->isTenured());
|
||||
}
|
||||
|
||||
bool
|
||||
FunctionBox::initStaticScope(Handle<StaticScope*> enclosingScope)
|
||||
{
|
||||
RootedFunction fun(context, function());
|
||||
staticScope_ = StaticFunctionScope::create(context, fun, enclosingScope);
|
||||
return staticScope_ != nullptr;
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox*
|
||||
Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
|
||||
ParseContext<ParseHandler>* outerpc,
|
||||
Directives inheritedDirectives,
|
||||
GeneratorKind generatorKind,
|
||||
Handle<StaticScope*> enclosingStaticScope)
|
||||
JSObject* enclosingStaticScope)
|
||||
{
|
||||
MOZ_ASSERT_IF(outerpc, enclosingStaticScope == outerpc->innermostStaticScope());
|
||||
MOZ_ASSERT(fun);
|
||||
|
@ -825,17 +816,15 @@ Parser<ParseHandler>::newFunctionBox(Node fn, JSFunction* fun,
|
|||
* function.
|
||||
*/
|
||||
FunctionBox* funbox =
|
||||
alloc.new_<FunctionBox>(context, traceListHead, fun, outerpc, inheritedDirectives,
|
||||
options().extraWarningsOption, generatorKind);
|
||||
alloc.new_<FunctionBox>(context, traceListHead, fun, enclosingStaticScope, outerpc,
|
||||
inheritedDirectives, options().extraWarningsOption,
|
||||
generatorKind);
|
||||
if (!funbox) {
|
||||
ReportOutOfMemory(context);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
traceListHead = funbox;
|
||||
|
||||
if (!funbox->initStaticScope(enclosingStaticScope))
|
||||
return nullptr;
|
||||
|
||||
if (fn)
|
||||
handler.setFunctionBox(fn, funbox);
|
||||
|
||||
|
@ -1184,7 +1173,7 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
|
|||
GeneratorKind generatorKind,
|
||||
Directives inheritedDirectives,
|
||||
Directives* newDirectives,
|
||||
Handle<StaticScope*> enclosingStaticScope)
|
||||
HandleObject enclosingStaticScope)
|
||||
{
|
||||
MOZ_ASSERT(checkOptionsCalled);
|
||||
|
||||
|
@ -2877,9 +2866,7 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox* funbo
|
|||
size_t numInnerFunctions = pc->innerFunctions.length();
|
||||
|
||||
RootedFunction fun(context, funbox->function());
|
||||
Rooted<StaticFunctionScope*> funScope(context, funbox->staticScope());
|
||||
LazyScript* lazy = LazyScript::CreateRaw(context, fun, funScope,
|
||||
numFreeVariables, numInnerFunctions,
|
||||
LazyScript* lazy = LazyScript::CreateRaw(context, fun, numFreeVariables, numInnerFunctions,
|
||||
versionNumber(), funbox->bufStart, funbox->bufEnd,
|
||||
funbox->startLine, funbox->startColumn);
|
||||
if (!lazy)
|
||||
|
@ -3082,7 +3069,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict
|
|||
if (!tokenStream.peekTokenPos(&pn->pn_pos))
|
||||
return null();
|
||||
|
||||
Rooted<StaticScope*> enclosing(context, fun->lazyScript()->enclosingScope());
|
||||
RootedObject enclosing(context, fun->lazyScript()->enclosingScope());
|
||||
Directives directives(/* strict = */ strict);
|
||||
FunctionBox* funbox = newFunctionBox(pn, fun, directives, generatorKind, enclosing);
|
||||
if (!funbox)
|
||||
|
@ -6622,11 +6609,8 @@ template <>
|
|||
ParseNode*
|
||||
Parser<FullParseHandler>::withStatement(YieldHandling yieldHandling)
|
||||
{
|
||||
// This is intentionally different from other abortIfSyntaxParser()
|
||||
// bailouts: `with` statements rule out syntax-only parsing for the entire
|
||||
// compilation unit. This `return null()` causes us to bail out all the way
|
||||
// to BytecodeCompiler::compileScript(), which retries with syntax parsing
|
||||
// disabled. See bug 892583.
|
||||
// test262/ch12/12.10/12.10-0-1.js fails if we try to parse with-statements
|
||||
// in syntax-parse mode. See bug 892583.
|
||||
if (handler.syntaxParser) {
|
||||
handler.disableSyntaxParser();
|
||||
abortedSyntaxParse = true;
|
||||
|
|
|
@ -295,7 +295,7 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
|
|||
StmtInfoPC* innermostStmt() const { return stmtStack.innermost(); }
|
||||
StmtInfoPC* innermostScopeStmt() const { return stmtStack.innermostScopeStmt(); }
|
||||
StmtInfoPC* innermostNonLabelStmt() const { return stmtStack.innermostNonLabel(); }
|
||||
StaticScope* innermostStaticScope() const {
|
||||
JSObject* innermostStaticScope() const {
|
||||
if (StmtInfoPC* stmt = innermostScopeStmt())
|
||||
return stmt->staticScope;
|
||||
return sc->staticScope();
|
||||
|
@ -325,7 +325,9 @@ struct MOZ_STACK_CLASS ParseContext : public GenericParseContext
|
|||
if (sc->staticScope()->is<StaticEvalScope>()) {
|
||||
bool bl = !stmt->enclosing;
|
||||
MOZ_ASSERT_IF(bl, stmt->type == StmtType::BLOCK);
|
||||
MOZ_ASSERT_IF(bl, stmt->staticScope->enclosingScope() == sc->staticScope());
|
||||
MOZ_ASSERT_IF(bl, stmt->staticScope
|
||||
->template as<StaticBlockScope>()
|
||||
.enclosingStaticScope() == sc->staticScope());
|
||||
return bl;
|
||||
}
|
||||
return !stmt;
|
||||
|
@ -520,11 +522,11 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
ObjectBox* newObjectBox(JSObject* obj);
|
||||
FunctionBox* newFunctionBox(Node fn, JSFunction* fun, ParseContext<ParseHandler>* outerpc,
|
||||
Directives directives, GeneratorKind generatorKind,
|
||||
Handle<StaticScope*> enclosingStaticScope);
|
||||
JSObject* enclosingStaticScope);
|
||||
|
||||
// Use when the funbox is the outermost.
|
||||
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, Directives directives,
|
||||
GeneratorKind generatorKind, Handle<StaticScope*> enclosingStaticScope)
|
||||
GeneratorKind generatorKind, HandleObject enclosingStaticScope)
|
||||
{
|
||||
return newFunctionBox(fn, fun, nullptr, directives, generatorKind,
|
||||
enclosingStaticScope);
|
||||
|
@ -534,7 +536,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
FunctionBox* newFunctionBox(Node fn, HandleFunction fun, ParseContext<ParseHandler>* outerpc,
|
||||
Directives directives, GeneratorKind generatorKind)
|
||||
{
|
||||
Rooted<StaticScope*> enclosing(context, outerpc->innermostStaticScope());
|
||||
RootedObject enclosing(context, outerpc->innermostStaticScope());
|
||||
return newFunctionBox(fn, fun, outerpc, directives, generatorKind, enclosing);
|
||||
}
|
||||
|
||||
|
@ -547,7 +549,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
JSFunction* newFunction(HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind,
|
||||
HandleObject proto);
|
||||
|
||||
bool generateBlockId(StaticScope* staticScope, uint32_t* blockIdOut) {
|
||||
bool generateBlockId(JSObject* staticScope, uint32_t* blockIdOut) {
|
||||
if (blockScopes.length() == StmtInfoPC::BlockIdLimit) {
|
||||
tokenStream.reportError(JSMSG_NEED_DIET, "program");
|
||||
return false;
|
||||
|
@ -613,7 +615,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
|||
Node standaloneFunctionBody(HandleFunction fun, Handle<PropertyNameVector> formals,
|
||||
GeneratorKind generatorKind,
|
||||
Directives inheritedDirectives, Directives* newDirectives,
|
||||
Handle<StaticScope*> enclosingStaticScope);
|
||||
HandleObject enclosingStaticScope);
|
||||
|
||||
// Parse a function, given only its arguments and body. Used for lazily
|
||||
// parsed functions.
|
||||
|
|
|
@ -229,10 +229,10 @@ class SharedContext
|
|||
// GlobalSharedContexts are stack allocated and thus may use RootedObject
|
||||
// for the static scope. FunctionBoxes are LifoAlloc'd and need to
|
||||
// manually trace their static scope.
|
||||
virtual StaticScope* staticScope() const = 0;
|
||||
void computeAllowSyntax(StaticScope* staticScope);
|
||||
void computeInWith(StaticScope* staticScope);
|
||||
void computeThisBinding(StaticScope* staticScope);
|
||||
virtual JSObject* staticScope() const = 0;
|
||||
void computeAllowSyntax(JSObject* staticScope);
|
||||
void computeInWith(JSObject* staticScope);
|
||||
void computeThisBinding(JSObject* staticScope);
|
||||
|
||||
virtual ObjectBox* toObjectBox() { return nullptr; }
|
||||
bool isObjectBox() { return toObjectBox() != nullptr; }
|
||||
|
@ -300,19 +300,19 @@ class MOZ_STACK_CLASS GlobalSharedContext : public SharedContext
|
|||
// non-function scope, so we have to compute our ThisBinding based on
|
||||
// the actual callee.
|
||||
if (maybeEvalCaller)
|
||||
computeThisBinding(maybeEvalCaller->nonLazyScript()->staticScope());
|
||||
computeThisBinding(maybeEvalCaller);
|
||||
else
|
||||
computeThisBinding(staticScope);
|
||||
}
|
||||
|
||||
StaticScope* staticScope() const override { return staticScope_; }
|
||||
JSObject* staticScope() const override { return staticScope_; }
|
||||
};
|
||||
|
||||
class FunctionBox : public ObjectBox, public SharedContext
|
||||
{
|
||||
public:
|
||||
Bindings bindings; /* bindings for this function */
|
||||
StaticFunctionScope* staticScope_;
|
||||
JSObject* enclosingStaticScope_;
|
||||
uint32_t bufStart;
|
||||
uint32_t bufEnd;
|
||||
uint32_t startLine;
|
||||
|
@ -335,15 +335,13 @@ class FunctionBox : public ObjectBox, public SharedContext
|
|||
|
||||
template <typename ParseHandler>
|
||||
FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunction* fun,
|
||||
ParseContext<ParseHandler>* pc, Directives directives, bool extraWarnings,
|
||||
GeneratorKind generatorKind);
|
||||
|
||||
bool initStaticScope(Handle<StaticScope*> enclosingScope);
|
||||
JSObject* enclosingStaticScope, ParseContext<ParseHandler>* pc,
|
||||
Directives directives, bool extraWarnings, GeneratorKind generatorKind);
|
||||
|
||||
ObjectBox* toObjectBox() override { return this; }
|
||||
JSFunction* function() const { return &object->as<JSFunction>(); }
|
||||
StaticFunctionScope* staticScope() const override { return staticScope_; }
|
||||
StaticScope* enclosingStaticScope() const { return staticScope_->enclosingScope(); }
|
||||
JSObject* staticScope() const override { return function(); }
|
||||
JSObject* enclosingStaticScope() const { return enclosingStaticScope_; }
|
||||
|
||||
GeneratorKind generatorKind() const { return GeneratorKindFromBits(generatorKindBits_); }
|
||||
bool isGenerator() const { return generatorKind() != NotGenerator; }
|
||||
|
@ -429,7 +427,7 @@ class ModuleBox : public ObjectBox, public SharedContext
|
|||
|
||||
ObjectBox* toObjectBox() override { return this; }
|
||||
ModuleObject* module() const { return &object->as<ModuleObject>(); }
|
||||
StaticModuleScope* staticScope() const override { return module()->staticScope(); }
|
||||
JSObject* staticScope() const override { return module(); }
|
||||
|
||||
void trace(JSTracer* trc) override;
|
||||
};
|
||||
|
|
|
@ -955,8 +955,8 @@ LazyScript::traceChildren(JSTracer* trc)
|
|||
if (sourceObject_)
|
||||
TraceEdge(trc, &sourceObject_, "sourceObject");
|
||||
|
||||
if (staticScope_)
|
||||
TraceEdge(trc, &staticScope_, "staticScope");
|
||||
if (enclosingScope_)
|
||||
TraceEdge(trc, &enclosingScope_, "enclosingScope");
|
||||
|
||||
// We rely on the fact that atoms are always tenured.
|
||||
FreeVariable* freeVariables = this->freeVariables();
|
||||
|
@ -981,8 +981,8 @@ js::GCMarker::eagerlyMarkChildren(LazyScript *thing)
|
|||
if (thing->sourceObject_)
|
||||
traverseEdge(thing, static_cast<JSObject*>(thing->sourceObject_));
|
||||
|
||||
if (thing->staticScope_)
|
||||
traverseEdge(thing, static_cast<JSObject*>(thing->staticScope_));
|
||||
if (thing->enclosingScope_)
|
||||
traverseEdge(thing, static_cast<JSObject*>(thing->enclosingScope_));
|
||||
|
||||
// We rely on the fact that atoms are always tenured.
|
||||
LazyScript::FreeVariable* freeVariables = thing->freeVariables();
|
||||
|
|
|
@ -100,8 +100,6 @@ class JitCode;
|
|||
D(js::ScriptSourceObject*) \
|
||||
D(js::Shape*) \
|
||||
D(js::SharedArrayBufferObject*) \
|
||||
D(js::StaticFunctionScope*) \
|
||||
D(js::StaticScope*) \
|
||||
D(js::StructTypeDescr*) \
|
||||
D(js::UnownedBaseShape*) \
|
||||
D(js::jit::JitCode*)
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
if (helperThreadCount() == 0)
|
||||
quit();
|
||||
|
||||
var code = `
|
||||
function f() {
|
||||
[function() { { function g() { } } },
|
||||
function() { with ({}) { } }];
|
||||
}
|
||||
`;
|
||||
|
||||
offThreadCompileScript(code);
|
||||
runOffThreadScript();
|
|
@ -1,50 +1,6 @@
|
|||
load(libdir + 'bytecode-cache.js');
|
||||
var test = "";
|
||||
|
||||
// code a nested function after calling it
|
||||
test = `
|
||||
function f() {
|
||||
function g() {
|
||||
return [f, g];
|
||||
}
|
||||
return g();
|
||||
}
|
||||
f()
|
||||
`;
|
||||
evalWithCache(test, {
|
||||
assertEqBytecode: true,
|
||||
checkAfter(ctx) {
|
||||
let [f, g] = ctx.global.f();
|
||||
assertEq(f, ctx.global.f);
|
||||
assertEq(f()[0], f);
|
||||
assertEq(f()[1] === g, false); // second call, fresh g closure
|
||||
assertEq(f()[1].toString(), g.toString()); // but the same source code
|
||||
assertEq(g()[0], f);
|
||||
assertEq(g()[1], g);
|
||||
}
|
||||
});
|
||||
|
||||
// code an unused function that contains an unused nested function
|
||||
test = `
|
||||
function f() {
|
||||
function g() {
|
||||
return [f, g];
|
||||
}
|
||||
return g;
|
||||
}
|
||||
f
|
||||
`;
|
||||
evalWithCache(test, {
|
||||
assertEqBytecode: true,
|
||||
checkAfter(ctx) {
|
||||
let f = ctx.global.f;
|
||||
let g = f();
|
||||
let [f1, g1] = g();
|
||||
assertEq(f1, f);
|
||||
assertEq(g1, g);
|
||||
}
|
||||
});
|
||||
|
||||
// code a function which has both used and unused inner functions.
|
||||
test = (function () {
|
||||
function f() {
|
||||
|
@ -60,4 +16,4 @@ test = (function () {
|
|||
|
||||
return "var obj = { x : 2 };" + f.toSource() + "; f()";
|
||||
})();
|
||||
evalWithCache(test, { assertEqBytecode: true, assertEqResult: true });
|
||||
evalWithCache(test, { assertEqBytecode: true, assertEqResult : true });
|
||||
|
|
|
@ -3463,9 +3463,8 @@ CreateNonSyntacticScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
|
|||
|
||||
staticScopeObj.set(&globalLexical->staticBlock());
|
||||
if (!scopeChain.empty()) {
|
||||
Rooted<StaticNonSyntacticScope*> scope(cx,
|
||||
StaticNonSyntacticScope::create(cx, staticScopeObj));
|
||||
if (!scope)
|
||||
staticScopeObj.set(StaticNonSyntacticScope::create(cx, staticScopeObj));
|
||||
if (!staticScopeObj)
|
||||
return false;
|
||||
|
||||
// The XPConnect subscript loader, which may pass in its own dynamic
|
||||
|
@ -3486,11 +3485,10 @@ CreateNonSyntacticScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
|
|||
// TODOshu: disallow the subscript loader from using non-distinguished
|
||||
// objects as dynamic scopes.
|
||||
dynamicScopeObj.set(
|
||||
cx->compartment()->getOrCreateNonSyntacticLexicalScope(cx, scope, dynamicScopeObj));
|
||||
cx->compartment()->getOrCreateNonSyntacticLexicalScope(cx, staticScopeObj,
|
||||
dynamicScopeObj));
|
||||
if (!dynamicScopeObj)
|
||||
return false;
|
||||
|
||||
staticScopeObj.set(scope);
|
||||
}
|
||||
|
||||
return true;
|
||||
|
@ -3504,7 +3502,7 @@ IsFunctionCloneable(HandleFunction fun)
|
|||
|
||||
// If a function was compiled to be lexically nested inside some other
|
||||
// script, we cannot clone it without breaking the compiler's assumptions.
|
||||
if (StaticScope* scope = fun->nonLazyScript()->enclosingStaticScope()) {
|
||||
if (JSObject* scope = fun->nonLazyScript()->enclosingStaticScope()) {
|
||||
// If the script is directly under the global scope, we can clone it.
|
||||
if (IsStaticGlobalLexicalScope(scope))
|
||||
return true;
|
||||
|
@ -3521,7 +3519,7 @@ IsFunctionCloneable(HandleFunction fun)
|
|||
if (block.needsClone())
|
||||
return false;
|
||||
|
||||
StaticScope* enclosing = block.enclosingScope();
|
||||
JSObject* enclosing = block.enclosingStaticScope();
|
||||
|
||||
// If the script is an indirect eval that is immediately scoped
|
||||
// under the global, we can clone it.
|
||||
|
|
|
@ -505,7 +505,7 @@ JSCompartment::wrap(JSContext* cx, MutableHandle<PropertyDescriptor> desc)
|
|||
|
||||
ClonedBlockObject*
|
||||
JSCompartment::getOrCreateNonSyntacticLexicalScope(JSContext* cx,
|
||||
Handle<StaticNonSyntacticScope*> enclosingStatic,
|
||||
HandleObject enclosingStatic,
|
||||
HandleObject enclosingScope)
|
||||
{
|
||||
if (!nonSyntacticLexicalScopes_) {
|
||||
|
|
|
@ -32,7 +32,6 @@ template<class Node> class ComponentFinder;
|
|||
|
||||
struct NativeIterator;
|
||||
class ClonedBlockObject;
|
||||
class StaticNonSyntacticScope;
|
||||
|
||||
/*
|
||||
* A single-entry cache for some base-10 double-to-string conversions. This
|
||||
|
@ -532,10 +531,9 @@ struct JSCompartment
|
|||
explicit WrapperEnum(JSCompartment* c) : js::WrapperMap::Enum(c->crossCompartmentWrappers) {}
|
||||
};
|
||||
|
||||
js::ClonedBlockObject* getOrCreateNonSyntacticLexicalScope(
|
||||
JSContext* cx,
|
||||
js::Handle<js::StaticNonSyntacticScope*> enclosingStatic,
|
||||
js::HandleObject enclosingScope);
|
||||
js::ClonedBlockObject* getOrCreateNonSyntacticLexicalScope(JSContext* cx,
|
||||
js::HandleObject enclosingStatic,
|
||||
js::HandleObject enclosingScope);
|
||||
js::ClonedBlockObject* getNonSyntacticLexicalScope(JSObject* enclosingScope) const;
|
||||
|
||||
/*
|
||||
|
|
|
@ -405,9 +405,9 @@ js::GetOutermostEnclosingFunctionOfScriptedCaller(JSContext* cx)
|
|||
return nullptr;
|
||||
|
||||
RootedFunction curr(cx, iter.callee(cx));
|
||||
for (StaticScopeIter<NoGC> i(curr->nonLazyScript()->staticScope()); !i.done(); i++) {
|
||||
for (StaticScopeIter<NoGC> i(curr); !i.done(); i++) {
|
||||
if (i.type() == StaticScopeIter<NoGC>::Function)
|
||||
curr = &i.fun().function();
|
||||
curr = &i.fun();
|
||||
}
|
||||
return curr;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include "vm/Debugger.h"
|
||||
#include "vm/GlobalObject.h"
|
||||
#include "vm/Interpreter.h"
|
||||
#include "vm/ScopeObject.h"
|
||||
#include "vm/Shape.h"
|
||||
#include "vm/StringBuffer.h"
|
||||
#include "vm/WrapperObject.h"
|
||||
|
@ -536,8 +535,8 @@ fun_resolve(JSContext* cx, HandleObject obj, HandleId id, bool* resolvedp)
|
|||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
js::XDRInterpretedFunction(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
HandleScript enclosingScript, MutableHandleFunction objp)
|
||||
js::XDRInterpretedFunction(XDRState<mode>* xdr, HandleObject enclosingScope, HandleScript enclosingScript,
|
||||
MutableHandleFunction objp)
|
||||
{
|
||||
enum FirstWordFlag {
|
||||
HasAtom = 0x1,
|
||||
|
@ -653,12 +652,10 @@ js::XDRInterpretedFunction(XDRState<mode>* xdr, Handle<StaticScope*> enclosingSc
|
|||
}
|
||||
|
||||
template bool
|
||||
js::XDRInterpretedFunction(XDRState<XDR_ENCODE>*, Handle<StaticScope*>, HandleScript,
|
||||
MutableHandleFunction);
|
||||
js::XDRInterpretedFunction(XDRState<XDR_ENCODE>*, HandleObject, HandleScript, MutableHandleFunction);
|
||||
|
||||
template bool
|
||||
js::XDRInterpretedFunction(XDRState<XDR_DECODE>*, Handle<StaticScope*>, HandleScript,
|
||||
MutableHandleFunction);
|
||||
js::XDRInterpretedFunction(XDRState<XDR_DECODE>*, HandleObject, HandleScript, MutableHandleFunction);
|
||||
|
||||
/*
|
||||
* [[HasInstance]] internal method for Function objects: fetch the .prototype
|
||||
|
@ -754,14 +751,15 @@ static JSObject*
|
|||
CreateFunctionPrototype(JSContext* cx, JSProtoKey key)
|
||||
{
|
||||
Rooted<GlobalObject*> self(cx, cx->global());
|
||||
RootedObject objectProto(cx, &self->getPrototype(JSProto_Object).toObject());
|
||||
|
||||
// Bizarrely, |Function.prototype| must be an interpreted function, so
|
||||
// give it the guts to be one.
|
||||
Rooted<ClonedBlockObject*> globalLexicalEnv(cx, &self->lexicalScope());
|
||||
RootedObject objectProto(cx, &self->getPrototype(JSProto_Object).toObject());
|
||||
/*
|
||||
* Bizarrely, |Function.prototype| must be an interpreted function, so
|
||||
* give it the guts to be one.
|
||||
*/
|
||||
JSObject* functionProto_ =
|
||||
NewFunctionWithProto(cx, nullptr, 0, JSFunction::INTERPRETED,
|
||||
globalLexicalEnv, nullptr, objectProto, AllocKind::FUNCTION,
|
||||
self, nullptr, objectProto, AllocKind::FUNCTION,
|
||||
SingletonObject);
|
||||
if (!functionProto_)
|
||||
return nullptr;
|
||||
|
@ -789,12 +787,8 @@ CreateFunctionPrototype(JSContext* cx, JSProtoKey key)
|
|||
if (!sourceObject || !ScriptSourceObject::initFromOptions(cx, sourceObject, options))
|
||||
return nullptr;
|
||||
|
||||
Rooted<StaticScope*> globalScope(cx, &globalLexicalEnv->staticBlock());
|
||||
Rooted<StaticScope*> funScope(cx, StaticFunctionScope::create(cx, functionProto, globalScope));
|
||||
if (!funScope)
|
||||
return nullptr;
|
||||
RootedScript script(cx, JSScript::Create(cx,
|
||||
funScope,
|
||||
/* enclosingScope = */ nullptr,
|
||||
/* savedCallerFun = */ false,
|
||||
options,
|
||||
sourceObject,
|
||||
|
@ -1451,7 +1445,7 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext* cx, HandleFuncti
|
|||
}
|
||||
|
||||
if (script) {
|
||||
Rooted<StaticScope*> enclosingScope(cx, lazy->enclosingScope());
|
||||
RootedObject enclosingScope(cx, lazy->enclosingScope());
|
||||
RootedScript clonedScript(cx, CloneScriptIntoFunction(cx, enclosingScope, fun, script));
|
||||
if (!clonedScript)
|
||||
return false;
|
||||
|
@ -2058,7 +2052,7 @@ js::CloneFunctionReuseScript(JSContext* cx, HandleFunction fun, HandleObject par
|
|||
|
||||
JSFunction*
|
||||
js::CloneFunctionAndScript(JSContext* cx, HandleFunction fun, HandleObject parent,
|
||||
Handle<StaticScope*> newStaticScope,
|
||||
HandleObject newStaticScope,
|
||||
gc::AllocKind allocKind /* = FUNCTION */,
|
||||
HandleObject proto /* = nullptr */)
|
||||
{
|
||||
|
|
|
@ -728,7 +728,7 @@ CloneFunctionReuseScript(JSContext* cx, HandleFunction fun, HandleObject parent,
|
|||
// Functions whose scripts are cloned are always given singleton types.
|
||||
extern JSFunction*
|
||||
CloneFunctionAndScript(JSContext* cx, HandleFunction fun, HandleObject parent,
|
||||
Handle<StaticScope*> newStaticScope,
|
||||
HandleObject newStaticScope,
|
||||
gc::AllocKind kind = gc::AllocKind::FUNCTION,
|
||||
HandleObject proto = nullptr);
|
||||
|
||||
|
@ -789,7 +789,7 @@ JSString* FunctionToString(JSContext* cx, HandleFunction fun, bool lambdaParen);
|
|||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRInterpretedFunction(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
XDRInterpretedFunction(XDRState<mode>* xdr, HandleObject enclosingScope,
|
||||
HandleScript enclosingScript, MutableHandleFunction objp);
|
||||
|
||||
/*
|
||||
|
|
|
@ -92,7 +92,7 @@ CloneFunctionObjectIfNotSingleton(JSContext* cx, HandleFunction fun, HandleObjec
|
|||
RootedScript script(cx, fun->getOrCreateScript(cx));
|
||||
if (!script)
|
||||
return nullptr;
|
||||
Rooted<StaticScope*> staticScope(cx, script->enclosingStaticScope());
|
||||
RootedObject staticScope(cx, script->enclosingStaticScope());
|
||||
return CloneFunctionAndScript(cx, fun, parent, staticScope, kind, proto);
|
||||
}
|
||||
|
||||
|
|
|
@ -6858,7 +6858,7 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target)
|
|||
|
||||
// Get the static global lexical scope of the target compartment. Static
|
||||
// scopes need to be fixed up below.
|
||||
Rooted<StaticScope*> targetStaticGlobalLexicalScope(rt);
|
||||
RootedObject targetStaticGlobalLexicalScope(rt);
|
||||
targetStaticGlobalLexicalScope = &target->maybeGlobal()->lexicalScope().staticBlock();
|
||||
|
||||
for (ZoneCellIter iter(source->zone(), AllocKind::SCRIPT); !iter.done(); iter.next()) {
|
||||
|
|
|
@ -516,7 +516,7 @@ XDRLazyFreeVariables(XDRState<mode>* xdr, MutableHandle<LazyScript*> lazy)
|
|||
template<XDRMode mode>
|
||||
static bool
|
||||
XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun, HandleScript script,
|
||||
Handle<StaticFunctionScope*> funScope, MutableHandle<LazyScript*> lazy)
|
||||
HandleObject enclosingScope, MutableHandle<LazyScript*> lazy)
|
||||
{
|
||||
MOZ_ASSERT_IF(mode == XDR_ENCODE, script->isRelazifiable() && script->maybeLazyScript());
|
||||
MOZ_ASSERT_IF(mode == XDR_ENCODE, !lazy->numInnerFunctions());
|
||||
|
@ -546,8 +546,8 @@ XDRRelazificationInfo(XDRState<mode>* xdr, HandleFunction fun, HandleScript scri
|
|||
return false;
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
lazy.set(LazyScript::Create(cx, fun, script, funScope, script, packedFields,
|
||||
begin, end, lineno, column));
|
||||
lazy.set(LazyScript::Create(cx, fun, script, enclosingScope, script,
|
||||
packedFields, begin, end, lineno, column));
|
||||
|
||||
// As opposed to XDRLazyScript, we need to restore the runtime bits
|
||||
// of the script, as we are trying to match the fact this function
|
||||
|
@ -593,8 +593,8 @@ enum XDRClassKind {
|
|||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
||||
HandleScript enclosingScript, HandleFunction fun, MutableHandleScript scriptp)
|
||||
js::XDRScript(XDRState<mode>* xdr, HandleObject enclosingScopeArg, HandleScript enclosingScript,
|
||||
HandleFunction fun, MutableHandleScript scriptp)
|
||||
{
|
||||
/* NB: Keep this in sync with CopyScript. */
|
||||
|
||||
|
@ -638,7 +638,7 @@ js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
|||
|
||||
JSContext* cx = xdr->cx();
|
||||
RootedScript script(cx);
|
||||
Rooted<StaticScope*> enclosingScope(cx, enclosingScopeArg);
|
||||
RootedObject enclosingScope(cx, enclosingScopeArg);
|
||||
natoms = nsrcnotes = 0;
|
||||
nconsts = nobjects = nregexps = ntrynotes = nblockscopes = nyieldoffsets = 0;
|
||||
|
||||
|
@ -846,12 +846,6 @@ js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (fun) {
|
||||
enclosingScope = StaticFunctionScope::create(cx, fun, enclosingScope);
|
||||
if (!enclosingScope)
|
||||
return false;
|
||||
}
|
||||
|
||||
script = JSScript::Create(cx, enclosingScope, !!(scriptBits & (1 << SavedCallerFun)),
|
||||
options, sourceObject, 0, 0);
|
||||
if (!script)
|
||||
|
@ -1050,33 +1044,28 @@ js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
|||
}
|
||||
if (!xdr->codeUint32(&enclosingStaticScopeIndex))
|
||||
return false;
|
||||
Rooted<StaticScope*> enclosingStaticScope(cx);
|
||||
Rooted<JSObject*> enclosingStaticScope(cx);
|
||||
if (mode == XDR_DECODE) {
|
||||
if (enclosingStaticScopeIndex != UINT32_MAX) {
|
||||
MOZ_ASSERT(enclosingStaticScopeIndex < i);
|
||||
enclosingStaticScope = &script->objects()->vector[enclosingStaticScopeIndex]
|
||||
->as<StaticScope>();
|
||||
enclosingStaticScope = script->objects()->vector[enclosingStaticScopeIndex];
|
||||
} else {
|
||||
// This is not ternary because MSVC can't typecheck the
|
||||
// ternary.
|
||||
if (fun)
|
||||
enclosingStaticScope = script->staticScope();
|
||||
enclosingStaticScope = fun;
|
||||
else
|
||||
enclosingStaticScope = enclosingScope;
|
||||
}
|
||||
}
|
||||
|
||||
if (classk == CK_BlockObject) {
|
||||
Rooted<StaticBlockScope*> tmp(cx);
|
||||
if (mode == XDR_ENCODE)
|
||||
tmp = &(*objp)->as<StaticBlockScope>();
|
||||
Rooted<StaticBlockScope*> tmp(cx, static_cast<StaticBlockScope*>(objp->get()));
|
||||
if (!XDRStaticBlockScope(xdr, enclosingStaticScope, &tmp))
|
||||
return false;
|
||||
*objp = tmp;
|
||||
} else {
|
||||
Rooted<StaticWithScope*> tmp(cx);
|
||||
if (mode == XDR_ENCODE)
|
||||
tmp = &(*objp)->as<StaticWithScope>();
|
||||
Rooted<StaticWithScope*> tmp(cx, static_cast<StaticWithScope*>(objp->get()));
|
||||
if (!XDRStaticWithScope(xdr, enclosingStaticScope, &tmp))
|
||||
return false;
|
||||
*objp = tmp;
|
||||
|
@ -1098,7 +1087,7 @@ js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
|||
case CK_JSFunction: {
|
||||
/* Code the nested function's enclosing scope. */
|
||||
uint32_t funEnclosingScopeIndex = 0;
|
||||
Rooted<StaticScope*> funEnclosingScope(cx);
|
||||
RootedObject funEnclosingScope(cx);
|
||||
if (mode == XDR_ENCODE) {
|
||||
RootedFunction function(cx, &(*objp)->as<JSFunction>());
|
||||
|
||||
|
@ -1145,13 +1134,12 @@ js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
|||
// This is not ternary because MSVC can't typecheck the
|
||||
// ternary.
|
||||
if (fun)
|
||||
funEnclosingScope = script->staticScope();
|
||||
funEnclosingScope = fun;
|
||||
else
|
||||
funEnclosingScope = enclosingScope;
|
||||
} else {
|
||||
MOZ_ASSERT(funEnclosingScopeIndex < i);
|
||||
funEnclosingScope = &script->objects()->vector[funEnclosingScopeIndex]
|
||||
.get()->as<StaticScope>();
|
||||
funEnclosingScope = script->objects()->vector[funEnclosingScopeIndex];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1218,10 +1206,7 @@ js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
|||
if (mode == XDR_ENCODE)
|
||||
lazy = script->maybeLazyScript();
|
||||
|
||||
Rooted<StaticFunctionScope*> lazyScope(cx, mode == XDR_DECODE
|
||||
? &enclosingScope->as<StaticFunctionScope>()
|
||||
: nullptr);
|
||||
if (!XDRRelazificationInfo(xdr, fun, script, lazyScope, &lazy))
|
||||
if (!XDRRelazificationInfo(xdr, fun, script, enclosingScope, &lazy))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE)
|
||||
|
@ -1240,18 +1225,17 @@ js::XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScopeArg,
|
|||
}
|
||||
|
||||
template bool
|
||||
js::XDRScript(XDRState<XDR_ENCODE>*, Handle<StaticScope*>, HandleScript, HandleFunction,
|
||||
js::XDRScript(XDRState<XDR_ENCODE>*, HandleObject, HandleScript, HandleFunction,
|
||||
MutableHandleScript);
|
||||
|
||||
template bool
|
||||
js::XDRScript(XDRState<XDR_DECODE>*, Handle<StaticScope*>, HandleScript, HandleFunction,
|
||||
js::XDRScript(XDRState<XDR_DECODE>*, HandleObject, HandleScript, HandleFunction,
|
||||
MutableHandleScript);
|
||||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
js::XDRLazyScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
HandleScript enclosingScript, HandleFunction fun,
|
||||
MutableHandle<LazyScript*> lazy)
|
||||
js::XDRLazyScript(XDRState<mode>* xdr, HandleObject enclosingScope, HandleScript enclosingScript,
|
||||
HandleFunction fun, MutableHandle<LazyScript*> lazy)
|
||||
{
|
||||
JSContext* cx = xdr->cx();
|
||||
|
||||
|
@ -1284,11 +1268,7 @@ js::XDRLazyScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
|||
}
|
||||
|
||||
if (mode == XDR_DECODE) {
|
||||
Rooted<StaticFunctionScope*> funScope(cx,
|
||||
StaticFunctionScope::create(cx, fun, enclosingScope));
|
||||
if (!funScope)
|
||||
return false;
|
||||
lazy.set(LazyScript::Create(cx, fun, nullptr, funScope, enclosingScript,
|
||||
lazy.set(LazyScript::Create(cx, fun, nullptr, enclosingScope, enclosingScript,
|
||||
packedFields, begin, end, lineno, column));
|
||||
if (!lazy)
|
||||
return false;
|
||||
|
@ -1303,14 +1283,13 @@ js::XDRLazyScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
|||
// Code inner functions.
|
||||
{
|
||||
RootedFunction func(cx);
|
||||
Rooted<StaticFunctionScope*> funScope(cx, lazy->staticScope());
|
||||
HeapPtrFunction* innerFunctions = lazy->innerFunctions();
|
||||
size_t numInnerFunctions = lazy->numInnerFunctions();
|
||||
for (size_t i = 0; i < numInnerFunctions; i++) {
|
||||
if (mode == XDR_ENCODE)
|
||||
func = innerFunctions[i];
|
||||
|
||||
if (!XDRInterpretedFunction(xdr, funScope, enclosingScript, &func))
|
||||
if (!XDRInterpretedFunction(xdr, fun, enclosingScript, &func))
|
||||
return false;
|
||||
|
||||
if (mode == XDR_DECODE)
|
||||
|
@ -1322,11 +1301,11 @@ js::XDRLazyScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
|||
}
|
||||
|
||||
template bool
|
||||
js::XDRLazyScript(XDRState<XDR_ENCODE>*, Handle<StaticScope*>, HandleScript,
|
||||
js::XDRLazyScript(XDRState<XDR_ENCODE>*, HandleObject, HandleScript,
|
||||
HandleFunction, MutableHandle<LazyScript*>);
|
||||
|
||||
template bool
|
||||
js::XDRLazyScript(XDRState<XDR_DECODE>*, Handle<StaticScope*>, HandleScript,
|
||||
js::XDRLazyScript(XDRState<XDR_DECODE>*, HandleObject, HandleScript,
|
||||
HandleFunction, MutableHandle<LazyScript*>);
|
||||
|
||||
void
|
||||
|
@ -2766,7 +2745,7 @@ JSScript::initCompartment(ExclusiveContext* cx)
|
|||
}
|
||||
|
||||
/* static */ JSScript*
|
||||
JSScript::Create(ExclusiveContext* cx, Handle<StaticScope*> staticScope, bool savedCallerFun,
|
||||
JSScript::Create(ExclusiveContext* cx, HandleObject enclosingScope, bool savedCallerFun,
|
||||
const ReadOnlyCompileOptions& options, HandleObject sourceObject,
|
||||
uint32_t bufStart, uint32_t bufEnd)
|
||||
{
|
||||
|
@ -2779,7 +2758,7 @@ JSScript::Create(ExclusiveContext* cx, Handle<StaticScope*> staticScope, bool sa
|
|||
PodZero(script.get());
|
||||
new (&script->bindings) Bindings;
|
||||
|
||||
script->staticScope_ = staticScope;
|
||||
script->enclosingStaticScope_ = enclosingScope;
|
||||
script->savedCallerFun_ = savedCallerFun;
|
||||
script->initCompartment(cx);
|
||||
|
||||
|
@ -2787,12 +2766,10 @@ JSScript::Create(ExclusiveContext* cx, Handle<StaticScope*> staticScope, bool sa
|
|||
script->noScriptRval_ = options.noScriptRval;
|
||||
script->treatAsRunOnce_ = options.isRunOnce;
|
||||
|
||||
// Compute whether this script is under a non-syntactic scope, passing
|
||||
// staticScope->enclosingScope() in a case where staticScope itself is not
|
||||
// a non-syntactic scope and may not be fully initialized yet.
|
||||
Rooted<StaticScope*> enclosingScope(cx, staticScope);
|
||||
if (staticScope && staticScope->is<StaticFunctionScope>())
|
||||
enclosingScope = staticScope->enclosingScope();
|
||||
// Compute whether this script is under a non-syntactic scope. We don't
|
||||
// need to walk the entire static scope chain if the script is nested in a
|
||||
// function. In that case, we can propagate the cached value from the
|
||||
// outer script.
|
||||
script->hasNonSyntacticScope_ = HasNonSyntacticStaticScopeChain(enclosingScope);
|
||||
|
||||
script->version = options.version;
|
||||
|
@ -3131,20 +3108,15 @@ JSScript::uninlinedGlobal() const
|
|||
void
|
||||
JSScript::fixEnclosingStaticGlobalLexicalScope()
|
||||
{
|
||||
if (function_) {
|
||||
MOZ_ASSERT(IsStaticGlobalLexicalScope(staticScope_->enclosingScope()));
|
||||
staticScope_->setEnclosingScope(&global().lexicalScope().staticBlock());
|
||||
} else {
|
||||
MOZ_ASSERT(IsStaticGlobalLexicalScope(staticScope_));
|
||||
staticScope_ = &global().lexicalScope().staticBlock();
|
||||
}
|
||||
MOZ_ASSERT(IsStaticGlobalLexicalScope(enclosingStaticScope_));
|
||||
enclosingStaticScope_ = &global().lexicalScope().staticBlock();
|
||||
}
|
||||
|
||||
void
|
||||
LazyScript::fixEnclosingStaticGlobalLexicalScope()
|
||||
{
|
||||
MOZ_ASSERT(IsStaticGlobalLexicalScope(staticScope_->enclosingScope()));
|
||||
staticScope_->setEnclosingScope(&function_->global().lexicalScope().staticBlock());
|
||||
MOZ_ASSERT(IsStaticGlobalLexicalScope(enclosingScope_));
|
||||
enclosingScope_ = &function_->global().lexicalScope().staticBlock();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -3422,8 +3394,7 @@ Rebase(JSScript* dst, JSScript* src, T* srcp)
|
|||
}
|
||||
|
||||
static JSObject*
|
||||
CloneInnerInterpretedFunction(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
||||
HandleFunction srcFun)
|
||||
CloneInnerInterpretedFunction(JSContext* cx, HandleObject enclosingScope, HandleFunction srcFun)
|
||||
{
|
||||
/* NB: Keep this in sync with XDRInterpretedFunction. */
|
||||
RootedObject cloneProto(cx);
|
||||
|
@ -3463,7 +3434,7 @@ CloneInnerInterpretedFunction(JSContext* cx, Handle<StaticScope*> enclosingScope
|
|||
}
|
||||
|
||||
bool
|
||||
js::detail::CopyScript(JSContext* cx, Handle<StaticScope*> scriptStaticScope, HandleScript src,
|
||||
js::detail::CopyScript(JSContext* cx, HandleObject scriptStaticScope, HandleScript src,
|
||||
HandleScript dst)
|
||||
{
|
||||
if (src->treatAsRunOnce() && !src->functionNonDelazifying()) {
|
||||
|
@ -3509,15 +3480,14 @@ js::detail::CopyScript(JSContext* cx, Handle<StaticScope*> scriptStaticScope, Ha
|
|||
if (obj->is<NestedStaticScope>()) {
|
||||
Rooted<NestedStaticScope*> innerBlock(cx, &obj->as<NestedStaticScope>());
|
||||
|
||||
Rooted<StaticScope*> enclosingScope(cx);
|
||||
RootedObject enclosingScope(cx);
|
||||
if (NestedStaticScope* enclosingBlock = innerBlock->enclosingNestedScope()) {
|
||||
if (IsStaticGlobalLexicalScope(enclosingBlock)) {
|
||||
MOZ_ASSERT(IsStaticGlobalLexicalScope(scriptStaticScope) ||
|
||||
scriptStaticScope->is<StaticNonSyntacticScope>());
|
||||
enclosingScope = scriptStaticScope;
|
||||
} else {
|
||||
enclosingScope = &objects[FindScopeObjectIndex(src, *enclosingBlock)]
|
||||
.get()->as<StaticScope>();
|
||||
enclosingScope = objects[FindScopeObjectIndex(src, *enclosingBlock)];
|
||||
}
|
||||
} else {
|
||||
enclosingScope = scriptStaticScope;
|
||||
|
@ -3543,14 +3513,13 @@ js::detail::CopyScript(JSContext* cx, Handle<StaticScope*> scriptStaticScope, Ha
|
|||
if (!innerFun->getOrCreateScript(cx))
|
||||
return false;
|
||||
}
|
||||
Rooted<StaticScope*> staticScope(cx, innerFun->nonLazyScript()
|
||||
->enclosingStaticScope());
|
||||
RootedObject staticScope(cx, innerFun->nonLazyScript()->enclosingStaticScope());
|
||||
StaticScopeIter<CanGC> ssi(cx, staticScope);
|
||||
Rooted<StaticScope*> enclosingScope(cx);
|
||||
RootedObject enclosingScope(cx);
|
||||
if (ssi.done() || ssi.type() == StaticScopeIter<CanGC>::NonSyntactic) {
|
||||
enclosingScope = scriptStaticScope;
|
||||
} else if (ssi.type() == StaticScopeIter<CanGC>::Function) {
|
||||
MOZ_ASSERT(scriptStaticScope->is<StaticFunctionScope>());
|
||||
MOZ_ASSERT(scriptStaticScope->is<JSFunction>());
|
||||
enclosingScope = scriptStaticScope;
|
||||
} else if (ssi.type() == StaticScopeIter<CanGC>::Block) {
|
||||
if (ssi.block().isGlobal()) {
|
||||
|
@ -3558,12 +3527,10 @@ js::detail::CopyScript(JSContext* cx, Handle<StaticScope*> scriptStaticScope, Ha
|
|||
scriptStaticScope->is<StaticNonSyntacticScope>());
|
||||
enclosingScope = scriptStaticScope;
|
||||
} else {
|
||||
enclosingScope = &objects[FindScopeObjectIndex(src, ssi.block())]
|
||||
.get()->as<StaticBlockScope>();
|
||||
enclosingScope = objects[FindScopeObjectIndex(src, ssi.block())];
|
||||
}
|
||||
} else {
|
||||
enclosingScope = &objects[FindScopeObjectIndex(src, ssi.staticWith())]
|
||||
.get()->as<StaticWithScope>();
|
||||
enclosingScope = objects[FindScopeObjectIndex(src, ssi.staticWith())];
|
||||
}
|
||||
|
||||
clone = CloneInnerInterpretedFunction(cx, enclosingScope, innerFun);
|
||||
|
@ -3661,7 +3628,7 @@ js::detail::CopyScript(JSContext* cx, Handle<StaticScope*> scriptStaticScope, Ha
|
|||
}
|
||||
|
||||
static JSScript*
|
||||
CreateEmptyScriptForClone(JSContext* cx, Handle<StaticScope*> enclosingScope, HandleScript src)
|
||||
CreateEmptyScriptForClone(JSContext* cx, HandleObject enclosingScope, HandleScript src)
|
||||
{
|
||||
/*
|
||||
* Wrap the script source object as needed. Self-hosted scripts may be
|
||||
|
@ -3713,23 +3680,18 @@ js::CloneGlobalScript(JSContext* cx, Handle<StaticScope*> enclosingScope, Handle
|
|||
}
|
||||
|
||||
JSScript*
|
||||
js::CloneScriptIntoFunction(JSContext* cx, Handle<StaticScope*> enclosingScope, HandleFunction fun,
|
||||
js::CloneScriptIntoFunction(JSContext* cx, HandleObject enclosingScope, HandleFunction fun,
|
||||
HandleScript src)
|
||||
{
|
||||
MOZ_ASSERT(fun->isInterpreted());
|
||||
|
||||
Rooted<StaticFunctionScope*> funScope(cx, StaticFunctionScope::create(cx, fun,
|
||||
enclosingScope));
|
||||
if (!funScope)
|
||||
return nullptr;
|
||||
|
||||
// Allocate the destination script up front and set it as the script of
|
||||
// |fun|, which is to be its container.
|
||||
//
|
||||
// This is so that when cloning nested functions, they can walk the static
|
||||
// scope chain via fun and correctly compute the presence of a
|
||||
// non-syntactic global.
|
||||
RootedScript dst(cx, CreateEmptyScriptForClone(cx, funScope, src));
|
||||
RootedScript dst(cx, CreateEmptyScriptForClone(cx, enclosingScope, src));
|
||||
if (!dst)
|
||||
return nullptr;
|
||||
|
||||
|
@ -3745,7 +3707,7 @@ js::CloneScriptIntoFunction(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
|||
fun->initScript(dst);
|
||||
}
|
||||
|
||||
if (!detail::CopyScript(cx, funScope, src, dst)) {
|
||||
if (!detail::CopyScript(cx, fun, src, dst)) {
|
||||
if (lazy)
|
||||
fun->initLazyScript(lazy);
|
||||
else
|
||||
|
@ -3985,8 +3947,8 @@ JSScript::traceChildren(JSTracer* trc)
|
|||
if (module_)
|
||||
TraceEdge(trc, &module_, "module");
|
||||
|
||||
if (staticScope_)
|
||||
TraceEdge(trc, &staticScope_, "staticScope");
|
||||
if (enclosingStaticScope_)
|
||||
TraceEdge(trc, &enclosingStaticScope_, "enclosingStaticScope");
|
||||
|
||||
if (maybeLazyScript())
|
||||
TraceManuallyBarrieredEdge(trc, &lazyScript, "lazyScript");
|
||||
|
@ -4088,18 +4050,20 @@ JSScript::getStaticBlockScope(jsbytecode* pc)
|
|||
return blockChain;
|
||||
}
|
||||
|
||||
StaticScope*
|
||||
JSObject*
|
||||
JSScript::innermostStaticScopeInScript(jsbytecode* pc)
|
||||
{
|
||||
if (NestedStaticScope* scope = getStaticBlockScope(pc))
|
||||
if (JSObject* scope = getStaticBlockScope(pc))
|
||||
return scope;
|
||||
return staticScope_;
|
||||
if (module())
|
||||
return module();
|
||||
return functionNonDelazifying();
|
||||
}
|
||||
|
||||
StaticScope*
|
||||
JSObject*
|
||||
JSScript::innermostStaticScope(jsbytecode* pc)
|
||||
{
|
||||
if (StaticScope* scope = innermostStaticScopeInScript(pc))
|
||||
if (JSObject* scope = innermostStaticScopeInScript(pc))
|
||||
return scope;
|
||||
return enclosingStaticScope();
|
||||
}
|
||||
|
@ -4144,13 +4108,8 @@ js::SetFrameArgumentsObject(JSContext* cx, AbstractFramePtr frame,
|
|||
// Note that here and below, it is insufficient to only check for
|
||||
// JS_OPTIMIZED_ARGUMENTS, as Ion could have optimized out the
|
||||
// arguments slot.
|
||||
if (IsOptimizedPlaceholderMagicValue(frame.callObj().as<ScopeObject>()
|
||||
.aliasedVar(ScopeCoordinate(pc))))
|
||||
{
|
||||
frame.callObj().as<ScopeObject>().setAliasedVar(cx, ScopeCoordinate(pc),
|
||||
cx->names().arguments,
|
||||
ObjectValue(*argsobj));
|
||||
}
|
||||
if (IsOptimizedPlaceholderMagicValue(frame.callObj().as<ScopeObject>().aliasedVar(ScopeCoordinate(pc))))
|
||||
frame.callObj().as<ScopeObject>().setAliasedVar(cx, ScopeCoordinate(pc), cx->names().arguments, ObjectValue(*argsobj));
|
||||
} else {
|
||||
if (IsOptimizedPlaceholderMagicValue(frame.unaliasedLocal(bi.frameIndex())))
|
||||
frame.unaliasedLocal(bi.frameIndex()) = ObjectValue(*argsobj);
|
||||
|
@ -4248,12 +4207,10 @@ JSScript::formalLivesInArgumentsObject(unsigned argSlot)
|
|||
return argsObjAliasesFormals() && !formalIsAliased(argSlot);
|
||||
}
|
||||
|
||||
LazyScript::LazyScript(JSFunction* fun, StaticFunctionScope* funScope, void* table,
|
||||
uint64_t packedFields, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column)
|
||||
LazyScript::LazyScript(JSFunction* fun, void* table, uint64_t packedFields, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
: script_(nullptr),
|
||||
function_(fun),
|
||||
staticScope_(funScope),
|
||||
enclosingScope_(nullptr),
|
||||
sourceObject_(nullptr),
|
||||
table_(table),
|
||||
packedFields_(packedFields),
|
||||
|
@ -4281,10 +4238,13 @@ LazyScript::resetScript()
|
|||
}
|
||||
|
||||
void
|
||||
LazyScript::initSource(ScriptSourceObject* sourceObject)
|
||||
LazyScript::setParent(JSObject* enclosingScope, ScriptSourceObject* sourceObject)
|
||||
{
|
||||
MOZ_ASSERT(!sourceObject_);
|
||||
MOZ_ASSERT(!sourceObject_ && !enclosingScope_);
|
||||
MOZ_ASSERT_IF(enclosingScope, function_->compartment() == enclosingScope->compartment());
|
||||
MOZ_ASSERT(function_->compartment() == sourceObject->compartment());
|
||||
|
||||
enclosingScope_ = enclosingScope;
|
||||
sourceObject_ = sourceObject;
|
||||
}
|
||||
|
||||
|
@ -4302,7 +4262,6 @@ LazyScript::maybeForwardedScriptSource() const
|
|||
|
||||
/* static */ LazyScript*
|
||||
LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
||||
Handle<StaticFunctionScope*> funScope,
|
||||
uint64_t packedFields, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column)
|
||||
{
|
||||
|
@ -4332,12 +4291,11 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
|||
|
||||
cx->compartment()->scheduleDelazificationForDebugger();
|
||||
|
||||
return new (res) LazyScript(fun, funScope, table.forget(), packed, begin, end, lineno, column);
|
||||
return new (res) LazyScript(fun, table.forget(), packed, begin, end, lineno, column);
|
||||
}
|
||||
|
||||
/* static */ LazyScript*
|
||||
LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
||||
Handle<StaticFunctionScope*> funScope,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions, JSVersion version,
|
||||
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
{
|
||||
|
@ -4358,15 +4316,14 @@ LazyScript::CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
|||
p.isDerivedClassConstructor = false;
|
||||
p.needsHomeObject = false;
|
||||
|
||||
LazyScript* res = LazyScript::CreateRaw(cx, fun, funScope, packedFields,
|
||||
begin, end, lineno, column);
|
||||
LazyScript* res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, lineno, column);
|
||||
MOZ_ASSERT_IF(res, res->version() == version);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* static */ LazyScript*
|
||||
LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
|
||||
HandleScript script, Handle<StaticFunctionScope*> funScope,
|
||||
HandleScript script, HandleObject enclosingScope,
|
||||
HandleScript sourceObjectScript,
|
||||
uint64_t packedFields, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column)
|
||||
|
@ -4378,8 +4335,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
|
|||
// holding this lazy script.
|
||||
HandleFunction dummyFun = fun;
|
||||
|
||||
LazyScript* res = LazyScript::CreateRaw(cx, fun, funScope, packedFields,
|
||||
begin, end, lineno, column);
|
||||
LazyScript* res = LazyScript::CreateRaw(cx, fun, packedFields, begin, end, lineno, column);
|
||||
if (!res)
|
||||
return nullptr;
|
||||
|
||||
|
@ -4397,7 +4353,7 @@ LazyScript::Create(ExclusiveContext* cx, HandleFunction fun,
|
|||
// Set the enclosing scope of the lazy function, this would later be
|
||||
// used to define the environment when the function would be used.
|
||||
MOZ_ASSERT(!res->sourceObject());
|
||||
res->initSource(&sourceObjectScript->scriptSourceUnwrap());
|
||||
res->setParent(enclosingScope, &sourceObjectScript->scriptSourceUnwrap());
|
||||
|
||||
MOZ_ASSERT(!res->hasScript());
|
||||
if (script)
|
||||
|
@ -4430,10 +4386,10 @@ LazyScript::hasUncompiledEnclosingScript() const
|
|||
// If the enclosing scope is a function with a null script or has a script
|
||||
// without code, it was not successfully compiled.
|
||||
|
||||
if (!enclosingScope() || !enclosingScope()->is<StaticFunctionScope>())
|
||||
if (!enclosingScope() || !enclosingScope()->is<JSFunction>())
|
||||
return false;
|
||||
|
||||
JSFunction& fun = enclosingScope()->as<StaticFunctionScope>().function();
|
||||
JSFunction& fun = enclosingScope()->as<JSFunction>();
|
||||
return !fun.hasScript() || fun.hasUncompiledScript() || !fun.nonLazyScript()->code();
|
||||
}
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ class LazyScript;
|
|||
class ModuleObject;
|
||||
class NestedStaticScope;
|
||||
class StaticScope;
|
||||
class StaticFunctionScope;
|
||||
class RegExpObject;
|
||||
struct SourceCompressionTask;
|
||||
class Shape;
|
||||
|
@ -67,8 +66,7 @@ namespace detail {
|
|||
// Do not call this directly! It is exposed for the friend declarations in
|
||||
// this file.
|
||||
bool
|
||||
CopyScript(JSContext* cx, Handle<StaticScope*> scriptStaticScope, HandleScript src,
|
||||
HandleScript dst);
|
||||
CopyScript(JSContext* cx, HandleObject scriptStaticScope, HandleScript src, HandleScript dst);
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
@ -148,7 +146,7 @@ struct BlockScopeArray {
|
|||
|
||||
class YieldOffsetArray {
|
||||
friend bool
|
||||
detail::CopyScript(JSContext* cx, Handle<StaticScope*> scriptStaticScope, HandleScript src,
|
||||
detail::CopyScript(JSContext* cx, HandleObject scriptStaticScope, HandleScript src,
|
||||
HandleScript dst);
|
||||
|
||||
uint32_t* vector_; // Array of bytecode offsets.
|
||||
|
@ -922,20 +920,20 @@ GeneratorKindFromBits(unsigned val) {
|
|||
* subsequent set-up of owning function or script object and then call
|
||||
* CallNewScriptHook.
|
||||
*/
|
||||
template <XDRMode mode>
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
HandleScript enclosingScript, HandleFunction fun, MutableHandleScript scriptp);
|
||||
XDRScript(XDRState<mode>* xdr, HandleObject enclosingScope, HandleScript enclosingScript,
|
||||
HandleFunction fun, MutableHandleScript scriptp);
|
||||
|
||||
template <XDRMode mode>
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRLazyScript(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
HandleScript enclosingScript, HandleFunction fun, MutableHandle<LazyScript*> lazy);
|
||||
XDRLazyScript(XDRState<mode>* xdr, HandleObject enclosingScope, HandleScript enclosingScript,
|
||||
HandleFunction fun, MutableHandle<LazyScript*> lazy);
|
||||
|
||||
/*
|
||||
* Code any constant value.
|
||||
*/
|
||||
template <XDRMode mode>
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRScriptConst(XDRState<mode>* xdr, MutableHandleValue vp);
|
||||
|
||||
|
@ -946,13 +944,13 @@ class JSScript : public js::gc::TenuredCell
|
|||
template <js::XDRMode mode>
|
||||
friend
|
||||
bool
|
||||
js::XDRScript(js::XDRState<mode>* xdr, js::Handle<js::StaticScope*> enclosingScope,
|
||||
js::XDRScript(js::XDRState<mode>* xdr, js::HandleObject enclosingScope,
|
||||
js::HandleScript enclosingScript,
|
||||
js::HandleFunction fun, js::MutableHandleScript scriptp);
|
||||
|
||||
friend bool
|
||||
js::detail::CopyScript(JSContext* cx, js::Handle<js::StaticScope*> scriptStaticScope,
|
||||
js::HandleScript src, js::HandleScript dst);
|
||||
js::detail::CopyScript(JSContext* cx, js::HandleObject scriptStaticScope, js::HandleScript src,
|
||||
js::HandleScript dst);
|
||||
|
||||
public:
|
||||
//
|
||||
|
@ -1006,22 +1004,7 @@ class JSScript : public js::gc::TenuredCell
|
|||
|
||||
js::HeapPtrFunction function_;
|
||||
js::HeapPtr<js::ModuleObject*> module_;
|
||||
|
||||
// The static scope this script runs in.
|
||||
//
|
||||
// Specifically, it depends on the case:
|
||||
//
|
||||
// * direct eval: staticScope_ is the StaticEvalScope for the eval call.
|
||||
//
|
||||
// * function script: staticScope_ is function_'s StaticFunctionScope.
|
||||
//
|
||||
// * module script: staticScope_ is module_'s StaticModuleScope.
|
||||
//
|
||||
// * plain old global script or indirect eval: staticScope_ is the static
|
||||
// global lexical scope (regardless of whether the script uses any
|
||||
// global lexical bindings).
|
||||
//
|
||||
js::HeapPtr<js::StaticScope*> staticScope_;
|
||||
js::HeapPtrObject enclosingStaticScope_;
|
||||
|
||||
/*
|
||||
* Information attached by Ion. Nexto a valid IonScript this could be
|
||||
|
@ -1229,7 +1212,7 @@ class JSScript : public js::gc::TenuredCell
|
|||
|
||||
public:
|
||||
static JSScript* Create(js::ExclusiveContext* cx,
|
||||
js::Handle<js::StaticScope*> staticScope, bool savedCallerFun,
|
||||
js::HandleObject enclosingScope, bool savedCallerFun,
|
||||
const JS::ReadOnlyCompileOptions& options,
|
||||
js::HandleObject sourceObject, uint32_t sourceStart,
|
||||
uint32_t sourceEnd);
|
||||
|
@ -1713,13 +1696,10 @@ class JSScript : public js::gc::TenuredCell
|
|||
inline js::GlobalObject& global() const;
|
||||
js::GlobalObject& uninlinedGlobal() const;
|
||||
|
||||
js::StaticScope* staticScope() const { return staticScope_; }
|
||||
|
||||
/*
|
||||
* The static scope this script runs in, skipping the StaticFunctionScope
|
||||
* if this is a non-eval function script.
|
||||
*/
|
||||
inline js::StaticScope* enclosingStaticScope() const;
|
||||
/* See StaticScopeIter comment. */
|
||||
JSObject* enclosingStaticScope() const {
|
||||
return enclosingStaticScope_;
|
||||
}
|
||||
|
||||
// Switch the script over from the off-thread compartment's static
|
||||
// global lexical scope to the main thread compartment's.
|
||||
|
@ -1883,13 +1863,13 @@ class JSScript : public js::gc::TenuredCell
|
|||
|
||||
// Returns the innermost static scope at pc if it falls within the extent
|
||||
// of the script. Returns nullptr otherwise.
|
||||
js::StaticScope* innermostStaticScopeInScript(jsbytecode* pc);
|
||||
JSObject* innermostStaticScopeInScript(jsbytecode* pc);
|
||||
|
||||
// As innermostStaticScopeInScript, but returns the enclosing static scope
|
||||
// if the innermost static scope falls without the extent of the script.
|
||||
js::StaticScope* innermostStaticScope(jsbytecode* pc);
|
||||
JSObject* innermostStaticScope(jsbytecode* pc);
|
||||
|
||||
js::StaticScope* innermostStaticScope() { return innermostStaticScope(main()); }
|
||||
JSObject* innermostStaticScope() { return innermostStaticScope(main()); }
|
||||
|
||||
/*
|
||||
* The isEmpty method tells whether this script has code that computes any
|
||||
|
@ -2152,9 +2132,8 @@ class LazyScript : public gc::TenuredCell
|
|||
// Original function with which the lazy script is associated.
|
||||
HeapPtrFunction function_;
|
||||
|
||||
// Static scope of this function. (All lazy scripts are for functions;
|
||||
// global scripts and eval scripts are never lazified.)
|
||||
HeapPtr<StaticFunctionScope*> staticScope_;
|
||||
// Function or block chain in which the script is nested, or nullptr.
|
||||
HeapPtrObject enclosingScope_;
|
||||
|
||||
// ScriptSourceObject. We leave this set to nullptr until we generate
|
||||
// bytecode for our immediate parent. This is never a CCW; we don't clone
|
||||
|
@ -2206,14 +2185,13 @@ class LazyScript : public gc::TenuredCell
|
|||
uint32_t lineno_;
|
||||
uint32_t column_;
|
||||
|
||||
LazyScript(JSFunction* fun, StaticFunctionScope* funScope, void* table, uint64_t packedFields,
|
||||
LazyScript(JSFunction* fun, void* table, uint64_t packedFields,
|
||||
uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column);
|
||||
|
||||
// Create a LazyScript without initializing the freeVariables and the
|
||||
// innerFunctions. To be GC-safe, the caller must initialize both vectors
|
||||
// with valid atoms and functions.
|
||||
static LazyScript* CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
||||
Handle<StaticFunctionScope*> funScope,
|
||||
uint64_t packedData, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
||||
|
@ -2222,7 +2200,6 @@ class LazyScript : public gc::TenuredCell
|
|||
// innerFunctions. To be GC-safe, the caller must initialize both vectors
|
||||
// with valid atoms and functions.
|
||||
static LazyScript* CreateRaw(ExclusiveContext* cx, HandleFunction fun,
|
||||
Handle<StaticFunctionScope*> funScope,
|
||||
uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
@ -2237,7 +2214,7 @@ class LazyScript : public gc::TenuredCell
|
|||
// The sourceObjectScript argument must be non-null and is the script that
|
||||
// should be used to get the sourceObject_ of this lazyScript.
|
||||
static LazyScript* Create(ExclusiveContext* cx, HandleFunction fun,
|
||||
HandleScript script, Handle<StaticFunctionScope*> funScope,
|
||||
HandleScript script, HandleObject enclosingScope,
|
||||
HandleScript sourceObjectScript,
|
||||
uint64_t packedData, uint32_t begin, uint32_t end,
|
||||
uint32_t lineno, uint32_t column);
|
||||
|
@ -2262,8 +2239,9 @@ class LazyScript : public gc::TenuredCell
|
|||
return bool(script_);
|
||||
}
|
||||
|
||||
StaticFunctionScope* staticScope() const { return staticScope_; }
|
||||
StaticScope* enclosingScope() const;
|
||||
JSObject* enclosingScope() const {
|
||||
return enclosingScope_;
|
||||
}
|
||||
|
||||
// Switch the script over from the off-thread compartment's static
|
||||
// global lexical scope to the main thread compartment's.
|
||||
|
@ -2282,7 +2260,7 @@ class LazyScript : public gc::TenuredCell
|
|||
return (p_.version == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(p_.version);
|
||||
}
|
||||
|
||||
void initSource(ScriptSourceObject* sourceObject);
|
||||
void setParent(JSObject* enclosingScope, ScriptSourceObject* sourceObject);
|
||||
|
||||
uint32_t numFreeVariables() const {
|
||||
return p_.numFreeVariables;
|
||||
|
@ -2542,7 +2520,7 @@ DescribeScriptedCallerForCompilation(JSContext* cx, MutableHandleScript maybeScr
|
|||
LineOption opt = NOT_CALLED_FROM_JSOP_EVAL);
|
||||
|
||||
JSScript*
|
||||
CloneScriptIntoFunction(JSContext* cx, Handle<StaticScope*> enclosingScope, HandleFunction fun,
|
||||
CloneScriptIntoFunction(JSContext* cx, HandleObject enclosingScope, HandleFunction fun,
|
||||
HandleScript src);
|
||||
|
||||
JSScript*
|
||||
|
@ -2554,7 +2532,7 @@ CloneGlobalScript(JSContext* cx, Handle<StaticScope*> enclosingScope, HandleScri
|
|||
// with no associated compartment.
|
||||
namespace JS {
|
||||
namespace ubi {
|
||||
template <>
|
||||
template<>
|
||||
struct Concrete<js::LazyScript> : TracerConcrete<js::LazyScript> {
|
||||
CoarseType coarseType() const final { return CoarseType::Script; }
|
||||
Size size(mozilla::MallocSizeOf mallocSizeOf) const override;
|
||||
|
|
|
@ -92,23 +92,8 @@ LazyScript::functionDelazifying(JSContext* cx) const
|
|||
return function_;
|
||||
}
|
||||
|
||||
inline StaticScope*
|
||||
LazyScript::enclosingScope() const
|
||||
{
|
||||
return staticScope_->enclosingScope();
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
inline js::StaticScope*
|
||||
JSScript::enclosingStaticScope() const
|
||||
{
|
||||
// The static scope of a function script is the function scope (which
|
||||
// contains arguments and local variables). This method's callers want to
|
||||
// skip that scope.
|
||||
return function_ ? staticScope_->enclosingScope() : staticScope_;
|
||||
}
|
||||
|
||||
inline JSFunction*
|
||||
JSScript::functionDelazifying() const
|
||||
{
|
||||
|
|
|
@ -4675,8 +4675,6 @@ DumpStaticScopeChain(JSContext* cx, unsigned argc, Value* vp)
|
|||
return false;
|
||||
}
|
||||
script = fun->getOrCreateScript(cx);
|
||||
if (!script)
|
||||
return false;
|
||||
} else {
|
||||
script = obj->as<ModuleObject>().script();
|
||||
}
|
||||
|
|
|
@ -927,8 +927,9 @@ js::TypeOfValue(const Value& v)
|
|||
*/
|
||||
bool
|
||||
js::EnterWithOperation(JSContext* cx, AbstractFramePtr frame, HandleValue val,
|
||||
Handle<StaticWithScope*> staticWith)
|
||||
HandleObject staticWith)
|
||||
{
|
||||
MOZ_ASSERT(staticWith->is<StaticWithScope>());
|
||||
RootedObject obj(cx);
|
||||
if (val.isObject()) {
|
||||
obj = &val.toObject();
|
||||
|
@ -1038,8 +1039,8 @@ SettleOnTryNote(JSContext* cx, JSTryNote* tn, ScopeIter& si, InterpreterRegs& re
|
|||
// Unwind the scope to the beginning of the JSOP_TRY.
|
||||
UnwindScope(cx, si, UnwindScopeToTryPc(regs.fp()->script(), tn));
|
||||
|
||||
// Set pc to the first bytecode after the span of the try note, the
|
||||
// beginning of the first catch or finally block.
|
||||
// Set pc to the first bytecode after the the try note to point
|
||||
// to the beginning of catch or finally.
|
||||
regs.pc = regs.fp()->script()->main() + tn->start + tn->length;
|
||||
regs.sp = regs.spForStackDepth(tn->stackDepth);
|
||||
}
|
||||
|
@ -1493,9 +1494,6 @@ class ReservedRooted : public ReservedRootedBase<T>
|
|||
operator Rooted<T>&() { return *savedRoot; }
|
||||
MutableHandle<T> operator&() { return &*savedRoot; }
|
||||
|
||||
template <typename U>
|
||||
Handle<U*> as() { return savedRoot->template as<U>(); }
|
||||
|
||||
DECLARE_NONPOINTER_ACCESSOR_METHODS(savedRoot->get())
|
||||
DECLARE_NONPOINTER_MUTABLE_ACCESSOR_METHODS(savedRoot->get())
|
||||
DECLARE_POINTER_CONSTREF_OPS(T)
|
||||
|
@ -1875,7 +1873,7 @@ CASE(JSOP_ENTERWITH)
|
|||
REGS.sp--;
|
||||
ReservedRooted<JSObject*> staticWith(&rootObject0, script->getObject(REGS.pc));
|
||||
|
||||
if (!EnterWithOperation(cx, REGS.fp(), val, staticWith.as<StaticWithScope>()))
|
||||
if (!EnterWithOperation(cx, REGS.fp(), val, staticWith))
|
||||
goto error;
|
||||
}
|
||||
END_CASE(JSOP_ENTERWITH)
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
namespace js {
|
||||
|
||||
class ScopeIter;
|
||||
class StaticWithScope;
|
||||
|
||||
/*
|
||||
* For a given |call|, convert null/undefined |this| into the global object for
|
||||
|
@ -429,8 +428,8 @@ unsigned
|
|||
GetInitDataPropAttrs(JSOp op);
|
||||
|
||||
bool
|
||||
EnterWithOperation(JSContext* cx, AbstractFramePtr frame, HandleValue val,
|
||||
Handle<StaticWithScope*> staticWith);
|
||||
EnterWithOperation(JSContext* cx, AbstractFramePtr frame, HandleValue val, HandleObject staticWith);
|
||||
|
||||
|
||||
bool
|
||||
InitGetterSetterOperation(JSContext* cx, jsbytecode* pc, HandleObject obj, HandleValue idval,
|
||||
|
|
|
@ -84,39 +84,49 @@ template <AllowGC allowGC>
|
|||
inline void
|
||||
StaticScopeIter<allowGC>::operator++(int)
|
||||
{
|
||||
if (!scope->template is<StaticFunctionScope>()) {
|
||||
scope = scope->enclosingScope();
|
||||
} else if (onNamedLambda || !scope->template as<StaticFunctionScope>().isNamedLambda()) {
|
||||
if (obj->template is<NestedStaticScope>()) {
|
||||
obj = obj->template as<NestedStaticScope>().enclosingScope();
|
||||
} else if (obj->template is<StaticEvalScope>()) {
|
||||
obj = obj->template as<StaticEvalScope>().enclosingScope();
|
||||
} else if (obj->template is<StaticNonSyntacticScope>()) {
|
||||
obj = obj->template as<StaticNonSyntacticScope>().enclosingScope();
|
||||
} else if (obj->template is<ModuleObject>()) {
|
||||
obj = obj->template as<ModuleObject>().enclosingStaticScope();
|
||||
} else if (onNamedLambda || !obj->template as<JSFunction>().isNamedLambda()) {
|
||||
onNamedLambda = false;
|
||||
scope = scope->enclosingScope();
|
||||
JSFunction& fun = obj->template as<JSFunction>();
|
||||
if (fun.isBeingParsed())
|
||||
obj = fun.functionBox()->enclosingStaticScope();
|
||||
else
|
||||
obj = fun.nonLazyScript()->enclosingStaticScope();
|
||||
} else {
|
||||
onNamedLambda = true;
|
||||
}
|
||||
MOZ_ASSERT_IF(scope, scope->template is<StaticScope>());
|
||||
MOZ_ASSERT_IF(onNamedLambda, scope->template is<StaticFunctionScope>());
|
||||
MOZ_ASSERT_IF(obj, IsStaticScope(obj));
|
||||
MOZ_ASSERT_IF(onNamedLambda, obj->template is<JSFunction>());
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline bool
|
||||
StaticScopeIter<allowGC>::hasSyntacticDynamicScopeObject() const
|
||||
{
|
||||
if (scope->template is<StaticFunctionScope>()) {
|
||||
JSFunction& fun = scope->template as<StaticFunctionScope>().function();
|
||||
if (obj->template is<JSFunction>()) {
|
||||
JSFunction& fun = obj->template as<JSFunction>();
|
||||
if (fun.isBeingParsed())
|
||||
return fun.functionBox()->needsCallObject();
|
||||
return fun.needsCallObject();
|
||||
}
|
||||
if (scope->template is<StaticModuleScope>())
|
||||
if (obj->template is<ModuleObject>())
|
||||
return true;
|
||||
if (scope->template is<StaticBlockScope>()) {
|
||||
return scope->template as<StaticBlockScope>().needsClone() ||
|
||||
scope->template as<StaticBlockScope>().isGlobal();
|
||||
if (obj->template is<StaticBlockScope>()) {
|
||||
return obj->template as<StaticBlockScope>().needsClone() ||
|
||||
obj->template as<StaticBlockScope>().isGlobal();
|
||||
}
|
||||
if (scope->template is<StaticWithScope>())
|
||||
if (obj->template is<StaticWithScope>())
|
||||
return true;
|
||||
if (scope->template is<StaticEvalScope>())
|
||||
return scope->template as<StaticEvalScope>().isStrict();
|
||||
MOZ_ASSERT(scope->template is<StaticNonSyntacticScope>());
|
||||
if (obj->template is<StaticEvalScope>())
|
||||
return obj->template as<StaticEvalScope>().isStrict();
|
||||
MOZ_ASSERT(obj->template is<StaticNonSyntacticScope>());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -129,8 +139,8 @@ StaticScopeIter<allowGC>::scopeShape() const
|
|||
if (type() == Block)
|
||||
return block().lastProperty();
|
||||
if (type() == Module)
|
||||
return module().environmentShape();
|
||||
return fun().environmentShape();
|
||||
return moduleScript()->callObjShape();
|
||||
return funScript()->callObjShape();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
|
@ -139,17 +149,17 @@ StaticScopeIter<allowGC>::type() const
|
|||
{
|
||||
if (onNamedLambda)
|
||||
return NamedLambda;
|
||||
if (scope->template is<StaticBlockScope>())
|
||||
if (obj->template is<StaticBlockScope>())
|
||||
return Block;
|
||||
if (scope->template is<StaticModuleScope>())
|
||||
return Module;
|
||||
if (scope->template is<StaticWithScope>())
|
||||
if (obj->template is<StaticWithScope>())
|
||||
return With;
|
||||
if (scope->template is<StaticEvalScope>())
|
||||
if (obj->template is<StaticEvalScope>())
|
||||
return Eval;
|
||||
if (scope->template is<StaticNonSyntacticScope>())
|
||||
if (obj->template is<StaticNonSyntacticScope>())
|
||||
return NonSyntactic;
|
||||
MOZ_ASSERT(scope->template is<StaticFunctionScope>());
|
||||
if (obj->template is<ModuleObject>())
|
||||
return Module;
|
||||
MOZ_ASSERT(obj->template is<JSFunction>());
|
||||
return Function;
|
||||
}
|
||||
|
||||
|
@ -158,7 +168,7 @@ inline StaticBlockScope&
|
|||
StaticScopeIter<allowGC>::block() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Block);
|
||||
return scope->template as<StaticBlockScope>();
|
||||
return obj->template as<StaticBlockScope>();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
|
@ -166,7 +176,7 @@ inline StaticWithScope&
|
|||
StaticScopeIter<allowGC>::staticWith() const
|
||||
{
|
||||
MOZ_ASSERT(type() == With);
|
||||
return scope->template as<StaticWithScope>();
|
||||
return obj->template as<StaticWithScope>();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
|
@ -174,7 +184,7 @@ inline StaticEvalScope&
|
|||
StaticScopeIter<allowGC>::eval() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Eval);
|
||||
return scope->template as<StaticEvalScope>();
|
||||
return obj->template as<StaticEvalScope>();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
|
@ -182,7 +192,7 @@ inline StaticNonSyntacticScope&
|
|||
StaticScopeIter<allowGC>::nonSyntactic() const
|
||||
{
|
||||
MOZ_ASSERT(type() == NonSyntactic);
|
||||
return scope->template as<StaticNonSyntacticScope>();
|
||||
return obj->template as<StaticNonSyntacticScope>();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
|
@ -190,15 +200,15 @@ inline JSScript*
|
|||
StaticScopeIter<allowGC>::funScript() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Function);
|
||||
return scope->template as<StaticFunctionScope>().function().nonLazyScript();
|
||||
return obj->template as<JSFunction>().nonLazyScript();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline StaticFunctionScope&
|
||||
inline JSFunction&
|
||||
StaticScopeIter<allowGC>::fun() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Function);
|
||||
return scope->template as<StaticFunctionScope>();
|
||||
return obj->template as<JSFunction>();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
|
@ -206,17 +216,25 @@ inline frontend::FunctionBox*
|
|||
StaticScopeIter<allowGC>::maybeFunctionBox() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Function);
|
||||
if (fun().function().isBeingParsed())
|
||||
return fun().function().functionBox();
|
||||
if (fun().isBeingParsed())
|
||||
return fun().functionBox();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline StaticModuleScope&
|
||||
inline JSScript*
|
||||
StaticScopeIter<allowGC>::moduleScript() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Module);
|
||||
return obj->template as<ModuleObject>().script();
|
||||
}
|
||||
|
||||
template <AllowGC allowGC>
|
||||
inline ModuleObject&
|
||||
StaticScopeIter<allowGC>::module() const
|
||||
{
|
||||
MOZ_ASSERT(type() == Module);
|
||||
return scope->template as<StaticModuleScope>();
|
||||
return obj->template as<ModuleObject>();
|
||||
}
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -233,8 +251,7 @@ JSObject::enclosingScope()
|
|||
if (is<js::GlobalObject>())
|
||||
return nullptr;
|
||||
|
||||
MOZ_ASSERT(!is<JSFunction>());
|
||||
MOZ_ASSERT(!is<js::StaticScope>());
|
||||
MOZ_ASSERT_IF(is<JSFunction>(), as<JSFunction>().isInterpreted());
|
||||
return &global();
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@ typedef MutableHandle<ArgumentsObject*> MutableHandleArgumentsObject;
|
|||
/*** Static scope objects ************************************************************************/
|
||||
|
||||
void
|
||||
StaticScope::setEnclosingScope(StaticScope* scope)
|
||||
StaticScope::setEnclosingScope(HandleObject obj)
|
||||
{
|
||||
MOZ_ASSERT_IF(scope->is<StaticBlockScope>(), scope->isDelegate());
|
||||
setFixedSlot(ENCLOSING_SCOPE_SLOT, ObjectValue(*scope));
|
||||
MOZ_ASSERT_IF(obj->is<StaticBlockScope>(), obj->isDelegate());
|
||||
setFixedSlot(ENCLOSING_SCOPE_SLOT, ObjectValue(*obj));
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -118,63 +118,6 @@ StaticBlockScope::addVar(ExclusiveContext* cx, Handle<StaticBlockScope*> block,
|
|||
/* allowDictionary = */ false);
|
||||
}
|
||||
|
||||
const Class StaticFunctionScope::class_ = {
|
||||
"StaticFunctionScope",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(StaticFunctionScope::RESERVED_SLOTS) |
|
||||
JSCLASS_IS_ANONYMOUS
|
||||
};
|
||||
|
||||
StaticFunctionScope*
|
||||
StaticFunctionScope::create(ExclusiveContext* cx, Handle<JSFunction*> functionObject,
|
||||
Handle<StaticScope*> enclosingScope)
|
||||
{
|
||||
Rooted<TaggedProto> proto(cx, TaggedProto(nullptr));
|
||||
JSObject* obj = NewObjectWithGivenTaggedProto(cx, &class_, proto, TenuredObject,
|
||||
BaseShape::DELEGATE);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
StaticFunctionScope* scope = &obj->as<StaticFunctionScope>();
|
||||
scope->initEnclosingScope(enclosingScope);
|
||||
scope->setReservedSlot(FUNCTION_OBJECT_SLOT, ObjectValue(*functionObject));
|
||||
return scope;
|
||||
}
|
||||
|
||||
StaticModuleScope*
|
||||
StaticModuleScope::create(ExclusiveContext* cx, Handle<ModuleObject*> moduleObject,
|
||||
Handle<StaticScope*> enclosingScope)
|
||||
{
|
||||
Rooted<TaggedProto> nullProto(cx, TaggedProto(nullptr));
|
||||
JSObject* obj = NewObjectWithGivenTaggedProto(cx, &ModuleEnvironmentObject::class_, nullProto,
|
||||
TenuredObject, BaseShape::DELEGATE);
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
StaticModuleScope* scope = &obj->as<StaticModuleScope>();
|
||||
scope->initEnclosingScope(enclosingScope);
|
||||
scope->setReservedSlot(MODULE_OBJECT_SLOT, ObjectValue(*moduleObject));
|
||||
return scope;
|
||||
}
|
||||
|
||||
ModuleObject&
|
||||
StaticModuleScope::moduleObject()
|
||||
{
|
||||
return getReservedSlot(MODULE_OBJECT_SLOT).toObject().as<ModuleObject>();
|
||||
}
|
||||
|
||||
JSScript*
|
||||
StaticModuleScope::script()
|
||||
{
|
||||
return moduleObject().script();
|
||||
}
|
||||
|
||||
Shape*
|
||||
StaticModuleScope::environmentShape()
|
||||
{
|
||||
ModuleObject* module = &getReservedSlot(MODULE_OBJECT_SLOT).toObject().as<ModuleObject>();
|
||||
return module->script()->bindings.callObjShape();
|
||||
}
|
||||
|
||||
const Class StaticWithScope::class_ = {
|
||||
"WithTemplate",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(StaticWithScope::RESERVED_SLOTS) |
|
||||
|
@ -189,7 +132,7 @@ StaticWithScope::create(ExclusiveContext* cx)
|
|||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
js::XDRStaticWithScope(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
js::XDRStaticWithScope(XDRState<mode>* xdr, HandleObject enclosingScope,
|
||||
MutableHandle<StaticWithScope*> objp)
|
||||
{
|
||||
if (mode == XDR_DECODE) {
|
||||
|
@ -208,12 +151,10 @@ js::XDRStaticWithScope(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
|||
}
|
||||
|
||||
template bool
|
||||
js::XDRStaticWithScope(XDRState<XDR_ENCODE>*, Handle<StaticScope*>,
|
||||
MutableHandle<StaticWithScope*>);
|
||||
js::XDRStaticWithScope(XDRState<XDR_ENCODE>*, HandleObject, MutableHandle<StaticWithScope*>);
|
||||
|
||||
template bool
|
||||
js::XDRStaticWithScope(XDRState<XDR_DECODE>*, Handle<StaticScope*>,
|
||||
MutableHandle<StaticWithScope*>);
|
||||
js::XDRStaticWithScope(XDRState<XDR_DECODE>*, HandleObject, MutableHandle<StaticWithScope*>);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -499,9 +440,6 @@ const Class CallObject::class_ = {
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static_assert(StaticModuleScope::RESERVED_SLOTS == ModuleEnvironmentObject::RESERVED_SLOTS,
|
||||
"static module scopes and dynamic module environments share a Class");
|
||||
|
||||
const Class ModuleEnvironmentObject::class_ = {
|
||||
"ModuleEnvironmentObject",
|
||||
JSCLASS_HAS_RESERVED_SLOTS(ModuleEnvironmentObject::RESERVED_SLOTS) |
|
||||
|
@ -542,8 +480,7 @@ ModuleEnvironmentObject::create(ExclusiveContext* cx, HandleModuleObject module)
|
|||
RootedShape shape(cx, script->bindings.callObjShape());
|
||||
MOZ_ASSERT(shape->getObjectClass() == &class_);
|
||||
|
||||
Rooted<TaggedProto> proto(cx, module->staticScope());
|
||||
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, &class_, proto));
|
||||
RootedObjectGroup group(cx, ObjectGroup::defaultNewGroup(cx, &class_, TaggedProto(nullptr)));
|
||||
if (!group)
|
||||
return nullptr;
|
||||
|
||||
|
@ -588,12 +525,6 @@ ModuleEnvironmentObject::module()
|
|||
return getReservedSlot(MODULE_SLOT).toObject().as<ModuleObject>();
|
||||
}
|
||||
|
||||
StaticModuleScope&
|
||||
ModuleEnvironmentObject::staticScope()
|
||||
{
|
||||
return getProto()->as<StaticModuleScope>();
|
||||
}
|
||||
|
||||
IndirectBindingMap&
|
||||
ModuleEnvironmentObject::importBindings()
|
||||
{
|
||||
|
@ -789,9 +720,8 @@ DeclEnvObject::create(JSContext* cx, HandleObject enclosing, HandleFunction call
|
|||
return obj;
|
||||
}
|
||||
|
||||
static StaticWithScope*
|
||||
CloneStaticWithScope(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
||||
Handle<StaticWithScope*> srcWith)
|
||||
static JSObject*
|
||||
CloneStaticWithScope(JSContext* cx, HandleObject enclosingScope, Handle<StaticWithScope*> srcWith)
|
||||
{
|
||||
Rooted<StaticWithScope*> clone(cx, StaticWithScope::create(cx));
|
||||
if (!clone)
|
||||
|
@ -804,8 +734,10 @@ CloneStaticWithScope(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
|||
|
||||
DynamicWithObject*
|
||||
DynamicWithObject::create(JSContext* cx, HandleObject object, HandleObject enclosing,
|
||||
Handle<StaticWithScope*> staticWith, WithKind kind)
|
||||
HandleObject staticWith, WithKind kind)
|
||||
{
|
||||
MOZ_ASSERT(staticWith->is<StaticWithScope>());
|
||||
|
||||
Rooted<TaggedProto> proto(cx, TaggedProto(staticWith));
|
||||
Rooted<DynamicWithObject*> obj(cx);
|
||||
obj = NewObjectWithGivenTaggedProto<DynamicWithObject>(cx, proto, GenericObject,
|
||||
|
@ -928,16 +860,16 @@ const Class DynamicWithObject::class_ = {
|
|||
};
|
||||
|
||||
/* static */ StaticEvalScope*
|
||||
StaticEvalScope::create(JSContext* cx, Handle<StaticScope*> enclosing)
|
||||
StaticEvalScope::create(JSContext* cx, HandleObject enclosing)
|
||||
{
|
||||
StaticEvalScope* scope =
|
||||
StaticEvalScope* obj =
|
||||
NewObjectWithNullTaggedProto<StaticEvalScope>(cx, TenuredObject, BaseShape::DELEGATE);
|
||||
if (!scope)
|
||||
if (!obj)
|
||||
return nullptr;
|
||||
|
||||
scope->initEnclosingScope(enclosing);
|
||||
scope->setReservedSlot(STRICT_SLOT, BooleanValue(false));
|
||||
return scope;
|
||||
obj->setReservedSlot(ENCLOSING_SCOPE_SLOT, ObjectOrNullValue(enclosing));
|
||||
obj->setReservedSlot(STRICT_SLOT, BooleanValue(false));
|
||||
return obj;
|
||||
}
|
||||
|
||||
const Class StaticEvalScope::class_ = {
|
||||
|
@ -1061,10 +993,10 @@ ClonedBlockObject::createGlobal(JSContext* cx, Handle<GlobalObject*> global)
|
|||
}
|
||||
|
||||
/* static */ ClonedBlockObject*
|
||||
ClonedBlockObject::createNonSyntactic(JSContext* cx,
|
||||
Handle<StaticNonSyntacticScope*> enclosingStatic,
|
||||
ClonedBlockObject::createNonSyntactic(JSContext* cx, HandleObject enclosingStatic,
|
||||
HandleObject enclosingScope)
|
||||
{
|
||||
MOZ_ASSERT(enclosingStatic->is<StaticNonSyntacticScope>());
|
||||
MOZ_ASSERT(!IsSyntacticScope(enclosingScope));
|
||||
|
||||
Rooted<StaticBlockScope*> staticLexical(cx, StaticBlockScope::create(cx));
|
||||
|
@ -1183,7 +1115,7 @@ const Class ClonedBlockObject::class_ = {
|
|||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
js::XDRStaticBlockScope(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
js::XDRStaticBlockScope(XDRState<mode>* xdr, HandleObject enclosingScope,
|
||||
MutableHandle<StaticBlockScope*> objp)
|
||||
{
|
||||
/* NB: Keep this in sync with CloneStaticBlockScope. */
|
||||
|
@ -1289,16 +1221,13 @@ js::XDRStaticBlockScope(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope
|
|||
}
|
||||
|
||||
template bool
|
||||
js::XDRStaticBlockScope(XDRState<XDR_ENCODE>*, Handle<StaticScope*>,
|
||||
MutableHandle<StaticBlockScope*>);
|
||||
js::XDRStaticBlockScope(XDRState<XDR_ENCODE>*, HandleObject, MutableHandle<StaticBlockScope*>);
|
||||
|
||||
template bool
|
||||
js::XDRStaticBlockScope(XDRState<XDR_DECODE>*, Handle<StaticScope*>,
|
||||
MutableHandle<StaticBlockScope*>);
|
||||
js::XDRStaticBlockScope(XDRState<XDR_DECODE>*, HandleObject, MutableHandle<StaticBlockScope*>);
|
||||
|
||||
static StaticBlockScope*
|
||||
CloneStaticBlockScope(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
||||
Handle<StaticBlockScope*> srcBlock)
|
||||
static JSObject*
|
||||
CloneStaticBlockScope(JSContext* cx, HandleObject enclosingScope, Handle<StaticBlockScope*> srcBlock)
|
||||
{
|
||||
/* NB: Keep this in sync with XDRStaticBlockScope. */
|
||||
|
||||
|
@ -1339,16 +1268,16 @@ CloneStaticBlockScope(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
|||
return clone;
|
||||
}
|
||||
|
||||
NestedStaticScope*
|
||||
js::CloneNestedScopeObject(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
||||
JSObject*
|
||||
js::CloneNestedScopeObject(JSContext* cx, HandleObject enclosingScope,
|
||||
Handle<NestedStaticScope*> srcBlock)
|
||||
{
|
||||
if (srcBlock->is<StaticBlockScope>()) {
|
||||
return CloneStaticBlockScope(cx, enclosingScope,
|
||||
HandleObject(srcBlock).as<StaticBlockScope>());
|
||||
Rooted<StaticBlockScope*> blockScope(cx, &srcBlock->as<StaticBlockScope>());
|
||||
return CloneStaticBlockScope(cx, enclosingScope, blockScope);
|
||||
} else {
|
||||
return CloneStaticWithScope(cx, enclosingScope,
|
||||
HandleObject(srcBlock).as<StaticWithScope>());
|
||||
Rooted<StaticWithScope*> withScope(cx, &srcBlock->as<StaticWithScope>());
|
||||
return CloneStaticWithScope(cx, enclosingScope, withScope);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1474,7 +1403,7 @@ ScopeIter::ScopeIter(JSContext* cx, const ScopeIter& si
|
|||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||
}
|
||||
|
||||
ScopeIter::ScopeIter(JSContext* cx, JSObject* scope, StaticScope* staticScope
|
||||
ScopeIter::ScopeIter(JSContext* cx, JSObject* scope, JSObject* staticScope
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
|
||||
: ssi_(cx, staticScope),
|
||||
scope_(cx, scope),
|
||||
|
@ -1559,7 +1488,7 @@ ScopeIter::settle()
|
|||
if (!ssi_.done() && hasAnyScopeObject()) {
|
||||
switch (ssi_.type()) {
|
||||
case StaticScopeIter<CanGC>::Module:
|
||||
MOZ_ASSERT(scope_->as<ModuleEnvironmentObject>().staticScope() == ssi_.module());
|
||||
MOZ_ASSERT(scope_->as<ModuleEnvironmentObject>().module() == ssi_.module());
|
||||
break;
|
||||
case StaticScopeIter<CanGC>::Function:
|
||||
MOZ_ASSERT(scope_->as<CallObject>().callee().nonLazyScript() == ssi_.funScript());
|
||||
|
@ -1630,7 +1559,7 @@ ScopeIter::scope() const
|
|||
return scope_->as<ScopeObject>();
|
||||
}
|
||||
|
||||
StaticScope*
|
||||
JSObject*
|
||||
ScopeIter::maybeStaticScope() const
|
||||
{
|
||||
if (ssi_.done())
|
||||
|
@ -1638,12 +1567,17 @@ ScopeIter::maybeStaticScope() const
|
|||
|
||||
switch (ssi_.type()) {
|
||||
case StaticScopeIter<CanGC>::Function:
|
||||
return &fun();
|
||||
case StaticScopeIter<CanGC>::Module:
|
||||
return &module();
|
||||
case StaticScopeIter<CanGC>::Block:
|
||||
return &staticBlock();
|
||||
case StaticScopeIter<CanGC>::With:
|
||||
return &staticWith();
|
||||
case StaticScopeIter<CanGC>::Eval:
|
||||
return &staticEval();
|
||||
case StaticScopeIter<CanGC>::NonSyntactic:
|
||||
return ssi_.staticScope();
|
||||
return &staticNonSyntactic();
|
||||
case StaticScopeIter<CanGC>::NamedLambda:
|
||||
MOZ_CRASH("named lambda static scopes should have been skipped");
|
||||
default:
|
||||
|
@ -2651,7 +2585,7 @@ DebugScopes::addDebugScope(JSContext* cx, const ScopeIter& si, DebugScopeObject&
|
|||
MOZ_ASSERT(!si.hasSyntacticScopeObject());
|
||||
MOZ_ASSERT(cx->compartment() == debugScope.compartment());
|
||||
// Generators should always reify their scopes.
|
||||
MOZ_ASSERT_IF(si.type() == ScopeIter::Call, !si.fun().function().isGenerator());
|
||||
MOZ_ASSERT_IF(si.type() == ScopeIter::Call, !si.fun().isGenerator());
|
||||
|
||||
if (!CanUseDebugScopeMaps(cx))
|
||||
return true;
|
||||
|
@ -3009,8 +2943,7 @@ GetDebugScopeForMissing(JSContext* cx, const ScopeIter& si)
|
|||
break;
|
||||
|
||||
case ScopeIter::Call: {
|
||||
RootedFunction callee(cx, &si.fun().function());
|
||||
|
||||
RootedFunction callee(cx, &si.fun());
|
||||
// Generators should always reify their scopes.
|
||||
MOZ_ASSERT(!callee->isGenerator());
|
||||
|
||||
|
@ -3167,7 +3100,7 @@ js::CreateScopeObjectsForScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
|
|||
// Construct With object wrappers for the things on this scope
|
||||
// chain and use the result as the thing to scope the function to.
|
||||
Rooted<StaticWithScope*> staticWith(cx);
|
||||
Rooted<StaticWithScope*> staticEnclosingScope(cx);
|
||||
RootedObject staticEnclosingScope(cx);
|
||||
Rooted<DynamicWithObject*> dynamicWith(cx);
|
||||
RootedObject dynamicEnclosingScope(cx, dynamicTerminatingScope);
|
||||
for (size_t i = scopeChain.length(); i > 0; ) {
|
||||
|
@ -3189,7 +3122,7 @@ js::CreateScopeObjectsForScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
|
|||
}
|
||||
|
||||
bool
|
||||
js::HasNonSyntacticStaticScopeChain(StaticScope* staticScope)
|
||||
js::HasNonSyntacticStaticScopeChain(JSObject* staticScope)
|
||||
{
|
||||
for (StaticScopeIter<NoGC> ssi(staticScope); !ssi.done(); ssi++) {
|
||||
// If we hit a function scope, we can short circuit the logic, as
|
||||
|
@ -3203,7 +3136,7 @@ js::HasNonSyntacticStaticScopeChain(StaticScope* staticScope)
|
|||
}
|
||||
|
||||
uint32_t
|
||||
js::StaticScopeChainLength(StaticScope* staticScope)
|
||||
js::StaticScopeChainLength(JSObject* staticScope)
|
||||
{
|
||||
uint32_t length = 0;
|
||||
for (StaticScopeIter<NoGC> ssi(staticScope); !ssi.done(); ssi++)
|
||||
|
@ -3220,7 +3153,7 @@ js::GetModuleEnvironmentForScript(JSScript* script)
|
|||
if (ssi.done())
|
||||
return nullptr;
|
||||
|
||||
return ssi.module().moduleObject().environment();
|
||||
return ssi.module().environment();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -3233,10 +3166,10 @@ js::GetThisValueForDebuggerMaybeOptimizedOut(JSContext* cx, AbstractFramePtr fra
|
|||
return true;
|
||||
}
|
||||
|
||||
if (si.type() != ScopeIter::Call || si.fun().function().hasLexicalThis())
|
||||
if (si.type() != ScopeIter::Call || si.fun().hasLexicalThis())
|
||||
continue;
|
||||
|
||||
RootedScript script(cx, si.fun().function().nonLazyScript());
|
||||
RootedScript script(cx, si.fun().nonLazyScript());
|
||||
|
||||
if (!script->functionHasThisBinding()) {
|
||||
MOZ_ASSERT(!script->isDerivedClassConstructor(),
|
||||
|
@ -3420,11 +3353,11 @@ js::CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
|
|||
void
|
||||
js::DumpStaticScopeChain(JSScript* script)
|
||||
{
|
||||
DumpStaticScopeChain(script->staticScope());
|
||||
DumpStaticScopeChain(script->enclosingStaticScope());
|
||||
}
|
||||
|
||||
void
|
||||
js::DumpStaticScopeChain(StaticScope* staticScope)
|
||||
js::DumpStaticScopeChain(JSObject* staticScope)
|
||||
{
|
||||
for (StaticScopeIter<NoGC> ssi(staticScope); !ssi.done(); ssi++) {
|
||||
switch (ssi.type()) {
|
||||
|
@ -3432,12 +3365,10 @@ js::DumpStaticScopeChain(StaticScope* staticScope)
|
|||
fprintf(stdout, "module [%p]", &ssi.module());
|
||||
break;
|
||||
case StaticScopeIter<NoGC>::Function:
|
||||
if (ssi.fun().function().isBeingParsed()) {
|
||||
fprintf(stdout, "funbox [%p box=%p fun=%p]",
|
||||
&ssi.fun(), ssi.maybeFunctionBox(), &ssi.fun().function());
|
||||
} else {
|
||||
fprintf(stdout, "function [%p fun=%p]", &ssi.fun(), &ssi.fun().function());
|
||||
}
|
||||
if (ssi.fun().isBeingParsed())
|
||||
fprintf(stdout, "funbox [%p fun=%p]", ssi.maybeFunctionBox(), &ssi.fun());
|
||||
else
|
||||
fprintf(stdout, "function [%p]", &ssi.fun());
|
||||
break;
|
||||
case StaticScopeIter<NoGC>::Block:
|
||||
fprintf(stdout, "block [%p]", &ssi.block());
|
||||
|
|
|
@ -50,11 +50,11 @@ typedef Handle<ModuleObject*> HandleModuleObject;
|
|||
* StaticBlockScope
|
||||
* Scope for non-function body blocks. e.g., |{ let x; }|
|
||||
*
|
||||
* StaticFunctionScope
|
||||
* JSFunction
|
||||
* Scope for function bodies. e.g., |function f() { var x; let y; }|
|
||||
*
|
||||
* StaticModuleScope
|
||||
* Scope for modules.
|
||||
* ModuleObject
|
||||
* Scope for moddules.
|
||||
*
|
||||
* StaticWithScope
|
||||
* Scope for |with|. e.g., |with ({}) { ... }|
|
||||
|
@ -82,14 +82,16 @@ class StaticScope : public NativeObject
|
|||
static const uint32_t ENCLOSING_SCOPE_SLOT = 0;
|
||||
static const unsigned RESERVED_SLOTS = ENCLOSING_SCOPE_SLOT + 1;
|
||||
|
||||
inline StaticScope* enclosingScope() const;
|
||||
|
||||
void initEnclosingScope(StaticScope* scope) {
|
||||
MOZ_ASSERT(getReservedSlot(ENCLOSING_SCOPE_SLOT).isUndefined());
|
||||
setReservedSlot(ENCLOSING_SCOPE_SLOT, ObjectOrNullValue(scope));
|
||||
inline JSObject* enclosingScope() const {
|
||||
return getFixedSlot(ENCLOSING_SCOPE_SLOT).toObjectOrNull();
|
||||
}
|
||||
|
||||
void setEnclosingScope(StaticScope* obj);
|
||||
void initEnclosingScope(JSObject* obj) {
|
||||
MOZ_ASSERT(getReservedSlot(ENCLOSING_SCOPE_SLOT).isUndefined());
|
||||
setReservedSlot(ENCLOSING_SCOPE_SLOT, ObjectOrNullValue(obj));
|
||||
}
|
||||
|
||||
void setEnclosingScope(HandleObject obj);
|
||||
};
|
||||
|
||||
class NestedStaticScope : public StaticScope
|
||||
|
@ -107,7 +109,7 @@ class NestedStaticScope : public StaticScope
|
|||
* called separately in the emitter. 'reset' is just for asserting
|
||||
* stackiness.
|
||||
*/
|
||||
void initEnclosingScopeFromParser(StaticScope* prev) {
|
||||
void initEnclosingScopeFromParser(JSObject* prev) {
|
||||
setReservedSlot(ENCLOSING_SCOPE_SLOT, ObjectOrNullValue(prev));
|
||||
}
|
||||
|
||||
|
@ -161,6 +163,11 @@ class StaticBlockScope : public NestedStaticScope
|
|||
*/
|
||||
bool isExtensible() const;
|
||||
|
||||
/* See StaticScopeIter comment. */
|
||||
JSObject* enclosingStaticScope() const {
|
||||
return getFixedSlot(ENCLOSING_SCOPE_SLOT).toObjectOrNull();
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the index (in the range [0, numVariables()) corresponding to the
|
||||
* given shape of a block object.
|
||||
|
@ -173,7 +180,7 @@ class StaticBlockScope : public NestedStaticScope
|
|||
|
||||
/*
|
||||
* A refinement of enclosingStaticScope that returns nullptr if the enclosing
|
||||
* static scope is a StaticFunctionScope.
|
||||
* static scope is a JSFunction.
|
||||
*/
|
||||
inline StaticBlockScope* enclosingBlock() const;
|
||||
|
||||
|
@ -206,7 +213,7 @@ class StaticBlockScope : public NestedStaticScope
|
|||
|
||||
/*
|
||||
* A let binding is aliased if accessed lexically by nested functions or
|
||||
* dynamically through dynamic name lookup (eval, with, etc).
|
||||
* dynamically through dynamic name lookup (eval, with, function::, etc).
|
||||
*/
|
||||
bool isAliased(unsigned i) {
|
||||
return slotValue(i).isTrue();
|
||||
|
@ -225,10 +232,7 @@ class StaticBlockScope : public NestedStaticScope
|
|||
|
||||
// Is this the static global lexical scope?
|
||||
bool isGlobal() const {
|
||||
// This method is called from js::gc::MergeCompartments() on scopes
|
||||
// that may be otherwise unreachable (!) and whose enclosing scope slot
|
||||
// may be `undefined`.
|
||||
return getFixedSlot(ENCLOSING_SCOPE_SLOT).isNull();
|
||||
return !enclosingStaticScope();
|
||||
}
|
||||
|
||||
bool isSyntactic() const {
|
||||
|
@ -296,45 +300,6 @@ class StaticBlockScope : public NestedStaticScope
|
|||
bool constant, unsigned index, bool* redeclared);
|
||||
};
|
||||
|
||||
class StaticFunctionScope : public StaticScope
|
||||
{
|
||||
static const unsigned FUNCTION_OBJECT_SLOT = StaticScope::RESERVED_SLOTS;
|
||||
|
||||
public:
|
||||
static const unsigned RESERVED_SLOTS = FUNCTION_OBJECT_SLOT + 1;
|
||||
static const Class class_;
|
||||
|
||||
static StaticFunctionScope* create(ExclusiveContext* cx, HandleFunction functionObject,
|
||||
Handle<StaticScope*> enclosingScope);
|
||||
|
||||
JSFunction& function() {
|
||||
return getFixedSlot(FUNCTION_OBJECT_SLOT).toObject().as<JSFunction>();
|
||||
}
|
||||
|
||||
bool isNamedLambda() { return function().isNamedLambda(); }
|
||||
|
||||
Shape* environmentShape() {
|
||||
return function().nonLazyScript()->callObjShape();
|
||||
}
|
||||
};
|
||||
|
||||
// The top-level scope of a module.
|
||||
// Shares ModuleEnvironmentObject::class_.
|
||||
class StaticModuleScope : public StaticScope
|
||||
{
|
||||
static const unsigned MODULE_OBJECT_SLOT = StaticScope::RESERVED_SLOTS;
|
||||
|
||||
public:
|
||||
static const unsigned RESERVED_SLOTS = MODULE_OBJECT_SLOT + 1;
|
||||
|
||||
static StaticModuleScope* create(ExclusiveContext* cx, Handle<ModuleObject*> moduleObject,
|
||||
Handle<StaticScope*> enclosingScope);
|
||||
|
||||
ModuleObject& moduleObject();
|
||||
JSScript* script();
|
||||
Shape* environmentShape();
|
||||
};
|
||||
|
||||
// Represents the lexical scope of a 'with' statement.
|
||||
class StaticWithScope : public NestedStaticScope
|
||||
{
|
||||
|
@ -346,7 +311,7 @@ class StaticWithScope : public NestedStaticScope
|
|||
|
||||
template <XDRMode mode>
|
||||
bool
|
||||
XDRStaticWithScope(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
XDRStaticWithScope(XDRState<mode>* xdr, HandleObject enclosingScope,
|
||||
MutableHandle<StaticWithScope*> objp);
|
||||
|
||||
/*
|
||||
|
@ -362,7 +327,11 @@ class StaticEvalScope : public StaticScope
|
|||
public:
|
||||
static const Class class_;
|
||||
|
||||
static StaticEvalScope* create(JSContext* cx, Handle<StaticScope*> enclosing);
|
||||
static StaticEvalScope* create(JSContext* cx, HandleObject enclosing);
|
||||
|
||||
JSObject* enclosingScopeForStaticScopeIter() {
|
||||
return getReservedSlot(ENCLOSING_SCOPE_SLOT).toObjectOrNull();
|
||||
}
|
||||
|
||||
void setStrict() {
|
||||
setReservedSlot(STRICT_SLOT, BooleanValue(true));
|
||||
|
@ -489,51 +458,64 @@ class StaticNonSyntacticScope : public StaticScope
|
|||
static const Class class_;
|
||||
|
||||
static StaticNonSyntacticScope* create(JSContext* cx, HandleObject enclosing);
|
||||
|
||||
JSObject* enclosingScopeForStaticScopeIter() {
|
||||
return getReservedSlot(ENCLOSING_SCOPE_SLOT).toObjectOrNull();
|
||||
}
|
||||
};
|
||||
|
||||
template <AllowGC allowGC>
|
||||
class StaticScopeIter
|
||||
{
|
||||
typename MaybeRooted<StaticScope*, allowGC>::RootType scope;
|
||||
typename MaybeRooted<JSObject*, allowGC>::RootType obj;
|
||||
bool onNamedLambda;
|
||||
|
||||
static bool IsStaticScope(JSObject* obj) {
|
||||
return obj->is<StaticBlockScope>() ||
|
||||
obj->is<StaticWithScope>() ||
|
||||
obj->is<StaticEvalScope>() ||
|
||||
obj->is<StaticNonSyntacticScope>() ||
|
||||
obj->is<JSFunction>() ||
|
||||
obj->is<ModuleObject>();
|
||||
}
|
||||
|
||||
public:
|
||||
StaticScopeIter(ExclusiveContext* cx, StaticScope* scope)
|
||||
: scope(cx, scope), onNamedLambda(false)
|
||||
StaticScopeIter(ExclusiveContext* cx, JSObject* obj)
|
||||
: obj(cx, obj), onNamedLambda(false)
|
||||
{
|
||||
static_assert(allowGC == CanGC,
|
||||
"the context-accepting constructor should only be used "
|
||||
"in CanGC code");
|
||||
MOZ_ASSERT_IF(scope, scope->is<StaticScope>());
|
||||
MOZ_ASSERT_IF(obj, IsStaticScope(obj));
|
||||
}
|
||||
|
||||
StaticScopeIter(ExclusiveContext* cx, const StaticScopeIter<CanGC>& ssi)
|
||||
: scope(cx, ssi.scope), onNamedLambda(ssi.onNamedLambda)
|
||||
: obj(cx, ssi.obj), onNamedLambda(ssi.onNamedLambda)
|
||||
{
|
||||
JS_STATIC_ASSERT(allowGC == CanGC);
|
||||
}
|
||||
|
||||
explicit StaticScopeIter(StaticScope* scope)
|
||||
: scope((ExclusiveContext*) nullptr, scope), onNamedLambda(false)
|
||||
explicit StaticScopeIter(JSObject* obj)
|
||||
: obj((ExclusiveContext*) nullptr, obj), onNamedLambda(false)
|
||||
{
|
||||
static_assert(allowGC == NoGC,
|
||||
"the constructor not taking a context should only be "
|
||||
"used in NoGC code");
|
||||
MOZ_ASSERT_IF(scope, scope->is<StaticScope>());
|
||||
MOZ_ASSERT_IF(obj, IsStaticScope(obj));
|
||||
}
|
||||
|
||||
explicit StaticScopeIter(const StaticScopeIter<NoGC>& ssi)
|
||||
: scope((ExclusiveContext*) nullptr, ssi.scope), onNamedLambda(ssi.onNamedLambda)
|
||||
: obj((ExclusiveContext*) nullptr, ssi.obj), onNamedLambda(ssi.onNamedLambda)
|
||||
{
|
||||
static_assert(allowGC == NoGC,
|
||||
"the constructor not taking a context should only be "
|
||||
"used in NoGC code");
|
||||
}
|
||||
|
||||
bool done() const { return !scope; }
|
||||
bool done() const { return !obj; }
|
||||
void operator++(int);
|
||||
|
||||
StaticScope* staticScope() const { MOZ_ASSERT(!done()); return scope; }
|
||||
JSObject* staticScope() const { MOZ_ASSERT(!done()); return obj; }
|
||||
|
||||
// Return whether this static scope will have a syntactic scope (i.e. a
|
||||
// ScopeObject that isn't a non-syntactic With or
|
||||
|
@ -545,13 +527,14 @@ class StaticScopeIter
|
|||
Type type() const;
|
||||
|
||||
StaticBlockScope& block() const;
|
||||
StaticModuleScope& module() const;
|
||||
StaticWithScope& staticWith() const;
|
||||
StaticEvalScope& eval() const;
|
||||
StaticNonSyntacticScope& nonSyntactic() const;
|
||||
StaticFunctionScope& fun() const;
|
||||
JSScript* funScript() const;
|
||||
JSFunction& fun() const;
|
||||
frontend::FunctionBox* maybeFunctionBox() const;
|
||||
JSScript* moduleScript() const;
|
||||
ModuleObject& module() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -619,46 +602,42 @@ ScopeCoordinateFunctionScript(JSScript* script, jsbytecode* pc);
|
|||
* chain (that is, fp->scopeChain() or fun->environment()). The hierarchy of
|
||||
* scope objects is:
|
||||
*
|
||||
* JSObject Generic object
|
||||
* JSObject Generic object
|
||||
* | |
|
||||
* | StaticScope Created at compile time
|
||||
* | | | |
|
||||
* | | | StaticNonSyntacticScope See "Non-syntactic scopes"
|
||||
* | | |
|
||||
* | | StaticEvalScope Placeholder so eval scopes may be iterated through
|
||||
* | |
|
||||
* | NestedStaticScope Enclosing scope is in the same JSScript
|
||||
* | | |
|
||||
* | | StaticBlockScope See NB
|
||||
* | |
|
||||
* | StaticWithScope Template for "with" object in static scope chain
|
||||
* |
|
||||
* +--StaticScope Created at compile time
|
||||
* ScopeObject Engine-internal scope
|
||||
* | | |
|
||||
* | | DeclEnvObject Holds name of recursive/needsCallObject named lambda
|
||||
* | |
|
||||
* | +--StaticNonSyntacticScope See "Non-syntactic scopes"
|
||||
* | LexicalScopeBase Shared base for function and modules scopes
|
||||
* | | |
|
||||
* | | CallObject Scope of entire function or strict eval
|
||||
* | |
|
||||
* | +--StaticEvalScope Placeholder so eval scopes may be iterated through
|
||||
* | |
|
||||
* | +--StaticFunctionScope Scope in a function
|
||||
* | |
|
||||
* | +--StaticModuleScope Toplevel scope in a module
|
||||
* | |
|
||||
* | +--NestedStaticScope Enclosing scope is in the same JSScript
|
||||
* | |
|
||||
* | +--StaticBlockScope See "N.B." below.
|
||||
* | |
|
||||
* | +--StaticWithScope Template for "with" object in static scope chain
|
||||
* | ModuleEnvironmentObject Module top-level scope on run-time scope chain
|
||||
* |
|
||||
* +--ScopeObject Engine-internal scope
|
||||
* |
|
||||
* +--DeclEnvObject Holds name of recursive/needsCallObject named lambda
|
||||
* |
|
||||
* +--LexicalScopeBase Shared base for function and modules scopes
|
||||
* | |
|
||||
* | +--CallObject Scope of entire function or strict eval
|
||||
* | |
|
||||
* | +--ModuleEnvironmentObject Module top-level scope on run-time scope chain
|
||||
* |
|
||||
* +--NestedScopeObject Statement scopes; don't cross script boundaries
|
||||
* |
|
||||
* +--ClonedBlockObject let, switch, catch, for
|
||||
* |
|
||||
* +--DynamicWithObject Run-time "with" object on scope chain
|
||||
* NestedScopeObject Statement scopes; don't cross script boundaries
|
||||
* | |
|
||||
* | DynamicWithObject Run-time "with" object on scope chain
|
||||
* |
|
||||
* ClonedBlockObject let, switch, catch, for
|
||||
*
|
||||
* This hierarchy represents more than just the interface hierarchy: reserved
|
||||
* slots in base classes are fixed for all derived classes. Thus, for example,
|
||||
* ScopeObject::enclosingScope() can simply access a fixed slot without further
|
||||
* dynamic type information.
|
||||
*
|
||||
* N.B. Static block objects are a special case: these objects are created at
|
||||
* NB: Static block objects are a special case: these objects are created at
|
||||
* compile time to hold the shape/binding information from which block objects
|
||||
* are cloned at runtime. These objects should never escape into the wild and
|
||||
* support a restricted set of ScopeObject operations.
|
||||
|
@ -771,13 +750,23 @@ class CallObject : public LexicalScopeBase
|
|||
static CallObject* createHollowForDebug(JSContext* cx, HandleFunction callee);
|
||||
|
||||
/* True if this is for a strict mode eval frame. */
|
||||
inline bool isForEval() const;
|
||||
bool isForEval() const {
|
||||
if (is<ModuleEnvironmentObject>())
|
||||
return false;
|
||||
MOZ_ASSERT(getFixedSlot(CALLEE_SLOT).isObjectOrNull());
|
||||
MOZ_ASSERT_IF(getFixedSlot(CALLEE_SLOT).isObject(),
|
||||
getFixedSlot(CALLEE_SLOT).toObject().is<JSFunction>());
|
||||
return getFixedSlot(CALLEE_SLOT).isNull();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the function for which this CallObject was created. (This may
|
||||
* only be called if !isForEval.)
|
||||
*/
|
||||
inline JSFunction& callee() const;
|
||||
JSFunction& callee() const {
|
||||
MOZ_ASSERT(!is<ModuleEnvironmentObject>());
|
||||
return getFixedSlot(CALLEE_SLOT).toObject().as<JSFunction>();
|
||||
}
|
||||
|
||||
/* For jit access. */
|
||||
static size_t offsetOfCallee() {
|
||||
|
@ -800,7 +789,6 @@ class ModuleEnvironmentObject : public LexicalScopeBase
|
|||
|
||||
static ModuleEnvironmentObject* create(ExclusiveContext* cx, HandleModuleObject module);
|
||||
ModuleObject& module();
|
||||
StaticModuleScope& staticScope();
|
||||
IndirectBindingMap& importBindings();
|
||||
|
||||
bool createImportBinding(JSContext* cx, HandleAtom importName, HandleModuleObject module,
|
||||
|
@ -897,8 +885,8 @@ class DynamicWithObject : public NestedScopeObject
|
|||
};
|
||||
|
||||
static DynamicWithObject*
|
||||
create(JSContext* cx, HandleObject object, HandleObject enclosing,
|
||||
Handle<StaticWithScope*> staticWith, WithKind kind = SyntacticWith);
|
||||
create(JSContext* cx, HandleObject object, HandleObject enclosing, HandleObject staticWith,
|
||||
WithKind kind = SyntacticWith);
|
||||
|
||||
StaticWithScope& staticWith() const {
|
||||
return getProto()->as<StaticWithScope>();
|
||||
|
@ -951,8 +939,7 @@ class ClonedBlockObject : public NestedScopeObject
|
|||
|
||||
static ClonedBlockObject* createGlobal(JSContext* cx, Handle<GlobalObject*> global);
|
||||
|
||||
static ClonedBlockObject* createNonSyntactic(JSContext* cx,
|
||||
Handle<StaticNonSyntacticScope*> enclosingStatic,
|
||||
static ClonedBlockObject* createNonSyntactic(JSContext* cx, HandleObject enclosingStatic,
|
||||
HandleObject enclosingScope);
|
||||
|
||||
static ClonedBlockObject* createHollowForDebug(JSContext* cx,
|
||||
|
@ -1059,11 +1046,11 @@ class RuntimeLexicalErrorObject : public ScopeObject
|
|||
|
||||
template<XDRMode mode>
|
||||
bool
|
||||
XDRStaticBlockScope(XDRState<mode>* xdr, Handle<StaticScope*> enclosingScope,
|
||||
XDRStaticBlockScope(XDRState<mode>* xdr, HandleObject enclosingScope,
|
||||
MutableHandle<StaticBlockScope*> objp);
|
||||
|
||||
extern NestedStaticScope*
|
||||
CloneNestedScopeObject(JSContext* cx, Handle<StaticScope*> enclosingScope,
|
||||
extern JSObject*
|
||||
CloneNestedScopeObject(JSContext* cx, HandleObject enclosingScope,
|
||||
Handle<NestedStaticScope*> src);
|
||||
|
||||
|
||||
|
@ -1094,7 +1081,7 @@ class MOZ_RAII ScopeIter
|
|||
|
||||
// Constructing from a dynamic scope, static scope pair. All scopes are
|
||||
// considered not to be withinInitialFrame, since no frame is given.
|
||||
ScopeIter(JSContext* cx, JSObject* scope, StaticScope* staticScope
|
||||
ScopeIter(JSContext* cx, JSObject* scope, JSObject* staticScope
|
||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
|
||||
|
||||
// Constructing from a frame. Places the ScopeIter on the innermost scope
|
||||
|
@ -1118,13 +1105,13 @@ class MOZ_RAII ScopeIter
|
|||
inline bool canHaveSyntacticScopeObject() const;
|
||||
ScopeObject& scope() const;
|
||||
|
||||
StaticScope* maybeStaticScope() const;
|
||||
JSObject* maybeStaticScope() const;
|
||||
StaticBlockScope& staticBlock() const { return ssi_.block(); }
|
||||
StaticModuleScope& module() const { return ssi_.module(); }
|
||||
StaticWithScope& staticWith() const { return ssi_.staticWith(); }
|
||||
StaticEvalScope& staticEval() const { return ssi_.eval(); }
|
||||
StaticNonSyntacticScope& staticNonSyntactic() const { return ssi_.nonSyntactic(); }
|
||||
StaticFunctionScope& fun() const { return ssi_.fun(); }
|
||||
JSFunction& fun() const { return ssi_.fun(); }
|
||||
ModuleObject& module() const { return ssi_.module(); }
|
||||
|
||||
bool withinInitialFrame() const { return !!frame_; }
|
||||
AbstractFramePtr initialFrame() const { MOZ_ASSERT(withinInitialFrame()); return frame_; }
|
||||
|
@ -1150,7 +1137,7 @@ class MissingScopeKey
|
|||
friend class LiveScopeVal;
|
||||
|
||||
AbstractFramePtr frame_;
|
||||
StaticScope* staticScope_;
|
||||
JSObject* staticScope_;
|
||||
|
||||
public:
|
||||
explicit MissingScopeKey(const ScopeIter& si)
|
||||
|
@ -1159,9 +1146,9 @@ class MissingScopeKey
|
|||
{ }
|
||||
|
||||
AbstractFramePtr frame() const { return frame_; }
|
||||
StaticScope* staticScope() const { return staticScope_; }
|
||||
JSObject* staticScope() const { return staticScope_; }
|
||||
|
||||
void updateStaticScope(StaticScope* scope) { staticScope_ = scope; }
|
||||
void updateStaticScope(JSObject* obj) { staticScope_ = obj; }
|
||||
void updateFrame(AbstractFramePtr frame) { frame_ = frame; }
|
||||
|
||||
// For use as hash policy.
|
||||
|
@ -1183,7 +1170,7 @@ class LiveScopeVal
|
|||
friend class MissingScopeKey;
|
||||
|
||||
AbstractFramePtr frame_;
|
||||
RelocatablePtr<StaticScope*> staticScope_;
|
||||
RelocatablePtrObject staticScope_;
|
||||
|
||||
static void staticAsserts();
|
||||
|
||||
|
@ -1194,7 +1181,7 @@ class LiveScopeVal
|
|||
{ }
|
||||
|
||||
AbstractFramePtr frame() const { return frame_; }
|
||||
StaticScope* staticScope() const { return staticScope_; }
|
||||
JSObject* staticScope() const { return staticScope_; }
|
||||
|
||||
void updateFrame(AbstractFramePtr frame) { frame_ = frame; }
|
||||
|
||||
|
@ -1360,13 +1347,6 @@ JSObject::is<js::StaticBlockScope>() const
|
|||
return hasClass(&js::ClonedBlockObject::class_) && !getProto();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool
|
||||
JSObject::is<js::StaticModuleScope>() const
|
||||
{
|
||||
return hasClass(&js::ModuleEnvironmentObject::class_) && !getProto();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool
|
||||
JSObject::is<js::NestedStaticScope>() const
|
||||
|
@ -1380,19 +1360,10 @@ inline bool
|
|||
JSObject::is<js::StaticScope>() const
|
||||
{
|
||||
return is<js::NestedStaticScope>() ||
|
||||
is<js::StaticFunctionScope>() ||
|
||||
is<js::StaticModuleScope>() ||
|
||||
is<js::StaticEvalScope>() ||
|
||||
is<js::StaticNonSyntacticScope>();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool
|
||||
JSObject::is<js::ModuleEnvironmentObject>() const
|
||||
{
|
||||
return hasClass(&js::ModuleEnvironmentObject::class_) && !!getProto();
|
||||
}
|
||||
|
||||
template<>
|
||||
inline bool
|
||||
JSObject::is<js::ClonedBlockObject>() const
|
||||
|
@ -1469,13 +1440,6 @@ IsGlobalLexicalScope(JSObject* scope)
|
|||
return scope->is<ClonedBlockObject>() && scope->as<ClonedBlockObject>().isGlobal();
|
||||
}
|
||||
|
||||
inline js::StaticScope*
|
||||
js::StaticScope::enclosingScope() const
|
||||
{
|
||||
JSObject *obj = getFixedSlot(ENCLOSING_SCOPE_SLOT).toObjectOrNull();
|
||||
return obj ? &obj->as<StaticScope>() : nullptr;
|
||||
}
|
||||
|
||||
inline NestedStaticScope*
|
||||
NestedStaticScope::enclosingNestedScope() const
|
||||
{
|
||||
|
@ -1569,31 +1533,13 @@ ScopeIter::enclosingScope() const
|
|||
return *scope_;
|
||||
}
|
||||
|
||||
inline bool
|
||||
js::CallObject::isForEval() const
|
||||
{
|
||||
if (is<ModuleEnvironmentObject>())
|
||||
return false;
|
||||
MOZ_ASSERT(getFixedSlot(CALLEE_SLOT).isObjectOrNull());
|
||||
MOZ_ASSERT_IF(getFixedSlot(CALLEE_SLOT).isObject(),
|
||||
getFixedSlot(CALLEE_SLOT).toObject().is<JSFunction>());
|
||||
return getFixedSlot(CALLEE_SLOT).isNull();
|
||||
}
|
||||
|
||||
inline JSFunction&
|
||||
js::CallObject::callee() const
|
||||
{
|
||||
MOZ_ASSERT(!is<ModuleEnvironmentObject>());
|
||||
return getFixedSlot(CALLEE_SLOT).toObject().as<JSFunction>();
|
||||
}
|
||||
|
||||
extern bool
|
||||
CreateScopeObjectsForScopeChain(JSContext* cx, AutoObjectVector& scopeChain,
|
||||
HandleObject dynamicTerminatingScope,
|
||||
MutableHandleObject dynamicScopeObj);
|
||||
|
||||
bool HasNonSyntacticStaticScopeChain(StaticScope* staticScope);
|
||||
uint32_t StaticScopeChainLength(StaticScope* staticScope);
|
||||
bool HasNonSyntacticStaticScopeChain(JSObject* staticScope);
|
||||
uint32_t StaticScopeChainLength(JSObject* staticScope);
|
||||
|
||||
ModuleEnvironmentObject* GetModuleEnvironmentForScript(JSScript* script);
|
||||
|
||||
|
@ -1615,7 +1561,7 @@ bool CheckEvalDeclarationConflicts(JSContext* cx, HandleScript script,
|
|||
|
||||
#ifdef DEBUG
|
||||
void DumpStaticScopeChain(JSScript* script);
|
||||
void DumpStaticScopeChain(StaticScope* staticScope);
|
||||
void DumpStaticScopeChain(JSObject* staticScope);
|
||||
bool
|
||||
AnalyzeEntrainedVariables(JSContext* cx, HandleScript script);
|
||||
#endif
|
||||
|
|
|
@ -2277,10 +2277,9 @@ CloneObject(JSContext* cx, HandleNativeObject selfHostedObject)
|
|||
: selfHostedFunction->getAllocKind();
|
||||
MOZ_ASSERT(!CanReuseScriptForClone(cx->compartment(), selfHostedFunction, cx->global()));
|
||||
Rooted<ClonedBlockObject*> globalLexical(cx, &cx->global()->lexicalScope());
|
||||
Rooted<StaticScope*> staticGlobalLexical(cx, &globalLexical->staticBlock());
|
||||
RootedObject staticGlobalLexical(cx, &globalLexical->staticBlock());
|
||||
clone = CloneFunctionAndScript(cx, selfHostedFunction, globalLexical,
|
||||
staticGlobalLexical, kind);
|
||||
|
||||
// To be able to re-lazify the cloned function, its name in the
|
||||
// self-hosting compartment has to be stored on the clone.
|
||||
if (clone && hasName) {
|
||||
|
|
|
@ -105,7 +105,7 @@ AssertDynamicScopeMatchesStaticScope(JSContext* cx, JSScript* script, JSObject*
|
|||
{
|
||||
#ifdef DEBUG
|
||||
RootedObject originalScope(cx, scope);
|
||||
Rooted<StaticScope*> enclosingScope(cx, script->enclosingStaticScope());
|
||||
RootedObject enclosingScope(cx, script->enclosingStaticScope());
|
||||
for (StaticScopeIter<NoGC> i(enclosingScope); !i.done(); i++) {
|
||||
if (i.type() == StaticScopeIter<NoGC>::NonSyntactic) {
|
||||
while (scope->is<DynamicWithObject>() ||
|
||||
|
@ -119,7 +119,7 @@ AssertDynamicScopeMatchesStaticScope(JSContext* cx, JSScript* script, JSObject*
|
|||
} else if (i.hasSyntacticDynamicScopeObject()) {
|
||||
switch (i.type()) {
|
||||
case StaticScopeIter<NoGC>::Module:
|
||||
MOZ_ASSERT(scope->as<ModuleEnvironmentObject>().module().staticScope() == &i.module());
|
||||
MOZ_ASSERT(scope->as<ModuleEnvironmentObject>().module().script() == i.moduleScript());
|
||||
scope = &scope->as<ModuleEnvironmentObject>().enclosingScope();
|
||||
break;
|
||||
case StaticScopeIter<NoGC>::Function:
|
||||
|
|
|
@ -118,7 +118,7 @@ XDRState<mode>::codeFunction(MutableHandleFunction objp)
|
|||
if (!VersionCheck(this))
|
||||
return false;
|
||||
|
||||
Rooted<StaticScope*> staticLexical(cx(), &cx()->global()->lexicalScope().staticBlock());
|
||||
RootedObject staticLexical(cx(), &cx()->global()->lexicalScope().staticBlock());
|
||||
return XDRInterpretedFunction(this, staticLexical, nullptr, objp);
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ XDRState<mode>::codeScript(MutableHandleScript scriptp)
|
|||
if (!VersionCheck(this))
|
||||
return false;
|
||||
|
||||
Rooted<StaticScope*> staticLexical(cx(), &cx()->global()->lexicalScope().staticBlock());
|
||||
RootedObject staticLexical(cx(), &cx()->global()->lexicalScope().staticBlock());
|
||||
if (!XDRScript(this, staticLexical, nullptr, nullptr, scriptp))
|
||||
return false;
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче