Bug 704369: Move do-while emit. (r=Waldo)
authorChris Leary <cdleary@mozilla.com>
Mon, 21 Nov 2011 17:54:57 -0800
changeset 82886 c57c39973ceaa6b81aa0291ba7c277de4f790a90
parent 82885 c27aaef8236b4093b4c24117b853bbda35d36cea
child 82887 29150131be3a5761b9a0e7a6b97dd8f98aa62c41
push idunknown
push userunknown
push dateunknown
reviewersWaldo
bugs704369
milestone11.0a1
Bug 704369: Move do-while emit. (r=Waldo)
js/src/frontend/BytecodeEmitter.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5894,16 +5894,67 @@ EmitFunc(JSContext *cx, BytecodeEmitter 
 
         /* Make blockChain determination quicker. */
         return EmitBlockChain(cx, bce) >= 0;
     }
 
     return true;
 }
 
+static bool
+EmitDo(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
+{
+    /* Emit an annotated nop so we know to decompile a 'do' keyword. */
+    ptrdiff_t noteIndex = NewSrcNote(cx, bce, SRC_WHILE);
+    if (noteIndex < 0 || Emit1(cx, bce, JSOP_NOP) < 0)
+        return JS_FALSE;
+
+    ptrdiff_t noteIndex2 = NewSrcNote(cx, bce, SRC_LOOPHEAD);
+    if (noteIndex2 < 0)
+        return JS_FALSE;
+
+    /* Compile the loop body. */
+    ptrdiff_t top = EmitTraceOp(cx, bce, pn->pn_left);
+    if (top < 0)
+        return JS_FALSE;
+    StmtInfo stmtInfo;
+    PushStatement(bce, &stmtInfo, STMT_DO_LOOP, top);
+    if (!EmitTree(cx, bce, pn->pn_left))
+        return JS_FALSE;
+
+    /* Set loop and enclosing label update offsets, for continue. */
+    ptrdiff_t off = bce->offset();
+    StmtInfo *stmt = &stmtInfo;
+    do {
+        stmt->update = off;
+    } while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL);
+
+    /* Compile the loop condition, now that continues know where to go. */
+    if (!EmitTree(cx, bce, pn->pn_right))
+        return JS_FALSE;
+
+    /*
+     * Since we use JSOP_IFNE for other purposes as well as for do-while
+     * loops, we must store 1 + (beq - top) in the SRC_WHILE note offset,
+     * and the decompiler must get that delta and decompile recursively.
+     */
+    ptrdiff_t beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
+    if (beq < 0)
+        return JS_FALSE;
+    /*
+     * Be careful: We must set noteIndex2 before noteIndex in case the noteIndex
+     * note gets bigger.
+     */
+    if (!SetSrcNoteOffset(cx, bce, noteIndex2, 0, beq - top))
+        return JS_FALSE;
+    if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, 1 + (off - top)))
+        return JS_FALSE;
+    return PopStatementBCE(cx, bce);
+}
+
 JSBool
 frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
 {
     JSBool useful, wantval;
     StmtInfo stmtInfo;
     StmtInfo *stmt;
     ptrdiff_t top, off, tmp, beq, jmp;
     ParseNode *pn2, *pn3;
@@ -6012,61 +6063,17 @@ frontend::EmitTree(JSContext *cx, Byteco
         if (!SetSrcNoteOffset(cx, bce, noteIndex2, 0, beq - top))
             return JS_FALSE;
         if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, beq - jmp))
             return JS_FALSE;
         ok = PopStatementBCE(cx, bce);
         break;
 
       case PNK_DOWHILE:
-        /* Emit an annotated nop so we know to decompile a 'do' keyword. */
-        noteIndex = NewSrcNote(cx, bce, SRC_WHILE);
-        if (noteIndex < 0 || Emit1(cx, bce, JSOP_NOP) < 0)
-            return JS_FALSE;
-
-        noteIndex2 = NewSrcNote(cx, bce, SRC_LOOPHEAD);
-        if (noteIndex2 < 0)
-            return JS_FALSE;
-
-        /* Compile the loop body. */
-        top = EmitTraceOp(cx, bce, pn->pn_left);
-        if (top < 0)
-            return JS_FALSE;
-        PushStatement(bce, &stmtInfo, STMT_DO_LOOP, top);
-        if (!EmitTree(cx, bce, pn->pn_left))
-            return JS_FALSE;
-
-        /* Set loop and enclosing label update offsets, for continue. */
-        off = bce->offset();
-        stmt = &stmtInfo;
-        do {
-            stmt->update = off;
-        } while ((stmt = stmt->down) != NULL && stmt->type == STMT_LABEL);
-
-        /* Compile the loop condition, now that continues know where to go. */
-        if (!EmitTree(cx, bce, pn->pn_right))
-            return JS_FALSE;
-
-        /*
-         * Since we use JSOP_IFNE for other purposes as well as for do-while
-         * loops, we must store 1 + (beq - top) in the SRC_WHILE note offset,
-         * and the decompiler must get that delta and decompile recursively.
-         */
-        beq = EmitJump(cx, bce, JSOP_IFNE, top - bce->offset());
-        if (beq < 0)
-            return JS_FALSE;
-        /*
-         * Be careful: We must set noteIndex2 before noteIndex in case the noteIndex
-         * note gets bigger.
-         */
-        if (!SetSrcNoteOffset(cx, bce, noteIndex2, 0, beq - top))
-            return JS_FALSE;
-        if (!SetSrcNoteOffset(cx, bce, noteIndex, 0, 1 + (off - top)))
-            return JS_FALSE;
-        ok = PopStatementBCE(cx, bce);
+        ok = EmitDo(cx, bce, pn);
         break;
 
       case PNK_FOR:
         ok = EmitFor(cx, bce, pn, top);
         break;
 
       case PNK_BREAK: {
         stmt = bce->topStmt;