Backed out changeset bba922f6d4f3 (bug 914405) for mochitest-bc bustage

This commit is contained in:
Wes Kocher 2013-09-17 17:34:51 -07:00
parent 38282113a2
commit edaeb7bf86
7 changed files with 93 additions and 167 deletions

View File

@ -1,26 +0,0 @@
// Debugger.prototype.makeGlobalObjectReference returns a D.O for a global
// without adding it as a debuggee.
let g1 = newGlobal();
let dbg = new Debugger;
assertEq(dbg.hasDebuggee(g1), false);
let g1w = dbg.makeGlobalObjectReference(g1);
assertEq(dbg.hasDebuggee(g1), false);
assertEq(g1w.unsafeDereference(), g1);
assertEq(g1w, g1w.makeDebuggeeValue(g1));
assertEq(dbg.addDebuggee(g1w), g1w);
assertEq(dbg.hasDebuggee(g1), true);
assertEq(dbg.hasDebuggee(g1w), true);
assertEq(g1w.unsafeDereference(), g1);
assertEq(g1w, g1w.makeDebuggeeValue(g1));
// makeGlobalObjectReference dereferences CCWs.
let g2 = newGlobal();
g2.g1 = g1;
let g2w = dbg.addDebuggee(g2);
let g2g1w = g2w.getOwnPropertyDescriptor('g1').value;
assertEq(g2g1w !== g1w, true);
assertEq(g2g1w.unwrap(), g1w);
assertEq(dbg.makeGlobalObjectReference(g2g1w), g1w);

View File

@ -1,13 +0,0 @@
// Debugger.prototype.makeGlobalObjectReference only accepts actual global objects.
load(libdir + 'asserts.js');
var dbg = new Debugger;
assertThrowsInstanceOf(() => dbg.makeGlobalObjectReference(true), TypeError);
assertThrowsInstanceOf(() => dbg.makeGlobalObjectReference("foo"), TypeError);
assertThrowsInstanceOf(() => dbg.makeGlobalObjectReference(12), TypeError);
assertThrowsInstanceOf(() => dbg.makeGlobalObjectReference(undefined), TypeError);
assertThrowsInstanceOf(() => dbg.makeGlobalObjectReference(null), TypeError);
assertThrowsInstanceOf(() => dbg.makeGlobalObjectReference({ xlerb: "sbot" }), TypeError);
assertEq(dbg.makeGlobalObjectReference(this) instanceof Debugger.Object, true);

View File

@ -2665,20 +2665,6 @@ Debugger::findAllGlobals(JSContext *cx, unsigned argc, Value *vp)
return true;
}
bool
Debugger::makeGlobalObjectReference(JSContext *cx, unsigned argc, Value *vp)
{
REQUIRE_ARGC("Debugger.makeGlobalObjectReference", 1);
THIS_DEBUGGER(cx, argc, vp, "makeGlobalObjectReference", args, dbg);
Rooted<GlobalObject *> global(cx, dbg->unwrapDebuggeeArgument(cx, args[0]));
if (!global)
return false;
args.rval().setObject(*global);
return dbg->wrapDebuggeeValue(cx, args.rval());
}
const JSPropertySpec Debugger::properties[] = {
JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0),
JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
@ -2704,7 +2690,6 @@ const JSFunctionSpec Debugger::methods[] = {
JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 1, 0),
JS_FN("findScripts", Debugger::findScripts, 1, 0),
JS_FN("findAllGlobals", Debugger::findAllGlobals, 0, 0),
JS_FN("makeGlobalObjectReference", Debugger::makeGlobalObjectReference, 1, 0),
JS_FS_END
};

View File

@ -334,7 +334,6 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
static bool clearAllBreakpoints(JSContext *cx, unsigned argc, Value *vp);
static bool findScripts(JSContext *cx, unsigned argc, Value *vp);
static bool findAllGlobals(JSContext *cx, unsigned argc, Value *vp);
static bool makeGlobalObjectReference(JSContext *cx, unsigned argc, Value *vp);
static bool construct(JSContext *cx, unsigned argc, Value *vp);
static const JSPropertySpec properties[];
static const JSFunctionSpec methods[];

View File

@ -59,9 +59,13 @@ function WebConsoleActor(aConnection, aParentActor)
this.dbg = new Debugger();
this._protoChains = new Map();
this._dbgGlobals = new Map();
this._netEvents = new Map();
this._getDebuggerGlobal(this.window);
this._onObserverNotification = this._onObserverNotification.bind(this);
Services.obs.addObserver(this._onObserverNotification,
"inner-window-destroyed", false);
if (this.parentActor.isRootActor) {
Services.obs.addObserver(this._onObserverNotification,
"last-pb-context-exited", false);
@ -92,6 +96,14 @@ WebConsoleActor.prototype =
*/
_prefs: null,
/**
* Holds a map between inner window IDs and Debugger.Objects for the window
* objects.
* @private
* @type Map
*/
_dbgGlobals: null,
/**
* Holds a map between nsIChannel objects and NetworkEventActors for requests
* created with sendHTTPRequest.
@ -187,6 +199,8 @@ WebConsoleActor.prototype =
this.consoleProgressListener = null;
}
this.conn.removeActorPool(this._actorPool);
Services.obs.removeObserver(this._onObserverNotification,
"inner-window-destroyed");
if (this.parentActor.isRootActor) {
Services.obs.removeObserver(this._onObserverNotification,
"last-pb-context-exited");
@ -195,6 +209,7 @@ WebConsoleActor.prototype =
this._netEvents.clear();
this._protoChains.clear();
this._dbgGlobals.clear();
this.dbg.enabled = false;
this.dbg = null;
this.conn = null;
@ -233,7 +248,16 @@ WebConsoleActor.prototype =
// The above can throw an exception if aValue is not an actual object.
}
}
let dbgGlobal = this.dbg.makeGlobalObjectReference(global);
let dbgGlobal = null;
try {
dbgGlobal = this._getDebuggerGlobal(global);
}
catch (ex) {
// The above call can throw in addDebuggee() if the given global object
// is already in the stackframe of code that is executing now. Console.jsm
// and the Browser Console can cause this case.
dbgGlobal = this._getDebuggerGlobal(this.window);
}
return dbgGlobal.makeDebuggeeValue(aValue);
},
@ -643,6 +667,27 @@ WebConsoleActor.prototype =
// End of request handlers.
//////////////////
/**
* Get the Debugger.Object for the given global object (usually a window
* object).
*
* @private
* @param object aGlobal
* The global object for which you want a Debugger.Object.
* @return Debugger.Object
* The Debugger.Object for the given global object.
*/
_getDebuggerGlobal: function WCA__getDebuggerGlobal(aGlobal)
{
let windowId = WebConsoleUtils.getInnerWindowId(aGlobal);
if (!this._dbgGlobals.has(windowId)) {
let dbgGlobal = this.dbg.addDebuggee(aGlobal);
this.dbg.removeDebuggee(aGlobal);
this._dbgGlobals.set(windowId, dbgGlobal);
}
return this._dbgGlobals.get(windowId);
},
/**
* Create an object with the API we expose to the Web Console during
* JavaScript evaluation.
@ -742,6 +787,16 @@ WebConsoleActor.prototype =
aString = "help()";
}
// Find the Debugger.Object of the given ObjectActor. This is used as
// a binding during eval: |_self|.
let bindSelf = null;
if (aOptions.bindObjectActor) {
let objActor = this.getActorByID(aOptions.bindObjectActor);
if (objActor) {
bindSelf = objActor.obj;
}
}
// Find the Debugger.Frame of the given FrameActor.
let frame = null, frameActor = null;
if (aOptions.frameActor) {
@ -755,31 +810,36 @@ WebConsoleActor.prototype =
}
}
// If we've been given a frame actor in whose scope we should evaluate the
// expression, be sure to use that frame's Debugger (that is, the JavaScript
// debugger's Debugger) for the whole operation, not the console's Debugger.
// (One Debugger will treat a different Debugger's Debugger.Object instances
// as ordinary objects, not as references to be followed, so mixing
// debuggers causes strange behaviors.)
let dbg = frame ? frameActor.threadActor.dbg : this.dbg;
let dbgWindow = dbg.makeGlobalObjectReference(this.window);
// Determine which debugger to use, depending on the presence of the
// stackframe.
// This helps with avoid having bindings from a different Debugger. The
// Debugger.Frame comes from the jsdebugger's Debugger instance.
let dbg = this.dbg;
let dbgWindow = this._getDebuggerGlobal(this.window);
if (frame) {
dbg = frameActor.threadActor.dbg;
dbgWindow = dbg.addDebuggee(this.window);
}
// If we have an object to bind to |_self|, create a Debugger.Object
// referring to that object, belonging to dbg.
let bindSelf = null;
let dbgWindow = dbg.makeGlobalObjectReference(this.window);
if (aOptions.bindObjectActor) {
let objActor = this.getActorByID(aOptions.bindObjectActor);
if (objActor) {
let jsObj = objActor.obj.unsafeDereference();
// If we use the makeDebuggeeValue method of jsObj's own global, then
// we'll get a D.O that sees jsObj as viewed from its own compartment -
// that is, without wrappers. The evalWithBindings call will then wrap
// jsObj appropriately for the evaluation compartment.
let global = Cu.getGlobalForObject(jsObj);
dbgWindow = dbg.makeGlobalObjectReference(global);
bindSelf = dbgWindow.makeDebuggeeValue(jsObj);
// If we have an object to bind to |_self| we need to determine the
// global of the given JavaScript object.
if (bindSelf) {
let jsObj = bindSelf.unsafeDereference();
let global = Cu.getGlobalForObject(jsObj);
// Get the Debugger.Object for the new global.
if (global != this.window) {
dbgWindow = dbg.addDebuggee(global);
// Remove the debuggee only if the Debugger instance belongs to the
// console actor, to avoid breaking the ThreadActor that owns the
// Debugger object.
if (dbg == this.dbg) {
dbg.removeDebuggee(global);
}
}
bindSelf = dbgWindow.makeDebuggeeValue(jsObj);
}
// Get the JSTerm helpers for the given debugger window.
@ -1085,7 +1145,8 @@ WebConsoleActor.prototype =
},
/**
* Notification observer for the "last-pb-context-exited" topic.
* Notification observer for the "inner-window-destroyed" topic. This function
* cleans up |this._dbgGlobals| when needed.
*
* @private
* @param object aSubject
@ -1097,6 +1158,13 @@ WebConsoleActor.prototype =
_onObserverNotification: function WCA__onObserverNotification(aSubject, aTopic)
{
switch (aTopic) {
case "inner-window-destroyed": {
let windowId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (this._dbgGlobals.has(windowId)) {
this._dbgGlobals.delete(windowId);
}
break;
}
case "last-pb-context-exited":
this.conn.send({
from: this.actorID,

View File

@ -27,7 +27,6 @@ MOCHITEST_CHROME_FILES = \
test_styles-matched.html \
test_styles-modify.html \
test_unsafeDereference.html \
test_makeGlobalObjectReference.html \
nonchrome_unsafeDereference.html \
test_connection-manager.html \
test_device.html \

View File

@ -1,86 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=914405
Debugger.prototype.makeGlobalObjectReference should dereference WindowProxy
(outer window) objects.
-->
<head>
<meta charset="utf-8">
<title>Mozilla Bug 914405</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css">
</head>
<body>
<pre id="test">
<script>
Components.utils.import("resource://gre/modules/jsdebugger.jsm");
addDebuggerToGlobal(this);
window.onload = function () {
SimpleTest.waitForExplicitFinish();
var iframe = document.createElement("iframe");
iframe.src = "data:text/html,<html>The word 'smorgasbord', spoken by an adorably plump child, symbolizing prosperity</html>";
iframe.onload = iframeOnLoad;
document.body.appendChild(iframe);
function iframeOnLoad() {
var dbg = new Debugger;
var g1o = iframe.contentWindow; // 'o' for 'outer window'
ok(!dbg.hasDebuggee(g1o), "iframe is not initially a debuggee");
// Like addDebuggee, makeGlobalObjectReference innerizes.
// 'i' stands for 'inner window'.
// 'DO' stands for 'Debugger.Object'.
var g1iDO = dbg.makeGlobalObjectReference(g1o);
ok(!dbg.hasDebuggee(g1o), "makeGlobalObjectReference does not add g1 as debuggee, designated via outer");
ok(!dbg.hasDebuggee(g1iDO), "makeGlobalObjectReference does not add g1 as debuggee, designated via D.O ");
// Wrapping an object automatically outerizes it, so dereferencing an
// inner object D.O gets you an outer object.
// ('===' does distinguish inner and outer objects.)
// (That's a capital '=', if you must know.)
ok(g1iDO.unsafeDereference() === g1o, "g1iDO has the right referent");
// However, Debugger.Objects do distinguish inner and outer windows.
var g1oDO = g1iDO.makeDebuggeeValue(g1o);
ok(g1iDO !== g1oDO, "makeDebuggeeValue doesn't innerize");
ok(g1iDO.unsafeDereference() === g1oDO.unsafeDereference(),
"unsafeDereference() outerizes, so inner and outer window D.Os both dereference to outer");
ok(dbg.addDebuggee(g1o) === g1iDO, "addDebuggee returns the inner window's D.O");
ok(dbg.hasDebuggee(g1o), "addDebuggee adds the correct global");
ok(dbg.hasDebuggee(g1iDO), "hasDebuggee can take a D.O referring to the inner window");
ok(dbg.hasDebuggee(g1oDO), "hasDebuggee can take a D.O referring to the outer window");
var iframe2 = document.createElement("iframe");
iframe2.src = "data:text/html,<html>Her retrospection, in hindsight, was prescient.</html>";
iframe2.onload = iframe2OnLoad;
document.body.appendChild(iframe2);
function iframe2OnLoad() {
// makeGlobalObjectReference dereferences CCWs.
var g2o = iframe2.contentWindow;
g2o.g1o = g1o;
var g2iDO = dbg.addDebuggee(g2o);
var g2g1oDO = g2iDO.getOwnPropertyDescriptor('g1o').value;
ok(g2g1oDO !== g1oDO, "g2's cross-compartment wrapper for g1o gets its own D.O");
ok(g2g1oDO.unwrap() === g1oDO,
"unwrapping g2's cross-compartment wrapper for g1o gets the right D.O");
ok(dbg.makeGlobalObjectReference(g2g1oDO) === g1iDO,
"makeGlobalObjectReference unwraps cross-compartment wrappers, and innerizes");
SimpleTest.finish();
}
}
}
</script>
</pre>
</body>
</html>