mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1031876 - Remove JS_SetTrap and friends. r=jimb
This commit is contained in:
parent
58f2cd6666
commit
55ca76bc2e
@ -59,10 +59,6 @@ typedef enum JSTrapStatus {
|
||||
JSTRAP_LIMIT
|
||||
} JSTrapStatus;
|
||||
|
||||
typedef JSTrapStatus
|
||||
(* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
|
||||
JS::Value closure);
|
||||
|
||||
typedef JSTrapStatus
|
||||
(* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
|
||||
void *closure);
|
||||
@ -125,21 +121,6 @@ JS_SetDebugMode(JSContext *cx, bool debug);
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_SetSingleStepMode(JSContext *cx, JS::HandleScript script, bool singleStep);
|
||||
|
||||
/* The closure argument will be marked. */
|
||||
extern JS_PUBLIC_API(bool)
|
||||
JS_SetTrap(JSContext *cx, JS::HandleScript script, jsbytecode *pc,
|
||||
JSTrapHandler handler, JS::HandleValue closure);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
JSTrapHandler *handlerp, JS::Value *closurep);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ClearScriptTraps(JSRuntime *rt, JSScript *script);
|
||||
|
||||
extern JS_PUBLIC_API(void)
|
||||
JS_ClearAllTrapsForCompartment(JSContext *cx);
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
extern JS_PUBLIC_API(bool)
|
||||
|
@ -100,7 +100,6 @@ class EvalScriptGuard
|
||||
|
||||
~EvalScriptGuard() {
|
||||
if (script_) {
|
||||
script_->clearTraps(cx_->runtime()->defaultFreeOp());
|
||||
script_->cacheForEval();
|
||||
EvalCacheEntry cacheEntry = {script_, lookup_.callerScript, lookup_.pc};
|
||||
lookup_.str = lookupStr_;
|
||||
|
@ -1,8 +0,0 @@
|
||||
// |jit-test| debug;
|
||||
|
||||
// Binary: cache/js-dbg-32-ceef8a5c3ca1-linux
|
||||
// Flags:
|
||||
//
|
||||
function f() { eval(''); }
|
||||
trap(f, 9, "");
|
||||
f()
|
@ -1,4 +0,0 @@
|
||||
// |jit-test| debug
|
||||
var f = (function () {with ({}) {}});
|
||||
trap(f, 5, ''); // trap "nullblockchain" op
|
||||
f();
|
@ -1,4 +0,0 @@
|
||||
// |jit-test| debug
|
||||
function f() { ({}).m = function(){}; }
|
||||
trap(f, 11, '');
|
||||
f();
|
@ -1,79 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
|
||||
// bug 657975
|
||||
function f1(){ "use strict"; options('strict'); }
|
||||
trap(f1, 0, '')
|
||||
f1()
|
||||
|
||||
// bug 657979
|
||||
function f2(){ with({a:0}){}; }
|
||||
trap(f2, 0, '')
|
||||
f2()
|
||||
|
||||
x = 0;
|
||||
|
||||
// bug 657984 #1
|
||||
function f3(){ for(y in x); }
|
||||
trap(f3, 5, '')
|
||||
f3()
|
||||
|
||||
// bug 657984 #2
|
||||
function f4(){ for(y in x); }
|
||||
trap(f4, 8, '')
|
||||
f4()
|
||||
|
||||
// bug 658464
|
||||
function f5() {
|
||||
for ([, x] in 0) {}
|
||||
}
|
||||
trap(f5, 7, '')
|
||||
f5()
|
||||
|
||||
// bug 658465
|
||||
function f6() {
|
||||
"use strict";
|
||||
print(Math.min(0, 1));
|
||||
}
|
||||
trap(f6, 10, '')
|
||||
f6()
|
||||
|
||||
// bug 658491
|
||||
function f7() {
|
||||
try { y = w; } catch(y) {}
|
||||
}
|
||||
trap(f7, 14, '')
|
||||
f7()
|
||||
|
||||
// bug 658950
|
||||
f8 = (function() {
|
||||
let x;
|
||||
yield
|
||||
})
|
||||
trap(f8, 6, undefined);
|
||||
for (a in f8())
|
||||
(function() {})()
|
||||
|
||||
// bug 659043
|
||||
f9 = (function() {
|
||||
for (let a = 0; a < 0; ++a) {
|
||||
for each(let w in []) {}
|
||||
}
|
||||
})
|
||||
trap(f9, 23, undefined);
|
||||
for (b in f9())
|
||||
(function() {})()
|
||||
|
||||
// bug 659233
|
||||
f10 = (function() {
|
||||
while (h) {
|
||||
continue
|
||||
}
|
||||
})
|
||||
trap(f10, 0, '');
|
||||
try { f10() } catch (e) {}
|
||||
|
||||
// bug 659337
|
||||
f11 = Function("for (x = 0; x < 6; x++) { gc() }");
|
||||
trap(f11, 23, '');
|
||||
f11()
|
@ -11,5 +11,5 @@ var s = '';
|
||||
for (var i = 0; i < 70000; i++) {
|
||||
s += 'function x' + i + '() { x' + i + '(); }\n';
|
||||
}
|
||||
s += 'trap(0); pc2line(1);\n'
|
||||
s += 'pc2line(1);\n'
|
||||
evaluate(s);
|
||||
|
@ -1,14 +0,0 @@
|
||||
// |jit-test| debug
|
||||
|
||||
function f(){
|
||||
this.zzz.zzz;
|
||||
for(let d in []);
|
||||
}
|
||||
trap(f, 16, '')
|
||||
try {
|
||||
f()
|
||||
} catch(e) {
|
||||
caught = true;
|
||||
assertEq(""+e, "TypeError: this.zzz is undefined");
|
||||
}
|
||||
assertEq(caught, true);
|
@ -1,5 +0,0 @@
|
||||
// |jit-test| debug
|
||||
|
||||
function f() {}
|
||||
trap(f, 0, 'eval("2+2")');
|
||||
f();
|
@ -1,15 +0,0 @@
|
||||
// |jit-test| debug
|
||||
|
||||
f = (function() {
|
||||
function b() {
|
||||
"use strict";
|
||||
Object.defineProperty(this, "x", ({}));
|
||||
}
|
||||
for each(let d in [0, 0]) {
|
||||
try {
|
||||
b(d);
|
||||
} catch (e) {}
|
||||
}
|
||||
})
|
||||
trap(f, 40, undefined);
|
||||
f();
|
@ -1,6 +0,0 @@
|
||||
// |jit-test| debug; error: TypeError
|
||||
function f() {
|
||||
""(this.z)
|
||||
}
|
||||
trap(f, 0, '')
|
||||
f()
|
@ -1,4 +0,0 @@
|
||||
// |jit-test| debug
|
||||
function f() {}
|
||||
trap(f, 0, 'eval("2+2")');
|
||||
f();
|
@ -1,4 +0,0 @@
|
||||
// |jit-test| debug
|
||||
function f() { eval(''); }
|
||||
trap(f, 6, '');
|
||||
f();
|
@ -1,25 +0,0 @@
|
||||
// |jit-test| debug
|
||||
// The GC can cope with old and new breakpoints at the same position.
|
||||
|
||||
// This is a regression test for a bug Bill McCloskey found just by looking at
|
||||
// the source code. See bug 677386 comment 8. Here we're testing that the trap
|
||||
// string is correctly marked. (The silly expression for the trap string is to
|
||||
// ensure that it isn't constant-folded; it's harder to get a compile-time
|
||||
// constant to be GC'd.)
|
||||
|
||||
var g = newGlobal();
|
||||
g.eval("var d = 0;\n" +
|
||||
"function f() { return 'ok'; }\n" +
|
||||
"trap(f, 0, Array(17).join('\\n') + 'd++;');\n");
|
||||
|
||||
var dbg = new Debugger;
|
||||
var gw = dbg.addDebuggee(g);
|
||||
var fw = gw.getOwnPropertyDescriptor("f").value;
|
||||
var bp = {hits: 0, hit: function (frame) { this.hits++; }};
|
||||
fw.script.setBreakpoint(0, bp);
|
||||
|
||||
gc();
|
||||
|
||||
g.f();
|
||||
assertEq(g.d, 1);
|
||||
assertEq(bp.hits, 1);
|
@ -1,10 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
|
||||
function nop(){}
|
||||
function caller(obj) {
|
||||
var x = 'ignominy';
|
||||
return x;
|
||||
}
|
||||
trap(caller, 9 /* getlocal 'x' */, "var x = 'success'; nop()");
|
||||
assertEq(caller(this), "success");
|
@ -1,12 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
|
||||
function nop(){}
|
||||
function caller(obj) {
|
||||
var x = ({ dana : "zuul" });
|
||||
return x;
|
||||
}
|
||||
// 0 is the pc of the first line, we want the pc of "return x", on the next line.
|
||||
var pc = line2pc(caller, pc2line(caller, 0) + 1);
|
||||
trap(caller, pc, "x = 'success'; nop()");
|
||||
assertEq(caller(this), "success");
|
@ -1,10 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
|
||||
function nop(){}
|
||||
function caller(obj) {
|
||||
var x = "failure";
|
||||
return x;
|
||||
}
|
||||
trap(caller, 9 /* GETLOCAL x */, "x = 'success'; nop()");
|
||||
assertEq(caller(this), "success");
|
@ -1,10 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
var x = "failure";
|
||||
function main() { x = "success"; }
|
||||
|
||||
/* The JSOP_STOP in main. */
|
||||
trap(main, 10, "");
|
||||
main();
|
||||
|
||||
assertEq(x, "success");
|
@ -1,11 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
var x = "notset";
|
||||
function main() { x = "failure"; }
|
||||
function success() { x = "success"; }
|
||||
|
||||
/* The JSOP_STOP in main. */
|
||||
trap(main, 16, "success()");
|
||||
main();
|
||||
|
||||
assertEq(x, "success");
|
@ -1,12 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
var x = "notset";
|
||||
function main() { x = "success"; }
|
||||
function failure() { x = "failure"; }
|
||||
|
||||
/* The JSOP_STOP in main. */
|
||||
trap(main, 10, "failure()");
|
||||
untrap(main, 10);
|
||||
main();
|
||||
|
||||
assertEq(x, "success");
|
@ -1,8 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
function main() {
|
||||
return "failure";
|
||||
}
|
||||
/* JSOP_RETURN in main. */
|
||||
trap(main, 5, "'success'");
|
||||
assertEq(main(), "success");
|
@ -1,8 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
function main() {
|
||||
return 1;
|
||||
}
|
||||
/* JSOP_RETURN in main. */
|
||||
trap(main, 1, "0");
|
||||
assertEq(main(), 0);
|
@ -1,13 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
function main() {
|
||||
/* The JSOP_STOP in main. */
|
||||
a = { valueOf: function () { trap(main, 55, "success()"); } };
|
||||
a + "";
|
||||
x = "failure";
|
||||
}
|
||||
function success() { x = "success"; }
|
||||
|
||||
main();
|
||||
assertEq(x, "success");
|
@ -1,15 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
function main() {
|
||||
/* The JSOP_STOP in main. */
|
||||
a = { valueOf: function () { trap(main, 91, "success()"); } };
|
||||
b = "";
|
||||
eval();
|
||||
a + b;
|
||||
x = "failure";
|
||||
}
|
||||
function success() { x = "success"; }
|
||||
|
||||
main();
|
||||
assertEq(x, "success");
|
@ -1,16 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
function myparent(nested) {
|
||||
if (nested) {
|
||||
/* myparent call in myparent. */
|
||||
trap(myparent, 39, "failure()");
|
||||
} else {
|
||||
x = "success";
|
||||
myparent(true);
|
||||
}
|
||||
}
|
||||
function failure() { x = "failure"; }
|
||||
|
||||
myparent(false);
|
||||
assertEq(x, "success");
|
@ -1,22 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
|
||||
function child() {
|
||||
x = "failure1";
|
||||
/* JSOP_STOP in parent. */
|
||||
trap(parent, 16, "success()");
|
||||
}
|
||||
|
||||
function parent() {
|
||||
x = "failure2";
|
||||
}
|
||||
/* First op in parent. */
|
||||
trap(parent, 0, "child()");
|
||||
|
||||
function success() {
|
||||
x = "success";
|
||||
}
|
||||
|
||||
parent();
|
||||
assertEq(x, "success");
|
@ -1,17 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
function child() {
|
||||
/* JSOP_STOP in parent. */
|
||||
trap(parent, 26, "success()");
|
||||
}
|
||||
function parent() {
|
||||
child();
|
||||
x = "failure";
|
||||
}
|
||||
function success() {
|
||||
x = "success";
|
||||
}
|
||||
|
||||
parent()
|
||||
assertEq(x, "success");
|
@ -1,19 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
|
||||
function myparent(nested) {
|
||||
if (nested) {
|
||||
/* noop call in myparent */
|
||||
trap(myparent, 62, "success()");
|
||||
} else {
|
||||
myparent(true);
|
||||
x = "failure";
|
||||
noop();
|
||||
}
|
||||
}
|
||||
function noop() { }
|
||||
function success() { x = "success"; }
|
||||
|
||||
myparent();
|
||||
assertEq(x, "success");
|
@ -1,24 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
|
||||
function doNothing() { }
|
||||
|
||||
function myparent(nested) {
|
||||
if (nested) {
|
||||
/* JSOP_CALL to doNothing in myparent with nested = true. */
|
||||
trap(myparent, 36, "success()");
|
||||
doNothing();
|
||||
} else {
|
||||
doNothing();
|
||||
}
|
||||
}
|
||||
/* JSOP_CALL to doNothing in myparent with nested = false. */
|
||||
trap(myparent, 51, "myparent(true)");
|
||||
|
||||
function success() {
|
||||
x = "success";
|
||||
}
|
||||
|
||||
myparent(false);
|
||||
assertEq(x, "success");
|
@ -1,12 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
function main() {
|
||||
/* The JSOP_STOP in main. */
|
||||
trap(main, 38, "success()");
|
||||
x = "failure";
|
||||
}
|
||||
function success() { x = "success"; }
|
||||
|
||||
main();
|
||||
assertEq(x, "success");
|
@ -1,5 +0,0 @@
|
||||
// |jit-test| debug
|
||||
|
||||
var otherGlobal = newGlobal();
|
||||
var f = otherGlobal.untrap;
|
||||
f();
|
@ -1,16 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
function child() {
|
||||
/* JSOP_STOP in parent */
|
||||
untrap(parent, 16);
|
||||
x = "success";
|
||||
}
|
||||
function parent() {
|
||||
x = "failure";
|
||||
}
|
||||
/* JSOP_STOP in parent */
|
||||
trap(parent, 16, "child()");
|
||||
|
||||
parent();
|
||||
assertEq(x, "success");
|
@ -1,14 +0,0 @@
|
||||
// |jit-test| debug
|
||||
setDebug(true);
|
||||
x = "notset";
|
||||
function main() {
|
||||
/* JSOP_STOP in main. */
|
||||
untrap(main, 24);
|
||||
x = "success";
|
||||
}
|
||||
function failure() { x = "failure"; }
|
||||
|
||||
/* JSOP_STOP in main. */
|
||||
trap(main, 24, "failure()");
|
||||
main();
|
||||
assertEq(x, "success");
|
@ -1,8 +0,0 @@
|
||||
// |jit-test| debug
|
||||
function f() {
|
||||
do {
|
||||
return
|
||||
} while (e)
|
||||
}
|
||||
trap(f, 1, '')
|
||||
f()
|
@ -71,7 +71,6 @@ UNIFIED_SOURCES += [
|
||||
'testStructuredClone.cpp',
|
||||
'testSymbol.cpp',
|
||||
'testToIntWidth.cpp',
|
||||
'testTrap.cpp',
|
||||
'testTypedArrays.cpp',
|
||||
'testUncaughtError.cpp',
|
||||
'testUTF8.cpp',
|
||||
|
@ -1,86 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "js/OldDebugAPI.h"
|
||||
#include "jsapi-tests/tests.h"
|
||||
|
||||
static int emptyTrapCallCount = 0;
|
||||
|
||||
static JSTrapStatus
|
||||
EmptyTrapHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
|
||||
jsval closureArg)
|
||||
{
|
||||
JS::RootedValue closure(cx, closureArg);
|
||||
JS_GC(JS_GetRuntime(cx));
|
||||
if (closure.isString())
|
||||
++emptyTrapCallCount;
|
||||
return JSTRAP_CONTINUE;
|
||||
}
|
||||
|
||||
BEGIN_TEST(testTrap_gc)
|
||||
{
|
||||
static const char source[] =
|
||||
"var i = 0;\n"
|
||||
"var sum = 0;\n"
|
||||
"while (i < 10) {\n"
|
||||
" sum += i;\n"
|
||||
" ++i;\n"
|
||||
"}\n"
|
||||
"({ result: sum });\n"
|
||||
;
|
||||
|
||||
// compile
|
||||
JS::CompileOptions options(cx);
|
||||
options.setFileAndLine(__FILE__, 1);
|
||||
JS::RootedScript script(cx);
|
||||
CHECK(JS_CompileScript(cx, global, source, strlen(source), options, &script));
|
||||
CHECK(script);
|
||||
|
||||
// execute
|
||||
JS::RootedValue v2(cx);
|
||||
CHECK(JS_ExecuteScript(cx, global, script, &v2));
|
||||
CHECK(v2.isObject());
|
||||
CHECK_EQUAL(emptyTrapCallCount, 0);
|
||||
|
||||
// Enable debug mode
|
||||
CHECK(JS_SetDebugMode(cx, true));
|
||||
|
||||
static const char trapClosureText[] = "some trap closure";
|
||||
|
||||
// scope JSScript usage to make sure that it is not used after
|
||||
// JS_ExecuteScript. This way we avoid using Anchor.
|
||||
JS::RootedString trapClosure(cx);
|
||||
{
|
||||
jsbytecode *line2 = JS_LineNumberToPC(cx, script, 1);
|
||||
CHECK(line2);
|
||||
|
||||
jsbytecode *line6 = JS_LineNumberToPC(cx, script, 5);
|
||||
CHECK(line2);
|
||||
|
||||
trapClosure = JS_NewStringCopyZ(cx, trapClosureText);
|
||||
CHECK(trapClosure);
|
||||
JS::RootedValue closureValue(cx, JS::StringValue(trapClosure));
|
||||
JS_SetTrap(cx, script, line2, EmptyTrapHandler, closureValue);
|
||||
JS_SetTrap(cx, script, line6, EmptyTrapHandler, closureValue);
|
||||
|
||||
JS_GC(rt);
|
||||
|
||||
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
|
||||
}
|
||||
|
||||
// execute
|
||||
CHECK(JS_ExecuteScript(cx, global, script, &v2));
|
||||
CHECK_EQUAL(emptyTrapCallCount, 11);
|
||||
|
||||
JS_GC(rt);
|
||||
|
||||
CHECK(JS_FlatStringEqualsAscii(JS_ASSERT_STRING_IS_FLAT(trapClosure), trapClosureText));
|
||||
|
||||
return true;
|
||||
}
|
||||
END_TEST(testTrap_gc)
|
||||
|
@ -932,17 +932,6 @@ JSCompartment::clearBreakpointsIn(FreeOp *fop, js::Debugger *dbg, HandleObject h
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::clearTraps(FreeOp *fop)
|
||||
{
|
||||
MinorGC(fop->runtime(), JS::gcreason::EVICT_NURSERY);
|
||||
for (gc::ZoneCellIter i(zone(), gc::FINALIZE_SCRIPT); !i.done(); i.next()) {
|
||||
JSScript *script = i.get<JSScript>();
|
||||
if (script->compartment() == this && script->hasAnyBreakpointsOrStepMode())
|
||||
script->clearTraps(fop);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JSCompartment::addSizeOfIncludingThis(mozilla::MallocSizeOf mallocSizeOf,
|
||||
size_t *tiAllocationSiteTables,
|
||||
|
@ -428,7 +428,6 @@ struct JSCompartment
|
||||
js::AutoDebugModeInvalidation &invalidate);
|
||||
|
||||
void clearBreakpointsIn(js::FreeOp *fop, js::Debugger *dbg, JS::HandleObject handler);
|
||||
void clearTraps(js::FreeOp *fop);
|
||||
|
||||
private:
|
||||
void sweepBreakpoints(js::FreeOp *fop);
|
||||
|
@ -2620,7 +2620,6 @@ JSScript::finalize(FreeOp *fop)
|
||||
// JSScript::Create(), but not yet finished initializing it with
|
||||
// fullyInitFromEmitter() or fullyInitTrivial().
|
||||
|
||||
clearTraps(fop);
|
||||
fop->runtime()->spsProfiler.onScriptFinalized(this);
|
||||
|
||||
if (types)
|
||||
@ -3141,7 +3140,6 @@ JSScript::destroyDebugScript(FreeOp *fop)
|
||||
if (BreakpointSite *site = getBreakpointSite(pc)) {
|
||||
/* Breakpoints are swept before finalization. */
|
||||
JS_ASSERT(site->firstBreakpoint() == nullptr);
|
||||
site->clearTrap(fop, nullptr, nullptr);
|
||||
JS_ASSERT(getBreakpointSite(pc) == nullptr);
|
||||
}
|
||||
}
|
||||
@ -3312,20 +3310,7 @@ JSScript::hasBreakpointsAt(jsbytecode *pc)
|
||||
if (!site)
|
||||
return false;
|
||||
|
||||
return site->enabledCount > 0 || site->trapHandler;
|
||||
}
|
||||
|
||||
void
|
||||
JSScript::clearTraps(FreeOp *fop)
|
||||
{
|
||||
if (!hasAnyBreakpointsOrStepMode())
|
||||
return;
|
||||
|
||||
for (jsbytecode *pc = code(); pc < codeEnd(); pc++) {
|
||||
BreakpointSite *site = getBreakpointSite(pc);
|
||||
if (site)
|
||||
site->clearTrap(fop);
|
||||
}
|
||||
return site->enabledCount > 0;
|
||||
}
|
||||
|
||||
void
|
||||
@ -3383,14 +3368,6 @@ JSScript::markChildren(JSTracer *trc)
|
||||
|
||||
bindings.trace(trc);
|
||||
|
||||
if (hasAnyBreakpointsOrStepMode()) {
|
||||
for (unsigned i = 0; i < length(); i++) {
|
||||
BreakpointSite *site = debugScript()->breakpoints[i];
|
||||
if (site && site->trapHandler)
|
||||
MarkValue(trc, &site->trapClosure, "trap closure");
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef JS_ION
|
||||
jit::TraceIonScripts(trc, this);
|
||||
#endif
|
||||
|
@ -1578,9 +1578,6 @@ class JSScript : public js::gc::BarrieredCell<JSScript>
|
||||
void destroyBreakpointSite(js::FreeOp *fop, jsbytecode *pc);
|
||||
|
||||
void clearBreakpointsIn(js::FreeOp *fop, js::Debugger *dbg, JSObject *handler);
|
||||
void clearTraps(js::FreeOp *fop);
|
||||
|
||||
void markTrapClosures(JSTracer *trc);
|
||||
|
||||
/*
|
||||
* Set or clear the single-step flag. If the flag is set or the count
|
||||
|
@ -1814,43 +1814,6 @@ TrapHandler(JSContext *cx, JSScript *, jsbytecode *pc, jsval *rvalArg,
|
||||
return JSTRAP_CONTINUE;
|
||||
}
|
||||
|
||||
static bool
|
||||
Trap(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedScript script(cx);
|
||||
int32_t i;
|
||||
|
||||
if (args.length() == 0) {
|
||||
JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr, JSSMSG_TRAP_USAGE);
|
||||
return false;
|
||||
}
|
||||
argc = args.length() - 1;
|
||||
RootedString str(cx, JS::ToString(cx, args[argc]));
|
||||
if (!str)
|
||||
return false;
|
||||
args[argc].setString(str);
|
||||
if (!GetScriptAndPCArgs(cx, argc, args.array(), &script, &i))
|
||||
return false;
|
||||
args.rval().setUndefined();
|
||||
RootedValue strValue(cx, StringValue(str));
|
||||
return JS_SetTrap(cx, script, script->offsetToPC(i), TrapHandler, strValue);
|
||||
}
|
||||
|
||||
static bool
|
||||
Untrap(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
RootedScript script(cx);
|
||||
int32_t i;
|
||||
|
||||
if (!GetScriptAndPCArgs(cx, args.length(), args.array(), &script, &i))
|
||||
return false;
|
||||
JS_ClearTrap(cx, script, script->offsetToPC(i), nullptr, nullptr);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSTrapStatus
|
||||
DebuggerAndThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval,
|
||||
void *closure)
|
||||
@ -4848,18 +4811,10 @@ static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
|
||||
" arguments[0] (of the call to nestedShell) will be argv[1], arguments[1] will\n"
|
||||
" be argv[2], etc."),
|
||||
|
||||
JS_FN_HELP("trap", Trap, 3, 0,
|
||||
"trap([fun, [pc,]] exp)",
|
||||
" Trap bytecode execution."),
|
||||
|
||||
JS_FN_HELP("assertFloat32", testingFunc_assertFloat32, 2, 0,
|
||||
"assertFloat32(value, isFloat32)",
|
||||
" In IonMonkey only, asserts that value has (resp. hasn't) the MIRType_Float32 if isFloat32 is true (resp. false)."),
|
||||
|
||||
JS_FN_HELP("untrap", Untrap, 2, 0,
|
||||
"untrap(fun[, pc])",
|
||||
" Remove a trap."),
|
||||
|
||||
JS_FN_HELP("withSourceHook", WithSourceHook, 1, 0,
|
||||
"withSourceHook(hook, fun)",
|
||||
" Set this JS runtime's lazy source retrieval hook (that is, the hook\n"
|
||||
|
@ -1,26 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
/*
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/licenses/publicdomain/
|
||||
*/
|
||||
|
||||
var BUGNUMBER = 549617;
|
||||
var summary = 'flat closure debugged via trap while still active';
|
||||
|
||||
var expect = "abc";
|
||||
var actual = expect;
|
||||
|
||||
function a(x, y) {
|
||||
return function () { return x; };
|
||||
}
|
||||
|
||||
var f = a("abc", 123);
|
||||
if (this.trap && this.setDebug) {
|
||||
setDebug(true);
|
||||
trap(f, "try {actual = x} catch (e) {actual = e}");
|
||||
}
|
||||
f();
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
printStatus("All tests passed!");
|
@ -1,36 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 429248;
|
||||
var summary = 'Do not assert: 0';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
function c() { do{}while(0) }
|
||||
|
||||
if (typeof trap == 'function' && typeof setDebug == 'function')
|
||||
{
|
||||
setDebug(true);
|
||||
trap(c, 0, "");
|
||||
}
|
||||
c + '';
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,36 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 422137;
|
||||
var summary = 'Do not assert or bogo OOM with debugger trap on JOF_CALL bytecode';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
function f() { return a(); }
|
||||
|
||||
if (typeof trap == 'function' && typeof setDebug == 'function')
|
||||
{
|
||||
setDebug(true);
|
||||
trap(f, 0, "print('trap')");
|
||||
}
|
||||
f + '';
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,34 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 429264;
|
||||
var summary = 'Do not assert: top < ss->printer->script->depth';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
function f() { for(; 1; ) { } }
|
||||
if (typeof trap == 'function' && typeof setDebug == 'function')
|
||||
{
|
||||
setDebug(true);
|
||||
trap(f, 0, "");
|
||||
}
|
||||
f + '';
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 431428;
|
||||
var summary = 'Do not crash with for..in, trap';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
function f() {
|
||||
for ( var a in [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]) { }
|
||||
}
|
||||
|
||||
if (typeof trap == 'function' && typeof setDebug == 'function')
|
||||
{
|
||||
setDebug(true);
|
||||
"" + f;
|
||||
trap(f, 0, "");
|
||||
"" + f;
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
var BUGNUMBER = 429266;
|
||||
var summary = 'Do not assert: nuses == 0 || *pcstack[pcdepth - 1] == JSOP_ENTERBLOCK';
|
||||
var actual = 'No Crash';
|
||||
var expect = 'No Crash';
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
test();
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
function test()
|
||||
{
|
||||
enterFunc ('test');
|
||||
printBugNumber(BUGNUMBER);
|
||||
printStatus (summary);
|
||||
|
||||
try
|
||||
{
|
||||
function f() { let (a) 1; null.x; }
|
||||
if (typeof trap == 'function')
|
||||
{
|
||||
trap(f, 0, "");
|
||||
}
|
||||
f();
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
}
|
||||
|
||||
reportCompare(expect, actual, summary);
|
||||
|
||||
exitFunc ('test');
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var a = 0;
|
||||
function f() {
|
||||
let (a = let (x = 1) x) {}
|
||||
}
|
||||
|
||||
trap(f, 4, 'assertEq(evalInFrame(1, "a"), 0)');
|
||||
f();
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,13 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var a = 0;
|
||||
function f() {
|
||||
let (a = let (x = 1) x) {}
|
||||
}
|
||||
|
||||
trap(f, 4, 'assertEq(evalInFrame(1, "a"), 0)');
|
||||
f();
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,12 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
var e = [], x = {b: []};
|
||||
function f() {
|
||||
let (a = [[] for (x in e)], {b: []} = x) {}
|
||||
}
|
||||
trap(f, 3, '');
|
||||
f();
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
@ -1,18 +0,0 @@
|
||||
// |reftest| require-or(debugMode,skip)
|
||||
// Any copyright is dedicated to the Public Domain.
|
||||
// http://creativecommons.org/licenses/publicdomain/
|
||||
|
||||
|
||||
var err;
|
||||
try {
|
||||
f = function() { var x; x.y; }
|
||||
trap(f, 0, "");
|
||||
f();
|
||||
} catch (e) {
|
||||
err = e;
|
||||
}
|
||||
assertEq(err instanceof TypeError, true);
|
||||
assertEq(err.message, "x is undefined")
|
||||
|
||||
reportCompare(0, 0, 'ok');
|
||||
|
@ -235,8 +235,7 @@ class Debugger::FrameRange
|
||||
/*** Breakpoints *********************************************************************************/
|
||||
|
||||
BreakpointSite::BreakpointSite(JSScript *script, jsbytecode *pc)
|
||||
: script(script), pc(pc), enabledCount(0),
|
||||
trapHandler(nullptr), trapClosure(UndefinedValue())
|
||||
: script(script), pc(pc), enabledCount(0)
|
||||
{
|
||||
JS_ASSERT(!script->hasBreakpointsAt(pc));
|
||||
JS_INIT_CLIST(&breakpoints);
|
||||
@ -255,7 +254,7 @@ void
|
||||
BreakpointSite::inc(FreeOp *fop)
|
||||
{
|
||||
enabledCount++;
|
||||
if (enabledCount == 1 && !trapHandler)
|
||||
if (enabledCount == 1)
|
||||
recompile(fop);
|
||||
}
|
||||
|
||||
@ -264,43 +263,14 @@ BreakpointSite::dec(FreeOp *fop)
|
||||
{
|
||||
JS_ASSERT(enabledCount > 0);
|
||||
enabledCount--;
|
||||
if (enabledCount == 0 && !trapHandler)
|
||||
recompile(fop);
|
||||
}
|
||||
|
||||
void
|
||||
BreakpointSite::setTrap(FreeOp *fop, JSTrapHandler handler, const Value &closure)
|
||||
{
|
||||
trapHandler = handler;
|
||||
trapClosure = closure;
|
||||
|
||||
if (enabledCount == 0)
|
||||
recompile(fop);
|
||||
}
|
||||
|
||||
void
|
||||
BreakpointSite::clearTrap(FreeOp *fop, JSTrapHandler *handlerp, Value *closurep)
|
||||
{
|
||||
if (handlerp)
|
||||
*handlerp = trapHandler;
|
||||
if (closurep)
|
||||
*closurep = trapClosure;
|
||||
|
||||
trapHandler = nullptr;
|
||||
trapClosure = UndefinedValue();
|
||||
if (enabledCount == 0) {
|
||||
if (!fop->runtime()->isHeapBusy()) {
|
||||
/* If the GC is running then the script is being destroyed. */
|
||||
recompile(fop);
|
||||
}
|
||||
destroyIfEmpty(fop);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
BreakpointSite::destroyIfEmpty(FreeOp *fop)
|
||||
{
|
||||
if (JS_CLIST_IS_EMPTY(&breakpoints) && !trapHandler)
|
||||
if (JS_CLIST_IS_EMPTY(&breakpoints))
|
||||
script->destroyBreakpointSite(fop, pc);
|
||||
}
|
||||
|
||||
@ -1278,12 +1248,6 @@ Debugger::onTrap(JSContext *cx, MutableHandleValue vp)
|
||||
}
|
||||
}
|
||||
|
||||
if (site && site->trapHandler) {
|
||||
JSTrapStatus st = site->trapHandler(cx, script, pc, vp.address(), site->trapClosure);
|
||||
if (st != JSTRAP_CONTINUE)
|
||||
return st;
|
||||
}
|
||||
|
||||
/* By convention, return the true op to the interpreter in vp. */
|
||||
vp.setInt32(op);
|
||||
return JSTRAP_CONTINUE;
|
||||
|
@ -601,8 +601,6 @@ class BreakpointSite {
|
||||
private:
|
||||
JSCList breakpoints; /* cyclic list of all js::Breakpoints at this instruction */
|
||||
size_t enabledCount; /* number of breakpoints in the list that are enabled */
|
||||
JSTrapHandler trapHandler; /* trap state */
|
||||
HeapValue trapClosure;
|
||||
|
||||
void recompile(FreeOp *fop);
|
||||
|
||||
@ -610,12 +608,9 @@ class BreakpointSite {
|
||||
BreakpointSite(JSScript *script, jsbytecode *pc);
|
||||
Breakpoint *firstBreakpoint() const;
|
||||
bool hasBreakpoint(Breakpoint *bp);
|
||||
bool hasTrap() const { return !!trapHandler; }
|
||||
|
||||
void inc(FreeOp *fop);
|
||||
void dec(FreeOp *fop);
|
||||
void setTrap(FreeOp *fop, JSTrapHandler handler, const Value &closure);
|
||||
void clearTrap(FreeOp *fop, JSTrapHandler *handlerp = nullptr, Value *closurep = nullptr);
|
||||
void destroyIfEmpty(FreeOp *fop);
|
||||
};
|
||||
|
||||
|
@ -182,48 +182,6 @@ JS_SetSingleStepMode(JSContext *cx, HandleScript script, bool singleStep)
|
||||
return script->setStepModeFlag(cx, singleStep);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
JS_SetTrap(JSContext *cx, HandleScript script, jsbytecode *pc, JSTrapHandler handler,
|
||||
HandleValue closure)
|
||||
{
|
||||
assertSameCompartment(cx, script, closure);
|
||||
|
||||
if (!CheckDebugMode(cx))
|
||||
return false;
|
||||
|
||||
BreakpointSite *site = script->getOrCreateBreakpointSite(cx, pc);
|
||||
if (!site)
|
||||
return false;
|
||||
site->setTrap(cx->runtime()->defaultFreeOp(), handler, closure);
|
||||
return true;
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ClearTrap(JSContext *cx, JSScript *script, jsbytecode *pc,
|
||||
JSTrapHandler *handlerp, jsval *closurep)
|
||||
{
|
||||
if (BreakpointSite *site = script->getBreakpointSite(pc)) {
|
||||
site->clearTrap(cx->runtime()->defaultFreeOp(), handlerp, closurep);
|
||||
} else {
|
||||
if (handlerp)
|
||||
*handlerp = nullptr;
|
||||
if (closurep)
|
||||
*closurep = JSVAL_VOID;
|
||||
}
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ClearScriptTraps(JSRuntime *rt, JSScript *script)
|
||||
{
|
||||
script->clearTraps(rt->defaultFreeOp());
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ClearAllTrapsForCompartment(JSContext *cx)
|
||||
{
|
||||
cx->compartment()->clearTraps(cx->runtime()->defaultFreeOp());
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
JS_PUBLIC_API(bool)
|
||||
|
@ -371,7 +371,6 @@ JSRuntime::~JSRuntime()
|
||||
|
||||
/* Clear debugging state to remove GC roots. */
|
||||
for (CompartmentsIter comp(this, SkipAtoms); !comp.done(); comp.next()) {
|
||||
comp->clearTraps(defaultFreeOp());
|
||||
if (WatchpointMap *wpmap = comp->watchpointMap)
|
||||
wpmap->clear();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user