Fix for-in loops to be yieldable (r=mrbkap).

This commit is contained in:
brendan%mozilla.org 2006-09-09 22:43:11 +00:00
Родитель c624065cb5
Коммит 2a144173dd
5 изменённых файлов: 27 добавлений и 19 удалений

Просмотреть файл

@ -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.