mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 738480: Simplify Debugger::ScriptQuery after CPG. Fix missing compile-and-go scripts. r=luke
This commit is contained in:
parent
ca5d69fe83
commit
cf6faf87d0
9
js/src/jit-test/tests/debug/Debugger-findScripts-15.js
Normal file
9
js/src/jit-test/tests/debug/Debugger-findScripts-15.js
Normal file
@ -0,0 +1,9 @@
|
||||
// findScripts finds non-compile-and-go scripts
|
||||
|
||||
var g = newGlobal("new-compartment");
|
||||
g.evaluate("function f(x) { return x + 1; }", {compileAndGo: false});
|
||||
var dbg = new Debugger;
|
||||
var gw = dbg.addDebuggee(g);
|
||||
var s = dbg.findScripts();
|
||||
var fw = gw.getOwnPropertyDescriptor("f").value;
|
||||
assertEq(s.indexOf(fw.script) !== -1, true);
|
@ -2126,16 +2126,15 @@ class Debugger::ScriptQuery {
|
||||
public:
|
||||
/* Construct a ScriptQuery to use matching scripts for |dbg|. */
|
||||
ScriptQuery(JSContext *cx, Debugger *dbg):
|
||||
cx(cx), debugger(dbg), compartments(cx), url(cx), innermostForGlobal(cx) {}
|
||||
cx(cx), debugger(dbg), compartments(cx), url(cx), innermostForCompartment(cx) {}
|
||||
|
||||
/*
|
||||
* Initialize this ScriptQuery. Raise an error and return false if we
|
||||
* haven't enough memory.
|
||||
*/
|
||||
bool init() {
|
||||
if (!globals.init() ||
|
||||
!compartments.init() ||
|
||||
!innermostForGlobal.init())
|
||||
if (!compartments.init() ||
|
||||
!innermostForCompartment.init())
|
||||
{
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
@ -2247,29 +2246,7 @@ class Debugger::ScriptQuery {
|
||||
for (CompartmentSet::Range r = compartments.all(); !r.empty(); r.popFront()) {
|
||||
for (gc::CellIter i(r.front(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
RawScript script = i.get<JSScript>();
|
||||
if (script->compileAndGo && !script->isForEval()) {
|
||||
if (!consider(script, &script->global(), vector))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Since eval scripts have no global, we need to find them via the call
|
||||
* stack, where frame's scope tells us the global in use.
|
||||
*/
|
||||
for (ScriptFrameIter fri(cx); !fri.done(); ++fri) {
|
||||
if (fri.isEvalFrame()) {
|
||||
RawScript script = fri.script();
|
||||
|
||||
/*
|
||||
* Eval scripts were not considered above so we don't need to
|
||||
* check the existing script vector for duplicates.
|
||||
*/
|
||||
JS_ASSERT(script->isForEval());
|
||||
|
||||
GlobalObject *global = &fri.interpFrame()->global();
|
||||
if (!consider(script, global, vector))
|
||||
if (!consider(script, vector))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -2277,11 +2254,13 @@ class Debugger::ScriptQuery {
|
||||
/*
|
||||
* For most queries, we just accumulate results in 'vector' as we find
|
||||
* them. But if this is an 'innermost' query, then we've accumulated the
|
||||
* results in the 'innermostForGlobal' map. In that case, we now need to
|
||||
* results in the 'innermostForCompartment' map. In that case, we now need to
|
||||
* walk that map and populate 'vector'.
|
||||
*/
|
||||
if (innermost) {
|
||||
for (GlobalToScriptMap::Range r = innermostForGlobal.all(); !r.empty(); r.popFront()) {
|
||||
for (CompartmentToScriptMap::Range r = innermostForCompartment.all();
|
||||
!r.empty();
|
||||
r.popFront()) {
|
||||
if (!vector->append(r.front().value)) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
@ -2299,13 +2278,10 @@ class Debugger::ScriptQuery {
|
||||
/* The debugger for which we conduct queries. */
|
||||
Debugger *debugger;
|
||||
|
||||
/* A script must run in one of these globals to match the query. */
|
||||
GlobalObjectSet globals;
|
||||
|
||||
typedef HashSet<JSCompartment *, DefaultHasher<JSCompartment *>, RuntimeAllocPolicy>
|
||||
CompartmentSet;
|
||||
|
||||
/* The smallest set of compartments that contains all globals in globals. */
|
||||
/* A script must be in one of these compartments to match the query. */
|
||||
CompartmentSet compartments;
|
||||
|
||||
/* If this is a string, matching scripts have urls equal to it. */
|
||||
@ -2323,20 +2299,20 @@ class Debugger::ScriptQuery {
|
||||
/* True if the query has an 'innermost' property whose value is true. */
|
||||
bool innermost;
|
||||
|
||||
typedef HashMap<GlobalObject *, JSScript *, DefaultHasher<GlobalObject *>, RuntimeAllocPolicy>
|
||||
GlobalToScriptMap;
|
||||
typedef HashMap<JSCompartment *, JSScript *, DefaultHasher<JSCompartment *>, RuntimeAllocPolicy>
|
||||
CompartmentToScriptMap;
|
||||
|
||||
/*
|
||||
* For 'innermost' queries, a map from global objects to the innermost
|
||||
* script we've seen so far in that global. (Instantiation code size
|
||||
* For 'innermost' queries, a map from compartments to the innermost script
|
||||
* we've seen so far in that compartment. (Template instantiation code size
|
||||
* explosion ho!)
|
||||
*/
|
||||
GlobalToScriptMap innermostForGlobal;
|
||||
CompartmentToScriptMap innermostForCompartment;
|
||||
|
||||
/* Arrange for this ScriptQuery to match only scripts that run in |global|. */
|
||||
bool matchSingleGlobal(GlobalObject *global) {
|
||||
JS_ASSERT(globals.count() == 0);
|
||||
if (!globals.put(global)) {
|
||||
JS_ASSERT(compartments.count() == 0);
|
||||
if (!compartments.put(global->compartment())) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
@ -2348,10 +2324,10 @@ class Debugger::ScriptQuery {
|
||||
* globals.
|
||||
*/
|
||||
bool matchAllDebuggeeGlobals() {
|
||||
JS_ASSERT(globals.count() == 0);
|
||||
/* Copy the debugger's set of debuggee globals to our global set. */
|
||||
JS_ASSERT(compartments.count() == 0);
|
||||
/* Build our compartment set from the debugger's set of debuggee globals. */
|
||||
for (GlobalObjectSet::Range r = debugger->debuggees.all(); !r.empty(); r.popFront()) {
|
||||
if (!globals.put(r.front())) {
|
||||
if (!compartments.put(r.front()->compartment())) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
@ -2364,17 +2340,6 @@ class Debugger::ScriptQuery {
|
||||
* match scripts. Set urlCString as appropriate.
|
||||
*/
|
||||
bool prepareQuery() {
|
||||
/*
|
||||
* Compute the proper value for |compartments|, given the present
|
||||
* value of |globals|.
|
||||
*/
|
||||
for (GlobalObjectSet::Range r = globals.all(); !r.empty(); r.popFront()) {
|
||||
if (!compartments.put(r.front()->compartment())) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Compute urlCString, if a url was given. */
|
||||
if (url.isString()) {
|
||||
if (!urlCString.encode(cx, url.toString()))
|
||||
@ -2385,12 +2350,13 @@ class Debugger::ScriptQuery {
|
||||
}
|
||||
|
||||
/*
|
||||
* If |script|, a script in |global|, matches this query, append it to
|
||||
* |vector| or place it in |innermostForGlobal|, as appropriate. Return true
|
||||
* if no error occurs, false if an error occurs.
|
||||
* If |script| matches this query, append it to |vector| or place it in
|
||||
* |innermostForCompartment|, as appropriate. Return true if no error
|
||||
* occurs, false if an error occurs.
|
||||
*/
|
||||
bool consider(JSScript *script, GlobalObject *global, AutoScriptVector *vector) {
|
||||
if (!globals.has(global))
|
||||
bool consider(JSScript *script, AutoScriptVector *vector) {
|
||||
JSCompartment *compartment = script->compartment();
|
||||
if (!compartments.has(compartment))
|
||||
return true;
|
||||
if (urlCString.ptr()) {
|
||||
if (!script->filename || strcmp(script->filename, urlCString.ptr()) != 0)
|
||||
@ -2400,21 +2366,20 @@ class Debugger::ScriptQuery {
|
||||
if (line < script->lineno || script->lineno + js_GetScriptLineExtent(script) < line)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (innermost) {
|
||||
/*
|
||||
* For 'innermost' queries, we don't place scripts in |vector| right
|
||||
* away; we may later find another script that is nested inside this
|
||||
* one. Instead, we record the innermost script we've found so far
|
||||
* for each global in innermostForGlobal, and only populate |vector|
|
||||
* at the bottom of findScripts, when we've traversed all the
|
||||
* scripts.
|
||||
* for each compartment in innermostForCompartment, and only
|
||||
* populate |vector| at the bottom of findScripts, when we've
|
||||
* traversed all the scripts.
|
||||
*
|
||||
* So: check this script against the innermost one we've found so
|
||||
* far (if any), as recorded in innermostForGlobal, and replace that
|
||||
* if it's better.
|
||||
* far (if any), as recorded in innermostForCompartment, and replace
|
||||
* that if it's better.
|
||||
*/
|
||||
GlobalToScriptMap::AddPtr p = innermostForGlobal.lookupForAdd(global);
|
||||
CompartmentToScriptMap::AddPtr p = innermostForCompartment.lookupForAdd(compartment);
|
||||
if (p) {
|
||||
/* Is our newly found script deeper than the last one we found? */
|
||||
JSScript *incumbent = p->value;
|
||||
@ -2423,9 +2388,9 @@ class Debugger::ScriptQuery {
|
||||
} else {
|
||||
/*
|
||||
* This is the first matching script we've encountered for this
|
||||
* global, so it is thus the innermost such script.
|
||||
* compartment, so it is thus the innermost such script.
|
||||
*/
|
||||
if (!innermostForGlobal.add(p, global, script)) {
|
||||
if (!innermostForCompartment.add(p, compartment, script)) {
|
||||
js_ReportOutOfMemory(cx);
|
||||
return false;
|
||||
}
|
||||
|
@ -1052,6 +1052,9 @@ ThreadActor.prototype = {
|
||||
* @returns true, if the script was added, false otherwise.
|
||||
*/
|
||||
_addScript: function TA__addScript(aScript) {
|
||||
// Ignore anything we don't have a URL for (eval scripts, for example).
|
||||
if (!aScript.url)
|
||||
return false;
|
||||
// Ignore XBL bindings for content debugging.
|
||||
if (aScript.url.indexOf("chrome://") == 0) {
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user