Bug 743351: Implement Debugger.Script.prototype.staticLevel. r=jorendorff
authorJim Blandy <jimb@mozilla.com>
Fri, 13 Apr 2012 13:17:18 -0700
changeset 94954 4a6a021e38cab64c8910ac4fa39ae81e9b484a9a
parent 94953 92e87abb646b56b804779c049cf128ce76818867
child 94955 a93b99783b8c80955114a96209212b556eae8188
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
bugs743351
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 743351: Implement Debugger.Script.prototype.staticLevel. r=jorendorff
js/src/jit-test/tests/debug/Script-staticLevel.js
js/src/vm/Debugger.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Script-staticLevel.js
@@ -0,0 +1,43 @@
+// Debugger.Script.prototype.staticLevel returns the script's static level.
+load(libdir + 'asserts.js');
+
+var g = newGlobal('new-compartment');
+var dbg = Debugger();
+var gw = dbg.addDebuggee(g);
+
+function test(expr, level) {
+    var log;
+    dbg.onDebuggerStatement = function (frame) {
+        log += 'd';
+        assertEq(frame.script.staticLevel, level);
+    };
+
+    print("Testing: " + expr);
+
+    log = '';
+    // The shell's 'evaluate' runs its argument as global code.
+    g.evaluate(expr);
+    assertEq(log, 'd');
+}
+
+
+test("debugger;", 0);
+test("(function () { debugger; })()", 1);
+test("(function () { (function () { debugger; })(); })()", 2);
+test("(function () { (function () { (function () { debugger; })(); })(); })()", 3);
+
+test("eval('debugger;');", 1);
+test("eval('eval(\\\'debugger;\\\');');", 2);
+test("evil = eval; eval('evil(\\\'debugger;\\\');');", 0); // I don't think it's evil at all!
+test("(function () { eval('debugger;'); })();", 2);
+test("evil = eval; (function () { evil('debugger;'); })();", 0);
+
+// Generators' expressions are within a synthesized function's body.
+test("((function () { debugger; })() for (x in [1])).next();", 2);
+test("(x for (x in ((function () { debugger; })(), [1]))).next();", 2);
+
+// The staticLevel accessor can't be assigned to.
+g.eval('function f() {}');
+var fw = gw.makeDebuggeeValue(g.f);
+assertThrowsInstanceOf(function () { "use strict"; fw.script.staticLevel = 10; },
+                       TypeError);
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2476,44 +2476,52 @@ DebuggerScript_checkThis(JSContext *cx, 
     JSObject *obj = DebuggerScript_checkThis(cx, args, fnname);                     \
     if (!obj)                                                                       \
         return false;                                                               \
     JSScript *script = GetScriptReferent(obj)
 
 static JSBool
 DebuggerScript_getUrl(JSContext *cx, unsigned argc, Value *vp)
 {
-    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "getUrl", args, obj, script);
+    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get url)", args, obj, script);
 
     JSString *str = js_NewStringCopyZ(cx, script->filename);
     if (!str)
         return false;
     args.rval().setString(str);
     return true;
 }
 
 static JSBool
 DebuggerScript_getStartLine(JSContext *cx, unsigned argc, Value *vp)
 {
-    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "getStartLine", args, obj, script);
+    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get startLine)", args, obj, script);
     args.rval().setNumber(script->lineno);
     return true;
 }
 
 static JSBool
 DebuggerScript_getLineCount(JSContext *cx, unsigned argc, Value *vp)
 {
-    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "getLineCount", args, obj, script);
+    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get lineCount)", args, obj, script);
 
     unsigned maxLine = js_GetScriptLineExtent(script);
     args.rval().setNumber(double(maxLine));
     return true;
 }
 
 static JSBool
+DebuggerScript_getStaticLevel(JSContext *cx, unsigned argc, Value *vp)
+{
+    THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "(get staticLevel)", args, obj, script);
+    args.rval().setNumber(uint32_t(script->staticLevel));
+    return true;
+}
+
+static JSBool
 DebuggerScript_getChildScripts(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "getChildScripts", args, obj, script);
     Debugger *dbg = Debugger::fromChildJSObject(obj);
 
     JSObject *result = NewDenseEmptyArray(cx);
     if (!result)
         return false;
@@ -2921,16 +2929,17 @@ DebuggerScript_construct(JSContext *cx, 
     JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NO_CONSTRUCTOR, "Debugger.Script");
     return false;
 }
 
 static JSPropertySpec DebuggerScript_properties[] = {
     JS_PSG("url", DebuggerScript_getUrl, 0),
     JS_PSG("startLine", DebuggerScript_getStartLine, 0),
     JS_PSG("lineCount", DebuggerScript_getLineCount, 0),
+    JS_PSG("staticLevel", DebuggerScript_getStaticLevel, 0),
     JS_PS_END
 };
 
 static JSFunctionSpec DebuggerScript_methods[] = {
     JS_FN("getChildScripts", DebuggerScript_getChildScripts, 0, 0),
     JS_FN("getAllOffsets", DebuggerScript_getAllOffsets, 0, 0),
     JS_FN("getLineOffsets", DebuggerScript_getLineOffsets, 1, 0),
     JS_FN("getOffsetLine", DebuggerScript_getOffsetLine, 0, 0),