зеркало из 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()) {
|
||||
BaselineFrame *baselineFrame = frame.baselineFrame();
|
||||
JSTrapStatus status = DebugExceptionUnwind(cx, baselineFrame, pc);
|
||||
switch (status) {
|
||||
switch (Debugger::onExceptionUnwind(cx, baselineFrame)) {
|
||||
case JSTRAP_ERROR:
|
||||
// Uncatchable exception.
|
||||
MOZ_ASSERT(!cx->isExceptionPending());
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "jit/BaselineFrame-inl.h"
|
||||
#include "jit/IonFrames-inl.h"
|
||||
#include "vm/Debugger-inl.h"
|
||||
#include "vm/Interpreter-inl.h"
|
||||
#include "vm/ObjectImpl-inl.h"
|
||||
#include "vm/StringObject-inl.h"
|
||||
|
@ -763,8 +764,7 @@ DebugPrologue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool *mustRet
|
|||
{
|
||||
*mustReturn = false;
|
||||
|
||||
JSTrapStatus status = ScriptDebugPrologue(cx, frame, pc);
|
||||
switch (status) {
|
||||
switch (Debugger::onEnterFrame(cx, frame)) {
|
||||
case JSTRAP_CONTINUE:
|
||||
return true;
|
||||
|
||||
|
@ -780,7 +780,7 @@ DebugPrologue(JSContext *cx, BaselineFrame *frame, jsbytecode *pc, bool *mustRet
|
|||
return false;
|
||||
|
||||
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();
|
||||
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.
|
||||
// In both cases we have to pop debug scopes.
|
||||
ok = ScriptDebugEpilogue(cx, frame, pc, ok);
|
||||
ok = Debugger::onLeaveFrame(cx, frame, ok);
|
||||
|
||||
if (frame->isNonEvalFunctionFrame()) {
|
||||
MOZ_ASSERT_IF(ok, frame->hasReturnValue());
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
inline bool
|
||||
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. */
|
||||
bool evalTraps = frame.isEvalFrame() &&
|
||||
frame.script()->hasAnyBreakpointsOrStepMode();
|
||||
|
|
|
@ -498,9 +498,9 @@ Debugger::hasAnyLiveHooks() const
|
|||
}
|
||||
|
||||
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);
|
||||
Handle<GlobalObject*> global = cx->global();
|
||||
|
||||
|
@ -510,22 +510,45 @@ Debugger::slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHan
|
|||
if (dbg->observesFrame(frame) && dbg->observesEnterFrame() &&
|
||||
!triggered.append(ObjectValue(*dbg->toJSObject())))
|
||||
{
|
||||
cx->clearPendingException();
|
||||
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++) {
|
||||
Debugger *dbg = Debugger::fromJSObject(&p->toObject());
|
||||
if (dbg->debuggees.has(global) && dbg->observesEnterFrame()) {
|
||||
JSTrapStatus status = dbg->fireEnterFrame(cx, frame, vp);
|
||||
status = dbg->fireEnterFrame(cx, frame, &rval);
|
||||
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
|
||||
|
@ -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
|
||||
Debugger::wrapEnvironment(JSContext *cx, Handle<Env*> env, MutableHandleValue rval)
|
||||
{
|
||||
|
|
|
@ -369,9 +369,9 @@ class Debugger : private mozilla::LinkedListElement<Debugger>
|
|||
JSObject *getHook(Hook hook) const;
|
||||
bool hasAnyLiveHooks() const;
|
||||
|
||||
static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame,
|
||||
MutableHandleValue vp);
|
||||
static JSTrapStatus slowPathOnEnterFrame(JSContext *cx, AbstractFramePtr frame);
|
||||
static bool slowPathOnLeaveFrame(JSContext *cx, AbstractFramePtr frame, bool ok);
|
||||
static JSTrapStatus slowPathOnExceptionUnwind(JSContext *cx, AbstractFramePtr frame);
|
||||
static void slowPathOnNewScript(JSContext *cx, HandleScript script,
|
||||
GlobalObject *compileAndGoGlobal);
|
||||
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 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 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 bool onLogAllocationSite(JSContext *cx, HandleSavedFrame frame);
|
||||
static JSTrapStatus onTrap(JSContext *cx, MutableHandleValue vp);
|
||||
|
@ -734,11 +782,11 @@ Debugger::observesGlobal(GlobalObject *global) const
|
|||
}
|
||||
|
||||
JSTrapStatus
|
||||
Debugger::onEnterFrame(JSContext *cx, AbstractFramePtr frame, MutableHandleValue vp)
|
||||
Debugger::onEnterFrame(JSContext *cx, AbstractFramePtr frame)
|
||||
{
|
||||
if (!cx->compartment()->debugMode())
|
||||
return JSTRAP_CONTINUE;
|
||||
return slowPathOnEnterFrame(cx, frame, vp);
|
||||
return slowPathOnEnterFrame(cx, frame);
|
||||
}
|
||||
|
||||
JSTrapStatus
|
||||
|
@ -750,11 +798,11 @@ Debugger::onDebuggerStatement(JSContext *cx, MutableHandleValue vp)
|
|||
}
|
||||
|
||||
JSTrapStatus
|
||||
Debugger::onExceptionUnwind(JSContext *cx, MutableHandleValue vp)
|
||||
Debugger::onExceptionUnwind(JSContext *cx, AbstractFramePtr frame)
|
||||
{
|
||||
return cx->compartment()->debugMode()
|
||||
? dispatchHook(cx, vp, OnExceptionUnwind)
|
||||
: JSTRAP_CONTINUE;
|
||||
if (!cx->compartment()->debugMode())
|
||||
return JSTRAP_CONTINUE;
|
||||
return slowPathOnExceptionUnwind(cx, frame);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "jsscriptinlines.h"
|
||||
|
||||
#include "jit/IonFrames-inl.h"
|
||||
#include "vm/Debugger-inl.h"
|
||||
#include "vm/ObjectImpl-inl.h"
|
||||
#include "vm/Probes-inl.h"
|
||||
#include "vm/ScopeObject-inl.h"
|
||||
|
@ -1024,8 +1025,7 @@ HandleError(JSContext *cx, InterpreterRegs ®s)
|
|||
again:
|
||||
if (cx->isExceptionPending()) {
|
||||
/* Call debugger throw hooks. */
|
||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
|
||||
JSTrapStatus status = DebugExceptionUnwind(cx, regs.fp(), regs.pc);
|
||||
JSTrapStatus status = Debugger::onExceptionUnwind(cx, regs.fp());
|
||||
switch (status) {
|
||||
case JSTRAP_ERROR:
|
||||
goto again;
|
||||
|
@ -1039,8 +1039,7 @@ HandleError(JSContext *cx, InterpreterRegs ®s)
|
|||
return SuccessfulReturnContinuation;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Invalid trap status");
|
||||
}
|
||||
MOZ_CRASH("Bad Debugger::onExceptionUnwind status");
|
||||
}
|
||||
|
||||
RootedValue exception(cx);
|
||||
|
@ -1505,9 +1504,8 @@ Interpret(JSContext *cx, RunState &state)
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
|
||||
JSTrapStatus status = ScriptDebugPrologue(cx, activation.entryFrame(), REGS.pc);
|
||||
switch (status) {
|
||||
|
||||
switch (Debugger::onEnterFrame(cx, activation.entryFrame())) {
|
||||
case JSTRAP_CONTINUE:
|
||||
break;
|
||||
case JSTRAP_RETURN:
|
||||
|
@ -1517,8 +1515,7 @@ Interpret(JSContext *cx, RunState &state)
|
|||
case JSTRAP_ERROR:
|
||||
goto error;
|
||||
default:
|
||||
MOZ_CRASH("bad ScriptDebugPrologue status");
|
||||
}
|
||||
MOZ_CRASH("bad Debugger::onEnterFrame status");
|
||||
}
|
||||
|
||||
if (cx->runtime()->profilingScripts)
|
||||
|
@ -1787,8 +1784,7 @@ CASE(JSOP_RETRVAL)
|
|||
// Stop the script. (Again no details about which script exactly.)
|
||||
TraceLogStopEvent(logger);
|
||||
|
||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
|
||||
interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), REGS.pc, interpReturnOK);
|
||||
interpReturnOK = Debugger::onLeaveFrame(cx, REGS.fp(), interpReturnOK);
|
||||
|
||||
if (!REGS.fp()->isYielding())
|
||||
REGS.fp()->epilogue(cx);
|
||||
|
@ -2609,8 +2605,8 @@ CASE(JSOP_FUNCALL)
|
|||
|
||||
if (!REGS.fp()->prologue(cx))
|
||||
goto error;
|
||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode())) {
|
||||
switch (ScriptDebugPrologue(cx, REGS.fp(), REGS.pc)) {
|
||||
|
||||
switch (Debugger::onEnterFrame(cx, REGS.fp())) {
|
||||
case JSTRAP_CONTINUE:
|
||||
break;
|
||||
case JSTRAP_RETURN:
|
||||
|
@ -2620,8 +2616,7 @@ CASE(JSOP_FUNCALL)
|
|||
case JSTRAP_ERROR:
|
||||
goto error;
|
||||
default:
|
||||
MOZ_CRASH("bad ScriptDebugPrologue status");
|
||||
}
|
||||
MOZ_CRASH("bad Debugger::onEnterFrame status");
|
||||
}
|
||||
|
||||
/* Load first op and dispatch it (safe since JSOP_RETRVAL). */
|
||||
|
@ -3467,8 +3462,8 @@ DEFAULT()
|
|||
MOZ_CRASH("Invalid HandleError continuation");
|
||||
|
||||
exit:
|
||||
if (MOZ_UNLIKELY(cx->compartment()->debugMode()))
|
||||
interpReturnOK = ScriptDebugEpilogue(cx, REGS.fp(), REGS.pc, interpReturnOK);
|
||||
interpReturnOK = Debugger::onLeaveFrame(cx, REGS.fp(), interpReturnOK);
|
||||
|
||||
if (!REGS.fp()->isYielding())
|
||||
REGS.fp()->epilogue(cx);
|
||||
else
|
||||
|
|
|
@ -20,63 +20,6 @@ namespace js {
|
|||
|
||||
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
|
||||
* the callee and replace other primitives with boxed versions. This assumes
|
||||
|
|
|
@ -39,76 +39,6 @@ using namespace js::gc;
|
|||
|
||||
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_GetFunctionScript(JSContext *cx, HandleFunction fun)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче