Unbox iterator after deep bail. Bug 618574, r=dvander.

This commit is contained in:
Jason Orendorff 2010-12-16 14:59:50 -08:00
parent 201a276d97
commit 85ac72d3bd
2 changed files with 33 additions and 10 deletions

View File

@ -7194,7 +7194,7 @@ TraceRecorder::monitorRecording(JSOp op)
pendingGuardCondition = NULL;
}
/* Handle one-shot request to unbox the result of a property get. */
/* Handle one-shot request to unbox the result of a property get or ObjectToIterator. */
if (pendingUnboxSlot) {
LIns* val_ins = get(pendingUnboxSlot);
/*
@ -14365,18 +14365,16 @@ TraceRecorder::record_JSOP_IMACOP()
}
static JSBool FASTCALL
ObjectToIterator(JSContext* cx, JSObject *obj, int32 flags, JSObject **objp)
ObjectToIterator(JSContext* cx, JSObject *obj, int32 flags, Value* vp)
{
AutoValueRooter tvr(cx, ObjectValue(*obj));
bool ok = js_ValueToIterator(cx, flags, tvr.addr());
bool ok = js_ValueToIterator(cx, flags, vp);
if (!ok) {
SetBuiltinError(cx);
return false;
}
*objp = &tvr.value().toObject();
return cx->tracerState->builtinStatus == 0;
}
JS_DEFINE_CALLINFO_4(static, BOOL_FAIL, ObjectToIterator, CONTEXT, OBJECT, INT32, OBJECTPTR,
JS_DEFINE_CALLINFO_4(static, BOOL_FAIL, ObjectToIterator, CONTEXT, OBJECT, INT32, VALUEPTR,
0, ACCSET_STORE_ANY)
JS_REQUIRES_STACK AbortableRecordingStatus
@ -14393,17 +14391,22 @@ TraceRecorder::record_JSOP_ITER()
enterDeepBailCall();
LIns* objp_ins = w.allocp(sizeof(JSObject*));
LIns* args[] = { objp_ins, w.immi(flags), obj_ins, cx_ins };
LIns* vp_ins = w.allocp(sizeof(Value));
LIns* args[] = { vp_ins, w.immi(flags), obj_ins, cx_ins };
LIns* ok_ins = w.call(&ObjectToIterator_ci, args);
// We need to guard on ok_ins, but this requires a snapshot of the state
// after this op. monitorRecording will do it for us.
pendingGuardCondition = ok_ins;
leaveDeepBailCall();
// ObjectToIterator can deep-bail without throwing, leaving a value of
// unknown type in *vp (it can be either a function or a non-function
// object). Use the same mechanism as finishGetProp to arrange for
// LeaveTree to deal with this value.
pendingUnboxSlot = cx->regs->sp - 1;
set(pendingUnboxSlot, w.name(w.lddAlloc(vp_ins), "iterval"));
stack(-1, w.name(w.ldpAlloc(objp_ins), "iterobj"));
leaveDeepBailCall();
return ARECORD_CONTINUE;
}

View File

@ -0,0 +1,20 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
* Contributors: Gary Kwong and Jason Orendorff
*/
var x = Proxy.create({
iterate: function () {
function f(){}
f.next = function () { throw StopIteration; }
return f;
}
});
for each (var e in [{}, {}, {}, {}, {}, {}, {}, {}, x]) {
for (var v in e) // do not assert
;
}
reportCompare(0, 0, 'ok');