mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
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:
parent
2ed818c0ac
commit
6a958619a0
@ -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);
|
17
js/src/jit-test/tests/debug/Debug-ctor-02.js
Normal file
17
js/src/jit-test/tests/debug/Debug-ctor-02.js
Normal 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);
|
6
js/src/jit-test/tests/debug/Debug-ctor-03.js
Normal file
6
js/src/jit-test/tests/debug/Debug-ctor-03.js
Normal 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);");
|
@ -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();
|
||||
|
@ -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');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Debug hooks fire based on debuggees.
|
||||
|
||||
var g1 = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// hasDebuggee tests.
|
||||
|
||||
var g1 = newGlobal('new-compartment'), g1w;
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// addDebuggee returns different Debug.Object wrappers for different Debug objects.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// {has,add,remove}Debuggee throw a TypeError if the argument is invalid.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Handle proto-less objects passed to addDebuggee.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);");
|
||||
|
@ -1,5 +1,3 @@
|
||||
// |jit-test| debug
|
||||
|
||||
var desc = Object.getOwnPropertyDescriptor(Debug.prototype, "enabled");
|
||||
assertEq(typeof desc.get, 'function');
|
||||
assertEq(typeof desc.set, 'function');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// getYoungestFrame basics.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Hooks and Debug.prototype.getYoungestFrame produce the same Frame object.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// When there are multiple debuggers, their hooks are called in order.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -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.
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Q: But who shall debug the debuggers? A: jimb
|
||||
|
||||
var log = '';
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Frame.prototype.arguments with primitive values
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Object arguments.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Destructuring arguments.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// frame.arguments works for all live frames
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// frame.arguments is "live" (it reflects assignments to arguments).
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Test extracting frame.arguments element getters and calling them in
|
||||
// various awkward ways.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// simplest possible test of Debug.Frame.prototype.eval
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// frame.eval() throws if frame is not live
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Test eval-ing names in a topmost script frame
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// frame.eval SyntaxErrors are reflected, not thrown
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// var declarations in strict frame.eval do not modify the frame
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -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");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// test frame.eval in non-top frames
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// The arguments can escape from a function via a debugging hook.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// assigning to local variables in frame.eval code
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -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);
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// evalWithBindings basics
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// evalWithBindings code can assign to the bindings.
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = new Debug(g);
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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);
|
||||
|
28
js/src/jit-test/tests/debug/Frame-live-04.js
Normal file
28
js/src/jit-test/tests/debug/Frame-live-04.js
Normal 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);
|
@ -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");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Frame.prototype.this in strict-mode functions, with primitive values
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Frame.prototype.this in strict direct eval frames
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Frame.prototype.this in non-strict-mode functions, with primitive values
|
||||
|
||||
function classOf(obj) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Debug.Frame.prototype.this in functions, with object values
|
||||
|
||||
function classOf(obj) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Debug.Object basics
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// tests calling script functions via Debug.Object.prototype.apply/call
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// tests calling native functions via Debug.Object.prototype.apply/call
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -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");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Debug.Object.prototype.apply/call works with function proxies
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Test Debug.Object.prototype.callable.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -1,6 +1,4 @@
|
||||
// |jit-test| debug
|
||||
// Debug.Object.prototype.name
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbg = Debug(g);
|
||||
var name, hits;
|
||||
|
@ -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);
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
load(libdir + 'array-compare.js');
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,4 @@
|
||||
// |jit-test| debug
|
||||
// Debug.Object.prototype.proto
|
||||
var g = newGlobal('new-compartment');
|
||||
var dbgeval = function () {
|
||||
var dbg = new Debug(g);
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Test removing hooks during dispatch.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -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.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Debuggers with enabled hooks should not be GC'd even if they are otherwise
|
||||
// unreachable.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Dispatching an event to a debugger must keep enough of it gc-alive to avoid
|
||||
// crashing.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
|
@ -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'));
|
||||
|
@ -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;
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Debuggers with enabled throw hooks should not be GC'd even if they are
|
||||
// otherwise unreachable.
|
||||
|
||||
|
@ -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);
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Activity in the debugger compartment should not trigger debug hooks.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// A debugger statement in a debuggerHandler should not reenter.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// If a hook is deleted after setHooks or overwritten with a primitive, it
|
||||
// simply isn't called.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Basic throw hook test.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -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 = '';
|
||||
|
@ -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) {
|
||||
|
@ -1,8 +1,5 @@
|
||||
// |jit-test| debug
|
||||
// Simple {return:} resumption.
|
||||
|
||||
var g = newGlobal('new-compartment');
|
||||
|
||||
var dbg = Debug(g);
|
||||
dbg.hooks = {
|
||||
debuggerHandler: function (stack) {
|
||||
|
@ -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);
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Debug.prototype.hooks
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// dumb basics of uncaughtExceptionHook
|
||||
|
||||
load(libdir + 'asserts.js');
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Uncaught exceptions in the debugger itself are delivered to the
|
||||
// uncaughtExceptionHook.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// Returning a bad resumption value causes an exception that is reported to the
|
||||
// uncaughtExceptionHook.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// uncaughtExceptionHook returns a resumption value.
|
||||
|
||||
load(libdir + "asserts.js");
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// uncaughtExceptionHook resumption value other than undefined causes further
|
||||
// hooks to be skipped.
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
// |jit-test| debug
|
||||
// After hooks.throw throws, if uncaughtExceptionHook returns undefined,
|
||||
// the original exception continues to propagate.
|
||||
|
||||
|
@ -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;
|
||||
|
||||
/*
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user