Bug 678037 - Enable lazy JS parsing and fix various bugs, r=waldo,evilpie,nobody.
This commit is contained in:
@@ -74,6 +74,15 @@ CheckArgumentsWithinEval(JSContext *cx, Parser<FullParseHandler> &parser, Handle
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
CanLazilyParse(JSContext *cx, const CompileOptions &options)
|
||||
{
|
||||
return options.canLazilyParse &&
|
||||
options.compileAndGo &&
|
||||
options.sourcePolicy == CompileOptions::SAVE_SOURCE &&
|
||||
!cx->compartment()->debugMode();
|
||||
}
|
||||
|
||||
JSScript *
|
||||
frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
||||
HandleScript evalCaller,
|
||||
@@ -102,7 +111,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
||||
return NULL;
|
||||
if (options.filename && !ss->setFilename(cx, options.filename))
|
||||
return NULL;
|
||||
|
||||
|
||||
JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, ss));
|
||||
if (!sourceObject)
|
||||
return NULL;
|
||||
@@ -120,28 +129,21 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
||||
break;
|
||||
}
|
||||
|
||||
bool canLazilyParse = CanLazilyParse(cx, options);
|
||||
|
||||
Maybe<Parser<SyntaxParseHandler> > syntaxParser;
|
||||
if (options.canLazilyParse) {
|
||||
if (canLazilyParse) {
|
||||
syntaxParser.construct(cx, options, chars, length, /* foldConstants = */ false,
|
||||
(Parser<SyntaxParseHandler> *) NULL,
|
||||
(LazyScript *) NULL);
|
||||
}
|
||||
|
||||
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true,
|
||||
options.canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
||||
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
||||
parser.sct = sct;
|
||||
|
||||
GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx));
|
||||
|
||||
// Syntax parsing may cause us to restart processing of top level
|
||||
// statements in the script. Use Maybe<> so that the parse context can be
|
||||
// reset when this occurs.
|
||||
Maybe<ParseContext<FullParseHandler> > pc;
|
||||
|
||||
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc, staticLevel, /* bodyid = */ 0);
|
||||
if (!pc.ref().init())
|
||||
return NULL;
|
||||
|
||||
bool savedCallerFun =
|
||||
options.compileAndGo &&
|
||||
evalCaller &&
|
||||
@@ -169,6 +171,15 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain,
|
||||
if (!bce.init())
|
||||
return NULL;
|
||||
|
||||
// Syntax parsing may cause us to restart processing of top level
|
||||
// statements in the script. Use Maybe<> so that the parse context can be
|
||||
// reset when this occurs.
|
||||
Maybe<ParseContext<FullParseHandler> > pc;
|
||||
|
||||
pc.construct(&parser, (GenericParseContext *) NULL, &globalsc, staticLevel, /* bodyid = */ 0);
|
||||
if (!pc.ref().init())
|
||||
return NULL;
|
||||
|
||||
/* If this is a direct call to eval, inherit the caller's strictness. */
|
||||
if (evalCaller && evalCaller->strict)
|
||||
globalsc.strict = true;
|
||||
@@ -313,32 +324,34 @@ bool
|
||||
frontend::CompileLazyFunction(JSContext *cx, HandleFunction fun, LazyScript *lazy,
|
||||
const jschar *chars, size_t length)
|
||||
{
|
||||
CompileOptions options(cx);
|
||||
JS_ASSERT(cx->compartment() == fun->compartment());
|
||||
|
||||
CompileOptions options(cx, lazy->version());
|
||||
options.setPrincipals(cx->compartment()->principals)
|
||||
.setOriginPrincipals(lazy->parent()->originPrincipals)
|
||||
.setVersion(lazy->parent()->getVersion())
|
||||
.setFileAndLine(lazy->parent()->filename(), lazy->lineno())
|
||||
.setOriginPrincipals(lazy->originPrincipals())
|
||||
.setFileAndLine(lazy->source()->filename(), lazy->lineno())
|
||||
.setColumn(lazy->column())
|
||||
.setCompileAndGo(lazy->parent()->compileAndGo)
|
||||
.setCompileAndGo(true)
|
||||
.setNoScriptRval(false)
|
||||
.setSelfHostingMode(false);
|
||||
|
||||
Parser<FullParseHandler> parser(cx, options, chars, length,
|
||||
/* foldConstants = */ true, NULL, lazy);
|
||||
|
||||
RootedObject enclosingScope(cx, lazy->parent()->function());
|
||||
RootedObject enclosingScope(cx, lazy->parentFunction());
|
||||
|
||||
ParseNode *pn = parser.standaloneLazyFunction(fun, lazy->parent()->staticLevel + 1,
|
||||
lazy->strict());
|
||||
ParseNode *pn = parser.standaloneLazyFunction(fun, lazy->staticLevel(), lazy->strict());
|
||||
if (!pn)
|
||||
return false;
|
||||
|
||||
JS::RootedScriptSource sourceObject(cx, ScriptSourceObject::create(cx, lazy->source()));
|
||||
if (!sourceObject)
|
||||
if (!NameFunctions(cx, pn))
|
||||
return false;
|
||||
|
||||
JS::RootedScriptSource sourceObject(cx, lazy->sourceObject());
|
||||
JS_ASSERT(sourceObject);
|
||||
|
||||
Rooted<JSScript*> script(cx, JSScript::Create(cx, enclosingScope, false,
|
||||
options, lazy->parent()->staticLevel + 1,
|
||||
options, lazy->staticLevel(),
|
||||
sourceObject, lazy->begin(), lazy->end()));
|
||||
if (!script)
|
||||
return false;
|
||||
@@ -347,11 +360,11 @@ frontend::CompileLazyFunction(JSContext *cx, HandleFunction fun, LazyScript *laz
|
||||
|
||||
if (lazy->directlyInsideEval())
|
||||
script->directlyInsideEval = true;
|
||||
|
||||
bool hasGlobalScope = lazy->parent()->compileAndGo;
|
||||
if (lazy->usesArgumentsAndApply())
|
||||
script->usesArgumentsAndApply = true;
|
||||
|
||||
BytecodeEmitter bce(/* parent = */ NULL, &parser, pn->pn_funbox, script, options.forEval,
|
||||
/* evalCaller = */ NullPtr(), hasGlobalScope,
|
||||
/* evalCaller = */ NullPtr(), /* hasGlobalScope = */ true,
|
||||
options.lineno, BytecodeEmitter::LazyFunction);
|
||||
if (!bce.init())
|
||||
return false;
|
||||
@@ -385,8 +398,10 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
||||
return false;
|
||||
}
|
||||
|
||||
bool canLazilyParse = CanLazilyParse(cx, options);
|
||||
|
||||
Maybe<Parser<SyntaxParseHandler> > syntaxParser;
|
||||
if (options.canLazilyParse) {
|
||||
if (canLazilyParse) {
|
||||
syntaxParser.construct(cx, options, chars, length, /* foldConstants = */ false,
|
||||
(Parser<SyntaxParseHandler> *) NULL,
|
||||
(LazyScript *) NULL);
|
||||
@@ -395,7 +410,7 @@ frontend::CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, CompileO
|
||||
JS_ASSERT(!options.forEval);
|
||||
|
||||
Parser<FullParseHandler> parser(cx, options, chars, length, /* foldConstants = */ true,
|
||||
options.canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
||||
canLazilyParse ? &syntaxParser.ref() : NULL, NULL);
|
||||
parser.sct = &sct;
|
||||
|
||||
JS_ASSERT(fun);
|
||||
|
||||
Reference in New Issue
Block a user