зеркало из https://github.com/mozilla/gecko-dev.git
Bug 793860, part 2 - Remove JSOP_ENUMELEM. r=luke.
--HG-- extra : rebase_source : 4437d5bbf10755e184419471afccee81af367e14
This commit is contained in:
Родитель
4d7a6376b1
Коммит
e0c7c9458a
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче