]> granicus.if.org Git - php/commitdiff
Embed "fast" operator functions (add, sub, increment, etc) into executor with additio...
authorDmitry Stogov <dmitry@zend.com>
Tue, 17 Mar 2015 15:53:19 +0000 (18:53 +0300)
committerDmitry Stogov <dmitry@zend.com>
Tue, 17 Mar 2015 15:53:19 +0000 (18:53 +0300)
Zend/zend_execute.c
Zend/zend_operators.c
Zend/zend_operators.h
Zend/zend_vm_def.h
Zend/zend_vm_execute.h
Zend/zend_vm_gen.php

index 17e68dc55d375bde24955a86ff1357e1e4fe2985..42e96737444e7b86e544235bb452abef7baab1ac 100644 (file)
@@ -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)
index 7c2348986486a3b8780d004a10e363cb1c1ddb7a..d8e92a97ad1c088f855c6c3a3e485162aece1701 100644 (file)
@@ -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)) {
index b656e435b2fe6af24fedf9720c2f122b0a7a1ae2..e2e9abfaae8d841cb6393920c6236eadb788eeda 100644 (file)
@@ -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)) {
index c6fff781588744f8b791a04d15b15d0990128497..079231b8cc8d7d65759bbb7150bf8c294eaf5916 100644 (file)
@@ -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();
index a9ad8deec4f119ff8b5401d91e725ac87f1f1687..9dcf0ad462e141c9a17531be83a61433af844189 100644 (file)
@@ -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();
index cd0fb378b0071b5ac72cf0f3dc7972b67433e1c5..a4eac1dcd7f2c79e0bfa43f09a25ebfdc1ee5301 100644 (file)
@@ -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],