Bug 775807 - Don't disassemble partially-compiled scripts (r=jimb)

--HG--
extra : rebase_source : 5179fd12faea43f227c8369bae4588d5adfebc7c
This commit is contained in:
Luke Wagner 2012-07-20 17:16:14 -07:00
parent 12e8e98fdf
commit 24a7ebc815
4 changed files with 64 additions and 4 deletions

View File

@ -0,0 +1,19 @@
// |jit-test| dump-bytecode;error:SyntaxError
(function() {
const x = ((function() {
return {
e: function() {
(function() {
for (e in x) {}
})()
}
}
}(function() {
return {
t: {
c
}
}
})))
})()

View File

@ -1780,8 +1780,10 @@ JS_DumpCompartmentBytecode(JSContext *cx)
ScriptsToDump scripts;
IterateCells(cx->runtime, cx->compartment, gc::FINALIZE_SCRIPT, &scripts, DumpBytecodeScriptCallback);
for (size_t i = 0; i < scripts.length(); i++)
JS_DumpBytecode(cx, scripts[i]);
for (size_t i = 0; i < scripts.length(); i++) {
if (scripts[i]->enclosingScriptsCompiledSuccessfully())
JS_DumpBytecode(cx, scripts[i]);
}
}
JS_PUBLIC_API(void)
@ -1789,7 +1791,7 @@ JS_DumpCompartmentPCCounts(JSContext *cx)
{
for (CellIter i(cx->compartment, gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
JSScript *script = i.get<JSScript>();
if (script->hasScriptCounts)
if (script->hasScriptCounts && script->enclosingScriptsCompiledSuccessfully())
JS_DumpPCCounts(cx, script);
}
}

View File

@ -1860,6 +1860,30 @@ JSScript::numNotes()
return sn - notes_ + 1; /* +1 for the terminator */
}
bool
JSScript::enclosingScriptsCompiledSuccessfully() const
{
/*
* When a nested script is succesfully compiled, it is eagerly given the
* static JSFunction of its enclosing script. The enclosing function's
* 'script' field will be NULL until the enclosing script successfully
* compiles. Thus, we can detect failed compilation by looking for
* JSFunctions in the enclosingScope chain without scripts.
*/
JSObject *enclosing = enclosingScope_;
while (enclosing) {
if (enclosing->isFunction()) {
JSFunction *fun = enclosing->toFunction();
if (!fun->script())
return false;
enclosing = fun->script()->enclosingScope_;
} else {
enclosing = enclosing->asStaticBlock().enclosingStaticScope();
}
}
return true;
}
JS_FRIEND_API(void)
js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun)
{

View File

@ -653,7 +653,22 @@ struct JSScript : public js::gc::Cell
inline js::GlobalObject &global() const;
/* See StaticScopeIter comment. */
JSObject *enclosingStaticScope() const { return enclosingScope_; }
JSObject *enclosingStaticScope() const {
JS_ASSERT(enclosingScriptsCompiledSuccessfully());
return enclosingScope_;
}
/*
* If a compile error occurs in an enclosing function after parsing a
* nested function, the enclosing function's JSFunction, which appears on
* the nested function's enclosingScope chain, will be invalid. Normal VM
* operation only sees scripts where all enclosing scripts have been
* successfully compiled. Any path that may look at scripts left over from
* unsuccessful compilation (e.g., by iterating over all scripts in the
* compartment) should check this predicate before doing any operation that
* uses enclosingScope (e.g., ScopeCoordinateName).
*/
bool enclosingScriptsCompiledSuccessfully() const;
private:
bool makeTypes(JSContext *cx);