Bug 704369: Factor logical emit. (r=Waldo)

This commit is contained in:
Chris Leary 2011-11-22 11:23:52 -08:00
Родитель 9decd4f9c4
Коммит 5ef6e04649
1 изменённых файлов: 47 добавлений и 45 удалений

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

@ -6437,62 +6437,64 @@ EmitLogical(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
* JSOP_AND converts the operand on the stack to boolean and jumps if false;
* otherwise it falls into the right operand's bytecode.
*/
if (pn->isArity(PN_BINARY)) {
if (!EmitTree(cx, bce, pn->pn_left))
return JS_FALSE;
return false;
ptrdiff_t top = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
if (top < 0)
return JS_FALSE;
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return JS_FALSE;
return false;
if (!EmitTree(cx, bce, pn->pn_right))
return JS_FALSE;
return false;
ptrdiff_t off = bce->offset();
jsbytecode *pc = bce->code(top);
CHECK_AND_SET_JUMP_OFFSET(cx, bce, pc, off - top);
*pc = pn->getOp();
} else {
JS_ASSERT(pn->isArity(PN_LIST));
JS_ASSERT(pn->pn_head->pn_next->pn_next);
/* Left-associative operator chain: avoid too much recursion. */
ParseNode *pn2 = pn->pn_head;
if (!EmitTree(cx, bce, pn2))
return JS_FALSE;
ptrdiff_t top = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
if (top < 0)
return JS_FALSE;
if (Emit1(cx, bce, JSOP_POP) < 0)
return JS_FALSE;
/* Emit nodes between the head and the tail. */
ptrdiff_t jmp = top;
while ((pn2 = pn2->pn_next)->pn_next) {
if (!EmitTree(cx, bce, pn2))
return JS_FALSE;
ptrdiff_t off = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
if (off < 0)
return JS_FALSE;
if (Emit1(cx, bce, JSOP_POP) < 0)
return JS_FALSE;
if (!SetBackPatchDelta(cx, bce, bce->code(jmp), off - jmp))
return JS_FALSE;
jmp = off;
}
if (!EmitTree(cx, bce, pn2))
return JS_FALSE;
pn2 = pn->pn_head;
ptrdiff_t off = bce->offset();
do {
jsbytecode *pc = bce->code(top);
ptrdiff_t tmp = GetJumpOffset(bce, pc);
CHECK_AND_SET_JUMP_OFFSET(cx, bce, pc, off - top);
*pc = pn->getOp();
top += tmp;
} while ((pn2 = pn2->pn_next)->pn_next);
return true;
}
JS_ASSERT(pn->isArity(PN_LIST));
JS_ASSERT(pn->pn_head->pn_next->pn_next);
/* Left-associative operator chain: avoid too much recursion. */
ParseNode *pn2 = pn->pn_head;
if (!EmitTree(cx, bce, pn2))
return false;
ptrdiff_t top = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
if (top < 0)
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
/* Emit nodes between the head and the tail. */
ptrdiff_t jmp = top;
while ((pn2 = pn2->pn_next)->pn_next) {
if (!EmitTree(cx, bce, pn2))
return false;
ptrdiff_t off = EmitJump(cx, bce, JSOP_BACKPATCH, 0);
if (off < 0)
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
if (!SetBackPatchDelta(cx, bce, bce->code(jmp), off - jmp))
return false;
jmp = off;
}
if (!EmitTree(cx, bce, pn2))
return false;
pn2 = pn->pn_head;
ptrdiff_t off = bce->offset();
do {
jsbytecode *pc = bce->code(top);
ptrdiff_t tmp = GetJumpOffset(bce, pc);
CHECK_AND_SET_JUMP_OFFSET(cx, bce, pc, off - top);
*pc = pn->getOp();
top += tmp;
} while ((pn2 = pn2->pn_next)->pn_next);
return true;
}