From 0a2a9c19f9a963aea93ba17e9a2cd92737bea6d6 Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Sat, 13 Oct 2012 16:04:41 -0700 Subject: [PATCH] Bug 743311: Implement Debugger.prototype.findAllGlobals. r=jorendorff --- .../tests/debug/Debugger-findAllGlobals-01.js | 24 +++++++++++++++++ .../tests/debug/Debugger-findAllGlobals-02.js | 27 +++++++++++++++++++ js/src/vm/Debugger.cpp | 26 ++++++++++++++++++ js/src/vm/Debugger.h | 1 + 4 files changed, 78 insertions(+) create mode 100644 js/src/jit-test/tests/debug/Debugger-findAllGlobals-01.js create mode 100644 js/src/jit-test/tests/debug/Debugger-findAllGlobals-02.js diff --git a/js/src/jit-test/tests/debug/Debugger-findAllGlobals-01.js b/js/src/jit-test/tests/debug/Debugger-findAllGlobals-01.js new file mode 100644 index 00000000000..7400ef9ea1e --- /dev/null +++ b/js/src/jit-test/tests/debug/Debugger-findAllGlobals-01.js @@ -0,0 +1,24 @@ +// Debugger.prototype.findAllGlobals surface. + +load(libdir + 'asserts.js'); + +var dbg = new Debugger; +var d = Object.getOwnPropertyDescriptor(Object.getPrototypeOf(dbg), 'findAllGlobals'); +assertEq(d.configurable, true); +assertEq(d.enumerable, false); +assertEq(d.writable, true); +assertEq(typeof d.value, 'function'); +assertEq(dbg.findAllGlobals.length, 0); +assertEq(dbg.findAllGlobals.name, 'findAllGlobals'); + +// findAllGlobals can only be applied to real Debugger instances. +assertThrowsInstanceOf(function() { + Debugger.prototype.findAllGlobals.call(Debugger.prototype); + }, + TypeError); +var a = dbg.findAllGlobals(); +assertEq(a instanceof Array, true); +assertEq(a.length > 0, true); +for (g of a) { + assertEq(g instanceof Debugger.Object, true); +} diff --git a/js/src/jit-test/tests/debug/Debugger-findAllGlobals-02.js b/js/src/jit-test/tests/debug/Debugger-findAllGlobals-02.js new file mode 100644 index 00000000000..d8766c16095 --- /dev/null +++ b/js/src/jit-test/tests/debug/Debugger-findAllGlobals-02.js @@ -0,0 +1,27 @@ +// Debugger.prototype.findAllGlobals finds ALL the globals! + +var g1 = newGlobal(); // Created before the Debugger; debuggee. +var g2 = newGlobal(); // Created before the Debugger; not debuggee. + +var dbg = new Debugger; + +var g3 = newGlobal(); // Created after the Debugger; debuggee. +var g4 = newGlobal(); // Created after the Debugger; not debuggee. + +var g1w = dbg.addDebuggee(g1); +var g3w = dbg.addDebuggee(g3); + +var a = dbg.findAllGlobals(); + +// Get Debugger.Objects viewing the globals from their own compartments; +// this is the sort that findAllGlobals and addDebuggee return. +var g2w = g1w.makeDebuggeeValue(g2).unwrap(); +var g4w = g1w.makeDebuggeeValue(g4).unwrap(); +var thisw = g1w.makeDebuggeeValue(this).unwrap(); + +// Check that they're all there. +assertEq(a.indexOf(g1w) != -1, true); +assertEq(a.indexOf(g2w) != -1, true); +assertEq(a.indexOf(g3w) != -1, true); +assertEq(a.indexOf(g4w) != -1, true); +assertEq(a.indexOf(thisw) != -1, true); diff --git a/js/src/vm/Debugger.cpp b/js/src/vm/Debugger.cpp index 86dcee2a61a..d1ca3c4ecc6 100644 --- a/js/src/vm/Debugger.cpp +++ b/js/src/vm/Debugger.cpp @@ -16,6 +16,7 @@ #include "jsinterpinlines.h" #include "jsobjinlines.h" #include "jsopcodeinlines.h" +#include "jscompartment.h" #include "frontend/BytecodeCompiler.h" #include "frontend/BytecodeEmitter.h" @@ -2484,6 +2485,30 @@ Debugger::findScripts(JSContext *cx, unsigned argc, Value *vp) return true; } +JSBool +Debugger::findAllGlobals(JSContext *cx, unsigned argc, Value *vp) +{ + THIS_DEBUGGER(cx, argc, vp, "findAllGlobals", args, dbg); + + RootedObject result(cx, NewDenseEmptyArray(cx)); + if (!result) + return false; + + for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) { + GlobalObject *global = c->maybeGlobal(); + if (global) { + Value globalValue(ObjectValue(*global)); + if (!dbg->wrapDebuggeeValue(cx, &globalValue)) + return false; + if (!js_NewbornArrayPush(cx, result, globalValue)) + return false; + } + } + + args.rval().setObject(*result); + return true; +} + JSPropertySpec Debugger::properties[] = { JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0), JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement, @@ -2506,6 +2531,7 @@ JSFunctionSpec Debugger::methods[] = { JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0), JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 1, 0), JS_FN("findScripts", Debugger::findScripts, 1, 0), + JS_FN("findAllGlobals", Debugger::findAllGlobals, 0, 0), JS_FS_END }; diff --git a/js/src/vm/Debugger.h b/js/src/vm/Debugger.h index b4b2e491524..5a8247270a6 100644 --- a/js/src/vm/Debugger.h +++ b/js/src/vm/Debugger.h @@ -181,6 +181,7 @@ class Debugger { static JSBool getNewestFrame(JSContext *cx, unsigned argc, Value *vp); static JSBool clearAllBreakpoints(JSContext *cx, unsigned argc, Value *vp); static JSBool findScripts(JSContext *cx, unsigned argc, Value *vp); + static JSBool findAllGlobals(JSContext *cx, unsigned argc, Value *vp); static JSBool wrap(JSContext *cx, unsigned argc, Value *vp); static JSBool construct(JSContext *cx, unsigned argc, Value *vp); static JSPropertySpec properties[];