Bug 741615: Replace Debugger.prototype.wrap with Debugger.Object.prototype.makeDebuggeeValue. r=jorendorff
authorJim Blandy <jimb@mozilla.com>
Thu, 05 Apr 2012 12:30:35 -0700
changeset 94415 0b28f9e01c51c6b38f187e8b3f5d4183d4d19ade
parent 94414 fe8ffd7166eb82cce58630bb8112f6e1e8537196
child 94416 324e1ebd118d47c9b7f164c21015e3877a857395
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs741615
milestone14.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 741615: Replace Debugger.prototype.wrap with Debugger.Object.prototype.makeDebuggeeValue. r=jorendorff
js/src/jit-test/tests/debug/Debugger-wrap-01.js
js/src/jit-test/tests/debug/Object-makeDebuggeeValue-01.js
js/src/jit-test/tests/debug/Object-makeDebuggeeValue-02.js
js/src/vm/Debugger.cpp
deleted file mode 100644
--- a/js/src/jit-test/tests/debug/Debugger-wrap-01.js
+++ /dev/null
@@ -1,34 +0,0 @@
-// Debugger.prototype.wrap creates only one Debugger.Object instance for each debuggee object.
-var g = newGlobal('new-compartment');
-var dbg = new Debugger(g);
-
-g.eval("var x = { 'now playing': 'Joy Division' };");
-g.eval("var y = { 'mood': 'bleak' };");
-
-wx = dbg.wrap(g.x);
-assertEq(wx, dbg.wrap(g.x));
-assertEq(wx === g.x, false);
-assertEq("now playing" in wx, false);
-assertEq(wx.getOwnPropertyNames().indexOf("now playing"), 0);
-wx.commentary = "deconstruction";
-assertEq("deconstruction" in g.x, false);
-
-wy = dbg.wrap(g.y);
-assertEq(wy === wx, false);
-wy.commentary = "reconstruction";
-assertEq(wx.commentary, "deconstruction");
-
-// Separate debuggers get separate wrappers, but they both view the same underlying object.
-var dbg2 = new Debugger(g);
-w2x = dbg2.wrap(g.x);
-assertEq(wx === w2x, false);
-w2x.defineProperty("breadcrumb", { value: "pumpernickel" });
-assertEq(wx.getOwnPropertyDescriptor("breadcrumb").value, "pumpernickel");
-
-// Trying to wrap things that aren't objects should pass them through unchanged.
-assertEq(dbg.wrap("foonting turlingdromes"), "foonting turlingdromes");
-assertEq(dbg.wrap(true), true);
-assertEq(dbg.wrap(false), false);
-assertEq(dbg.wrap(null), null);
-assertEq(dbg.wrap(1729), 1729);
-assertEq(dbg.wrap(undefined), undefined);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Object-makeDebuggeeValue-01.js
@@ -0,0 +1,40 @@
+// Debugger.Object.prototype.makeDebuggeeValue creates only one
+// Debugger.Object instance for each debuggee object.
+
+var g = newGlobal('new-compartment');
+var dbg = new Debugger();
+var gw = dbg.addDebuggee(g);
+
+g.eval("var x = { 'now playing': 'Joy Division' };");
+g.eval("var y = { 'mood': 'bleak' };");
+
+wx = gw.makeDebuggeeValue(g.x);
+assertEq(wx, gw.makeDebuggeeValue(g.x));
+assertEq(wx === g.x, false);
+assertEq("now playing" in wx, false);
+assertEq(wx.getOwnPropertyNames().indexOf("now playing"), 0);
+wx.commentary = "deconstruction";
+assertEq("deconstruction" in g.x, false);
+
+wy = gw.makeDebuggeeValue(g.y);
+assertEq(wy === wx, false);
+wy.commentary = "reconstruction";
+assertEq(wx.commentary, "deconstruction");
+
+// Separate debuggers get separate Debugger.Object instances, but both
+// instances' referents are the same underlying object.
+var dbg2 = new Debugger();
+var gw2 = dbg2.addDebuggee(g);
+w2x = gw2.makeDebuggeeValue(g.x);
+assertEq(wx === w2x, false);
+w2x.defineProperty("breadcrumb", { value: "pumpernickel" });
+assertEq(wx.getOwnPropertyDescriptor("breadcrumb").value, "pumpernickel");
+
+// Non-objects are already debuggee values.
+assertEq(gw.makeDebuggeeValue("foonting turlingdromes"), "foonting turlingdromes");
+assertEq(gw.makeDebuggeeValue(true), true);
+assertEq(gw.makeDebuggeeValue(false), false);
+assertEq(gw.makeDebuggeeValue(null), null);
+assertEq(gw.makeDebuggeeValue(1729), 1729);
+assertEq(gw.makeDebuggeeValue(Math.PI), Math.PI);
+assertEq(gw.makeDebuggeeValue(undefined), undefined);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Object-makeDebuggeeValue-02.js
@@ -0,0 +1,12 @@
+// Debugger.Object.prototype.makeDebuggeeValue returns the object wrapped
+// the same way as Debugger.Frame.prototype.eval, etc.
+var g = newGlobal('new-compartment');
+g.eval("function f() { debugger; }");
+var dbg = Debugger();
+var gw = dbg.addDebuggee(g);
+var jsonw;
+dbg.onDebuggerStatement = function (frame) {
+    jsonw = frame.eval("JSON").return;
+};
+g.eval("debugger;");
+assertEq(gw.makeDebuggeeValue(g.JSON), jsonw);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2048,39 +2048,16 @@ Debugger::findScripts(JSContext *cx, uns
             return false;
         result->setDenseArrayElement(i, ObjectValue(*scriptObject));
     }
 
     args.rval().setObject(*result);
     return true;
 }
 
