summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Smith <brian@dbsoft.org>2023-09-16 05:38:42 -0500
committerMoonchild <moonchild@palemoon.org>2023-09-20 03:33:33 +0200
commitd8441d7c8175608835f3b56a76666f48e4da0548 (patch)
tree610784b2357dcd8f8dc0f46d2712d6917c1813bb
parentc2446f2478ef847c8787092165443a8674384408 (diff)
downloaduxp-d8441d7c8175608835f3b56a76666f48e4da0548.tar.gz
Issue #2308 & #1240 Follow-up - Introduce new increment and decrement operations.
https://bugzilla.mozilla.org/show_bug.cgi?id=1508521
-rw-r--r--js/src/frontend/ElemOpEmitter.cpp7
-rw-r--r--js/src/frontend/NameOpEmitter.cpp7
-rw-r--r--js/src/frontend/PropOpEmitter.cpp7
-rw-r--r--js/src/jit/BaselineCompiler.cpp12
-rw-r--r--js/src/jit/BaselineCompiler.h8
-rw-r--r--js/src/jit/IonBuilder.cpp37
-rw-r--r--js/src/jit/IonBuilder.h1
-rw-r--r--js/src/jit/SharedIC.cpp20
-rw-r--r--js/src/jit/SharedIC.h2
-rw-r--r--js/src/jit/x86-shared/BaseAssembler-x86-shared.h8
-rw-r--r--js/src/vm/Interpreter-inl.h34
-rw-r--r--js/src/vm/Interpreter.cpp20
-rw-r--r--js/src/vm/Opcodes.h24
13 files changed, 157 insertions, 30 deletions
diff --git a/js/src/frontend/ElemOpEmitter.cpp b/js/src/frontend/ElemOpEmitter.cpp
index f17b554e7a..dd6da9dcb4 100644
--- a/js/src/frontend/ElemOpEmitter.cpp
+++ b/js/src/frontend/ElemOpEmitter.cpp
@@ -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()) {
diff --git a/js/src/frontend/NameOpEmitter.cpp b/js/src/frontend/NameOpEmitter.cpp
index 8fa7f9d966..478cd44151 100644
--- a/js/src/frontend/NameOpEmitter.cpp
+++ b/js/src/frontend/NameOpEmitter.cpp
@@ -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()) {
diff --git a/js/src/frontend/PropOpEmitter.cpp b/js/src/frontend/PropOpEmitter.cpp
index bfbca00e1d..01e365f154 100644
--- a/js/src/frontend/PropOpEmitter.cpp
+++ b/js/src/frontend/PropOpEmitter.cpp
@@ -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()) {
diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp
index 7dbd076c6b..7985a3b2a9 100644
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1940,6 +1940,18 @@ BaselineCompiler::emit_JSOP_NEG()
}
bool
+BaselineCompiler::emit_JSOP_INC()
+{
+ return emitUnaryArith();
+}
+
+bool
+BaselineCompiler::emit_JSOP_DEC()
+{
+ return emitUnaryArith();
+}
+
+bool
BaselineCompiler::emit_JSOP_LT()
{
return emitCompare();
diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h
index 8e9976b17f..9996c0f47f 100644
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -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.
diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp
index a440bfa598..2134d1b613 100644
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -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:
@@ -5203,6 +5217,29 @@ IonBuilder::jsop_neg()
}
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()
{
if (current->peek(-1)->type() == MIRType::String)
diff --git a/js/src/jit/IonBuilder.h b/js/src/jit/IonBuilder.h
index 6f3fc027f6..162edb36f2 100644
--- a/js/src/jit/IonBuilder.h
+++ b/js/src/jit/IonBuilder.h
@@ -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);
diff --git a/js/src/jit/SharedIC.cpp b/js/src/jit/SharedIC.cpp
index 375edb1400..0afc7e12b5 100644
--- a/js/src/jit/SharedIC.cpp
+++ b/js/src/jit/SharedIC.cpp
@@ -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");
}
diff --git a/js/src/jit/SharedIC.h b/js/src/jit/SharedIC.h
index d0038c9378..d259ebf0bc 100644
--- a/js/src/jit/SharedIC.h
+++ b/js/src/jit/SharedIC.h
@@ -1855,6 +1855,8 @@ class ICBinaryArith_DoubleWithInt32 : public ICStub
// UnaryArith
// JSOP_BITNOT
// JSOP_NEG
+// JSOP_INC
+// JSOP_DEC
class ICUnaryArith_Fallback : public ICFallbackStub
{
diff --git a/js/src/jit/x86-shared/BaseAssembler-x86-shared.h b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h
index b5f800cdab..e8f7f07e2c 100644
--- a/js/src/jit/x86-shared/BaseAssembler-x86-shared.h
+++ b/js/src/jit/x86-shared/BaseAssembler-x86-shared.h
@@ -4937,7 +4937,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);
@@ -4946,7 +4946,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);
@@ -4956,7 +4956,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);
@@ -4970,7 +4970,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);
diff --git a/js/src/vm/Interpreter-inl.h b/js/src/vm/Interpreter-inl.h
index a48c753f1d..93d2672b0f 100644
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -417,6 +417,40 @@ NegOperation(JSContext* cx, HandleScript script, jsbytecode* pc, MutableHandleVa
}
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)
{
diff --git a/js/src/vm/Interpreter.cpp b/js/src/vm/Interpreter.cpp
index a03fa847f7..7b04f5fb72 100644
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -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)));
diff --git a/js/src/vm/Opcodes.h b/js/src/vm/Opcodes.h
index ff707aac08..c86a22baac 100644
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -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) \