Automatically turn debug mode on/off when adding/removing debuggees.

This allows most of the tests to run without the -d command-line flag.

Now a compartment is in debug mode if
 * JSD1 wants debug mode on, thanks to a JS_SetDebugMode* call; OR
 * JSD2 wants debug mode on, because a live Debug object has a debuggee
   global in that compartment.

Since this patch only adds the second half of the rule, JSD1 should be
unaffected.

The new rule has three issues:

1. When removeDebuggee is called, it can cause debug mode to be turned
   off for a compartment. If any scripts from that compartment are on
   the stack, and the methodjit is enabled, returning to those stack
   frames will crash.

2. When a Debug object is GC'd, it can cause debug mode to be turned off
   for one or more compartments. This causes the same problem with
   returning to deleted methodjit code, but the fix is different: such
   Debug objects simply should not be GC'd.

3. Setting .enabled to false still does not turn off debug mode
   anywhere, so it does not reduce overhead as much as it should.

A possible fix for issue #1 would be to make such removeDebuggee calls
throw.  The fix to issues #2 and #3 is to tweak the rule--and to tweak
the rule for Debug object GC-reachability.

--HG--
rename : js/src/jit-test/tests/debug/Debug-ctor.js => js/src/jit-test/tests/debug/Debug-ctor-01.js
This commit is contained in:
Jason Orendorff 2011-06-02 21:58:46 -05:00
parent 2ed818c0ac
commit 6a958619a0
113 changed files with 310 additions and 408 deletions

View File

@ -1,5 +1,3 @@
// |jit-test| debug
load(libdir + 'asserts.js');
// Debug rejects arguments that aren't cross-compartment wrappers.
@ -21,14 +19,3 @@ 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);

View File

