Last active
December 17, 2015 14:49
-
-
Save simonlindholm/5627711 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From a4537a44618140589f8448281d6f7616bf9ff09c Mon Sep 17 00:00:00 2001 | |
From: Simon Lindholm <[email protected]> | |
Date: Wed, 22 May 2013 15:52:57 +0200 | |
Subject: [PATCH] Add Debugger.prototype.makeDebuggeeValueFromGlobal | |
--- | |
Debugger-makeDebuggeeValueFromGlobal-01.js | 31 ++++++++++++++++++++++++++++++ | |
Debugger.cpp | 26 ++++++++++++++++++++++--- | |
Debugger.h | 2 +- | |
3 files changed, 55 insertions(+), 4 deletions(-) | |
create mode 100644 Debugger-makeDebuggeeValueFromGlobal-01.js | |
diff --git a/Debugger-makeDebuggeeValueFromGlobal-01.js b/Debugger-makeDebuggeeValueFromGlobal-01.js | |
new file mode 100644 | |
index 0000000..3836f2d | |
--- /dev/null | |
+++ b/Debugger-makeDebuggeeValueFromGlobal-01.js | |
@@ -0,0 +1,31 @@ | |
+// Debugger.prototype.makeDebuggeeValueFromGlobal creates a debuggee value from | |
+// a global without adding it as a debuggee. | |
+ | |
+var g = newGlobal(); | |
+var dbg = new Debugger(); | |
+ | |
+var gw = dbg.makeDebuggeeValueFromGlobal(g); | |
+assertEq(dbg.hasDebuggee(g), false); | |
+ | |
+ | |
+// Sanity test that the object is usable without having to be a debuggee. | |
+ | |
+assertEq(gw.getOwnPropertyDescriptor('Math').value, gw.makeDebuggeeValue(g.Math)); | |
+assertEq(gw['class'], 'global'); | |
+assertEq(gw.callable, false); | |
+assertEq(gw.global, gw); | |
+ | |
+assertEq(gw.evalInGlobal('1+1'), 2); | |
+ | |
+g.eval('with ({a: 1}) { function f(x) { eval(x); } }'); | |
+var df = gw.makeDebuggeeValue(g.f); | |
+assertEq(df.environment.getVariable('a'), 1); | |
+ | |
+assertEq(gw.asEnvironment().object, gw); | |
+ | |
+assertEq(df.callable, true); | |
+assertEq(df.script, undefined); | |
+ | |
+ | |
+var gw2 = dbg.addDebuggee(g); | |
+assertEq(gw, gw2); | |
diff --git a/Debugger.cpp b/Debugger.cpp | |
index 89cc92c..898a072 100644 | |
--- a/Debugger.cpp | |
+++ b/Debugger.cpp | |
@@ -1869,28 +1869,31 @@ Debugger::setUncaughtExceptionHook(JSContext *cx, unsigned argc, Value *vp) | |
} | |
dbg->uncaughtExceptionHook = args[0].toObjectOrNull(); | |
args.rval().setUndefined(); | |
return true; | |
} | |
GlobalObject * | |
-Debugger::unwrapDebuggeeArgument(JSContext *cx, const Value &v) | |
+Debugger::unwrapDebuggeeArgument(JSContext *cx, const Value &v, bool allowDO) | |
{ | |
if (!v.isObject()) { | |
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_UNEXPECTED_TYPE, | |
"argument", "not a global object"); | |
return NULL; | |
} | |
RootedObject obj(cx, &v.toObject()); | |
- /* If it's a Debugger.Object belonging to this debugger, dereference that. */ | |
- if (obj->getClass() == &DebuggerObject_class) { | |
+ /* | |
+ * If it's a Debugger.Object belonging to this debugger, dereference that if | |
+ * the caller allows us. | |
+ */ | |
+ if (allowDO && obj->getClass() == &DebuggerObject_class) { | |
RootedValue rv(cx, v); | |
if (!unwrapDebuggeeValue(cx, &rv)) | |
return NULL; | |
obj = &rv.toObject(); | |
} | |
/* If we have a cross-compartment wrapper, dereference as far as is secure. */ | |
obj = CheckedUnwrap(obj); | |
@@ -1929,16 +1932,32 @@ Debugger::addDebuggee(JSContext *cx, unsigned argc, Value *vp) | |
RootedValue v(cx, ObjectValue(*global)); | |
if (!dbg->wrapDebuggeeValue(cx, &v)) | |
return false; | |
args.rval().set(v); | |
return true; | |
} | |
JSBool | |
+Debugger::makeDebuggeeValueFromGlobal(JSContext *cx, unsigned argc, Value *vp) | |
+{ | |
+ REQUIRE_ARGC("Debugger.makeDebuggeeValueFromGlobal", 1); | |
+ THIS_DEBUGGER(cx, argc, vp, "makeDebuggeeValueFromGlobal", args, dbg); | |
+ Rooted<GlobalObject*> global(cx, dbg->unwrapDebuggeeArgument(cx, args[0], false)); | |
+ if (!global) | |
+ return false; | |
+ | |
+ RootedValue v(cx, ObjectValue(*global)); | |
+ if (!dbg->wrapDebuggeeValue(cx, &v)) | |
+ return false; | |
+ args.rval().set(v); | |
+ return true; | |
+} | |
+ | |
+JSBool | |
Debugger::addAllGlobalsAsDebuggees(JSContext *cx, unsigned argc, Value *vp) | |
{ | |
THIS_DEBUGGER(cx, argc, vp, "addAllGlobalsAsDebuggees", args, dbg); | |
AutoDebugModeGC dmgc(cx->runtime); | |
for (CompartmentsIter c(cx->runtime); !c.done(); c.next()) { | |
if (c == dbg->object->compartment()) | |
continue; | |
c->zone()->scheduledForDestruction = false; | |
@@ -2649,16 +2668,17 @@ const JSFunctionSpec Debugger::methods[] = { | |
JS_FN("removeDebuggee", Debugger::removeDebuggee, 1, 0), | |
JS_FN("removeAllDebuggees", Debugger::removeAllDebuggees, 0, 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("findAllGlobals", Debugger::findAllGlobals, 0, 0), | |
+ JS_FN("makeDebuggeeValueFromGlobal", Debugger::makeDebuggeeValueFromGlobal, 1, 0), | |
JS_FS_END | |
}; | |
/*** Debugger.Script *****************************************************************************/ | |
static inline JSScript * | |
GetScriptReferent(JSObject *obj) | |
diff --git a/Debugger.h b/Debugger.h | |
index faa4352..e029f1e 100644 | |
--- a/Debugger.h | |
+++ b/Debugger.h | |
@@ -280,17 +280,17 @@ class Debugger : private mozilla::LinkedListElement<Debugger> | |
* null - Return JSTRAP_ERROR to terminate the debuggee with an | |
* uncatchable error. | |
* anything else - Make a new TypeError the pending exception and | |
* return handleUncaughtException(ac, vp, callHook). | |
*/ | |
JSTrapStatus parseResumptionValue(mozilla::Maybe<AutoCompartment> &ac, bool ok, const Value &rv, | |
MutableHandleValue vp, bool callHook = true); | |
- GlobalObject *unwrapDebuggeeArgument(JSContext *cx, const Value &v); | |
+ GlobalObject *unwrapDebuggeeArgument(JSContext *cx, const Value &v, bool allowDO = true); | |
static void traceObject(JSTracer *trc, JSObject *obj); | |
void trace(JSTracer *trc); | |
static void finalize(FreeOp *fop, JSObject *obj); | |
void markKeysInCompartment(JSTracer *tracer); | |
static Class jsclass; | |
-- | |
1.8.1.2 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment