Bug 547911 - TM: Crash [@ js_CallIteratorNext] or "Assertion failure: !JSVAL_IS_PRIMITIVE(regs.sp[-2]), at ../jsops.cpp" or "Assertion failure: regs.sp == StackBase(fp), at ../jsops.cpp" with defineGetter, StopIteration. r=brendan.

This commit is contained in:
Jason Orendorff 2010-02-24 17:32:46 -08:00
parent b311c364f2
commit 4b5079e907
5 changed files with 31 additions and 2 deletions

View File

@ -3110,9 +3110,14 @@ js_Interpret(JSContext *cx)
error:
if (fp->imacpc && cx->throwing) {
// To keep things simple, we hard-code imacro exception handlers here.
if (*fp->imacpc == JSOP_NEXTITER && js_ValueIsStopIteration(cx->exception)) {
if (*fp->imacpc == JSOP_NEXTITER &&
InCustomIterNextTryRegion(regs.pc) &&
js_ValueIsStopIteration(cx->exception)) {
// If the other NEXTITER imacro, native_iter_next, throws
// StopIteration, do not catch it here. See bug 547911.
// pc may point to JSOP_DUP here due to bug 474854.
JS_ASSERT(*regs.pc == JSOP_CALL || *regs.pc == JSOP_DUP || *regs.pc == JSOP_TRUE);
JS_ASSERT(*regs.pc == JSOP_CALL || *regs.pc == JSOP_DUP);
cx->throwing = JS_FALSE;
cx->exception = JSVAL_VOID;
regs.sp[-1] = JSVAL_HOLE;

View File

@ -7701,6 +7701,13 @@ DeepBail(JSContext *cx)
state->deepBailSp = state->sp;
}
extern bool
InCustomIterNextTryRegion(jsbytecode *pc)
{
return nextiter_imacros.custom_iter_next <= pc &&
pc < nextiter_imacros.custom_iter_next + sizeof(nextiter_imacros.custom_iter_next);
}
JS_REQUIRES_STACK jsval&
TraceRecorder::argval(unsigned n) const
{

View File

@ -1518,6 +1518,9 @@ SetMaxCodeCacheBytes(JSContext* cx, uint32 bytes);
extern bool
NativeToValue(JSContext* cx, jsval& v, TraceType type, double* slot);
extern bool
InCustomIterNextTryRegion(jsbytecode *pc);
#ifdef MOZ_TRACEVIS
extern JS_FRIEND_API(bool)

View File

@ -0,0 +1,7 @@
a = b = c = d = 0;
__defineGetter__("e", function () { throw StopIteration; })
try {
for each(f in this) {}
} catch (exc) {
assertEq(exc, StopIteration);
}

View File

@ -0,0 +1,7 @@
var obj = {a: 0, b: 0, c: 0, d: 0, get e() { throw StopIteration; }};
try {
for each (x in obj) {}
FAIL;
} catch (exc) {
assertEq(exc, StopIteration);
}