@ -0,0 +1,17 @@
// |jit-test| debug
// Test creating a Debug in a sandbox, debugging the initial global.
//
// This requires debug mode to already be on in the initial global, since it's
// always on the stack in the shell. Hence the |jit-test| tag.
load(libdir + 'asserts.js');
var g = newGlobal('new-compartment');
g.debuggeeGlobal = this;
g.eval("var dbg = new Debug(debuggeeGlobal);");
assertEq(g.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.
g.parent = this;
assertThrowsInstanceOf(function () { g.eval("parent.Debug(parent.Object())"); }, TypeError);

View File

@ -0,0 +1,6 @@
// If the debuggee cannot be put into debug mode, throw.
var g = newGlobal('new-compartment');
g.libdir = libdir;
g.eval("load(libdir + 'asserts.js');");
g.parent = this;
g.eval("assertThrowsInstanceOf(function () { new Debug(parent); }, Error);");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// A Debug object created with no argument initially has no debuggees.
var dbg = new Debug;
var debuggees = dbg.getDebuggees();

View File

@ -1,5 +1,4 @@
// |jit-test| debug
// The array returned by getDebuggees is just a snapshot, not live
// The array returned by getDebuggees is just a snapshot, not live.
var dbg = new Debug;
var a1 = dbg.getDebuggees();
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Debug hooks fire based on debuggees.
var g1 = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// hasDebuggee tests.
var g1 = newGlobal('new-compartment'), g1w;

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// addDebuggee returns different Debug.Object wrappers for different Debug objects.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// {has,add,remove}Debuggee throw a TypeError if the argument is invalid.
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Handle proto-less objects passed to addDebuggee.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// addDebuggee(obj), where obj is not global, adds obj's global.
// Adding a debuggee more than once is redundant.

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Allow diamonds in the graph of the compartment "debugs" relation.
var program = newGlobal('new-compartment');
var d1 = newGlobal('new-compartment');
d1.top = this;

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Events in a non-debuggee are ignored, even if a debuggee is in the same compartment.
var g1 = newGlobal('new-compartment');
var g2 = g1.eval("newGlobal('same-compartment')");
var dbg = new Debug(g1);

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Removing a debuggee does not detach the debugger from a compartment if another debuggee is in it.
var g1 = newGlobal('new-compartment');
var g2 = g1.eval("newGlobal('same-compartment')");
var dbg = new Debug(g1, g2);

View File

@ -1,11 +1,7 @@
// Reject non-debug-mode debuggees without asserting.
load(libdir + "asserts.js");
function f() {
var v = new Debug;
var g = newGlobal('new-compartment');
v.addDebuggee(g); // don't assert
}
assertThrowsInstanceOf(f, Error);
// Adding a debuggee in a compartment that is already in debug mode works
// even if a script from that compartment is on the stack.
var g = newGlobal('new-compartment');
var dbg1 = Debug(g);
var dbg2 = Debug();
g.parent = this;
g.eval("parent.dbg2.addDebuggee(this);");

View File

@ -1,5 +1,3 @@
// |jit-test| debug
var desc = Object.getOwnPropertyDescriptor(Debug.prototype, "enabled");
assertEq(typeof desc.get, 'function');
assertEq(typeof desc.set, 'function');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// getYoungestFrame basics.
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Hooks and Debug.prototype.getYoungestFrame produce the same Frame object.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// When there are multiple debuggers, their hooks are called in order.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |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.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Q: But who shall debug the debuggers? A: jimb
var log = '';

View File

@ -1,70 +1,33 @@
// |jit-test| debug
// Test .type and .generator fields of topmost stack frame passed to debuggerHandler.
var g = newGlobal('new-compartment');
g.debuggeeGlobal = this;
g.eval("var hits;");
g.eval("(" + function () {
var dbg = Debug(debuggeeGlobal);
dbg.hooks = {
debuggerHandler: function (f) {
// print(uneval(expected));
assertEq(Object.getPrototypeOf(f), Debug.Frame.prototype);
assertEq(f.type, expected.type);
assertEq(f.generator, expected.generator);
assertEq(f.constructing, expected.constructing);
hits++;
}
};
} + ")()");
var dbg = Debug(g);
var expected, hits;
dbg.hooks = {
debuggerHandler: function (f) {
assertEq(Object.getPrototypeOf(f), Debug.Frame.prototype);
assertEq(f.type, expected.type);
assertEq(f.generator, expected.generator);
assertEq(f.constructing, expected.constructing);
hits++;
}
};
g.expected = { type:"global", generator:false, constructing:false };
g.hits = 0;
debugger;
assertEq(g.hits, 1);
g.expected = { type:"call", generator:false, constructing:false };
g.hits = 0;
(function () { debugger; })();
assertEq(g.hits, 1);
g.expected = { type:"call", generator:false, constructing:true };
g.hits = 0;
new function() { debugger; };
assertEq(g.hits, 1);
g.expected = { type:"call", generator:false, constructing:false };
g.hits = 0;
new function () {
(function() { debugger; })();
assertEq(g.hits, 1);
function test(code, expectobj, expectedHits) {
expected = expectobj;
hits = 0;
g.evaluate(code);
assertEq(hits, arguments.length < 3 ? 1 : expectedHits);
}
g.expected = { type:"eval", generator:false, constructing:false };
g.hits = 0;
eval("debugger;");
assertEq(g.hits, 1);
g.expected = { type:"eval", generator:false, constructing:false };
g.hits = 0;
this.eval("debugger;"); // indirect eval
assertEq(g.hits, 1);
g.expected = { type:"eval", generator:false, constructing:false };
g.hits = 0;
(function () { eval("debugger;"); })();
assertEq(g.hits, 1);
g.expected = { type:"eval", generator:false, constructing:false };
g.hits = 0;
new function () {
eval("debugger");
assertEq(g.hits, 1);
}
g.expected = { type:"call", generator:true, constructing:false };
g.hits = 0;
function gen() { debugger; yield 1; debugger; }
for (var x in gen()) {
}
assertEq(g.hits, 2);
test("debugger;", {type: "global", generator: false, constructing: false});
test("(function () { debugger; })();", {type: "call", generator: false, constructing: false});
test("new function() { debugger; };", {type: "call", generator: false, constructing: true});
test("new function () { (function() { debugger; })(); }", {type: "call", generator: false, constructing: false});
test("eval('debugger;');", {type: "eval", generator: false, constructing: false});
test("this.eval('debugger;'); // indirect eval", {type: "eval", generator: false, constructing: false});
test("(function () { eval('debugger;'); })();", {type: "eval", generator: false, constructing: false});
test("new function () { eval('debugger'); }", {type: "eval", generator: false, constructing: false});
test("function gen() { debugger; yield 1; debugger; }\n" +
"for (var x in gen()) {}\n",
{type: "call", generator: true, constructing: false}, 2);

View File

@ -1,35 +1,26 @@
// |jit-test| debug
// When the debugger is triggered twice from the same stack frame, the same
// Debug.Frame object must be passed to the hook both times.
var g = newGlobal('new-compartment');
g.debuggeeGlobal = this;
g.eval("var hits, frame;");
g.eval("(" + function () {
var dbg = Debug(debuggeeGlobal);
dbg.hooks = {
debuggerHandler: function (f) {
if (hits++ == 0)
frame = f;
else
assertEq(f, frame);
}
};
} + ")()");
var hits, frame;
var dbg = Debug(g);
dbg.hooks = {
debuggerHandler: function (f) {
if (hits++ == 0)
frame = f;
else
assertEq(f, frame);
}
};
g.hits = 0;
debugger;
debugger;
assertEq(g.hits, 2);
hits = 0;
g.evaluate("debugger; debugger;");
assertEq(hits, 2);
g.hits = 0;
function f() {
debugger;
debugger;
}
f();
assertEq(g.hits, 2);
hits = 0;
g.evaluate("function f() { debugger; debugger; } f();");
assertEq(hits, 2);
g.hits = 0;
eval("debugger; debugger;");
assertEq(g.hits, 2);
hits = 0;
g.evaluate("eval('debugger; debugger;');");
assertEq(hits, 2);

View File

@ -1,26 +1,21 @@
// |jit-test| debug
// When the debugger is triggered from different stack frames that happen to
// occupy the same memory, it must deliver different Debug.Frame objects.
var g = newGlobal('new-compartment');
g.debuggeeGlobal = this;
g.eval("var hits;");
g.eval("(" + function () {
var a = [];
var dbg = Debug(debuggeeGlobal);
dbg.hooks = {
debuggerHandler: function (frame) {
for (var i = 0; i < a.length; i++)
assertEq(a[i] === frame, false);
a.push(frame);
hits++;
}
};
} + ")()");
var dbg = Debug(g);
var hits;
var a = [];
dbg.hooks = {
debuggerHandler: function (frame) {
for (var i = 0; i < a.length; i++)
assertEq(a[i] === frame, false);
a.push(frame);
hits++;
}
};
function f() { debugger; }
function h() { debugger; f(); }
g.hits = 0;
for (var i = 0; i < 4; i++)
h();
assertEq(g.hits, 8);
g.eval("function f() { debugger; }");
g.eval("function h() { debugger; f(); }");
hits = 0;
g.eval("for (var i = 0; i < 4; i++) h();");
assertEq(hits, 8);

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Frame.prototype.arguments with primitive values
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Object arguments.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Destructuring arguments.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// frame.arguments works for all live frames
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// frame.arguments is "live" (it reflects assignments to arguments).
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Test extracting frame.arguments element getters and calling them in
// various awkward ways.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// simplest possible test of Debug.Frame.prototype.eval
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// frame.eval() throws if frame is not live
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Test eval-ing names in a topmost script frame
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// frame.eval SyntaxErrors are reflected, not thrown
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// var declarations in strict frame.eval do not modify the frame
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// frame.eval throws if frame is a generator frame that isn't currently on the stack
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// test frame.eval in non-top frames
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// The arguments can escape from a function via a debugging hook.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// assigning to local variables in frame.eval code
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// frame.eval returns null if the eval code fails with an uncatchable error.
var g = newGlobal('new-compartment');
var dbg = Debug(g);

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// evalWithBindings basics
var g = newGlobal('new-compartment');

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// evalWithBindings to call a method of a debuggee object
var g = newGlobal('new-compartment');
var dbg = new Debug;
var global = dbg.addDebuggee(g);

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// arguments works in evalWithBindings (it does not interpose a function scope)
var g = newGlobal('new-compartment');
var dbg = new Debug;
var global = dbg.addDebuggee(g);

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// evalWithBindings works on non-top frames.
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
var f1;

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// evalWithBindings code can assign to the bindings.
var g = newGlobal('new-compartment');
var dbg = new Debug(g);

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// In evalWithBindings code, assignment to any name not in the bindings works just as in eval.
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
dbg.hooks = {

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// var statements in strict evalWithBindings code behave like strict eval.
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
var hits = 0;

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// evalWithBindings ignores non-enumerable and non-own properties.
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
var hits = 0;

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// evalWithBindings code is debuggee code, so it can trip the debugger. It nests!
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
var f1;

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Direct eval code under evalWithbindings sees both the bindings and the enclosing scope.
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
var hits = 0;

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Test that on-stack Debug.Frames are not GC'd even if they are only reachable
// from the js::Debug::frames table.

View File

@ -4,18 +4,15 @@
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
g.debuggeeGlobal = this;
g.eval("var f;");
g.eval("(" + function () {
Debug(debuggeeGlobal).hooks = {
debuggerHandler: function (frame) {
assertEq(frame.type, "call");
assertEq(frame.live, true);
f = frame;
}
};
} + ")()");
var f;
Debug(g).hooks = {
debuggerHandler: function (frame) {
assertEq(frame.type, "call");
assertEq(frame.live, true);
f = frame;
}
};
(function () { debugger; })();
assertEq(g.f.live, false);
assertThrowsInstanceOf(function () { g.f.type; }, g.Error);
g.eval("(function () { debugger; })();");
assertEq(f.live, false);
assertThrowsInstanceOf(function () { f.type; }, Error);

View File

@ -0,0 +1,28 @@
// Frame.live is false for frames discarded during uncatchable error unwinding.
var g = newGlobal('new-compartment');
var dbg = Debug(g);
var hits = 0;
var snapshot;
dbg.hooks = {
debuggerHandler: function (frame) {
var stack = [];
for (var f = frame; f; f = f.older) {
if (f.type === "call")
stack.push(f);
}
snapshot = stack;
if (hits++ === 0)
assertEq(frame.eval("x();"), null);
else
return null;
}
};
g.eval("function z() { debugger; }");
g.eval("function y() { z(); }");
g.eval("function x() { y(); }");
assertEq(g.eval("debugger; 'ok';"), "ok");
assertEq(hits, 2);
assertEq(snapshot.length, 3);
for (var i = 0; i < snapshot.length; i++)
assertEq(snapshot[i].live, false);

View File

@ -2,24 +2,21 @@
// Basic call chain.
var g = newGlobal('new-compartment');
g.debuggeeGlobal = this;
g.result = null;
g.eval("(" + function () {
var dbg = new Debug(debuggeeGlobal);
dbg.hooks = {
debuggerHandler: function (frame) {
var a = [];
assertEq(frame === frame.older, false);
for (; frame; frame = frame.older)
a.push(frame.type === 'call' ? frame.callee.name : frame.type);
a.reverse();
result = a.join(", ");
}
};
} + ")();");
var result = null;
var dbg = new Debug(g);
dbg.hooks = {
debuggerHandler: function (frame) {
var a = [];
assertEq(frame === frame.older, false);
for (; frame; frame = frame.older)
a.push(frame.type === 'call' ? frame.callee.name : frame.type);
a.reverse();
result = a.join(", ");
}
};
function first() { return second(); }
function second() { return eval("third()"); }
function third() { debugger; }
first();
assertEq(g.result, "global, first, second, eval, third");
g.eval("function first() { return second(); }");
g.eval("function second() { return eval('third()'); }");
g.eval("function third() { debugger; }");
g.evaluate("first();");
assertEq(result, "global, first, second, eval, third");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Frame.prototype.this in strict-mode functions, with primitive values
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Frame.prototype.this in strict direct eval frames
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Frame.prototype.this in non-strict-mode functions, with primitive values
function classOf(obj) {

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Debug.Frame.prototype.this in functions, with object values
function classOf(obj) {

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Debug.Object basics
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// tests calling script functions via Debug.Object.prototype.apply/call
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// tests calling native functions via Debug.Object.prototype.apply/call
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// reentering the debugger several times via debuggerHandler and apply/call on a single stack
var g = newGlobal("new-compartment");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Debug.Object.prototype.apply/call works with function proxies
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Test Debug.Object.prototype.callable.
var g = newGlobal('new-compartment');

View File

@ -1,5 +1,4 @@
// |jit-test| debug
// Basic tests for Debug.Object.prototype.class.
var g = newGlobal('new-compartment');
var dbg = new Debug(g);
var hits = 0;
@ -14,6 +13,5 @@ dbg.hooks = {
hits++;
}
};
g.eval("(function () { debugger; })(Object.prototype, [], eval, new Date, Proxy.create({}));");
assertEq(hits, 1);

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Two references to the same object get the same Debug.Object wrapper.
var g = newGlobal('new-compartment');
var dbg = Debug(g);
var hits = 0;

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Different objects get different Debug.Object wrappers.
var g = newGlobal('new-compartment');
var dbg = Debug(g);
var hits = 0;

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// The same object gets the same Debug.Object wrapper at different times, if the difference would be observable.
var N = HOTLOOP + 4;

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Debug.Object.prototype.name
var g = newGlobal('new-compartment');
var dbg = Debug(g);
var name, hits;

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// The .name of a non-function object is undefined.
var g = newGlobal('new-compartment');
var hits = 0;
var dbg = new Debug(g);

View File

@ -1,4 +1,3 @@
// |jit-test| debug
load(libdir + 'array-compare.js');
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,4 @@
// |jit-test| debug
// Debug.Object.prototype.proto
var g = newGlobal('new-compartment');
var dbgeval = function () {
var dbg = new Debug(g);

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Test removing hooks during dispatch.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |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.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Debuggers with enabled hooks should not be GC'd even if they are otherwise
// unreachable.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Dispatching an event to a debugger must keep enough of it gc-alive to avoid
// crashing.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Storing a property on a Debug.Object protects it from GC as long as the
// referent is alive.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Storing a Debug.Object as a key in a WeakMap protects it from GC as long as
// the referent is alive.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// If a Debug survives its debuggee, its object cache must still be swept.
var g2arr = []; // non-debuggee globals

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Debug objects do not keep debuggee globals live.
var dbg = new Debug;
for (var i = 0; i < 4; i++)
dbg.addDebuggee(newGlobal('new-compartment'));

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// Don't assert with dead Debug.Object and live cross-compartment wrapper of referent.
var g = newGlobal('new-compartment');
for (var j = 0; j < 4; j++) {
var dbg = new Debug;

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Debuggers with enabled throw hooks should not be GC'd even if they are
// otherwise unreachable.

View File

@ -1,13 +1,8 @@
// |jit-test| debug
var g = newGlobal('new-compartment');
g.log = '';
var dbg = Debug(g);
var hooks = {
debuggerHandler: function (stack) {
g.log += '!';
}
};
var hooks = {debuggerHandler: function (stack) { g.log += '!'; }};
dbg.hooks = hooks;
assertEq(dbg.hooks, hooks);
assertEq(g.eval("log += '1'; debugger; log += '2'; 3;"), 3);

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Activity in the debugger compartment should not trigger debug hooks.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// A debugger statement in a debuggerHandler should not reenter.
var g = newGlobal('new-compartment');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// If a hook is deleted after setHooks or overwritten with a primitive, it
// simply isn't called.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Basic throw hook test.
load(libdir + "asserts.js");

View File

@ -1,6 +1,4 @@
// |jit-test| debug
// hooks.throw is not called for exceptions thrown and handled in the debugger.
var g = newGlobal('new-compartment');
var dbg = Debug(g);
g.log = '';

View File

@ -1,10 +1,8 @@
// |jit-test| debug
// Simple {throw:} resumption.
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
var dbg = Debug(g);
dbg.hooks = {
debuggerHandler: function (stack) {

View File

@ -1,8 +1,5 @@
// |jit-test| debug
// Simple {return:} resumption.
var g = newGlobal('new-compartment');
var dbg = Debug(g);
dbg.hooks = {
debuggerHandler: function (stack) {

View File

@ -1,4 +1,4 @@
// |jit-test| debug
// Check superficial characteristics of functions and properties (not functionality).
function checkFunction(obj, name, nargs) {
var desc = Object.getOwnPropertyDescriptor(obj, name);

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Debug.prototype.hooks
load(libdir + 'asserts.js');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// dumb basics of uncaughtExceptionHook
load(libdir + 'asserts.js');

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Uncaught exceptions in the debugger itself are delivered to the
// uncaughtExceptionHook.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// Returning a bad resumption value causes an exception that is reported to the
// uncaughtExceptionHook.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// uncaughtExceptionHook returns a resumption value.
load(libdir + "asserts.js");

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// uncaughtExceptionHook resumption value other than undefined causes further
// hooks to be skipped.

View File

@ -1,4 +1,3 @@
// |jit-test| debug
// After hooks.throw throws, if uncaughtExceptionHook returns undefined,
// the original exception continues to propagate.

View File

@ -315,7 +315,7 @@ Script::analyze(JSContext *cx, JSScript *script)
* by debug code or by eval, or if they could be accessed by an inner script.
*/
if (script->usesEval || cx->compartment->debugMode) {
if (script->usesEval || cx->compartment->debugMode()) {
for (uint32 i = 0; i < nfixed; i++)
setLocal(i, LOCAL_USE_BEFORE_DEF);
}
@ -330,7 +330,7 @@ Script::analyze(JSContext *cx, JSScript *script)
* If the script is in debug mode, JS_SetFrameReturnValue can be called at
* any safe point.
*/
if (cx->compartment->debugMode)
if (cx->compartment->debugMode())
usesRval = true;
/*

View File

@ -139,7 +139,7 @@ BEGIN_TEST(testDebugger_debugObjectVsDebugMode)
EVAL("debuggee.eval('debugger; debugger; debugger;');\n"
"hits;\n",
&v);
CHECK_SAME(v, JSVAL_ONE);
CHECK_SAME(v, INT_TO_JSVAL(4));
return true;
}

Some files were not shown because too many files have changed in this diff Show More