Bug 704369: Move inc/dec emit. (r=Waldo)

This commit is contained in:
Chris Leary 2011-11-22 11:26:47 -08:00
parent 2c5efb6b54
commit 50972c49bb

View File

@ -6498,6 +6498,93 @@ EmitLogical(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return true;
}
static bool
EmitIncOrDec(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
/* Emit lvalue-specialized code for ++/-- operators. */
ParseNode *pn2 = pn->pn_kid;
JS_ASSERT(!pn2->isKind(PNK_RP));
JSOp op = pn->getOp();
switch (pn2->getKind()) {
default:
JS_ASSERT(pn2->isKind(PNK_NAME));
pn2->setOp(op);
if (!BindNameToSlot(cx, bce, pn2))
return JS_FALSE;
op = pn2->getOp();
if (op == JSOP_CALLEE) {
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
} else if (!pn2->pn_cookie.isFree()) {
jsatomid atomIndex = pn2->pn_cookie.asInteger();
EMIT_UINT16_IMM_OP(op, atomIndex);
} else {
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
if (js_CodeSpec[op].format & (JOF_INC | JOF_DEC)) {
if (!EmitNameIncDec(cx, pn2, op, bce))
return JS_FALSE;
} else {
if (!EmitAtomOp(cx, pn2, op, bce))
return JS_FALSE;
}
break;
}
if (pn2->isConst()) {
if (Emit1(cx, bce, JSOP_POS) < 0)
return JS_FALSE;
op = pn->getOp();
if (!(js_CodeSpec[op].format & JOF_POST)) {
if (Emit1(cx, bce, JSOP_ONE) < 0)
return JS_FALSE;
op = (js_CodeSpec[op].format & JOF_INC) ? JSOP_ADD : JSOP_SUB;
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
}
}
break;
case PNK_DOT:
if (!EmitPropIncDec(cx, pn2, op, bce))
return JS_FALSE;
break;
case PNK_LB:
if (!EmitElemIncDec(cx, pn2, op, bce))
return JS_FALSE;
break;
case PNK_LP:
if (!EmitTree(cx, bce, pn2))
return JS_FALSE;
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - pn2->pn_offset) < 0)
return JS_FALSE;
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
/*
* This is dead code for the decompiler, don't generate
* a decomposed version of the opcode. We do need to balance
* the stacks in the decomposed version.
*/
JS_ASSERT(js_CodeSpec[op].format & JOF_DECOMPOSE);
JS_ASSERT(js_CodeSpec[op].format & JOF_ELEM);
if (Emit1(cx, bce, (JSOp)1) < 0)
return JS_FALSE;
if (Emit1(cx, bce, JSOP_POP) < 0)
return JS_FALSE;
break;
#if JS_HAS_XML_SUPPORT
case PNK_XMLUNARY:
JS_ASSERT(!bce->inStrictMode());
JS_ASSERT(pn2->isOp(JSOP_SETXMLNAME));
if (!EmitTree(cx, bce, pn2->pn_kid))
return JS_FALSE;
if (Emit1(cx, bce, JSOP_BINDXMLNAME) < 0)
return JS_FALSE;
if (!EmitElemIncDec(cx, NULL, op, bce))
return JS_FALSE;
break;
#endif
}
return true;
}
JSBool
frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
@ -6901,87 +6988,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
case PNK_INC:
case PNK_DEC:
/* Emit lvalue-specialized code for ++/-- operators. */
pn2 = pn->pn_kid;
JS_ASSERT(!pn2->isKind(PNK_RP));
op = pn->getOp();
switch (pn2->getKind()) {
default:
JS_ASSERT(pn2->isKind(PNK_NAME));
pn2->setOp(op);
if (!BindNameToSlot(cx, bce, pn2))
return JS_FALSE;
op = pn2->getOp();
if (op == JSOP_CALLEE) {
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
} else if (!pn2->pn_cookie.isFree()) {
atomIndex = pn2->pn_cookie.asInteger();
EMIT_UINT16_IMM_OP(op, atomIndex);
} else {
JS_ASSERT(JOF_OPTYPE(op) == JOF_ATOM);
if (js_CodeSpec[op].format & (JOF_INC | JOF_DEC)) {
if (!EmitNameIncDec(cx, pn2, op, bce))
return JS_FALSE;
} else {
if (!EmitAtomOp(cx, pn2, op, bce))
return JS_FALSE;
}
break;
}
if (pn2->isConst()) {
if (Emit1(cx, bce, JSOP_POS) < 0)
return JS_FALSE;
op = pn->getOp();
if (!(js_CodeSpec[op].format & JOF_POST)) {
if (Emit1(cx, bce, JSOP_ONE) < 0)
return JS_FALSE;
op = (js_CodeSpec[op].format & JOF_INC) ? JSOP_ADD : JSOP_SUB;
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
}
}
break;
case PNK_DOT:
if (!EmitPropIncDec(cx, pn2, op, bce))
return JS_FALSE;
break;
case PNK_LB:
if (!EmitElemIncDec(cx, pn2, op, bce))
return JS_FALSE;
break;
case PNK_LP:
if (!EmitTree(cx, bce, pn2))
return JS_FALSE;
if (NewSrcNote2(cx, bce, SRC_PCBASE, bce->offset() - pn2->pn_offset) < 0)
return JS_FALSE;
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
/*
* This is dead code for the decompiler, don't generate
* a decomposed version of the opcode. We do need to balance
* the stacks in the decomposed version.
*/
JS_ASSERT(js_CodeSpec[op].format & JOF_DECOMPOSE);
JS_ASSERT(js_CodeSpec[op].format & JOF_ELEM);
if (Emit1(cx, bce, (JSOp)1) < 0)
return JS_FALSE;
if (Emit1(cx, bce, JSOP_POP) < 0)
return JS_FALSE;
break;
#if JS_HAS_XML_SUPPORT
case PNK_XMLUNARY:
JS_ASSERT(!bce->inStrictMode());
JS_ASSERT(pn2->isOp(JSOP_SETXMLNAME));
if (!EmitTree(cx, bce, pn2->pn_kid))
return JS_FALSE;
if (Emit1(cx, bce, JSOP_BINDXMLNAME) < 0)
return JS_FALSE;
if (!EmitElemIncDec(cx, NULL, op, bce))
return JS_FALSE;
break;
#endif
}
ok = EmitIncOrDec(cx, bce, pn);
break;
case PNK_DELETE: