Bug 1031881: Remove unused elements of JSDebugHooks, and their supporting code. r=sfink

This commit is contained in:
Jim Blandy 2014-07-19 18:07:05 -07:00
parent fd4ef3048a
commit 946ed74728
24 changed files with 15 additions and 756 deletions

View File

@ -63,41 +63,14 @@ typedef JSTrapStatus
(* JSTrapHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
JS::Value closure);
typedef JSTrapStatus
(* JSInterruptHook)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
void *closure);
typedef JSTrapStatus
(* JSDebuggerHandler)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
void *closure);
typedef JSTrapStatus
(* JSThrowHook)(JSContext *cx, JSScript *script, jsbytecode *pc, JS::Value *rval,
void *closure);
typedef bool
(* JSWatchPointHandler)(JSContext *cx, JSObject *obj, jsid id, JS::Value old,
JS::Value *newp, void *closure);
/* called just after script creation */
typedef void
(* JSNewScriptHook)(JSContext *cx,
const char *filename, /* URL of script */
unsigned lineno, /* first line */
JSScript *script,
JSFunction *fun,
void *callerdata);
/* called just before script destruction */
typedef void
(* JSDestroyScriptHook)(JSFreeOp *fop,
JSScript *script,
void *callerdata);
typedef void
(* JSSourceHandler)(const char *filename, unsigned lineno, const jschar *str,
size_t length, void **listenerTSData, void *closure);
extern JS_PUBLIC_API(JSCompartment *)
@ -167,12 +140,6 @@ JS_ClearScriptTraps(JSRuntime *rt, JSScript *script);
extern JS_PUBLIC_API(void)
JS_ClearAllTrapsForCompartment(JSContext *cx);
extern JS_PUBLIC_API(bool)
JS_SetInterrupt(JSRuntime *rt, JSInterruptHook handler, void *closure);
extern JS_PUBLIC_API(bool)
JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *handlerp, void **closurep);
/************************************************************************/
extern JS_PUBLIC_API(bool)
@ -264,22 +231,6 @@ JS_GetScriptIsSelfHosted(JSScript *script);
/************************************************************************/
/*
* Hook setters for script creation and destruction. These macros provide
* binary compatibility and newer, shorter synonyms.
*/
#define JS_SetNewScriptHook JS_SetNewScriptHookProc
#define JS_SetDestroyScriptHook JS_SetDestroyScriptHookProc
extern JS_PUBLIC_API(void)
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata);
extern JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
void *callerdata);
/************************************************************************/
typedef struct JSPropertyDesc {
JS::Value id; /* primary id, atomized string, or int */
JS::Value value; /* property value */
@ -387,58 +338,13 @@ class JS_PUBLIC_API(JSBrokenFrameIterator)
bool isConstructing() const;
};
/*
* This hook captures high level script execution and function calls (JS or
* native). It is used by JS_SetExecuteHook to hook top level scripts and by
* JS_SetCallHook to hook function calls. It will get called twice per script
* or function call: just before execution begins and just after it finishes.
* In both cases the 'current' frame is that of the executing code.
*
* The 'before' param is true for the hook invocation before the execution
* and false for the invocation after the code has run.
*
* The 'ok' param is significant only on the post execution invocation to
* signify whether or not the code completed 'normally'.
*
* The 'closure' param is as passed to JS_SetExecuteHook or JS_SetCallHook
* for the 'before'invocation, but is whatever value is returned from that
* invocation for the 'after' invocation. Thus, the hook implementor *could*
* allocate a structure in the 'before' invocation and return a pointer to that
* structure. The pointer would then be handed to the hook for the 'after'
* invocation. Alternately, the 'before' could just return the same value as
* in 'closure' to cause the 'after' invocation to be called with the same
* 'closure' value as the 'before'.
*
* Returning nullptr in the 'before' hook will cause the 'after' hook *not* to
* be called.
*/
typedef void *
(* JSInterpreterHook)(JSContext *cx, JSAbstractFramePtr frame, bool isConstructing,
bool before, bool *ok, void *closure);
typedef bool
(* JSDebugErrorHook)(JSContext *cx, const char *message, JSErrorReport *report,
void *closure);
typedef struct JSDebugHooks {
JSInterruptHook interruptHook;
void *interruptHookData;
JSNewScriptHook newScriptHook;
void *newScriptHookData;
JSDestroyScriptHook destroyScriptHook;
void *destroyScriptHookData;
JSDebuggerHandler debuggerHandler;
void *debuggerHandlerData;
JSSourceHandler sourceHandler;
void *sourceHandlerData;
JSInterpreterHook executeHook;
void *executeHookData;
JSInterpreterHook callHook;
void *callHookData;
JSThrowHook throwHook;
void *throwHookData;
JSDebugErrorHook debugErrorHook;
void *debugErrorHookData;
} JSDebugHooks;
/************************************************************************/
@ -446,21 +352,6 @@ typedef struct JSDebugHooks {
extern JS_PUBLIC_API(bool)
JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler hook, void *closure);
extern JS_PUBLIC_API(bool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure);
extern JS_PUBLIC_API(bool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
extern JS_PUBLIC_API(bool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure);
extern JS_PUBLIC_API(bool)
JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure);
extern JS_PUBLIC_API(bool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure);
/************************************************************************/
extern JS_PUBLIC_API(const JSDebugHooks *)

