Bug 678037 - Enable lazy JS parsing and fix various bugs, r=waldo,evilpie,nobody.

This commit is contained in:
Brian Hackett
2013-06-14 05:58:28 -06:00
parent d8eb57d01a
commit 7aae7e0a25
28 changed files with 447 additions and 206 deletions

View File

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