mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Transparently introduce type-specialized opcode handlers.
This affects only PHP VM, and doesn't change anything else.
This commit is contained in:
parent
3f1e35756c
commit
f4475a2360
@ -40,6 +40,7 @@
|
||||
#include "zend_vm.h"
|
||||
#include "zend_dtrace.h"
|
||||
#include "zend_inheritance.h"
|
||||
#include "zend_type_info.h"
|
||||
|
||||
/* Virtual current working directory support */
|
||||
#include "zend_virtual_cwd.h"
|
||||
@ -2610,6 +2611,20 @@ void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t
|
||||
cleanup_live_vars(execute_data, op_num, catch_op_num);
|
||||
}
|
||||
|
||||
static void zend_swap_operands(zend_op *op) /* {{{ */
|
||||
{
|
||||
znode_op tmp;
|
||||
zend_uchar tmp_type;
|
||||
|
||||
tmp = op->op1;
|
||||
tmp_type = op->op1_type;
|
||||
op->op1 = op->op2;
|
||||
op->op1_type = op->op2_type;
|
||||
op->op2 = tmp;
|
||||
op->op2_type = tmp_type;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef HAVE_GCC_GLOBAL_REGS
|
||||
# if defined(__GNUC__) && ZEND_GCC_VERSION >= 4008 && defined(i386)
|
||||
# define ZEND_VM_FP_GLOBAL_REG "%esi"
|
||||
|
@ -25,6 +25,7 @@ BEGIN_EXTERN_C()
|
||||
|
||||
ZEND_API void zend_vm_use_old_executor(void);
|
||||
ZEND_API void zend_vm_set_opcode_handler(zend_op* opcode);
|
||||
ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* opcode, uint32_t op1_info, uint32_t op2_info, uint32_t res_info);
|
||||
ZEND_API int zend_vm_call_opcode_handler(zend_execute_data *ex);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
@ -8256,4 +8256,397 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, CONST, REF)
|
||||
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) + Z_LVAL_P(op2));
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_ADD_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
fast_long_add_function(result, op1, op2);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_ADD, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_ADD_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) + Z_DVAL_P(op2));
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_SUB_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
fast_long_sub_function(result, op1, op2);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_SUB, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_SUB_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) - Z_DVAL_P(op2));
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG_NO_OVERFLOW, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) * Z_LVAL_P(op2));
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_MUL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
zend_long overflow;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
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();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_MUL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_MUL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2, *result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = EX_VAR(opline->result.var);
|
||||
ZVAL_DOUBLE(result, Z_DVAL_P(op1) * Z_DVAL_P(op2));
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_LVAL_P(op1) == Z_LVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_DVAL_P(op1) == Z_DVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_NOT_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_LVAL_P(op1) != Z_LVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_NOT_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_NOT_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST,COMMUTATIVE))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_DVAL_P(op1) != Z_DVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_LVAL_P(op1) < Z_LVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_DVAL_P(op1) < Z_DVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_LONG && op2_info == MAY_BE_LONG), ZEND_IS_SMALLER_OR_EQUAL_LONG, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_LVAL_P(op1) <= Z_LVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_IS_SMALLER_OR_EQUAL, (op1_info == MAY_BE_DOUBLE && op2_info == MAY_BE_DOUBLE), ZEND_IS_SMALLER_OR_EQUAL_DOUBLE, CONST|TMPVARCV, CONST|TMPVARCV, SPEC(SMART_BRANCH,NO_CONST_CONST))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *op1, *op2;
|
||||
int result;
|
||||
|
||||
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
result = (Z_DVAL_P(op1) <= Z_DVAL_P(op2));
|
||||
ZEND_VM_SMART_BRANCH(result, 0);
|
||||
ZVAL_BOOL(EX_VAR(opline->result.var), result);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
Z_LVAL_P(var_ptr)++;
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == MAY_BE_LONG), ZEND_PRE_INC_LONG, TMPVARCV, ANY, SPEC(RETVAL))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
fast_long_increment_function(var_ptr);
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_INC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
|
||||
fast_long_increment_function(var_ptr);
|
||||
} else {
|
||||
Z_DVAL_P(var_ptr)++;
|
||||
}
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY, SPEC(RETVAL))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
Z_LVAL_P(var_ptr)--;
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == MAY_BE_LONG), ZEND_PRE_DEC_LONG, TMPVARCV, ANY, SPEC(RETVAL))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
fast_long_decrement_function(var_ptr);
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_PRE_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_PRE_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY, SPEC(RETVAL))
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
|
||||
fast_long_decrement_function(var_ptr);
|
||||
} else {
|
||||
Z_DVAL_P(var_ptr)--;
|
||||
}
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG_NO_OVERFLOW, TMPVARCV, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
|
||||
Z_LVAL_P(var_ptr)++;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == MAY_BE_LONG), ZEND_POST_INC_LONG, TMPVARCV, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
|
||||
fast_long_increment_function(var_ptr);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_INC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_INC_LONG_OR_DOUBLE, TMPVARCV, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
|
||||
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
|
||||
fast_long_increment_function(var_ptr);
|
||||
} else {
|
||||
Z_DVAL_P(var_ptr)++;
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (res_info == MAY_BE_LONG && op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG_NO_OVERFLOW, TMPVARCV, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
|
||||
Z_LVAL_P(var_ptr)--;
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == MAY_BE_LONG), ZEND_POST_DEC_LONG, TMPVARCV, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
ZVAL_LONG(EX_VAR(opline->result.var), Z_LVAL_P(var_ptr));
|
||||
fast_long_decrement_function(var_ptr);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_POST_DEC, (op1_info == (MAY_BE_LONG|MAY_BE_DOUBLE)), ZEND_POST_DEC_LONG_OR_DOUBLE, TMPVARCV, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zval *var_ptr;
|
||||
|
||||
var_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_RW);
|
||||
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), var_ptr);
|
||||
if (EXPECTED(Z_TYPE_P(var_ptr) == IS_LONG)) {
|
||||
fast_long_decrement_function(var_ptr);
|
||||
} else {
|
||||
Z_DVAL_P(var_ptr)--;
|
||||
}
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_TYPE_SPEC_HANDLER(ZEND_QM_ASSIGN, (!(op1_info & ((MAY_BE_ANY|MAY_BE_UNDEF)-(MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE)))), ZEND_QM_ASSIGN_NOREF, CONST|TMPVARCV, ANY)
|
||||
{
|
||||
USE_OPLINE
|
||||
zend_free_op free_op1;
|
||||
zval *value;
|
||||
|
||||
value = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
|
||||
ZVAL_COPY_VALUE(EX_VAR(opline->result.var), value);
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
|
||||
ZEND_VM_DEFINE_OP(137, ZEND_OP_DATA);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1053,6 +1053,10 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
|
||||
if ($flags) {
|
||||
$specs[$num] .= " | ".implode("|", $flags);
|
||||
}
|
||||
if ($num >= 256) {
|
||||
$opcodes[$num]['spec_code'] = $specs[$num];
|
||||
unset($specs[$num]);
|
||||
}
|
||||
|
||||
$foreach_op1 = function($do) use ($dsc, $op_types) {
|
||||
return function() use ($do, $dsc, $op_types) {
|
||||
@ -1226,6 +1230,9 @@ function gen_labels($f, $spec, $kind, $prolog, &$specs, $switch_labels = array()
|
||||
}
|
||||
$next++;
|
||||
}
|
||||
if ($num >= 256) {
|
||||
continue;
|
||||
}
|
||||
$next = $num+1;
|
||||
|
||||
//ugly trick for ZEND_VM_DEFINE_OP
|
||||
@ -1430,11 +1437,13 @@ function gen_executor_code($f, $spec, $kind, $prolog, &$switch_labels = array())
|
||||
foreach ($list as $lineno => $dsc) {
|
||||
if (isset($dsc["handler"])) {
|
||||
$num = $dsc["handler"];
|
||||
// Generate handler code
|
||||
gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno);
|
||||
// Generate handler code
|
||||
if ($num < 256) {
|
||||
gen_handler($f, 0, $kind, $opcodes[$num]["op"], "ANY", "ANY", isset($opcodes[$num]["use"]), $opcodes[$num]["code"], $lineno);
|
||||
}
|
||||
} else if (isset($dsc["helper"])) {
|
||||
$num = $dsc["helper"];
|
||||
// Generate helper code
|
||||
// Generate helper code
|
||||
gen_helper($f, 0, $kind, $num, "ANY", "ANY", $helpers[$num]["param"], $helpers[$num]["code"], $lineno, $helpers[$num]["inline"]);
|
||||
} else {
|
||||
var_dump($dsc);
|
||||
@ -1892,6 +1901,7 @@ function gen_vm($def, $skel) {
|
||||
$helper = null;
|
||||
$max_opcode_len = 0;
|
||||
$max_opcode = 0;
|
||||
$extra_num = 256;
|
||||
$export = array();
|
||||
foreach ($in as $line) {
|
||||
++$lineno;
|
||||
@ -1939,6 +1949,48 @@ function gen_vm($def, $skel) {
|
||||
$handler = $code;
|
||||
$helper = null;
|
||||
$list[$lineno] = array("handler"=>$handler);
|
||||
} else if (strpos($line,"ZEND_VM_TYPE_SPEC_HANDLER(") === 0) {
|
||||
// Parsing opcode handler's definition
|
||||
if (preg_match(
|
||||
"/^ZEND_VM_TYPE_SPEC_HANDLER\(\s*([A-Z_]+)\s*,\s*([^,]+),\s*([A-Za-z_]+)\s*,\s*([A-Z_|]+)\s*,\s*([A-Z_|]+)\s*(,\s*([A-Z_|]+)\s*)?(,\s*SPEC\(([A-Z_|=,]+)\)\s*)?\)/",
|
||||
$line,
|
||||
$m) == 0) {
|
||||
die("ERROR ($def:$lineno): Invalid ZEND_VM_TYPE_HANDLER_HANDLER definition.\n");
|
||||
}
|
||||
$orig_op = $m[1];
|
||||
if (!isset($opnames[$orig_op])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$orig_op' is not defined.\n");
|
||||
}
|
||||
$orig_code = $opnames[$orig_op];
|
||||
$condition = $m[2];
|
||||
$code = $extra_num++;
|
||||
$op = $m[3];
|
||||
$op1 = parse_operand_spec($def, $lineno, $m[4], $flags1);
|
||||
$op2 = parse_operand_spec($def, $lineno, $m[5], $flags2);
|
||||
$flags = $flags1 | ($flags2 << 8);
|
||||
if (!empty($m[7])) {
|
||||
$flags |= parse_ext_spec($def, $lineno, $m[7]);
|
||||
}
|
||||
|
||||
if (isset($opcodes[$code])) {
|
||||
die("ERROR ($def:$lineno): Opcode with name '$code' is already defined.\n");
|
||||
}
|
||||
$opcodes[$orig_code]['type_spec'][$code] = $condition;
|
||||
$used_extra_spec["TYPE"] = 1;
|
||||
$opcodes[$code] = array("op"=>$op,"op1"=>$op1,"op2"=>$op2,"code"=>"","flags"=>$flags);
|
||||
if (isset($m[9])) {
|
||||
$opcodes[$code]["spec"] = parse_spec_rules($def, $lineno, $m[9]);
|
||||
if (isset($opcodes[$code]["spec"]["NO_CONST_CONST"])) {
|
||||
$opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_NO_CONST_CONST"];
|
||||
}
|
||||
if (isset($opcodes[$code]["spec"]["COMMUTATIVE"])) {
|
||||
$opcodes[$code]["flags"] |= $vm_op_flags["ZEND_VM_COMMUTATIVE"];
|
||||
}
|
||||
}
|
||||
$opnames[$op] = $code;
|
||||
$handler = $code;
|
||||
$helper = null;
|
||||
$list[$lineno] = array("handler"=>$handler);
|
||||
} else if (strpos($line,"ZEND_VM_HELPER(") === 0 || strpos($line,"ZEND_VM_INLINE_HELPER(") === 0) {
|
||||
// Parsing helper's definition
|
||||
if (preg_match(
|
||||
@ -2065,7 +2117,9 @@ function gen_vm($def, $skel) {
|
||||
foreach ($opcodes as $code => $dsc) {
|
||||
$code = str_pad((string)$code,$code_len," ",STR_PAD_LEFT);
|
||||
$op = str_pad($dsc["op"],$max_opcode_len);
|
||||
fputs($f,"#define $op $code\n");
|
||||
if ($code <= $max_opcode) {
|
||||
fputs($f,"#define $op $code\n");
|
||||
}
|
||||
}
|
||||
|
||||
$code = str_pad((string)$max_opcode,$code_len," ",STR_PAD_LEFT);
|
||||
@ -2153,10 +2207,10 @@ function gen_vm($def, $skel) {
|
||||
gen_executor($f, $skl, ZEND_VM_SPEC, ZEND_VM_KIND, "execute", "zend_init_opcodes_handlers");
|
||||
|
||||
// Generate zend_vm_get_opcode_handler() function
|
||||
out($f, "static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)\n");
|
||||
out($f, "static const void *zend_vm_get_opcode_handler_ex(uint32_t spec, const zend_op* op)\n");
|
||||
out($f, "{\n");
|
||||
if (!ZEND_VM_SPEC) {
|
||||
out($f, "\treturn zend_opcode_handlers[opcode];\n");
|
||||
out($f, "\treturn zend_opcode_handlers[spec];\n");
|
||||
} else {
|
||||
out($f, "\tstatic const int zend_vm_decode[] = {\n");
|
||||
out($f, "\t\t_UNUSED_CODE, /* 0 */\n");
|
||||
@ -2177,7 +2231,6 @@ function gen_vm($def, $skel) {
|
||||
out($f, "\t\t_UNUSED_CODE, /* 15 */\n");
|
||||
out($f, "\t\t_CV_CODE /* 16 = IS_CV */\n");
|
||||
out($f, "\t};\n");
|
||||
out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
|
||||
out($f, "\tuint32_t offset = 0;\n");
|
||||
out($f, "\tif (spec & SPEC_RULE_OP1) offset = offset * 5 + zend_vm_decode[op->op1_type];\n");
|
||||
out($f, "\tif (spec & SPEC_RULE_OP2) offset = offset * 5 + zend_vm_decode[op->op2_type];\n");
|
||||
@ -2203,6 +2256,14 @@ function gen_vm($def, $skel) {
|
||||
out($f, "\treturn zend_opcode_handlers[(spec & SPEC_START_MASK) + offset];\n");
|
||||
}
|
||||
out($f, "}\n\n");
|
||||
out($f, "static const void *zend_vm_get_opcode_handler(zend_uchar opcode, const zend_op* op)\n");
|
||||
out($f, "{\n");
|
||||
if (!ZEND_VM_SPEC) {
|
||||
out($f, "\treturn zend_vm_get_opcode_handler_ex(opcode, op);\n");
|
||||
} else {
|
||||
out($f, "\treturn zend_vm_get_opcode_handler_ex(zend_spec_handlers[opcode], op);\n");
|
||||
}
|
||||
out($f, "}\n\n");
|
||||
|
||||
// Generate zend_vm_get_opcode_handler() function
|
||||
out($f, "ZEND_API void zend_vm_set_opcode_handler(zend_op* op)\n");
|
||||
@ -2210,6 +2271,55 @@ function gen_vm($def, $skel) {
|
||||
out($f, "\top->handler = zend_vm_get_opcode_handler(zend_user_opcodes[op->opcode], op);\n");
|
||||
out($f, "}\n\n");
|
||||
|
||||
// Generate zend_vm_set_opcode_handler_ex() function
|
||||
out($f, "ZEND_API void zend_vm_set_opcode_handler_ex(zend_op* op, uint32_t op1_info, uint32_t op2_info, uint32_t res_info)\n");
|
||||
out($f, "{\n");
|
||||
out($f, "\tzend_uchar opcode = zend_user_opcodes[op->opcode];\n");
|
||||
if (!ZEND_VM_SPEC) {
|
||||
out($f, "\top->handler = zend_vm_get_opcode_handler_ex(opcode, op);\n");
|
||||
} else {
|
||||
out($f, "\tuint32_t spec = zend_spec_handlers[opcode];\n");
|
||||
if (isset($used_extra_spec["TYPE"])) {
|
||||
out($f, "\tswitch (opcode) {\n");
|
||||
foreach($opcodes as $code => $dsc) {
|
||||
if (isset($dsc['type_spec'])) {
|
||||
$orig_op = $dsc['op'];
|
||||
out($f, "\t\tcase $orig_op:\n");
|
||||
$first = true;
|
||||
foreach($dsc['type_spec'] as $code => $condition) {
|
||||
if ($first) {
|
||||
out($f, "\t\t\tif ($condition) {\n");
|
||||
$first = false;
|
||||
} else {
|
||||
out($f, "\t\t\t} else if ($condition) {\n");
|
||||
}
|
||||
$spec_dsc = $opcodes[$code];
|
||||
if (isset($spec_dsc["spec"]["NO_CONST_CONST"])) {
|
||||
out($f, "\t\t\t\tif (op->op1_type == IS_CONST && op->op2_type == IS_CONST) {\n");
|
||||
out($f, "\t\t\t\t\tbreak;\n");
|
||||
out($f, "\t\t\t\t}\n");
|
||||
}
|
||||
out($f, "\t\t\t\tspec = ${spec_dsc['spec_code']};\n");
|
||||
if (isset($spec_dsc["spec"]["COMMUTATIVE"])) {
|
||||
out($f, "\t\t\t\tif (op->op1_type > op->op2_type) {\n");
|
||||
out($f, "\t\t\t\t\tzend_swap_operands(op);\n");
|
||||
out($f, "\t\t\t\t}\n");
|
||||
}
|
||||
}
|
||||
if (!$first) {
|
||||
out($f, "\t\t\t}\n");
|
||||
}
|
||||
out($f, "\t\t\tbreak;\n");
|
||||
}
|
||||
}
|
||||
out($f, "\t\tdefault:\n");
|
||||
out($f, "\t\t\tbreak;\n");
|
||||
out($f, "\t}\n");
|
||||
}
|
||||
out($f, "\top->handler = zend_vm_get_opcode_handler_ex(spec, op);\n");
|
||||
}
|
||||
out($f, "}\n\n");
|
||||
|
||||
// Generate zend_vm_call_opcode_handler() function
|
||||
if (ZEND_VM_KIND == ZEND_VM_KIND_CALL) {
|
||||
out($f, "ZEND_API int zend_vm_call_opcode_handler(zend_execute_data* ex)\n");
|
||||
|
@ -24,39 +24,7 @@
|
||||
#include "zend_bitset.h"
|
||||
|
||||
/* Bitmask for type inference (zend_ssa_var_info.type) */
|
||||
#define MAY_BE_UNDEF (1 << IS_UNDEF)
|
||||
#define MAY_BE_NULL (1 << IS_NULL)
|
||||
#define MAY_BE_FALSE (1 << IS_FALSE)
|
||||
#define MAY_BE_TRUE (1 << IS_TRUE)
|
||||
#define MAY_BE_LONG (1 << IS_LONG)
|
||||
#define MAY_BE_DOUBLE (1 << IS_DOUBLE)
|
||||
#define MAY_BE_STRING (1 << IS_STRING)
|
||||
#define MAY_BE_ARRAY (1 << IS_ARRAY)
|
||||
#define MAY_BE_OBJECT (1 << IS_OBJECT)
|
||||
#define MAY_BE_RESOURCE (1 << IS_RESOURCE)
|
||||
#define MAY_BE_ANY (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_LONG|MAY_BE_DOUBLE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)
|
||||
#define MAY_BE_REF (1 << IS_REFERENCE) /* may be reference */
|
||||
|
||||
#define MAY_BE_ARRAY_SHIFT (IS_REFERENCE)
|
||||
|
||||
#define MAY_BE_ARRAY_OF_NULL (MAY_BE_NULL << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_FALSE (MAY_BE_FALSE << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_TRUE (MAY_BE_TRUE << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_LONG (MAY_BE_LONG << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_DOUBLE (MAY_BE_DOUBLE << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_STRING (MAY_BE_STRING << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_ARRAY (MAY_BE_ARRAY << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_OBJECT (MAY_BE_OBJECT << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_RESOURCE (MAY_BE_RESOURCE << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_ANY (MAY_BE_ANY << MAY_BE_ARRAY_SHIFT)
|
||||
#define MAY_BE_ARRAY_OF_REF (MAY_BE_REF << MAY_BE_ARRAY_SHIFT)
|
||||
|
||||
#define MAY_BE_ARRAY_KEY_LONG (1<<21)
|
||||
#define MAY_BE_ARRAY_KEY_STRING (1<<22)
|
||||
#define MAY_BE_ARRAY_KEY_ANY (MAY_BE_ARRAY_KEY_LONG | MAY_BE_ARRAY_KEY_STRING)
|
||||
|
||||
#define MAY_BE_ERROR (1<<23)
|
||||
#define MAY_BE_CLASS (1<<24)
|
||||
#include "zend_type_info.h"
|
||||
|
||||
#define MAY_BE_IN_REG (1<<25) /* value allocated in CPU register */
|
||||
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "zend_cfg.h"
|
||||
#include "zend_func_info.h"
|
||||
#include "zend_call_graph.h"
|
||||
#include "zend_inference.h"
|
||||
#include "zend_dump.h"
|
||||
|
||||
#ifndef HAVE_DFA_PASS
|
||||
@ -678,6 +679,34 @@ static void zend_redo_pass_two(zend_op_array *op_array)
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_DFA_PASS
|
||||
static void zend_redo_pass_two_ex(zend_op_array *op_array, zend_ssa *ssa)
|
||||
{
|
||||
zend_op *opline, *end;
|
||||
|
||||
opline = op_array->opcodes;
|
||||
end = opline + op_array->last;
|
||||
while (opline < end) {
|
||||
zend_vm_set_opcode_handler_ex(opline,
|
||||
opline->op1_type == IS_UNDEF ? 0 : (OP1_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY)),
|
||||
opline->op2_type == IS_UNDEF ? 0 : (OP2_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY)),
|
||||
(opline->opcode == ZEND_PRE_INC ||
|
||||
opline->opcode == ZEND_PRE_DEC ||
|
||||
opline->opcode == ZEND_POST_INC ||
|
||||
opline->opcode == ZEND_POST_DEC) ?
|
||||
((ssa->ops[opline - op_array->opcodes].op1_def >= 0) ? (OP1_DEF_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY)) : MAY_BE_ANY) :
|
||||
(opline->result_type == IS_UNDEF ? 0 : (RES_INFO() & (MAY_BE_UNDEF|MAY_BE_ANY|MAY_BE_REF|MAY_BE_ARRAY_OF_ANY|MAY_BE_ARRAY_KEY_ANY))));
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
|
||||
}
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
|
||||
}
|
||||
opline++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void zend_optimize_op_array(zend_op_array *op_array,
|
||||
zend_optimizer_ctx *ctx)
|
||||
{
|
||||
@ -810,8 +839,13 @@ int zend_optimize_script(zend_script *script, zend_long optimization_level, zend
|
||||
}
|
||||
|
||||
for (i = 0; i < call_graph.op_arrays_count; i++) {
|
||||
zend_redo_pass_two(call_graph.op_arrays[i]);
|
||||
ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
|
||||
func_info = ZEND_FUNC_INFO(call_graph.op_arrays[i]);
|
||||
if (func_info && func_info->ssa.var_info) {
|
||||
zend_redo_pass_two_ex(call_graph.op_arrays[i], &func_info->ssa);
|
||||
ZEND_SET_FUNC_INFO(call_graph.op_arrays[i], NULL);
|
||||
} else {
|
||||
zend_redo_pass_two(call_graph.op_arrays[i]);
|
||||
}
|
||||
}
|
||||
|
||||
zend_arena_release(&ctx.arena, checkpoint);
|
||||
|
Loading…
Reference in New Issue
Block a user