mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 775807 - Don't disassemble partially-compiled scripts (r=jimb)
--HG-- extra : rebase_source : 5179fd12faea43f227c8369bae4588d5adfebc7c
This commit is contained in:
parent
12e8e98fdf
commit
24a7ebc815
19
js/src/jit-test/tests/basic/testBug775807.js
Normal file
19
js/src/jit-test/tests/basic/testBug775807.js
Normal 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
|
||||
}
|
||||
}
|
||||
})))
|
||||
})()
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user