Bug 507425 - cx->bailExit doesn't get cleared after a native setter. r=gal.

This commit is contained in:
Jason Orendorff 2009-07-30 15:21:23 -05:00
parent b68e0c3d76
commit 8ca27f5bc7
3 changed files with 21 additions and 3 deletions

View File

@ -2734,7 +2734,7 @@ js_NewString(JSContext *cx, jschar *chars, size_t length)
if (JS_ON_TRACE(cx)) { if (JS_ON_TRACE(cx)) {
/* /*
* If we can't leave the trace, signal OOM condition, otherwise * If we can't leave the trace, signal OOM condition, otherwise
* exit from trace and proceed with GC. * exit from trace before throwing.
*/ */
if (!js_CanLeaveTrace(cx)) if (!js_CanLeaveTrace(cx))
return NULL; return NULL;

View File

@ -5539,6 +5539,7 @@ ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount,
cx->interpState = state->prev; cx->interpState = state->prev;
JS_ASSERT(!cx->bailExit);
JS_ASSERT(lr->exitType != LOOP_EXIT || !lr->calldepth); JS_ASSERT(lr->exitType != LOOP_EXIT || !lr->calldepth);
tm->tracecx = NULL; tm->tracecx = NULL;
LeaveTree(*state, lr); LeaveTree(*state, lr);
@ -9090,8 +9091,10 @@ TraceRecorder::emitNativePropertyOp(JSScope* scope, JSScopeProperty* sprop, LIns
LIns* args[] = { vp_ins, INS_CONSTWORD(SPROP_USERID(sprop)), obj_ins, cx_ins }; LIns* args[] = { vp_ins, INS_CONSTWORD(SPROP_USERID(sprop)), obj_ins, cx_ins };
LIns* ok_ins = lir->insCall(ci, args); LIns* ok_ins = lir->insCall(ci, args);
// Unroot the vp. // Cleanup.
lir->insStorei(INS_CONSTPTR(NULL), cx_ins, offsetof(JSContext, nativeVp)); LIns* null_ins = INS_CONSTPTR(NULL);
lir->insStorei(null_ins, cx_ins, offsetof(JSContext, nativeVp));
lir->insStorei(null_ins, cx_ins, offsetof(JSContext, bailExit));
// Guard that the call succeeded and builtinStatus is still 0. // Guard that the call succeeded and builtinStatus is still 0.
// If the native op succeeds but we deep-bail here, the result value is // If the native op succeeds but we deep-bail here, the result value is

View File

@ -5600,6 +5600,21 @@ testNativeSetter.jitstats = {
}; };
test(testNativeSetter); test(testNativeSetter);
function testBug507425() {
var r = /x/;
for (var i = 0; i < 3; i++)
r.lastIndex = 0; // call a setter
var s = ';';
try {
for (i = 0; i < 80; i++)
s += s; // call js_CanLeaveTrace
} catch (exc) {
return "ok";
}
}
testBug507425.expected = "ok";
test(testBug507425);
/***************************************************************************** /*****************************************************************************
* * * *
* _____ _ _ _____ ______ _____ _______ * * _____ _ _ _____ ______ _____ _______ *