From f98bcedaf3f878255ac06de79415cdfe2da11533 Mon Sep 17 00:00:00 2001 From: Jason Orendorff Date: Mon, 18 Apr 2011 23:52:17 -0500 Subject: [PATCH] Add Debug.prototype.enabled. This implementation is not ideal, since we want clearing .enabled to remove the debugger from every place where it might cause overhead. For now it just sets a flag. --- js/src/jsdbg.cpp | 22 ++++++++++++++- js/src/jsdbg.h | 6 +++- .../js1_8_5/extensions/debug-object-16.js | 23 +++++++++++++++ .../js1_8_5/extensions/debug-object-17.js | 28 +++++++++++++++++++ js/src/tests/js1_8_5/extensions/jstests.list | 2 ++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 js/src/tests/js1_8_5/extensions/debug-object-16.js create mode 100644 js/src/tests/js1_8_5/extensions/debug-object-17.js diff --git a/js/src/jsdbg.cpp b/js/src/jsdbg.cpp index 6e98465116d..717ace2781e 100644 --- a/js/src/jsdbg.cpp +++ b/js/src/jsdbg.cpp @@ -114,7 +114,8 @@ CheckThisClass(JSContext *cx, Value *vp, Class *clasp, const char *fnname) // === Debug hook dispatch Debug::Debug(JSObject *dbg, JSObject *hooks, JSCompartment *compartment) - : object(dbg), debuggeeCompartment(compartment), hooksObject(hooks), hasDebuggerHandler(false) + : object(dbg), debuggeeCompartment(compartment), hooksObject(hooks), + enabled(true), hasDebuggerHandler(false) { } @@ -347,6 +348,24 @@ Debug::setHooks(JSContext *cx, uintN argc, Value *vp) return true; } +JSBool +Debug::getEnabled(JSContext *cx, uintN argc, Value *vp) +{ + THISOBJ(cx, vp, Debug, "get enabled", thisobj, dbg); + vp->setBoolean(dbg->enabled); + return true; +} + +JSBool +Debug::setEnabled(JSContext *cx, uintN argc, Value *vp) +{ + REQUIRE_ARGC("Debug.set enabled", 1); + THISOBJ(cx, vp, Debug, "set enabled", thisobj, dbg); + dbg->enabled = js_ValueToBoolean(vp[2]); + vp->setUndefined(); + return true; +} + JSBool Debug::construct(JSContext *cx, uintN argc, Value *vp) { @@ -395,6 +414,7 @@ Debug::construct(JSContext *cx, uintN argc, Value *vp) JSPropertySpec Debug::properties[] = { JS_PSGS("hooks", Debug::getHooks, Debug::setHooks, 0), + JS_PSGS("enabled", Debug::getEnabled, Debug::setEnabled, 0), JS_PS_END }; diff --git a/js/src/jsdbg.h b/js/src/jsdbg.h index 61cd3b5e180..267d2d476c8 100644 --- a/js/src/jsdbg.h +++ b/js/src/jsdbg.h @@ -57,6 +57,8 @@ class Debug { JSCompartment *debuggeeCompartment; // Weak reference. JSObject *hooksObject; // See Debug.prototype.hooks. Strong reference. + bool enabled; + // True if hooksObject had a debuggerHandler property when the hooks // property was set. bool hasDebuggerHandler; @@ -70,6 +72,8 @@ class Debug { static Class jsclass; static JSBool getHooks(JSContext *cx, uintN argc, Value *vp); static JSBool setHooks(JSContext *cx, uintN argc, Value *vp); + static JSBool getEnabled(JSContext *cx, uintN argc, Value *vp); + static JSBool setEnabled(JSContext *cx, uintN argc, Value *vp); static JSBool construct(JSContext *cx, uintN argc, Value *vp); static JSPropertySpec properties[]; @@ -109,7 +113,7 @@ class Debug { return debuggeeCompartment == c; } - bool observesDebuggerStatement() const { return hasDebuggerHandler; } + bool observesDebuggerStatement() const { return enabled && hasDebuggerHandler; } JSTrapStatus onDebuggerStatement(JSContext *cx, Value *vp); }; diff --git a/js/src/tests/js1_8_5/extensions/debug-object-16.js b/js/src/tests/js1_8_5/extensions/debug-object-16.js new file mode 100644 index 00000000000..5f6369c6784 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/debug-object-16.js @@ -0,0 +1,23 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +var desc = Object.getOwnPropertyDescriptor(Debug.prototype, "enabled"); +assertEq(typeof desc.get, 'function'); +assertEq(typeof desc.set, 'function'); + +var g = newGlobal('new-compartment'); +var hits; +var dbg = new Debug(g); +assertEq(dbg.enabled, true); +dbg.hooks = {debuggerHandler: function () { hits++; }}; + +var vals = [true, false, null, undefined, NaN, "blah", {}]; +for (var i = 0; i < vals.length; i++) { + dbg.enabled = vals[i]; + assertEq(dbg.enabled, !!vals[i]); + hits = 0; + g.eval("debugger;"); + assertEq(hits, vals[i] ? 1 : 0); +} + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/debug-object-17.js b/js/src/tests/js1_8_5/extensions/debug-object-17.js new file mode 100644 index 00000000000..424b6271db4 --- /dev/null +++ b/js/src/tests/js1_8_5/extensions/debug-object-17.js @@ -0,0 +1,28 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/licenses/publicdomain/ + +// Disabling a Debug object causes events to stop being delivered to it +// immediately, even if we're in the middle of dispatching. + +var g = newGlobal('new-compartment'); +var log; + +var arr = []; +for (var i = 0; i < 4; i++) { + arr[i] = new Debug(g); + arr[i].hooks = { + num: i, + debuggerHandler: function () { + log += this.num; + // Disable them all. + for (var j = 0; j < arr.length; j++) + arr[j].enabled = false; + } + }; +} + +log = ''; +g.eval("debugger; debugger;"); +assertEq(log, '0'); + +reportCompare(0, 0, 'ok'); diff --git a/js/src/tests/js1_8_5/extensions/jstests.list b/js/src/tests/js1_8_5/extensions/jstests.list index fd2958f41a3..0ea54c1165a 100644 --- a/js/src/tests/js1_8_5/extensions/jstests.list +++ b/js/src/tests/js1_8_5/extensions/jstests.list @@ -56,3 +56,5 @@ skip-if(!xulRuntime.shell) script debug-object-12.js skip-if(!xulRuntime.shell) script debug-object-13.js skip-if(!xulRuntime.shell) script debug-object-14.js skip-if(!xulRuntime.shell) script debug-object-15.js +skip-if(!xulRuntime.shell) script debug-object-16.js +skip-if(!xulRuntime.shell) script debug-object-17.js