mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge backout.
This commit is contained in:
commit
e477e5125b
@ -1130,7 +1130,7 @@ nsJSContext::DOMOperationCallback(JSContext *cx)
|
|||||||
JS_SetFrameReturnValue(cx, fp, rval);
|
JS_SetFrameReturnValue(cx, fp, rval);
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
case JSTRAP_ERROR:
|
case JSTRAP_ERROR:
|
||||||
JS_ClearPendingException(cx);
|
cx->throwing = JS_FALSE;
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
JS_SetPendingException(cx, rval);
|
JS_SetPendingException(cx, rval);
|
||||||
|
@ -5173,8 +5173,7 @@ JS_IsRunning(JSContext *cx)
|
|||||||
VOUCH_DOES_NOT_REQUIRE_STACK();
|
VOUCH_DOES_NOT_REQUIRE_STACK();
|
||||||
|
|
||||||
#ifdef JS_TRACER
|
#ifdef JS_TRACER
|
||||||
JS_ASSERT_IF(cx->compartment &&
|
JS_ASSERT_IF(JS_TRACE_MONITOR(cx).tracecx == cx, cx->hasfp());
|
||||||
JS_TRACE_MONITOR(cx).tracecx == cx, cx->hasfp());
|
|
||||||
#endif
|
#endif
|
||||||
JSStackFrame *fp = cx->maybefp();
|
JSStackFrame *fp = cx->maybefp();
|
||||||
while (fp && fp->isDummyFrame())
|
while (fp && fp->isDummyFrame())
|
||||||
@ -5847,17 +5846,16 @@ JS_GetLocaleCallbacks(JSContext *cx)
|
|||||||
JS_PUBLIC_API(JSBool)
|
JS_PUBLIC_API(JSBool)
|
||||||
JS_IsExceptionPending(JSContext *cx)
|
JS_IsExceptionPending(JSContext *cx)
|
||||||
{
|
{
|
||||||
return (JSBool) cx->isExceptionPending();
|
return (JSBool) cx->throwing;
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSBool)
|
JS_PUBLIC_API(JSBool)
|
||||||
JS_GetPendingException(JSContext *cx, jsval *vp)
|
JS_GetPendingException(JSContext *cx, jsval *vp)
|
||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
if (!cx->isExceptionPending())
|
if (!cx->throwing)
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
Valueify(*vp) = cx->getPendingException();
|
Valueify(*vp) = cx->exception;
|
||||||
assertSameCompartment(cx, *vp);
|
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5866,13 +5864,14 @@ JS_SetPendingException(JSContext *cx, jsval v)
|
|||||||
{
|
{
|
||||||
CHECK_REQUEST(cx);
|
CHECK_REQUEST(cx);
|
||||||
assertSameCompartment(cx, v);
|
assertSameCompartment(cx, v);
|
||||||
cx->setPendingException(Valueify(v));
|
SetPendingException(cx, Valueify(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(void)
|
JS_PUBLIC_API(void)
|
||||||
JS_ClearPendingException(JSContext *cx)
|
JS_ClearPendingException(JSContext *cx)
|
||||||
{
|
{
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
|
cx->exception.setUndefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_PUBLIC_API(JSBool)
|
JS_PUBLIC_API(JSBool)
|
||||||
|
@ -1357,7 +1357,7 @@ js_ReportOutOfMemory(JSContext *cx)
|
|||||||
* exception if any now so the hooks can replace the out-of-memory error
|
* exception if any now so the hooks can replace the out-of-memory error
|
||||||
* by a script-catchable exception.
|
* by a script-catchable exception.
|
||||||
*/
|
*/
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
if (onError) {
|
if (onError) {
|
||||||
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
|
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
|
||||||
if (hook &&
|
if (hook &&
|
||||||
@ -2005,37 +2005,27 @@ JSContext::resetCompartment()
|
|||||||
scopeobj = &fp()->scopeChain();
|
scopeobj = &fp()->scopeChain();
|
||||||
} else {
|
} else {
|
||||||
scopeobj = globalObject;
|
scopeobj = globalObject;
|
||||||
if (!scopeobj)
|
if (!scopeobj) {
|
||||||
goto error;
|
compartment = runtime->defaultCompartment;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Innerize. Assert, but check anyway, that this succeeds. (It
|
* Innerize. Assert, but check anyway, that this succeeds. (It
|
||||||
* can only fail due to bugs in the engine or embedding.)
|
* can only fail due to bugs in the engine or embedding.)
|
||||||
*/
|
*/
|
||||||
OBJ_TO_INNER_OBJECT(this, scopeobj);
|
OBJ_TO_INNER_OBJECT(this, scopeobj);
|
||||||
if (!scopeobj)
|
if (!scopeobj) {
|
||||||
goto error;
|
/*
|
||||||
|
* Bug. Return NULL, not defaultCompartment, to crash rather
|
||||||
|
* than open a security hole.
|
||||||
|
*/
|
||||||
|
JS_ASSERT(0);
|
||||||
|
compartment = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
compartment = scopeobj->getCompartment();
|
||||||
compartment = scopeobj->compartment();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If wrapException fails, it overrides this->exception and
|
|
||||||
* reports OOM. The upshot is that we silently turn the exception
|
|
||||||
* into an uncatchable OOM error. A bit surprising, but the
|
|
||||||
* caller is just going to return false either way.
|
|
||||||
*/
|
|
||||||
if (isExceptionPending())
|
|
||||||
(void) compartment->wrapException(this);
|
|
||||||
return;
|
|
||||||
|
|
||||||
error:
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we try to use the context without a selected compartment,
|
|
||||||
* we will crash.
|
|
||||||
*/
|
|
||||||
compartment = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2299,4 +2289,11 @@ LeaveTrace(JSContext *cx)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
SetPendingException(JSContext *cx, const Value &v)
|
||||||
|
{
|
||||||
|
cx->throwing = JS_TRUE;
|
||||||
|
cx->exception = v;
|
||||||
|
}
|
||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
@ -888,7 +888,7 @@ private:
|
|||||||
* executing. cx must be a context on the current thread.
|
* executing. cx must be a context on the current thread.
|
||||||
*/
|
*/
|
||||||
#ifdef JS_TRACER
|
#ifdef JS_TRACER
|
||||||
# define JS_ON_TRACE(cx) (cx->compartment && JS_TRACE_MONITOR(cx).ontrace())
|
# define JS_ON_TRACE(cx) (JS_TRACE_MONITOR(cx).ontrace())
|
||||||
#else
|
#else
|
||||||
# define JS_ON_TRACE(cx) false
|
# define JS_ON_TRACE(cx) false
|
||||||
#endif
|
#endif
|
||||||
@ -1700,10 +1700,6 @@ struct JSContext
|
|||||||
JSVersion versionOverride; /* supercedes defaultVersion when valid */
|
JSVersion versionOverride; /* supercedes defaultVersion when valid */
|
||||||
bool hasVersionOverride;
|
bool hasVersionOverride;
|
||||||
|
|
||||||
/* Exception state -- the exception member is a GC root by definition. */
|
|
||||||
JSBool throwing; /* is there a pending exception? */
|
|
||||||
js::Value exception; /* most-recently-thrown exception */
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Per-context options. */
|
/* Per-context options. */
|
||||||
uint32 options; /* see jsapi.h for JSOPTION_* */
|
uint32 options; /* see jsapi.h for JSOPTION_* */
|
||||||
@ -1725,6 +1721,10 @@ struct JSContext
|
|||||||
*/
|
*/
|
||||||
JSPackedBool generatingError;
|
JSPackedBool generatingError;
|
||||||
|
|
||||||
|
/* Exception state -- the exception member is a GC root by definition. */
|
||||||
|
JSBool throwing; /* is there a pending exception? */
|
||||||
|
js::Value exception; /* most-recently-thrown exception */
|
||||||
|
|
||||||
/* Limit pointer for checking native stack consumption during recursion. */
|
/* Limit pointer for checking native stack consumption during recursion. */
|
||||||
jsuword stackLimit;
|
jsuword stackLimit;
|
||||||
|
|
||||||
@ -2168,22 +2168,6 @@ struct JSContext
|
|||||||
void assertValidStackDepth(uintN /*depth*/) {}
|
void assertValidStackDepth(uintN /*depth*/) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool isExceptionPending() {
|
|
||||||
return throwing;
|
|
||||||
}
|
|
||||||
|
|
||||||
js::Value getPendingException() {
|
|
||||||
JS_ASSERT(throwing);
|
|
||||||
return exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPendingException(js::Value v);
|
|
||||||
|
|
||||||
void clearPendingException() {
|
|
||||||
this->throwing = false;
|
|
||||||
this->exception.setUndefined();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*
|
/*
|
||||||
* The allocation code calls the function to indicate either OOM failure
|
* The allocation code calls the function to indicate either OOM failure
|
||||||
@ -3163,6 +3147,9 @@ js_CurrentPCIsInImacro(JSContext *cx);
|
|||||||
|
|
||||||
namespace js {
|
namespace js {
|
||||||
|
|
||||||
|
extern void
|
||||||
|
SetPendingException(JSContext *cx, const Value &v);
|
||||||
|
|
||||||
class RegExpStatics;
|
class RegExpStatics;
|
||||||
|
|
||||||
extern JS_FORCES_STACK JS_FRIEND_API(void)
|
extern JS_FORCES_STACK JS_FRIEND_API(void)
|
||||||
|
@ -686,13 +686,13 @@ JS_ALWAYS_INLINE bool
|
|||||||
CallJSNative(JSContext *cx, js::Native native, uintN argc, js::Value *vp)
|
CallJSNative(JSContext *cx, js::Native native, uintN argc, js::Value *vp)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
JSBool alreadyThrowing = cx->isExceptionPending();
|
JSBool alreadyThrowing = cx->throwing;
|
||||||
#endif
|
#endif
|
||||||
assertSameCompartment(cx, ValueArray(vp, argc + 2));
|
assertSameCompartment(cx, ValueArray(vp, argc + 2));
|
||||||
JSBool ok = native(cx, argc, vp);
|
JSBool ok = native(cx, argc, vp);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
assertSameCompartment(cx, vp[0]);
|
assertSameCompartment(cx, vp[0]);
|
||||||
JS_ASSERT_IF(!alreadyThrowing, !cx->isExceptionPending());
|
JS_ASSERT_IF(!alreadyThrowing, !cx->throwing);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
@ -800,11 +800,4 @@ CanLeaveTrace(JSContext *cx)
|
|||||||
|
|
||||||
} /* namespace js */
|
} /* namespace js */
|
||||||
|
|
||||||
inline void
|
|
||||||
JSContext::setPendingException(js::Value v) {
|
|
||||||
this->throwing = true;
|
|
||||||
this->exception = v;
|
|
||||||
assertSameCompartment(this, v);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* jscntxtinlines_h___ */
|
#endif /* jscntxtinlines_h___ */
|
||||||
|
@ -358,11 +358,14 @@ JSCompartment::wrapException(JSContext *cx)
|
|||||||
{
|
{
|
||||||
JS_ASSERT(cx->compartment == this);
|
JS_ASSERT(cx->compartment == this);
|
||||||
|
|
||||||
if (cx->isExceptionPending()) {
|
if (cx->throwing) {
|
||||||
Value v = cx->getPendingException();
|
AutoValueRooter tvr(cx, cx->exception);
|
||||||
cx->clearPendingException();
|
cx->throwing = false;
|
||||||
if (wrap(cx, &v))
|
cx->exception.setNull();
|
||||||
cx->setPendingException(v);
|
if (wrap(cx, tvr.addr())) {
|
||||||
|
cx->throwing = true;
|
||||||
|
cx->exception = tvr.value();
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -377,7 +377,6 @@ class PreserveCompartment {
|
|||||||
public:
|
public:
|
||||||
PreserveCompartment(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM) : cx(cx) {
|
PreserveCompartment(JSContext *cx JS_GUARD_OBJECT_NOTIFIER_PARAM) : cx(cx) {
|
||||||
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
JS_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
|
||||||
oldCompartment = cx->compartment;
|
oldCompartment = cx->compartment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1545,26 +1545,25 @@ JS_GetPropertyDesc(JSContext *cx, JSObject *obj, JSScopeProperty *sprop,
|
|||||||
Shape *shape = (Shape *) sprop;
|
Shape *shape = (Shape *) sprop;
|
||||||
pd->id = IdToJsval(shape->id);
|
pd->id = IdToJsval(shape->id);
|
||||||
|
|
||||||
JSBool wasThrowing = cx->isExceptionPending();
|
JSBool wasThrowing = cx->throwing;
|
||||||
Value lastException = UndefinedValue();
|
AutoValueRooter lastException(cx, cx->exception);
|
||||||
if (wasThrowing)
|
cx->throwing = JS_FALSE;
|
||||||
lastException = cx->getPendingException();
|
|
||||||
cx->clearPendingException();
|
|
||||||
|
|
||||||
if (!js_GetProperty(cx, obj, shape->id, Valueify(&pd->value))) {
|
if (!js_GetProperty(cx, obj, shape->id, Valueify(&pd->value))) {
|
||||||
if (!cx->isExceptionPending()) {
|
if (!cx->throwing) {
|
||||||
pd->flags = JSPD_ERROR;
|
pd->flags = JSPD_ERROR;
|
||||||
pd->value = JSVAL_VOID;
|
pd->value = JSVAL_VOID;
|
||||||
} else {
|
} else {
|
||||||
pd->flags = JSPD_EXCEPTION;
|
pd->flags = JSPD_EXCEPTION;
|
||||||
pd->value = Jsvalify(cx->getPendingException());
|
pd->value = Jsvalify(cx->exception);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
pd->flags = 0;
|
pd->flags = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cx->throwing = wasThrowing;
|
||||||
if (wasThrowing)
|
if (wasThrowing)
|
||||||
cx->setPendingException(lastException);
|
cx->exception = lastException.value();
|
||||||
|
|
||||||
pd->flags |= (shape->enumerable() ? JSPD_ENUMERATE : 0)
|
pd->flags |= (shape->enumerable() ? JSPD_ENUMERATE : 0)
|
||||||
| (!shape->writable() ? JSPD_READONLY : 0)
|
| (!shape->writable() ? JSPD_READONLY : 0)
|
||||||
|
@ -1582,8 +1582,12 @@ MarkContext(JSTracer *trc, JSContext *acx)
|
|||||||
/* Mark other roots-by-definition in acx. */
|
/* Mark other roots-by-definition in acx. */
|
||||||
if (acx->globalObject && !JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL))
|
if (acx->globalObject && !JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL))
|
||||||
MarkObject(trc, *acx->globalObject, "global object");
|
MarkObject(trc, *acx->globalObject, "global object");
|
||||||
if (acx->isExceptionPending())
|
if (acx->throwing) {
|
||||||
MarkValue(trc, acx->getPendingException(), "exception");
|
MarkValue(trc, acx->exception, "exception");
|
||||||
|
} else {
|
||||||
|
/* Avoid keeping GC-ed junk stored in JSContext.exception. */
|
||||||
|
acx->exception.setNull();
|
||||||
|
}
|
||||||
|
|
||||||
for (js::AutoGCRooter *gcr = acx->autoGCRooters; gcr; gcr = gcr->down)
|
for (js::AutoGCRooter *gcr = acx->autoGCRooters; gcr; gcr = gcr->down)
|
||||||
gcr->trace(trc);
|
gcr->trace(trc);
|
||||||
|
@ -2429,7 +2429,7 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||||||
argv = regs.fp->maybeFormalArgs(); \
|
argv = regs.fp->maybeFormalArgs(); \
|
||||||
atoms = FrameAtomBase(cx, regs.fp); \
|
atoms = FrameAtomBase(cx, regs.fp); \
|
||||||
JS_ASSERT(cx->regs == ®s); \
|
JS_ASSERT(cx->regs == ®s); \
|
||||||
if (cx->isExceptionPending()) \
|
if (cx->throwing) \
|
||||||
goto error; \
|
goto error; \
|
||||||
JS_END_MACRO
|
JS_END_MACRO
|
||||||
|
|
||||||
@ -2445,7 +2445,7 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||||||
CLEAR_LEAVE_ON_TRACE_POINT(); \
|
CLEAR_LEAVE_ON_TRACE_POINT(); \
|
||||||
} \
|
} \
|
||||||
RESTORE_INTERP_VARS(); \
|
RESTORE_INTERP_VARS(); \
|
||||||
JS_ASSERT_IF(cx->isExceptionPending(), r == MONITOR_ERROR); \
|
JS_ASSERT_IF(cx->throwing, r == MONITOR_ERROR); \
|
||||||
if (r == MONITOR_ERROR) \
|
if (r == MONITOR_ERROR) \
|
||||||
goto error; \
|
goto error; \
|
||||||
} \
|
} \
|
||||||
@ -2571,9 +2571,9 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* To support generator_throw and to catch ignored exceptions,
|
* To support generator_throw and to catch ignored exceptions,
|
||||||
* fail if cx->isExceptionPending() is true.
|
* fail if cx->throwing is set.
|
||||||
*/
|
*/
|
||||||
if (cx->isExceptionPending())
|
if (cx->throwing)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -2687,7 +2687,8 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||||||
interpReturnOK = JS_TRUE;
|
interpReturnOK = JS_TRUE;
|
||||||
goto forced_return;
|
goto forced_return;
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
cx->setPendingException(rval);
|
cx->throwing = JS_TRUE;
|
||||||
|
cx->exception = rval;
|
||||||
goto error;
|
goto error;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
@ -2715,7 +2716,7 @@ Interpret(JSContext *cx, JSStackFrame *entryFrame, uintN inlineCallCount, JSInte
|
|||||||
if (TraceRecorder* tr = TRACE_RECORDER(cx)) {
|
if (TraceRecorder* tr = TRACE_RECORDER(cx)) {
|
||||||
JS_ASSERT(!TRACE_PROFILER(cx));
|
JS_ASSERT(!TRACE_PROFILER(cx));
|
||||||
AbortableRecordingStatus status = tr->monitorRecording(op);
|
AbortableRecordingStatus status = tr->monitorRecording(op);
|
||||||
JS_ASSERT_IF(cx->isExceptionPending(), status == ARECORD_ERROR);
|
JS_ASSERT_IF(cx->throwing, status == ARECORD_ERROR);
|
||||||
|
|
||||||
if (interpMode != JSINTERP_NORMAL) {
|
if (interpMode != JSINTERP_NORMAL) {
|
||||||
JS_ASSERT(interpMode == JSINTERP_RECORD || JSINTERP_SAFEPOINT);
|
JS_ASSERT(interpMode == JSINTERP_RECORD || JSINTERP_SAFEPOINT);
|
||||||
@ -5203,7 +5204,8 @@ BEGIN_CASE(JSOP_TRAP)
|
|||||||
interpReturnOK = JS_TRUE;
|
interpReturnOK = JS_TRUE;
|
||||||
goto forced_return;
|
goto forced_return;
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
cx->setPendingException(rval);
|
cx->throwing = JS_TRUE;
|
||||||
|
cx->exception = rval;
|
||||||
goto error;
|
goto error;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -6229,7 +6231,8 @@ BEGIN_CASE(JSOP_RETSUB)
|
|||||||
* be necessary, but it seems clearer. And it points out a FIXME:
|
* be necessary, but it seems clearer. And it points out a FIXME:
|
||||||
* 350509, due to Igor Bukanov.
|
* 350509, due to Igor Bukanov.
|
||||||
*/
|
*/
|
||||||
cx->setPendingException(rval);
|
cx->throwing = JS_TRUE;
|
||||||
|
cx->exception = rval;
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
JS_ASSERT(rval.isInt32());
|
JS_ASSERT(rval.isInt32());
|
||||||
@ -6239,8 +6242,9 @@ END_VARLEN_CASE
|
|||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_EXCEPTION)
|
BEGIN_CASE(JSOP_EXCEPTION)
|
||||||
PUSH_COPY(cx->getPendingException());
|
JS_ASSERT(cx->throwing);
|
||||||
cx->clearPendingException();
|
PUSH_COPY(cx->exception);
|
||||||
|
cx->throwing = JS_FALSE;
|
||||||
#if defined(JS_TRACER) && defined(JS_METHODJIT)
|
#if defined(JS_TRACER) && defined(JS_METHODJIT)
|
||||||
if (interpMode == JSINTERP_PROFILE) {
|
if (interpMode == JSINTERP_PROFILE) {
|
||||||
leaveOnSafePoint = true;
|
leaveOnSafePoint = true;
|
||||||
@ -6255,24 +6259,19 @@ BEGIN_CASE(JSOP_FINALLY)
|
|||||||
END_CASE(JSOP_FINALLY)
|
END_CASE(JSOP_FINALLY)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_THROWING)
|
BEGIN_CASE(JSOP_THROWING)
|
||||||
{
|
JS_ASSERT(!cx->throwing);
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
cx->throwing = JS_TRUE;
|
||||||
Value v;
|
POP_COPY_TO(cx->exception);
|
||||||
POP_COPY_TO(v);
|
|
||||||
cx->setPendingException(v);
|
|
||||||
}
|
|
||||||
END_CASE(JSOP_THROWING)
|
END_CASE(JSOP_THROWING)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_THROW)
|
BEGIN_CASE(JSOP_THROW)
|
||||||
{
|
JS_ASSERT(!cx->throwing);
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
|
||||||
CHECK_BRANCH();
|
CHECK_BRANCH();
|
||||||
Value v;
|
cx->throwing = JS_TRUE;
|
||||||
POP_COPY_TO(v);
|
POP_COPY_TO(cx->exception);
|
||||||
cx->setPendingException(v);
|
|
||||||
/* let the code at error try to catch the exception. */
|
/* let the code at error try to catch the exception. */
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
BEGIN_CASE(JSOP_SETLOCALPOP)
|
BEGIN_CASE(JSOP_SETLOCALPOP)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -6348,7 +6347,8 @@ BEGIN_CASE(JSOP_DEBUGGER)
|
|||||||
interpReturnOK = JS_TRUE;
|
interpReturnOK = JS_TRUE;
|
||||||
goto forced_return;
|
goto forced_return;
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
cx->setPendingException(rval);
|
cx->throwing = JS_TRUE;
|
||||||
|
cx->exception = rval;
|
||||||
goto error;
|
goto error;
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
@ -6720,7 +6720,7 @@ END_CASE(JSOP_LEAVEBLOCK)
|
|||||||
#if JS_HAS_GENERATORS
|
#if JS_HAS_GENERATORS
|
||||||
BEGIN_CASE(JSOP_GENERATOR)
|
BEGIN_CASE(JSOP_GENERATOR)
|
||||||
{
|
{
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
JS_ASSERT(!cx->throwing);
|
||||||
regs.pc += JSOP_GENERATOR_LENGTH;
|
regs.pc += JSOP_GENERATOR_LENGTH;
|
||||||
JSObject *obj = js_NewGenerator(cx);
|
JSObject *obj = js_NewGenerator(cx);
|
||||||
if (!obj)
|
if (!obj)
|
||||||
@ -6734,7 +6734,7 @@ BEGIN_CASE(JSOP_GENERATOR)
|
|||||||
}
|
}
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_YIELD)
|
BEGIN_CASE(JSOP_YIELD)
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
JS_ASSERT(!cx->throwing);
|
||||||
JS_ASSERT(regs.fp->isFunctionFrame() && !regs.fp->isEvalFrame());
|
JS_ASSERT(regs.fp->isFunctionFrame() && !regs.fp->isEvalFrame());
|
||||||
if (cx->generatorFor(regs.fp)->state == JSGEN_CLOSING) {
|
if (cx->generatorFor(regs.fp)->state == JSGEN_CLOSING) {
|
||||||
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD,
|
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD,
|
||||||
@ -6830,7 +6830,7 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
error:
|
error:
|
||||||
JS_ASSERT(cx->regs == ®s);
|
JS_ASSERT(cx->regs == ®s);
|
||||||
#ifdef JS_TRACER
|
#ifdef JS_TRACER
|
||||||
if (regs.fp->hasImacropc() && cx->isExceptionPending()) {
|
if (regs.fp->hasImacropc() && cx->throwing) {
|
||||||
// Handle exceptions as if they came from the imacro-calling pc.
|
// Handle exceptions as if they came from the imacro-calling pc.
|
||||||
regs.pc = regs.fp->imacropc();
|
regs.pc = regs.fp->imacropc();
|
||||||
regs.fp->clearImacropc();
|
regs.fp->clearImacropc();
|
||||||
@ -6854,7 +6854,7 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
# endif
|
# endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!cx->isExceptionPending()) {
|
if (!cx->throwing) {
|
||||||
/* This is an error, not a catchable exception, quit the frame ASAP. */
|
/* This is an error, not a catchable exception, quit the frame ASAP. */
|
||||||
interpReturnOK = JS_FALSE;
|
interpReturnOK = JS_FALSE;
|
||||||
} else {
|
} else {
|
||||||
@ -6872,15 +6872,15 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
switch (handler(cx, script, regs.pc, Jsvalify(&rval),
|
switch (handler(cx, script, regs.pc, Jsvalify(&rval),
|
||||||
cx->debugHooks->throwHookData)) {
|
cx->debugHooks->throwHookData)) {
|
||||||
case JSTRAP_ERROR:
|
case JSTRAP_ERROR:
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
goto error;
|
goto error;
|
||||||
case JSTRAP_RETURN:
|
case JSTRAP_RETURN:
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
regs.fp->setReturnValue(rval);
|
regs.fp->setReturnValue(rval);
|
||||||
interpReturnOK = JS_TRUE;
|
interpReturnOK = JS_TRUE;
|
||||||
goto forced_return;
|
goto forced_return;
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
cx->setPendingException(rval);
|
cx->exception = rval;
|
||||||
case JSTRAP_CONTINUE:
|
case JSTRAP_CONTINUE:
|
||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
@ -6943,12 +6943,12 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
case JSTRY_CATCH:
|
case JSTRY_CATCH:
|
||||||
#if JS_HAS_GENERATORS
|
#if JS_HAS_GENERATORS
|
||||||
/* Catch cannot intercept the closing of a generator. */
|
/* Catch cannot intercept the closing of a generator. */
|
||||||
if (JS_UNLIKELY(cx->getPendingException().isMagic(JS_GENERATOR_CLOSING)))
|
if (JS_UNLIKELY(cx->exception.isMagic(JS_GENERATOR_CLOSING)))
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't clear exceptions to save cx->exception from GC
|
* Don't clear cx->throwing to save cx->exception from GC
|
||||||
* until it is pushed to the stack via [exception] in the
|
* until it is pushed to the stack via [exception] in the
|
||||||
* catch block.
|
* catch block.
|
||||||
*/
|
*/
|
||||||
@ -6961,21 +6961,22 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
* [retsub] should rethrow the exception.
|
* [retsub] should rethrow the exception.
|
||||||
*/
|
*/
|
||||||
PUSH_BOOLEAN(true);
|
PUSH_BOOLEAN(true);
|
||||||
PUSH_COPY(cx->getPendingException());
|
PUSH_COPY(cx->exception);
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
len = 0;
|
len = 0;
|
||||||
DO_NEXT_OP(len);
|
DO_NEXT_OP(len);
|
||||||
|
|
||||||
case JSTRY_ITER: {
|
case JSTRY_ITER: {
|
||||||
/* This is similar to JSOP_ENDITER in the interpreter loop. */
|
/* This is similar to JSOP_ENDITER in the interpreter loop. */
|
||||||
JS_ASSERT(js_GetOpcode(cx, regs.fp->script(), regs.pc) == JSOP_ENDITER);
|
JS_ASSERT(js_GetOpcode(cx, regs.fp->script(), regs.pc) == JSOP_ENDITER);
|
||||||
Value v = cx->getPendingException();
|
AutoValueRooter tvr(cx, cx->exception);
|
||||||
cx->clearPendingException();
|
cx->throwing = false;
|
||||||
ok = js_CloseIterator(cx, ®s.sp[-1].toObject());
|
ok = js_CloseIterator(cx, ®s.sp[-1].toObject());
|
||||||
regs.sp -= 1;
|
regs.sp -= 1;
|
||||||
if (!ok)
|
if (!ok)
|
||||||
goto error;
|
goto error;
|
||||||
cx->setPendingException(v);
|
cx->throwing = true;
|
||||||
|
cx->exception = tvr.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (++tn != tnlimit);
|
} while (++tn != tnlimit);
|
||||||
@ -6987,9 +6988,9 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
*/
|
*/
|
||||||
interpReturnOK = JS_FALSE;
|
interpReturnOK = JS_FALSE;
|
||||||
#if JS_HAS_GENERATORS
|
#if JS_HAS_GENERATORS
|
||||||
if (JS_UNLIKELY(cx->isExceptionPending() &&
|
if (JS_UNLIKELY(cx->throwing &&
|
||||||
cx->getPendingException().isMagic(JS_GENERATOR_CLOSING))) {
|
cx->exception.isMagic(JS_GENERATOR_CLOSING))) {
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
interpReturnOK = JS_TRUE;
|
interpReturnOK = JS_TRUE;
|
||||||
regs.fp->clearReturnValue();
|
regs.fp->clearReturnValue();
|
||||||
}
|
}
|
||||||
@ -7004,7 +7005,7 @@ END_CASE(JSOP_ARRAYPUSH)
|
|||||||
* When a trap handler returns JSTRAP_RETURN, we jump here with
|
* When a trap handler returns JSTRAP_RETURN, we jump here with
|
||||||
* interpReturnOK set to true bypassing any finally blocks.
|
* interpReturnOK set to true bypassing any finally blocks.
|
||||||
*/
|
*/
|
||||||
interpReturnOK &= js_UnwindScope(cx, 0, interpReturnOK || cx->isExceptionPending());
|
interpReturnOK &= js_UnwindScope(cx, 0, interpReturnOK || cx->throwing);
|
||||||
JS_ASSERT(regs.sp == regs.fp->base());
|
JS_ASSERT(regs.sp == regs.fp->base());
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
@ -767,7 +767,7 @@ js_ThrowStopIteration(JSContext *cx)
|
|||||||
|
|
||||||
JS_ASSERT(!JS_IsExceptionPending(cx));
|
JS_ASSERT(!JS_IsExceptionPending(cx));
|
||||||
if (js_FindClassObject(cx, NULL, JSProto_StopIteration, &v))
|
if (js_FindClassObject(cx, NULL, JSProto_StopIteration, &v))
|
||||||
cx->setPendingException(v);
|
SetPendingException(cx, v);
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1017,10 +1017,12 @@ js_IteratorMore(JSContext *cx, JSObject *iterobj, Value *rval)
|
|||||||
return false;
|
return false;
|
||||||
if (!ExternalInvoke(cx, iterobj, *rval, 0, NULL, rval)) {
|
if (!ExternalInvoke(cx, iterobj, *rval, 0, NULL, rval)) {
|
||||||
/* Check for StopIteration. */
|
/* Check for StopIteration. */
|
||||||
if (!cx->isExceptionPending() || !js_ValueIsStopIteration(cx->getPendingException()))
|
if (!cx->throwing || !js_ValueIsStopIteration(cx->exception))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
cx->clearPendingException();
|
/* Inline JS_ClearPendingException(cx). */
|
||||||
|
cx->throwing = JS_FALSE;
|
||||||
|
cx->exception.setUndefined();
|
||||||
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
|
cx->iterValue.setMagic(JS_NO_ITER_VALUE);
|
||||||
rval->setBoolean(false);
|
rval->setBoolean(false);
|
||||||
return true;
|
return true;
|
||||||
@ -1284,13 +1286,13 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case JSGENOP_THROW:
|
case JSGENOP_THROW:
|
||||||
cx->setPendingException(arg);
|
SetPendingException(cx, arg);
|
||||||
gen->state = JSGEN_RUNNING;
|
gen->state = JSGEN_RUNNING;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
JS_ASSERT(op == JSGENOP_CLOSE);
|
JS_ASSERT(op == JSGENOP_CLOSE);
|
||||||
cx->setPendingException(MagicValue(JS_GENERATOR_CLOSING));
|
SetPendingException(cx, MagicValue(JS_GENERATOR_CLOSING));
|
||||||
gen->state = JSGEN_CLOSING;
|
gen->state = JSGEN_CLOSING;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1348,7 +1350,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
|
|||||||
if (gen->floatingFrame()->isYielding()) {
|
if (gen->floatingFrame()->isYielding()) {
|
||||||
/* Yield cannot fail, throw or be called on closing. */
|
/* Yield cannot fail, throw or be called on closing. */
|
||||||
JS_ASSERT(ok);
|
JS_ASSERT(ok);
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
JS_ASSERT(!cx->throwing);
|
||||||
JS_ASSERT(gen->state == JSGEN_RUNNING);
|
JS_ASSERT(gen->state == JSGEN_RUNNING);
|
||||||
JS_ASSERT(op != JSGENOP_CLOSE);
|
JS_ASSERT(op != JSGENOP_CLOSE);
|
||||||
genfp->clearYielding();
|
genfp->clearYielding();
|
||||||
@ -1434,7 +1436,7 @@ generator_op(JSContext *cx, JSGeneratorOp op, Value *vp, uintN argc)
|
|||||||
case JSGENOP_SEND:
|
case JSGENOP_SEND:
|
||||||
return js_ThrowStopIteration(cx);
|
return js_ThrowStopIteration(cx);
|
||||||
case JSGENOP_THROW:
|
case JSGENOP_THROW:
|
||||||
cx->setPendingException(argc >= 1 ? vp[2] : UndefinedValue());
|
SetPendingException(cx, argc >= 1 ? vp[2] : UndefinedValue());
|
||||||
return JS_FALSE;
|
return JS_FALSE;
|
||||||
default:
|
default:
|
||||||
JS_ASSERT(op == JSGENOP_CLOSE);
|
JS_ASSERT(op == JSGENOP_CLOSE);
|
||||||
|
@ -1667,7 +1667,7 @@ class RegExpGuard
|
|||||||
* @param checkMetaChars Look for regexp metachars in the pattern string.
|
* @param checkMetaChars Look for regexp metachars in the pattern string.
|
||||||
* @return Whether flat matching could be used.
|
* @return Whether flat matching could be used.
|
||||||
*
|
*
|
||||||
* N.B. tryFlatMatch returns NULL on OOM, so the caller must check cx->isExceptionPending().
|
* N.B. tryFlatMatch returns NULL on OOM, so the caller must check cx->throwing.
|
||||||
*/
|
*/
|
||||||
const FlatMatch *
|
const FlatMatch *
|
||||||
tryFlatMatch(JSContext *cx, JSString *textstr, uintN optarg, uintN argc,
|
tryFlatMatch(JSContext *cx, JSString *textstr, uintN optarg, uintN argc,
|
||||||
@ -1856,7 +1856,7 @@ str_match(JSContext *cx, uintN argc, Value *vp)
|
|||||||
return false;
|
return false;
|
||||||
if (const FlatMatch *fm = g.tryFlatMatch(cx, str, 1, argc))
|
if (const FlatMatch *fm = g.tryFlatMatch(cx, str, 1, argc))
|
||||||
return BuildFlatMatchArray(cx, str, *fm, vp);
|
return BuildFlatMatchArray(cx, str, *fm, vp);
|
||||||
if (cx->isExceptionPending()) /* from tryFlatMatch */
|
if (cx->throwing) /* from tryFlatMatch */
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const RegExpPair *rep = g.normalizeRegExp(false, 1, argc, vp);
|
const RegExpPair *rep = g.normalizeRegExp(false, 1, argc, vp);
|
||||||
@ -1888,7 +1888,7 @@ str_search(JSContext *cx, uintN argc, Value *vp)
|
|||||||
vp->setInt32(fm->match());
|
vp->setInt32(fm->match());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (cx->isExceptionPending()) /* from tryFlatMatch */
|
if (cx->throwing) /* from tryFlatMatch */
|
||||||
return false;
|
return false;
|
||||||
const RegExpPair *rep = g.normalizeRegExp(false, 1, argc, vp);
|
const RegExpPair *rep = g.normalizeRegExp(false, 1, argc, vp);
|
||||||
if (!rep)
|
if (!rep)
|
||||||
@ -2501,7 +2501,7 @@ js::str_replace(JSContext *cx, uintN argc, Value *vp)
|
|||||||
|
|
||||||
const FlatMatch *fm = rdata.g.tryFlatMatch(cx, rdata.str, optarg, argc, false);
|
const FlatMatch *fm = rdata.g.tryFlatMatch(cx, rdata.str, optarg, argc, false);
|
||||||
if (!fm) {
|
if (!fm) {
|
||||||
if (cx->isExceptionPending()) /* oom in RopeMatch in tryFlatMatch */
|
if (cx->throwing) /* oom in RopeMatch in tryFlatMatch */
|
||||||
return false;
|
return false;
|
||||||
JS_ASSERT_IF(!rdata.g.hasRegExpPair(), argc > optarg);
|
JS_ASSERT_IF(!rdata.g.hasRegExpPair(), argc > optarg);
|
||||||
return str_replace_regexp(cx, argc, vp, rdata);
|
return str_replace_regexp(cx, argc, vp, rdata);
|
||||||
|
@ -6568,7 +6568,7 @@ ExecuteTree(JSContext* cx, TreeFragment* f, uintN& inlineCallCount,
|
|||||||
|
|
||||||
*lrp = state.innermost;
|
*lrp = state.innermost;
|
||||||
bool ok = !(state.builtinStatus & BUILTIN_ERROR);
|
bool ok = !(state.builtinStatus & BUILTIN_ERROR);
|
||||||
JS_ASSERT_IF(cx->isExceptionPending(), !ok);
|
JS_ASSERT_IF(cx->throwing, !ok);
|
||||||
|
|
||||||
size_t iters = tm->iterationCounter;
|
size_t iters = tm->iterationCounter;
|
||||||
|
|
||||||
@ -16592,7 +16592,7 @@ RecordTracePoint(JSContext* cx, uintN& inlineCallCount, bool* blacklist, bool ex
|
|||||||
if (!Interpret(cx, fp, inlineCallCount, JSINTERP_RECORD))
|
if (!Interpret(cx, fp, inlineCallCount, JSINTERP_RECORD))
|
||||||
return TPA_Error;
|
return TPA_Error;
|
||||||
|
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
JS_ASSERT(!cx->throwing);
|
||||||
|
|
||||||
return TPA_RanStuff;
|
return TPA_RanStuff;
|
||||||
}
|
}
|
||||||
@ -16759,7 +16759,7 @@ MonitorTracePoint(JSContext *cx, uintN& inlineCallCount, bool* blacklist,
|
|||||||
if (!Interpret(cx, cx->fp(), inlineCallCount, JSINTERP_PROFILE))
|
if (!Interpret(cx, cx->fp(), inlineCallCount, JSINTERP_PROFILE))
|
||||||
return TPA_Error;
|
return TPA_Error;
|
||||||
|
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
JS_ASSERT(!cx->throwing);
|
||||||
|
|
||||||
return TPA_RanStuff;
|
return TPA_RanStuff;
|
||||||
}
|
}
|
||||||
|
@ -358,8 +358,7 @@ AutoCompartment::enter()
|
|||||||
JSObject *scopeChain = target->getGlobal();
|
JSObject *scopeChain = target->getGlobal();
|
||||||
JS_ASSERT(scopeChain->isNative());
|
JS_ASSERT(scopeChain->isNative());
|
||||||
frame.construct();
|
frame.construct();
|
||||||
if (!context->stack().pushDummyFrame(context, *scopeChain, &frame.ref()) ||
|
if (!context->stack().pushDummyFrame(context, *scopeChain, &frame.ref())) {
|
||||||
!destination->wrapException(context)) {
|
|
||||||
frame.destroy();
|
frame.destroy();
|
||||||
context->compartment = origin;
|
context->compartment = origin;
|
||||||
return false;
|
return false;
|
||||||
|
@ -1720,9 +1720,16 @@ mjit::Compiler::generateMethod()
|
|||||||
END_CASE(JSOP_INSTANCEOF)
|
END_CASE(JSOP_INSTANCEOF)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_EXCEPTION)
|
BEGIN_CASE(JSOP_EXCEPTION)
|
||||||
prepareStubCall(Uses(0));
|
{
|
||||||
INLINE_STUBCALL(stubs::Exception);
|
JS_STATIC_ASSERT(sizeof(cx->throwing) == 4);
|
||||||
frame.pushSynced();
|
RegisterID reg = frame.allocReg();
|
||||||
|
masm.loadPtr(FrameAddress(offsetof(VMFrame, cx)), reg);
|
||||||
|
masm.store32(Imm32(JS_FALSE), Address(reg, offsetof(JSContext, throwing)));
|
||||||
|
|
||||||
|
Address excn(reg, offsetof(JSContext, exception));
|
||||||
|
frame.freeReg(reg);
|
||||||
|
frame.push(excn);
|
||||||
|
}
|
||||||
END_CASE(JSOP_EXCEPTION)
|
END_CASE(JSOP_EXCEPTION)
|
||||||
|
|
||||||
BEGIN_CASE(JSOP_LINENO)
|
BEGIN_CASE(JSOP_LINENO)
|
||||||
|
@ -81,7 +81,7 @@ FindExceptionHandler(JSContext *cx)
|
|||||||
JSScript *script = fp->script();
|
JSScript *script = fp->script();
|
||||||
|
|
||||||
top:
|
top:
|
||||||
if (cx->isExceptionPending() && JSScript::isValidOffset(script->trynotesOffset)) {
|
if (cx->throwing && JSScript::isValidOffset(script->trynotesOffset)) {
|
||||||
// The PC is updated before every stub call, so we can use it here.
|
// The PC is updated before every stub call, so we can use it here.
|
||||||
unsigned offset = cx->regs->pc - script->main;
|
unsigned offset = cx->regs->pc - script->main;
|
||||||
|
|
||||||
@ -119,7 +119,7 @@ top:
|
|||||||
|
|
||||||
#if JS_HAS_GENERATORS
|
#if JS_HAS_GENERATORS
|
||||||
/* Catch cannot intercept the closing of a generator. */
|
/* Catch cannot intercept the closing of a generator. */
|
||||||
if (JS_UNLIKELY(cx->getPendingException().isMagic(JS_GENERATOR_CLOSING)))
|
if (JS_UNLIKELY(cx->exception.isMagic(JS_GENERATOR_CLOSING)))
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -136,9 +136,9 @@ top:
|
|||||||
* [retsub] should rethrow the exception.
|
* [retsub] should rethrow the exception.
|
||||||
*/
|
*/
|
||||||
cx->regs->sp[0].setBoolean(true);
|
cx->regs->sp[0].setBoolean(true);
|
||||||
cx->regs->sp[1] = cx->getPendingException();
|
cx->regs->sp[1] = cx->exception;
|
||||||
cx->regs->sp += 2;
|
cx->regs->sp += 2;
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
return pc;
|
return pc;
|
||||||
|
|
||||||
case JSTRY_ITER:
|
case JSTRY_ITER:
|
||||||
@ -150,14 +150,15 @@ top:
|
|||||||
* adjustment and regs.sp[1] after, to save and restore the
|
* adjustment and regs.sp[1] after, to save and restore the
|
||||||
* pending exception.
|
* pending exception.
|
||||||
*/
|
*/
|
||||||
Value v = cx->getPendingException();
|
AutoValueRooter tvr(cx, cx->exception);
|
||||||
JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == JSOP_ENDITER);
|
JS_ASSERT(js_GetOpcode(cx, fp->script(), pc) == JSOP_ENDITER);
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
ok = !!js_CloseIterator(cx, &cx->regs->sp[-1].toObject());
|
ok = !!js_CloseIterator(cx, &cx->regs->sp[-1].toObject());
|
||||||
cx->regs->sp -= 1;
|
cx->regs->sp -= 1;
|
||||||
if (!ok)
|
if (!ok)
|
||||||
goto top;
|
goto top;
|
||||||
cx->setPendingException(v);
|
cx->throwing = JS_TRUE;
|
||||||
|
cx->exception = tvr.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -501,17 +502,17 @@ js_InternalThrow(VMFrame &f)
|
|||||||
switch (handler(cx, cx->fp()->script(), cx->regs->pc, Jsvalify(&rval),
|
switch (handler(cx, cx->fp()->script(), cx->regs->pc, Jsvalify(&rval),
|
||||||
cx->debugHooks->throwHookData)) {
|
cx->debugHooks->throwHookData)) {
|
||||||
case JSTRAP_ERROR:
|
case JSTRAP_ERROR:
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case JSTRAP_RETURN:
|
case JSTRAP_RETURN:
|
||||||
cx->clearPendingException();
|
cx->throwing = JS_FALSE;
|
||||||
cx->fp()->setReturnValue(rval);
|
cx->fp()->setReturnValue(rval);
|
||||||
return JS_FUNC_TO_DATA_PTR(void *,
|
return JS_FUNC_TO_DATA_PTR(void *,
|
||||||
cx->jaegerCompartment()->forceReturnTrampoline());
|
cx->jaegerCompartment()->forceReturnTrampoline());
|
||||||
|
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
cx->setPendingException(rval);
|
cx->exception = rval;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -530,7 +531,7 @@ js_InternalThrow(VMFrame &f)
|
|||||||
// but we shouldn't return from a JS function, because we're not in a
|
// but we shouldn't return from a JS function, because we're not in a
|
||||||
// JS function.
|
// JS function.
|
||||||
bool lastFrame = (f.entryfp == f.fp());
|
bool lastFrame = (f.entryfp == f.fp());
|
||||||
js_UnwindScope(cx, 0, cx->isExceptionPending());
|
js_UnwindScope(cx, 0, cx->throwing);
|
||||||
|
|
||||||
// For consistency with Interpret(), always run the script epilogue.
|
// For consistency with Interpret(), always run the script epilogue.
|
||||||
// This simplifies interactions with RunTracer(), since it can assume
|
// This simplifies interactions with RunTracer(), since it can assume
|
||||||
@ -657,7 +658,7 @@ HandleErrorInExcessFrame(VMFrame &f, JSStackFrame *stopFp, bool searchedTopmostF
|
|||||||
JS_ASSERT(!fp->hasImacropc());
|
JS_ASSERT(!fp->hasImacropc());
|
||||||
|
|
||||||
/* If there's an exception and a handler, set the pc and leave. */
|
/* If there's an exception and a handler, set the pc and leave. */
|
||||||
if (cx->isExceptionPending()) {
|
if (cx->throwing) {
|
||||||
jsbytecode *pc = FindExceptionHandler(cx);
|
jsbytecode *pc = FindExceptionHandler(cx);
|
||||||
if (pc) {
|
if (pc) {
|
||||||
cx->regs->pc = pc;
|
cx->regs->pc = pc;
|
||||||
@ -671,7 +672,7 @@ HandleErrorInExcessFrame(VMFrame &f, JSStackFrame *stopFp, bool searchedTopmostF
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
/* Unwind and return. */
|
/* Unwind and return. */
|
||||||
returnOK &= bool(js_UnwindScope(cx, 0, returnOK || cx->isExceptionPending()));
|
returnOK &= bool(js_UnwindScope(cx, 0, returnOK || cx->throwing));
|
||||||
returnOK = ScriptEpilogue(cx, fp, returnOK);
|
returnOK = ScriptEpilogue(cx, fp, returnOK);
|
||||||
InlineReturn(f);
|
InlineReturn(f);
|
||||||
}
|
}
|
||||||
@ -972,7 +973,7 @@ RunTracer(VMFrame &f)
|
|||||||
|
|
||||||
// Even though ExecuteTree() bypasses the interpreter, it should propagate
|
// Even though ExecuteTree() bypasses the interpreter, it should propagate
|
||||||
// error failures correctly.
|
// error failures correctly.
|
||||||
JS_ASSERT_IF(cx->isExceptionPending(), tpa == TPA_Error);
|
JS_ASSERT_IF(cx->throwing, tpa == TPA_Error);
|
||||||
|
|
||||||
f.fp() = cx->fp();
|
f.fp() = cx->fp();
|
||||||
JS_ASSERT(f.fp() == cx->fp());
|
JS_ASSERT(f.fp() == cx->fp());
|
||||||
|
@ -1291,11 +1291,12 @@ stubs::Debugger(VMFrame &f, jsbytecode *pc)
|
|||||||
switch (handler(f.cx, f.cx->fp()->script(), pc, Jsvalify(&rval),
|
switch (handler(f.cx, f.cx->fp()->script(), pc, Jsvalify(&rval),
|
||||||
f.cx->debugHooks->debuggerHandlerData)) {
|
f.cx->debugHooks->debuggerHandlerData)) {
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
f.cx->setPendingException(rval);
|
f.cx->throwing = JS_TRUE;
|
||||||
|
f.cx->exception = rval;
|
||||||
THROW();
|
THROW();
|
||||||
|
|
||||||
case JSTRAP_RETURN:
|
case JSTRAP_RETURN:
|
||||||
f.cx->clearPendingException();
|
f.cx->throwing = JS_FALSE;
|
||||||
f.cx->fp()->setReturnValue(rval);
|
f.cx->fp()->setReturnValue(rval);
|
||||||
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
||||||
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
||||||
@ -1307,7 +1308,7 @@ stubs::Debugger(VMFrame &f, jsbytecode *pc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case JSTRAP_ERROR:
|
case JSTRAP_ERROR:
|
||||||
f.cx->clearPendingException();
|
f.cx->throwing = JS_FALSE;
|
||||||
THROW();
|
THROW();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1351,11 +1352,12 @@ stubs::Trap(VMFrame &f, uint32 trapTypes)
|
|||||||
|
|
||||||
switch (result) {
|
switch (result) {
|
||||||
case JSTRAP_THROW:
|
case JSTRAP_THROW:
|
||||||
f.cx->setPendingException(rval);
|
f.cx->throwing = JS_TRUE;
|
||||||
|
f.cx->exception = rval;
|
||||||
THROW();
|
THROW();
|
||||||
|
|
||||||
case JSTRAP_RETURN:
|
case JSTRAP_RETURN:
|
||||||
f.cx->clearPendingException();
|
f.cx->throwing = JS_FALSE;
|
||||||
f.cx->fp()->setReturnValue(rval);
|
f.cx->fp()->setReturnValue(rval);
|
||||||
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
#if (defined(JS_NO_FASTCALL) && defined(JS_CPU_X86)) || defined(_WIN64)
|
||||||
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
*f.returnAddressLocation() = JS_FUNC_TO_DATA_PTR(void *,
|
||||||
@ -1367,7 +1369,7 @@ stubs::Trap(VMFrame &f, uint32 trapTypes)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case JSTRAP_ERROR:
|
case JSTRAP_ERROR:
|
||||||
f.cx->clearPendingException();
|
f.cx->throwing = JS_FALSE;
|
||||||
THROW();
|
THROW();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2333,8 +2335,9 @@ stubs::Throw(VMFrame &f)
|
|||||||
{
|
{
|
||||||
JSContext *cx = f.cx;
|
JSContext *cx = f.cx;
|
||||||
|
|
||||||
JS_ASSERT(!cx->isExceptionPending());
|
JS_ASSERT(!cx->throwing);
|
||||||
cx->setPendingException(f.regs.sp[-1]);
|
cx->throwing = JS_TRUE;
|
||||||
|
cx->exception = f.regs.sp[-1];
|
||||||
THROW();
|
THROW();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2767,12 +2770,6 @@ stubs::In(VMFrame &f)
|
|||||||
template void JS_FASTCALL stubs::DelElem<true>(VMFrame &f);
|
template void JS_FASTCALL stubs::DelElem<true>(VMFrame &f);
|
||||||
template void JS_FASTCALL stubs::DelElem<false>(VMFrame &f);
|
template void JS_FASTCALL stubs::DelElem<false>(VMFrame &f);
|
||||||
|
|
||||||
void JS_FASTCALL
|
|
||||||
stubs::Exception(VMFrame &f)
|
|
||||||
{
|
|
||||||
f.regs.sp[0] = f.cx->getPendingException();
|
|
||||||
f.cx->clearPendingException();
|
|
||||||
}
|
|
||||||
template <bool Clamped>
|
template <bool Clamped>
|
||||||
int32 JS_FASTCALL
|
int32 JS_FASTCALL
|
||||||
stubs::ConvertToTypedInt(JSContext *cx, Value *vp)
|
stubs::ConvertToTypedInt(JSContext *cx, Value *vp)
|
||||||
|
@ -224,8 +224,6 @@ void JS_FASTCALL Unbrand(VMFrame &f);
|
|||||||
template <bool strict> int32 JS_FASTCALL ConvertToTypedInt(JSContext *cx, Value *vp);
|
template <bool strict> int32 JS_FASTCALL ConvertToTypedInt(JSContext *cx, Value *vp);
|
||||||
void JS_FASTCALL ConvertToTypedFloat(JSContext *cx, Value *vp);
|
void JS_FASTCALL ConvertToTypedFloat(JSContext *cx, Value *vp);
|
||||||
|
|
||||||
void JS_FASTCALL Exception(VMFrame &f);
|
|
||||||
|
|
||||||
} /* namespace stubs */
|
} /* namespace stubs */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
Reference in New Issue
Block a user