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; 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) { if (pendingUnboxSlot) {
LIns* val_ins = get(pendingUnboxSlot); LIns* val_ins = get(pendingUnboxSlot);
/* /*
@ -14365,18 +14365,16 @@ TraceRecorder::record_JSOP_IMACOP()
} }
static JSBool FASTCALL 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, vp);
bool ok = js_ValueToIterator(cx, flags, tvr.addr());
if (!ok) { if (!ok) {
SetBuiltinError(cx); SetBuiltinError(cx);
return false; return false;
} }
*objp = &tvr.value().toObject();
return cx->tracerState->builtinStatus == 0; 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) 0, ACCSET_STORE_ANY)
JS_REQUIRES_STACK AbortableRecordingStatus JS_REQUIRES_STACK AbortableRecordingStatus
@ -14393,17 +14391,22 @@ TraceRecorder::record_JSOP_ITER()
enterDeepBailCall(); enterDeepBailCall();
LIns* objp_ins = w.allocp(sizeof(JSObject*)); LIns* vp_ins = w.allocp(sizeof(Value));
LIns* args[] = { objp_ins, w.immi(flags), obj_ins, cx_ins }; LIns* args[] = { vp_ins, w.immi(flags), obj_ins, cx_ins };
LIns* ok_ins = w.call(&ObjectToIterator_ci, args); LIns* ok_ins = w.call(&ObjectToIterator_ci, args);
// We need to guard on ok_ins, but this requires a snapshot of the state // We need to guard on ok_ins, but this requires a snapshot of the state
// after this op. monitorRecording will do it for us. // after this op. monitorRecording will do it for us.
pendingGuardCondition = ok_ins; 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; 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');