mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-08-15 08:53:07 +09:00
Issue #2308 & #1240 Follow-up - Introduce new increment and decrement operations. https://bugzilla.mozilla.org/show_bug.cgi?id=1508521
This commit is contained in:
parent
e9202b0b0f
commit
5c8a6c5bb8
13 changed files with 157 additions and 30 deletions
|
|
@ -233,7 +233,7 @@ ElemOpEmitter::emitIncDec()
|
|||
|
||||
MOZ_ASSERT(state_ == State::Get);
|
||||
|
||||
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
||||
JSOp incOp = isInc() ? JSOP_INC : JSOP_DEC;
|
||||
if (!bce_->emit1(JSOP_POS)) { // ... N
|
||||
return false;
|
||||
}
|
||||
|
|
@ -242,10 +242,7 @@ ElemOpEmitter::emitIncDec()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!bce_->emit1(JSOP_ONE)) { // ... N? N 1
|
||||
return false;
|
||||
}
|
||||
if (!bce_->emit1(binOp)) { // ... N? N+1
|
||||
if (!bce_->emit1(incOp)) { // ... N? N+1
|
||||
return false;
|
||||
}
|
||||
if (isPostIncDec()) {
|
||||
|
|
|
|||
|
|
@ -339,7 +339,7 @@ NameOpEmitter::emitIncDec()
|
|||
{
|
||||
MOZ_ASSERT(state_ == State::Start);
|
||||
|
||||
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
||||
JSOp incOp = isInc() ? JSOP_INC : JSOP_DEC;
|
||||
if (!prepareForRhs()) { // ENV? V
|
||||
return false;
|
||||
}
|
||||
|
|
@ -351,10 +351,7 @@ NameOpEmitter::emitIncDec()
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!bce_->emit1(JSOP_ONE)) { // ENV? N? N 1
|
||||
return false;
|
||||
}
|
||||
if (!bce_->emit1(binOp)) { // ENV? N? N+1
|
||||
if (!bce_->emit1(incOp)) { // ENV? N? N+1
|
||||
return false;
|
||||
}
|
||||
if (isPostIncDec() && emittedBindOp()) {
|
||||
|
|
|
|||
|
|
@ -217,7 +217,7 @@ PropOpEmitter::emitIncDec(JSAtom* prop)
|
|||
|
||||
MOZ_ASSERT(state_ == State::Get);
|
||||
|
||||
JSOp binOp = isInc() ? JSOP_ADD : JSOP_SUB;
|
||||
JSOp incOp = isInc() ? JSOP_INC : JSOP_DEC;
|
||||
|
||||
if (!bce_->emit1(JSOP_POS)) { // ... N
|
||||
return false;
|
||||
|
|
@ -227,10 +227,7 @@ PropOpEmitter::emitIncDec(JSAtom* prop)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
if (!bce_->emit1(JSOP_ONE)) { // ... N? N 1
|
||||
return false;
|
||||
}
|
||||
if (!bce_->emit1(binOp)) { // ... N? N+1
|
||||
if (!bce_->emit1(incOp)) { // ... N? N+1
|
||||
return false;
|
||||
}
|
||||
if (isPostIncDec()) {
|
||||
|
|
|
|||
|
|
@ -1939,6 +1939,18 @@ BaselineCompiler::emit_JSOP_NEG()
|
|||
return emitUnaryArith();
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_INC()
|
||||
{
|
||||
return emitUnaryArith();
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_DEC()
|
||||
{
|
||||
return emitUnaryArith();
|
||||
}
|
||||
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_LT()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -242,8 +242,10 @@ namespace jit {
|
|||
_(JSOP_JUMPTARGET) \
|
||||
_(JSOP_IS_CONSTRUCTING) \
|
||||
_(JSOP_TRY_DESTRUCTURING_ITERCLOSE) \
|
||||
_(JSOP_IMPORTMETA) \
|
||||
_(JSOP_DYNAMIC_IMPORT)
|
||||
_(JSOP_IMPORTMETA) \
|
||||
_(JSOP_DYNAMIC_IMPORT) \
|
||||
_(JSOP_INC) \
|
||||
_(JSOP_DEC)
|
||||
|
||||
class BaselineCompiler : public BaselineCompilerSpecific
|
||||
{
|
||||
|
|
@ -327,7 +329,7 @@ class BaselineCompiler : public BaselineCompilerSpecific
|
|||
OPCODE_LIST(EMIT_OP)
|
||||
#undef EMIT_OP
|
||||
|
||||
// JSOP_NEG, JSOP_BITNOT
|
||||
// JSOP_NEG, JSOP_BITNOT, JSOP_INC, JSOP_DEC
|
||||
MOZ_MUST_USE bool emitUnaryArith();
|
||||
|
||||
// JSOP_BITXOR, JSOP_LSH, JSOP_ADD etc.
|
||||
|
|
|
|||
|
|
@ -719,6 +719,8 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock* entry, jsbytecode* start, jsbytecod
|
|||
case JSOP_DIV:
|
||||
case JSOP_MOD:
|
||||
case JSOP_NEG:
|
||||
case JSOP_INC:
|
||||
case JSOP_DEC:
|
||||
type = inspector->expectedResultType(last);
|
||||
break;
|
||||
case JSOP_BIGINT:
|
||||
|
|
@ -1740,6 +1742,10 @@ IonBuilder::inspectOpcode(JSOp op)
|
|||
case JSOP_NEG:
|
||||
return jsop_neg();
|
||||
|
||||
case JSOP_INC:
|
||||
case JSOP_DEC:
|
||||
return jsop_inc_or_dec(op);
|
||||
|
||||
case JSOP_TOSTRING:
|
||||
return jsop_tostring();
|
||||
|
||||
|
|
@ -5070,6 +5076,14 @@ IonBuilder::arithTrySharedStub(bool* emitted, JSOp op,
|
|||
|
||||
stub = MUnarySharedStub::New(alloc(), right);
|
||||
break;
|
||||
case JSOP_INC:
|
||||
MOZ_ASSERT(op == JSOP_ADD && right->toConstant()->toInt32() == 1);
|
||||
stub = MUnarySharedStub::New(alloc(), left);
|
||||
break;
|
||||
case JSOP_DEC:
|
||||
MOZ_ASSERT(op == JSOP_SUB && right->toConstant()->toInt32() == 1);
|
||||
stub = MUnarySharedStub::New(alloc(), left);
|
||||
break;
|
||||
case JSOP_ADD:
|
||||
case JSOP_SUB:
|
||||
case JSOP_MUL:
|
||||
|
|
@ -5202,6 +5216,29 @@ IonBuilder::jsop_neg()
|
|||
return jsop_binary_arith(JSOP_MUL, negator, right);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_inc_or_dec(JSOp op)
|
||||
{
|
||||
// As above, pass constant without slot traffic.
|
||||
MConstant* one = MConstant::New(alloc(), Int32Value(1));
|
||||
current->add(one);
|
||||
|
||||
MDefinition* value = current->pop();
|
||||
|
||||
switch (op) {
|
||||
case JSOP_INC:
|
||||
op = JSOP_ADD;
|
||||
break;
|
||||
case JSOP_DEC:
|
||||
op = JSOP_SUB;
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("jsop_inc_or_dec with bad op");
|
||||
}
|
||||
|
||||
return jsop_binary_arith(op, value, one);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_tostring()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -692,6 +692,7 @@ class IonBuilder
|
|||
MOZ_MUST_USE bool jsop_pow();
|
||||
MOZ_MUST_USE bool jsop_pos();
|
||||
MOZ_MUST_USE bool jsop_neg();
|
||||
MOZ_MUST_USE bool jsop_inc_or_dec(JSOp op);
|
||||
MOZ_MUST_USE bool jsop_tostring();
|
||||
MOZ_MUST_USE bool jsop_setarg(uint32_t arg);
|
||||
MOZ_MUST_USE bool jsop_defvar(uint32_t index);
|
||||
|
|
|
|||
|
|
@ -1469,21 +1469,33 @@ DoUnaryArithFallback(JSContext* cx, void* payload, ICUnaryArith_Fallback* stub_,
|
|||
JSOp op = JSOp(*pc);
|
||||
FallbackICSpew(cx, stub, "UnaryArith(%s)", CodeName[op]);
|
||||
|
||||
// The unary operations take a copied val because the original value is needed
|
||||
// below.
|
||||
RootedValue valCopy(cx, val);
|
||||
switch (op) {
|
||||
case JSOP_BITNOT: {
|
||||
RootedValue valCopy(cx, val);
|
||||
if (!BitNot(cx, &valCopy, res)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JSOP_NEG: {
|
||||
// We copy val here because the original value is needed below.
|
||||
RootedValue valCopy(cx, val);
|
||||
if (!NegOperation(cx, script, pc, &valCopy, res))
|
||||
if (!NegOperation(cx, script, pc, &valCopy, res))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case JSOP_INC: {
|
||||
if (!IncOperation(cx, &valCopy, res)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case JSOP_DEC: {
|
||||
if (!DecOperation(cx, &valCopy, res)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
MOZ_CRASH("Unexpected op");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1855,6 +1855,8 @@ class ICBinaryArith_DoubleWithInt32 : public ICStub
|
|||
// UnaryArith
|
||||
// JSOP_BITNOT
|
||||
// JSOP_NEG
|
||||
// JSOP_INC
|
||||
// JSOP_DEC
|
||||
|
||||
class ICUnaryArith_Fallback : public ICFallbackStub
|
||||
{
|
||||
|
|
|
|||
|
|
@ -4958,7 +4958,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
|
|||
void twoByteOp8(TwoByteOpcodeID opcode, RegisterID rm, RegisterID reg)
|
||||
{
|
||||
m_buffer.ensureSpace(MaxInstructionSize);
|
||||
emitRexIf(byteRegRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
|
||||
emitRexIf(byteRegRequiresRex(reg)||byteRegRequiresRex(rm), reg, 0, rm);
|
||||
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
|
||||
m_buffer.putByteUnchecked(opcode);
|
||||
registerModRM(rm, reg);
|
||||
|
|
@ -4967,7 +4967,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
|
|||
void twoByteOp8(TwoByteOpcodeID opcode, int32_t offset, RegisterID base, RegisterID reg)
|
||||
{
|
||||
m_buffer.ensureSpace(MaxInstructionSize);
|
||||
emitRexIf(byteRegRequiresRex(reg)|regRequiresRex(base), reg, 0, base);
|
||||
emitRexIf(byteRegRequiresRex(reg)||regRequiresRex(base), reg, 0, base);
|
||||
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
|
||||
m_buffer.putByteUnchecked(opcode);
|
||||
memoryModRM(offset, base, reg);
|
||||
|
|
@ -4977,7 +4977,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
|
|||
int scale, RegisterID reg)
|
||||
{
|
||||
m_buffer.ensureSpace(MaxInstructionSize);
|
||||
emitRexIf(byteRegRequiresRex(reg)|regRequiresRex(base)|regRequiresRex(index),
|
||||
emitRexIf(byteRegRequiresRex(reg)||regRequiresRex(base)||regRequiresRex(index),
|
||||
reg, index, base);
|
||||
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
|
||||
m_buffer.putByteUnchecked(opcode);
|
||||
|
|
@ -4991,7 +4991,7 @@ threeByteOpImmSimd("vblendps", VEX_PD, OP3_BLENDPS_VpsWpsIb, ESCAPE_3A, imm, off
|
|||
void twoByteOp8_movx(TwoByteOpcodeID opcode, RegisterID rm, RegisterID reg)
|
||||
{
|
||||
m_buffer.ensureSpace(MaxInstructionSize);
|
||||
emitRexIf(regRequiresRex(reg)|byteRegRequiresRex(rm), reg, 0, rm);
|
||||
emitRexIf(regRequiresRex(reg)||byteRegRequiresRex(rm), reg, 0, rm);
|
||||
m_buffer.putByteUnchecked(OP_2BYTE_ESCAPE);
|
||||
m_buffer.putByteUnchecked(opcode);
|
||||
registerModRM(rm, reg);
|
||||
|
|
|
|||
|
|
@ -416,6 +416,40 @@ NegOperation(JSContext* cx, HandleScript script, jsbytecode* pc, MutableHandleVa
|
|||
return true;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
IncOperation(JSContext* cx,
|
||||
MutableHandleValue val,
|
||||
MutableHandleValue res)
|
||||
{
|
||||
MOZ_ASSERT(val.isNumber(), "+1 only callable on result of JSOP_TONUMERIC");
|
||||
|
||||
int32_t i;
|
||||
if (val.isInt32() && (i = val.toInt32()) != INT32_MAX) {
|
||||
res.setInt32(i + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
res.setNumber(val.toNumber() + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
DecOperation(JSContext* cx,
|
||||
MutableHandleValue val,
|
||||
MutableHandleValue res)
|
||||
{
|
||||
MOZ_ASSERT(val.isNumber(), "-1 only callable on result of JSOP_TONUMERIC");
|
||||
|
||||
int32_t i;
|
||||
if (val.isInt32() && (i = val.toInt32()) != INT32_MIN) {
|
||||
res.setInt32(i - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
res.setNumber(val.toNumber() - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static MOZ_ALWAYS_INLINE bool
|
||||
ToIdOperation(JSContext* cx, HandleScript script, jsbytecode* pc, HandleValue idval,
|
||||
MutableHandleValue res)
|
||||
|
|
|
|||
|
|
@ -4176,6 +4176,26 @@ CASE(JSOP_IS_CONSTRUCTING)
|
|||
PUSH_MAGIC(JS_IS_CONSTRUCTING);
|
||||
END_CASE(JSOP_IS_CONSTRUCTING)
|
||||
|
||||
CASE(JSOP_INC)
|
||||
{
|
||||
ReservedRooted<Value> val(&rootValue0, REGS.sp[-1]);
|
||||
MutableHandleValue res = REGS.stackHandleAt(-1);
|
||||
if (!IncOperation(cx, &val, res)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
END_CASE(JSOP_INC)
|
||||
|
||||
CASE(JSOP_DEC)
|
||||
{
|
||||
ReservedRooted<Value> val(&rootValue0, REGS.sp[-1]);
|
||||
MutableHandleValue res = REGS.stackHandleAt(-1);
|
||||
if (!DecOperation(cx, &val, res)) {
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
END_CASE(JSOP_DEC)
|
||||
|
||||
CASE(JSOP_BIGINT)
|
||||
{
|
||||
PUSH_COPY(script->getConst(GET_UINT32_INDEX(REGS.pc)));
|
||||
|
|
|
|||
|
|
@ -2357,7 +2357,25 @@
|
|||
* Operands:
|
||||
* Stack: arg => rval
|
||||
*/ \
|
||||
macro(JSOP_DYNAMIC_IMPORT, 234, "call-import", NULL, 1, 1, 1, JOF_BYTE) \
|
||||
macro(JSOP_DYNAMIC_IMPORT, 234, "call-import", NULL, 1, 1, 1, JOF_BYTE) \
|
||||
/*
|
||||
* Pops the numeric value 'val' from the stack, then pushes 'val + 1'.
|
||||
*
|
||||
* Category: Operators
|
||||
* Type: Arithmetic Operators
|
||||
* Operands:
|
||||
* Stack: val => (val + 1)
|
||||
*/ \
|
||||
macro(JSOP_INC, 235, "inc", NULL, 1, 1, 1, JOF_BYTE) \
|
||||
/*
|
||||
* Pops the numeric value 'val' from the stack, then pushes 'val - 1'.
|
||||
*
|
||||
* Category: Operators
|
||||
* Type: Arithmetic Operators
|
||||
* Operands:
|
||||
* Stack: val => (val - 1)
|
||||
*/ \
|
||||
macro(JSOP_DEC, 236, "dec", NULL, 1, 1, 1, JOF_BYTE) \
|
||||
/*
|
||||
* Pushes a BigInt constant onto the stack.
|
||||
* Category: Literals
|
||||
|
|
@ -2365,14 +2383,12 @@
|
|||
* Operands: uint32_t constIndex
|
||||
* Stack: => val
|
||||
*/ \
|
||||
macro(JSOP_BIGINT, 235, "bigint", NULL, 5, 0, 1, JOF_BIGINT)
|
||||
macro(JSOP_BIGINT, 237, "bigint", NULL, 5, 0, 1, JOF_BIGINT)
|
||||
/*
|
||||
* In certain circumstances it may be useful to "pad out" the opcode space to
|
||||
* a power of two. Use this macro to do so.
|
||||
*/
|
||||
#define FOR_EACH_TRAILING_UNUSED_OPCODE(macro) \
|
||||
macro(236) \
|
||||
macro(237) \
|
||||
macro(238) \
|
||||
macro(239) \
|
||||
macro(240) \
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue