mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Unbox iterator after deep bail. Bug 618574, r=dvander.
This commit is contained in:
parent
201a276d97
commit
85ac72d3bd
@ -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;
|
||||
}
|
||||
|
20
js/src/tests/js1_8_5/regress/regress-618574.js
Normal file
20
js/src/tests/js1_8_5/regress/regress-618574.js
Normal 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');
|
Loading…
Reference in New Issue
Block a user