Bug 1165486 - Detect with scopes at parse time using the static scope chain for non-function scripts. Also cache static scope properties on SharedGlobalContext. (r=efaust)

This commit is contained in:
Shu-yu Guo 2015-06-17 21:26:57 -07:00
Родитель 543778a467
Коммит 4f697151ff
3 изменённых файлов: 47 добавлений и 23 удалений

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

@ -2356,13 +2356,14 @@ BytecodeEmitter::checkRunOnceContext()
bool
BytecodeEmitter::needsImplicitThis()
{
if (sc->isFunctionBox() && sc->asFunctionBox()->inWith)
if (sc->inWith())
return true;
for (StmtInfoBCE* stmt = topStmt; stmt; stmt = stmt->down) {
if (stmt->type == STMT_WITH)
return true;
}
return false;
}

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

@ -596,7 +596,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
bufEnd(0),
length(0),
generatorKindBits_(GeneratorKindAsBits(generatorKind)),
inWith(false), // initialized below
inWith_(false), // initialized below
inGenexpLambda(false),
hasDestructuringArgs(false),
useAsm(false),
@ -612,7 +612,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
MOZ_ASSERT(fun->isTenured());
if (!outerpc) {
inWith = false;
inWith_ = false;
} else if (outerpc->parsingWith) {
// This covers cases that don't involve eval(). For example:
@ -621,7 +621,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
//
// In this case, |outerpc| corresponds to global code, and
// outerpc->parsingWith is true.
inWith = true;
inWith_ = true;
} else if (outerpc->sc->isFunctionBox()) {
// This is like the above case, but for more deeply nested functions.
@ -632,8 +632,8 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
// In this case, the inner anonymous function needs to inherit the
// setting of |inWith| from the outer one.
FunctionBox* parent = outerpc->sc->asFunctionBox();
if (parent && parent->inWith)
inWith = true;
if (parent && parent->inWith())
inWith_ = true;
} else {
// This is like the above case, but when inside eval.
//
@ -642,7 +642,7 @@ FunctionBox::FunctionBox(ExclusiveContext* cx, ObjectBox* traceListHead, JSFunct
// with(o) { eval("(function() { g(); })();"); }
//
// In this case, the static scope chain tells us the presence of with.
inWith = outerpc->sc->asGlobalSharedContext()->inWith();
inWith_ = outerpc->sc->inWith();
}
}
@ -2224,7 +2224,7 @@ Parser<SyntaxParseHandler>::finishFunctionDefinition(Node pn, FunctionBox* funbo
// while its ParseContext and associated lexdeps and inner functions are
// still available.
if (funbox->inWith)
if (funbox->inWith())
return abortIfSyntaxParser();
size_t numFreeVariables = pc->lexdeps->count();

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

@ -235,6 +235,7 @@ class SharedContext
SuperProperty
};
virtual bool allowSyntax(AllowedSyntax allowed) const = 0;
virtual bool inWith() const = 0;
protected:
static bool FunctionAllowsSyntax(JSFunction* func, AllowedSyntax allowed)
@ -257,19 +258,11 @@ class GlobalSharedContext : public SharedContext
{
private:
Handle<ScopeObject*> topStaticScope_;
bool allowNewTarget_;
bool allowSuperProperty_;
bool inWith_;
public:
GlobalSharedContext(ExclusiveContext* cx,
Directives directives, Handle<ScopeObject*> topStaticScope,
bool extraWarnings)
: SharedContext(cx, directives, extraWarnings),
topStaticScope_(topStaticScope)
{}
ObjectBox* toObjectBox() { return nullptr; }
HandleObject topStaticScope() const { return topStaticScope_; }
bool allowSyntax(AllowedSyntax allowed) const {
bool computeAllowSyntax(AllowedSyntax allowed) const {
StaticScopeIter<CanGC> it(context, topStaticScope_);
for (; !it.done(); it++) {
if (it.type() == StaticScopeIter<CanGC>::Function &&
@ -281,13 +274,39 @@ class GlobalSharedContext : public SharedContext
return false;
}
bool inWith() const {
bool computeInWith() const {
for (StaticScopeIter<CanGC> it(context, topStaticScope_); !it.done(); it++) {
if (it.type() == StaticScopeIter<CanGC>::With)
return true;
}
return false;
}
public:
GlobalSharedContext(ExclusiveContext* cx,
Directives directives, Handle<ScopeObject*> topStaticScope,
bool extraWarnings)
: SharedContext(cx, directives, extraWarnings),
topStaticScope_(topStaticScope),
allowNewTarget_(computeAllowSyntax(AllowedSyntax::NewTarget)),
allowSuperProperty_(computeAllowSyntax(AllowedSyntax::SuperProperty)),
inWith_(computeInWith())
{}
ObjectBox* toObjectBox() { return nullptr; }
HandleObject topStaticScope() const { return topStaticScope_; }
bool allowSyntax(AllowedSyntax allowSyntax) const override {
switch (allowSyntax) {
case AllowedSyntax::NewTarget:
// Any function supports new.target
return allowNewTarget_;
case AllowedSyntax::SuperProperty:
return allowSuperProperty_;
default:;
}
MOZ_CRASH("Unknown AllowedSyntax query");
}
bool inWith() const override { return inWith_; }
};
class FunctionBox : public ObjectBox, public SharedContext
@ -301,7 +320,7 @@ class FunctionBox : public ObjectBox, public SharedContext
uint16_t length;
uint8_t generatorKindBits_; /* The GeneratorKind of this function. */
bool inWith:1; /* some enclosing scope is a with-statement */
bool inWith_:1; /* some enclosing scope is a with-statement */
bool inGenexpLambda:1; /* lambda from generator expression */
bool hasDestructuringArgs:1; /* arguments list contains destructuring expression */
bool useAsm:1; /* see useAsmOrInsideUseAsm */
@ -380,9 +399,13 @@ class FunctionBox : public ObjectBox, public SharedContext
isGenerator();
}
bool allowSyntax(AllowedSyntax allowed) const {
bool allowSyntax(AllowedSyntax allowed) const override {
return FunctionAllowsSyntax(function(), allowed);
}
bool inWith() const override {
return inWith_;
}
};
inline FunctionBox*