mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
New rule: a Debug object cannot be attached to a compartment that is not in debug mode. Includes a jsapi-test to check that we do not crash if you turn debug mode off while a Debug object is already attached. (This changeset moves all the Debug object tests under jit-tests because the jit-test runner lets tests ask for debug mode.)
--HG-- rename : js/src/tests/js1_8_5/extensions/debug-object-01.js => js/src/jit-test/tests/debug/debug-object-01.js rename : js/src/tests/js1_8_5/extensions/debug-object-02.js => js/src/jit-test/tests/debug/debug-object-02.js rename : js/src/tests/js1_8_5/extensions/debug-object-03.js => js/src/jit-test/tests/debug/debug-object-03.js rename : js/src/tests/js1_8_5/extensions/debug-object-04.js => js/src/jit-test/tests/debug/debug-object-04.js rename : js/src/tests/js1_8_5/extensions/debug-object-05.js => js/src/jit-test/tests/debug/debug-object-05.js rename : js/src/tests/js1_8_5/extensions/debug-object-06.js => js/src/jit-test/tests/debug/debug-object-06.js rename : js/src/tests/js1_8_5/extensions/debug-object-07.js => js/src/jit-test/tests/debug/debug-object-07.js rename : js/src/tests/js1_8_5/extensions/debug-object-08.js => js/src/jit-test/tests/debug/debug-object-08.js rename : js/src/tests/js1_8_5/extensions/debug-object-09.js => js/src/jit-test/tests/debug/debug-object-09.js rename : js/src/tests/js1_8_5/extensions/debug-object-10.js => js/src/jit-test/tests/debug/debug-object-10.js rename : js/src/tests/js1_8_5/extensions/debug-object-11.js => js/src/jit-test/tests/debug/debug-object-11.js rename : js/src/tests/js1_8_5/extensions/debug-object-12.js => js/src/jit-test/tests/debug/debug-object-12.js rename : js/src/tests/js1_8_5/extensions/debug-object-13.js => js/src/jit-test/tests/debug/debug-object-13.js rename : js/src/tests/js1_8_5/extensions/debug-object-14.js => js/src/jit-test/tests/debug/debug-object-14.js rename : js/src/tests/js1_8_5/extensions/debug-object-15.js => js/src/jit-test/tests/debug/debug-object-15.js rename : js/src/tests/js1_8_5/extensions/debug-object-16.js => js/src/jit-test/tests/debug/debug-object-16.js rename : js/src/tests/js1_8_5/extensions/debug-object-17.js => js/src/jit-test/tests/debug/debug-object-17.js rename : js/src/tests/js1_8_5/extensions/debug-object-18.js => js/src/jit-test/tests/debug/debug-object-18.js rename : js/src/tests/js1_8_5/extensions/debug-object-19.js => js/src/jit-test/tests/debug/debug-object-19.js rename : js/src/tests/js1_8_5/extensions/debug-object-20.js => js/src/jit-test/tests/debug/debug-object-20.js rename : js/src/tests/js1_8_5/extensions/debug-object-21.js => js/src/jit-test/tests/debug/debug-object-21.js
This commit is contained in:
parent
a39d2d024a
commit
4fcb55d0aa
@ -52,7 +52,7 @@ The general format in EBNF is:
|
||||
cookie ::= "|jit-test|"
|
||||
item ::= flag | attribute
|
||||
|
||||
flag ::= "slow" | "allow-oom"
|
||||
flag ::= "slow" | "allow-oom" | "valgrind" | "mjitalways" | "debug"
|
||||
|
||||
attribute ::= name ":" value
|
||||
name ::= "TMFLAGS" | "error"
|
||||
@ -66,6 +66,8 @@ The meaning of the items:
|
||||
slow Test runs slowly. Do not run if the --no-slow option is given.
|
||||
allow-oom If the test runs out of memory, it counts as passing.
|
||||
valgrind Run test under valgrind.
|
||||
mjitalways Run js with -a, whether --jitflags says to or not
|
||||
debug Run js with -d, whether --jitflags says to or not
|
||||
|
||||
error The test should be considered to pass iff it throws the
|
||||
given JS exception.
|
||||
|
36
js/src/jit-test/lib/asserts.js
Normal file
36
js/src/jit-test/lib/asserts.js
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
if (typeof assertThrowsInstanceOf === 'undefined') {
|
||||
var assertThrowsInstanceOf = function assertThrowsInstanceOf(f, ctor, msg) {
|
||||
var fullmsg;
|
||||
try {
|
||||
f();
|
||||
} catch (exc) {
|
||||
if (exc instanceof ctor)
|
||||
return;
|
||||
fullmsg = "Assertion failed: expected exception " + ctor.name + ", got " + exc;
|
||||
}
|
||||
if (fullmsg === undefined)
|
||||
fullmsg = "Assertion failed: expected exception " + ctor.name + ", no exception thrown";
|
||||
if (msg !== undefined)
|
||||
fullmsg += " - " + msg;
|
||||
throw new Error(fullmsg);
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof assertThrowsValue === 'undefined') {
|
||||
var assertThrowsValue = function assertThrowsValue(f, val, msg) {
|
||||
var fullmsg;
|
||||
try {
|
||||
f();
|
||||
} catch (exc) {
|
||||
if ((exc === val) === (val === val) && (val !== 0 || 1 / exc === 1 / val))
|
||||
return;
|
||||
fullmsg = "Assertion failed: expected exception " + val + ", got " + exc;
|
||||
}
|
||||
if (fullmsg === undefined)
|
||||
fullmsg = "Assertion failed: expected exception " + val + ", no exception thrown";
|
||||
if (msg !== undefined)
|
||||
fullmsg += " - " + msg;
|
||||
throw new Error(fullmsg);
|
||||
};
|
||||
}
|
17
js/src/jit-test/tests/debug/debug-object-01.js
Normal file
17
js/src/jit-test/tests/debug/debug-object-01.js
Normal file
@ -0,0 +1,17 @@
|
||||
// |jit-test| debug
|
||||
|
||||
function checkFunction(obj, name, nargs) {
|
||||
var desc = Object.getOwnPropertyDescriptor(obj, name);
|
||||
assertEq(desc.configurable, true, name + " should be configurable");
|
||||
assertEq(desc.writable, true, name + " should be writable");
|
||||
assertEq(desc.enumerable, false, name + " should be non-enumerable");
|
||||
assertEq(desc.value, obj[name]); // well obviously
|
||||
assertEq(typeof desc.value, 'function', name + " should be a function");
|
||||
assertEq(desc.value.length, nargs, name + " should have .length === " + nargs);
|
||||
}
|
||||
|
||||
checkFunction(this, "Debug", 1);
|
||||
|
||||
assertEq(Debug.prototype.constructor, Debug);
|
||||
assertEq(Object.prototype.toString.call(Debug.prototype), "[object Debug]");
|
||||
assertEq(Object.getPrototypeOf(Debug.prototype), Object.prototype);
|
36
js/src/jit-test/tests/debug/debug-object-02.js
Normal file
36
js/src/jit-test/tests/debug/debug-object-02.js
Normal file
@ -0,0 +1,36 @@
|
||||
// |jit-test| debug
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
||||
// Debug rejects arguments that aren't cross-compartment wrappers.
|
||||
assertThrowsInstanceOf(function () { Debug(); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Debug(null); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Debug(true); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Debug(42); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Debug("bad"); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Debug(function () {}); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Debug(this); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { new Debug(); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { new Debug(null); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { new Debug(true); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { new Debug(42); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { new Debug("bad"); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { new Debug(function () {}); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { new Debug(this); }, TypeError);
|
||||
|
||||
// Very basic tests of Debug creation.
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debug(g);
|
||||
assertEq(dbg instanceof Debug, true);
|
||||
assertEq(Object.getPrototypeOf(dbg), Debug.prototype);
|
||||
|
||||
// The reverse.
|
||||
var g2 = newGlobal('new-compartment');
|
||||
g2.debuggeeGlobal = this;
|
||||
g2.eval("var dbg = new Debug(debuggeeGlobal);");
|
||||
assertEq(g2.eval("dbg instanceof Debug"), true);
|
||||
|
||||
// The Debug constructor from this compartment will not accept as its argument
|
||||
// an Object from this compartment. Shenanigans won't fool the membrane.
|
||||
g2.outer = this;
|
||||
assertThrowsInstanceOf(function () { g2.eval("outer.Debug(outer.Object())"); }, TypeError);
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
var g = newGlobal('new-compartment');
|
||||
g.log = '';
|
||||
|
||||
@ -14,5 +12,3 @@ dbg.hooks = hooks;
|
||||
assertEq(dbg.hooks, hooks);
|
||||
assertEq(g.eval("log += '1'; debugger; log += '2'; 3;"), 3);
|
||||
assertEq(g.log, '1!2');
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Activity in the debugger compartment should not trigger debug hooks.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
@ -27,5 +25,3 @@ assertEq(hit, false, "debugger statement in debugger compartment eval code shoul
|
||||
var g2 = newGlobal('new-compartment');
|
||||
g2.eval("debugger;");
|
||||
assertEq(hit, false, "debugger statement in unrelated non-debuggee compartment should not hit");
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// A debugger statement in a debuggerHandler should not reenter.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
@ -16,5 +14,3 @@ dbg.hooks = {
|
||||
|
||||
assertEq(g.eval("debugger; 7;"), 7);
|
||||
assertEq(calls, 1);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
18
js/src/jit-test/tests/debug/debug-object-06.js
Normal file
18
js/src/jit-test/tests/debug/debug-object-06.js
Normal file
@ -0,0 +1,18 @@
|
||||
// |jit-test| debug
|
||||
// Simple {throw:} resumption.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
||||
var dbg = Debug(g);
|
||||
dbg.hooks = {
|
||||
debuggerHandler: function (stack) {
|
||||
return {throw: "oops"};
|
||||
}
|
||||
};
|
||||
|
||||
assertThrowsValue(function () { g.eval("debugger;"); }, "oops");
|
||||
|
||||
g.eval("function f() { debugger; }");
|
||||
assertThrowsValue(function () { g.f(); }, "oops");
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Simple {return:} resumption.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
@ -15,5 +13,3 @@ dbg.hooks = {
|
||||
assertEq(g.eval("debugger; false;"), 1234);
|
||||
g.eval("function f() { debugger; return 'bad'; }");
|
||||
assertEq(g.f(), 1234);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// When there are multiple debuggers, their hooks are called in order.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
@ -38,5 +36,3 @@ arr[0].hooks = {
|
||||
log = '';
|
||||
assertEq(g.eval("debugger; 0;"), 1);
|
||||
assertEq(log, 'a');
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
30
js/src/jit-test/tests/debug/debug-object-09.js
Normal file
30
js/src/jit-test/tests/debug/debug-object-09.js
Normal file
@ -0,0 +1,30 @@
|
||||
// |jit-test| debug
|
||||
// Debug.prototype.hooks
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debug(g);
|
||||
gc(); // don't assert marking dbg.hooks
|
||||
var h = dbg.hooks;
|
||||
assertEq(typeof h, 'object');
|
||||
assertEq(Object.getOwnPropertyNames(h).length, 0);
|
||||
assertEq(Object.getPrototypeOf(h), Object.prototype);
|
||||
|
||||
assertThrowsInstanceOf(function () { dbg.hooks = null; }, TypeError);
|
||||
assertThrowsInstanceOf(function () { dbg.hooks = "bad"; }, TypeError);
|
||||
|
||||
assertEq(Object.getOwnPropertyNames(dbg).length, 0);
|
||||
var desc = Object.getOwnPropertyDescriptor(Debug.prototype, "hooks");
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
|
||||
assertThrowsInstanceOf(function () { desc.get(); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { desc.get.call(undefined); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { desc.get.call(Debug.prototype); }, TypeError);
|
||||
assertEq(desc.get.call(dbg), h);
|
||||
|
||||
assertThrowsInstanceOf(function () { desc.set(); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { desc.set.call(dbg); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { desc.set.call({}, {}); }, TypeError);
|
||||
assertThrowsInstanceOf(function () { desc.set.call(Debug.prototype, {}); }, TypeError);
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// If a hook is deleted after setHooks or overwritten with a primitive, it
|
||||
// simply isn't called.
|
||||
|
||||
@ -21,5 +19,3 @@ assertEq(hit, false);
|
||||
dbg.hooks.debuggerHandler = function (stack) { hit = true; };
|
||||
g.eval("debugger;");
|
||||
assertEq(hit, true);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Debuggers with enabled hooks should not be GC'd even if they are otherwise
|
||||
// unreachable.
|
||||
|
||||
@ -20,5 +18,3 @@ f();
|
||||
gc(); gc(); gc();
|
||||
g.eval("debugger;");
|
||||
assertEq(actual, expected);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Test adding hooks during dispatch. The behavior is deterministic and "nice",
|
||||
// but mainly what we are checking here is that we do not crash due to
|
||||
// modifying a data structure while we're iterating over it.
|
||||
@ -35,5 +33,3 @@ assertEq(hits, 4);
|
||||
hits = 0;
|
||||
g.eval("debugger;");
|
||||
assertEq(hits, 8);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Test removing hooks during dispatch.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
@ -27,5 +25,3 @@ function addDebug(n) {
|
||||
addDebug(10);
|
||||
g.eval("debugger;");
|
||||
assertEq(log, '0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ');
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Dispatching an event to a debugger must keep enough of it gc-alive to avoid
|
||||
// crashing.
|
||||
|
||||
@ -35,5 +33,3 @@ addDebug();
|
||||
hits = 0;
|
||||
g.eval("debugger;");
|
||||
assertEq(hits, 1);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Q: But who shall debug the debuggers? A: jimb
|
||||
|
||||
var log = '';
|
||||
@ -24,5 +22,3 @@ for (var i = 0; i < 8; i++) // why have 2 debuggers when you can have 8
|
||||
top = addDebug(top, i);
|
||||
base.eval("debugger;");
|
||||
assertEq(log, '0123456776543210');
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,5 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
// |jit-test| debug
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(Debug.prototype, "enabled");
|
||||
assertEq(typeof desc.get, 'function');
|
||||
@ -19,5 +18,3 @@ for (var i = 0; i < vals.length; i++) {
|
||||
g.eval("debugger;");
|
||||
assertEq(hits, vals[i] ? 1 : 0);
|
||||
}
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Disabling a Debug object causes events to stop being delivered to it
|
||||
// immediately, even if we're in the middle of dispatching.
|
||||
|
||||
@ -24,5 +22,3 @@ for (var i = 0; i < 4; i++) {
|
||||
log = '';
|
||||
g.eval("debugger; debugger;");
|
||||
assertEq(log, '0');
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// Uncaught exceptions in the debugger itself are delivered to the
|
||||
// uncaughtExceptionHook.
|
||||
|
||||
@ -22,5 +20,3 @@ dbg.uncaughtExceptionHook = function (exc) {
|
||||
log = '';
|
||||
g.eval("debugger");
|
||||
assertEq(log, 'x!');
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,8 +1,8 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// uncaughtExceptionHook returns a resumption value.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debug(g);
|
||||
var rv;
|
||||
@ -19,16 +19,8 @@ g.eval("debugger");
|
||||
// case 2: throw
|
||||
rv = {throw: 57};
|
||||
var result;
|
||||
try {
|
||||
g.eval("debugger");
|
||||
result = 'no exception thrown';
|
||||
} catch (exc) {
|
||||
result = 'caught ' + exc;
|
||||
}
|
||||
assertEq(result, 'caught 57');
|
||||
assertThrowsValue(function () { g.eval("debugger"); }, 57);
|
||||
|
||||
// case 3: return
|
||||
rv = {return: 42};
|
||||
assertEq(g.eval("debugger;"), 42);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,6 +1,4 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// uncaughtExceptionHook resumption value other than undefined causes further
|
||||
// hooks to be skipped.
|
||||
|
||||
@ -28,5 +26,3 @@ for (var i = 0; i < 6; i++)
|
||||
log = '';
|
||||
assertEq(g.eval("debugger;"), 42);
|
||||
assertEq(log, "012");
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,22 +1,20 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// |jit-test| debug
|
||||
// dumb basics of uncaughtExceptionHook
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(Debug.prototype, "uncaughtExceptionHook");
|
||||
assertEq(typeof desc.get, 'function');
|
||||
assertEq(typeof desc.set, 'function');
|
||||
|
||||
assertThrows(function () { Debug.prototype.uncaughtExceptionHook = null; }, TypeError);
|
||||
assertThrowsInstanceOf(function () { Debug.prototype.uncaughtExceptionHook = null; }, TypeError);
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debug(g);
|
||||
assertEq(desc.get.call(dbg), null);
|
||||
assertThrows(function () { dbg.uncaughtExceptionHook = []; }, TypeError);
|
||||
assertThrows(function () { dbg.uncaughtExceptionHook = 3; }, TypeError);
|
||||
assertThrowsInstanceOf(function () { dbg.uncaughtExceptionHook = []; }, TypeError);
|
||||
assertThrowsInstanceOf(function () { dbg.uncaughtExceptionHook = 3; }, TypeError);
|
||||
dbg.uncaughtExceptionHook = Math.sin;
|
||||
assertEq(dbg.uncaughtExceptionHook, Math.sin);
|
||||
dbg.uncaughtExceptionHook = null;
|
||||
assertEq(dbg.uncaughtExceptionHook, null);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -103,3 +103,44 @@ BEGIN_TEST(testDebugger_getThisStrict)
|
||||
return true;
|
||||
}
|
||||
END_TEST(testDebugger_getThisStrict)
|
||||
|
||||
BEGIN_TEST(testDebugger_debugObjectVsDebugMode)
|
||||
{
|
||||
CHECK(JS_DefineDebugObject(cx, global));
|
||||
JSObject *debuggee = JS_NewCompartmentAndGlobalObject(cx, getGlobalClass(), NULL);
|
||||
CHECK(debuggee);
|
||||
|
||||
{
|
||||
JSAutoEnterCompartment ae;
|
||||
CHECK(ae.enter(cx, debuggee));
|
||||
CHECK(JS_SetDebugMode(cx, true));
|
||||
CHECK(JS_InitStandardClasses(cx, debuggee));
|
||||
}
|
||||
|
||||
JSObject *debuggeeWrapper = debuggee;
|
||||
CHECK(JS_WrapObject(cx, &debuggeeWrapper));
|
||||
jsval v = OBJECT_TO_JSVAL(debuggeeWrapper);
|
||||
CHECK(JS_SetProperty(cx, global, "debuggee", &v));
|
||||
|
||||
EVAL("var dbg = new Debug(debuggee);\n"
|
||||
"var hits = 0;\n"
|
||||
"dbg.hooks = {debuggerHandler: function () { hits++; }};\n"
|
||||
"debuggee.eval('debugger;');\n"
|
||||
"hits;\n",
|
||||
&v);
|
||||
CHECK_SAME(v, JSVAL_ONE);
|
||||
|
||||
{
|
||||
JSAutoEnterCompartment ae;
|
||||
CHECK(ae.enter(cx, debuggee));
|
||||
CHECK(JS_SetDebugMode(cx, false));
|
||||
}
|
||||
|
||||
EVAL("debuggee.eval('debugger; debugger; debugger;');\n"
|
||||
"hits;\n",
|
||||
&v);
|
||||
CHECK_SAME(v, JSVAL_ONE);
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testDebugger_debugObjectVsDebugMode)
|
||||
|
@ -517,7 +517,10 @@ struct JS_FRIEND_API(JSCompartment) {
|
||||
|
||||
const DebugVector &getDebuggers() const { return debuggers; }
|
||||
|
||||
bool addDebug(js::Debug *dbg) { return debuggers.append(dbg); }
|
||||
bool addDebug(js::Debug *dbg) {
|
||||
JS_ASSERT(debugMode);
|
||||
return debuggers.append(dbg);
|
||||
}
|
||||
void removeDebug(js::Debug *dbg);
|
||||
};
|
||||
|
||||
|
@ -306,10 +306,16 @@ void
|
||||
Debug::finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
Debug *dbg = (Debug *) obj->getPrivate();
|
||||
if (dbg && dbg->debuggeeCompartment) {
|
||||
dbg->debuggeeCompartment->removeDebug(dbg);
|
||||
dbg->debuggeeCompartment = NULL;
|
||||
}
|
||||
if (dbg && dbg->debuggeeCompartment)
|
||||
dbg->detachFrom(dbg->debuggeeCompartment);
|
||||
}
|
||||
|
||||
void
|
||||
Debug::detachFrom(JSCompartment *c)
|
||||
{
|
||||
JS_ASSERT(c == debuggeeCompartment);
|
||||
c->removeDebug(this);
|
||||
debuggeeCompartment = NULL;
|
||||
}
|
||||
|
||||
Class Debug::jsclass = {
|
||||
@ -411,6 +417,13 @@ Debug::construct(JSContext *cx, uintN argc, Value *vp)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the target compartment is in debug mode.
|
||||
JSCompartment *debuggeeCompartment = argobj->getProxyPrivate().toObject().compartment();
|
||||
if (!debuggeeCompartment->debugMode) {
|
||||
JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_NEED_DEBUG_MODE);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get Debug.prototype.
|
||||
Value v;
|
||||
jsid prototypeId = ATOM_TO_JSID(cx->runtime->atomState.classPrototypeAtom);
|
||||
@ -426,7 +439,6 @@ Debug::construct(JSContext *cx, uintN argc, Value *vp)
|
||||
JSObject *hooks = NewBuiltinClassInstance(cx, &js_ObjectClass);
|
||||
if (!hooks)
|
||||
return false;
|
||||
JSCompartment *debuggeeCompartment = argobj->getProxyPrivate().toObject().compartment();
|
||||
Debug *dbg = cx->new_<Debug>(obj, hooks, debuggeeCompartment);
|
||||
if (!dbg)
|
||||
return false;
|
||||
|
@ -110,6 +110,7 @@ class Debug {
|
||||
static inline Debug *fromJSObject(JSObject *obj);
|
||||
|
||||
inline bool observesCompartment(JSCompartment *c) const;
|
||||
void detachFrom(JSCompartment *c);
|
||||
|
||||
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, js::Value *vp);
|
||||
};
|
||||
|
@ -51,6 +51,7 @@
|
||||
#include "jsapi.h"
|
||||
#include "jscntxt.h"
|
||||
#include "jsversion.h"
|
||||
#include "jsdbg.h"
|
||||
#include "jsdbgapi.h"
|
||||
#include "jsemit.h"
|
||||
#include "jsfun.h"
|
||||
@ -193,9 +194,16 @@ JS_SetDebugModeForCompartment(JSContext *cx, JSCompartment *comp, JSBool debug)
|
||||
// All scripts compiled from this point on should be in the requested debugMode.
|
||||
comp->debugMode = !!debug;
|
||||
|
||||
// Detach any debuggers attached to this compartment.
|
||||
if (debug) {
|
||||
JS_ASSERT(comp->getDebuggers().empty());
|
||||
} else {
|
||||
while (!comp->getDebuggers().empty())
|
||||
comp->getDebuggers().back()->detachFrom(comp);
|
||||
}
|
||||
|
||||
// Discard JIT code for any scripts that change debugMode. This function
|
||||
// assumes that 'comp' is in the same thread as 'cx'.
|
||||
|
||||
#ifdef JS_METHODJIT
|
||||
JS::AutoEnterScriptCompartment ac;
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
checkFunction(this, "Debug", 1);
|
||||
|
||||
assertEq(Debug.prototype.constructor, Debug);
|
||||
assertEq(Object.prototype.toString.call(Debug.prototype), "[object Debug]");
|
||||
assertEq(Object.getPrototypeOf(Debug.prototype), Object.prototype);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,37 +0,0 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// Debug rejects arguments that aren't cross-compartment wrappers.
|
||||
assertThrows(function () { Debug(); }, TypeError);
|
||||
assertThrows(function () { Debug(null); }, TypeError);
|
||||
assertThrows(function () { Debug(true); }, TypeError);
|
||||
assertThrows(function () { Debug(42); }, TypeError);
|
||||
assertThrows(function () { Debug("bad"); }, TypeError);
|
||||
assertThrows(function () { Debug(function () {}); }, TypeError);
|
||||
assertThrows(function () { Debug(this); }, TypeError);
|
||||
assertThrows(function () { new Debug(); }, TypeError);
|
||||
assertThrows(function () { new Debug(null); }, TypeError);
|
||||
assertThrows(function () { new Debug(true); }, TypeError);
|
||||
assertThrows(function () { new Debug(42); }, TypeError);
|
||||
assertThrows(function () { new Debug("bad"); }, TypeError);
|
||||
assertThrows(function () { new Debug(function () {}); }, TypeError);
|
||||
assertThrows(function () { new Debug(this); }, TypeError);
|
||||
|
||||
// Very basic tests of Debug creation.
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debug(g);
|
||||
assertEq(dbg instanceof Debug, true);
|
||||
assertEq(Object.getPrototypeOf(dbg), Debug.prototype);
|
||||
|
||||
// The reverse.
|
||||
var g2 = newGlobal('new-compartment');
|
||||
g2.debuggeeGlobal = this;
|
||||
g2.eval("var dbg = new Debug(debuggeeGlobal);");
|
||||
assertEq(g2.eval("dbg instanceof Debug"), true);
|
||||
|
||||
// The Debug constructor from this compartment will not accept as its argument
|
||||
// an Object from this compartment. Shenanigans won't fool the membrane.
|
||||
g2.outer = this;
|
||||
assertThrows(function () { g2.eval("outer.Debug(outer.Object())"); }, TypeError);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,32 +0,0 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// Simple {throw:} resumption.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
||||
var dbg = Debug(g);
|
||||
dbg.hooks = {
|
||||
debuggerHandler: function (stack) {
|
||||
return {throw: "oops"};
|
||||
}
|
||||
};
|
||||
|
||||
var result = 'no exception thrown';
|
||||
try {
|
||||
g.eval("debugger;");
|
||||
} catch (exc) {
|
||||
result = exc;
|
||||
}
|
||||
assertEq(result, "oops");
|
||||
|
||||
g.eval("function f() { debugger; }");
|
||||
result = 'no exception thrown';
|
||||
try {
|
||||
g.f();
|
||||
} catch (exc) {
|
||||
result = exc;
|
||||
}
|
||||
assertEq(result, "oops");
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,32 +0,0 @@
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
// Debug.prototype.hooks
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debug(g);
|
||||
gc(); // don't assert marking dbg.hooks
|
||||
var h = dbg.hooks;
|
||||
assertEq(typeof h, 'object');
|
||||
assertEq(Object.getOwnPropertyNames(h).length, 0);
|
||||
assertEq(Object.getPrototypeOf(h), Object.prototype);
|
||||
|
||||
assertThrows(function () { dbg.hooks = null; }, TypeError);
|
||||
assertThrows(function () { dbg.hooks = "bad"; }, TypeError);
|
||||
|
||||
assertEq(Object.getOwnPropertyNames(dbg).length, 0);
|
||||
var desc = Object.getOwnPropertyDescriptor(Debug.prototype, "hooks");
|
||||
assertEq(desc.configurable, true);
|
||||
assertEq(desc.enumerable, false);
|
||||
|
||||
assertThrows(function () { desc.get(); }, TypeError);
|
||||
assertThrows(function () { desc.get.call(undefined); }, TypeError);
|
||||
assertThrows(function () { desc.get.call(Debug.prototype); }, TypeError);
|
||||
assertEq(desc.get.call(dbg), h);
|
||||
|
||||
assertThrows(function () { desc.set(); }, TypeError);
|
||||
assertThrows(function () { desc.set.call(dbg); }, TypeError);
|
||||
assertThrows(function () { desc.set.call({}, {}); }, TypeError);
|
||||
assertThrows(function () { desc.set.call(Debug.prototype, {}); }, TypeError);
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -42,24 +42,3 @@ script regress-636697.js
|
||||
script is-generator.js
|
||||
script weakmap.js
|
||||
script regress-650753.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-01.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-02.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-03.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-04.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-05.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-06.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-07.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-08.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-09.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-10.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-11.js
|
||||
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
|
||||
skip-if(!xulRuntime.shell) script debug-object-18.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-19.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-20.js
|
||||
skip-if(!xulRuntime.shell) script debug-object-21.js
|
||||
|
@ -170,14 +170,3 @@ var Match =
|
||||
MatchError: MatchError };
|
||||
|
||||
})();
|
||||
|
||||
// used by several Debug object tests
|
||||
function checkFunction(obj, name, nargs) {
|
||||
var desc = Object.getOwnPropertyDescriptor(obj, name);
|
||||
assertEq(desc.configurable, true, name + " should be configurable");
|
||||
assertEq(desc.writable, true, name + " should be writable");
|
||||
assertEq(desc.enumerable, false, name + " should be non-enumerable");
|
||||
assertEq(desc.value, obj[name]); // well obviously
|
||||
assertEq(typeof desc.value, 'function', name + " should be a function");
|
||||
assertEq(desc.value.length, nargs, name + " should have .length === " + nargs);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user