Bug 1031876 - Remove JS_SetTrap and friends. r=jimb

This commit is contained in:
Tom Schuster 2014-07-25 14:26:39 +02:00
parent 58f2cd6666
commit 55ca76bc2e
55 changed files with 5 additions and 975 deletions

View File

@ -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)

View File

@ -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_;

View File

@ -1,8 +0,0 @@
// |jit-test| debug;
// Binary: cache/js-dbg-32-ceef8a5c3ca1-linux
// Flags:
//
function f() { eval(''); }
trap(f, 9, "");
f()

View File

@ -1,4 +0,0 @@
// |jit-test| debug
var f = (function () {with ({}) {}});
trap(f, 5, ''); // trap "nullblockchain" op
f();

View File

@ -1,4 +0,0 @@
// |jit-test| debug
function f() { ({}).m = function(){}; }
trap(f, 11, '');
f();

View File

@ -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()

View File

@ -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);

View File

@ -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);

View File

@ -1,5 +0,0 @@
// |jit-test| debug
function f() {}
trap(f, 0, 'eval("2+2")');
f();

View File

@ -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();

View File

@ -1,6 +0,0 @@
// |jit-test| debug; error: TypeError
function f() {
""(this.z)
}
trap(f, 0, '')
f()

View File

@ -1,4 +0,0 @@
// |jit-test| debug
function f() {}
trap(f, 0, 'eval("2+2")');
f();

View File

@ -1,4 +0,0 @@
// |jit-test| debug
function f() { eval(''); }
trap(f, 6, '');
f();

View File

@ -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);

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -1,8 +0,0 @@
// |jit-test| debug
setDebug(true);
function main() {
return "failure";
}
/* JSOP_RETURN in main. */
trap(main, 5, "'success'");
assertEq(main(), "success");

View File

@ -1,8 +0,0 @@
// |jit-test| debug
setDebug(true);
function main() {
return 1;
}
/* JSOP_RETURN in main. */
trap(main, 1, "0");
assertEq(main(), 0);

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -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");

View File

@ -1,5 +0,0 @@
// |jit-test| debug
var otherGlobal = newGlobal();
var f = otherGlobal.untrap;
f();

View File

@ -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");

View File

@ -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");

View File

@ -1,8 +0,0 @@
// |jit-test| debug
function f() {
do {
return
} while (e)
}
trap(f, 1, '')
f()

View File

@ -71,7 +71,6 @@ UNIFIED_SOURCES += [
'testStructuredClone.cpp',
'testSymbol.cpp',
'testToIntWidth.cpp',
'testTrap.cpp',
'testTypedArrays.cpp',
'testUncaughtError.cpp',
'testUTF8.cpp',

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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"

View File

@ -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!");

View File

@ -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');
}

View File

@ -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');
}

View File

@ -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');
}

View File

@ -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');
}

View File

@ -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');
}

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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');

View File

@ -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;

View File

@ -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);
};

View File

@ -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)

View File

@ -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();
}