diff options
Diffstat (limited to 'Zend/zend_execute.h')
-rw-r--r-- | Zend/zend_execute.h | 83 |
1 files changed, 55 insertions, 28 deletions
diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 51a6dc84d5..af329194bc 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -12,14 +12,12 @@ | obtain it through the world-wide-web, please send a note to | | license@zend.com so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Andi Gutmans <andi@zend.com> | - | Zeev Suraski <zeev@zend.com> | - | Dmitry Stogov <dmitry@zend.com> | + | Authors: Andi Gutmans <andi@php.net> | + | Zeev Suraski <zeev@php.net> | + | Dmitry Stogov <dmitry@php.net> | +----------------------------------------------------------------------+ */ -/* $Id$ */ - #ifndef ZEND_EXECUTE_H #define ZEND_EXECUTE_H @@ -85,25 +83,29 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval if (ZEND_CONST_COND(value_type & (IS_VAR|IS_CV), 1) && variable_ptr == value) { if (value_type == IS_VAR && ref) { ZEND_ASSERT(GC_REFCOUNT(ref) > 1); - --GC_REFCOUNT(ref); + GC_DELREF(ref); } return variable_ptr; } garbage = Z_COUNTED_P(variable_ptr); - if (--GC_REFCOUNT(garbage) == 0) { + if (GC_DELREF(garbage) == 0) { ZVAL_COPY_VALUE(variable_ptr, value); - if (value_type & (IS_CONST|IS_CV)) { + if (ZEND_CONST_COND(value_type == IS_CONST, 0)) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { Z_ADDREF_P(variable_ptr); } + } else if (value_type & (IS_CONST|IS_CV)) { + if (Z_OPT_REFCOUNTED_P(variable_ptr)) { + Z_ADDREF_P(variable_ptr); + } } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { Z_ADDREF_P(variable_ptr); } } - zval_dtor_func(garbage); + rc_dtor_func(garbage); return variable_ptr; } else { /* we need to split */ /* optimized version of GC_ZVAL_CHECK_POSSIBLE_ROOT(variable_ptr) */ @@ -115,12 +117,16 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval } while (0); ZVAL_COPY_VALUE(variable_ptr, value); - if (value_type & (IS_CONST|IS_CV)) { + if (ZEND_CONST_COND(value_type == IS_CONST, 0)) { if (UNEXPECTED(Z_OPT_REFCOUNTED_P(variable_ptr))) { Z_ADDREF_P(variable_ptr); } + } else if (value_type & (IS_CONST|IS_CV)) { + if (Z_OPT_REFCOUNTED_P(variable_ptr)) { + Z_ADDREF_P(variable_ptr); + } } else if (ZEND_CONST_COND(value_type == IS_VAR, 1) && UNEXPECTED(ref)) { - if (UNEXPECTED(--GC_REFCOUNT(ref) == 0)) { + if (UNEXPECTED(GC_DELREF(ref) == 0)) { efree_size(ref, sizeof(zend_reference)); } else if (Z_OPT_REFCOUNTED_P(variable_ptr)) { Z_ADDREF_P(variable_ptr); @@ -131,6 +137,7 @@ static zend_always_inline zval* zend_assign_to_variable(zval *variable_ptr, zval ZEND_API int zval_update_constant(zval *pp); ZEND_API int zval_update_constant_ex(zval *pp, zend_class_entry *scope); +ZEND_API int zend_use_undefined_constant(zend_string *name, zend_ast_attr attr, zval *result); /* dedicated Zend executor functions - do not use! */ struct _zend_vm_stack { @@ -161,6 +168,7 @@ struct _zend_vm_stack { #endif ZEND_API void zend_vm_stack_init(void); +ZEND_API void zend_vm_stack_init_ex(size_t page_size); ZEND_API void zend_vm_stack_destroy(void); ZEND_API void* zend_vm_stack_extend(size_t size); @@ -216,20 +224,20 @@ static zend_always_inline zend_execute_data *zend_vm_stack_push_call_frame(uint3 static zend_always_inline void zend_vm_stack_free_extra_args_ex(uint32_t call_info, zend_execute_data *call) { if (UNEXPECTED(call_info & ZEND_CALL_FREE_EXTRA_ARGS)) { - zval *end = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T); - zval *p = end + (ZEND_CALL_NUM_ARGS(call) - call->func->op_array.num_args); + uint32_t count = ZEND_CALL_NUM_ARGS(call) - call->func->op_array.num_args; + zval *p = ZEND_CALL_VAR_NUM(call, call->func->op_array.last_var + call->func->op_array.T); do { - p--; if (Z_REFCOUNTED_P(p)) { zend_refcounted *r = Z_COUNTED_P(p); - if (!--GC_REFCOUNT(r)) { + if (!GC_DELREF(r)) { ZVAL_NULL(p); - zval_dtor_func(r); + rc_dtor_func(r); } else { gc_check_possible_root(r); } } - } while (p != end); + p++; + } while (--count); } } @@ -243,19 +251,18 @@ static zend_always_inline void zend_vm_stack_free_args(zend_execute_data *call) uint32_t num_args = ZEND_CALL_NUM_ARGS(call); if (EXPECTED(num_args > 0)) { - zval *end = ZEND_CALL_ARG(call, 1); - zval *p = end + num_args; + zval *p = ZEND_CALL_ARG(call, 1); do { - p--; if (Z_REFCOUNTED_P(p)) { - if (!Z_DELREF_P(p)) { - zend_refcounted *r = Z_COUNTED_P(p); + zend_refcounted *r = Z_COUNTED_P(p); + if (!GC_DELREF(r)) { ZVAL_NULL(p); - zval_dtor_func(r); + rc_dtor_func(r); } } - } while (p != end); + p++; + } while (--num_args); } } @@ -300,6 +307,9 @@ ZEND_API zend_class_entry *zend_fetch_class(zend_string *class_name, int fetch_t ZEND_API zend_class_entry *zend_fetch_class_by_name(zend_string *class_name, const zval *key, int fetch_type); void zend_verify_abstract_class(zend_class_entry *ce); +ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name); +ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name, size_t len); + ZEND_API void zend_fetch_dimension_const(zval *result, zval *container, zval *dim, int type); ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute_data_ptr, uint32_t var); @@ -318,11 +328,11 @@ ZEND_API user_opcode_handler_t zend_get_user_opcode_handler(zend_uchar opcode); /* former zend_execute_locks.h */ typedef zval* zend_free_op; -ZEND_API zval *zend_get_zval_ptr(int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type); +ZEND_API zval *zend_get_zval_ptr(const zend_op *opline, int op_type, const znode_op *node, const zend_execute_data *execute_data, zend_free_op *should_free, int type); ZEND_API void zend_clean_and_cache_symbol_table(zend_array *symbol_table); -void zend_free_compiled_variables(zend_execute_data *execute_data); -void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num); +ZEND_API void zend_free_compiled_variables(zend_execute_data *execute_data); +ZEND_API void zend_cleanup_unfinished_execution(zend_execute_data *execute_data, uint32_t op_num, uint32_t catch_op_num); ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zval *ret); @@ -362,6 +372,23 @@ ZEND_API int ZEND_FASTCALL zend_do_fcall_overloaded(zend_execute_data *call, zva (slot)[1] = (ptr); \ } while (0) +#define CACHE_SPECIAL (1<<0) + +#define IS_SPECIAL_CACHE_VAL(ptr) \ + (((uintptr_t)(ptr)) & CACHE_SPECIAL) + +#define ENCODE_SPECIAL_CACHE_NUM(num) \ + ((void*)((((uintptr_t)(num)) << 1) | CACHE_SPECIAL)) + +#define DECODE_SPECIAL_CACHE_NUM(ptr) \ + (((uintptr_t)(ptr)) >> 1) + +#define ENCODE_SPECIAL_CACHE_PTR(ptr) \ + ((void*)(((uintptr_t)(ptr)) | CACHE_SPECIAL)) + +#define DECODE_SPECIAL_CACHE_PTR(ptr) \ + ((void*)(((uintptr_t)(ptr)) & ~CACHE_SPECIAL)) + #define SKIP_EXT_OPLINE(opline) do { \ while (UNEXPECTED((opline)->opcode >= ZEND_EXT_STMT \ && (opline)->opcode <= ZEND_TICKS)) { \ |