зеркало из https://github.com/mozilla/gecko-dev.git
Bug 883439 - Lazily parse scripts defined within catch blocks, r=luke.
This commit is contained in:
Родитель
986261c995
Коммит
0054473e24
|
@ -340,20 +340,21 @@ frontend::CompileLazyFunction(JSContext *cx, HandleFunction fun, LazyScript *laz
|
|||
Parser<FullParseHandler> parser(cx, options, chars, length,
|
||||
/* foldConstants = */ true, NULL, lazy);
|
||||
|
||||
RootedObject enclosingScope(cx, lazy->parentFunction());
|
||||
uint32_t staticLevel = lazy->staticLevel(cx);
|
||||
|
||||
ParseNode *pn = parser.standaloneLazyFunction(fun, lazy->staticLevel(), lazy->strict());
|
||||
ParseNode *pn = parser.standaloneLazyFunction(fun, staticLevel, lazy->strict());
|
||||
if (!pn)
|
||||
return false;
|
||||
|
||||
if (!NameFunctions(cx, pn))
|
||||
return false;
|
||||
|
||||
RootedObject enclosingScope(cx, lazy->enclosingScope());
|
||||
JS::RootedScriptSource sourceObject(cx, lazy->sourceObject());
|
||||
JS_ASSERT(sourceObject);
|
||||
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false,
|
||||
options, lazy->staticLevel(),
|
||||
options, staticLevel,
|
||||
sourceObject, lazy->begin(), lazy->end()));
|
||||
if (!script)
|
||||
return false;
|
||||
|
|
|
@ -1156,6 +1156,10 @@ TryConvertFreeName(BytecodeEmitter *bce, ParseNode *pn)
|
|||
RootedObject outerScope(bce->sc->context, bce->script->enclosingStaticScope());
|
||||
for (StaticScopeIter ssi(bce->sc->context, outerScope); !ssi.done(); ssi++) {
|
||||
if (ssi.type() != StaticScopeIter::FUNCTION) {
|
||||
if (ssi.type() == StaticScopeIter::BLOCK) {
|
||||
// Use generic ops if a catch block is encountered.
|
||||
return false;
|
||||
}
|
||||
if (ssi.hasDynamicScopeObject())
|
||||
hops++;
|
||||
continue;
|
||||
|
@ -4504,8 +4508,10 @@ EmitFunc(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
|||
|
||||
if (fun->isInterpretedLazy()) {
|
||||
if (!fun->lazyScript()->sourceObject()) {
|
||||
JSFunction *parent = bce->sc->isFunctionBox() ? bce->sc->asFunctionBox()->function() : NULL;
|
||||
fun->lazyScript()->setParent(parent, bce->script->sourceObject(), bce->script->originPrincipals);
|
||||
JSObject *scope = bce->blockChain;
|
||||
if (!scope && bce->sc->isFunctionBox())
|
||||
scope = bce->sc->asFunctionBox()->function();
|
||||
fun->lazyScript()->setParent(scope, bce->script->sourceObject(), bce->script->originPrincipals);
|
||||
}
|
||||
} else {
|
||||
SharedContext *outersc = bce->sc;
|
||||
|
|
|
@ -2065,11 +2065,6 @@ Parser<FullParseHandler>::functionArgsAndBody(ParseNode *pn, HandleFunction fun,
|
|||
if (!funbox)
|
||||
return false;
|
||||
|
||||
// Disable lazy parsing if any functions are defined within a scope
|
||||
// statement. Free names in the inner functions will be bound incorrectly.
|
||||
if (pc->topScopeStmt)
|
||||
handler.disableSyntaxParser();
|
||||
|
||||
// Try a syntax parse for this inner function.
|
||||
do {
|
||||
Parser<SyntaxParseHandler> *parser = handler.syntaxParser;
|
||||
|
@ -2151,11 +2146,6 @@ Parser<SyntaxParseHandler>::functionArgsAndBody(Node pn, HandleFunction fun,
|
|||
*becameStrict = false;
|
||||
ParseContext<SyntaxParseHandler> *outerpc = pc;
|
||||
|
||||
// As from a full parse handler, abort if functions are defined within
|
||||
// lexical scopes.
|
||||
if (pc->topScopeStmt)
|
||||
return abortIfSyntaxParser();
|
||||
|
||||
// Create box for fun->object early to protect against last-ditch GC.
|
||||
FunctionBox *funbox = newFunctionBox(fun, pc, strict);
|
||||
if (!funbox)
|
||||
|
|
|
@ -34,3 +34,12 @@ function test() {
|
|||
(function(x) { return !(x) })(0/0)
|
||||
}
|
||||
}
|
||||
|
||||
testCatch(15);
|
||||
function testCatch(y) {
|
||||
try {
|
||||
throw 5;
|
||||
} catch(ex) {
|
||||
(function(x) { assertEq(x + y + ex, 25); })(5)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2774,8 +2774,8 @@ LazyScript::markChildren(JSTracer *trc)
|
|||
if (sourceObject_)
|
||||
MarkObject(trc, &sourceObject_, "sourceObject");
|
||||
|
||||
if (parentFunction_)
|
||||
MarkObject(trc, &parentFunction_, "parentFunction");
|
||||
if (enclosingScope_)
|
||||
MarkObject(trc, &enclosingScope_, "enclosingScope");
|
||||
|
||||
if (script_)
|
||||
MarkScript(trc, &script_, "realScript");
|
||||
|
@ -2948,7 +2948,7 @@ JSScript::formalLivesInArgumentsObject(unsigned argSlot)
|
|||
LazyScript::LazyScript(void *table, uint32_t numFreeVariables, uint32_t numInnerFunctions,
|
||||
JSVersion version, uint32_t begin, uint32_t end, uint32_t lineno, uint32_t column)
|
||||
: script_(NULL),
|
||||
parentFunction_(NULL),
|
||||
enclosingScope_(NULL),
|
||||
sourceObject_(NULL),
|
||||
table_(table),
|
||||
originPrincipals_(NULL),
|
||||
|
@ -2978,11 +2978,11 @@ LazyScript::initScript(JSScript *script)
|
|||
}
|
||||
|
||||
void
|
||||
LazyScript::setParent(JSFunction *parentFunction, ScriptSourceObject *sourceObject,
|
||||
LazyScript::setParent(JSObject *enclosingScope, ScriptSourceObject *sourceObject,
|
||||
JSPrincipals *originPrincipals)
|
||||
{
|
||||
JS_ASSERT(sourceObject && !sourceObject_ && !parentFunction_ && !originPrincipals_);
|
||||
parentFunction_ = parentFunction;
|
||||
JS_ASSERT(sourceObject && !sourceObject_ && !enclosingScope_ && !originPrincipals_);
|
||||
enclosingScope_ = enclosingScope;
|
||||
sourceObject_ = sourceObject;
|
||||
originPrincipals_ = originPrincipals;
|
||||
if (originPrincipals)
|
||||
|
@ -3019,9 +3019,14 @@ LazyScript::Create(JSContext *cx, uint32_t numFreeVariables, uint32_t numInnerFu
|
|||
begin, end, lineno, column);
|
||||
}
|
||||
|
||||
uint32_t LazyScript::staticLevel() const
|
||||
uint32_t
|
||||
LazyScript::staticLevel(JSContext *cx) const
|
||||
{
|
||||
return parentFunction() ? parentFunction()->nonLazyScript()->staticLevel + 1 : 1;
|
||||
for (StaticScopeIter ssi(cx, enclosingScope()); !ssi.done(); ssi++) {
|
||||
if (ssi.type() == StaticScopeIter::FUNCTION)
|
||||
return ssi.funScript()->staticLevel + 1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1110,8 +1110,8 @@ class LazyScript : public js::gc::Cell
|
|||
// pointer to the result.
|
||||
HeapPtrScript script_;
|
||||
|
||||
// Immediate parent in which the script is nested, or NULL.
|
||||
HeapPtrFunction parentFunction_;
|
||||
// Function or block chain in which the script is nested, or NULL.
|
||||
HeapPtrObject enclosingScope_;
|
||||
|
||||
// Source code object, or NULL if the script in which this is nested has
|
||||
// not been compiled yet.
|
||||
|
@ -1157,8 +1157,8 @@ class LazyScript : public js::gc::Cell
|
|||
return script_;
|
||||
}
|
||||
|
||||
JSFunction *parentFunction() const {
|
||||
return parentFunction_;
|
||||
JSObject *enclosingScope() const {
|
||||
return enclosingScope_;
|
||||
}
|
||||
ScriptSourceObject *sourceObject() const;
|
||||
JSPrincipals *originPrincipals() const {
|
||||
|
@ -1169,7 +1169,7 @@ class LazyScript : public js::gc::Cell
|
|||
return (version_ == JS_BIT(8) - 1) ? JSVERSION_UNKNOWN : JSVersion(version_);
|
||||
}
|
||||
|
||||
void setParent(JSFunction *parentFunction, ScriptSourceObject *sourceObject,
|
||||
void setParent(JSObject *enclosingScope, ScriptSourceObject *sourceObject,
|
||||
JSPrincipals *originPrincipals);
|
||||
|
||||
uint32_t numFreeVariables() const {
|
||||
|
@ -1244,7 +1244,7 @@ class LazyScript : public js::gc::Cell
|
|||
return column_;
|
||||
}
|
||||
|
||||
uint32_t staticLevel() const;
|
||||
uint32_t staticLevel(JSContext *cx) const;
|
||||
|
||||
Zone *zone() const {
|
||||
return Cell::tenuredZone();
|
||||
|
|
Загрузка…
Ссылка в новой задаче