mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge remote-tracking branch 'origin/master' into native-tls
* origin/master: updated NEWS PowerPC64 support for add and sub with overflow check PowerPC64 support for operators with overflow check Fixed bug #68583 Crash in timeout thread Reduced size of zend_op on 64-bit systems. Make ZEND_INIT_FCALL keep predcalculted size of necessary stack space in opline->op1.num to avoid its recalculation on each execution. Removed unused variables Improved array_merge() and array_replace() (1-st array may be added using simple procedure). Replaced zendi_convert_to_long() with _zval_get_long_func() Moved zend_is_true() from zend_execute.h/zend_execute_API.c into zend_operators.h/zend_operators.c. Splited the most expensive part of inline i_zend_is_true() into a separate zend_object_is_true(). Replaced zendi_convert_to_long() with cals to zend_is_true(). Revert "Save one xor instr" Save one xor instr Conflicts: Zend/zend_execute_API.c
This commit is contained in:
commit
dfb18b1188
21 changed files with 1834 additions and 1634 deletions
|
@ -731,9 +731,6 @@ void zend_shutdown(TSRMLS_D) /* {{{ */
|
|||
{
|
||||
#ifdef ZEND_SIGNALS
|
||||
zend_signal_shutdown(TSRMLS_C);
|
||||
#endif
|
||||
#ifdef ZEND_WIN32
|
||||
zend_shutdown_timeout_thread();
|
||||
#endif
|
||||
zend_destroy_rsrc_list(&EG(persistent_list) TSRMLS_CC);
|
||||
if (EG(active))
|
||||
|
|
|
@ -32,12 +32,6 @@
|
|||
#include "zend_language_scanner.h"
|
||||
#include "zend_inheritance.h"
|
||||
|
||||
#define CONSTANT_EX(op_array, op) \
|
||||
(op_array)->literals[op]
|
||||
|
||||
#define CONSTANT(op) \
|
||||
CONSTANT_EX(CG(active_op_array), op)
|
||||
|
||||
#define SET_NODE(target, src) do { \
|
||||
target ## _type = (src)->op_type; \
|
||||
if ((src)->op_type == IS_CONST) { \
|
||||
|
@ -50,7 +44,7 @@
|
|||
#define GET_NODE(target, src) do { \
|
||||
(target)->op_type = src ## _type; \
|
||||
if ((target)->op_type == IS_CONST) { \
|
||||
(target)->u.constant = CONSTANT(src.constant); \
|
||||
ZVAL_COPY_VALUE(&(target)->u.constant, CT_CONSTANT(src)); \
|
||||
} else { \
|
||||
(target)->u.op = src; \
|
||||
} \
|
||||
|
@ -291,11 +285,11 @@ static int lookup_cv(zend_op_array *op_array, zend_string* name TSRMLS_DC) /* {{
|
|||
|
||||
void zend_del_literal(zend_op_array *op_array, int n) /* {{{ */
|
||||
{
|
||||
zval_dtor(&CONSTANT_EX(op_array, n));
|
||||
zval_dtor(CT_CONSTANT_EX(op_array, n));
|
||||
if (n + 1 == op_array->last_literal) {
|
||||
op_array->last_literal--;
|
||||
} else {
|
||||
ZVAL_UNDEF(&CONSTANT_EX(op_array, n));
|
||||
ZVAL_UNDEF(CT_CONSTANT_EX(op_array, n));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -310,7 +304,7 @@ static inline void zend_insert_literal(zend_op_array *op_array, zval *zv, int li
|
|||
Z_TYPE_FLAGS_P(zv) &= ~ (IS_TYPE_REFCOUNTED | IS_TYPE_COPYABLE);
|
||||
}
|
||||
}
|
||||
ZVAL_COPY_VALUE(&CONSTANT_EX(op_array, literal_position), zv);
|
||||
ZVAL_COPY_VALUE(CT_CONSTANT_EX(op_array, literal_position), zv);
|
||||
Z_CACHE_SLOT(op_array->literals[literal_position]) = -1;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -752,13 +746,13 @@ static void str_dtor(zval *zv) /* {{{ */ {
|
|||
void zend_resolve_goto_label(zend_op_array *op_array, zend_op *opline, int pass2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_label *dest;
|
||||
zend_long current, distance;
|
||||
int current, distance;
|
||||
zval *label;
|
||||
|
||||
if (pass2) {
|
||||
label = opline->op2.zv;
|
||||
label = RT_CONSTANT(op_array, opline->op2);
|
||||
} else {
|
||||
label = &CONSTANT_EX(op_array, opline->op2.constant);
|
||||
label = CT_CONSTANT_EX(op_array, opline->op2.constant);
|
||||
}
|
||||
if (CG(context).labels == NULL ||
|
||||
(dest = zend_hash_find_ptr(CG(context).labels, Z_STR_P(label))) == NULL) {
|
||||
|
@ -888,11 +882,11 @@ ZEND_API int do_bind_function(const zend_op_array *op_array, const zend_op *opli
|
|||
zval *op1, *op2;
|
||||
|
||||
if (compile_time) {
|
||||
op1 = &CONSTANT_EX(op_array, opline->op1.constant);
|
||||
op2 = &CONSTANT_EX(op_array, opline->op2.constant);
|
||||
op1 = CT_CONSTANT_EX(op_array, opline->op1.constant);
|
||||
op2 = CT_CONSTANT_EX(op_array, opline->op2.constant);
|
||||
} else {
|
||||
op1 = opline->op1.zv;
|
||||
op2 = opline->op2.zv;
|
||||
op1 = RT_CONSTANT(op_array, opline->op1);
|
||||
op2 = RT_CONSTANT(op_array, opline->op2);
|
||||
}
|
||||
|
||||
function = zend_hash_find_ptr(function_table, Z_STR_P(op1));
|
||||
|
@ -928,11 +922,11 @@ ZEND_API zend_class_entry *do_bind_class(const zend_op_array* op_array, const ze
|
|||
zval *op1, *op2;
|
||||
|
||||
if (compile_time) {
|
||||
op1 = &CONSTANT_EX(op_array, opline->op1.constant);
|
||||
op2 = &CONSTANT_EX(op_array, opline->op2.constant);
|
||||
op1 = CT_CONSTANT_EX(op_array, opline->op1.constant);
|
||||
op2 = CT_CONSTANT_EX(op_array, opline->op2.constant);
|
||||
} else {
|
||||
op1 = opline->op1.zv;
|
||||
op2 = opline->op2.zv;
|
||||
op1 = RT_CONSTANT(op_array, opline->op1);
|
||||
op2 = RT_CONSTANT(op_array, opline->op2);
|
||||
}
|
||||
if ((ce = zend_hash_find_ptr(class_table, Z_STR_P(op1))) == NULL) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Internal Zend error - Missing class information for %s", Z_STRVAL_P(op1));
|
||||
|
@ -965,11 +959,11 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op_array *op_array
|
|||
zval *op1, *op2;
|
||||
|
||||
if (compile_time) {
|
||||
op1 = &CONSTANT_EX(op_array, opline->op1.constant);
|
||||
op2 = &CONSTANT_EX(op_array, opline->op2.constant);
|
||||
op1 = CT_CONSTANT_EX(op_array, opline->op1.constant);
|
||||
op2 = CT_CONSTANT_EX(op_array, opline->op2.constant);
|
||||
} else {
|
||||
op1 = opline->op1.zv;
|
||||
op2 = opline->op2.zv;
|
||||
op1 = RT_CONSTANT(op_array, opline->op1);
|
||||
op2 = RT_CONSTANT(op_array, opline->op2);
|
||||
}
|
||||
|
||||
ce = zend_hash_find_ptr(class_table, Z_STR_P(op1));
|
||||
|
@ -1032,7 +1026,7 @@ void zend_do_early_binding(TSRMLS_D) /* {{{ */
|
|||
zval *parent_name;
|
||||
zend_class_entry *ce;
|
||||
|
||||
parent_name = &CONSTANT(fetch_class_opline->op2.constant);
|
||||
parent_name = CT_CONSTANT(fetch_class_opline->op2);
|
||||
if (((ce = zend_lookup_class(Z_STR_P(parent_name) TSRMLS_CC)) == NULL) ||
|
||||
((CG(compiler_options) & ZEND_COMPILE_IGNORE_INTERNAL_CLASSES) &&
|
||||
(ce->type == ZEND_INTERNAL_CLASS))) {
|
||||
|
@ -1071,7 +1065,7 @@ void zend_do_early_binding(TSRMLS_D) /* {{{ */
|
|||
return;
|
||||
}
|
||||
|
||||
zend_hash_del(table, Z_STR(CONSTANT(opline->op1.constant)));
|
||||
zend_hash_del(table, Z_STR_P(CT_CONSTANT(opline->op1)));
|
||||
zend_del_literal(CG(active_op_array), opline->op1.constant);
|
||||
zend_del_literal(CG(active_op_array), opline->op2.constant);
|
||||
MAKE_NOP(opline);
|
||||
|
@ -1087,7 +1081,7 @@ ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS
|
|||
|
||||
CG(in_compilation) = 1;
|
||||
while (opline_num != -1) {
|
||||
if ((ce = zend_lookup_class(Z_STR_P(op_array->opcodes[opline_num-1].op2.zv) TSRMLS_CC)) != NULL) {
|
||||
if ((ce = zend_lookup_class(Z_STR_P(RT_CONSTANT(op_array, op_array->opcodes[opline_num-1].op2)) TSRMLS_CC)) != NULL) {
|
||||
do_bind_inherited_class(op_array, &op_array->opcodes[opline_num], EG(class_table), ce, 0 TSRMLS_CC);
|
||||
}
|
||||
opline_num = op_array->opcodes[opline_num].result.opline_num;
|
||||
|
@ -2112,7 +2106,7 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t
|
|||
|
||||
opline = zend_delayed_emit_op(result, ZEND_FETCH_OBJ_R, &obj_node, &prop_node TSRMLS_CC);
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
convert_to_string(&CONSTANT(opline->op2.constant));
|
||||
convert_to_string(CT_CONSTANT(opline->op2));
|
||||
zend_alloc_polymorphic_cache_slot(opline->op2.constant TSRMLS_CC);
|
||||
}
|
||||
|
||||
|
@ -2509,6 +2503,10 @@ void zend_compile_call_common(znode *result, zend_ast *args_ast, zend_function *
|
|||
opline = &CG(active_op_array)->opcodes[opnum_init];
|
||||
opline->extended_value = arg_count;
|
||||
|
||||
if (opline->opcode == ZEND_INIT_FCALL) {
|
||||
opline->op1.num = zend_vm_calc_used_stack(arg_count, fbc);
|
||||
}
|
||||
|
||||
call_flags = (opline->opcode == ZEND_NEW ? ZEND_CALL_CTOR : 0);
|
||||
opline = zend_emit_op(result, ZEND_DO_FCALL, NULL, NULL TSRMLS_CC);
|
||||
opline->op1.num = call_flags;
|
||||
|
@ -2662,7 +2660,7 @@ static int zend_try_compile_ct_bound_init_user_func(zend_ast *name_ast, uint32_t
|
|||
|
||||
opline = zend_emit_op(NULL, ZEND_INIT_FCALL, NULL, NULL TSRMLS_CC);
|
||||
opline->extended_value = num_args;
|
||||
|
||||
opline->op1.num = zend_vm_calc_used_stack(num_args, fbc);
|
||||
opline->op2_type = IS_CONST;
|
||||
LITERAL_STR(opline->op2, lcname);
|
||||
zend_alloc_cache_slot(opline->op2.constant TSRMLS_CC);
|
||||
|
@ -3515,7 +3513,7 @@ void zend_compile_switch(zend_ast *ast TSRMLS_DC) /* {{{ */
|
|||
opline = zend_emit_op(NULL, ZEND_CASE, &expr_node, &cond_node TSRMLS_CC);
|
||||
SET_NODE(opline->result, &case_node);
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
zval_copy_ctor(&CONSTANT(opline->op1.constant));
|
||||
zval_copy_ctor(CT_CONSTANT(opline->op1));
|
||||
}
|
||||
|
||||
jmpnz_opnums[i] = zend_emit_cond_jump(ZEND_JMPNZ, &case_node, 0 TSRMLS_CC);
|
||||
|
|
|
@ -56,13 +56,34 @@ typedef struct _zend_compiler_context {
|
|||
HashTable *labels;
|
||||
} zend_compiler_context;
|
||||
|
||||
/* On 64-bi systems less optimal, but more compact VM code leads to better
|
||||
* performance. So on 32-bit systems we use absolute addresses for jump
|
||||
* targets and constants, but on 64-bit systems realtive 32-bit offsets */
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
# define ZEND_USE_ABS_JMP_ADDR 1
|
||||
# define ZEND_USE_ABS_CONST_ADDR 1
|
||||
# define ZEND_EX_USE_LITERALS 0
|
||||
# define ZEND_EX_USE_RUN_TIME_CACHE 1
|
||||
#else
|
||||
# define ZEND_USE_ABS_JMP_ADDR 0
|
||||
# define ZEND_USE_ABS_CONST_ADDR 0
|
||||
# define ZEND_EX_USE_LITERALS 1
|
||||
# define ZEND_EX_USE_RUN_TIME_CACHE 1
|
||||
#endif
|
||||
|
||||
typedef union _znode_op {
|
||||
uint32_t constant;
|
||||
uint32_t var;
|
||||
uint32_t num;
|
||||
uint32_t opline_num; /* Needs to be signed */
|
||||
#if ZEND_USE_ABS_JMP_ADDR
|
||||
zend_op *jmp_addr;
|
||||
#else
|
||||
uint32_t jmp_offset;
|
||||
#endif
|
||||
#if ZEND_USE_ABS_CONST_ADDR
|
||||
zval *zv;
|
||||
#endif
|
||||
} znode_op;
|
||||
|
||||
typedef struct _znode { /* used only during compilation */
|
||||
|
@ -112,8 +133,8 @@ struct _zend_op {
|
|||
znode_op op1;
|
||||
znode_op op2;
|
||||
znode_op result;
|
||||
zend_ulong extended_value;
|
||||
uint lineno;
|
||||
uint32_t extended_value;
|
||||
uint32_t lineno;
|
||||
zend_uchar opcode;
|
||||
zend_uchar op1_type;
|
||||
zend_uchar op2_type;
|
||||
|
@ -374,12 +395,17 @@ typedef enum _zend_call_kind {
|
|||
struct _zend_execute_data {
|
||||
const zend_op *opline; /* executed opline */
|
||||
zend_execute_data *call; /* current call */
|
||||
void **run_time_cache;
|
||||
zval *return_value;
|
||||
zend_function *func; /* executed op_array */
|
||||
zval This;
|
||||
#if ZEND_EX_USE_RUN_TIME_CACHE
|
||||
void **run_time_cache;
|
||||
#endif
|
||||
#if ZEND_EX_USE_LITERALS
|
||||
zval *literals;
|
||||
#endif
|
||||
zend_class_entry *called_scope;
|
||||
zend_execute_data *prev_execute_data;
|
||||
zval *return_value;
|
||||
zend_array *symbol_table;
|
||||
};
|
||||
|
||||
|
@ -430,6 +456,136 @@ struct _zend_execute_data {
|
|||
|
||||
#define EX_VAR_TO_NUM(n) (ZEND_CALL_VAR(NULL, n) - ZEND_CALL_VAR_NUM(NULL, 0))
|
||||
|
||||
#define ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline_num) \
|
||||
((char*)&(op_array)->opcodes[opline_num] - (char*)(opline))
|
||||
|
||||
#define ZEND_OFFSET_TO_OPLINE(base, offset) \
|
||||
((zend_op*)(((char*)(base)) + (int)offset))
|
||||
|
||||
#define ZEND_OFFSET_TO_OPLINE_NUM(op_array, base, offset) \
|
||||
(ZEND_OFFSET_TO_OPLINE(base, offset) - op_array->opcodes)
|
||||
|
||||
#if ZEND_USE_ABS_JMP_ADDR
|
||||
|
||||
/* run-time jump target */
|
||||
# define OP_JMP_ADDR(opline, node) \
|
||||
(node).jmp_addr
|
||||
|
||||
/* convert jump target from compile-time to run-time */
|
||||
# define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \
|
||||
(node).jmp_addr = (op_array)->opcodes + (node).opline_num; \
|
||||
} while (0)
|
||||
|
||||
/* convert jump target back from run-time to compile-time */
|
||||
# define ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, node) do { \
|
||||
(node).opline_num = (node).jmp_addr - (op_array)->opcodes; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
/* run-time jump target */
|
||||
# define OP_JMP_ADDR(opline, node) \
|
||||
ZEND_OFFSET_TO_OPLINE(opline, (node).jmp_offset)
|
||||
|
||||
/* convert jump target from compile-time to run-time */
|
||||
# define ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, node) do { \
|
||||
(node).jmp_offset = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, (node).opline_num); \
|
||||
} while (0)
|
||||
|
||||
/* convert jump target back from run-time to compile-time */
|
||||
# define ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, node) do { \
|
||||
(node).opline_num = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, (node).jmp_offset); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/* constant-time constant */
|
||||
# define CT_CONSTANT_EX(op_array, num) \
|
||||
((op_array)->literals + (num))
|
||||
|
||||
# define CT_CONSTANT(node) \
|
||||
CT_CONSTANT_EX(CG(active_op_array), (node).constant)
|
||||
|
||||
#if ZEND_USE_ABS_CONST_ADDR
|
||||
|
||||
/* run-time constant */
|
||||
# define RT_CONSTANT_EX(base, node) \
|
||||
(node).zv
|
||||
|
||||
/* convert constant from compile-time to run-time */
|
||||
# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, node) do { \
|
||||
(node).zv = CT_CONSTANT_EX(op_array, (node).constant); \
|
||||
} while (0)
|
||||
|
||||
/* convert constant back from run-time to compile-time */
|
||||
# define ZEND_PASS_TWO_UNDO_CONSTANT(op_array, node) do { \
|
||||
(node).constant = (node).zv - (op_array)->literals; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
/* run-time constant */
|
||||
# define RT_CONSTANT_EX(base, node) \
|
||||
((zval*)(((char*)(base)) + (node).constant))
|
||||
|
||||
/* convert constant from compile-time to run-time */
|
||||
# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, node) do { \
|
||||
(node).constant *= sizeof(zval); \
|
||||
} while (0)
|
||||
|
||||
/* convert constant back from run-time to compile-time (do nothing) */
|
||||
# define ZEND_PASS_TWO_UNDO_CONSTANT(op_array, node) do { \
|
||||
(node).constant /= sizeof(zval); \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#if ZEND_EX_USE_LITERALS
|
||||
|
||||
# define EX_LITERALS() \
|
||||
EX(literals)
|
||||
|
||||
# define EX_LOAD_LITERALS(op_array) do { \
|
||||
EX(literals) = (op_array)->literals; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
# define EX_LITERALS() \
|
||||
EX(func)->op_array.literals
|
||||
|
||||
# define EX_LOAD_LITERALS(op_array) do { \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
/* run-time constant */
|
||||
#define RT_CONSTANT(op_array, node) \
|
||||
RT_CONSTANT_EX((op_array)->literals, node)
|
||||
|
||||
/* constant in currently executed function */
|
||||
#define EX_CONSTANT(node) \
|
||||
RT_CONSTANT_EX(EX_LITERALS(), node)
|
||||
|
||||
#if ZEND_EX_USE_RUN_TIME_CACHE
|
||||
|
||||
# define EX_RUN_TIME_CACHE() \
|
||||
EX(run_time_cache)
|
||||
|
||||
# define EX_LOAD_RUN_TIME_CACHE(op_array) do { \
|
||||
EX(run_time_cache) = (op_array)->run_time_cache; \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
# define EX_RUN_TIME_CACHE() \
|
||||
EX(func)->op_array.run_time_cache
|
||||
|
||||
# define EX_LOAD_RUN_TIME_CACHE(op_array) do { \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
||||
#define IS_CONST (1<<0)
|
||||
#define IS_TMP_VAR (1<<1)
|
||||
#define IS_VAR (1<<2)
|
||||
|
|
|
@ -402,7 +402,7 @@ static zend_always_inline zval *_get_zval_ptr(int op_type, znode_op node, const
|
|||
} else {
|
||||
*should_free = NULL;
|
||||
if (op_type == IS_CONST) {
|
||||
return node.zv;
|
||||
return EX_CONSTANT(node);
|
||||
} else {
|
||||
ZEND_ASSERT(op_type == IS_CV);
|
||||
return _get_zval_ptr_cv(execute_data, node.var, type TSRMLS_CC);
|
||||
|
@ -422,7 +422,7 @@ static zend_always_inline zval *_get_zval_ptr_deref(int op_type, znode_op node,
|
|||
} else {
|
||||
*should_free = NULL;
|
||||
if (op_type == IS_CONST) {
|
||||
return node.zv;
|
||||
return EX_CONSTANT(node);
|
||||
} else {
|
||||
ZEND_ASSERT(op_type == IS_CV);
|
||||
return _get_zval_ptr_cv_deref(execute_data, node.var, type TSRMLS_CC);
|
||||
|
@ -1674,7 +1674,8 @@ static zend_always_inline void i_init_func_execute_data(zend_execute_data *execu
|
|||
if (!op_array->run_time_cache && op_array->last_cache_slot) {
|
||||
op_array->run_time_cache = zend_arena_calloc(&CG(arena), op_array->last_cache_slot, sizeof(void*));
|
||||
}
|
||||
EX(run_time_cache) = op_array->run_time_cache;
|
||||
EX_LOAD_RUN_TIME_CACHE(op_array);
|
||||
EX_LOAD_LITERALS(op_array);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
}
|
||||
|
@ -1698,7 +1699,8 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
|
|||
if (!op_array->run_time_cache && op_array->last_cache_slot) {
|
||||
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
|
||||
}
|
||||
EX(run_time_cache) = op_array->run_time_cache;
|
||||
EX_LOAD_RUN_TIME_CACHE(op_array);
|
||||
EX_LOAD_LITERALS(op_array);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
}
|
||||
|
@ -1772,7 +1774,8 @@ static zend_always_inline void i_init_execute_data(zend_execute_data *execute_da
|
|||
op_array->run_time_cache = ecalloc(op_array->last_cache_slot, sizeof(void*));
|
||||
}
|
||||
}
|
||||
EX(run_time_cache) = op_array->run_time_cache;
|
||||
EX_LOAD_RUN_TIME_CACHE(op_array);
|
||||
EX_LOAD_LITERALS(op_array);
|
||||
|
||||
EG(current_execute_data) = execute_data;
|
||||
}
|
||||
|
@ -1897,8 +1900,7 @@ static zend_always_inline void zend_vm_stack_extend_call_frame(zend_execute_data
|
|||
OPLINE = new_op
|
||||
|
||||
#define ZEND_VM_SET_RELATIVE_OPCODE(opline, offset) \
|
||||
CHECK_SYMBOL_TABLES() \
|
||||
OPLINE = ((zend_op*)(((char*)opline)+(offset)))
|
||||
ZEND_VM_SET_OPCODE(ZEND_OFFSET_TO_OPLINE(opline, offset))
|
||||
|
||||
#define ZEND_VM_JMP(new_op) \
|
||||
if (EXPECTED(!EG(exception))) { \
|
||||
|
|
|
@ -40,7 +40,6 @@ ZEND_API zend_execute_data *zend_create_generator_execute_data(zend_execute_data
|
|||
ZEND_API void zend_execute(zend_op_array *op_array, zval *return_value TSRMLS_DC);
|
||||
ZEND_API void execute_ex(zend_execute_data *execute_data TSRMLS_DC);
|
||||
ZEND_API void execute_internal(zend_execute_data *execute_data, zval *return_value TSRMLS_DC);
|
||||
ZEND_API int zend_is_true(zval *op TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_lookup_class(zend_string *name TSRMLS_DC);
|
||||
ZEND_API zend_class_entry *zend_lookup_class_ex(zend_string *name, const zval *key, int use_autoload TSRMLS_DC);
|
||||
ZEND_API int zend_eval_string(char *str, zval *retval_ptr, char *string_name TSRMLS_DC);
|
||||
|
@ -52,72 +51,6 @@ ZEND_API char * zend_verify_internal_arg_class_kind(const zend_internal_arg_info
|
|||
ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, char **class_name, zend_class_entry **pce TSRMLS_DC);
|
||||
ZEND_API void zend_verify_arg_error(int error_type, const zend_function *zf, uint32_t arg_num, const char *need_msg, const char *need_kind, const char *given_msg, const char *given_kind, zval *arg TSRMLS_DC);
|
||||
|
||||
static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC)
|
||||
{
|
||||
int result;
|
||||
|
||||
again:
|
||||
switch (Z_TYPE_P(op)) {
|
||||
case IS_UNDEF:
|
||||
case IS_NULL:
|
||||
case IS_FALSE:
|
||||
result = 0;
|
||||
break;
|
||||
case IS_TRUE:
|
||||
result = 1;
|
||||
break;
|
||||
case IS_LONG:
|
||||
result = (Z_LVAL_P(op)?1:0);
|
||||
break;
|
||||
case IS_RESOURCE:
|
||||
result = (Z_RES_HANDLE_P(op)?1:0);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
result = (Z_DVAL_P(op) ? 1 : 0);
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (Z_STRLEN_P(op) == 0
|
||||
|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
if (Z_OBJ_HT_P(op)->cast_object) {
|
||||
zval tmp;
|
||||
if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL TSRMLS_CC) == SUCCESS) {
|
||||
result = Z_TYPE(tmp) == IS_TRUE;
|
||||
break;
|
||||
}
|
||||
zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", Z_OBJ_P(op)->ce->name->val);
|
||||
} else if (Z_OBJ_HT_P(op)->get) {
|
||||
zval rv;
|
||||
zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv TSRMLS_CC);
|
||||
if (Z_TYPE_P(tmp) != IS_OBJECT) {
|
||||
/* for safety - avoid loop */
|
||||
convert_to_boolean(tmp);
|
||||
result = Z_TYPE_P(tmp) == IS_TRUE;
|
||||
zval_ptr_dtor(tmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = 1;
|
||||
break;
|
||||
case IS_REFERENCE:
|
||||
op = Z_REFVAL_P(op);
|
||||
goto again;
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval *value, zend_uchar value_type TSRMLS_DC)
|
||||
{
|
||||
do {
|
||||
|
@ -210,15 +143,10 @@ static zend_always_inline zval* zend_vm_stack_alloc(size_t size TSRMLS_DC)
|
|||
return (zval*)top;
|
||||
}
|
||||
|
||||
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
|
||||
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame_ex(uint32_t call_info, zend_function *func, uint32_t used_stack, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
|
||||
{
|
||||
uint32_t used_stack = ZEND_CALL_FRAME_SLOT + num_args;
|
||||
zend_execute_data *call;
|
||||
|
||||
if (ZEND_USER_CODE(func->type)) {
|
||||
used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
|
||||
}
|
||||
call = (zend_execute_data*)zend_vm_stack_alloc(used_stack * sizeof(zval) TSRMLS_CC);
|
||||
zend_execute_data *call = (zend_execute_data*)zend_vm_stack_alloc(used_stack TSRMLS_CC);
|
||||
|
||||
call->func = func;
|
||||
Z_OBJ(call->This) = object;
|
||||
ZEND_SET_CALL_INFO(call, call_info);
|
||||
|
@ -228,6 +156,24 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint3
|
|||
return call;
|
||||
}
|
||||
|
||||
static zend_always_inline uint32_t zend_vm_calc_used_stack(uint32_t num_args, zend_function *func)
|
||||
{
|
||||
uint32_t used_stack = ZEND_CALL_FRAME_SLOT + num_args;
|
||||
|
||||
if (ZEND_USER_CODE(func->type)) {
|
||||
used_stack += func->op_array.last_var + func->op_array.T - MIN(func->op_array.num_args, num_args);
|
||||
}
|
||||
return used_stack * sizeof(zval);
|
||||
}
|
||||
|
||||
static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint32_t call_info, zend_function *func, uint32_t num_args, zend_class_entry *called_scope, zend_object *object, zend_execute_data *prev TSRMLS_DC)
|
||||
{
|
||||
uint32_t used_stack = zend_vm_calc_used_stack(num_args, func);
|
||||
|
||||
return zend_vm_stack_push_call_frame_ex(call_info,
|
||||
func, used_stack, called_scope, object, prev TSRMLS_CC);
|
||||
}
|
||||
|
||||
static zend_always_inline void zend_vm_stack_free_extra_args(zend_execute_data *call TSRMLS_DC)
|
||||
{
|
||||
uint32_t first_extra_arg = call->func->op_array.num_args - ((call->func->common.fn_flags & ZEND_ACC_VARIADIC) != 0);
|
||||
|
@ -288,13 +234,6 @@ void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
|
|||
|
||||
ZEND_API void zend_fetch_dimension_by_zval(zval *result, zval *container, zval *dim TSRMLS_DC);
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
void zend_init_timeout_thread(void);
|
||||
void zend_shutdown_timeout_thread(void);
|
||||
#define WM_REGISTER_ZEND_TIMEOUT (WM_USER+1)
|
||||
#define WM_UNREGISTER_ZEND_TIMEOUT (WM_USER+2)
|
||||
#endif
|
||||
|
||||
ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var);
|
||||
|
||||
#define ZEND_USER_OPCODE_CONTINUE 0 /* execute next opcode */
|
||||
|
@ -319,20 +258,20 @@ ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table TSRMLS_
|
|||
void zend_free_compiled_variables(zend_execute_data *execute_data TSRMLS_DC);
|
||||
|
||||
#define CACHED_PTR(num) \
|
||||
EX(run_time_cache)[(num)]
|
||||
EX_RUN_TIME_CACHE()[(num)]
|
||||
|
||||
#define CACHE_PTR(num, ptr) do { \
|
||||
EX(run_time_cache)[(num)] = (ptr); \
|
||||
EX_RUN_TIME_CACHE()[(num)] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
#define CACHED_POLYMORPHIC_PTR(num, ce) \
|
||||
((EX(run_time_cache)[(num)] == (ce)) ? \
|
||||
EX(run_time_cache)[(num) + 1] : \
|
||||
((EX_RUN_TIME_CACHE()[(num)] == (ce)) ? \
|
||||
EX_RUN_TIME_CACHE()[(num) + 1] : \
|
||||
NULL)
|
||||
|
||||
#define CACHE_POLYMORPHIC_PTR(num, ce, ptr) do { \
|
||||
EX(run_time_cache)[(num)] = (ce); \
|
||||
EX(run_time_cache)[(num) + 1] = (ptr); \
|
||||
EX_RUN_TIME_CACHE()[(num)] = (ce); \
|
||||
EX_RUN_TIME_CACHE()[(num) + 1] = (ptr); \
|
||||
} while (0)
|
||||
|
||||
#define CACHED_PTR_EX(slot) \
|
||||
|
|
|
@ -46,13 +46,10 @@ ZEND_API const zend_fcall_info empty_fcall_info = { 0, NULL, {{0}, {{0}}, {0}},
|
|||
ZEND_API const zend_fcall_info_cache empty_fcall_info_cache = { 0, NULL, NULL, NULL, NULL };
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
#include <process.h>
|
||||
static WNDCLASS wc;
|
||||
static HWND timeout_window;
|
||||
static HANDLE timeout_thread_event;
|
||||
static HANDLE timeout_thread_handle;
|
||||
static unsigned timeout_thread_id;
|
||||
static volatile long timeout_thread_initialized=0;
|
||||
#ifdef ZTS
|
||||
__declspec(thread)
|
||||
#endif
|
||||
HANDLE tq_timer = NULL;
|
||||
#endif
|
||||
|
||||
#if 0&&ZEND_DEBUG
|
||||
|
@ -501,12 +498,6 @@ ZEND_API void _zval_internal_ptr_dtor(zval *zval_ptr ZEND_FILE_LINE_DC) /* {{{ *
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
return i_zend_is_true(op TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#define IS_VISITED_CONSTANT 0x80
|
||||
#define IS_CONSTANT_VISITED(p) (Z_TYPE_P(p) & IS_VISITED_CONSTANT)
|
||||
#define MARK_CONSTANT_VISITED(p) Z_TYPE_INFO_P(p) |= IS_VISITED_CONSTANT
|
||||
|
@ -1163,120 +1154,19 @@ ZEND_API void zend_timeout(int dummy) /* {{{ */
|
|||
/* }}} */
|
||||
|
||||
#ifdef ZEND_WIN32
|
||||
static LRESULT CALLBACK zend_timeout_WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) /* {{{ */
|
||||
VOID CALLBACK tq_timer_cb(PVOID arg, BOOLEAN timed_out)
|
||||
{
|
||||
#ifdef ZTS
|
||||
THREAD_T thread_id = (THREAD_T)wParam;
|
||||
#endif
|
||||
zend_bool *php_timed_out;
|
||||
|
||||
switch (message) {
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
case WM_REGISTER_ZEND_TIMEOUT:
|
||||
/* wParam is the thread id pointer, lParam is the timeout amount in seconds */
|
||||
if (lParam == 0) {
|
||||
KillTimer(timeout_window, wParam);
|
||||
} else {
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
#endif
|
||||
SetTimer(timeout_window, wParam, lParam*1000, NULL);
|
||||
#ifdef ZTS
|
||||
tsrm_ls = ts_resource_ex(0, &thread_id);
|
||||
if (!tsrm_ls) {
|
||||
/* shouldn't normally happen */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
/* XXX this won't work with TLS enabled, EG is on a different thread.
|
||||
But nothing happened anyway, no timeout here. */
|
||||
/* EG(timed_out) = 0; */
|
||||
}
|
||||
break;
|
||||
case WM_UNREGISTER_ZEND_TIMEOUT:
|
||||
/* wParam is the thread id pointer */
|
||||
KillTimer(timeout_window, wParam);
|
||||
break;
|
||||
case WM_TIMER: {
|
||||
#ifdef ZTS
|
||||
void ***tsrm_ls;
|
||||
|
||||
tsrm_ls = ts_resource_ex(0, &thread_id);
|
||||
if (!tsrm_ls) {
|
||||
/* Thread died before receiving its timeout? */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
KillTimer(timeout_window, wParam);
|
||||
|
||||
/* XXX this won't work with TLS enabled, EG is on a different thread.
|
||||
Maybe an ide were to throw the timeout window right from here. */
|
||||
/*EG(timed_out) = 1; */
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return DefWindowProc(hWnd, message, wParam, lParam);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static unsigned __stdcall timeout_thread_proc(void *pArgs) /* {{{ */
|
||||
{
|
||||
MSG message;
|
||||
|
||||
wc.style=0;
|
||||
wc.lpfnWndProc = zend_timeout_WndProc;
|
||||
wc.cbClsExtra=0;
|
||||
wc.cbWndExtra=0;
|
||||
wc.hInstance=NULL;
|
||||
wc.hIcon=NULL;
|
||||
wc.hCursor=NULL;
|
||||
wc.hbrBackground=(HBRUSH)(COLOR_BACKGROUND + 5);
|
||||
wc.lpszMenuName=NULL;
|
||||
wc.lpszClassName = "Zend Timeout Window";
|
||||
if (!RegisterClass(&wc)) {
|
||||
return -1;
|
||||
}
|
||||
timeout_window = CreateWindow(wc.lpszClassName, wc.lpszClassName, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, NULL, NULL);
|
||||
SetEvent(timeout_thread_event);
|
||||
while (GetMessage(&message, NULL, 0, 0)) {
|
||||
SendMessage(timeout_window, message.message, message.wParam, message.lParam);
|
||||
if (message.message == WM_QUIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
DestroyWindow(timeout_window);
|
||||
UnregisterClass(wc.lpszClassName, NULL);
|
||||
SetEvent(timeout_thread_handle);
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_init_timeout_thread(void) /* {{{ */
|
||||
{
|
||||
timeout_thread_event = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
timeout_thread_handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
_beginthreadex(NULL, 0, timeout_thread_proc, NULL, 0, &timeout_thread_id);
|
||||
WaitForSingleObject(timeout_thread_event, INFINITE);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_shutdown_timeout_thread(void) /* {{{ */
|
||||
{
|
||||
if (!timeout_thread_initialized) {
|
||||
/* The doc states it'll be always true, however it theoretically
|
||||
could be FALSE when the thread was signaled. */
|
||||
if (!timed_out) {
|
||||
return;
|
||||
}
|
||||
PostThreadMessage(timeout_thread_id, WM_QUIT, 0, 0);
|
||||
|
||||
/* Wait for thread termination */
|
||||
WaitForSingleObject(timeout_thread_handle, 5000);
|
||||
CloseHandle(timeout_thread_handle);
|
||||
timeout_thread_initialized = 0;
|
||||
php_timed_out = (zend_bool *)arg;
|
||||
*php_timed_out = 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#endif
|
||||
|
||||
/* This one doesn't exists on QNX */
|
||||
|
@ -1294,13 +1184,28 @@ void zend_set_timeout(zend_long seconds, int reset_signals) /* {{{ */
|
|||
if(!seconds) {
|
||||
return;
|
||||
}
|
||||
if (timeout_thread_initialized == 0 && InterlockedIncrement(&timeout_thread_initialized) == 1) {
|
||||
/* We start up this process-wide thread here and not in zend_startup(), because if Zend
|
||||
* is initialized inside a DllMain(), you're not supposed to start threads from it.
|
||||
*/
|
||||
zend_init_timeout_thread();
|
||||
|
||||
/* Don't use ChangeTimerQueueTimer() as it will not restart an expired
|
||||
timer, so we could end up with just an ignored timeout. Instead
|
||||
delete and recreate. */
|
||||
if (NULL != tq_timer) {
|
||||
if (!DeleteTimerQueueTimer(NULL, tq_timer, NULL)) {
|
||||
EG(timed_out) = 0;
|
||||
tq_timer = NULL;
|
||||
zend_error(E_ERROR, "Could not delete queued timer");
|
||||
return;
|
||||
}
|
||||
tq_timer = NULL;
|
||||
}
|
||||
PostThreadMessage(timeout_thread_id, WM_REGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) seconds);
|
||||
|
||||
/* XXX passing NULL means the default timer queue provided by the system is used */
|
||||
if (!CreateTimerQueueTimer(&tq_timer, NULL, (WAITORTIMERCALLBACK)tq_timer_cb, (VOID*)&EG(timed_out), seconds*1000, 0, WT_EXECUTEONLYONCE)) {
|
||||
EG(timed_out) = 0;
|
||||
tq_timer = NULL;
|
||||
zend_error(E_ERROR, "Could not queue new timer");
|
||||
return;
|
||||
}
|
||||
EG(timed_out) = 0;
|
||||
#else
|
||||
# ifdef HAVE_SETITIMER
|
||||
{
|
||||
|
@ -1342,9 +1247,16 @@ void zend_set_timeout(zend_long seconds, int reset_signals) /* {{{ */
|
|||
void zend_unset_timeout(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
#ifdef ZEND_WIN32
|
||||
if(timeout_thread_initialized) {
|
||||
PostThreadMessage(timeout_thread_id, WM_UNREGISTER_ZEND_TIMEOUT, (WPARAM) GetCurrentThreadId(), (LPARAM) 0);
|
||||
if (NULL != tq_timer) {
|
||||
if (!DeleteTimerQueueTimer(NULL, tq_timer, NULL)) {
|
||||
EG(timed_out) = 0;
|
||||
tq_timer = NULL;
|
||||
zend_error(E_ERROR, "Could not delete queued timer");
|
||||
return;
|
||||
}
|
||||
tq_timer = NULL;
|
||||
}
|
||||
EG(timed_out) = 0;
|
||||
#else
|
||||
# ifdef HAVE_SETITIMER
|
||||
if (EG(timeout_seconds)) {
|
||||
|
|
|
@ -454,7 +454,7 @@ static zend_string *zend_get_function_declaration(zend_function *fptr TSRMLS_DC)
|
|||
}
|
||||
}
|
||||
if (precv && precv->opcode == ZEND_RECV_INIT && precv->op2_type != IS_UNUSED) {
|
||||
zval *zv = precv->op2.zv;
|
||||
zval *zv = RT_CONSTANT(&fptr->op_array, precv->op2);
|
||||
|
||||
if (Z_TYPE_P(zv) == IS_CONSTANT) {
|
||||
smart_str_append(&str, Z_STR_P(zv));
|
||||
|
|
|
@ -662,9 +662,10 @@ static void zend_resolve_finally_calls(zend_op_array *op_array TSRMLS_DC)
|
|||
}
|
||||
}
|
||||
case ZEND_GOTO:
|
||||
if (Z_TYPE(op_array->literals[opline->op2.constant]) != IS_LONG) {
|
||||
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) {
|
||||
uint32_t num = opline->op2.constant;
|
||||
opline->op2.zv = &op_array->literals[opline->op2.constant];
|
||||
|
||||
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
|
||||
zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC);
|
||||
opline->op2.constant = num;
|
||||
}
|
||||
|
@ -717,12 +718,12 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
|
|||
end = opline + op_array->last;
|
||||
while (opline < end) {
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
opline->op1.zv = &op_array->literals[opline->op1.constant];
|
||||
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
|
||||
} else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
|
||||
opline->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op1.var);
|
||||
}
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
opline->op2.zv = &op_array->literals[opline->op2.constant];
|
||||
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
|
||||
} else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
|
||||
opline->op2.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op2.var);
|
||||
}
|
||||
|
@ -735,17 +736,17 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
|
|||
opline->extended_value = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->extended_value);
|
||||
break;
|
||||
case ZEND_GOTO:
|
||||
if (Z_TYPE_P(opline->op2.zv) != IS_LONG) {
|
||||
if (Z_TYPE_P(RT_CONSTANT(op_array, opline->op2)) != IS_LONG) {
|
||||
zend_resolve_goto_label(op_array, opline, 1 TSRMLS_CC);
|
||||
}
|
||||
/* break omitted intentionally */
|
||||
case ZEND_JMP:
|
||||
case ZEND_FAST_CALL:
|
||||
opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
|
||||
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
|
||||
break;
|
||||
case ZEND_JMPZNZ:
|
||||
/* absolute index to relative offset */
|
||||
opline->extended_value = (char*)(op_array->opcodes + opline->extended_value) - (char*)opline;
|
||||
opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
|
||||
/* break omitted intentionally */
|
||||
case ZEND_JMPZ:
|
||||
case ZEND_JMPNZ:
|
||||
|
@ -756,12 +757,12 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
|
|||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET:
|
||||
case ZEND_FE_FETCH:
|
||||
opline->op2.jmp_addr = &op_array->opcodes[opline->op2.opline_num];
|
||||
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op2);
|
||||
break;
|
||||
case ZEND_RETURN:
|
||||
case ZEND_RETURN_BY_REF:
|
||||
if (op_array->fn_flags & ZEND_ACC_GENERATOR) {
|
||||
if (opline->op1_type != IS_CONST || Z_TYPE_P(opline->op1.zv) != IS_NULL) {
|
||||
if (opline->op1_type != IS_CONST || Z_TYPE_P(RT_CONSTANT(op_array, opline->op1)) != IS_NULL) {
|
||||
CG(zend_lineno) = opline->lineno;
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Generators cannot return values using \"return\"");
|
||||
}
|
||||
|
|
|
@ -220,88 +220,6 @@ try_again:
|
|||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zendi_convert_to_long */
|
||||
#define zendi_convert_to_long(op, holder, result) \
|
||||
if (op == result) { \
|
||||
convert_to_long(op); \
|
||||
} else if (Z_TYPE_P(op) != IS_LONG) { \
|
||||
switch (Z_TYPE_P(op)) { \
|
||||
case IS_NULL: \
|
||||
case IS_FALSE: \
|
||||
ZVAL_LONG(&(holder), 0); \
|
||||
break; \
|
||||
case IS_TRUE: \
|
||||
ZVAL_LONG(&(holder), 1); \
|
||||
break; \
|
||||
case IS_DOUBLE: \
|
||||
ZVAL_LONG(&holder, zend_dval_to_lval(Z_DVAL_P(op)));\
|
||||
break; \
|
||||
case IS_STRING: \
|
||||
ZVAL_LONG(&holder, ZEND_STRTOL(Z_STRVAL_P(op), NULL, 10));\
|
||||
break; \
|
||||
case IS_ARRAY: \
|
||||
ZVAL_LONG(&holder, zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); \
|
||||
break; \
|
||||
case IS_OBJECT: \
|
||||
ZVAL_DUP(&(holder), (op)); \
|
||||
convert_to_long_base(&(holder), 10); \
|
||||
break; \
|
||||
case IS_RESOURCE: \
|
||||
ZVAL_LONG(&holder, Z_RES_HANDLE_P(op)); \
|
||||
break; \
|
||||
default: \
|
||||
zend_error(E_WARNING, "Cannot convert to ordinal value"); \
|
||||
ZVAL_LONG(&holder, 0); \
|
||||
break; \
|
||||
} \
|
||||
(op) = &(holder); \
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zendi_convert_to_boolean */
|
||||
#define zendi_convert_to_boolean(op, holder, result) \
|
||||
if (op==result) { \
|
||||
convert_to_boolean(op); \
|
||||
} else if (Z_TYPE_P(op) != IS_FALSE && \
|
||||
Z_TYPE_P(op) != IS_TRUE) { \
|
||||
switch (Z_TYPE_P(op)) { \
|
||||
case IS_NULL: \
|
||||
ZVAL_BOOL(&holder, 0); \
|
||||
break; \
|
||||
case IS_RESOURCE: \
|
||||
ZVAL_BOOL(&holder, Z_RES_HANDLE_P(op) ? 1 : 0); \
|
||||
break; \
|
||||
case IS_LONG: \
|
||||
ZVAL_BOOL(&holder, Z_LVAL_P(op) ? 1 : 0); \
|
||||
break; \
|
||||
case IS_DOUBLE: \
|
||||
ZVAL_BOOL(&holder, Z_DVAL_P(op) ? 1 : 0); \
|
||||
break; \
|
||||
case IS_STRING: \
|
||||
if (Z_STRLEN_P(op) == 0 \
|
||||
|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) { \
|
||||
ZVAL_BOOL(&holder, 0); \
|
||||
} else { \
|
||||
ZVAL_BOOL(&holder, 1); \
|
||||
} \
|
||||
break; \
|
||||
case IS_ARRAY: \
|
||||
ZVAL_BOOL(&holder, zend_hash_num_elements(Z_ARRVAL_P(op))?1:0); \
|
||||
break; \
|
||||
case IS_OBJECT: \
|
||||
ZVAL_DUP(&(holder), (op)); \
|
||||
convert_to_boolean(&(holder)); \
|
||||
break; \
|
||||
default: \
|
||||
ZVAL_BOOL(&holder, 0); \
|
||||
break; \
|
||||
} \
|
||||
(op) = &(holder); \
|
||||
}
|
||||
|
||||
/* }}} */
|
||||
|
||||
/* {{{ convert_object_to_type */
|
||||
#define convert_object_to_type(op, dst, ctype, conv_func) \
|
||||
ZVAL_UNDEF(dst); \
|
||||
|
@ -1199,51 +1117,58 @@ ZEND_API int div_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ *
|
|||
|
||||
ZEND_API int mod_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
zend_long op1_lval;
|
||||
zend_long op1_lval, op2_lval;
|
||||
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
|
||||
if (Z_ISREF_P(op1)) {
|
||||
op1 = Z_REFVAL_P(op1);
|
||||
if (Z_TYPE_P(op1) == IS_LONG) break;
|
||||
if (Z_TYPE_P(op1) == IS_LONG) {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_MOD, mod_function);
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
op1_lval = _zval_get_long_func(op1 TSRMLS_CC);
|
||||
} else {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
}
|
||||
} while (0);
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
|
||||
if (Z_ISREF_P(op2)) {
|
||||
op2 = Z_REFVAL_P(op2);
|
||||
if (Z_TYPE_P(op2) == IS_LONG) break;
|
||||
if (Z_TYPE_P(op2) == IS_LONG) {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_MOD);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
op2_lval = _zval_get_long_func(op2 TSRMLS_CC);
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
if (Z_LVAL_P(op2) == 0) {
|
||||
if (op2_lval == 0) {
|
||||
zend_error(E_WARNING, "Division by zero");
|
||||
ZVAL_BOOL(result, 0);
|
||||
return FAILURE; /* modulus by zero */
|
||||
}
|
||||
|
||||
if (Z_LVAL_P(op2) == -1) {
|
||||
if (op2_lval == -1) {
|
||||
/* Prevent overflow error/crash if op1==LONG_MIN */
|
||||
ZVAL_LONG(result, 0);
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval % Z_LVAL_P(op2));
|
||||
ZVAL_LONG(result, op1_lval % op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
int op1_val, op2_val;
|
||||
|
||||
do {
|
||||
|
@ -1263,8 +1188,7 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BOOL_XOR, boolean_xor_function);
|
||||
zendi_convert_to_boolean(op1, op1_copy, result);
|
||||
op1_val = (Z_TYPE_P(op1) == IS_TRUE);
|
||||
op1_val = zval_is_true(op1);
|
||||
}
|
||||
} while (0);
|
||||
do {
|
||||
|
@ -1284,8 +1208,7 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BOOL_XOR);
|
||||
zendi_convert_to_boolean(op2, op2_copy, result);
|
||||
op2_val = (Z_TYPE_P(op2) == IS_TRUE);
|
||||
op2_val = zval_is_true(op2);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
|
@ -1296,8 +1219,6 @@ ZEND_API int boolean_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
|
||||
ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy;
|
||||
|
||||
if (Z_TYPE_P(op1) < IS_TRUE) {
|
||||
ZVAL_TRUE(result);
|
||||
} else if (EXPECTED(Z_TYPE_P(op1) == IS_TRUE)) {
|
||||
|
@ -1315,9 +1236,7 @@ ZEND_API int boolean_not_function(zval *result, zval *op1 TSRMLS_DC) /* {{{ */
|
|||
}
|
||||
ZEND_TRY_UNARY_OBJECT_OPERATION(ZEND_BOOL_NOT);
|
||||
|
||||
zendi_convert_to_boolean(op1, op1_copy, result);
|
||||
|
||||
ZVAL_BOOL(result, Z_TYPE_P(op1) == IS_FALSE);
|
||||
ZVAL_BOOL(result, !zval_is_true(op1));
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
@ -1357,8 +1276,7 @@ try_again:
|
|||
|
||||
ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
zend_long op1_lval;
|
||||
zend_long op1_lval, op2_lval;
|
||||
|
||||
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) | Z_LVAL_P(op2));
|
||||
|
@ -1395,23 +1313,25 @@ ZEND_API int bitwise_or_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /
|
|||
|
||||
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_OR, bitwise_or_function);
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
op1_lval = _zval_get_long_func(op1 TSRMLS_CC);
|
||||
} else {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
}
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_OR);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
op2_lval = _zval_get_long_func(op2 TSRMLS_CC);
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval | Z_LVAL_P(op2));
|
||||
ZVAL_LONG(result, op1_lval | op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
zend_long op1_lval;
|
||||
zend_long op1_lval, op2_lval;
|
||||
|
||||
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) & Z_LVAL_P(op2));
|
||||
|
@ -1447,24 +1367,26 @@ ZEND_API int bitwise_and_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
}
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_and_function);
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_AND, bitwise_or_function);
|
||||
op1_lval = _zval_get_long_func(op1 TSRMLS_CC);
|
||||
} else {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
}
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_AND);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
op2_lval = _zval_get_long_func(op2 TSRMLS_CC);
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval & Z_LVAL_P(op2));
|
||||
ZVAL_LONG(result, op1_lval & op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
zend_long op1_lval;
|
||||
zend_long op1_lval, op2_lval;
|
||||
|
||||
if (EXPECTED(Z_TYPE_P(op1) == IS_LONG) && EXPECTED(Z_TYPE_P(op2) == IS_LONG)) {
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) ^ Z_LVAL_P(op2));
|
||||
|
@ -1500,104 +1422,123 @@ ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
}
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_xor_function);
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_BW_XOR, bitwise_or_function);
|
||||
op1_lval = _zval_get_long_func(op1 TSRMLS_CC);
|
||||
} else {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
}
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_BW_XOR);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
op2_lval = _zval_get_long_func(op2 TSRMLS_CC);
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval ^ Z_LVAL_P(op2));
|
||||
ZVAL_LONG(result, op1_lval ^ op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
zend_long op1_lval;
|
||||
zend_long op1_lval, op2_lval;
|
||||
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
|
||||
if (Z_ISREF_P(op1)) {
|
||||
op1 = Z_REFVAL_P(op1);
|
||||
if (Z_TYPE_P(op1) == IS_LONG) break;
|
||||
if (Z_TYPE_P(op1) == IS_LONG) {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SL, shift_left_function);
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SL, mod_function);
|
||||
op1_lval = _zval_get_long_func(op1 TSRMLS_CC);
|
||||
} else {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
}
|
||||
} while (0);
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
|
||||
if (Z_ISREF_P(op2)) {
|
||||
op2 = Z_REFVAL_P(op2);
|
||||
if (Z_TYPE_P(op2) == IS_LONG) break;
|
||||
if (Z_TYPE_P(op2) == IS_LONG) {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_SL);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
op2_lval = _zval_get_long_func(op2 TSRMLS_CC);
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
/* prevent wrapping quirkiness on some processors where << 64 + x == << x */
|
||||
if (Z_LVAL_P(op2) >= SIZEOF_ZEND_LONG * 8) {
|
||||
ZVAL_LONG(result, 0);
|
||||
return SUCCESS;
|
||||
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
|
||||
if (EXPECTED(op2_lval > 0)) {
|
||||
ZVAL_LONG(result, 0);
|
||||
return SUCCESS;
|
||||
} else {
|
||||
zend_error(E_WARNING, "Bit shift by negative number");
|
||||
ZVAL_FALSE(result);
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Z_LVAL_P(op2) < 0) {
|
||||
zend_error(E_WARNING, "Bit shift by negative number");
|
||||
ZVAL_FALSE(result);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval << Z_LVAL_P(op2));
|
||||
ZVAL_LONG(result, op1_lval << op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval op1_copy, op2_copy;
|
||||
zend_long op1_lval;
|
||||
zend_long op1_lval, op2_lval;
|
||||
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE_P(op1) != IS_LONG)) {
|
||||
if (Z_ISREF_P(op1)) {
|
||||
op1 = Z_REFVAL_P(op1);
|
||||
if (Z_TYPE_P(op1) == IS_LONG) break;
|
||||
if (Z_TYPE_P(op1) == IS_LONG) {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SR, shift_right_function);
|
||||
zendi_convert_to_long(op1, op1_copy, result);
|
||||
ZEND_TRY_BINARY_OP1_OBJECT_OPERATION(ZEND_SR, mod_function);
|
||||
op1_lval = _zval_get_long_func(op1 TSRMLS_CC);
|
||||
} else {
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
}
|
||||
} while (0);
|
||||
op1_lval = Z_LVAL_P(op1);
|
||||
do {
|
||||
if (UNEXPECTED(Z_TYPE_P(op2) != IS_LONG)) {
|
||||
if (Z_ISREF_P(op2)) {
|
||||
op2 = Z_REFVAL_P(op2);
|
||||
if (Z_TYPE_P(op2) == IS_LONG) break;
|
||||
if (Z_TYPE_P(op2) == IS_LONG) {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ZEND_TRY_BINARY_OP2_OBJECT_OPERATION(ZEND_SR);
|
||||
zendi_convert_to_long(op2, op2_copy, result);
|
||||
op2_lval = _zval_get_long_func(op2 TSRMLS_CC);
|
||||
} else {
|
||||
op2_lval = Z_LVAL_P(op2);
|
||||
}
|
||||
} while (0);
|
||||
|
||||
/* prevent wrapping quirkiness on some processors where >> 64 + x == >> x */
|
||||
if (Z_LVAL_P(op2) >= SIZEOF_ZEND_LONG * 8) {
|
||||
ZVAL_LONG(result, (Z_LVAL_P(op1) < 0) ? -1 : 0);
|
||||
return SUCCESS;
|
||||
if (UNEXPECTED((zend_ulong)op2_lval >= SIZEOF_ZEND_LONG * 8)) {
|
||||
if (EXPECTED(op2_lval > 0)) {
|
||||
ZVAL_LONG(result, (op1_lval < 0) ? -1 : 0);
|
||||
return SUCCESS;
|
||||
} else {
|
||||
zend_error(E_WARNING, "Bit shift by negative number");
|
||||
ZVAL_FALSE(result);
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if (Z_LVAL_P(op2) < 0) {
|
||||
zend_error(E_WARNING, "Bit shift by negative number");
|
||||
ZVAL_FALSE(result);
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
ZVAL_LONG(result, op1_lval >> Z_LVAL_P(op2));
|
||||
ZVAL_LONG(result, op1_lval >> op2_lval);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -1953,20 +1894,16 @@ ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC) /* {
|
|||
}
|
||||
if (!converted) {
|
||||
if (Z_TYPE_P(op1) == IS_NULL || Z_TYPE_P(op1) == IS_FALSE) {
|
||||
zendi_convert_to_boolean(op2, op2_copy, result);
|
||||
ZVAL_LONG(result, (Z_TYPE_P(op2) == IS_TRUE) ? -1 : 0);
|
||||
ZVAL_LONG(result, zval_is_true(op2) ? -1 : 0);
|
||||
return SUCCESS;
|
||||
} else if (Z_TYPE_P(op2) == IS_NULL || Z_TYPE_P(op2) == IS_FALSE) {
|
||||
zendi_convert_to_boolean(op1, op1_copy, result);
|
||||
ZVAL_LONG(result, (Z_TYPE_P(op1) == IS_TRUE) ? 1 : 0);
|
||||
ZVAL_LONG(result, zval_is_true(op1) ? 1 : 0);
|
||||
return SUCCESS;
|
||||
} else if (Z_TYPE_P(op1) == IS_TRUE) {
|
||||
zendi_convert_to_boolean(op2, op2_copy, result);
|
||||
ZVAL_LONG(result, (Z_TYPE_P(op2) == IS_TRUE) ? 0 : 1);
|
||||
ZVAL_LONG(result, zval_is_true(op2) ? 0 : 1);
|
||||
return SUCCESS;
|
||||
} else if (Z_TYPE_P(op2) == IS_TRUE) {
|
||||
zendi_convert_to_boolean(op1, op1_copy, result);
|
||||
ZVAL_LONG(result, (Z_TYPE_P(op1) == IS_TRUE) ? 0 : -1);
|
||||
ZVAL_LONG(result, zval_is_true(op1) ? 0 : -1);
|
||||
return SUCCESS;
|
||||
} else {
|
||||
zendi_convert_scalar_to_number(op1, op1_copy, result);
|
||||
|
@ -2384,10 +2321,33 @@ try_again:
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zval_is_true(zval *op) /* {{{ */
|
||||
ZEND_API int zend_is_true(zval *op TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
convert_to_boolean(op);
|
||||
return (Z_TYPE_P(op) == IS_TRUE ? 1 : 0);
|
||||
return i_zend_is_true(op TSRMLS_CC);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API int zend_object_is_true(zval *op TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
if (Z_OBJ_HT_P(op)->cast_object) {
|
||||
zval tmp;
|
||||
if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, _IS_BOOL TSRMLS_CC) == SUCCESS) {
|
||||
return Z_TYPE(tmp) == IS_TRUE;
|
||||
}
|
||||
zend_error(E_RECOVERABLE_ERROR, "Object of class %s could not be converted to boolean", Z_OBJ_P(op)->ce->name->val);
|
||||
} else if (Z_OBJ_HT_P(op)->get) {
|
||||
int result;
|
||||
zval rv;
|
||||
zval *tmp = Z_OBJ_HT_P(op)->get(op, &rv TSRMLS_CC);
|
||||
|
||||
if (Z_TYPE_P(tmp) != IS_OBJECT) {
|
||||
/* for safety - avoid loop */
|
||||
result = i_zend_is_true(tmp TSRMLS_CC);
|
||||
zval_ptr_dtor(tmp);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -252,7 +252,61 @@ ZEND_API int add_string_to_string(zval *result, const zval *op1, const zval *op2
|
|||
#define convert_to_cstring(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_cstring((op) ZEND_FILE_LINE_CC); }
|
||||
#define convert_to_string(op) if (Z_TYPE_P(op) != IS_STRING) { _convert_to_string((op) ZEND_FILE_LINE_CC); }
|
||||
|
||||
ZEND_API int zval_is_true(zval *op);
|
||||
|
||||
ZEND_API int zend_is_true(zval *op TSRMLS_DC);
|
||||
ZEND_API int zend_object_is_true(zval *op TSRMLS_DC);
|
||||
|
||||
#define zval_is_true(op) \
|
||||
zend_is_true(op TSRMLS_CC)
|
||||
|
||||
static zend_always_inline int i_zend_is_true(zval *op TSRMLS_DC)
|
||||
{
|
||||
int result;
|
||||
|
||||
again:
|
||||
switch (Z_TYPE_P(op)) {
|
||||
case IS_UNDEF:
|
||||
case IS_NULL:
|
||||
case IS_FALSE:
|
||||
result = 0;
|
||||
break;
|
||||
case IS_TRUE:
|
||||
result = 1;
|
||||
break;
|
||||
case IS_LONG:
|
||||
result = (Z_LVAL_P(op)?1:0);
|
||||
break;
|
||||
case IS_RESOURCE:
|
||||
result = (Z_RES_HANDLE_P(op)?1:0);
|
||||
break;
|
||||
case IS_DOUBLE:
|
||||
result = (Z_DVAL_P(op) ? 1 : 0);
|
||||
break;
|
||||
case IS_STRING:
|
||||
if (Z_STRLEN_P(op) == 0
|
||||
|| (Z_STRLEN_P(op)==1 && Z_STRVAL_P(op)[0]=='0')) {
|
||||
result = 0;
|
||||
} else {
|
||||
result = 1;
|
||||
}
|
||||
break;
|
||||
case IS_ARRAY:
|
||||
result = (zend_hash_num_elements(Z_ARRVAL_P(op))?1:0);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
result = zend_object_is_true(op TSRMLS_CC);
|
||||
break;
|
||||
case IS_REFERENCE:
|
||||
op = Z_REFVAL_P(op);
|
||||
goto again;
|
||||
break;
|
||||
default:
|
||||
result = 0;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ZEND_API int compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
|
||||
ZEND_API int numeric_compare_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
|
||||
ZEND_API int string_compare_function_ex(zval *result, zval *op1, zval *op2, zend_bool case_insensitive TSRMLS_DC);
|
||||
|
@ -389,6 +443,33 @@ static zend_always_inline int fast_increment_function(zval *op1)
|
|||
"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"
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
"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"
|
||||
#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");
|
||||
#else
|
||||
if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MAX)) {
|
||||
/* switch to double */
|
||||
|
@ -431,6 +512,33 @@ static zend_always_inline int fast_decrement_function(zval *op1)
|
|||
"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"
|
||||
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||
"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"
|
||||
#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");
|
||||
#else
|
||||
if (UNEXPECTED(Z_LVAL_P(op1) == ZEND_LONG_MIN)) {
|
||||
/* switch to double */
|
||||
|
@ -494,6 +602,36 @@ static zend_always_inline int fast_add_function(zval *result, zval *op1, zval *o
|
|||
"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");
|
||||
#else
|
||||
/*
|
||||
* 'result' may alias with op1 or op2, so we need to
|
||||
|
@ -583,6 +721,36 @@ static zend_always_inline int fast_sub_function(zval *result, zval *op1, zval *o
|
|||
"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");
|
||||
#else
|
||||
ZVAL_LONG(result, Z_LVAL_P(op1) - Z_LVAL_P(op2));
|
||||
|
||||
|
|
|
@ -361,7 +361,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
|||
|
||||
/* here we are sure we are dealing with an object */
|
||||
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
|
||||
|
||||
ZVAL_DEREF(zptr);
|
||||
SEPARATE_ZVAL_NOREF(zptr);
|
||||
|
@ -375,7 +375,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
|||
zval rv;
|
||||
|
||||
if (Z_OBJ_HT_P(object)->read_property &&
|
||||
(z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC)) != NULL) {
|
||||
(z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC)) != NULL) {
|
||||
if (Z_TYPE_P(z) == IS_OBJECT && Z_OBJ_HT_P(z)->get) {
|
||||
zval rv;
|
||||
zval *value = Z_OBJ_HT_P(z)->get(z, &rv TSRMLS_CC);
|
||||
|
@ -388,7 +388,7 @@ ZEND_VM_HELPER_EX(zend_binary_assign_op_obj_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
|||
ZVAL_DEREF(z);
|
||||
SEPARATE_ZVAL_NOREF(z);
|
||||
binary_op(z, z, value TSRMLS_CC);
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
|
||||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), z);
|
||||
}
|
||||
|
@ -759,7 +759,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
|
|||
/* here we are sure we are dealing with an object */
|
||||
|
||||
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
|
||||
|
||||
ZVAL_DEREF(zptr);
|
||||
SEPARATE_ZVAL_NOREF(zptr);
|
||||
|
@ -772,7 +772,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
|
|||
zval rv;
|
||||
|
||||
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
|
||||
zval rv;
|
||||
|
@ -789,7 +789,7 @@ ZEND_VM_HELPER_EX(zend_pre_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|C
|
|||
if (UNEXPECTED(RETURN_VALUE_USED(opline))) {
|
||||
ZVAL_COPY(retval, z);
|
||||
}
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, z, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
|
||||
zval_ptr_dtor(z);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Attempt to increment/decrement property of non-object");
|
||||
|
@ -846,7 +846,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
|||
/* here we are sure we are dealing with an object */
|
||||
|
||||
if (EXPECTED(Z_OBJ_HT_P(object)->get_property_ptr_ptr)
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
|
||||
&& EXPECTED((zptr = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, property, BP_VAR_RW, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC)) != NULL)) {
|
||||
|
||||
ZVAL_DEREF(zptr);
|
||||
ZVAL_COPY_VALUE(retval, zptr);
|
||||
|
@ -856,7 +856,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
|||
} else {
|
||||
if (Z_OBJ_HT_P(object)->read_property && Z_OBJ_HT_P(object)->write_property) {
|
||||
zval rv;
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
|
||||
zval *z = Z_OBJ_HT_P(object)->read_property(object, property, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), &rv TSRMLS_CC);
|
||||
zval z_copy;
|
||||
|
||||
if (UNEXPECTED(Z_TYPE_P(z) == IS_OBJECT) && Z_OBJ_HT_P(z)->get) {
|
||||
|
@ -872,7 +872,7 @@ ZEND_VM_HELPER_EX(zend_post_incdec_property_helper, VAR|UNUSED|CV, CONST|TMPVAR|
|
|||
ZVAL_DUP(&z_copy, z);
|
||||
incdec_op(&z_copy);
|
||||
if (Z_REFCOUNTED_P(z)) Z_ADDREF_P(z);
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
|
||||
Z_OBJ_HT_P(object)->write_property(object, property, &z_copy, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL) TSRMLS_CC);
|
||||
zval_ptr_dtor(&z_copy);
|
||||
zval_ptr_dtor(z);
|
||||
} else {
|
||||
|
@ -1118,10 +1118,10 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
|
|||
zend_class_entry *ce;
|
||||
|
||||
if (OP2_TYPE == IS_CONST) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0 TSRMLS_CC);
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
if (OP1_TYPE != IS_CONST) {
|
||||
zend_string_release(name);
|
||||
|
@ -1130,12 +1130,12 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMPVAR|CV, UNUSED|CONST|V
|
|||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
|
||||
}
|
||||
} else {
|
||||
ce = Z_CE_P(EX_VAR(opline->op2.var));
|
||||
}
|
||||
retval = zend_std_get_static_property(ce, name, 0, ((OP1_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
|
||||
retval = zend_std_get_static_property(ce, name, 0, ((OP1_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
|
||||
FREE_OP1();
|
||||
} else {
|
||||
target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
|
||||
|
@ -1423,7 +1423,7 @@ ZEND_VM_C_LABEL(fetch_obj_r_no_object):
|
|||
}
|
||||
}
|
||||
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_R, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
|
@ -1452,7 +1452,7 @@ ZEND_VM_HANDLER(85, ZEND_FETCH_OBJ_W, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
|||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
|
@ -1476,7 +1476,7 @@ ZEND_VM_HANDLER(88, ZEND_FETCH_OBJ_RW, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
|||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_RW TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
|
@ -1536,7 +1536,7 @@ ZEND_VM_C_LABEL(fetch_obj_is_no_object):
|
|||
}
|
||||
}
|
||||
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
retval = Z_OBJ_HT_P(container)->read_property(container, offset, BP_VAR_IS, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL), EX_VAR(opline->result.var) TSRMLS_CC);
|
||||
|
||||
if (retval != EX_VAR(opline->result.var)) {
|
||||
ZVAL_COPY(EX_VAR(opline->result.var), retval);
|
||||
|
@ -1570,7 +1570,7 @@ ZEND_VM_HANDLER(94, ZEND_FETCH_OBJ_FUNC_ARG, CONST|TMP|VAR|UNUSED|CV, CONST|TMPV
|
|||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_W TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
|
@ -1596,7 +1596,7 @@ ZEND_VM_HANDLER(97, ZEND_FETCH_OBJ_UNSET, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
|||
if (OP1_TYPE == IS_VAR && UNEXPECTED(container == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an object");
|
||||
}
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
|
||||
zend_fetch_property_address(EX_VAR(opline->result.var), container, OP1_TYPE, property, OP2_TYPE, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property)) : NULL), BP_VAR_UNSET TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
if (OP1_TYPE == IS_VAR && READY_TO_DESTROY(free_op1)) {
|
||||
EXTRACT_ZVAL_PTR(EX_VAR(opline->result.var));
|
||||
|
@ -1657,7 +1657,7 @@ ZEND_VM_HANDLER(136, ZEND_ASSIGN_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
|||
if (OP1_TYPE == IS_VAR && UNEXPECTED(object == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Cannot use string offset as an array");
|
||||
}
|
||||
zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
|
||||
zend_assign_to_object(UNEXPECTED(RETURN_VALUE_USED(opline)) ? EX_VAR(opline->result.var) : NULL, object, OP1_TYPE, property_name, OP2_TYPE, (opline+1)->op1_type, (opline+1)->op1, execute_data, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(property_name)) : NULL) TSRMLS_CC);
|
||||
FREE_OP2();
|
||||
FREE_OP1_VAR_PTR();
|
||||
/* assign_obj has two opcodes! */
|
||||
|
@ -1935,7 +1935,7 @@ ZEND_VM_HANDLER(42, ZEND_JMP, ANY, ANY)
|
|||
{
|
||||
USE_OPLINE
|
||||
|
||||
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
|
||||
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
|
@ -1953,9 +1953,9 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ANY)
|
|||
ZEND_VM_CONTINUE();
|
||||
} else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
|
||||
if (OP1_TYPE == IS_CV) {
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
} else {
|
||||
ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
|
||||
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
}
|
||||
|
@ -1963,7 +1963,7 @@ ZEND_VM_HANDLER(43, ZEND_JMPZ, CONST|TMPVAR|CV, ANY)
|
|||
if (i_zend_is_true(val TSRMLS_CC)) {
|
||||
opline++;
|
||||
} else {
|
||||
opline = opline->op2.jmp_addr;
|
||||
opline = OP_JMP_ADDR(opline, opline->op2);
|
||||
}
|
||||
FREE_OP1();
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
|
@ -1982,7 +1982,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ANY)
|
|||
val = GET_OP1_ZVAL_PTR(BP_VAR_R);
|
||||
|
||||
if (Z_TYPE_P(val) == IS_TRUE) {
|
||||
ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
|
||||
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
|
||||
if (OP1_TYPE == IS_CV) {
|
||||
|
@ -1994,7 +1994,7 @@ ZEND_VM_HANDLER(44, ZEND_JMPNZ, CONST|TMPVAR|CV, ANY)
|
|||
}
|
||||
|
||||
if (i_zend_is_true(val TSRMLS_CC)) {
|
||||
opline = opline->op2.jmp_addr;
|
||||
opline = OP_JMP_ADDR(opline, opline->op2);
|
||||
} else {
|
||||
opline++;
|
||||
}
|
||||
|
@ -2019,17 +2019,17 @@ ZEND_VM_HANDLER(45, ZEND_JMPZNZ, CONST|TMPVAR|CV, ANY)
|
|||
ZEND_VM_CONTINUE();
|
||||
} else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
|
||||
if (OP1_TYPE == IS_CV) {
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
} else {
|
||||
ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
|
||||
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
}
|
||||
|
||||
if (i_zend_is_true(val TSRMLS_CC)) {
|
||||
opline = (zend_op*)(((char*)opline) + opline->extended_value);
|
||||
opline = ZEND_OFFSET_TO_OPLINE(opline, opline->extended_value);
|
||||
} else {
|
||||
opline = opline->op2.jmp_addr;
|
||||
opline = OP_JMP_ADDR(opline, opline->op2);
|
||||
}
|
||||
FREE_OP1();
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
|
@ -2054,9 +2054,9 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ANY)
|
|||
} else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
if (OP1_TYPE == IS_CV) {
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
} else {
|
||||
ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
|
||||
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
}
|
||||
|
@ -2068,7 +2068,7 @@ ZEND_VM_HANDLER(46, ZEND_JMPZ_EX, CONST|TMPVAR|CV, ANY)
|
|||
} else {
|
||||
FREE_OP1();
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
opline = opline->op2.jmp_addr;
|
||||
opline = OP_JMP_ADDR(opline, opline->op2);
|
||||
}
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
HANDLE_EXCEPTION();
|
||||
|
@ -2087,7 +2087,7 @@ ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, ANY)
|
|||
|
||||
if (Z_TYPE_P(val) == IS_TRUE) {
|
||||
ZVAL_TRUE(EX_VAR(opline->result.var));
|
||||
ZEND_VM_SET_OPCODE(opline->op2.jmp_addr);
|
||||
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op2));
|
||||
ZEND_VM_CONTINUE();
|
||||
} else if (EXPECTED(Z_TYPE_P(val) <= IS_TRUE)) {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
|
@ -2100,7 +2100,7 @@ ZEND_VM_HANDLER(47, ZEND_JMPNZ_EX, CONST|TMPVAR|CV, ANY)
|
|||
}
|
||||
if (i_zend_is_true(val TSRMLS_CC)) {
|
||||
ZVAL_TRUE(EX_VAR(opline->result.var));
|
||||
opline = opline->op2.jmp_addr;
|
||||
opline = OP_JMP_ADDR(opline, opline->op2);
|
||||
} else {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
opline++;
|
||||
|
@ -2134,7 +2134,7 @@ ZEND_VM_HANDLER(54, ZEND_ADD_CHAR, TMP|UNUSED, CONST)
|
|||
ZVAL_EMPTY_STRING(str);
|
||||
}
|
||||
|
||||
add_char_to_string(str, str, opline->op2.zv);
|
||||
add_char_to_string(str, str, EX_CONSTANT(opline->op2));
|
||||
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
/*CHECK_EXCEPTION();*/
|
||||
|
@ -2153,7 +2153,7 @@ ZEND_VM_HANDLER(55, ZEND_ADD_STRING, TMP|UNUSED, CONST)
|
|||
ZVAL_EMPTY_STRING(str);
|
||||
}
|
||||
|
||||
add_string_to_string(str, str, opline->op2.zv);
|
||||
add_string_to_string(str, str, EX_CONSTANT(opline->op2));
|
||||
|
||||
/* FREE_OP is missing intentionally here - we're always working on the same temporary variable */
|
||||
/*CHECK_EXCEPTION();*/
|
||||
|
@ -2222,7 +2222,7 @@ ZEND_VM_C_LABEL(try_class_name):
|
|||
if (CACHED_PTR(Z_CACHE_SLOT_P(class_name))) {
|
||||
Z_CE_P(EX_VAR(opline->result.var)) = CACHED_PTR(Z_CACHE_SLOT_P(class_name));
|
||||
} else {
|
||||
Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), opline->op2.zv + 1, opline->extended_value TSRMLS_CC);
|
||||
Z_CE_P(EX_VAR(opline->result.var)) = zend_fetch_class_by_name(Z_STR_P(class_name), EX_CONSTANT(opline->op2) + 1, opline->extended_value TSRMLS_CC);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(class_name), Z_CE_P(EX_VAR(opline->result.var)));
|
||||
}
|
||||
} else if (Z_TYPE_P(class_name) == IS_OBJECT) {
|
||||
|
@ -2335,7 +2335,7 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMPVAR|UNUSED|CV, CONST|TMPVAR|CV)
|
|||
}
|
||||
|
||||
/* First, locate the function. */
|
||||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
|
||||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL) TSRMLS_CC);
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", obj->ce->name->val, Z_STRVAL_P(function_name));
|
||||
}
|
||||
|
@ -2375,17 +2375,17 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
|
|||
|
||||
if (OP1_TYPE == IS_CONST) {
|
||||
/* no function found. try a static method in class */
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
|
||||
} else {
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_DEFAULT TSRMLS_CC);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op1.zv));
|
||||
zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
|
||||
}
|
||||
} else {
|
||||
ce = Z_CE_P(EX_VAR(opline->op1.var));
|
||||
|
@ -2393,11 +2393,11 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
|
|||
|
||||
if (OP1_TYPE == IS_CONST &&
|
||||
OP2_TYPE == IS_CONST &&
|
||||
CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else if (OP1_TYPE != IS_CONST &&
|
||||
OP2_TYPE == IS_CONST &&
|
||||
(fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce))) {
|
||||
(fbc = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce))) {
|
||||
/* do nothing */
|
||||
} else if (OP2_TYPE != IS_UNUSED) {
|
||||
zend_free_op free_op2;
|
||||
|
@ -2415,7 +2415,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
|
|||
if (ce->get_static_method) {
|
||||
fbc = ce->get_static_method(ce, Z_STR_P(function_name) TSRMLS_CC);
|
||||
} else {
|
||||
fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (opline->op2.zv + 1) : NULL) TSRMLS_CC);
|
||||
fbc = zend_std_get_static_method(ce, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (EX_CONSTANT(opline->op2) + 1) : NULL) TSRMLS_CC);
|
||||
}
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined method %s::%s()", ce->name->val, Z_STRVAL_P(function_name));
|
||||
|
@ -2493,16 +2493,16 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMPVAR|CV)
|
|||
zend_function *fbc;
|
||||
zval *function_name, *func;
|
||||
|
||||
if (OP2_TYPE == IS_CONST && Z_TYPE_P(opline->op2.zv) == IS_STRING) {
|
||||
function_name = (zval*)(opline->op2.zv+1);
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (OP2_TYPE == IS_CONST && Z_TYPE_P(EX_CONSTANT(opline->op2)) == IS_STRING) {
|
||||
function_name = (zval*)(EX_CONSTANT(opline->op2)+1);
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(function_name))) == NULL)) {
|
||||
SAVE_OPLINE();
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
fbc = Z_FUNC_P(func);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
|
||||
}
|
||||
|
||||
EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
|
||||
|
@ -2673,7 +2673,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)
|
|||
}
|
||||
}
|
||||
} else {
|
||||
zend_error(E_WARNING, "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(opline->op1.zv), error);
|
||||
zend_error(E_WARNING, "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error);
|
||||
efree(error);
|
||||
func = (zend_function*)&zend_pass_function;
|
||||
called_scope = NULL;
|
||||
|
@ -2695,21 +2695,21 @@ ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
|
|||
zval *func;
|
||||
zend_function *fbc;
|
||||
|
||||
func_name = opline->op2.zv + 1;
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
func_name = EX_CONSTANT(opline->op2) + 1;
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
fbc = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else if ((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL) {
|
||||
func_name++;
|
||||
if (UNEXPECTED((func = zend_hash_find(EG(function_table), Z_STR_P(func_name))) == NULL)) {
|
||||
SAVE_OPLINE();
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(opline->op2.zv));
|
||||
zend_error_noreturn(E_ERROR, "Call to undefined function %s()", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
fbc = Z_FUNC_P(func);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
|
||||
}
|
||||
} else {
|
||||
fbc = Z_FUNC_P(func);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), fbc);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), fbc);
|
||||
}
|
||||
|
||||
EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
|
||||
|
@ -2736,8 +2736,8 @@ ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST)
|
|||
CACHE_PTR(Z_CACHE_SLOT_P(fname), fbc);
|
||||
}
|
||||
|
||||
EX(call) = zend_vm_stack_push_call_frame(ZEND_CALL_NESTED_FUNCTION,
|
||||
fbc, opline->extended_value, NULL, NULL, EX(call) TSRMLS_CC);
|
||||
EX(call) = zend_vm_stack_push_call_frame_ex(ZEND_CALL_NESTED_FUNCTION,
|
||||
fbc, opline->op1.num, NULL, NULL, EX(call) TSRMLS_CC);
|
||||
|
||||
FREE_OP2();
|
||||
|
||||
|
@ -3080,12 +3080,12 @@ ZEND_VM_HANDLER(107, ZEND_CATCH, CONST, CV)
|
|||
ZEND_VM_SET_OPCODE(&EX(func)->op_array.opcodes[opline->extended_value]);
|
||||
ZEND_VM_CONTINUE(); /* CHECK_ME */
|
||||
}
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
|
||||
catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
|
||||
catch_ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
|
||||
} else {
|
||||
catch_ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
|
||||
catch_ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
|
||||
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), catch_ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), catch_ce);
|
||||
}
|
||||
ce = EG(exception)->ce;
|
||||
|
||||
|
@ -3677,7 +3677,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
|
|||
SAVE_OPLINE();
|
||||
param = _get_zval_ptr_cv_undef_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
||||
if (arg_num > EX_NUM_ARGS()) {
|
||||
ZVAL_COPY_VALUE(param, opline->op2.zv);
|
||||
ZVAL_COPY_VALUE(param, EX_CONSTANT(opline->op2));
|
||||
if (Z_OPT_CONSTANT_P(param)) {
|
||||
zval_update_constant(param, 0 TSRMLS_CC);
|
||||
} else {
|
||||
|
@ -3689,7 +3689,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
|
|||
}
|
||||
|
||||
if (UNEXPECTED((EX(func)->op_array.fn_flags & ZEND_ACC_HAS_TYPE_HINTS) != 0)) {
|
||||
zend_verify_arg_type(EX(func), arg_num, param, opline->op2.zv TSRMLS_CC);
|
||||
zend_verify_arg_type(EX(func), arg_num, param, EX_CONSTANT(opline->op2) TSRMLS_CC);
|
||||
}
|
||||
|
||||
CHECK_EXCEPTION();
|
||||
|
@ -3760,7 +3760,7 @@ ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
|
|||
zend_brk_cont_element *el;
|
||||
|
||||
SAVE_OPLINE();
|
||||
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
|
||||
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
|
||||
&EX(func)->op_array, execute_data TSRMLS_CC);
|
||||
ZEND_VM_JMP(EX(func)->op_array.opcodes + el->brk);
|
||||
}
|
||||
|
@ -3771,7 +3771,7 @@ ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
|
|||
zend_brk_cont_element *el;
|
||||
|
||||
SAVE_OPLINE();
|
||||
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
|
||||
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->op1.opline_num,
|
||||
&EX(func)->op_array, execute_data TSRMLS_CC);
|
||||
ZEND_VM_JMP(EX(func)->op_array.opcodes + el->cont);
|
||||
}
|
||||
|
@ -3783,7 +3783,7 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
|
|||
zend_brk_cont_element *el;
|
||||
|
||||
SAVE_OPLINE();
|
||||
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->extended_value,
|
||||
el = zend_brk_cont(Z_LVAL_P(EX_CONSTANT(opline->op2)), opline->extended_value,
|
||||
&EX(func)->op_array, execute_data TSRMLS_CC);
|
||||
|
||||
brk_opline = EX(func)->op_array.opcodes + el->brk;
|
||||
|
@ -3793,7 +3793,7 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
|
|||
zval_ptr_dtor_nogc(EX_VAR(brk_opline->op1.var));
|
||||
}
|
||||
}
|
||||
ZEND_VM_JMP(opline->op1.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op1));
|
||||
}
|
||||
|
||||
ZEND_VM_HANDLER(48, ZEND_CASE, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
|
||||
|
@ -3821,15 +3821,15 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY)
|
|||
|
||||
SAVE_OPLINE();
|
||||
if (OP1_TYPE == IS_CONST) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
|
||||
} else {
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0 TSRMLS_CC);
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
|
||||
}
|
||||
} else {
|
||||
ce = Z_CE_P(EX_VAR(opline->op1.var));
|
||||
|
@ -3852,7 +3852,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY)
|
|||
} else {
|
||||
OBJ_RELEASE(Z_OBJ(object_zval));
|
||||
}
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
} else {
|
||||
/* We are not handling overloaded classes right now */
|
||||
EX(call) = zend_vm_stack_push_call_frame(
|
||||
|
@ -3951,17 +3951,17 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
|||
zend_constant *c;
|
||||
zval *retval;
|
||||
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
c = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
} else if ((c = zend_quick_get_constant(opline->op2.zv + 1, opline->extended_value TSRMLS_CC)) == NULL) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
c = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op2) + 1, opline->extended_value TSRMLS_CC)) == NULL) {
|
||||
if ((opline->extended_value & IS_CONSTANT_UNQUALIFIED) != 0) {
|
||||
char *actual = (char *)zend_memrchr(Z_STRVAL_P(opline->op2.zv), '\\', Z_STRLEN_P(opline->op2.zv));
|
||||
char *actual = (char *)zend_memrchr(Z_STRVAL_P(EX_CONSTANT(opline->op2)), '\\', Z_STRLEN_P(EX_CONSTANT(opline->op2)));
|
||||
if (!actual) {
|
||||
ZVAL_STR(EX_VAR(opline->result.var), zend_string_copy(Z_STR_P(opline->op2.zv)));
|
||||
ZVAL_STR(EX_VAR(opline->result.var), zend_string_copy(Z_STR_P(EX_CONSTANT(opline->op2))));
|
||||
} else {
|
||||
actual++;
|
||||
ZVAL_STRINGL(EX_VAR(opline->result.var),
|
||||
actual, Z_STRLEN_P(opline->op2.zv) - (actual - Z_STRVAL_P(opline->op2.zv)));
|
||||
actual, Z_STRLEN_P(EX_CONSTANT(opline->op2)) - (actual - Z_STRVAL_P(EX_CONSTANT(opline->op2))));
|
||||
}
|
||||
/* non-qualified constant - allow text substitution */
|
||||
zend_error(E_NOTICE, "Use of undefined constant %s - assumed '%s'",
|
||||
|
@ -3969,10 +3969,10 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
|||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(opline->op2.zv));
|
||||
zend_error_noreturn(E_ERROR, "Undefined constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
}
|
||||
} else {
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), c);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), c);
|
||||
}
|
||||
retval = EX_VAR(opline->result.var);
|
||||
ZVAL_COPY_VALUE(retval, &c->value);
|
||||
|
@ -3989,33 +3989,33 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
|||
zval *value;
|
||||
|
||||
if (OP1_TYPE == IS_CONST) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
value = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
value = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
ZVAL_DEREF(value);
|
||||
ZVAL_DUP(EX_VAR(opline->result.var), value);
|
||||
ZEND_VM_C_GOTO(constant_fetch_end);
|
||||
} else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv));
|
||||
} else if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)));
|
||||
} else {
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(opline->op1.zv), opline->op1.zv + 1, 0 TSRMLS_CC);
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op1)), EX_CONSTANT(opline->op1) + 1, 0 TSRMLS_CC);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op1.zv));
|
||||
zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op1)));
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), ce);
|
||||
}
|
||||
} else {
|
||||
ce = Z_CE_P(EX_VAR(opline->op1.var));
|
||||
if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce)) != NULL) {
|
||||
if ((value = CACHED_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce)) != NULL) {
|
||||
ZVAL_DEREF(value);
|
||||
ZVAL_DUP(EX_VAR(opline->result.var), value);
|
||||
ZEND_VM_C_GOTO(constant_fetch_end);
|
||||
}
|
||||
}
|
||||
|
||||
if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(opline->op2.zv))) != NULL)) {
|
||||
if (EXPECTED((value = zend_hash_find(&ce->constants_table, Z_STR_P(EX_CONSTANT(opline->op2)))) != NULL)) {
|
||||
ZVAL_DEREF(value);
|
||||
if (Z_CONSTANT_P(value)) {
|
||||
EG(scope) = ce;
|
||||
|
@ -4023,16 +4023,16 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
|
|||
EG(scope) = EX(func)->op_array.scope;
|
||||
}
|
||||
if (OP1_TYPE == IS_CONST) {
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), value);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), value);
|
||||
} else {
|
||||
CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce, value);
|
||||
CACHE_POLYMORPHIC_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce, value);
|
||||
}
|
||||
ZVAL_DUP(EX_VAR(opline->result.var), value);
|
||||
} else if (Z_STRLEN_P(opline->op2.zv) == sizeof("class")-1 && memcmp(Z_STRVAL_P(opline->op2.zv), "class", sizeof("class") - 1) == 0) {
|
||||
} else if (Z_STRLEN_P(EX_CONSTANT(opline->op2)) == sizeof("class")-1 && memcmp(Z_STRVAL_P(EX_CONSTANT(opline->op2)), "class", sizeof("class") - 1) == 0) {
|
||||
/* "class" is assigned as a case-sensitive keyword from zend_do_resolve_class_name */
|
||||
ZVAL_STR_COPY(EX_VAR(opline->result.var), ce->name);
|
||||
} else {
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(opline->op2.zv));
|
||||
zend_error_noreturn(E_ERROR, "Undefined class constant '%s'", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
}
|
||||
}
|
||||
ZEND_VM_C_LABEL(constant_fetch_end):
|
||||
|
@ -4432,10 +4432,10 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
|
|||
zend_class_entry *ce;
|
||||
|
||||
if (OP2_TYPE == IS_CONST) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0 TSRMLS_CC);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
if (OP1_TYPE != IS_CONST && Z_TYPE(tmp) != IS_UNDEF) {
|
||||
zend_string_release(Z_STR(tmp));
|
||||
|
@ -4444,14 +4444,14 @@ ZEND_VM_HANDLER(74, ZEND_UNSET_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
|
|||
HANDLE_EXCEPTION();
|
||||
}
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(opline->op2.zv));
|
||||
zend_error_noreturn(E_ERROR, "Class '%s' not found", Z_STRVAL_P(EX_CONSTANT(opline->op2)));
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
|
||||
}
|
||||
} else {
|
||||
ce = Z_CE_P(EX_VAR(opline->op2.var));
|
||||
}
|
||||
zend_std_unset_static_property(ce, Z_STR_P(varname), ((OP1_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
|
||||
zend_std_unset_static_property(ce, Z_STR_P(varname), ((OP1_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
|
||||
} else {
|
||||
target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
|
||||
zend_hash_del_ind(target_symbol_table, Z_STR_P(varname));
|
||||
|
@ -4579,7 +4579,7 @@ ZEND_VM_HANDLER(76, ZEND_UNSET_OBJ, VAR|UNUSED|CV, CONST|TMPVAR|CV)
|
|||
}
|
||||
}
|
||||
if (Z_OBJ_HT_P(container)->unset_property) {
|
||||
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
|
||||
Z_OBJ_HT_P(container)->unset_property(container, offset, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
|
||||
} else {
|
||||
zend_error(E_NOTICE, "Trying to unset property of non-object");
|
||||
}
|
||||
|
@ -4744,7 +4744,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
|
|||
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_FETCH_BYREF) {
|
||||
FREE_OP1_VAR_PTR();
|
||||
}
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
p = fe_ht->arData + pos;
|
||||
if (Z_TYPE(p->val) == IS_UNDEF ||
|
||||
|
@ -4775,7 +4775,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
|
|||
FREE_OP1_VAR_PTR();
|
||||
}
|
||||
if (is_empty) {
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
} else {
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
|
@ -4810,7 +4810,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
|||
pos = ptr->pos;
|
||||
if (UNEXPECTED(pos == INVALID_IDX)) {
|
||||
/* reached end of iteration */
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
} else if (UNEXPECTED(ptr->ht != fe_ht)) {
|
||||
ptr->ht = fe_ht;
|
||||
pos = 0;
|
||||
|
@ -4833,7 +4833,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
|||
while (1) {
|
||||
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
|
||||
/* reached end of iteration */
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
p = fe_ht->arData + pos;
|
||||
value = &p->val;
|
||||
|
@ -4891,7 +4891,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
|||
pos = ptr->pos;
|
||||
if (pos == INVALID_IDX) {
|
||||
/* reached end of iteration */
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
} else if (UNEXPECTED(ptr->ht != fe_ht)) {
|
||||
ptr->ht = fe_ht;
|
||||
pos = 0;
|
||||
|
@ -4914,7 +4914,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
|||
while (1) {
|
||||
if (UNEXPECTED(pos >= fe_ht->nNumUsed)) {
|
||||
/* reached end of iteration */
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
|
||||
p = fe_ht->arData + pos;
|
||||
|
@ -4994,7 +4994,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
|||
zval_ptr_dtor(array_ref);
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
value = iter->funcs->get_current_data(iter TSRMLS_CC);
|
||||
if (UNEXPECTED(EG(exception) != NULL)) {
|
||||
|
@ -5003,7 +5003,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
|||
}
|
||||
if (!value) {
|
||||
/* failure in get_current_data */
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
if (opline->extended_value & ZEND_FE_FETCH_BYREF) {
|
||||
ZVAL_MAKE_REF(value);
|
||||
|
@ -5028,7 +5028,7 @@ ZEND_VM_HANDLER(78, ZEND_FE_FETCH, VAR, ANY)
|
|||
}
|
||||
} else {
|
||||
zend_error(E_WARNING, "Invalid argument supplied for foreach()");
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5066,20 +5066,20 @@ ZEND_VM_HANDLER(114, ZEND_ISSET_ISEMPTY_VAR, CONST|TMPVAR|CV, UNUSED|CONST|VAR)
|
|||
zend_class_entry *ce;
|
||||
|
||||
if (OP2_TYPE == IS_CONST) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, 0 TSRMLS_CC);
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, 0 TSRMLS_CC);
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
|
||||
}
|
||||
} else {
|
||||
ce = Z_CE_P(EX_VAR(opline->op2.var));
|
||||
}
|
||||
value = zend_std_get_static_property(ce, Z_STR_P(varname), 1, ((OP1_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
|
||||
value = zend_std_get_static_property(ce, Z_STR_P(varname), 1, ((OP1_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(varname)) : NULL) TSRMLS_CC);
|
||||
} else {
|
||||
HashTable *target_symbol_table = zend_get_target_symbol_table(execute_data, opline->extended_value & ZEND_FETCH_TYPE_MASK TSRMLS_CC);
|
||||
value = zend_hash_find_ind(target_symbol_table, Z_STR_P(varname));
|
||||
|
@ -5249,7 +5249,7 @@ ZEND_VM_HANDLER(148, ZEND_ISSET_ISEMPTY_PROP_OBJ, CONST|TMPVAR|UNUSED|CV, CONST|
|
|||
ZEND_VM_C_LABEL(isset_no_object):
|
||||
result = ((opline->extended_value & ZEND_ISSET) == 0);
|
||||
} else {
|
||||
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX(run_time_cache) + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
|
||||
result = Z_OBJ_HT_P(container)->has_property(container, offset, (opline->extended_value & ZEND_ISSET) == 0, ((OP2_TYPE == IS_CONST) ? (EX_RUN_TIME_CACHE() + Z_CACHE_SLOT_P(offset)) : NULL) TSRMLS_CC);
|
||||
if ((opline->extended_value & ZEND_ISSET) == 0) {
|
||||
result = !result;
|
||||
}
|
||||
|
@ -5365,7 +5365,7 @@ ZEND_VM_HANDLER(152, ZEND_JMP_SET, CONST|TMP|VAR|CV, ANY)
|
|||
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
|
||||
FREE_OP1();
|
||||
}
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
|
||||
FREE_OP1();
|
||||
|
@ -5400,7 +5400,7 @@ ZEND_VM_HANDLER(169, ZEND_COALESCE, CONST|TMP|VAR|CV, ANY)
|
|||
if (Z_OPT_REFCOUNTED_P(value)) Z_ADDREF_P(value);
|
||||
FREE_OP1();
|
||||
}
|
||||
ZEND_VM_JMP(opline->op2.jmp_addr);
|
||||
ZEND_VM_JMP(OP_JMP_ADDR(opline, opline->op2));
|
||||
}
|
||||
|
||||
FREE_OP1();
|
||||
|
@ -5489,8 +5489,8 @@ ZEND_VM_HANDLER(145, ZEND_DECLARE_INHERITED_CLASS_DELAYED, ANY, ANY)
|
|||
zval *zce, *orig_zce;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if ((zce = zend_hash_find(EG(class_table), Z_STR_P(opline->op2.zv))) == NULL ||
|
||||
((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(opline->op1.zv))) != NULL &&
|
||||
if ((zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op2)))) == NULL ||
|
||||
((orig_zce = zend_hash_find(EG(class_table), Z_STR_P(EX_CONSTANT(opline->op1)))) != NULL &&
|
||||
Z_CE_P(zce) != Z_CE_P(orig_zce))) {
|
||||
do_bind_inherited_class(&EX(func)->op_array, opline, EG(class_table), Z_CE_P(EX_VAR(opline->extended_value)), 0 TSRMLS_CC);
|
||||
}
|
||||
|
@ -5538,17 +5538,17 @@ ZEND_VM_C_LABEL(try_instanceof):
|
|||
zend_class_entry *ce;
|
||||
|
||||
if (OP2_TYPE == IS_CONST) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
|
||||
ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD TSRMLS_CC);
|
||||
if (UNEXPECTED(ce == NULL)) {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
FREE_OP1();
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), ce);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), ce);
|
||||
}
|
||||
} else {
|
||||
ce = Z_CE_P(EX_VAR(opline->op2.var));
|
||||
|
@ -5583,15 +5583,15 @@ ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST)
|
|||
zend_class_entry *iface;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
iface = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
iface = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
iface = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv), opline->op2.zv + 1, ZEND_FETCH_CLASS_INTERFACE TSRMLS_CC);
|
||||
iface = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)), EX_CONSTANT(opline->op2) + 1, ZEND_FETCH_CLASS_INTERFACE TSRMLS_CC);
|
||||
if (UNEXPECTED(iface == NULL)) {
|
||||
CHECK_EXCEPTION();
|
||||
ZEND_VM_NEXT_OPCODE();
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), iface);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), iface);
|
||||
}
|
||||
|
||||
if (UNEXPECTED((iface->ce_flags & ZEND_ACC_INTERFACE) == 0)) {
|
||||
|
@ -5610,11 +5610,11 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY)
|
|||
zend_class_entry *trait;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
|
||||
trait = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)))) {
|
||||
trait = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)));
|
||||
} else {
|
||||
trait = zend_fetch_class_by_name(Z_STR_P(opline->op2.zv),
|
||||
opline->op2.zv + 1,
|
||||
trait = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(opline->op2)),
|
||||
EX_CONSTANT(opline->op2) + 1,
|
||||
ZEND_FETCH_CLASS_TRAIT TSRMLS_CC);
|
||||
if (UNEXPECTED(trait == NULL)) {
|
||||
CHECK_EXCEPTION();
|
||||
|
@ -5623,7 +5623,7 @@ ZEND_VM_HANDLER(154, ZEND_ADD_TRAIT, ANY, ANY)
|
|||
if (!((trait->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT)) {
|
||||
zend_error_noreturn(E_ERROR, "%s cannot use %s - it is not a trait", ce->name->val, trait->name->val);
|
||||
}
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op2.zv), trait);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op2)), trait);
|
||||
}
|
||||
|
||||
zend_do_implement_trait(ce, trait TSRMLS_CC);
|
||||
|
@ -5832,7 +5832,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
|
|||
|
||||
SAVE_OPLINE();
|
||||
|
||||
if (UNEXPECTED((zfunc = zend_hash_find(EG(function_table), Z_STR_P(opline->op1.zv))) == NULL) ||
|
||||
if (UNEXPECTED((zfunc = zend_hash_find(EG(function_table), Z_STR_P(EX_CONSTANT(opline->op1)))) == NULL) ||
|
||||
UNEXPECTED(Z_FUNC_P(zfunc)->type != ZEND_USER_FUNCTION)) {
|
||||
zend_error_noreturn(E_ERROR, "Base lambda function for closure not found");
|
||||
}
|
||||
|
@ -6029,7 +6029,7 @@ ZEND_VM_HANDLER(162, ZEND_FAST_CALL, ANY, ANY)
|
|||
Z_OBJ_P(fast_call) = NULL;
|
||||
/* set return address */
|
||||
fast_call->u2.lineno = opline - EX(func)->op_array.opcodes;
|
||||
ZEND_VM_SET_OPCODE(opline->op1.jmp_addr);
|
||||
ZEND_VM_SET_OPCODE(OP_JMP_ADDR(opline, opline->op1));
|
||||
ZEND_VM_CONTINUE();
|
||||
}
|
||||
|
||||
|
@ -6240,12 +6240,12 @@ ZEND_VM_HANDLER(122, ZEND_DEFINED, CONST, ANY)
|
|||
zend_constant *c;
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
|
||||
if (CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)))) {
|
||||
ZVAL_TRUE(EX_VAR(opline->result.var));
|
||||
} else if ((c = zend_quick_get_constant(opline->op1.zv, 0 TSRMLS_CC)) == NULL) {
|
||||
} else if ((c = zend_quick_get_constant(EX_CONSTANT(opline->op1), 0 TSRMLS_CC)) == NULL) {
|
||||
ZVAL_FALSE(EX_VAR(opline->result.var));
|
||||
} else {
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(opline->op1.zv), c);
|
||||
CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(opline->op1)), c);
|
||||
ZVAL_TRUE(EX_VAR(opline->result.var));
|
||||
}
|
||||
CHECK_EXCEPTION();
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -137,7 +137,7 @@ $op1_get_zval_ptr = array(
|
|||
"ANY" => "get_zval_ptr(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" => "opline->op1.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op1)",
|
||||
"UNUSED" => "NULL",
|
||||
"CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
|
||||
"TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)",
|
||||
|
@ -147,7 +147,7 @@ $op2_get_zval_ptr = array(
|
|||
"ANY" => "get_zval_ptr(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" => "opline->op2.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op2)",
|
||||
"UNUSED" => "NULL",
|
||||
"CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
|
||||
"TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)",
|
||||
|
@ -177,7 +177,7 @@ $op1_get_zval_ptr_deref = array(
|
|||
"ANY" => "get_zval_ptr_deref(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_deref(opline->op1.var, execute_data, &free_op1)",
|
||||
"CONST" => "opline->op1.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op1)",
|
||||
"UNUSED" => "NULL",
|
||||
"CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var TSRMLS_CC)",
|
||||
"TMPVAR" => "???",
|
||||
|
@ -187,7 +187,7 @@ $op2_get_zval_ptr_deref = array(
|
|||
"ANY" => "get_zval_ptr_deref(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_deref(opline->op2.var, execute_data, &free_op2)",
|
||||
"CONST" => "opline->op2.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op2)",
|
||||
"UNUSED" => "NULL",
|
||||
"CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var TSRMLS_CC)",
|
||||
"TMPVAR" => "???",
|
||||
|
@ -217,7 +217,7 @@ $op1_get_obj_zval_ptr = array(
|
|||
"ANY" => "get_obj_zval_ptr(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" => "opline->op1.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op1)",
|
||||
"UNUSED" => "_get_obj_zval_ptr_unused(execute_data)",
|
||||
"CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op1.var TSRMLS_CC)",
|
||||
"TMPVAR" => "_get_zval_ptr_var(opline->op1.var, execute_data, &free_op1)",
|
||||
|
@ -227,7 +227,7 @@ $op2_get_obj_zval_ptr = array(
|
|||
"ANY" => "get_obj_zval_ptr(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" => "opline->op2.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op2)",
|
||||
"UNUSED" => "_get_obj_zval_ptr_unused(execute_data)",
|
||||
"CV" => "_get_zval_ptr_cv_\\1(execute_data, opline->op2.var TSRMLS_CC)",
|
||||
"TMPVAR" => "_get_zval_ptr_var(opline->op2.var, execute_data, &free_op2)",
|
||||
|
@ -237,7 +237,7 @@ $op1_get_obj_zval_ptr_deref = array(
|
|||
"ANY" => "get_obj_zval_ptr(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_deref(opline->op1.var, execute_data, &free_op1)",
|
||||
"CONST" => "opline->op1.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op1)",
|
||||
"UNUSED" => "_get_obj_zval_ptr_unused(execute_data)",
|
||||
"CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op1.var TSRMLS_CC)",
|
||||
"TMPVAR" => "???",
|
||||
|
@ -247,7 +247,7 @@ $op2_get_obj_zval_ptr_deref = array(
|
|||
"ANY" => "get_obj_zval_ptr(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_deref(opline->op2.var, execute_data, &free_op2)",
|
||||
"CONST" => "opline->op2.zv",
|
||||
"CONST" => "EX_CONSTANT(opline->op2)",
|
||||
"UNUSED" => "_get_obj_zval_ptr_unused(execute_data)",
|
||||
"CV" => "_get_zval_ptr_cv_deref_\\1(execute_data, opline->op2.var TSRMLS_CC)",
|
||||
"TMPVAR" => "???",
|
||||
|
|
|
@ -80,11 +80,13 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS
|
|||
|
||||
if (fcall->opcode == ZEND_INIT_FCALL_BY_NAME) {
|
||||
fcall->opcode = ZEND_INIT_FCALL;
|
||||
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
|
||||
Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]);
|
||||
literal_dtor(&ZEND_OP2_LITERAL(fcall));
|
||||
fcall->op2.constant = fcall->op2.constant + 1;
|
||||
} else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
|
||||
fcall->opcode = ZEND_INIT_FCALL;
|
||||
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
|
||||
Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]);
|
||||
literal_dtor(&op_array->literals[fcall->op2.constant]);
|
||||
literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
|
||||
|
@ -92,17 +94,6 @@ void optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRMLS
|
|||
} else {
|
||||
ZEND_ASSERT(0);
|
||||
}
|
||||
} else if (call_stack[call].opline &&
|
||||
call_stack[call].opline->opcode == ZEND_INIT_FCALL_BY_NAME &&
|
||||
call_stack[call].opline->extended_value == 0 &&
|
||||
ZEND_OP2_IS_CONST_STRING(call_stack[call].opline)) {
|
||||
|
||||
zend_op *fcall = call_stack[call].opline;
|
||||
|
||||
fcall->opcode = ZEND_INIT_FCALL;
|
||||
Z_CACHE_SLOT(op_array->literals[fcall->op2.constant + 1]) = Z_CACHE_SLOT(op_array->literals[fcall->op2.constant]);
|
||||
literal_dtor(&ZEND_OP2_LITERAL(fcall));
|
||||
fcall->op2.constant = fcall->op2.constant + 1;
|
||||
}
|
||||
call_stack[call].func = NULL;
|
||||
call_stack[call].opline = NULL;
|
||||
|
|
|
@ -401,7 +401,7 @@ void zend_optimizer_pass1(zend_op_array *op_array, zend_optimizer_ctx *ctx TSRML
|
|||
opline->result_type = IS_UNUSED;
|
||||
opline->op1.constant = send1_opline->op1.constant;
|
||||
opline->op2.constant = send2_opline->op1.constant;
|
||||
opline->result.zv = NULL;
|
||||
opline->result.num = 0;
|
||||
|
||||
literal_dtor(&ZEND_OP2_LITERAL(init_opline));
|
||||
MAKE_NOP(init_opline);
|
||||
|
|
|
@ -428,20 +428,20 @@ static void zend_accel_optimize(zend_op_array *op_array,
|
|||
end = opline + op_array->last;
|
||||
while (opline < end) {
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
opline->op1.constant = opline->op1.zv - op_array->literals;
|
||||
ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline->op1);
|
||||
}
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
opline->op2.constant = opline->op2.zv - op_array->literals;
|
||||
ZEND_PASS_TWO_UNDO_CONSTANT(op_array, opline->op2);
|
||||
}
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMP:
|
||||
case ZEND_GOTO:
|
||||
case ZEND_FAST_CALL:
|
||||
ZEND_OP1(opline).opline_num = ZEND_OP1(opline).jmp_addr - op_array->opcodes;
|
||||
ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, ZEND_OP1(opline));
|
||||
break;
|
||||
case ZEND_JMPZNZ:
|
||||
/* relative offset into absolute index */
|
||||
opline->extended_value = (zend_op*)(((char*)opline) + opline->extended_value) - op_array->opcodes;
|
||||
opline->extended_value = ZEND_OFFSET_TO_OPLINE_NUM(op_array, opline, opline->extended_value);
|
||||
/* break omitted intentionally */
|
||||
case ZEND_JMPZ:
|
||||
case ZEND_JMPNZ:
|
||||
|
@ -452,7 +452,7 @@ static void zend_accel_optimize(zend_op_array *op_array,
|
|||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET:
|
||||
case ZEND_FE_FETCH:
|
||||
ZEND_OP2(opline).opline_num = ZEND_OP2(opline).jmp_addr - op_array->opcodes;
|
||||
ZEND_PASS_TWO_UNDO_JMP_TARGET(op_array, opline, ZEND_OP2(opline));
|
||||
break;
|
||||
}
|
||||
opline++;
|
||||
|
@ -466,20 +466,20 @@ static void zend_accel_optimize(zend_op_array *op_array,
|
|||
end = opline + op_array->last;
|
||||
while (opline < end) {
|
||||
if (opline->op1_type == IS_CONST) {
|
||||
opline->op1.zv = &op_array->literals[opline->op1.constant];
|
||||
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
|
||||
}
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
opline->op2.zv = &op_array->literals[opline->op2.constant];
|
||||
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
|
||||
}
|
||||
switch (opline->opcode) {
|
||||
case ZEND_JMP:
|
||||
case ZEND_GOTO:
|
||||
case ZEND_FAST_CALL:
|
||||
ZEND_OP1(opline).jmp_addr = &op_array->opcodes[ZEND_OP1(opline).opline_num];
|
||||
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, ZEND_OP1(opline));
|
||||
break;
|
||||
case ZEND_JMPZNZ:
|
||||
/* absolute index to relative offset */
|
||||
opline->extended_value = (char*)(op_array->opcodes + opline->extended_value) - (char*)opline;
|
||||
opline->extended_value = ZEND_OPLINE_NUM_TO_OFFSET(op_array, opline, opline->extended_value);
|
||||
/* break omitted intentionally */
|
||||
case ZEND_JMPZ:
|
||||
case ZEND_JMPNZ:
|
||||
|
@ -490,7 +490,7 @@ static void zend_accel_optimize(zend_op_array *op_array,
|
|||
case ZEND_NEW:
|
||||
case ZEND_FE_RESET:
|
||||
case ZEND_FE_FETCH:
|
||||
ZEND_OP2(opline).jmp_addr = &op_array->opcodes[ZEND_OP2(opline).opline_num];
|
||||
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, ZEND_OP2(opline));
|
||||
break;
|
||||
}
|
||||
ZEND_VM_SET_OPCODE_HANDLER(opline);
|
||||
|
|
|
@ -345,18 +345,21 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
|||
op_array->opcodes = persist_ptr;
|
||||
} else {
|
||||
zend_op *new_opcodes = zend_accel_memdup(op_array->opcodes, sizeof(zend_op) * op_array->last);
|
||||
#if ZEND_USE_ABS_CONST_ADDR || ZEND_USE_ABS_JMP_ADDR
|
||||
zend_op *opline = new_opcodes;
|
||||
zend_op *end = new_opcodes + op_array->last;
|
||||
int offset = 0;
|
||||
|
||||
for (; opline < end ; opline++, offset++) {
|
||||
# if ZEND_USE_ABS_CONST_ADDR
|
||||
if (ZEND_OP1_TYPE(opline) == IS_CONST) {
|
||||
opline->op1.zv = (zval*)((char*)opline->op1.zv + ((char*)op_array->literals - (char*)orig_literals));
|
||||
}
|
||||
if (ZEND_OP2_TYPE(opline) == IS_CONST) {
|
||||
opline->op2.zv = (zval*)((char*)opline->op2.zv + ((char*)op_array->literals - (char*)orig_literals));
|
||||
}
|
||||
|
||||
# endif
|
||||
# if ZEND_USE_ABS_JMP_ADDR
|
||||
if (ZEND_DONE_PASS_TWO(op_array)) {
|
||||
/* fix jumps to point to new array */
|
||||
switch (opline->opcode) {
|
||||
|
@ -381,7 +384,9 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
|||
break;
|
||||
}
|
||||
}
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
efree(op_array->opcodes);
|
||||
op_array->opcodes = new_opcodes;
|
||||
|
|
|
@ -722,7 +722,7 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
|
|||
zend_class_entry *old_scope;
|
||||
|
||||
string_write(str, " = ", sizeof(" = ")-1);
|
||||
ZVAL_DUP(&zv, precv->op2.zv);
|
||||
ZVAL_DUP(&zv, RT_CONSTANT(&fptr->op_array, precv->op2));
|
||||
old_scope = EG(scope);
|
||||
EG(scope) = fptr->common.scope;
|
||||
zval_update_constant_ex(&zv, 1, NULL TSRMLS_CC);
|
||||
|
@ -2618,7 +2618,7 @@ ZEND_METHOD(reflection_parameter, getDefaultValue)
|
|||
return;
|
||||
}
|
||||
|
||||
ZVAL_COPY_VALUE(return_value, precv->op2.zv);
|
||||
ZVAL_COPY_VALUE(return_value, RT_CONSTANT(¶m->fptr->op_array, precv->op2));
|
||||
if (Z_CONSTANT_P(return_value)) {
|
||||
zend_class_entry *old_scope = EG(scope);
|
||||
|
||||
|
@ -2648,7 +2648,7 @@ ZEND_METHOD(reflection_parameter, isDefaultValueConstant)
|
|||
}
|
||||
|
||||
precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
|
||||
if (precv && Z_TYPE_P(precv->op2.zv) == IS_CONSTANT) {
|
||||
if (precv && Z_TYPE_P(RT_CONSTANT(¶m->fptr->op_array, precv->op2)) == IS_CONSTANT) {
|
||||
RETURN_TRUE;
|
||||
}
|
||||
|
||||
|
@ -2673,8 +2673,8 @@ ZEND_METHOD(reflection_parameter, getDefaultValueConstantName)
|
|||
}
|
||||
|
||||
precv = _reflection_param_get_default_precv(INTERNAL_FUNCTION_PARAM_PASSTHRU, param);
|
||||
if (precv && Z_TYPE_P(precv->op2.zv) == IS_CONSTANT) {
|
||||
RETURN_STR(zend_string_copy(Z_STR_P(precv->op2.zv)));
|
||||
if (precv && Z_TYPE_P(RT_CONSTANT(¶m->fptr->op_array, precv->op2)) == IS_CONSTANT) {
|
||||
RETURN_STR(zend_string_copy(Z_STR_P(RT_CONSTANT(¶m->fptr->op_array, precv->op2))));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
|
|
@ -2348,99 +2348,104 @@ PHP_FUNCTION(array_slice)
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC) /* {{{ */
|
||||
PHPAPI int php_array_merge_recursive(HashTable *dest, HashTable *src TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *src_entry, *dest_entry;
|
||||
zend_string *string_key;
|
||||
|
||||
if (recursive) {
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) {
|
||||
if (string_key) {
|
||||
if ((dest_entry = zend_hash_find(dest, string_key)) != NULL) {
|
||||
zval *src_zval = src_entry;
|
||||
zval *dest_zval = dest_entry;
|
||||
HashTable *thash;
|
||||
zval tmp;
|
||||
int ret;
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) {
|
||||
if (string_key) {
|
||||
if ((dest_entry = zend_hash_find(dest, string_key)) != NULL) {
|
||||
zval *src_zval = src_entry;
|
||||
zval *dest_zval = dest_entry;
|
||||
HashTable *thash;
|
||||
zval tmp;
|
||||
int ret;
|
||||
|
||||
ZVAL_DEREF(src_zval);
|
||||
ZVAL_DEREF(dest_zval);
|
||||
thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL;
|
||||
if ((thash && thash->u.v.nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
|
||||
ZVAL_DEREF(src_zval);
|
||||
ZVAL_DEREF(dest_zval);
|
||||
thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL;
|
||||
if ((thash && thash->u.v.nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) {
|
||||
php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Z_ISREF_P(dest_entry)) {
|
||||
if (Z_REFCOUNT_P(dest_entry) == 1) {
|
||||
ZVAL_UNREF(dest_entry);
|
||||
} else {
|
||||
Z_DELREF_P(dest_entry);
|
||||
ZVAL_DUP(dest_entry, dest_zval);
|
||||
}
|
||||
dest_zval = dest_entry;
|
||||
} else {
|
||||
SEPARATE_ZVAL(dest_zval);
|
||||
}
|
||||
if (Z_TYPE_P(dest_zval) == IS_NULL) {
|
||||
convert_to_array_ex(dest_zval);
|
||||
add_next_index_null(dest_zval);
|
||||
} else {
|
||||
convert_to_array_ex(dest_zval);
|
||||
}
|
||||
ZVAL_UNDEF(&tmp);
|
||||
if (Z_TYPE_P(src_zval) == IS_OBJECT) {
|
||||
ZVAL_DUP(&tmp, src_zval);
|
||||
convert_to_array(&tmp);
|
||||
src_zval = &tmp;
|
||||
}
|
||||
if (Z_TYPE_P(src_zval) == IS_ARRAY) {
|
||||
if (thash && ZEND_HASH_APPLY_PROTECTION(thash)) {
|
||||
thash->u.v.nApplyCount++;
|
||||
}
|
||||
ret = php_array_merge_recursive(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval) TSRMLS_CC);
|
||||
if (thash && ZEND_HASH_APPLY_PROTECTION(thash)) {
|
||||
thash->u.v.nApplyCount--;
|
||||
}
|
||||
if (!ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (Z_ISREF_P(dest_entry)) {
|
||||
if (Z_REFCOUNT_P(dest_entry) == 1) {
|
||||
ZVAL_UNREF(dest_entry);
|
||||
} else {
|
||||
Z_DELREF_P(dest_entry);
|
||||
ZVAL_DUP(dest_entry, dest_zval);
|
||||
}
|
||||
dest_zval = dest_entry;
|
||||
} else {
|
||||
SEPARATE_ZVAL(dest_zval);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(dest_zval) == IS_NULL) {
|
||||
convert_to_array_ex(dest_zval);
|
||||
add_next_index_null(dest_zval);
|
||||
} else {
|
||||
convert_to_array_ex(dest_zval);
|
||||
}
|
||||
ZVAL_UNDEF(&tmp);
|
||||
if (Z_TYPE_P(src_zval) == IS_OBJECT) {
|
||||
ZVAL_DUP(&tmp, src_zval);
|
||||
convert_to_array(&tmp);
|
||||
src_zval = &tmp;
|
||||
}
|
||||
if (Z_TYPE_P(src_zval) == IS_ARRAY) {
|
||||
if (thash && ZEND_HASH_APPLY_PROTECTION(thash)) {
|
||||
thash->u.v.nApplyCount++;
|
||||
}
|
||||
ret = php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), 1 TSRMLS_CC);
|
||||
if (thash && ZEND_HASH_APPLY_PROTECTION(thash)) {
|
||||
thash->u.v.nApplyCount--;
|
||||
}
|
||||
if (!ret) {
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval);
|
||||
}
|
||||
zval_ptr_dtor(&tmp);
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_add_new(dest, string_key, src_entry);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval);
|
||||
}
|
||||
zval_ptr_dtor(&tmp);
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_next_index_insert_new(dest, src_entry);
|
||||
zend_hash_add_new(dest, string_key, src_entry);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} else {
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) {
|
||||
if (string_key) {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_update(dest, string_key, src_entry);
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_next_index_insert_new(dest, src_entry);
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
zend_hash_next_index_insert_new(dest, src_entry);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
PHPAPI int php_array_merge(HashTable *dest, HashTable *src TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zval *src_entry;
|
||||
zend_string *string_key;
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) {
|
||||
if (string_key) {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_update(dest, string_key, src_entry);
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_next_index_insert_new(dest, src_entry);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
return 1;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -2521,6 +2526,7 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC
|
|||
static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int recursive, int replace) /* {{{ */
|
||||
{
|
||||
zval *args = NULL;
|
||||
zval *arg;
|
||||
int argc, i, init_size = 0;
|
||||
|
||||
#ifndef FAST_ZPP
|
||||
|
@ -2551,16 +2557,80 @@ static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int
|
|||
|
||||
array_init_size(return_value, init_size);
|
||||
|
||||
for (i = 0; i < argc; i++) {
|
||||
zval *arg = args + i;
|
||||
if (replace) {
|
||||
zend_string *string_key;
|
||||
zval *src_entry;
|
||||
zend_ulong idx;
|
||||
HashTable *src, *dest;
|
||||
|
||||
/* copy first array */
|
||||
arg = args;
|
||||
ZVAL_DEREF(arg);
|
||||
if (!replace) {
|
||||
php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_P(arg), recursive TSRMLS_CC);
|
||||
} else if (recursive && i > 0) { /* First array will be copied directly instead */
|
||||
php_array_replace_recursive(Z_ARRVAL_P(return_value), Z_ARRVAL_P(arg) TSRMLS_CC);
|
||||
src = Z_ARRVAL_P(arg);
|
||||
dest = Z_ARRVAL_P(return_value);
|
||||
ZEND_HASH_FOREACH_KEY_VAL(src, idx, string_key, src_entry) {
|
||||
if (string_key) {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_add_new(dest, string_key, src_entry);
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_index_add_new(dest, idx, src_entry);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (recursive) {
|
||||
for (i = 1; i < argc; i++) {
|
||||
arg = args + i;
|
||||
ZVAL_DEREF(arg);
|
||||
php_array_replace_recursive(Z_ARRVAL_P(return_value), Z_ARRVAL_P(arg) TSRMLS_CC);
|
||||
}
|
||||
} else {
|
||||
zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_P(arg), zval_add_ref, 1);
|
||||
for (i = 1; i < argc; i++) {
|
||||
arg = args + i;
|
||||
ZVAL_DEREF(arg);
|
||||
zend_hash_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_P(arg), zval_add_ref, 1);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
zend_string *string_key;
|
||||
zval *src_entry;
|
||||
HashTable *src, *dest;
|
||||
|
||||
/* copy first array */
|
||||
arg = args;
|
||||
ZVAL_DEREF(arg);
|
||||
src = Z_ARRVAL_P(arg);
|
||||
dest = Z_ARRVAL_P(return_value);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(src, string_key, src_entry) {
|
||||
if (string_key) {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_add_new(dest, string_key, src_entry);
|
||||
} else {
|
||||
if (Z_REFCOUNTED_P(src_entry)) {
|
||||
Z_ADDREF_P(src_entry);
|
||||
}
|
||||
zend_hash_next_index_insert_new(dest, src_entry);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (recursive) {
|
||||
for (i = 1; i < argc; i++) {
|
||||
arg = args + i;
|
||||
ZVAL_DEREF(arg);
|
||||
php_array_merge_recursive(Z_ARRVAL_P(return_value), Z_ARRVAL_P(arg) TSRMLS_CC);
|
||||
}
|
||||
} else {
|
||||
for (i = 1; i < argc; i++) {
|
||||
arg = args + i;
|
||||
ZVAL_DEREF(arg);
|
||||
php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_P(arg) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,8 @@ PHP_FUNCTION(array_chunk);
|
|||
PHP_FUNCTION(array_combine);
|
||||
|
||||
PHPAPI HashTable* php_splice(HashTable *, int, int, zval *, int, HashTable *);
|
||||
PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS_DC);
|
||||
PHPAPI int php_array_merge(HashTable *dest, HashTable *src TSRMLS_DC);
|
||||
PHPAPI int php_array_merge_recursive(HashTable *dest, HashTable *src TSRMLS_DC);
|
||||
PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC);
|
||||
PHPAPI int php_multisort_compare(const void *a, const void *b TSRMLS_DC);
|
||||
PHPAPI zend_long php_count_recursive(zval *array, zend_long mode TSRMLS_DC);
|
||||
|
|
|
@ -64,7 +64,7 @@ static inline char *phpdbg_decode_op(zend_op_array *ops, znode_op *op, uint32_t
|
|||
} break;
|
||||
|
||||
case IS_CONST:
|
||||
asprintf(&decode, "C%u", phpdbg_decode_literal(ops, op->zv TSRMLS_CC));
|
||||
asprintf(&decode, "C%u", phpdbg_decode_literal(ops, RT_CONSTANT(ops, *op) TSRMLS_CC));
|
||||
break;
|
||||
|
||||
case IS_UNUSED:
|
||||
|
@ -86,7 +86,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM
|
|||
#ifdef ZEND_FAST_CALL
|
||||
case ZEND_FAST_CALL:
|
||||
#endif
|
||||
asprintf(&decode[1], "J%ld", op->op1.jmp_addr - ops->opcodes);
|
||||
asprintf(&decode[1], "J%ld", OP_JMP_ADDR(op, op->op1) - ops->opcodes);
|
||||
goto format;
|
||||
|
||||
case ZEND_JMPZNZ:
|
||||
|
@ -103,7 +103,7 @@ char *phpdbg_decode_opline(zend_op_array *ops, zend_op *op, HashTable *vars TSRM
|
|||
case ZEND_JMP_SET:
|
||||
#endif
|
||||
decode[1] = phpdbg_decode_op(ops, &op->op1, op->op1_type, vars TSRMLS_CC);
|
||||
asprintf(&decode[2], "J%ld", op->op2.jmp_addr - ops->opcodes);
|
||||
asprintf(&decode[2], "J%ld", OP_JMP_ADDR(op, op->op2) - ops->opcodes);
|
||||
goto result;
|
||||
|
||||
case ZEND_RECV_INIT:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue