Browse Source

Arithmetic speedup. Inlined most probable code-paths for arithmetic operations directly into executor.

pull/7/head
Dmitry Stogov 15 years ago
parent
commit
b7eb3c1c5a
  1. 2
      NEWS
  2. 12
      Zend/zend_multiply.h
  3. 3
      Zend/zend_operators.c
  4. 416
      Zend/zend_operators.h
  5. 46
      Zend/zend_vm_def.h
  6. 512
      Zend/zend_vm_execute.h

2
NEWS

@ -80,6 +80,8 @@ PHP NEWS
opcode operands into a separate literal table. (Dmitry)
- Improved Zend Engine, performance tweaks and optimizations: (Dmitry)
. Inlined most probable code-paths for arithmetic operations directly into
executor
. Eliminated unnecessary iterations during request startup/shutdown.
. Changed $GLOBALS into a JIT autoglobal, so it's initialized only if used.
(this may affect opcode caches!)

12
Zend/zend_multiply.h

@ -31,6 +31,18 @@
else (lval) = __tmpvar; \
} while (0)
#elif defined(__x86_64__) && defined(__GNUC__)
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \
long __tmpvar; \
__asm__ ("imulq %3,%0\n" \
"adcq $0,%1" \
: "=r"(__tmpvar),"=r"(usedval) \
: "0"(a), "r"(b), "1"(0)); \
if (usedval) (dval) = (double) (a) * (double) (b); \
else (lval) = __tmpvar; \
} while (0)
#elif SIZEOF_LONG == 4 && defined(HAVE_ZEND_LONG64)
#define ZEND_SIGNED_MULTIPLY_LONG(a, b, lval, dval, usedval) do { \

3
Zend/zend_operators.c

@ -27,13 +27,10 @@
#include "zend_globals.h"
#include "zend_list.h"
#include "zend_API.h"
#include "zend_multiply.h"
#include "zend_strtod.h"
#include "zend_exceptions.h"
#include "zend_closures.h"
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
#if ZEND_USE_TOLOWER_L
#include <locale.h>
static _locale_t current_locale = NULL;

416
Zend/zend_operators.h

@ -31,11 +31,14 @@
#endif
#include "zend_strtod.h"
#include "zend_multiply.h"
#if 0&&HAVE_BCMATH
#include "ext/bcmath/libbcmath/src/bcmath.h"
#endif
#define LONG_SIGN_MASK (1L << (8*sizeof(long)-1))
BEGIN_EXTERN_C()
ZEND_API int add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
@ -448,6 +451,419 @@ ZEND_API void zend_update_current_locale(void);
#define zend_update_current_locale()
#endif
#define offsetof(t,f) \
((int)(&((t*)0)->f))
static zend_always_inline int fast_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"
"movb $0x2,0xc(%0)\n"
"0:"
:
: "r"(op1));
#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"
"movb $0x2,0x14(%0)\n"
"0:"
:
: "r"(op1));
#else
if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MAX)) {
/* switch to double */
Z_DVAL_P(op1) = (double)LONG_MAX + 1.0;
Z_TYPE_P(op1) = IS_DOUBLE;
} else {
Z_LVAL_P(op1)++;
}
#endif
return SUCCESS;
}
return increment_function(op1);
}
static zend_always_inline int fast_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"
"movb $0x2,0xc(%0)\n"
"0:"
:
: "r"(op1));
#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"
"movb $0x2,0x14(%0)\n"
"0:"
:
: "r"(op1));
#else
if (UNEXPECTED(Z_LVAL_P(op1) == LONG_MIN)) {
/* switch to double */
Z_DVAL_P(op1) = (double)LONG_MIN - 1.0;
Z_TYPE_P(op1) = IS_DOUBLE;
} else {
Z_LVAL_P(op1)--;
}
#endif
return SUCCESS;
}
return decrement_function(op1);
}
static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
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"
"movb $0x1,0xc(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildl (%1)\n\t"
"fildl (%2)\n\t"
"faddp %%st, %%st(1)\n\t"
"movb $0x2,0xc(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
: "r"(result),
"r"(op1),
"r"(op2)
: "eax");
#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"
"movb $0x1,0x14(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildq (%1)\n\t"
"fildq (%2)\n\t"
"faddp %%st, %%st(1)\n\t"
"movb $0x2,0x14(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
: "r"(result),
"r"(op1),
"r"(op2)
: "rax");
#else
Z_LVAL_P(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))) {
Z_DVAL_P(result) = (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
} else {
Z_TYPE_P(result) = IS_LONG;
}
#endif
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) + Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
Z_DVAL_P(result) = Z_DVAL_P(op1) + Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
Z_DVAL_P(result) = Z_DVAL_P(op1) + ((double)Z_LVAL_P(op2));
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
}
return add_function(result, op1, op2 TSRMLS_CC);
}
static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
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"
"movb $0x1,0xc(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildl (%2)\n\t"
"fildl (%1)\n\t"
"fsubp %%st, %%st(1)\n\t"
"movb $0x2,0xc(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
: "r"(result),
"r"(op1),
"r"(op2)
: "eax");
#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"
"movb $0x1,0x14(%0)\n\t"
"jmp 1f\n"
"0:\n\t"
"fildq (%2)\n\t"
"fildq (%1)\n\t"
"fsubp %%st, %%st(1)\n\t"
"movb $0x2,0x14(%0)\n\t"
"fstpl (%0)\n"
"1:"
:
: "r"(result),
"r"(op1),
"r"(op2)
: "rax");
#else
Z_LVAL_P(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))) {
Z_DVAL_P(result) = (double) Z_LVAL_P(op1) + (double) Z_LVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
} else {
Z_TYPE_P(result) = IS_LONG;
}
#endif
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) - Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
Z_DVAL_P(result) = Z_DVAL_P(op1) - Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
Z_DVAL_P(result) = Z_DVAL_P(op1) - ((double)Z_LVAL_P(op2));
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
}
return sub_function(result, op1, op2 TSRMLS_CC);
}
static zend_always_inline int fast_mul_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
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_P(result) = overflow ? IS_DOUBLE : IS_LONG;
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) * Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
Z_DVAL_P(result) = Z_DVAL_P(op1) * Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
Z_DVAL_P(result) = Z_DVAL_P(op1) * ((double)Z_LVAL_P(op2));
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
}
return mul_function(result, op1, op2 TSRMLS_CC);
}
static zend_always_inline int fast_div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && 0) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
zend_error(E_WARNING, "Division by zero");
Z_LVAL_P(result) = 0;
Z_TYPE_P(result) = IS_BOOL;
return FAILURE;
} else if (UNEXPECTED(Z_LVAL_P(op2) == -1 && Z_LVAL_P(op1) == LONG_MIN)) {
/* Prevent overflow error/crash */
Z_DVAL_P(result) = (double) LONG_MIN / -1;
Z_TYPE_P(result) = IS_DOUBLE;
} else if (EXPECTED(Z_LVAL_P(op1) % Z_LVAL_P(op2) == 0)) {
/* integer */
Z_LVAL_P(result) = Z_LVAL_P(op1) / Z_LVAL_P(op2);
Z_TYPE_P(result) = IS_LONG;
} else {
Z_DVAL_P(result) = ((double) Z_LVAL_P(op1)) / ((double)Z_LVAL_P(op2));
Z_TYPE_P(result) = IS_DOUBLE;
}
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
zend_error(E_WARNING, "Division by zero");
Z_LVAL_P(result) = 0;
Z_TYPE_P(result) = IS_BOOL;
return FAILURE;
}
Z_DVAL_P(result) = ((double)Z_LVAL_P(op1)) / Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE) && 0) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
if (UNEXPECTED(Z_DVAL_P(op2) == 0)) {
zend_error(E_WARNING, "Division by zero");
Z_LVAL_P(result) = 0;
Z_TYPE_P(result) = IS_BOOL;
return FAILURE;
}
Z_DVAL_P(result) = Z_DVAL_P(op1) / Z_DVAL_P(op2);
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
if (UNEXPECTED(Z_LVAL_P(op2) == 0)) {
zend_error(E_WARNING, "Division by zero");
Z_LVAL_P(result) = 0;
Z_TYPE_P(result) = IS_BOOL;
return FAILURE;
}
Z_DVAL_P(result) = Z_DVAL_P(op1) / ((double)Z_LVAL_P(op2));
Z_TYPE_P(result) = IS_DOUBLE;
return SUCCESS;
}
}
return div_function(result, op1, op2 TSRMLS_CC);
}
static zend_always_inline int fast_mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
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");
Z_LVAL_P(result) = 0;
Z_TYPE_P(result) = IS_BOOL;
return FAILURE;
} else if (UNEXPECTED(Z_LVAL_P(op2) == -1)) {
/* Prevent overflow error/crash if op1==LONG_MIN */
Z_LVAL_P(result) = 0;
Z_TYPE_P(result) = IS_LONG;
return SUCCESS;
}
Z_LVAL_P(result) = Z_LVAL_P(op1) % Z_LVAL_P(op2);
Z_TYPE_P(result) = IS_LONG;
return SUCCESS;
}
}
return mod_function(result, op1, op2 TSRMLS_CC);
}
static zend_always_inline int fast_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_LVAL_P(op1) == Z_LVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return ((double)Z_LVAL_P(op1)) == Z_DVAL_P(op2);
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return Z_DVAL_P(op1) == Z_DVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_DVAL_P(op1) == ((double)Z_LVAL_P(op2));
}
}
compare_function(result, op1, op2 TSRMLS_CC);
return Z_LVAL_P(result) == 0;
}
static zend_always_inline int fast_not_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_LVAL_P(op1) != Z_LVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return ((double)Z_LVAL_P(op1)) != Z_DVAL_P(op2);
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return Z_DVAL_P(op1) != Z_DVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_DVAL_P(op1) != ((double)Z_LVAL_P(op2));
}
}
compare_function(result, op1, op2 TSRMLS_CC);
return Z_LVAL_P(result) != 0;
}
static zend_always_inline int fast_is_smaller_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_LVAL_P(op1) < Z_LVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return ((double)Z_LVAL_P(op1)) < Z_DVAL_P(op2);
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return Z_DVAL_P(op1) < Z_DVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_DVAL_P(op1) < ((double)Z_LVAL_P(op2));
}
}
compare_function(result, op1, op2 TSRMLS_CC);
return Z_LVAL_P(result) < 0;
}
static zend_always_inline int fast_is_smaller_or_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
{
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_LVAL_P(op1) <= Z_LVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return ((double)Z_LVAL_P(op1)) <= Z_DVAL_P(op2);
}
} else if (EXPECTED(Z_TYPE_P(op1) == IS_DOUBLE)) {
if (EXPECTED(Z_TYPE_P(op2) == IS_DOUBLE)) {
return Z_DVAL_P(op1) <= Z_DVAL_P(op2);
} else if (EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
return Z_DVAL_P(op1) <= ((double)Z_LVAL_P(op2));
}
}
compare_function(result, op1, op2 TSRMLS_CC);
return Z_LVAL_P(result) <= 0;
}
#endif
/*

46
Zend/zend_vm_def.h

@ -31,7 +31,7 @@ ZEND_VM_HANDLER(1, ZEND_ADD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zend_free_op free_op1, free_op2;
SAVE_OPLINE();
add_function(&EX_T(opline->result.var).tmp_var,
fast_add_function(&EX_T(opline->result.var).tmp_var,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
FREE_OP1();
@ -46,7 +46,7 @@ ZEND_VM_HANDLER(2, ZEND_SUB, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zend_free_op free_op1, free_op2;
SAVE_OPLINE();
sub_function(&EX_T(opline->result.var).tmp_var,
fast_sub_function(&EX_T(opline->result.var).tmp_var,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
FREE_OP1();
@ -61,7 +61,7 @@ ZEND_VM_HANDLER(3, ZEND_MUL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zend_free_op free_op1, free_op2;
SAVE_OPLINE();
mul_function(&EX_T(opline->result.var).tmp_var,
fast_mul_function(&EX_T(opline->result.var).tmp_var,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
FREE_OP1();
@ -76,7 +76,7 @@ ZEND_VM_HANDLER(4, ZEND_DIV, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zend_free_op free_op1, free_op2;
SAVE_OPLINE();
div_function(&EX_T(opline->result.var).tmp_var,
fast_div_function(&EX_T(opline->result.var).tmp_var,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
FREE_OP1();
@ -91,7 +91,7 @@ ZEND_VM_HANDLER(5, ZEND_MOD, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zend_free_op free_op1, free_op2;
SAVE_OPLINE();
mod_function(&EX_T(opline->result.var).tmp_var,
fast_mod_function(&EX_T(opline->result.var).tmp_var,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
FREE_OP1();
@ -184,10 +184,9 @@ ZEND_VM_HANDLER(17, ZEND_IS_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
compare_function(result,
ZVAL_BOOL(result, fast_equal_function(result,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
ZVAL_BOOL(result, (Z_LVAL_P(result) == 0));
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@ -201,10 +200,9 @@ ZEND_VM_HANDLER(18, ZEND_IS_NOT_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
compare_function(result,
ZVAL_BOOL(result, fast_not_equal_function(result,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
ZVAL_BOOL(result, (Z_LVAL_P(result) != 0));
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@ -218,10 +216,9 @@ ZEND_VM_HANDLER(19, ZEND_IS_SMALLER, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV)
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
compare_function(result,
ZVAL_BOOL(result, fast_is_smaller_function(result,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
ZVAL_BOOL(result, (Z_LVAL_P(result) < 0));
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@ -235,10 +232,9 @@ ZEND_VM_HANDLER(20, ZEND_IS_SMALLER_OR_EQUAL, CONST|TMP|VAR|CV, CONST|TMP|VAR|CV
zval *result = &EX_T(opline->result.var).tmp_var;
SAVE_OPLINE();
compare_function(result,
ZVAL_BOOL(result, fast_is_smaller_or_equal_function(result,
GET_OP1_ZVAL_PTR(BP_VAR_R),
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC);
ZVAL_BOOL(result, (Z_LVAL_P(result) <= 0));
GET_OP2_ZVAL_PTR(BP_VAR_R) TSRMLS_CC));
FREE_OP1();
FREE_OP2();
CHECK_EXCEPTION();
@ -824,11 +820,11 @@ ZEND_VM_HANDLER(34, ZEND_PRE_INC, VAR|CV, ANY)
/* proxy object */
zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
Z_ADDREF_P(val);
increment_function(val);
fast_increment_function(val);
Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
zval_ptr_dtor(&val);
} else {
increment_function(*var_ptr);
fast_increment_function(*var_ptr);
}
if (RETURN_VALUE_USED(opline)) {
@ -871,11 +867,11 @@ ZEND_VM_HANDLER(35, ZEND_PRE_DEC, VAR|CV, ANY)
/* proxy object */
zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
Z_ADDREF_P(val);
decrement_function(val);
fast_decrement_function(val);
Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
zval_ptr_dtor(&val);
} else {
decrement_function(*var_ptr);
fast_decrement_function(*var_ptr);
}
if (RETURN_VALUE_USED(opline)) {
@ -919,11 +915,11 @@ ZEND_VM_HANDLER(36, ZEND_POST_INC, VAR|CV, ANY)
/* proxy object */
zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
Z_ADDREF_P(val);
increment_function(val);
fast_increment_function(val);
Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
zval_ptr_dtor(&val);
} else {
increment_function(*var_ptr);
fast_increment_function(*var_ptr);
}
FREE_OP1_VAR_PTR();
@ -962,11 +958,11 @@ ZEND_VM_HANDLER(37, ZEND_POST_DEC, VAR|CV, ANY)
/* proxy object */
zval *val = Z_OBJ_HANDLER_PP(var_ptr, get)(*var_ptr TSRMLS_CC);
Z_ADDREF_P(val);
decrement_function(val);
fast_decrement_function(val);
Z_OBJ_HANDLER_PP(var_ptr, set)(var_ptr, val TSRMLS_CC);
zval_ptr_dtor(&val);
} else {
decrement_function(*var_ptr);
fast_decrement_function(*var_ptr);
}
FREE_OP1_VAR_PTR();

512
Zend/zend_vm_execute.h
File diff suppressed because it is too large
View File

Loading…
Cancel
Save