summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@zend.com>2015-03-17 18:53:19 +0300
committerDmitry Stogov <dmitry@zend.com>2015-03-17 18:53:19 +0300
commit4d4a5336f149fc0d49ac8fa10f0f85fa364366ac (patch)
tree7a496c53ce0989c5aac1d396151713d7d52a80e8
parentfb4b7069842491eb66272587422a1f61d41eb869 (diff)
downloadphp-git-4d4a5336f149fc0d49ac8fa10f0f85fa364366ac.tar.gz
Embed "fast" operator functions (add, sub, increment, etc) into executor with additional optimizations
-rw-r--r--Zend/zend_execute.c37
-rw-r--r--Zend/zend_operators.c19
-rw-r--r--Zend/zend_operators.h757
-rw-r--r--Zend/zend_vm_def.h428
-rw-r--r--Zend/zend_vm_execute.h3530
-rw-r--r--Zend/zend_vm_gen.php25
6 files changed, 3938 insertions, 858 deletions
diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c
index 17e68dc55d..42e9673744 100644
--- a/Zend/zend_execute.c
+++ b/Zend/zend_execute.c
@@ -53,6 +53,7 @@ typedef int (ZEND_FASTCALL *incdec_t)(zval *);
#define get_zval_ptr(op_type, node, ex, should_free, type) _get_zval_ptr(op_type, node, ex, should_free, type)
#define get_zval_ptr_deref(op_type, node, ex, should_free, type) _get_zval_ptr_deref(op_type, node, ex, should_free, type)
+#define get_zval_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_undef(op_type, node, ex, should_free, type)
#define get_zval_ptr_ptr(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
#define get_zval_ptr_ptr_undef(op_type, node, ex, should_free, type) _get_zval_ptr_ptr(op_type, node, ex, should_free, type)
#define get_obj_zval_ptr(op_type, node, ex, should_free, type) _get_obj_zval_ptr(op_type, node, ex, should_free, type)
@@ -283,6 +284,11 @@ static zend_always_inline zval *_get_zval_ptr_cv(const zend_execute_data *execut
return ret;
}
+static zend_always_inline zval *_get_zval_ptr_cv_undef(const zend_execute_data *execute_data, uint32_t var)
+{
+ return EX_VAR(var);
+}
+
static zend_always_inline zval *_get_zval_ptr_cv_deref(const zend_execute_data *execute_data, uint32_t var, int type)
{
zval *ret = EX_VAR(var);
@@ -387,6 +393,11 @@ static zend_always_inline zval *_get_zval_ptr_cv_undef_BP_VAR_W(const zend_execu
return EX_VAR(var);
}
+static zend_always_inline zval *_get_zval_ptr_cv_undef_BP_VAR_RW(const zend_execute_data *execute_data, uint32_t var)
+{
+ return EX_VAR(var);
+}
+
static zend_always_inline zval *_get_zval_ptr_cv_deref_BP_VAR_W(const zend_execute_data *execute_data, uint32_t var)
{
zval *ret = EX_VAR(var);
@@ -440,6 +451,27 @@ static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node,
}
}
+static zend_always_inline zval *_get_zval_ptr_undef(int op_type, znode_op node, const zend_execute_data *execute_data, zend_free_op *should_free, int type)
+{
+ if (op_type & (IS_TMP_VAR|IS_VAR)) {
+ if (op_type == IS_TMP_VAR) {
+ return _get_zval_ptr_tmp(node.var, execute_data, should_free);
+ } else {
+ ZEND_ASSERT(op_type == IS_VAR);
+ return _get_zval_ptr_var(node.var, execute_data, should_free);
+ }
+ } else {
+ *should_free = NULL;
+ if (op_type == IS_CONST) {
+ return EX_CONSTANT(node);
+ } else if (op_type == IS_CV) {
+ return _get_zval_ptr_cv_undef(execute_data, node.var);
+ } else {
+ return NULL;
+ }
+ }
+}
+
static zend_always_inline zval *_get_zval_ptr_ptr_var(uint32_t var, const zend_execute_data *execute_data, zend_free_op *should_free)
{
zval *ret = EX_VAR(var);
@@ -2093,6 +2125,11 @@ static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data
# define ZEND_VM_GUARD(name)
#endif
+#define GET_OP1_UNDEF_CV(ptr, type) \
+ _get_zval_cv_lookup_ ## type(ptr, opline->op1.var, execute_data)
+#define GET_OP2_UNDEF_CV(ptr, type) \
+ _get_zval_cv_lookup_ ## type(ptr, opline->op2.var, execute_data)
+
#include "zend_vm_execute.h"
ZEND_API int zend_set_user_opcode_handler(zend_uchar opcode, user_opcode_handler_t handler)
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 7c23489864..d8e92a97ad 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -2162,13 +2162,7 @@ ZEND_API int ZEND_FASTCALL increment_function(zval *op1) /* {{{ */
try_again:
switch (Z_TYPE_P(op1)) {
case IS_LONG:
- if (Z_LVAL_P(op1) == ZEND_LONG_MAX) {
- /* switch to double */
- double d = (double)Z_LVAL_P(op1);
- ZVAL_DOUBLE(op1, d+1);
- } else {
- Z_LVAL_P(op1)++;
- }
+ fast_long_increment_function(op1);
break;
case IS_DOUBLE:
Z_DVAL_P(op1) = Z_DVAL_P(op1) + 1;
@@ -2211,7 +2205,7 @@ try_again:
val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
Z_ADDREF_P(val);
- fast_increment_function(val);
+ increment_function(val);
Z_OBJ_HANDLER_P(op1, set)(op1, val);
zval_ptr_dtor(val);
} else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
@@ -2243,12 +2237,7 @@ ZEND_API int ZEND_FASTCALL decrement_function(zval *op1) /* {{{ */
try_again:
switch (Z_TYPE_P(op1)) {
case IS_LONG:
- if (Z_LVAL_P(op1) == ZEND_LONG_MIN) {
- double d = (double)Z_LVAL_P(op1);
- ZVAL_DOUBLE(op1, d-1);
- } else {
- Z_LVAL_P(op1)--;
- }
+ fast_long_decrement_function(op1);
break;
case IS_DOUBLE:
Z_DVAL_P(op1) = Z_DVAL_P(op1) - 1;
@@ -2284,7 +2273,7 @@ try_again:
val = Z_OBJ_HANDLER_P(op1, get)(op1, &rv);
Z_ADDREF_P(val);
- fast_decrement_function(val);
+ decrement_function(val);
Z_OBJ_HANDLER_P(op1, set)(op1, val);
zval_ptr_dtor(val);
} else if (Z_OBJ_HANDLER_P(op1, do_operation)) {
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h
index b656e435b2..e2e9abfaae 100644
--- a/Zend/zend_operators.h
+++ b/Zend/zend_operators.h
@@ -435,238 +435,235 @@ ZEND_API void zend_update_current_locale(void);
#define ZVAL_OFFSETOF_TYPE \
(offsetof(zval, u1.type_info) - offsetof(zval, value))
-static zend_always_inline int fast_increment_function(zval *op1)
+static zend_always_inline void fast_long_increment_function(zval *op1)
{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
#if defined(__GNUC__) && defined(__i386__)
- __asm__(
- "incl (%0)\n\t"
- "jno 0f\n\t"
- "movl $0x0, (%0)\n\t"
- "movl $0x41e00000, 0x4(%0)\n\t"
- "movl %1, %c2(%0)\n"
- "0:"
- :
- : "r"(&op1->value),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "cc");
+ __asm__(
+ "incl (%0)\n\t"
+ "jno 0f\n\t"
+ "movl $0x0, (%0)\n\t"
+ "movl $0x41e00000, 0x4(%0)\n\t"
+ "movl %1, %c2(%0)\n"
+ "0:"
+ :
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#elif defined(__GNUC__) && defined(__x86_64__)
- __asm__(
- "incq (%0)\n\t"
- "jno 0f\n\t"
- "movl $0x0, (%0)\n\t"
- "movl $0x43e00000, 0x4(%0)\n\t"
- "movl %1, %c2(%0)\n"
- "0:"
- :
- : "r"(&op1->value),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "cc");
+ __asm__(
+ "incq (%0)\n\t"
+ "jno 0f\n\t"
+ "movl $0x0, (%0)\n\t"
+ "movl $0x43e00000, 0x4(%0)\n\t"
+ "movl %1, %c2(%0)\n"
+ "0:"
+ :
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#elif defined(__GNUC__) && defined(__powerpc64__)
- __asm__(
- "ld 14, 0(%0)\n\t"
- "li 15, 1\n\t"
- "li 16, 0\n\t"
- "mtxer 16\n\t"
- "addo. 14, 14, 15\n\t"
- "std 14, 0(%0)\n\t"
- "bns+ 0f\n\t"
- "xor 14, 14, 14\n\t"
- "lis 15, 0x43e00000@h\n\t"
- "ori 15, 15, 0x43e00000@l\n\t"
+ __asm__(
+ "ld 14, 0(%0)\n\t"
+ "li 15, 1\n\t"
+ "li 16, 0\n\t"
+ "mtxer 16\n\t"
+ "addo. 14, 14, 15\n\t"
+ "std 14, 0(%0)\n\t"
+ "bns+ 0f\n\t"
+ "xor 14, 14, 14\n\t"
+ "lis 15, 0x43e00000@h\n\t"
+ "ori 15, 15, 0x43e00000@l\n\t"
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- "stw 14, 0(%0)\n\t"
- "stw 15, 0x4(%0)\n\t"
+ "stw 14, 0(%0)\n\t"
+ "stw 15, 0x4(%0)\n\t"
#else
- "stw 14, 0x4(%0)\n\t"
- "stw 15, 0(%0)\n\t"
+ "stw 14, 0x4(%0)\n\t"
+ "stw 15, 0(%0)\n\t"
#endif
- "li 14, %1\n\t"
- "stw 14, %c2(%0)\n"
- "0:"
- :
- : "r"(&op1->value),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "r14", "r15", "r16", "cc");
+ "li 14, %1\n\t"
+ "stw 14, %c2(%0)\n"
+ "0:"
+ :
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "r14", "r15", "r16", "cc");
#else
- if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
- /* switch to double */
- ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
- } else {
- Z_LVAL_P(op1)++;
- }
-#endif
- return SUCCESS;
+ if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
+ /* switch to double */
+ ZVAL_DOUBLE(op1, (double)ZEND_LONG_MAX + 1.0);
+ } else {
+ Z_LVAL_P(op1)++;
}
- return increment_function(op1);
+#endif
}
-static zend_always_inline int fast_decrement_function(zval *op1)
+static zend_always_inline void fast_long_decrement_function(zval *op1)
{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
#if defined(__GNUC__) && defined(__i386__)
- __asm__(
- "decl (%0)\n\t"
- "jno 0f\n\t"
- "movl $0x00200000, (%0)\n\t"
- "movl $0xc1e00000, 0x4(%0)\n\t"
- "movl %1,%c2(%0)\n"
- "0:"
- :
- : "r"(&op1->value),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "cc");
+ __asm__(
+ "decl (%0)\n\t"
+ "jno 0f\n\t"
+ "movl $0x00200000, (%0)\n\t"
+ "movl $0xc1e00000, 0x4(%0)\n\t"
+ "movl %1,%c2(%0)\n"
+ "0:"
+ :
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#elif defined(__GNUC__) && defined(__x86_64__)
- __asm__(
- "decq (%0)\n\t"
- "jno 0f\n\t"
- "movl $0x00000000, (%0)\n\t"
- "movl $0xc3e00000, 0x4(%0)\n\t"
- "movl %1,%c2(%0)\n"
- "0:"
- :
- : "r"(&op1->value),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "cc");
+ __asm__(
+ "decq (%0)\n\t"
+ "jno 0f\n\t"
+ "movl $0x00000000, (%0)\n\t"
+ "movl $0xc3e00000, 0x4(%0)\n\t"
+ "movl %1,%c2(%0)\n"
+ "0:"
+ :
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "cc");
#elif defined(__GNUC__) && defined(__powerpc64__)
- __asm__(
- "ld 14, 0(%0)\n\t"
- "li 15, 1\n\t"
- "li 16, 0\n\t"
- "mtxer 16\n\t"
- "subo. 14, 14, 15\n\t"
- "std 14, 0(%0)\n\t"
- "bns+ 0f\n\t"
- "xor 14, 14, 14\n\t"
- "lis 15, 0xc3e00000@h\n\t"
- "ori 15, 15, 0xc3e00000@l\n\t"
+ __asm__(
+ "ld 14, 0(%0)\n\t"
+ "li 15, 1\n\t"
+ "li 16, 0\n\t"
+ "mtxer 16\n\t"
+ "subo. 14, 14, 15\n\t"
+ "std 14, 0(%0)\n\t"
+ "bns+ 0f\n\t"
+ "xor 14, 14, 14\n\t"
+ "lis 15, 0xc3e00000@h\n\t"
+ "ori 15, 15, 0xc3e00000@l\n\t"
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- "stw 14, 0(%0)\n\t"
- "stw 15, 0x4(%0)\n\t"
+ "stw 14, 0(%0)\n\t"
+ "stw 15, 0x4(%0)\n\t"
#else
- "stw 14, 0x4(%0)\n\t"
- "stw 15, 0(%0)\n\t"
+ "stw 14, 0x4(%0)\n\t"
+ "stw 15, 0(%0)\n\t"
#endif
- "li 14, %1\n\t"
- "stw 14, %c2(%0)\n"
- "0:"
- :
- : "r"(&op1->value),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "r14", "r15", "r16", "cc");
+ "li 14, %1\n\t"
+ "stw 14, %c2(%0)\n"
+ "0:"
+ :
+ : "r"(&op1->value),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "r14", "r15", "r16", "cc");
#else
- if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
- /* switch to double */
- ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
- } else {
- Z_LVAL_P(op1)--;
- }
-#endif
- return SUCCESS;
+ if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
+ /* switch to double */
+ ZVAL_DOUBLE(op1, (double)ZEND_LONG_MIN - 1.0);
+ } else {
+ Z_LVAL_P(op1)--;
}
- return decrement_function(op1);
+#endif
}
-static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2)
+static zend_always_inline void fast_long_add_function(zval *result, zval *op1, zval *op2)
{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
#if defined(__GNUC__) && defined(__i386__)
- __asm__(
- "movl (%1), %%eax\n\t"
- "addl (%2), %%eax\n\t"
- "jo 0f\n\t"
- "movl %%eax, (%0)\n\t"
- "movl %3, %c5(%0)\n\t"
- "jmp 1f\n"
- "0:\n\t"
- "fildl (%1)\n\t"
- "fildl (%2)\n\t"
- "faddp %%st, %%st(1)\n\t"
- "movl %4, %c5(%0)\n\t"
- "fstpl (%0)\n"
- "1:"
- :
- : "r"(&result->value),
- "r"(&op1->value),
- "r"(&op2->value),
- "n"(IS_LONG),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "eax","cc");
+ __asm__(
+ "movl (%1), %%eax\n\t"
+ "addl (%2), %%eax\n\t"
+ "jo 0f\n\t"
+ "movl %%eax, (%0)\n\t"
+ "movl %3, %c5(%0)\n\t"
+ "jmp 1f\n"
+ "0:\n\t"
+ "fildl (%1)\n\t"
+ "fildl (%2)\n\t"
+ "faddp %%st, %%st(1)\n\t"
+ "movl %4, %c5(%0)\n\t"
+ "fstpl (%0)\n"
+ "1:"
+ :
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "eax","cc");
#elif defined(__GNUC__) && defined(__x86_64__)
- __asm__(
- "movq (%1), %%rax\n\t"
- "addq (%2), %%rax\n\t"
- "jo 0f\n\t"
- "movq %%rax, (%0)\n\t"
- "movl %3, %c5(%0)\n\t"
- "jmp 1f\n"
- "0:\n\t"
- "fildq (%1)\n\t"
- "fildq (%2)\n\t"
- "faddp %%st, %%st(1)\n\t"
- "movl %4, %c5(%0)\n\t"
- "fstpl (%0)\n"
- "1:"
- :
- : "r"(&result->value),
- "r"(&op1->value),
- "r"(&op2->value),
- "n"(IS_LONG),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "rax","cc");
+ __asm__(
+ "movq (%1), %%rax\n\t"
+ "addq (%2), %%rax\n\t"
+ "jo 0f\n\t"
+ "movq %%rax, (%0)\n\t"
+ "movl %3, %c5(%0)\n\t"
+ "jmp 1f\n"
+ "0:\n\t"
+ "fildq (%1)\n\t"
+ "fildq (%2)\n\t"
+ "faddp %%st, %%st(1)\n\t"
+ "movl %4, %c5(%0)\n\t"
+ "fstpl (%0)\n"
+ "1:"
+ :
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "rax","cc");
#elif defined(__GNUC__) && defined(__powerpc64__)
- __asm__(
- "ld 14, 0(%1)\n\t"
- "ld 15, 0(%2)\n\t"
- "li 16, 0 \n\t"
- "mtxer 16\n\t"
- "addo. 14, 14, 15\n\t"
- "bso- 0f\n\t"
- "std 14, 0(%0)\n\t"
- "li 14, %3\n\t"
- "stw 14, %c5(%0)\n\t"
- "b 1f\n"
- "0:\n\t"
- "lfd 0, 0(%1)\n\t"
- "lfd 1, 0(%2)\n\t"
- "fcfid 0, 0\n\t"
- "fcfid 1, 1\n\t"
- "fadd 0, 0, 1\n\t"
- "li 14, %4\n\t"
- "stw 14, %c5(%0)\n\t"
- "stfd 0, 0(%0)\n"
- "1:"
- :
- : "r"(&result->value),
- "r"(&op1->value),
- "r"(&op2->value),
- "n"(IS_LONG),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "r14","r15","r16","fr0","fr1","cc");
+ __asm__(
+ "ld 14, 0(%1)\n\t"
+ "ld 15, 0(%2)\n\t"
+ "li 16, 0 \n\t"
+ "mtxer 16\n\t"
+ "addo. 14, 14, 15\n\t"
+ "bso- 0f\n\t"
+ "std 14, 0(%0)\n\t"
+ "li 14, %3\n\t"
+ "stw 14, %c5(%0)\n\t"
+ "b 1f\n"
+ "0:\n\t"
+ "lfd 0, 0(%1)\n\t"
+ "lfd 1, 0(%2)\n\t"
+ "fcfid 0, 0\n\t"
+ "fcfid 1, 1\n\t"
+ "fadd 0, 0, 1\n\t"
+ "li 14, %4\n\t"
+ "stw 14, %c5(%0)\n\t"
+ "stfd 0, 0(%0)\n"
+ "1:"
+ :
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "r14","r15","r16","fr0","fr1","cc");
#else
- /*
- * 'result' may alias with op1 or op2, so we need to
- * ensure that 'result' is not updated until after we
- * have read the values of op1 and op2.
- */
-
- if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
- && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
- ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
- } else {
- ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
- }
+ /*
+ * 'result' may alias with op1 or op2, so we need to
+ * ensure that 'result' is not updated until after we
+ * have read the values of op1 and op2.
+ */
+
+ if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) == (Z_LVAL_P(op2) & LONG_SIGN_MASK)
+ && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != ((Z_LVAL_P(op1) + Z_LVAL_P(op2)) & LONG_SIGN_MASK))) {
+ ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2));
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
+ }
#endif
+}
+
+static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2)
+{
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ fast_long_add_function(result, op1, op2);
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
@@ -684,142 +681,100 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o
return add_function(result, op1, op2);
}
-static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *op2)
+static zend_always_inline void fast_long_sub_function(zval *result, zval *op1, zval *op2)
{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
#if defined(__GNUC__) && defined(__i386__)
- __asm__(
- "movl (%1), %%eax\n\t"
- "subl (%2), %%eax\n\t"
- "jo 0f\n\t"
- "movl %%eax, (%0)\n\t"
- "movl %3, %c5(%0)\n\t"
- "jmp 1f\n"
- "0:\n\t"
- "fildl (%2)\n\t"
- "fildl (%1)\n\t"
+ __asm__(
+ "movl (%1), %%eax\n\t"
+ "subl (%2), %%eax\n\t"
+ "jo 0f\n\t"
+ "movl %%eax, (%0)\n\t"
+ "movl %3, %c5(%0)\n\t"
+ "jmp 1f\n"
+ "0:\n\t"
+ "fildl (%2)\n\t"
+ "fildl (%1)\n\t"
#if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
- "fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */
+ "fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */
#else
- "fsubp %%st, %%st(1)\n\t"
+ "fsubp %%st, %%st(1)\n\t"
#endif
- "movl %4, %c5(%0)\n\t"
- "fstpl (%0)\n"
- "1:"
- :
- : "r"(&result->value),
- "r"(&op1->value),
- "r"(&op2->value),
- "n"(IS_LONG),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "eax","cc");
+ "movl %4, %c5(%0)\n\t"
+ "fstpl (%0)\n"
+ "1:"
+ :
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "eax","cc");
#elif defined(__GNUC__) && defined(__x86_64__)
- __asm__(
- "movq (%1), %%rax\n\t"
- "subq (%2), %%rax\n\t"
- "jo 0f\n\t"
- "movq %%rax, (%0)\n\t"
- "movl %3, %c5(%0)\n\t"
- "jmp 1f\n"
- "0:\n\t"
- "fildq (%2)\n\t"
- "fildq (%1)\n\t"
+ __asm__(
+ "movq (%1), %%rax\n\t"
+ "subq (%2), %%rax\n\t"
+ "jo 0f\n\t"
+ "movq %%rax, (%0)\n\t"
+ "movl %3, %c5(%0)\n\t"
+ "jmp 1f\n"
+ "0:\n\t"
+ "fildq (%2)\n\t"
+ "fildq (%1)\n\t"
#if defined(__clang__) && (__clang_major__ < 2 || (__clang_major__ == 2 && __clang_minor__ < 10))
- "fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */
+ "fsubp %%st(1), %%st\n\t" /* LLVM bug #9164 */
#else
- "fsubp %%st, %%st(1)\n\t"
+ "fsubp %%st, %%st(1)\n\t"
#endif
- "movl %4, %c5(%0)\n\t"
- "fstpl (%0)\n"
- "1:"
- :
- : "r"(&result->value),
- "r"(&op1->value),
- "r"(&op2->value),
- "n"(IS_LONG),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "rax","cc");
+ "movl %4, %c5(%0)\n\t"
+ "fstpl (%0)\n"
+ "1:"
+ :
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "rax","cc");
#elif defined(__GNUC__) && defined(__powerpc64__)
- __asm__(
- "ld 14, 0(%1)\n\t"
- "ld 15, 0(%2)\n\t"
- "li 16, 0\n\t"
- "mtxer 16\n\t"
- "subo. 14, 14, 15\n\t"
- "bso- 0f\n\t"
- "std 14, 0(%0)\n\t"
- "li 14, %3\n\t"
- "stw 14, %c5(%0)\n\t"
- "b 1f\n"
- "0:\n\t"
- "lfd 0, 0(%1)\n\t"
- "lfd 1, 0(%2)\n\t"
- "fcfid 0, 0\n\t"
- "fcfid 1, 1\n\t"
- "fsub 0, 0, 1\n\t"
- "li 14, %4\n\t"
- "stw 14, %c5(%0)\n\t"
- "stfd 0, 0(%0)\n"
- "1:"
- :
- : "r"(&result->value),
- "r"(&op1->value),
- "r"(&op2->value),
- "n"(IS_LONG),
- "n"(IS_DOUBLE),
- "n"(ZVAL_OFFSETOF_TYPE)
- : "r14","r15","r16","fr0","fr1","cc");
+ __asm__(
+ "ld 14, 0(%1)\n\t"
+ "ld 15, 0(%2)\n\t"
+ "li 16, 0\n\t"
+ "mtxer 16\n\t"
+ "subo. 14, 14, 15\n\t"
+ "bso- 0f\n\t"
+ "std 14, 0(%0)\n\t"
+ "li 14, %3\n\t"
+ "stw 14, %c5(%0)\n\t"
+ "b 1f\n"
+ "0:\n\t"
+ "lfd 0, 0(%1)\n\t"
+ "lfd 1, 0(%2)\n\t"
+ "fcfid 0, 0\n\t"
+ "fcfid 1, 1\n\t"
+ "fsub 0, 0, 1\n\t"
+ "li 14, %4\n\t"
+ "stw 14, %c5(%0)\n\t"
+ "stfd 0, 0(%0)\n"
+ "1:"
+ :
+ : "r"(&result->value),
+ "r"(&op1->value),
+ "r"(&op2->value),
+ "n"(IS_LONG),
+ "n"(IS_DOUBLE),
+ "n"(ZVAL_OFFSETOF_TYPE)
+ : "r14","r15","r16","fr0","fr1","cc");
#else
- ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
+ ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
- if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
- && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
- ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
- }
-#endif
- return SUCCESS;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
- return SUCCESS;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
- return SUCCESS;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
- return SUCCESS;
- }
- }
- return sub_function(result, op1, op2);
-}
-
-static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *op2)
-{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- zend_long overflow;
-
- ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
- Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
- return SUCCESS;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
- return SUCCESS;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
- return SUCCESS;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
- return SUCCESS;
- }
+ if (UNEXPECTED((Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(op2) & LONG_SIGN_MASK)
+ && (Z_LVAL_P(op1) & LONG_SIGN_MASK) != (Z_LVAL_P(result) & LONG_SIGN_MASK))) {
+ ZVAL_DOUBLE(result, (double) Z_LVAL_P(op1) - (double) Z_LVAL_P(op2));
}
- return mul_function(result, op1, op2);
+#endif
}
static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2)
@@ -873,26 +828,6 @@ static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *o
return div_function(result, op1, op2);
}
-static zend_always_inline int fast_mod_function(zval *result, zval *op1, zval *op2)
-{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
- zend_error(E_WARNING, "Division by zero");
- ZVAL_FALSE(result);
- return FAILURE;
- } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
- /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
- ZVAL_LONG(result, 0);
- return SUCCESS;
- }
- ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
- return SUCCESS;
- }
- }
- return mod_function(result, op1, op2);
-}
-
static zend_always_inline int fast_equal_check_function(zval *op1, zval *op2)
{
zval result;
@@ -957,134 +892,6 @@ static zend_always_inline int fast_equal_check_string(zval *op1, zval *op2)
return Z_LVAL(result) == 0;
}
-static zend_always_inline void fast_equal_function(zval *result, zval *op1, zval *op2)
-{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_LVAL_P(op1) == Z_LVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
- return;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) == Z_DVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
- return;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
- if (Z_STR_P(op1) == Z_STR_P(op2)) {
- ZVAL_TRUE(result);
- return;
- } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
- if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
- ZVAL_FALSE(result);
- return;
- } else {
- ZVAL_BOOL(result, memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
- return;
- }
- } else {
- ZVAL_BOOL(result, zendi_smart_strcmp(op1, op2) == 0);
- return;
- }
- }
- }
- compare_function(result, op1, op2);
- ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
-}
-
-static zend_always_inline void fast_not_equal_function(zval *result, zval *op1, zval *op2)
-{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_LVAL_P(op1) != Z_LVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
- return;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) != Z_DVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
- return;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
- if (Z_STR_P(op1) == Z_STR_P(op2)) {
- ZVAL_FALSE(result);
- return;
- } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
- if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
- ZVAL_TRUE(result);
- return;
- } else {
- ZVAL_BOOL(result, memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
- return;
- }
- } else {
- ZVAL_BOOL(result, zendi_smart_strcmp(op1, op2) != 0);
- return;
- }
- }
- }
- compare_function(result, op1, op2);
- ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
-}
-
-static zend_always_inline void fast_is_smaller_function(zval *result, zval *op1, zval *op2)
-{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_LVAL_P(op1) < Z_LVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
- return;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) < Z_DVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
- return;
- }
- }
- compare_function(result, op1, op2);
- ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
-}
-
-static zend_always_inline void fast_is_smaller_or_equal_function(zval *result, zval *op1, zval *op2)
-{
- if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_LVAL_P(op1) <= Z_LVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
- return;
- }
- } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
- if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) <= Z_DVAL_P(op2));
- return;
- } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
- ZVAL_BOOL(result, Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
- return;
- }
- }
- compare_function(result, op1, op2);
- ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
-}
-
static zend_always_inline void fast_is_identical_function(zval *result, zval *op1, zval *op2)
{
if (Z_TYPE_P(op1) != Z_TYPE_P(op2)) {
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index c6fff78158..079231b8cc 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -29,11 +29,40 @@ ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -44,11 +73,40 @@ ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -59,11 +117,43 @@ ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -89,11 +179,36 @@ ZEND_VM_HANDLER(5, ZEND_MOD, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -180,12 +295,64 @@ ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -196,12 +363,64 @@ ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+ FREE_OP1();
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -212,12 +431,38 @@ ZEND_VM_HANDLER(19, ZEND_IS_SMALLER, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -228,12 +473,38 @@ ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@@ -961,17 +1232,17 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
+ var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
- fast_increment_function(var_ptr);
+ fast_long_increment_function(var_ptr);
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
}
@@ -982,10 +1253,13 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
SEPARATE_ZVAL_NOREF(var_ptr);
@@ -1006,17 +1280,17 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
+ var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
- fast_decrement_function(var_ptr);
+ fast_long_decrement_function(var_ptr);
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
}
@@ -1027,10 +1301,13 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
SEPARATE_ZVAL_NOREF(var_ptr);
@@ -1051,10 +1328,10 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
+ var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
@@ -1062,16 +1339,19 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
- fast_increment_function(var_ptr);
+ fast_long_increment_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
zval_opt_copy_ctor(var_ptr);
@@ -1089,10 +1369,10 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = GET_OP1_ZVAL_PTR_PTR(BP_VAR_RW);
+ var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
FREE_OP1_VAR_PTR();
HANDLE_EXCEPTION();
@@ -1100,16 +1380,19 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
- fast_decrement_function(var_ptr);
+ fast_long_decrement_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (OP1_TYPE == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
zval_opt_copy_ctor(var_ptr);
@@ -4210,13 +4493,60 @@ ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
- SAVE_OPLINE();
- fast_equal_function(result,
- GET_OP1_ZVAL_PTR(BP_VAR_R),
- GET_OP2_ZVAL_PTR(BP_VAR_R));
+ op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
+ op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ FREE_OP2();
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
+ SAVE_OPLINE();
+ if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (OP2_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
FREE_OP2();
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index a9ad8deec4..9dcf0ad462 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -3865,11 +3865,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -3880,11 +3909,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -3895,11 +3953,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -3925,11 +4015,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CONST_HANDLER(Z
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -4016,12 +4131,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CONST_HAND
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
@@ -4032,12 +4199,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CONST_
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
CHECK_EXCEPTION();
@@ -4048,12 +4267,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CONST_HA
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
CHECK_EXCEPTION();
@@ -4064,12 +4309,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
CHECK_EXCEPTION();
@@ -4800,12 +5071,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- EX_CONSTANT(opline->op1),
- EX_CONSTANT(opline->op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -7073,11 +7392,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -7088,11 +7436,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -7103,11 +7480,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -7133,11 +7542,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_CV_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -7224,12 +7658,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_CV_HANDLER
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
@@ -7240,12 +7726,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_CV_HAN
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
CHECK_EXCEPTION();
@@ -7256,12 +7794,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_CV_HANDL
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
CHECK_EXCEPTION();
@@ -7272,12 +7836,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
CHECK_EXCEPTION();
@@ -7850,12 +8440,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CV_HANDLER(ZEN
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -8296,11 +8934,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CONST_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8311,11 +8978,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CONST_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8326,11 +9022,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CONST_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8356,11 +9084,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CONST_TMPVAR_HANDLER(
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8416,12 +9169,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CONST_TMPVAR_HAN
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8432,12 +9237,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CONST_TMPVAR
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8448,12 +9305,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CONST_TMPVAR_H
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8464,12 +9347,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CONST
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -8994,13 +9903,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
- SAVE_OPLINE();
- fast_equal_function(result,
- EX_CONSTANT(opline->op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = EX_CONSTANT(opline->op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
+ SAVE_OPLINE();
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -11934,17 +12890,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
- fast_increment_function(var_ptr);
+ fast_long_increment_function(var_ptr);
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
}
@@ -11955,10 +12911,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_VAR_HANDLER(ZEND_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
SEPARATE_ZVAL_NOREF(var_ptr);
@@ -11979,17 +12938,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
- fast_decrement_function(var_ptr);
+ fast_long_decrement_function(var_ptr);
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
}
@@ -12000,10 +12959,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_VAR_HANDLER(ZEND_
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
SEPARATE_ZVAL_NOREF(var_ptr);
@@ -12024,10 +12986,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
@@ -12035,16 +12997,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_VAR_HANDLER(ZEND
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
- fast_increment_function(var_ptr);
+ fast_long_increment_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
zval_opt_copy_ctor(var_ptr);
@@ -12062,10 +13027,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND
zend_free_op free_op1;
zval *var_ptr;
- SAVE_OPLINE();
var_ptr = _get_zval_ptr_ptr_var(opline->op1.var, execute_data, &free_op1);
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
if (free_op1) {zval_ptr_dtor_nogc(free_op1);};
HANDLE_EXCEPTION();
@@ -12073,16 +13038,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_VAR_HANDLER(ZEND
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
- fast_decrement_function(var_ptr);
+ fast_long_decrement_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (IS_VAR == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_VAR == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
zval_opt_copy_ctor(var_ptr);
@@ -24699,17 +25667,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_O
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var);
+ var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
HANDLE_EXCEPTION();
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
- fast_increment_function(var_ptr);
+ fast_long_increment_function(var_ptr);
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
}
@@ -24720,10 +25688,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_INC_SPEC_CV_HANDLER(ZEND_O
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
SEPARATE_ZVAL_NOREF(var_ptr);
@@ -24743,17 +25714,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_O
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var);
+ var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
HANDLE_EXCEPTION();
}
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
- fast_decrement_function(var_ptr);
+ fast_long_decrement_function(var_ptr);
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
}
@@ -24764,10 +25735,13 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_PRE_DEC_SPEC_CV_HANDLER(ZEND_O
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
ZVAL_NULL(EX_VAR(opline->result.var));
}
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
SEPARATE_ZVAL_NOREF(var_ptr);
@@ -24787,10 +25761,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var);
+ var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
HANDLE_EXCEPTION();
@@ -24798,16 +25772,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_INC_SPEC_CV_HANDLER(ZEND_
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
- fast_increment_function(var_ptr);
+ fast_long_increment_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
zval_opt_copy_ctor(var_ptr);
@@ -24824,10 +25801,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_
zval *var_ptr;
- SAVE_OPLINE();
- var_ptr = _get_zval_ptr_cv_BP_VAR_RW(execute_data, opline->op1.var);
+ var_ptr = _get_zval_ptr_cv_undef_BP_VAR_RW(execute_data, opline->op1.var);
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == NULL)) {
+ SAVE_OPLINE();
zend_error(E_EXCEPTION | E_ERROR, "Cannot increment/decrement overloaded objects nor string offsets");
HANDLE_EXCEPTION();
@@ -24835,16 +25812,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_POST_DEC_SPEC_CV_HANDLER(ZEND_
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
- fast_decrement_function(var_ptr);
+ fast_long_decrement_function(var_ptr);
ZEND_VM_NEXT_OPCODE();
}
if (IS_CV == IS_VAR && UNEXPECTED(var_ptr == &EG(error_zval))) {
ZVAL_NULL(EX_VAR(opline->result.var));
- CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
}
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(var_ptr) == IS_UNDEF)) {
+ var_ptr = GET_OP1_UNDEF_CV(var_ptr, BP_VAR_RW);
+ }
ZVAL_DEREF(var_ptr);
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
zval_opt_copy_ctor(var_ptr);
@@ -26193,11 +27173,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CONST_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -26208,11 +27217,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CONST_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -26223,11 +27261,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CONST_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -26253,11 +27323,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CONST_HANDLER(ZEND
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -26344,12 +27439,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CONST_HANDLER
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
@@ -26360,12 +27507,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CONST_HAN
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
CHECK_EXCEPTION();
@@ -26376,12 +27575,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CONST_HANDL
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
CHECK_EXCEPTION();
@@ -26392,12 +27617,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CO
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
CHECK_EXCEPTION();
@@ -27943,12 +29194,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEN
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- EX_CONSTANT(opline->op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -30768,11 +32067,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_CV_HANDLER(ZEND_OP
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30783,11 +32111,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_CV_HANDLER(ZEND_OP
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30798,11 +32155,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_CV_HANDLER(ZEND_OP
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30828,11 +32217,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_CV_HANDLER(ZEND_OP
{
USE_OPLINE
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
CHECK_EXCEPTION();
@@ -30919,12 +32333,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_CV_HANDLER(ZE
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
@@ -30935,12 +32401,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_CV_HANDLE
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
CHECK_EXCEPTION();
@@ -30951,12 +32469,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_CV_HANDLER(
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
CHECK_EXCEPTION();
@@ -30967,12 +32511,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_CV
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
CHECK_EXCEPTION();
@@ -32371,12 +33941,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_O
{
USE_OPLINE
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -32950,11 +34568,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_CV_TMPVAR_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -32965,11 +34612,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_CV_TMPVAR_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -32980,11 +34656,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_CV_TMPVAR_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -33010,11 +34718,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_CV_TMPVAR_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -33070,12 +34803,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_CV_TMPVAR_HANDLE
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -33086,12 +34871,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_CV_TMPVAR_HA
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -33102,12 +34939,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_CV_TMPVAR_HAND
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -33118,12 +34981,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_CV_TM
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -34435,13 +36324,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZE
{
USE_OPLINE
zend_free_op free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
- SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op1.var),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_cv_undef(execute_data, opline->op1.var);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
+ SAVE_OPLINE();
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -35437,11 +37373,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_CONST_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -35452,11 +37417,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_CONST_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -35467,11 +37461,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_CONST_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -35497,11 +37523,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_CONST_HANDLER(
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -35557,12 +37608,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CONST_HAN
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -35573,12 +37676,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CONST
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -35589,12 +37744,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_CONST_H
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -35605,12 +37786,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVA
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -36095,12 +38302,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = EX_CONSTANT(opline->op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- EX_CONSTANT(opline->op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CONST == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -37249,11 +39504,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_CV_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37264,11 +39548,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_CV_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37279,11 +39592,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_CV_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37309,11 +39654,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_CV_HANDLER(ZEN
{
USE_OPLINE
zend_free_op free_op1;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37369,12 +39739,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_CV_HANDLE
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37385,12 +39807,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_CV_HA
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+ zval_ptr_dtor_nogc(free_op1);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37401,12 +39875,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_CV_HAND
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37417,12 +39917,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVA
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
zval_ptr_dtor_nogc(free_op1);
CHECK_EXCEPTION();
@@ -37697,12 +40223,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZE
{
USE_OPLINE
zend_free_op free_op1;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_cv_undef(execute_data, opline->op2.var);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if (IS_CV == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
@@ -37883,11 +40457,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_SPEC_TMPVAR_TMPVAR_HANDLER
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_add_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_add_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ add_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -37898,11 +40501,40 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_SUB_SPEC_TMPVAR_TMPVAR_HANDLER
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ fast_long_sub_function(result, op1, op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_sub_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ sub_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -37913,11 +40545,43 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MUL_SPEC_TMPVAR_TMPVAR_HANDLER
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ zend_long overflow;
+
+ result = EX_VAR(opline->result.var);
+ ZEND_SIGNED_MULTIPLY_LONG(Z_LVAL_P(op1), Z_LVAL_P(op2), Z_LVAL_P(result), Z_DVAL_P(result), overflow);
+ Z_TYPE_INFO_P(result) = overflow ? IS_DOUBLE : IS_LONG;
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ ZVAL_DOUBLE(result, Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mul_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mul_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -37943,11 +40607,36 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_MOD_SPEC_TMPVAR_TMPVAR_HANDLER
{
USE_OPLINE
zend_free_op free_op1, free_op2;
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ result = EX_VAR(opline->result.var);
+ if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
+ // TODO: change into exception ???
+ SAVE_OPLINE();
+ zend_error(E_WARNING, "Division by zero");
+ ZVAL_FALSE(result);
+ } else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
+ /* Prevent overflow error/crash if op1==ZEND_LONG_MIN */
+ ZVAL_LONG(result, 0);
+ } else {
+ ZVAL_LONG(result, Z_LVAL_P(op1) % Z_LVAL_P(op2));
+ }
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_mod_function(EX_VAR(opline->result.var),
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ mod_function(EX_VAR(opline->result.var), op1, op2);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38003,12 +40692,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_EQUAL_SPEC_TMPVAR_TMPVAR_HA
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38019,12 +40760,64 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_NOT_EQUAL_SPEC_TMPVAR_TMPVA
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) != Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) != 0);
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) != 0);
+ zval_ptr_dtor_nogc(free_op1);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
SAVE_OPLINE();
- fast_not_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) != 0);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38035,12 +40828,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_SPEC_TMPVAR_TMPVAR_
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) < Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) < 0);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38051,12 +40870,38 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_IS_SMALLER_OR_EQUAL_SPEC_TMPVA
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
+
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) <= Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
SAVE_OPLINE();
- fast_is_smaller_or_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) <= 0);
zval_ptr_dtor_nogc(free_op1);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
@@ -38333,13 +41178,60 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLE
{
USE_OPLINE
zend_free_op free_op1, free_op2;
- zval *result = EX_VAR(opline->result.var);
+ zval *op1, *op2, *result;
- SAVE_OPLINE();
- fast_equal_function(result,
- _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1),
- _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2));
+ op1 = _get_zval_ptr_var(opline->op1.var, execute_data, &free_op1);
+ op2 = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
+ if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_LVAL_P(op1) == Z_LVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), (double)Z_LVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == Z_DVAL_P(op2));
+ ZEND_VM_NEXT_OPCODE();
+ } else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
+ ZVAL_BOOL(EX_VAR(opline->result.var), Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2)));
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else if (EXPECTED(Z_TYPE_P(op1) == IS_STRING)) {
+ if (EXPECTED(Z_TYPE_P(op2) == IS_STRING)) {
+ if (Z_STR_P(op1) == Z_STR_P(op2)) {
+ ZVAL_TRUE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else if (Z_STRVAL_P(op1)[0] > '9' || Z_STRVAL_P(op2)[0] > '9') {
+ if (Z_STRLEN_P(op1) != Z_STRLEN_P(op2)) {
+ ZVAL_FALSE(EX_VAR(opline->result.var));
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ } else {
+ ZVAL_BOOL(EX_VAR(opline->result.var), zendi_smart_strcmp(op1, op2) == 0);
+ zval_ptr_dtor_nogc(free_op2);
+ ZEND_VM_NEXT_OPCODE();
+ }
+ }
+ }
+ SAVE_OPLINE();
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op1) == IS_UNDEF)) {
+ op1 = GET_OP1_UNDEF_CV(op1, BP_VAR_R);
+ }
+ if ((IS_TMP_VAR|IS_VAR) == IS_CV && UNEXPECTED(Z_TYPE_P(op2) == IS_UNDEF)) {
+ op2 = GET_OP2_UNDEF_CV(op2, BP_VAR_R);
+ }
+ result = EX_VAR(opline->result.var);
+ compare_function(result, op1, op2);
+ ZVAL_BOOL(result, Z_LVAL_P(result) == 0);
zval_ptr_dtor_nogc(free_op2);
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php
index cd0fb378b0..a4eac1dcd7 100644
--- a/Zend/zend_vm_gen.php
+++ b/Zend/zend_vm_gen.php
@@ -199,6 +199,26 @@ $op2_get_zval_ptr_deref = array(
"TMPVAR" => "???",
);
+$op1_get_zval_ptr_undef = array(
+ "ANY" => "get_zval_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)",
+ "TMP" => "_get_zval_ptr_tmp(opline->op1.var, execute_data, &free_op1)",
+ "VAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)",
+ "CONST" => "EX_CONSTANT(opline->op1)",
+ "UNUSED" => "NULL",
+ "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op1.var)",
+ "TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)",
+);
+
+$op2_get_zval_ptr_undef = array(
+ "ANY" => "get_zval_ptr_undef(opline->op2_type, opline->op2, execute_data, &free_op2, \\1)",
+ "TMP" => "_get_zval_ptr_tmp(opline->op2.var, execute_data, &free_op2)",
+ "VAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)",
+ "CONST" => "EX_CONSTANT(opline->op2)",
+ "UNUSED" => "NULL",
+ "CV" => "_get_zval_ptr_cv_undef(execute_data, opline->op2.var)",
+ "TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)",
+);
+
$op1_get_zval_ptr_ptr_undef = array(
"ANY" => "get_zval_ptr_ptr_undef(opline->op1_type, opline->op1, execute_data, &free_op1, \\1)",
"TMP" => "NULL",
@@ -425,6 +445,7 @@ function helper_name($name, $spec, $op1, $op2) {
function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
global $op1_type, $op2_type, $op1_get_zval_ptr, $op2_get_zval_ptr,
$op1_get_zval_ptr_deref, $op2_get_zval_ptr_deref,
+ $op1_get_zval_ptr_undef, $op2_get_zval_ptr_undef,
$op1_get_zval_ptr_ptr, $op2_get_zval_ptr_ptr,
$op1_get_zval_ptr_ptr_undef, $op2_get_zval_ptr_ptr_undef,
$op1_get_obj_zval_ptr, $op2_get_obj_zval_ptr,
@@ -446,6 +467,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
"/GET_OP2_ZVAL_PTR\(([^)]*)\)/",
"/GET_OP1_ZVAL_PTR_DEREF\(([^)]*)\)/",
"/GET_OP2_ZVAL_PTR_DEREF\(([^)]*)\)/",
+ "/GET_OP1_ZVAL_PTR_UNDEF\(([^)]*)\)/",
+ "/GET_OP2_ZVAL_PTR_UNDEF\(([^)]*)\)/",
"/GET_OP1_ZVAL_PTR_PTR\(([^)]*)\)/",
"/GET_OP2_ZVAL_PTR_PTR\(([^)]*)\)/",
"/GET_OP1_ZVAL_PTR_PTR_UNDEF\(([^)]*)\)/",
@@ -486,6 +509,8 @@ function gen_code($f, $spec, $kind, $export, $code, $op1, $op2, $name) {
$op2_get_zval_ptr[$op2],
$op1_get_zval_ptr_deref[$op1],
$op2_get_zval_ptr_deref[$op2],
+ $op1_get_zval_ptr_undef[$op1],
+ $op2_get_zval_ptr_undef[$op2],
$op1_get_zval_ptr_ptr[$op1],
$op2_get_zval_ptr_ptr[$op2],
$op1_get_zval_ptr_ptr_undef[$op1],