View File

@ -100,7 +100,7 @@ class EvalScriptGuard
~EvalScriptGuard() {
if (script_) {
CallDestroyScriptHook(cx_->runtime()->defaultFreeOp(), script_);
script_->clearTraps(cx_->runtime()->defaultFreeOp());
script_->cacheForEval();
EvalCacheEntry cacheEntry = {script_, lookup_.callerScript, lookup_.pc};
lookup_.str = lookupStr_;
@ -120,7 +120,6 @@ class EvalScriptGuard
if (p_) {
script_ = p_->script;
cx_->runtime()->evalCache.remove(p_);
CallNewScriptHook(cx_, script_, NullPtr());
script_->uncacheForEval();
}
}

View File

@ -147,9 +147,7 @@ CanLazilyParse(ExclusiveContext *cx, const ReadOnlyCompileOptions &options)
return options.canLazilyParse &&
options.compileAndGo &&
!cx->compartment()->options().discardSource() &&
!options.sourceIsLazy &&
!(cx->compartment()->debugMode() &&
cx->compartment()->runtimeFromAnyThread()->debugHooks.newScriptHook);
!options.sourceIsLazy;
}
static void
@ -176,20 +174,6 @@ MarkFunctionsWithinEvalScript(JSScript *script)
}
}
void
frontend::MaybeCallSourceHandler(JSContext *cx, const ReadOnlyCompileOptions &options,
SourceBufferHolder &srcBuf)
{
JSSourceHandler listener = cx->runtime()->debugHooks.sourceHandler;
void *listenerData = cx->runtime()->debugHooks.sourceHandlerData;
if (listener) {
void *listenerTSData;
listener(options.filename(), options.lineno, srcBuf.get(), srcBuf.length(),
&listenerTSData, listenerData);
}
}
ScriptSourceObject *
frontend::CreateScriptSourceObject(ExclusiveContext *cx, const ReadOnlyCompileOptions &options)
{
@ -242,9 +226,6 @@ frontend::CompileScript(ExclusiveContext *cx, LifoAlloc *alloc, HandleObject sco
js::AutoTraceLog scriptLogger(logger, logId);
js::AutoTraceLog typeLogger(logger, TraceLogger::ParserCompileScript);
if (cx->isJSContext())
MaybeCallSourceHandler(cx->asJSContext(), options, srcBuf);
/*
* The scripted callerFrame can only be given for compile-and-go scripts
* and non-zero static level requires callerFrame.
@ -553,8 +534,6 @@ CompileFunctionBody(JSContext *cx, MutableHandleFunction fun, const ReadOnlyComp
// FIXME: make Function pass in two strings and parse them as arguments and
// ProgramElements respectively.
MaybeCallSourceHandler(cx, options, srcBuf);
if (!CheckLength(cx, srcBuf))
return false;

View File

@ -42,14 +42,6 @@ CompileStarGeneratorBody(JSContext *cx, MutableHandleFunction fun,
ScriptSourceObject *
CreateScriptSourceObject(ExclusiveContext *cx, const ReadOnlyCompileOptions &options);
/*
* This should be called while still on the main thread if compilation will
* occur on a worker thread.
*/
void
MaybeCallSourceHandler(JSContext *cx, const ReadOnlyCompileOptions &options,
JS::SourceBufferHolder &srcBuf);
/*
* True if str consists of an IdentifierStart character, followed by one or
* more IdentifierPart characters, i.e. it matches the IdentifierName production

View File

@ -2003,8 +2003,6 @@ BytecodeEmitter::tellDebuggerAboutCompiledScript(ExclusiveContext *cx)
if (!cx->isJSContext())
return;
RootedFunction function(cx, script->functionNonDelazifying());
CallNewScriptHook(cx->asJSContext(), script, function);
// Lazy scripts are never top level (despite always being invoked with a
// nullptr parent), and so the hook should never be fired.
if (emitterMode != LazyFunction && !parent) {

View File

@ -1,19 +0,0 @@
// |jit-test| debug
var result1 = "unset";
var result2 = "failure";
function main() {
result1 = "failure";
try {
throw "something";
} catch(e) {
result2 = "success";
}
}
function nop() { }
setDebug(true);
setThrowHook("result1 = 'success'; nop()");
main();
assertEq(result1, "success");
assertEq(result2, "success");

View File

@ -1,14 +0,0 @@
// |jit-test| debug
function main() {
try {
throw "something";
} catch(e) {
return "failure";
}
return "unset";
}
setDebug(true);
setThrowHook("'success'");
assertEq(main(), "success");

View File

@ -170,11 +170,6 @@ BaselineFrame::initForOsr(InterpreterFrame *fp, uint32_t numStackValues)
argsObj_ = &fp->argsObj();
}
if (fp->hasHookData()) {
flags_ |= BaselineFrame::HAS_HOOK_DATA;
hookData_ = fp->hookData();
}
if (fp->hasReturnValue())
setReturnValue(fp->returnValue());

View File

@ -52,9 +52,6 @@ class BaselineFrame
// Eval frame, see the "eval frames" comment.
EVAL = 1 << 6,
// Frame has hookData_ set.
HAS_HOOK_DATA = 1 << 7,
// Frame has profiler entry pushed.
HAS_PUSHED_SPS_FRAME = 1 << 8,
@ -92,7 +89,7 @@ class BaselineFrame
JSObject *scopeChain_; // Scope chain (always initialized).
JSScript *evalScript_; // If isEvalFrame(), the current eval script.
ArgumentsObject *argsObj_; // If HAS_ARGS_OBJ, the arguments object.
void *hookData_; // If HAS_HOOK_DATA, debugger call hook data.
void *unused; // See static assertion re: sizeof, below.
uint32_t unwoundScopeOverrideOffset_; // If HAS_UNWOUND_SCOPE_OVERRIDE_PC.
uint32_t flags_;
@ -284,19 +281,6 @@ class BaselineFrame
return evalScript_;
}
bool hasHookData() const {
return flags_ & HAS_HOOK_DATA;
}
void *maybeHookData() const {
return hasHookData() ? hookData_ : nullptr;
}
void setHookData(void *v) {
hookData_ = v;
flags_ |= HAS_HOOK_DATA;
}
bool hasPushedSPSFrame() const {
return flags_ & HAS_PUSHED_SPS_FRAME;
}

View File

@ -82,12 +82,6 @@ CheckFrame(InterpreterFrame *fp)
return true;
}
static bool
IsJSDEnabled(JSContext *cx)
{
return cx->compartment()->debugMode() && cx->runtime()->debugHooks.callHook;
}
static IonExecStatus
EnterBaseline(JSContext *cx, EnterJitData &data)
{
@ -117,8 +111,6 @@ EnterBaseline(JSContext *cx, EnterJitData &data)
if (data.osrFrame)
data.osrFrame->setRunningInJit();
JS_ASSERT_IF(data.osrFrame, !IsJSDEnabled(cx));
// Single transition point from Interpreter to Baseline.
CALL_GENERATED_CODE(enter, data.jitcode, data.maxArgc, data.maxArgv, data.osrFrame, data.calleeToken,
data.scopeChain.get(), data.osrNumStackValues, data.result.address());
@ -266,16 +258,14 @@ CanEnterBaselineJIT(JSContext *cx, HandleScript script, bool osr)
if (script->hasBaselineScript())
return Method_Compiled;
// Check script use count. However, always eagerly compile scripts if JSD
// is enabled, so that we don't have to OSR and don't have to update the
// frame pointer stored in JSD's frames list.
// Check script use count.
//
// Also eagerly compile if we are in parallel warmup, the point of which
// is to gather type information so that the script may be compiled for
// parallel execution. We want to avoid the situation of OSRing during
// warmup and only gathering type information for the loop, and not the
// rest of the function.
if (IsJSDEnabled(cx) || cx->runtime()->forkJoinWarmup > 0) {
if (cx->runtime()->forkJoinWarmup > 0) {
if (osr)
return Method_Skipped;
} else if (script->incUseCount() <= js_JitOptions.baselineUsesBeforeCompile) {

View File

@ -888,14 +888,9 @@ HandleDebugTrap(JSContext *cx, BaselineFrame *frame, uint8_t *retAddr, bool *mus
RootedValue rval(cx);
JSTrapStatus status = JSTRAP_CONTINUE;
JSInterruptHook hook = cx->runtime()->debugHooks.interruptHook;
if (hook || script->stepModeEnabled()) {
if (hook)
status = hook(cx, script, pc, rval.address(), cx->runtime()->debugHooks.interruptHookData);
if (status == JSTRAP_CONTINUE && script->stepModeEnabled())
status = Debugger::onSingleStep(cx, &rval);
}
if (script->stepModeEnabled())
status = Debugger::onSingleStep(cx, &rval);
if (status == JSTRAP_CONTINUE && script->hasBreakpointsAt(pc))
status = Debugger::onTrap(cx, &rval);

View File

@ -12,142 +12,6 @@
using namespace js;
static int callCounts[2] = {0, 0};
static void *
callCountHook(JSContext *cx, JSAbstractFramePtr frame, bool isConstructing, bool before,
bool *ok, void *closure)
{
callCounts[before]++;
JS::RootedValue thisv(cx);
frame.getThisValue(cx, &thisv); // assert if fp is incomplete
return cx; // any non-null value causes the hook to be called again after
}
BEGIN_TEST(testDebugger_bug519719)
{
CHECK(JS_SetDebugMode(cx, true));
JS_SetCallHook(rt, callCountHook, nullptr);
EXEC("function call(fn) { fn(0); }\n"
"function f(g) { for (var i = 0; i < 9; i++) call(g); }\n"
"f(Math.sin);\n" // record loop, starting in f
"f(Math.cos);\n"); // side exit in f -> call
CHECK_EQUAL(callCounts[0], 20);
CHECK_EQUAL(callCounts[1], 20);
return true;
}
END_TEST(testDebugger_bug519719)
static void *
nonStrictThisHook(JSContext *cx, JSAbstractFramePtr frame, bool isConstructing, bool before,
bool *ok, void *closure)
{
if (before) {
bool *allWrapped = (bool *) closure;
JS::RootedValue thisv(cx);
frame.getThisValue(cx, &thisv);
*allWrapped = *allWrapped && !thisv.isPrimitive();
}
return nullptr;
}
BEGIN_TEST(testDebugger_getThisNonStrict)
{
bool allWrapped = true;
CHECK(JS_SetDebugMode(cx, true));
JS_SetCallHook(rt, nonStrictThisHook, (void *) &allWrapped);
EXEC("function nonstrict() { }\n"
"Boolean.prototype.nonstrict = nonstrict;\n"
"String.prototype.nonstrict = nonstrict;\n"
"Number.prototype.nonstrict = nonstrict;\n"
"Object.prototype.nonstrict = nonstrict;\n"
"nonstrict.call(true);\n"
"true.nonstrict();\n"
"nonstrict.call('');\n"
"''.nonstrict();\n"
"nonstrict.call(42);\n"
"(42).nonstrict();\n"
// The below don't really get 'wrapped', but it's okay.
"nonstrict.call(undefined);\n"
"nonstrict.call(null);\n"
"nonstrict.call({});\n"
"({}).nonstrict();\n");
CHECK(allWrapped);
return true;
}
END_TEST(testDebugger_getThisNonStrict)
static void *
strictThisHook(JSContext *cx, JSAbstractFramePtr frame, bool isConstructing, bool before,
bool *ok, void *closure)
{
if (before) {
bool *anyWrapped = (bool *) closure;
JS::RootedValue thisv(cx);
frame.getThisValue(cx, &thisv);
*anyWrapped = *anyWrapped || !thisv.isPrimitive();
}
return nullptr;
}
BEGIN_TEST(testDebugger_getThisStrict)
{
bool anyWrapped = false;
CHECK(JS_SetDebugMode(cx, true));
JS_SetCallHook(rt, strictThisHook, (void *) &anyWrapped);
EXEC("function strict() { 'use strict'; }\n"
"Boolean.prototype.strict = strict;\n"
"String.prototype.strict = strict;\n"
"Number.prototype.strict = strict;\n"
"strict.call(true);\n"
"true.strict();\n"
"strict.call('');\n"
"''.strict();\n"
"strict.call(42);\n"
"(42).strict();\n"
"strict.call(undefined);\n"
"strict.call(null);\n");
CHECK(!anyWrapped);
return true;
}
END_TEST(testDebugger_getThisStrict)
static bool calledThrowHook = false;
static JSTrapStatus
ThrowHook(JSContext *cx, JSScript *, jsbytecode *, jsval *rval, void *closure)
{
JS_ASSERT(!closure);
calledThrowHook = true;
JS::RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
char text[] = "new Error()";
JS::RootedValue _(cx);
JS_EvaluateScript(cx, global, text, strlen(text), "", 0, &_);
return JSTRAP_CONTINUE;
}
BEGIN_TEST(testDebugger_throwHook)
{
CHECK(JS_SetDebugMode(cx, true));
CHECK(JS_SetThrowHook(rt, ThrowHook, nullptr));
EXEC("function foo() { throw 3 };\n"
"for (var i = 0; i < 10; ++i) { \n"
" var x = {}\n"
" try {\n"
" foo(); \n"
" } catch(e) {}\n"
"}\n");
CHECK(calledThrowHook);
CHECK(JS_SetThrowHook(rt, nullptr, nullptr));
return true;
}
END_TEST(testDebugger_throwHook)
BEGIN_TEST(testDebugger_debuggerObjectVsDebugMode)
{
CHECK(JS_DefineDebuggerObject(cx, global));
@ -237,38 +101,3 @@ bool testIndirectEval(JS::HandleObject scope, const char *code)
return true;
}
END_TEST(testDebugger_newScriptHook)
BEGIN_TEST(testDebugger_singleStepThrow)
{
CHECK(JS_SetDebugModeForCompartment(cx, cx->compartment(), true));
CHECK(JS_SetInterrupt(rt, onStep, nullptr));
CHECK(JS_DefineFunction(cx, global, "setStepMode", setStepMode, 0, 0));
EXEC("var e;\n"
"setStepMode();\n"
"function f() { throw 0; }\n"
"try { f(); }\n"
"catch (x) { e = x; }\n");
return true;
}
static bool
setStepMode(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
NonBuiltinScriptFrameIter iter(cx);
JS::RootedScript script(cx, iter.script());
if (!JS_SetSingleStepMode(cx, script, true))
return false;
args.rval().set(UndefinedValue());
return true;
}
static JSTrapStatus
onStep(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, void *closure)
{
return JSTRAP_CONTINUE;
}
END_TEST(testDebugger_singleStepThrow)

View File

@ -25,26 +25,3 @@ BEGIN_TEST(testBug795104)
return true;
}
END_TEST(testBug795104)
static const char *const simpleSource = "var x = 4;";
BEGIN_TEST(testScriptSourceReentrant)
{
JS::CompileOptions opts(cx);
bool match = false;
JS_SetNewScriptHook(rt, NewScriptHook, &match);
CHECK(JS::Evaluate(cx, global, opts, simpleSource, strlen(simpleSource)));
CHECK(match);
JS_SetNewScriptHook(rt, nullptr, nullptr);
return true;
}
static void
NewScriptHook(JSContext *cx, const char *fn, unsigned lineno,
JSScript *script, JSFunction *fun, void *data)
{
if (!JS_StringEqualsAscii(cx, script->sourceData(cx), simpleSource, (bool *)data))
*((bool *)data) = false;
}
END_TEST(testScriptSourceReentrant)

View File

@ -303,27 +303,10 @@ ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
/*
* Call the error reporter only if an exception wasn't raised.
*
* If an exception was raised, then we call the debugErrorHook
* (if present) to give it a chance to see the error before it
* propagates out of scope. This is needed for compatibility
* with the old scheme.
*/
if (!JS_IsRunning(cx) || !js_ErrorToException(cx, message, reportp, callback, userRef)) {
if (message)
CallErrorReporter(cx, message, reportp);
} else if (JSDebugErrorHook hook = cx->runtime()->debugHooks.debugErrorHook) {
/*
* If we've already chewed up all the C stack, don't call into the
* error reporter since this may trigger an infinite recursion where
* the reporter triggers an over-recursion.
*/
int stackDummy;
if (!JS_CHECK_STACK_SIZE(GetNativeStackLimit(cx), &stackDummy))
return;
if (cx->errorReporter)
hook(cx, message, reportp, cx->runtime()->debugHooks.debugErrorHookData);
}
}
@ -902,14 +885,6 @@ js::CallErrorReporter(JSContext *cx, const char *message, JSErrorReport *reportp
JS_ASSERT(message);
JS_ASSERT(reportp);
// If debugErrorHook is present, give it a chance to veto sending the error
// on to the regular ErrorReporter.
if (cx->errorReporter) {
JSDebugErrorHook hook = cx->runtime()->debugHooks.debugErrorHook;
if (hook && !hook(cx, message, reportp, cx->runtime()->debugHooks.debugErrorHookData))
return;
}
if (JSErrorReporter onError = cx->errorReporter)
onError(cx, message, reportp);
}

View File

@ -515,7 +515,6 @@ js::CloneFunctionAndScript(JSContext *cx, HandleObject enclosingScope, HandleFun
return nullptr;
RootedScript cloneScript(cx, clone->nonLazyScript());
CallNewScriptHook(cx, cloneScript, clone);
return clone;
}
@ -701,20 +700,6 @@ CreateFunctionPrototype(JSContext *cx, JSProtoKey key)
return functionProto;
}
static bool
FinishFunctionClassInit(JSContext *cx, JS::HandleObject ctor, JS::HandleObject proto)
{
/*
* Notify any debuggers about the creation of the script for
* |Function.prototype| -- after all initialization, for simplicity.
*/
RootedFunction functionProto(cx, &proto->as<JSFunction>());
RootedScript functionProtoScript(cx, functionProto->nonLazyScript());
CallNewScriptHook(cx, functionProtoScript, functionProto);
return true;
}
const Class JSFunction::class_ = {
js_Function_str,
JSCLASS_NEW_RESOLVE | JSCLASS_IMPLEMENTS_BARRIERS |
@ -735,9 +720,7 @@ const Class JSFunction::class_ = {
CreateFunctionConstructor,
CreateFunctionPrototype,
nullptr,
function_methods,
nullptr,
FinishFunctionClassInit
function_methods
}
};
@ -1269,8 +1252,6 @@ JSFunction::createScriptForLazilyInterpretedFunction(JSContext *cx, HandleFuncti
fun->setUnlazifiedScript(clonedScript);
CallNewScriptHook(cx, clonedScript, fun);
if (!lazy->maybeScript())
lazy->initScript(clonedScript);
return true;

View File

@ -1017,7 +1017,6 @@ js::XDRScript(XDRState<mode> *xdr, HandleObject enclosingScope, HandleScript enc
scriptp.set(script);
/* see BytecodeEmitter::tellDebuggerAboutCompiledScript */
CallNewScriptHook(cx, script, fun);
if (!fun) {
RootedGlobalObject global(cx, script->compileAndGo() ? &script->global() : nullptr);
Debugger::onNewScript(cx, script, global);
@ -2621,32 +2620,6 @@ JSScript::uninlinedGlobal() const
return global();
}
void
js::CallNewScriptHook(JSContext *cx, HandleScript script, HandleFunction fun)
{
if (script->selfHosted())
return;
JS_ASSERT(!script->isActiveEval());
if (JSNewScriptHook hook = cx->runtime()->debugHooks.newScriptHook) {
AutoKeepAtoms keepAtoms(cx->perThreadData);
hook(cx, script->filename(), script->lineno(), script, fun,
cx->runtime()->debugHooks.newScriptHookData);
}
}
void
js::CallDestroyScriptHook(FreeOp *fop, JSScript *script)
{
if (script->selfHosted())
return;
// The hook will only call into JS if a GC is not running.
if (JSDestroyScriptHook hook = fop->runtime()->debugHooks.destroyScriptHook)
hook(fop, script, fop->runtime()->debugHooks.destroyScriptHookData);
script->clearTraps(fop);
}
void
JSScript::finalize(FreeOp *fop)
{
@ -2655,7 +2628,7 @@ JSScript::finalize(FreeOp *fop)
// JSScript::Create(), but not yet finished initializing it with
// fullyInitFromEmitter() or fullyInitTrivial().
CallDestroyScriptHook(fop, this);
clearTraps(fop);
fop->runtime()->spsProfiler.onScriptFinalized(this);
if (types)
@ -3137,7 +3110,6 @@ js::CloneFunctionScript(JSContext *cx, HandleFunction original, HandleFunction c
cscript->setFunction(clone);
script = clone->nonLazyScript();
CallNewScriptHook(cx, script, clone);
RootedGlobalObject global(cx, script->compileAndGo() ? &script->global() : nullptr);
Debugger::onNewScript(cx, script, global);

View File

@ -1913,19 +1913,6 @@ class LazyScript : public gc::BarrieredCell<LazyScript>
/* If this fails, add/remove padding within LazyScript. */
JS_STATIC_ASSERT(sizeof(LazyScript) % js::gc::CellSize == 0);
/*
* New-script-hook calling is factored from JSScript::fullyInitFromEmitter() so
* that it and callers of XDRScript() can share this code. In the case of
* callers of XDRScript(), the hook should be invoked only after successful
* decode of any owning function (the fun parameter) or script object (null
* fun).
*/
extern void
CallNewScriptHook(JSContext *cx, JS::HandleScript script, JS::HandleFunction fun);
extern void
CallDestroyScriptHook(FreeOp *fop, JSScript *script);
struct SharedScriptData
{
uint32_t length;

View File

@ -1886,26 +1886,6 @@ SetDebuggerHandler(JSContext *cx, unsigned argc, jsval *vp)
return true;
}
static bool
SetThrowHook(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
JSString *str;
if (args.length() == 0) {
JS_ReportErrorNumber(cx, my_GetErrorMessage, nullptr,
JSSMSG_NOT_ENOUGH_ARGS, "setThrowHook");
return false;
}
str = JS::ToString(cx, args[0]);
if (!str)
return false;
JS_SetThrowHook(cx->runtime(), DebuggerAndThrowHandler, str);
args.rval().setUndefined();
return true;
}
static bool
LineToPC(JSContext *cx, unsigned argc, jsval *vp)
{
@ -4885,10 +4865,6 @@ static const JSFunctionSpecWithHelp fuzzing_unsafe_functions[] = {
" Redirect stdout and/or stderr to the named file. Pass undefined to avoid\n"
" redirecting. Filenames are relative to the current working directory."),
JS_FN_HELP("setThrowHook", SetThrowHook, 1, 0,
"setThrowHook(f)",
" Set throw hook to f."),
JS_FN_HELP("system", System, 1, 0,
"system(command)",
" Execute command on the current host, returning result code."),

View File

@ -298,9 +298,6 @@ js::StartOffThreadParseScript(JSContext *cx, const ReadOnlyCompileOptions &optio
// which could require barriers on the atoms compartment.
gc::AutoSuppressGC suppress(cx);
SourceBufferHolder srcBuf(chars, length, SourceBufferHolder::NoOwnership);
frontend::MaybeCallSourceHandler(cx, options, srcBuf);
EnsureHelperThreadsInitialized(cx);
JS::CompartmentOptions compartmentOptions(cx->compartment()->options());
@ -701,33 +698,6 @@ GlobalHelperThreadState::canStartGCHelperTask()
return !gcHelperWorklist().empty();
}
static void
CallNewScriptHookForAllScripts(JSContext *cx, HandleScript script)
{
// We should never hit this, since nested scripts are also constructed via
// BytecodeEmitter instances on the stack.
JS_CHECK_RECURSION(cx, return);
// Recurse to any nested scripts.
if (script->hasObjects()) {
ObjectArray *objects = script->objects();
for (size_t i = 0; i < objects->length; i++) {
JSObject *obj = objects->vector[i];
if (obj->is<JSFunction>()) {
JSFunction *fun = &obj->as<JSFunction>();
if (fun->hasScript()) {
RootedScript nested(cx, fun->nonLazyScript());
CallNewScriptHookForAllScripts(cx, nested);
}
}
}
}
// The global new script hook is called on every script that was compiled.
RootedFunction function(cx, script->functionNonDelazifying());
CallNewScriptHook(cx, script, function);
}
JSScript *
GlobalHelperThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void *token)
{
@ -818,9 +788,6 @@ GlobalHelperThreadState::finishParseTask(JSContext *maybecx, JSRuntime *rt, void
compileAndGoGlobal = &script->global();
Debugger::onNewScript(cx, script, compileAndGoGlobal);
// The NewScript hook needs to be called for all compiled scripts.
CallNewScriptHookForAllScripts(cx, script);
// Update the compressed source table with the result. This is normally
// called by setCompressedSource when compilation occurs on the main thread.
if (script->scriptSource()->hasCompressedSource())

View File

@ -1505,7 +1505,7 @@ Interpret(JSContext *cx, RunState &state)
}
}
if (cx->runtime()->profilingScripts || cx->runtime()->debugHooks.interruptHook)
if (cx->runtime()->profilingScripts)
activation.enableInterruptsUnconditionally();
// Enter the interpreter loop starting at the current pc.
@ -1531,15 +1531,10 @@ CASE(EnableInterruptsPseudoOpcode)
}
if (cx->compartment()->debugMode()) {
JSInterruptHook hook = cx->runtime()->debugHooks.interruptHook;
if (hook || script->stepModeEnabled()) {
if (script->stepModeEnabled()) {
RootedValue rval(cx);
JSTrapStatus status = JSTRAP_CONTINUE;
if (hook)
status = hook(cx, script, REGS.pc, rval.address(),
cx->runtime()->debugHooks.interruptHookData);
if (status == JSTRAP_CONTINUE && script->stepModeEnabled())
status = Debugger::onSingleStep(cx, &rval);
status = Debugger::onSingleStep(cx, &rval);
switch (status) {
case JSTRAP_ERROR:
goto error;

View File

@ -59,32 +59,11 @@ JS_SetRuntimeDebugMode(JSRuntime *rt, bool debug)
rt->debugMode = !!debug;
}
static bool
IsTopFrameConstructing(JSContext *cx, AbstractFramePtr frame)
{
ScriptFrameIter iter(cx);
JS_ASSERT(iter.abstractFramePtr() == frame);
return iter.isConstructing();
}
JSTrapStatus
js::ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
{
JS_ASSERT_IF(frame.isInterpreterFrame(), frame.asInterpreterFrame() == cx->interpreterFrame());
if (!frame.script()->selfHosted()) {
JSAbstractFramePtr jsframe(frame.raw(), pc);
if (frame.isFramePushedByExecute()) {
if (JSInterpreterHook hook = cx->runtime()->debugHooks.executeHook)
frame.setHookData(hook(cx, jsframe, IsTopFrameConstructing(cx, frame),
true, 0, cx->runtime()->debugHooks.executeHookData));
} else {
if (JSInterpreterHook hook = cx->runtime()->debugHooks.callHook)
frame.setHookData(hook(cx, jsframe, IsTopFrameConstructing(cx, frame),
true, 0, cx->runtime()->debugHooks.callHookData));
}
}
RootedValue rval(cx);
JSTrapStatus status = Debugger::onEnterFrame(cx, frame, &rval);
switch (status) {
@ -112,18 +91,6 @@ js::ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc, b
bool ok = okArg;
// We don't add hook data for self-hosted scripts, so we don't need to check for them, here.
if (void *hookData = frame.maybeHookData()) {
JSAbstractFramePtr jsframe(frame.raw(), pc);
if (frame.isFramePushedByExecute()) {
if (JSInterpreterHook hook = cx->runtime()->debugHooks.executeHook)
hook(cx, jsframe, IsTopFrameConstructing(cx, frame), false, &ok, hookData);
} else {
if (JSInterpreterHook hook = cx->runtime()->debugHooks.callHook)
hook(cx, jsframe, IsTopFrameConstructing(cx, frame), false, &ok, hookData);
}
}
return Debugger::onLeaveFrame(cx, frame, ok);
}
@ -132,18 +99,12 @@ js::DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
{
JS_ASSERT(cx->compartment()->debugMode());
if (!cx->runtime()->debugHooks.throwHook && cx->compartment()->getDebuggees().empty())
if (cx->compartment()->getDebuggees().empty())
return JSTRAP_CONTINUE;
/* Call debugger throw hook if set. */
RootedValue rval(cx);
JSTrapStatus status = Debugger::onExceptionUnwind(cx, &rval);
if (status == JSTRAP_CONTINUE) {
if (JSThrowHook handler = cx->runtime()->debugHooks.throwHook) {
RootedScript script(cx, frame.script());
status = handler(cx, script, pc, rval.address(), cx->runtime()->debugHooks.throwHookData);
}
}
switch (status) {
case JSTRAP_ERROR:
@ -263,32 +224,6 @@ JS_ClearAllTrapsForCompartment(JSContext *cx)
cx->compartment()->clearTraps(cx->runtime()->defaultFreeOp());
}
JS_PUBLIC_API(bool)
JS_SetInterrupt(JSRuntime *rt, JSInterruptHook hook, void *closure)
{
rt->debugHooks.interruptHook = hook;
rt->debugHooks.interruptHookData = closure;
for (ActivationIterator iter(rt); !iter.done(); ++iter) {
if (iter->isInterpreter())
iter->asInterpreter()->enableInterruptsUnconditionally();
}
return true;
}
JS_PUBLIC_API(bool)
JS_ClearInterrupt(JSRuntime *rt, JSInterruptHook *hoop, void **closurep)
{
if (hoop)
*hoop = rt->debugHooks.interruptHook;
if (closurep)
*closurep = rt->debugHooks.interruptHookData;
rt->debugHooks.interruptHook = 0;
rt->debugHooks.interruptHookData = 0;
return true;
}
/************************************************************************/
JS_PUBLIC_API(bool)
@ -564,23 +499,6 @@ JS_GetScriptIsSelfHosted(JSScript *script)
/***************************************************************************/
JS_PUBLIC_API(void)
JS_SetNewScriptHook(JSRuntime *rt, JSNewScriptHook hook, void *callerdata)
{
rt->debugHooks.newScriptHook = hook;
rt->debugHooks.newScriptHookData = callerdata;
}
JS_PUBLIC_API(void)
JS_SetDestroyScriptHook(JSRuntime *rt, JSDestroyScriptHook hook,
void *callerdata)
{
rt->debugHooks.destroyScriptHook = hook;
rt->debugHooks.destroyScriptHookData = callerdata;
}
/***************************************************************************/
/* This all should be reworked to avoid requiring JSScopeProperty types. */
static bool
@ -742,46 +660,6 @@ JS_SetDebuggerHandler(JSRuntime *rt, JSDebuggerHandler handler, void *closure)
return true;
}
JS_PUBLIC_API(bool)
JS_SetSourceHandler(JSRuntime *rt, JSSourceHandler handler, void *closure)
{
rt->debugHooks.sourceHandler = handler;
rt->debugHooks.sourceHandlerData = closure;
return true;
}
JS_PUBLIC_API(bool)
JS_SetExecuteHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->debugHooks.executeHook = hook;
rt->debugHooks.executeHookData = closure;
return true;
}
JS_PUBLIC_API(bool)
JS_SetCallHook(JSRuntime *rt, JSInterpreterHook hook, void *closure)
{
rt->debugHooks.callHook = hook;
rt->debugHooks.callHookData = closure;
return true;
}
JS_PUBLIC_API(bool)
JS_SetThrowHook(JSRuntime *rt, JSThrowHook hook, void *closure)
{
rt->debugHooks.throwHook = hook;
rt->debugHooks.throwHookData = closure;
return true;
}
JS_PUBLIC_API(bool)
JS_SetDebugErrorHook(JSRuntime *rt, JSDebugErrorHook hook, void *closure)
{
rt->debugHooks.debugErrorHook = hook;
rt->debugHooks.debugErrorHookData = closure;
return true;
}
/************************************************************************/
JS_PUBLIC_API(const JSDebugHooks *)

View File

@ -87,7 +87,6 @@ InterpreterFrame::initCallFrame(JSContext *cx, InterpreterFrame *prev, jsbytecod
prev_ = prev;
prevpc_ = prevpc;
prevsp_ = prevsp;
JS_ASSERT(!hasHookData());
initVarsToUndefined();
}
@ -353,32 +352,6 @@ FrameIter::unaliasedForEachActual(JSContext *cx, Op op)
MOZ_CRASH("Unexpected state");
}
inline void *
AbstractFramePtr::maybeHookData() const
{
if (isInterpreterFrame())
return asInterpreterFrame()->maybeHookData();
#ifdef JS_ION
return asBaselineFrame()->maybeHookData();
#else
MOZ_CRASH("Invalid frame");
#endif
}
inline void
AbstractFramePtr::setHookData(void *data) const
{
if (isInterpreterFrame()) {
asInterpreterFrame()->setHookData(data);
return;
}
#ifdef JS_ION
asBaselineFrame()->setHookData(data);
#else
MOZ_CRASH("Invalid frame");
#endif
}
inline HandleValue
AbstractFramePtr::returnValue() const
{
@ -629,13 +602,6 @@ AbstractFramePtr::isEvalFrame() const
MOZ_CRASH("Invalid frame");
#endif
}
inline bool
AbstractFramePtr::isFramePushedByExecute() const
{
return isGlobalFrame() || isEvalFrame();
}
inline bool
AbstractFramePtr::isDebuggerFrame() const
{

View File

@ -90,7 +90,6 @@ InterpreterFrame::initExecuteFrame(JSContext *cx, JSScript *script, AbstractFram
#ifdef DEBUG
Debug_SetValueRangeToCrashOnTouch(&rval_, 1);
hookData_ = (void *)0xbad;
#endif
}

View File

@ -197,7 +197,6 @@ class AbstractFramePtr
inline bool isFunctionFrame() const;
inline bool isGlobalFrame() const;
inline bool isEvalFrame() const;
inline bool isFramePushedByExecute() const;
inline bool isDebuggerFrame() const;
inline JSScript *script() const;
@ -235,8 +234,6 @@ class AbstractFramePtr
JSObject *evalPrevScopeChain(JSContext *cx) const;
inline void *maybeHookData() const;
inline void setHookData(void *data) const;
inline HandleValue returnValue() const;
inline void setReturnValue(const Value &rval) const;
@ -318,7 +315,6 @@ class InterpreterFrame
HAS_ARGS_OBJ = 0x200, /* ArgumentsObject created for needsArgsObj script */
/* Lazy frame initialization */
HAS_HOOK_DATA = 0x400, /* frame has hookData_ set */
HAS_RVAL = 0x800, /* frame has rval_ set */
HAS_SCOPECHAIN = 0x1000, /* frame has scopeChain_ set */
@ -361,7 +357,7 @@ class InterpreterFrame
jsbytecode *prevpc_;
Value *prevsp_;
void *hookData_; /* if HAS_HOOK_DATA, closure returned by call hook */
void *unused;
/*
* For an eval-in-frame DEBUGGER frame, the frame in whose scope we're
@ -742,25 +738,7 @@ class InterpreterFrame
inline JSCompartment *compartment() const;
/* Debugger hook data */
bool hasHookData() const {
return !!(flags_ & HAS_HOOK_DATA);
}
void* hookData() const {
JS_ASSERT(hasHookData());
return hookData_;
}
void* maybeHookData() const {
return hasHookData() ? hookData_ : nullptr;
}
void setHookData(void *v) {
hookData_ = v;
flags_ |= HAS_HOOK_DATA;
}
/* Profiler flags */
bool hasPushedSPSFrame() {
return !!(flags_ & HAS_PUSHED_SPS_FRAME);
@ -847,17 +825,6 @@ class InterpreterFrame
void copyFrameAndValues(JSContext *cx, Value *vp, InterpreterFrame *otherfp,
const Value *othervp, Value *othersp);
/*
* js::Execute pushes both global and function frames (since eval() in a
* function pushes a frame with isFunctionFrame() && isEvalFrame()). Most
* code should not care where a frame was pushed, but if it is necessary to
* pick out frames pushed by js::Execute, this is the right query:
*/
bool isFramePushedByExecute() const {
return !!(flags_ & (GLOBAL | EVAL));
}
/*
* Other flags
*/