Bug 1101905 - Part 4: Add strict variant of JSOP_SETGNAME. (r=Waldo)

This commit is contained in:
Eric Faust 2014-11-26 14:42:52 -08:00
Родитель 5d8b874d2c
Коммит 641450c9ba
11 изменённых файлов: 54 добавлений и 17 удалений

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

@ -1522,6 +1522,10 @@ StrictifySetNameOp(JSOp op, BytecodeEmitter *bce)
if (bce->sc->strict)
op = JSOP_STRICTSETNAME;
break;
case JSOP_SETGNAME:
if (bce->sc->strict)
op = JSOP_STRICTSETGNAME;
break;
default:;
}
return op;
@ -1658,7 +1662,7 @@ TryConvertFreeName(BytecodeEmitter *bce, ParseNode *pn)
JSOp op;
switch (pn->getOp()) {
case JSOP_NAME: op = JSOP_GETGNAME; break;
case JSOP_SETNAME: op = JSOP_SETGNAME; break;
case JSOP_SETNAME: op = StrictifySetNameOp(JSOP_SETGNAME, bce); break;
case JSOP_SETCONST:
// Not supported.
return false;
@ -3351,6 +3355,7 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
case JSOP_SETNAME:
case JSOP_STRICTSETNAME:
case JSOP_SETGNAME:
case JSOP_STRICTSETGNAME:
case JSOP_SETCONST: {
// This is like ordinary assignment, but with one difference.
//
@ -3367,7 +3372,8 @@ EmitDestructuringLHS(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn,
return false;
if (!pn->isOp(JSOP_SETCONST)) {
JSOp bindOp = pn->isOp(JSOP_SETGNAME) ? JSOP_BINDGNAME : JSOP_BINDNAME;
bool global = pn->isOp(JSOP_SETGNAME) || pn->isOp(JSOP_STRICTSETGNAME);
JSOp bindOp = global ? JSOP_BINDGNAME : JSOP_BINDNAME;
if (!EmitIndex32(cx, bindOp, atomIndex, bce))
return false;
if (Emit1(cx, bce, JSOP_SWAP) < 0)
@ -3893,12 +3899,17 @@ EmitVariables(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, VarEmit
if (pn3) {
MOZ_ASSERT(emitOption != DefineVars);
if (op == JSOP_SETNAME || op == JSOP_STRICTSETNAME || op == JSOP_SETGNAME || op == JSOP_SETINTRINSIC) {
if (op == JSOP_SETNAME ||
op == JSOP_STRICTSETNAME ||
op == JSOP_SETGNAME ||
op == JSOP_STRICTSETGNAME ||
op == JSOP_SETINTRINSIC)
{
MOZ_ASSERT(emitOption != PushInitialValues);
JSOp bindOp;
if (op == JSOP_SETNAME || op == JSOP_STRICTSETNAME)
bindOp = JSOP_BINDNAME;
else if (op == JSOP_SETGNAME)
else if (op == JSOP_SETGNAME || op == JSOP_STRICTSETGNAME)
bindOp = JSOP_BINDGNAME;
else
bindOp = JSOP_BINDINTRINSIC;
@ -3974,7 +3985,7 @@ EmitAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp
JSOp bindOp;
if (lhs->isOp(JSOP_SETNAME) || lhs->isOp(JSOP_STRICTSETNAME))
bindOp = JSOP_BINDNAME;
else if (lhs->isOp(JSOP_SETGNAME))
else if (lhs->isOp(JSOP_SETGNAME) || lhs->isOp(JSOP_STRICTSETGNAME))
bindOp = JSOP_BINDGNAME;
else
bindOp = JSOP_BINDINTRINSIC;
@ -4034,7 +4045,7 @@ EmitAssignment(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *lhs, JSOp
return false;
if (!EmitIndex32(cx, JSOP_GETXPROP, atomIndex, bce))
return false;
} else if (lhs->isOp(JSOP_SETGNAME)) {
} else if (lhs->isOp(JSOP_SETGNAME) || lhs->isOp(JSOP_STRICTSETGNAME)) {
MOZ_ASSERT(lhs->pn_cookie.isFree());
if (!EmitAtomOp(cx, lhs, JSOP_GETGNAME, bce))
return false;
@ -6311,6 +6322,7 @@ EmitIncOrDec(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
case JSOP_SETNAME:
case JSOP_STRICTSETNAME:
case JSOP_SETGNAME:
case JSOP_STRICTSETGNAME:
maySet = true;
break;
default:

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

@ -2082,6 +2082,12 @@ BaselineCompiler::emit_JSOP_SETGNAME()
return emit_JSOP_SETPROP();
}
bool
BaselineCompiler::emit_JSOP_STRICTSETGNAME()
{
return emit_JSOP_SETPROP();
}
bool
BaselineCompiler::emit_JSOP_GETPROP()
{

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

@ -115,6 +115,7 @@ namespace jit {
_(JSOP_GETGNAME) \
_(JSOP_BINDGNAME) \
_(JSOP_SETGNAME) \
_(JSOP_STRICTSETGNAME) \
_(JSOP_SETNAME) \
_(JSOP_STRICTSETNAME) \
_(JSOP_GETPROP) \

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

@ -7900,6 +7900,7 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_
op == JSOP_SETNAME ||
op == JSOP_STRICTSETNAME ||
op == JSOP_SETGNAME ||
op == JSOP_STRICTSETGNAME ||
op == JSOP_INITPROP ||
op == JSOP_SETALIASEDVAR ||
op == JSOP_INITALIASEDLEXICAL);
@ -7943,7 +7944,8 @@ DoSetPropFallback(JSContext *cx, BaselineFrame *frame, ICSetProp_Fallback *stub_
}
} else if (op == JSOP_SETNAME ||
op == JSOP_STRICTSETNAME ||
op == JSOP_SETGNAME)
op == JSOP_SETGNAME ||
op == JSOP_STRICTSETGNAME)
{
if (!SetNameOperation(cx, script, pc, obj, rhs))
return false;

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

@ -1680,6 +1680,7 @@ IonBuilder::inspectOpcode(JSOp op)
return pushConstant(ObjectValue(script()->global()));
case JSOP_SETGNAME:
case JSOP_STRICTSETGNAME:
{
PropertyName *name = info().getAtom(pc)->asPropertyName();
JSObject *obj = &script()->global();

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

@ -508,7 +508,7 @@ SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValu
return baseops::SetPropertyHelper<SequentialExecution>(
cx, obj.as<NativeObject>(), obj.as<NativeObject>(), id,
(op == JSOP_SETNAME || op == JSOP_STRICTSETNAME ||
op == JSOP_SETGNAME)
op == JSOP_SETGNAME || op == JSOP_STRICTSETGNAME)
? baseops::Unqualified
: baseops::Qualified,
&v,

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

@ -659,7 +659,8 @@ IsStrictSetPC(jsbytecode *pc)
{
JSOp op = JSOp(*pc);
return op == JSOP_STRICTSETPROP ||
op == JSOP_STRICTSETNAME;
op == JSOP_STRICTSETNAME ||
op == JSOP_STRICTSETGNAME;
}
inline bool
@ -668,7 +669,7 @@ IsSetPropPC(jsbytecode *pc)
JSOp op = JSOp(*pc);
return op == JSOP_SETPROP || op == JSOP_STRICTSETPROP ||
op == JSOP_SETNAME || op == JSOP_STRICTSETNAME ||
op == JSOP_SETGNAME;
op == JSOP_SETGNAME || op == JSOP_STRICTSETGNAME;
}
inline bool

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

@ -307,11 +307,12 @@ SetNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, HandleObject s
{
MOZ_ASSERT(*pc == JSOP_SETNAME ||
*pc == JSOP_STRICTSETNAME ||
*pc == JSOP_SETGNAME);
*pc == JSOP_SETGNAME ||
*pc == JSOP_STRICTSETGNAME);
MOZ_ASSERT_IF(*pc == JSOP_SETGNAME, scope == cx->global());
MOZ_ASSERT_IF(*pc == JSOP_STRICTSETGNAME, scope == cx->global());
// XXX: Removed later in stack. SETGNAME still relies on script.
bool strict = *pc == JSOP_STRICTSETNAME || script->strict();
bool strict = *pc == JSOP_STRICTSETNAME || *pc == JSOP_STRICTSETGNAME;
RootedPropertyName name(cx, script->getName(pc));
RootedValue valCopy(cx, val);

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

@ -1608,7 +1608,6 @@ CASE(JSOP_UNUSED147)
CASE(JSOP_UNUSED148)
CASE(JSOP_BACKPATCH)
CASE(JSOP_UNUSED150)
CASE(JSOP_UNUSED156)
CASE(JSOP_UNUSED157)
CASE(JSOP_UNUSED158)
CASE(JSOP_UNUSED159)
@ -2381,11 +2380,14 @@ CASE(JSOP_SETINTRINSIC)
END_CASE(JSOP_SETINTRINSIC)
CASE(JSOP_SETGNAME)
CASE(JSOP_STRICTSETGNAME)
CASE(JSOP_SETNAME)
CASE(JSOP_STRICTSETNAME)
{
static_assert(JSOP_SETNAME_LENGTH == JSOP_STRICTSETNAME_LENGTH,
"setname and strictsetname must be the same size");
static_assert(JSOP_SETGNAME_LENGTH == JSOP_STRICTSETGNAME_LENGTH,
"setganem adn strictsetgname must be the same size");
RootedObject &scope = rootObject0;
scope = &REGS.sp[-2].toObject();
HandleValue value = REGS.stackHandleAt(-1);

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

@ -1444,9 +1444,20 @@
* Operands: uint32_t nameIndex
* Stack: scope, val => val
*/ \
macro(JSOP_SETGNAME, 155,"setgname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME) \
macro(JSOP_SETGNAME, 155,"setgname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME|JOF_CHECKSLOPPY) \
\
macro(JSOP_UNUSED156, 156, "unused156", NULL, 1, 0, 0, JOF_BYTE) \
/*
* Pops the top two values on the stack as 'val' and 'scope', sets property
* of 'scope' as 'val' and pushes 'val' back on the stack. Throws a
* TypeError if the set fails, per strict mode semantics.
*
* 'scope' should be the global scope.
* Category: Variables and Scopes
* Type: Free Variables
* Operands: uint32_t nameIndex
* Stack: scope, val => val
*/ \
macro(JSOP_STRICTSETGNAME, 156, "strict-setgname", NULL, 5, 2, 1, JOF_ATOM|JOF_NAME|JOF_SET|JOF_DETECTING|JOF_GNAME|JOF_CHECKSTRICT) \
macro(JSOP_UNUSED157, 157, "unused157", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED158, 158, "unused158", NULL, 1, 0, 0, JOF_BYTE) \
macro(JSOP_UNUSED159, 159, "unused159", NULL, 1, 0, 0, JOF_BYTE) \

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

@ -34,7 +34,7 @@ namespace js {
* Nightly) and without (all others). FIXME: Bug 1066322 - Enable ES6 symbols
* in all builds.
*/
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 212;
static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 214;
static_assert(XDR_BYTECODE_VERSION_SUBTRAHEND % 2 == 0, "see the comment above");
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - (XDR_BYTECODE_VERSION_SUBTRAHEND