-JSBool
-Debugger::wrap(JSContext *cx, unsigned argc, Value *vp)
-{
-    REQUIRE_ARGC("Debugger.prototype.wrap", 1);
-    THIS_DEBUGGER(cx, argc, vp, "wrap", args, dbg);
-
-    /* Wrapping a non-object returns the value unchanged. */
-    if (!args[0].isObject()) {
-        args.rval() = args[0];
-        return true;
-    }
-
-    JSObject *obj = dbg->unwrapDebuggeeArgument(cx, args[0]);
-    if (!obj)
-        return false;
-
-    args.rval() = args[0];
-    if (!dbg->wrapDebuggeeValue(cx, &args.rval()))
-        return false;
-
-    return true;
-}
-
 JSPropertySpec Debugger::properties[] = {
     JS_PSGS("enabled", Debugger::getEnabled, Debugger::setEnabled, 0),
     JS_PSGS("onDebuggerStatement", Debugger::getOnDebuggerStatement,
             Debugger::setOnDebuggerStatement, 0),
     JS_PSGS("onExceptionUnwind", Debugger::getOnExceptionUnwind,
             Debugger::setOnExceptionUnwind, 0),
     JS_PSGS("onNewScript", Debugger::getOnNewScript, Debugger::setOnNewScript, 0),
     JS_PSGS("onEnterFrame", Debugger::getOnEnterFrame, Debugger::setOnEnterFrame, 0),
@@ -2092,17 +2069,16 @@ JSPropertySpec Debugger::properties[] = 
 JSFunctionSpec Debugger::methods[] = {
     JS_FN("addDebuggee", Debugger::addDebuggee, 1, 0),
     JS_FN("removeDebuggee", Debugger::removeDebuggee, 1, 0),
     JS_FN("hasDebuggee", Debugger::hasDebuggee, 1, 0),
     JS_FN("getDebuggees", Debugger::getDebuggees, 0, 0),
     JS_FN("getNewestFrame", Debugger::getNewestFrame, 0, 0),
     JS_FN("clearAllBreakpoints", Debugger::clearAllBreakpoints, 1, 0),
     JS_FN("findScripts", Debugger::findScripts, 1, 0),
-    JS_FN("wrap", Debugger::wrap, 1, 0),
     JS_FS_END
 };
 
 
 /*** Debugger.Script *****************************************************************************/
 
 static inline JSScript *
 GetScriptReferent(JSObject *obj)
@@ -3853,16 +3829,43 @@ DebuggerObject_apply(JSContext *cx, unsi
 }
 
 static JSBool
 DebuggerObject_call(JSContext *cx, unsigned argc, Value *vp)
 {
     return ApplyOrCall(cx, argc, vp, CallMode);
 }
 
+static JSBool
+DebuggerObject_makeDebuggeeValue(JSContext *cx, unsigned argc, Value *vp)
+{
+    REQUIRE_ARGC("Debugger.Object.prototype.makeDebuggeeValue", 1);
+    THIS_DEBUGOBJECT_OWNER_REFERENT(cx, argc, vp, "makeDebuggeeValue", args, dbg, referent);
+
+    /* Non-objects are already debuggee values. */
+    if (args[0].isObject()) {
+        // Enter this Debugger.Object's referent's compartment, and wrap the
+        // argument as appropriate for references from there.
+        {
+            AutoCompartment ac(cx, referent);
+            if (!ac.enter() ||
+                !cx->compartment->wrap(cx, &args[0]))
+                return false;
+        }
+
+        // Back in the debugger's compartment, produce a new Debugger.Object
+        // instance referring to the wrapped argument.
+        if (!dbg->wrapDebuggeeValue(cx, &args[0]))
+            return false;
+    }
+
+    args.rval() = args[0];
+    return true;
+}
+
 static JSPropertySpec DebuggerObject_properties[] = {
     JS_PSG("proto", DebuggerObject_getProto, 0),
     JS_PSG("class", DebuggerObject_getClass, 0),
     JS_PSG("callable", DebuggerObject_getCallable, 0),
     JS_PSG("name", DebuggerObject_getName, 0),
     JS_PSG("parameterNames", DebuggerObject_getParameterNames, 0),
     JS_PSG("script", DebuggerObject_getScript, 0),
     JS_PSG("environment", DebuggerObject_getEnvironment, 0),
@@ -3878,16 +3881,17 @@ static JSFunctionSpec DebuggerObject_met
     JS_FN("seal", DebuggerObject_seal, 0, 0),
     JS_FN("freeze", DebuggerObject_freeze, 0, 0),
     JS_FN("preventExtensions", DebuggerObject_preventExtensions, 0, 0),
     JS_FN("isSealed", DebuggerObject_isSealed, 0, 0),
     JS_FN("isFrozen", DebuggerObject_isFrozen, 0, 0),
     JS_FN("isExtensible", DebuggerObject_isExtensible, 0, 0),
     JS_FN("apply", DebuggerObject_apply, 0, 0),
     JS_FN("call", DebuggerObject_call, 0, 0),
+    JS_FN("makeDebuggeeValue", DebuggerObject_makeDebuggeeValue, 1, 0),
     JS_FS_END
 };
 
 
 /*** Debugger.Environment ************************************************************************/
 
 static void
 DebuggerEnv_trace(JSTracer *trc, JSObject *obj)