зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1060936 - Directly call debugger hooks. r=shu
This commit is contained in:
Родитель
2c5b4e5e64
Коммит
ddb2dec55a
|
@ -511,8 +511,7 @@ HandleExceptionBaseline(JSContext *cx, const JitFrameIterator &frame, ResumeFrom
|
||||||
|
|
||||||
if (cx->isExceptionPending() && cx->compartment()->debugMode()) {
|
if (cx->isExceptionPending() && cx->compartment()->debugMode()) {
|
||||||
BaselineFrame *baselineFrame = frame.baselineFrame();
|
BaselineFrame *baselineFrame = frame.baselineFrame();
|
||||||
JSTrapStatus status = DebugExceptionUnwind(cx, baselineFrame, pc);
|
switch (Debugger::onExceptionUnwind(cx, baselineFrame)) {
|
||||||
switch (status) {
|
|
||||||
case JSTRAP_ERROR:
|
case JSTRAP_ERROR:
|
||||||
// Uncatchable exception.
|
// Uncatchable exception.
|
||||||
MOZ_ASSERT(!cx->isExceptionPending());
|
MOZ_ASSERT(!cx->isExceptionPending());
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
|
|
||||||
#include "jit/BaselineFrame-inl.h"
|
#include "jit/BaselineFrame-inl.h"
|
||||||
#include "jit/IonFrames-inl.h"
|
#include "jit/IonFrames-inl.h"
|
||||||
|
#include "vm/Debugger-inl.h"
|
||||||
#include "vm/Interpreter-inl.h"
|
#include "vm/Interpreter-inl.h"
|
||||||
#include "vm/ObjectImpl-inl.h"
|
#include "vm/ObjectImpl-inl.h"
|
||||||
#include "vm/StringObject-inl.h"
|
#include "vm/StringObject-inl.h"
|
||||||
|
@ -763,8 +764,7 @@ DebugPrologue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool *mustRet
|
||||||
{
|
{
|
||||||
*mustReturn = false;
|
*mustReturn = false;
|
||||||
|
|
||||||
JSTrapStatus status = ScriptDebugPrologue(cx, frame, pc);
|
switch (Debugger::onEnterFrame(cx, frame)) {
|
||||||
switch (status) {
|
|
||||||
case JSTRAP_CONTINUE:
|
case JSTRAP_CONTINUE:
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -780,7 +780,7 @@ DebugPrologue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool *mustRet
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("Invalid trap status");
|
MOZ_CRASH("bad Debugger::onEnterFrame status");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,10 +808,10 @@ DebugEpilogue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool ok)
|
||||||
jsbytecode *unwindPc = frame->script()->main();
|
jsbytecode *unwindPc = frame->script()->main();
|
||||||
frame->setUnwoundScopeOverridePc(unwindPc);
|
frame->setUnwoundScopeOverridePc(unwindPc);
|
||||||
|
|
||||||
// If ScriptDebugEpilogue returns |true| we have to return the frame's
|
// If Debugger::onLeaveFrame returns |true| we have to return the frame's
|
||||||
// return value. If it returns |false|, the debugger threw an exception.
|
// return value. If it returns |false|, the debugger threw an exception.
|
||||||
// In both cases we have to pop debug scopes.
|
// In both cases we have to pop debug scopes.
|
||||||
ok = ScriptDebugEpilogue(cx, frame, pc, ok);
|
ok = Debugger::onLeaveFrame(cx, frame, ok);
|
||||||
|
|
||||||
if (frame->isNonEvalFunctionFrame()) {
|
if (frame->isNonEvalFunctionFrame()) {
|
||||||
MOZ_ASSERT_IF(ok, frame->hasReturnValue());
|
MOZ_ASSERT_IF(ok, frame->hasReturnValue());
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
inline bool
|
inline bool
|
||||||
js::Debugger::onLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok)
|
js::Debugger::onLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT_IF(frame.isInterpreterFrame(), frame.asInterpreterFrame() == cx->interpreterFrame());
|
||||||
/* Traps must be cleared from eval frames, see slowPathOnLeaveFrame. */
|
/* Traps must be cleared from eval frames, see slowPathOnLeaveFrame. */
|
||||||
bool evalTraps = frame.isEvalFrame() &&
|
bool evalTraps = frame.isEvalFrame() &&
|
||||||
frame.script()->hasAnyBreakpointsOrStepMode();
|
frame.script()->hasAnyBreakpointsOrStepMode();
|
||||||
|
|
|
@ -498,9 +498,9 @@ Debugger::hasAnyLiveHooks() const
|
||||||
}
|
}
|
||||||
|
|
||||||
JSTrapStatus
|
JSTrapStatus
|
||||||
Debugger::slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHandleValue vp)
|
Debugger::slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame)
|
||||||
{
|
{
|
||||||
/* Build the list of recipients. */
|
// Build the list of recipients.
|
||||||
AutoValueVector triggered(cx);
|
AutoValueVector triggered(cx);
|
||||||
Handle<GlobalObject*> global = cx->global();
|
Handle<GlobalObject*> global = cx->global();
|
||||||
|
|
||||||
|
@ -510,22 +510,45 @@ Debugger::slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHan
|
||||||
if (dbg->observesFrame(frame) && dbg->observesEnterFrame() &&
|
if (dbg->observesFrame(frame) && dbg->observesEnterFrame() &&
|
||||||
!triggered.append(ObjectValue(*dbg->toJSObject())))
|
!triggered.append(ObjectValue(*dbg->toJSObject())))
|
||||||
{
|
{
|
||||||
|
cx->clearPendingException();
|
||||||
return JSTRAP_ERROR;
|
return JSTRAP_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Deliver the event, checking again as in dispatchHook. */
|
JSTrapStatus status = JSTRAP_CONTINUE;
|
||||||
|
RootedValue rval(cx);
|
||||||
|
// Deliver the event, checking again as in dispatchHook.
|
||||||
for (Value *p = triggered.begin(); p != triggered.end(); p++) {
|
for (Value *p = triggered.begin(); p != triggered.end(); p++) {
|
||||||
Debugger *dbg = Debugger::fromJSObject(&p->toObject());
|
Debugger *dbg = Debugger::fromJSObject(&p->toObject());
|
||||||
if (dbg->debuggees.has(global) && dbg->observesEnterFrame()) {
|
if (dbg->debuggees.has(global) && dbg->observesEnterFrame()) {
|
||||||
JSTrapStatus status = dbg->fireEnterFrame(cx, frame, vp);
|
status = dbg->fireEnterFrame(cx, frame, &rval);
|
||||||
if (status != JSTRAP_CONTINUE)
|
if (status != JSTRAP_CONTINUE)
|
||||||
return status;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return JSTRAP_CONTINUE;
|
switch (status) {
|
||||||
|
case JSTRAP_CONTINUE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSTRAP_THROW:
|
||||||
|
cx->setPendingException(rval);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSTRAP_ERROR:
|
||||||
|
cx->clearPendingException();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSTRAP_RETURN:
|
||||||
|
frame.setReturnValue(rval);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("bad Debugger::onEnterFrame JSTrapStatus value");
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -644,6 +667,36 @@ Debugger::slowPathOnLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool frame
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSTrapStatus
|
||||||
|
Debugger::slowPathOnExceptionUnwind(JSContext *cx, AbstractFramePtr frame)
|
||||||
|
{
|
||||||
|
RootedValue rval(cx);
|
||||||
|
JSTrapStatus status = dispatchHook(cx, &rval, OnExceptionUnwind);
|
||||||
|
|
||||||
|
switch (status) {
|
||||||
|
case JSTRAP_CONTINUE:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSTRAP_THROW:
|
||||||
|
cx->setPendingException(rval);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSTRAP_ERROR:
|
||||||
|
cx->clearPendingException();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JSTRAP_RETURN:
|
||||||
|
cx->clearPendingException();
|
||||||
|
frame.setReturnValue(rval);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Invalid trap status");
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Debugger::wrapEnvironment(JSContext *cx, Handle<Env*> env, MutableHandleValue rval)
|
Debugger::wrapEnvironment(JSContext *cx, Handle<Env*> env, MutableHandleValue rval)
|
||||||
{
|
{
|
||||||
|
|
|
@ -369,9 +369,9 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||||
JSObject *getHook(Hook hook) const;
|
JSObject *getHook(Hook hook) const;
|
||||||
bool hasAnyLiveHooks() const;
|
bool hasAnyLiveHooks() const;
|
||||||
|
|
||||||
static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame,
|
static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame);
|
||||||
MutableHandleValue vp);
|
|
||||||
static bool slowPathOnLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok);
|
static bool slowPathOnLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok);
|
||||||
|
static JSTrapStatus slowPathOnExceptionUnwind(JSContext *cx, AbstractFramePtr frame);
|
||||||
static void slowPathOnNewScript(JSContext *cx, HandleScript script,
|
static void slowPathOnNewScript(JSContext *cx, HandleScript script,
|
||||||
GlobalObject *compileAndGoGlobal);
|
GlobalObject *compileAndGoGlobal);
|
||||||
static void slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
static void slowPathOnNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
||||||
|
@ -453,13 +453,61 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
||||||
static void detachAllDebuggersFromGlobal(FreeOp *fop, GlobalObject *global);
|
static void detachAllDebuggersFromGlobal(FreeOp *fop, GlobalObject *global);
|
||||||
static void findCompartmentEdges(JS::Zone *v, gc::ComponentFinder<JS::Zone> &finder);
|
static void findCompartmentEdges(JS::Zone *v, gc::ComponentFinder<JS::Zone> &finder);
|
||||||
|
|
||||||
static inline JSTrapStatus onEnterFrame(JSContext *cx, AbstractFramePtr frame,
|
/*
|
||||||
MutableHandleValue vp);
|
* Announce to the debugger that the thread has entered a new JavaScript frame,
|
||||||
|
* |frame|. Call whatever hooks have been registered to observe new frames, and
|
||||||
|
* return a JSTrapStatus code indication how execution should proceed:
|
||||||
|
*
|
||||||
|
* - JSTRAP_CONTINUE: Continue execution normally.
|
||||||
|
*
|
||||||
|
* - JSTRAP_THROW: Throw an exception. onEnterFrame has set |cx|'s
|
||||||
|
* pending exception to the value to be thrown.
|
||||||
|
*
|
||||||
|
* - JSTRAP_ERROR: Terminate execution (as is done when a script is terminated
|
||||||
|
* for running too long). onEnterFrame has cleared |cx|'s pending
|
||||||
|
* exception.
|
||||||
|
*
|
||||||
|
* - JSTRAP_RETURN: Return from the new frame immediately. onEnterFrame
|
||||||
|
* has set |frame|'s return value appropriately.
|
||||||
|
*/
|
||||||
|
static inline JSTrapStatus onEnterFrame(JSContext *cx, AbstractFramePtr frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Announce to the debugger that the thread has exited a JavaScript frame, |frame|.
|
||||||
|
* If |ok| is true, the frame is returning normally; if |ok| is false, the frame
|
||||||
|
* is throwing an exception or terminating.
|
||||||
|
*
|
||||||
|
* Change cx's current exception and |frame|'s return value to reflect the changes
|
||||||
|
* in behavior the hooks request, if any. Return the new error/success value.
|
||||||
|
*
|
||||||
|
* This function may be called twice for the same outgoing frame; only the
|
||||||
|
* first call has any effect. (Permitting double calls simplifies some
|
||||||
|
* cases where an onPop handler's resumption value changes a return to a
|
||||||
|
* throw, or vice versa: we can redirect to a complete copy of the
|
||||||
|
* alternative path, containing its own call to onLeaveFrame.)
|
||||||
|
*/
|
||||||
static inline bool onLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok);
|
static inline bool onLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok);
|
||||||
|
|
||||||
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, MutableHandleValue vp);
|
static inline JSTrapStatus onDebuggerStatement(JSContext *cx, MutableHandleValue vp);
|
||||||
static inline JSTrapStatus onExceptionUnwind(JSContext *cx, MutableHandleValue vp);
|
|
||||||
static inline void onNewScript(JSContext *cx, HandleScript script,
|
/*
|
||||||
GlobalObject *compileAndGoGlobal);
|
* Announce to the debugger that an exception has been thrown and propagated
|
||||||
|
* to |frame|. Call whatever hooks have been registered to observe this and
|
||||||
|
* return a JSTrapStatus code indication how execution should proceed:
|
||||||
|
*
|
||||||
|
* - JSTRAP_CONTINUE: Continue throwing the current exception.
|
||||||
|
*
|
||||||
|
* - JSTRAP_THROW: Throw another value. onExceptionUnwind has set |cx|'s
|
||||||
|
* pending exception to the new value.
|
||||||
|
*
|
||||||
|
* - JSTRAP_ERROR: Terminate execution. onExceptionUnwind has cleared |cx|'s
|
||||||
|
* pending exception.
|
||||||
|
*
|
||||||
|
* - JSTRAP_RETURN: Return from |frame|. onExceptionUnwind has cleared
|
||||||
|
* |cx|'s pending exception and set |frame|'s return value.
|
||||||
|
*/
|
||||||
|
static inline JSTrapStatus onExceptionUnwind(JSContext *cx, AbstractFramePtr frame);
|
||||||
|
static inline void onNewScript(JSContext *cx, HandleScript script, GlobalObject *compileAndGoGlobal);
|
||||||
static inline void onNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
static inline void onNewGlobalObject(JSContext *cx, Handle<GlobalObject *> global);
|
||||||
static inline bool onLogAllocationSite(JSContext *cx, HandleSavedFrame frame);
|
static inline bool onLogAllocationSite(JSContext *cx, HandleSavedFrame frame);
|
||||||
static JSTrapStatus onTrap(JSContext *cx, MutableHandleValue vp);
|
static JSTrapStatus onTrap(JSContext *cx, MutableHandleValue vp);
|
||||||
|
@ -734,11 +782,11 @@ Debugger::observesGlobal(GlobalObject *global) const
|
||||||
}
|
}
|
||||||
|
|
||||||
JSTrapStatus
|
JSTrapStatus
|
||||||
Debugger::onEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHandleValue vp)
|
Debugger::onEnterFrame(JSContext *cx, AbstractFramePtr frame)
|
||||||
{
|
{
|
||||||
if (!cx->compartment()->debugMode())
|
if (!cx->compartment()->debugMode())
|
||||||
return JSTRAP_CONTINUE;
|
return JSTRAP_CONTINUE;
|
||||||
return slowPathOnEnterFrame(cx, frame, vp);
|
return slowPathOnEnterFrame(cx, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSTrapStatus
|
JSTrapStatus
|
||||||
|
@ -750,11 +798,11 @@ Debugger::onDebuggerStatement(JSContext *cx, MutableHandleValue vp)
|
||||||
}
|
}
|
||||||
|
|
||||||
JSTrapStatus
|
JSTrapStatus
|
||||||
Debugger::onExceptionUnwind(JSContext *cx, MutableHandleValue vp)
|
Debugger::onExceptionUnwind(JSContext *cx, AbstractFramePtr frame)
|
||||||
{
|
{
|
||||||
return cx->compartment()->debugMode()
|
if (!cx->compartment()->debugMode())
|
||||||
? dispatchHook(cx, vp, OnExceptionUnwind)
|
return JSTRAP_CONTINUE;
|
||||||
: JSTRAP_CONTINUE;
|
return slowPathOnExceptionUnwind(cx, frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -47,6 +47,7 @@
|
||||||
#include "jsscriptinlines.h"
|
#include "jsscriptinlines.h"
|
||||||
|
|
||||||
#include "jit/IonFrames-inl.h"
|
#include "jit/IonFrames-inl.h"
|
||||||
|
#include "vm/Debugger-inl.h"
|
||||||
#include "vm/ObjectImpl-inl.h"
|
#include "vm/ObjectImpl-inl.h"
|
||||||
#include "vm/Probes-inl.h"
|
#include "vm/Probes-inl.h"
|
||||||
#include "vm/ScopeObject-inl.h"
|
#include "vm/ScopeObject-inl.h"
|
||||||
|
@ -1024,23 +1025,21 @@ HandleError(JSContext *cx, InterpreterRegs ®s)
|
||||||
again:
|
again:
|
||||||
if (cx->isExceptionPending()) {
|
if (cx->isExceptionPending()) {
|
||||||
/* Call debugger throw hooks. */
|
/* Call debugger throw hooks. */
|
||||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
|
JSTrapStatus status = Debugger::onExceptionUnwind(cx, regs.fp());
|
||||||
JSTrapStatus status = DebugExceptionUnwind(cx, regs.fp(), regs.pc);
|
switch (status) {
|
||||||
switch (status) {
|
case JSTRAP_ERROR:
|
||||||
case JSTRAP_ERROR:
|
goto again;
|
||||||
goto again;
|
|
||||||
|
|
||||||
case JSTRAP_CONTINUE:
|
case JSTRAP_CONTINUE:
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case JSTRAP_RETURN:
|
case JSTRAP_RETURN:
|
||||||
ForcedReturn(cx, si, regs);
|
ForcedReturn(cx, si, regs);
|
||||||
return SuccessfulReturnContinuation;
|
return SuccessfulReturnContinuation;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("Invalid trap status");
|
MOZ_CRASH("Bad Debugger::onExceptionUnwind status");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RootedValue exception(cx);
|
RootedValue exception(cx);
|
||||||
|
@ -1505,20 +1504,18 @@ Interpret(JSContext *cx, RunState &state)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
|
|
||||||
JSTrapStatus status = ScriptDebugPrologue(cx, activation.entryFrame(), REGS.pc);
|
switch (Debugger::onEnterFrame(cx, activation.entryFrame())) {
|
||||||
switch (status) {
|
case JSTRAP_CONTINUE:
|
||||||
case JSTRAP_CONTINUE:
|
break;
|
||||||
break;
|
case JSTRAP_RETURN:
|
||||||
case JSTRAP_RETURN:
|
ForcedReturn(cx, REGS);
|
||||||
ForcedReturn(cx, REGS);
|
goto successful_return_continuation;
|
||||||
goto successful_return_continuation;
|
case JSTRAP_THROW:
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_ERROR:
|
||||||
case JSTRAP_ERROR:
|
goto error;
|
||||||
goto error;
|
default:
|
||||||
default:
|
MOZ_CRASH("bad Debugger::onEnterFrame status");
|
||||||
MOZ_CRASH("bad ScriptDebugPrologue status");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cx->runtime()->profilingScripts)
|
if (cx->runtime()->profilingScripts)
|
||||||
|
@ -1787,8 +1784,7 @@ CASE(JSOP_RETRVAL)
|
||||||
// Stop the script. (Again no details about which script exactly.)
|
// Stop the script. (Again no details about which script exactly.)
|
||||||
TraceLogStopEvent(logger);
|
TraceLogStopEvent(logger);
|
||||||
|
|
||||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
|
interpReturnOK = Debugger::onLeaveFrame(cx, REGS.fp(), interpReturnOK);
|
||||||
interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), REGS.pc, interpReturnOK);
|
|
||||||
|
|
||||||
if (!REGS.fp()->isYielding())
|
if (!REGS.fp()->isYielding())
|
||||||
REGS.fp()->epilogue(cx);
|
REGS.fp()->epilogue(cx);
|
||||||
|
@ -2609,19 +2605,18 @@ CASE(JSOP_FUNCALL)
|
||||||
|
|
||||||
if (!REGS.fp()->prologue(cx))
|
if (!REGS.fp()->prologue(cx))
|
||||||
goto error;
|
goto error;
|
||||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
|
|
||||||
switch (ScriptDebugPrologue(cx, REGS.fp(), REGS.pc)) {
|
switch (Debugger::onEnterFrame(cx, REGS.fp())) {
|
||||||
case JSTRAP_CONTINUE:
|
case JSTRAP_CONTINUE:
|
||||||
break;
|
break;
|
||||||
case JSTRAP_RETURN:
|
case JSTRAP_RETURN:
|
||||||
ForcedReturn(cx, REGS);
|
ForcedReturn(cx, REGS);
|
||||||
goto successful_return_continuation;
|
goto successful_return_continuation;
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
case JSTRAP_ERROR:
|
case JSTRAP_ERROR:
|
||||||
goto error;
|
goto error;
|
||||||
default:
|
default:
|
||||||
MOZ_CRASH("bad ScriptDebugPrologue status");
|
MOZ_CRASH("bad Debugger::onEnterFrame status");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load first op and dispatch it (safe since JSOP_RETRVAL). */
|
/* Load first op and dispatch it (safe since JSOP_RETRVAL). */
|
||||||
|
@ -3467,8 +3462,8 @@ DEFAULT()
|
||||||
MOZ_CRASH("Invalid HandleError continuation");
|
MOZ_CRASH("Invalid HandleError continuation");
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
|
interpReturnOK = Debugger::onLeaveFrame(cx, REGS.fp(), interpReturnOK);
|
||||||
interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), REGS.pc, interpReturnOK);
|
|
||||||
if (!REGS.fp()->isYielding())
|
if (!REGS.fp()->isYielding())
|
||||||
REGS.fp()->epilogue(cx);
|
REGS.fp()->epilogue(cx);
|
||||||
else
|
else
|
||||||
|
|
|
@ -20,63 +20,6 @@ namespace js {
|
||||||
|
|
||||||
class ScopeIter;
|
class ScopeIter;
|
||||||
|
|
||||||
/*
|
|
||||||
* Announce to the debugger that the thread has entered a new JavaScript frame,
|
|
||||||
* |frame|. Call whatever hooks have been registered to observe new frames, and
|
|
||||||
* return a JSTrapStatus code indication how execution should proceed:
|
|
||||||
*
|
|
||||||
* - JSTRAP_CONTINUE: Continue execution normally.
|
|
||||||
*
|
|
||||||
* - JSTRAP_THROW: Throw an exception. ScriptDebugPrologue has set |cx|'s
|
|
||||||
* pending exception to the value to be thrown.
|
|
||||||
*
|
|
||||||
* - JSTRAP_ERROR: Terminate execution (as is done when a script is terminated
|
|
||||||
* for running too long). ScriptDebugPrologue has cleared |cx|'s pending
|
|
||||||
* exception.
|
|
||||||
*
|
|
||||||
* - JSTRAP_RETURN: Return from the new frame immediately. ScriptDebugPrologue
|
|
||||||
* has set |frame|'s return value appropriately.
|
|
||||||
*/
|
|
||||||
extern JSTrapStatus
|
|
||||||
ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Announce to the debugger that the thread has exited a JavaScript frame, |frame|.
|
|
||||||
* If |ok| is true, the frame is returning normally; if |ok| is false, the frame
|
|
||||||
* is throwing an exception or terminating.
|
|
||||||
*
|
|
||||||
* Call whatever hooks have been registered to observe frame exits. Change cx's
|
|
||||||
* current exception and |frame|'s return value to reflect the changes in behavior
|
|
||||||
* the hooks request, if any. Return the new error/success value.
|
|
||||||
*
|
|
||||||
* This function may be called twice for the same outgoing frame; only the
|
|
||||||
* first call has any effect. (Permitting double calls simplifies some
|
|
||||||
* cases where an onPop handler's resumption value changes a return to a
|
|
||||||
* throw, or vice versa: we can redirect to a complete copy of the
|
|
||||||
* alternative path, containing its own call to ScriptDebugEpilogue.)
|
|
||||||
*/
|
|
||||||
extern bool
|
|
||||||
ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc, bool ok);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Announce to the debugger that an exception has been thrown and propagated
|
|
||||||
* to |frame|. Call whatever hooks have been registered to observe this and
|
|
||||||
* return a JSTrapStatus code indication how execution should proceed:
|
|
||||||
*
|
|
||||||
* - JSTRAP_CONTINUE: Continue throwing the current exception.
|
|
||||||
*
|
|
||||||
* - JSTRAP_THROW: Throw another value. DebugExceptionUnwind has set |cx|'s
|
|
||||||
* pending exception to the new value.
|
|
||||||
*
|
|
||||||
* - JSTRAP_ERROR: Terminate execution. DebugExceptionUnwind has cleared |cx|'s
|
|
||||||
* pending exception.
|
|
||||||
*
|
|
||||||
* - JSTRAP_RETURN: Return from |frame|. DebugExceptionUnwind has cleared
|
|
||||||
* |cx|'s pending exception and set |frame|'s return value.
|
|
||||||
*/
|
|
||||||
extern JSTrapStatus
|
|
||||||
DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For a given |call|, convert null/undefined |this| into the global object for
|
* For a given |call|, convert null/undefined |this| into the global object for
|
||||||
* the callee and replace other primitives with boxed versions. This assumes
|
* the callee and replace other primitives with boxed versions. This assumes
|
||||||
|
|
|
@ -39,76 +39,6 @@ using namespace js::gc;
|
||||||
|
|
||||||
using mozilla::PodZero;
|
using mozilla::PodZero;
|
||||||
|
|
||||||
JSTrapStatus
|
|
||||||
js::ScriptDebugPrologue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT_IF(frame.isInterpreterFrame(), frame.asInterpreterFrame() == cx->interpreterFrame());
|
|
||||||
|
|
||||||
RootedValue rval(cx);
|
|
||||||
JSTrapStatus status = Debugger::onEnterFrame(cx, frame, &rval);
|
|
||||||
switch (status) {
|
|
||||||
case JSTRAP_CONTINUE:
|
|
||||||
break;
|
|
||||||
case JSTRAP_THROW:
|
|
||||||
cx->setPendingException(rval);
|
|
||||||
break;
|
|
||||||
case JSTRAP_ERROR:
|
|
||||||
cx->clearPendingException();
|
|
||||||
break;
|
|
||||||
case JSTRAP_RETURN:
|
|
||||||
frame.setReturnValue(rval);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("bad Debugger::onEnterFrame JSTrapStatus value");
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
js::ScriptDebugEpilogue(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc, bool okArg)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT_IF(frame.isInterpreterFrame(), frame.asInterpreterFrame() == cx->interpreterFrame());
|
|
||||||
|
|
||||||
bool ok = okArg;
|
|
||||||
|
|
||||||
return Debugger::onLeaveFrame(cx, frame, ok);
|
|
||||||
}
|
|
||||||
|
|
||||||
JSTrapStatus
|
|
||||||
js::DebugExceptionUnwind(JSContext *cx, AbstractFramePtr frame, jsbytecode *pc)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(cx->compartment()->debugMode());
|
|
||||||
|
|
||||||
/* Call debugger throw hook if set. */
|
|
||||||
RootedValue rval(cx);
|
|
||||||
JSTrapStatus status = Debugger::onExceptionUnwind(cx, &rval);
|
|
||||||
|
|
||||||
switch (status) {
|
|
||||||
case JSTRAP_ERROR:
|
|
||||||
cx->clearPendingException();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JSTRAP_RETURN:
|
|
||||||
cx->clearPendingException();
|
|
||||||
frame.setReturnValue(rval);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JSTRAP_THROW:
|
|
||||||
cx->setPendingException(rval);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case JSTRAP_CONTINUE:
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Invalid trap status");
|
|
||||||
}
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
|
|
||||||
JS_PUBLIC_API(JSScript *)
|
JS_PUBLIC_API(JSScript *)
|
||||||
JS_GetFunctionScript(JSContext *cx, HandleFunction fun)
|
JS_GetFunctionScript(JSContext *cx, HandleFunction fun)
|
||||||
{
|
{
|
||||||
|
|
Загрузка…
Ссылка в новой задаче