mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-09 13:25:00 +00:00
Bug 998908 - Mark inner objects inside eval'd scripts before firing Debugger's onNewScript hook. (r=till)
This commit is contained in:
parent
df87b3b9de
commit
d99af5333f
@ -191,30 +191,6 @@ TryEvalJSON(JSContext *cx, JSScript *callerScript,
|
||||
return EvalJSON_NotJSON;
|
||||
}
|
||||
|
||||
static void
|
||||
MarkFunctionsWithinEvalScript(JSScript *script)
|
||||
{
|
||||
// Mark top level functions in an eval script as being within an eval and,
|
||||
// if applicable, inside a with statement.
|
||||
|
||||
if (!script->hasObjects())
|
||||
return;
|
||||
|
||||
ObjectArray *objects = script->objects();
|
||||
size_t start = script->innerObjectsStart();
|
||||
|
||||
for (size_t i = start; i < objects->length; i++) {
|
||||
JSObject *obj = objects->vector[i];
|
||||
if (obj->is<JSFunction>()) {
|
||||
JSFunction *fun = &obj->as<JSFunction>();
|
||||
if (fun->hasScript())
|
||||
fun->nonLazyScript()->setDirectlyInsideEval();
|
||||
else if (fun->isInterpretedLazy())
|
||||
fun->lazyScript()->setDirectlyInsideEval();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Define subset of ExecuteType so that casting performs the injection.
|
||||
enum EvalType { DIRECT_EVAL = EXECUTE_DIRECT_EVAL, INDIRECT_EVAL = EXECUTE_INDIRECT_EVAL };
|
||||
|
||||
@ -327,8 +303,6 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, AbstractFrame
|
||||
if (!compiled)
|
||||
return false;
|
||||
|
||||
MarkFunctionsWithinEvalScript(compiled);
|
||||
|
||||
esg.setNewScript(compiled);
|
||||
}
|
||||
|
||||
@ -396,8 +370,6 @@ js::DirectEvalStringFromIon(JSContext *cx,
|
||||
if (!compiled)
|
||||
return false;
|
||||
|
||||
MarkFunctionsWithinEvalScript(compiled);
|
||||
|
||||
esg.setNewScript(compiled);
|
||||
}
|
||||
|
||||
|
@ -152,6 +152,30 @@ CanLazilyParse(ExclusiveContext *cx, const ReadOnlyCompileOptions &options)
|
||||
cx->compartment()->runtimeFromAnyThread()->debugHooks.newScriptHook);
|
||||
}
|
||||
|
||||
static void
|
||||
MarkFunctionsWithinEvalScript(JSScript *script)
|
||||
{
|
||||
// Mark top level functions in an eval script as being within an eval and,
|
||||
// if applicable, inside a with statement.
|
||||
|
||||
if (!script->hasObjects())
|
||||
return;
|
||||
|
||||
ObjectArray *objects = script->objects();
|
||||
size_t start = script->innerObjectsStart();
|
||||
|
||||
for (size_t i = start; i < objects->length; i++) {
|
||||
JSObject *obj = objects->vector[i];
|
||||
if (obj->is<JSFunction>()) {
|
||||
JSFunction *fun = &obj->as<JSFunction>();
|
||||
if (fun->hasScript())
|
||||
fun->nonLazyScript()->setDirectlyInsideEval();
|
||||
else if (fun->isInterpretedLazy())
|
||||
fun->lazyScript()->setDirectlyInsideEval();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
frontend::MaybeCallSourceHandler(JSContext *cx, const ReadOnlyCompileOptions &options,
|
||||
SourceBufferHolder &srcBuf)
|
||||
@ -420,6 +444,12 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco
|
||||
if (!JSScript::fullyInitFromEmitter(cx, script, &bce))
|
||||
return nullptr;
|
||||
|
||||
// Note that this marking must happen before we tell Debugger
|
||||
// about the new script, in case Debugger delazifies the script's
|
||||
// inner functions.
|
||||
if (options.forEval)
|
||||
MarkFunctionsWithinEvalScript(script);
|
||||
|
||||
bce.tellDebuggerAboutCompiledScript(cx);
|
||||
|
||||
if (sct && !extraSct && !sct->complete())
|
||||
|
16
js/src/jit-test/tests/debug/Script-getChildScripts-05.js
Normal file
16
js/src/jit-test/tests/debug/Script-getChildScripts-05.js
Normal file
@ -0,0 +1,16 @@
|
||||
// Test that lazy inner functions inside eval are tagged properly so we don't
|
||||
// incorrectly do NAME -> GNAME optimization.
|
||||
|
||||
var g = newGlobal();
|
||||
var dbg = new Debugger(g);
|
||||
dbg.onNewScript = function delazify(script, global) {
|
||||
// Force delazification of inner functions.
|
||||
script.getChildScripts();
|
||||
};
|
||||
|
||||
g.eval("" + function f() {
|
||||
var $;
|
||||
eval('var obj={foo:1}; $=function() { assertEq(obj.foo, 1); }');
|
||||
return $;
|
||||
});
|
||||
g.eval("f()();");
|
Loading…
Reference in New Issue
Block a user