Bug 793860, part 2 - Remove JSOP_ENUMELEM. r=luke.

--HG--
extra : rebase_source : 4437d5bbf10755e184419471afccee81af367e14
This commit is contained in:
Jason Orendorff 2013-12-09 14:12:39 -06:00
Родитель 4d7a6376b1
Коммит e0c7c9458a
6 изменённых файлов: 43 добавлений и 87 удалений

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

@ -2071,22 +2071,6 @@ EmitNameOp(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callC
return true;
}
static inline bool
EmitElemOpBase(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
{
if (Emit1(cx, bce, op) < 0)
return false;
CheckTypeSet(cx, bce, op);
if (op == JSOP_CALLELEM) {
if (Emit1(cx, bce, JSOP_SWAP) < 0)
return false;
if (Emit1(cx, bce, JSOP_NOTEARG) < 0)
return false;
}
return true;
}
static bool
EmitPropLHS(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
@ -2234,6 +2218,11 @@ EmitNameIncDec(ExclusiveContext *cx, ParseNode *pn, BytecodeEmitter *bce)
return true;
}
/*
* Emit bytecode to put operands for a JSOP_GETELEM/CALLELEM/SETELEM/DELELEM
* opcode onto the stack in the right order. In the case of SETELEM, the
* value to be assigned must already be pushed.
*/
static bool
EmitElemOperands(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *bce)
{
@ -2244,6 +2233,24 @@ EmitElemOperands(ExclusiveContext *cx, ParseNode *pn, JSOp op, BytecodeEmitter *
return false;
if (!EmitTree(cx, bce, pn->pn_right))
return false;
if (op == JSOP_SETELEM && Emit2(cx, bce, JSOP_PICK, (jsbytecode)2) < 0)
return false;
return true;
}
static inline bool
EmitElemOpBase(ExclusiveContext *cx, BytecodeEmitter *bce, JSOp op)
{
if (Emit1(cx, bce, op) < 0)
return false;
CheckTypeSet(cx, bce, op);
if (op == JSOP_CALLELEM) {
if (Emit1(cx, bce, JSOP_SWAP) < 0)
return false;
if (Emit1(cx, bce, JSOP_NOTEARG) < 0)
return false;
}
return true;
}
@ -2913,20 +2920,16 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
{
JS_ASSERT(emitOption != DefineVars);
/*
* Now emit the lvalue opcode sequence. If the lvalue is a nested
* destructuring initialiser-form, call ourselves to handle it, then
* pop the matched value. Otherwise emit an lvalue bytecode sequence
* ending with a JSOP_ENUMELEM or equivalent op.
*/
// Now emit the lvalue opcode sequence. If the lvalue is a nested
// destructuring initialiser-form, call ourselves to handle it, then pop
// the matched value. Otherwise emit an lvalue bytecode sequence followed
// by an assignment op.
if (pn->isKind(PNK_ARRAY) || pn->isKind(PNK_OBJECT)) {
if (!EmitDestructuringOpsHelper(cx, bce, pn, emitOption))
return false;
if (emitOption == InitializeVars) {
/*
* Per its post-condition, EmitDestructuringOpsHelper has left the
* to-be-destructured value on top of the stack.
*/
// Per its post-condition, EmitDestructuringOpsHelper has left the
// to-be-destructured value on top of the stack.
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
}
@ -2936,8 +2939,6 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
JS_ASSERT(pn->getOp() == JSOP_GETLOCAL);
JS_ASSERT(pn->pn_dflags & PND_BOUND);
} else {
// All paths below must pop after assigning to the lhs.
switch (pn->getKind()) {
case PNK_NAME:
if (!BindNameToSlot(cx, bce, pn))
@ -2975,8 +2976,6 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
if (!EmitIndexOp(cx, pn->getOp(), atomIndex, bce))
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
break;
}
@ -2984,8 +2983,6 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
case JSOP_SETARG:
if (!EmitVarOp(cx, pn, pn->getOp(), bce))
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
break;
default:
@ -3008,16 +3005,13 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
return false;
if (!EmitAtomOp(cx, pn, JSOP_SETPROP, bce))
return false;
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
break;
case PNK_ELEM:
// See the comment at `case PNK_DOT:` above. This case,
// `[a[x]] = [b]`, is handled much the same way, but no JSOP_SWAP
// is necessary because there is a specialized opcode for that,
// JSOP_ENUMELEM.
if (!EmitElemOp(cx, pn, JSOP_ENUMELEM, bce))
// `[a[x]] = [b]`, is handled much the same way. The JSOP_SWAP
// is emitted by EmitElemOperands.
if (!EmitElemOp(cx, pn, JSOP_SETELEM, bce))
return false;
break;
@ -3026,13 +3020,11 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
if (!EmitTree(cx, bce, pn))
return false;
// Pop the call return value and the RHS, presumably for the
// benefit of bytecode analysis. (The interpreter will never reach
// these instructions since we just emitted JSOP_SETCALL, which
// always throws. It's possible no analyses actually depend on this
// either.)
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
// Pop the call return value. Below, we pop the RHS too, balancing
// the stack --- presumably for the benefit of bytecode
// analysis. (The interpreter will never reach these instructions
// since we just emitted JSOP_SETCALL, which always throws. It's
// possible no analyses actually depend on this either.)
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
break;
@ -3040,6 +3032,10 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
default:
MOZ_ASSUME_UNREACHABLE("EmitDestructuringLHS: bad lhs kind");
}
// Pop the assigned value.
if (Emit1(cx, bce, JSOP_POP) < 0)
return false;
}
return true;

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

@ -1727,25 +1727,6 @@ BaselineCompiler::emit_JSOP_SETELEM()
return true;
}
bool
BaselineCompiler::emit_JSOP_ENUMELEM()
{
// ENUMELEM is a SETELEM with a different stack arrangement.
// Instead of: OBJ ID RHS
// The stack is: RHS OBJ ID
// Keep object and index in R0 and R1, and keep RHS on the stack.
frame.popRegsAndSync(2);
// Call IC.
ICSetElem_Fallback::Compiler stubCompiler(cx);
if (!emitOpIC(stubCompiler.getStub(&stubSpace_)))
return false;
frame.pop();
return true;
}
typedef bool (*DeleteElementFn)(JSContext *, HandleValue, HandleValue, bool *);
static const VMFunction DeleteElementStrictInfo = FunctionInfo<DeleteElementFn>(DeleteElement<true>);
static const VMFunction DeleteElementNonStrictInfo = FunctionInfo<DeleteElementFn>(DeleteElement<false>);

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

@ -98,7 +98,6 @@ namespace jit {
_(JSOP_GETELEM) \
_(JSOP_SETELEM) \
_(JSOP_CALLELEM) \
_(JSOP_ENUMELEM) \
_(JSOP_DELELEM) \
_(JSOP_IN) \
_(JSOP_GETGNAME) \

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

@ -4932,7 +4932,6 @@ DoSetElemFallback(JSContext *cx, BaselineFrame *frame, ICSetElem_Fallback *stub,
FallbackICSpew(cx, stub, "SetElem(%s)", js_CodeName[JSOp(*pc)]);
JS_ASSERT(op == JSOP_SETELEM ||
op == JSOP_ENUMELEM ||
op == JSOP_INITELEM ||
op == JSOP_INITELEM_ARRAY);

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

@ -273,11 +273,7 @@ OPDEF(JSOP_DEFAULT, 122,"default", NULL, 5, 1, 0, JOF_JUMP)
*/
OPDEF(JSOP_EVAL, 123,"eval", NULL, 3, -1, 1, JOF_UINT16|JOF_INVOKE|JOF_TYPESET)
/*
* ECMA-compliant helper for 'for (x[i] in o)' loops.
*/
OPDEF(JSOP_ENUMELEM, 124,"enumelem", NULL, 1, 3, 0, JOF_BYTE |JOF_SET|JOF_TMPSLOT)
OPDEF(JSOP_UNUSED124, 124, "unused124", NULL, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_UNUSED125, 125, "unused125", NULL, 1, 0, 0, JOF_BYTE)
OPDEF(JSOP_UNUSED126, 126, "unused126", NULL, 1, 0, 0, JOF_BYTE)

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

@ -1603,6 +1603,7 @@ CASE(JSOP_UNUSED103)
CASE(JSOP_UNUSED104)
CASE(JSOP_UNUSED105)
CASE(JSOP_UNUSED107)
CASE(JSOP_UNUSED124)
CASE(JSOP_UNUSED125)
CASE(JSOP_UNUSED126)
CASE(JSOP_UNUSED132)
@ -2477,22 +2478,6 @@ CASE(JSOP_SETELEM)
}
END_CASE(JSOP_SETELEM)
CASE(JSOP_ENUMELEM)
{
RootedObject &obj = rootObject0;
RootedValue &rval = rootValue0;
/* Funky: the value to set is under the [obj, id] pair. */
FETCH_OBJECT(cx, -2, obj);
RootedId &id = rootId0;
FETCH_ELEMENT_ID(-1, id);
rval = REGS.sp[-3];
if (!JSObject::setGeneric(cx, obj, obj, id, &rval, script->strict()))
goto error;
REGS.sp -= 3;
}
END_CASE(JSOP_ENUMELEM)
CASE(JSOP_EVAL)
{
CallArgs args = CallArgsFromSp(GET_ARGC(REGS.pc), REGS.sp);