Bug 775323 - build Bindings after, not during, parsing (r=ejpbruel)

This commit is contained in:
Luke Wagner
2012-07-30 11:38:53 -07:00
parent ad53c498a3
commit 658252b244
33 changed files with 700 additions and 881 deletions

View File

@@ -176,7 +176,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
if (!FoldConstants(cx, pn, &parser))
return NULL;
if (!AnalyzeFunctions(&parser, callerFrame))
if (!AnalyzeFunctions(&parser))
return NULL;
tc.functionList = NULL;
@@ -215,8 +215,6 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
return NULL;
}
}
// We're not in a function context, so we don't expect any bindings.
JS_ASSERT(!sc.bindings.hasBinding(cx, arguments));
}
/*
@@ -238,7 +236,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call
// handler attribute in an HTML <INPUT> tag, or in a Function() constructor.
bool
frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions options,
Bindings *bindings, const jschar *chars, size_t length)
const AutoNameVector &formals, const jschar *chars, size_t length)
{
if (!CheckLength(cx, length))
return NULL;
@@ -262,25 +260,13 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
JS_ASSERT(fun);
SharedContext funsc(cx, /* scopeChain = */ NULL, fun, /* funbox = */ NULL,
StrictModeFromContext(cx));
funsc.bindings.transfer(bindings);
fun->setArgCount(funsc.bindings.numArgs());
fun->setArgCount(formals.length());
unsigned staticLevel = 0;
TreeContext funtc(&parser, &funsc, staticLevel, /* bodyid = */ 0);
if (!funtc.init())
return false;
Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), false, options,
staticLevel, ss, 0, length));
if (!script)
return false;
StackFrame *nullCallerFrame = NULL;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, nullCallerFrame,
/* hasGlobalScope = */ false, options.lineno);
if (!funbce.init())
return false;
/* FIXME: make Function format the source for a function definition. */
ParseNode *fn = FunctionNode::create(PNK_NAME, &parser);
if (!fn)
@@ -296,22 +282,9 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
argsbody->makeEmpty();
fn->pn_body = argsbody;
unsigned nargs = fun->nargs;
if (nargs) {
/*
* NB: do not use AutoLocalNameArray because it will release space
* allocated from cx->tempLifoAlloc by DefineArg.
*/
BindingVector names(cx);
if (!GetOrderedBindings(cx, funsc.bindings, &names))
for (unsigned i = 0; i < formals.length(); i++) {
if (!DefineArg(&parser, fn, formals[i]))
return false;
RootedPropertyName name(cx);
for (unsigned i = 0; i < nargs; i++) {
name = names[i].maybeName;
if (!DefineArg(fn, name, i, &parser))
return false;
}
}
/*
@@ -331,7 +304,20 @@ frontend::CompileFunctionBody(JSContext *cx, HandleFunction fun, CompileOptions
if (!FoldConstants(cx, pn, &parser))
return false;
if (!AnalyzeFunctions(&parser, nullCallerFrame))
Rooted<JSScript*> script(cx, JSScript::Create(cx, NullPtr(), false, options,
staticLevel, ss, 0, length));
if (!script)
return false;
if (!funtc.generateBindings(cx, &script->bindings))
return false;
BytecodeEmitter funbce(/* parent = */ NULL, &parser, &funsc, script, /* callerFrame = */ NULL,
/* hasGlobalScope = */ false, options.lineno);
if (!funbce.init())
return false;
if (!AnalyzeFunctions(&parser))
return false;
if (fn->pn_body) {