mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-02 06:22:20 +00:00
Fix for-in loops to be yieldable (r=mrbkap).
This commit is contained in:
parent
c624065cb5
commit
2a144173dd
@ -3776,7 +3776,7 @@ GettableNoteForNextOp(JSCodeGenerator *cg)
|
||||
{
|
||||
ptrdiff_t offset, target;
|
||||
jssrcnote *sn, *end;
|
||||
|
||||
|
||||
offset = 0;
|
||||
target = CG_OFFSET(cg);
|
||||
for (sn = CG_NOTES(cg), end = sn + CG_NOTE_COUNT(cg); sn < end;
|
||||
@ -4169,11 +4169,14 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
top = CG_OFFSET(cg);
|
||||
SET_STATEMENT_TOP(&stmtInfo, top);
|
||||
|
||||
#if JS_HAS_XML_SUPPORT
|
||||
/* Emit a prefix opcode if 'for each (... in ...)' was used. */
|
||||
if (pn->pn_op != JSOP_NOP && js_Emit1(cx, cg, pn->pn_op) < 0)
|
||||
/*
|
||||
* Emit a prefix bytecode to set flags distinguishing kinds of
|
||||
* for-in loops (for-in, for-each-in, destructuring for-in) for
|
||||
* the immediately subsequent JSOP_FOR* bytecode.
|
||||
*/
|
||||
JS_ASSERT(pn->pn_op != JSOP_NOP);
|
||||
if (js_Emit1(cx, cg, pn->pn_op) < 0)
|
||||
return JS_FALSE;
|
||||
#endif
|
||||
|
||||
/* Compile a JSOP_FOR* bytecode based on the left hand side. */
|
||||
emitIFEQ = JS_TRUE;
|
||||
@ -4724,7 +4727,7 @@ js_EmitTree(JSContext *cx, JSCodeGenerator *cg, JSParseNode *pn)
|
||||
* [throwing] opcode in front of the [setsp][gosub] finally sequence.
|
||||
* This opcode will restore cx->throwing to true before running the
|
||||
* finally.
|
||||
*
|
||||
*
|
||||
* For rethrowing after a try-catch(guard) without a finally, we emit
|
||||
* [throwing] before the [setsp][exception][throw] rethrow sequence.
|
||||
*/
|
||||
|
@ -2604,6 +2604,10 @@ interrupt:
|
||||
OBJ_DROP_PROPERTY(cx, obj2, prop);
|
||||
END_CASE(JSOP_IN)
|
||||
|
||||
BEGIN_CASE(JSOP_FORIN)
|
||||
flags = 0;
|
||||
END_CASE(JSOP_FORIN)
|
||||
|
||||
BEGIN_CASE(JSOP_FOREACH)
|
||||
flags = JSITER_FOREACH;
|
||||
END_CASE(JSOP_FOREACH)
|
||||
@ -2703,10 +2707,7 @@ interrupt:
|
||||
|
||||
/* Is this the first iteration ? */
|
||||
if (JSVAL_IS_NULL(rval)) {
|
||||
/*
|
||||
* Yes, and because rval is null we know JSOP_STARTITER stored
|
||||
* that slot, and we must use the new iteration protocol.
|
||||
*/
|
||||
/* Yes, use the new iteration protocol. */
|
||||
fp->pc = (jsbytecode *) sp[i-depth];
|
||||
iterobj = js_ValueToIterator(cx, OBJECT_TO_JSVAL(obj), flags);
|
||||
fp->pc = pc;
|
||||
@ -6077,15 +6078,12 @@ interrupt:
|
||||
#if JS_HAS_GENERATORS
|
||||
BEGIN_CASE(JSOP_STARTITER)
|
||||
/*
|
||||
* Start of a for-in or for-each-in loop: clear flags and push two
|
||||
* nulls. If this is a for-each-in loop, JSOP_FOREACH will follow
|
||||
* and set flags = JSITER_FOREACH. Push null instead of undefined
|
||||
* so that code at do_forinloop: can tell that this opcode pushed
|
||||
* the iterator slot, rather than a backward compatible JSOP_PUSH
|
||||
* that was emitted prior to the introduction of the new iteration
|
||||
* protocol.
|
||||
* Start of a for-in or for-each-in loop: push two nulls. Push
|
||||
* null instead of undefined so that code at do_forinloop: can
|
||||
* tell that this opcode pushed the iterator slot, rather than a
|
||||
* backward compatible JSOP_PUSH that was emitted prior to the
|
||||
* introduction of the new iteration protocol.
|
||||
*/
|
||||
flags = 0;
|
||||
sp[0] = sp[1] = JSVAL_NULL;
|
||||
sp += 2;
|
||||
END_CASE(JSOP_STARTITER)
|
||||
|
@ -472,3 +472,9 @@ OPDEF(JSOP_ENUMCONSTELEM, 214,"enumconstelem",NULL, 1, 3, 0, 3, JOF_BYTE|J
|
||||
* which must be moved down when the block pops.
|
||||
*/
|
||||
OPDEF(JSOP_LEAVEBLOCKEXPR,215,"leaveblockexpr",NULL, 3, 0, 0, 1, JOF_UINT16)
|
||||
|
||||
/*
|
||||
* This opcode prefixes one of JSOP_FOR{NAME,ARG,VAR,LOCAL,PROP,ELEM} in a
|
||||
* standard for-in loop. See also JSOP_FOREACH and JSOP_FOREACHKEYVAL.
|
||||
*/
|
||||
OPDEF(JSOP_FORIN, 216,"forin", NULL, 1, 0, 0, 0, JOF_BYTE)
|
||||
|
@ -2805,6 +2805,7 @@ Statement(JSContext *cx, JSTokenStream *ts, JSTreeContext *tc)
|
||||
*/
|
||||
if (pn1 && js_MatchToken(cx, ts, TOK_IN)) {
|
||||
stmtInfo.type = STMT_FOR_IN_LOOP;
|
||||
pn->pn_op = JSOP_FORIN;
|
||||
|
||||
/* Check that the left side of the 'in' is valid. */
|
||||
JS_ASSERT(!TOKEN_TYPE_IS_DECL(tt) || pn1->pn_type == tt);
|
||||
|
@ -200,7 +200,7 @@ JS_XDRFindClassById(JSXDRState *xdr, uint32 id);
|
||||
* before deserialization of bytecode. If the saved version does not match
|
||||
* the current version, abort deserialization and invalidate the file.
|
||||
*/
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 0)
|
||||
#define JSXDR_BYTECODE_VERSION (0xb973c0de - 2)
|
||||
|
||||
/*
|
||||
* Library-private functions.
|
||||
|
Loading…
x
Reference in New Issue
Block a user