backout Bug 1221144 for perf regression

MozReview-Commit-ID: Aete3iN6i3r
This commit is contained in:
Joel Maher 2016-02-12 04:11:10 -08:00
Родитель 1674c865bc
Коммит bf2ce4db2f
34 изменённых файлов: 463 добавлений и 758 удалений

Просмотреть файл

@ -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;