Bug 704369: Move delete emit. (r=Waldo)

This commit is contained in:
Chris Leary 2011-11-22 11:09:15 -08:00
Родитель 2ebc35ec9f
Коммит 10ec98ae42
1 изменённых файлов: 72 добавлений и 61 удалений

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

@ -6265,10 +6265,80 @@ EmitStatement(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
return true;
}
static bool
EmitDelete(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
/*
* Under ECMA 3, deleting a non-reference returns true -- but alas we
* must evaluate the operand if it appears it might have side effects.
*/
ParseNode *pn2 = pn->pn_kid;
switch (pn2->getKind()) {
case PNK_NAME:
{
if (!BindNameToSlot(cx, bce, pn2))
return JS_FALSE;
JSOp op = pn2->getOp();
if (op == JSOP_FALSE) {
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
} else {
if (!EmitAtomOp(cx, pn2, op, bce))
return JS_FALSE;
}
break;
}
case PNK_DOT:
if (!EmitPropOp(cx, pn2, JSOP_DELPROP, bce, JS_FALSE))
return JS_FALSE;
break;
#if JS_HAS_XML_SUPPORT
case PNK_DBLDOT:
JS_ASSERT(!bce->inStrictMode());
if (!EmitElemOp(cx, pn2, JSOP_DELDESC, bce))
return JS_FALSE;
break;
#endif
case PNK_LB:
if (!EmitElemOp(cx, pn2, JSOP_DELELEM, bce))
return JS_FALSE;
break;
default:
{
/*
* If useless, just emit JSOP_TRUE; otherwise convert delete foo()
* to foo(), true (a comma expression, requiring SRC_PCDELTA).
*/
JSBool useful = JS_FALSE;
if (!CheckSideEffects(cx, bce, pn2, &useful))
return JS_FALSE;
ptrdiff_t off, noteIndex;
if (!useful) {
off = noteIndex = -1;
} else {
JS_ASSERT_IF(pn2->isKind(PNK_LP), !(pn2->pn_xflags & PNX_SETCALL));
if (!EmitTree(cx, bce, pn2))
return JS_FALSE;
off = bce->offset();
noteIndex = NewSrcNote2(cx, bce, SRC_PCDELTA, 0);
if (noteIndex < 0 || Emit1(cx, bce, JSOP_POP) < 0)
return JS_FALSE;
}
if (Emit1(cx, bce, JSOP_TRUE) < 0)
return JS_FALSE;
if (noteIndex >= 0) {
ptrdiff_t tmp = bce->offset();
if (!SetSrcNoteOffset(cx, bce, (uintN)noteIndex, 0, tmp-off))
return JS_FALSE;
}
}
}
return true;
}
JSBool
frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
{
JSBool useful;
StmtInfo stmtInfo;
ptrdiff_t top, off, tmp, beq, jmp;
ParseNode *pn2, *pn3;
@ -6818,66 +6888,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
break;
case PNK_DELETE:
/*
* Under ECMA 3, deleting a non-reference returns true -- but alas we
* must evaluate the operand if it appears it might have side effects.
*/
pn2 = pn->pn_kid;
switch (pn2->getKind()) {
case PNK_NAME:
if (!BindNameToSlot(cx, bce, pn2))
return JS_FALSE;
op = pn2->getOp();
if (op == JSOP_FALSE) {
if (Emit1(cx, bce, op) < 0)
return JS_FALSE;
} else {
if (!EmitAtomOp(cx, pn2, op, bce))
return JS_FALSE;
}
break;
case PNK_DOT:
if (!EmitPropOp(cx, pn2, JSOP_DELPROP, bce, JS_FALSE))
return JS_FALSE;
break;
#if JS_HAS_XML_SUPPORT
case PNK_DBLDOT:
JS_ASSERT(!bce->inStrictMode());
if (!EmitElemOp(cx, pn2, JSOP_DELDESC, bce))
return JS_FALSE;
break;
#endif
case PNK_LB:
if (!EmitElemOp(cx, pn2, JSOP_DELELEM, bce))
return JS_FALSE;
break;
default:
/*
* If useless, just emit JSOP_TRUE; otherwise convert delete foo()
* to foo(), true (a comma expression, requiring SRC_PCDELTA).
*/
useful = JS_FALSE;
if (!CheckSideEffects(cx, bce, pn2, &useful))
return JS_FALSE;
if (!useful) {
off = noteIndex = -1;
} else {
JS_ASSERT_IF(pn2->isKind(PNK_LP), !(pn2->pn_xflags & PNX_SETCALL));
if (!EmitTree(cx, bce, pn2))
return JS_FALSE;
off = bce->offset();
noteIndex = NewSrcNote2(cx, bce, SRC_PCDELTA, 0);
if (noteIndex < 0 || Emit1(cx, bce, JSOP_POP) < 0)
return JS_FALSE;
}
if (Emit1(cx, bce, JSOP_TRUE) < 0)
return JS_FALSE;
if (noteIndex >= 0) {
tmp = bce->offset();
if (!SetSrcNoteOffset(cx, bce, (uintN)noteIndex, 0, tmp-off))
return JS_FALSE;
}
}
ok = EmitDelete(cx, bce, pn);
break;
#if JS_HAS_XML_SUPPORT