mirror of
https://github.com/php/php-src.git
synced 2025-01-18 17:54:05 +08:00
Immutable clases and op_arrays
This commit is contained in:
parent
4f1274c59b
commit
94099586ec
@ -7,6 +7,7 @@ PHP 7.4 INTERNALS UPGRADE NOTES
|
||||
d. Removed zend_check_private()
|
||||
e. php_win32_error_to_msg() memory management
|
||||
f. get_properties_for() handler / Z_OBJDEBUG_P
|
||||
g. Immutable classes and op_arrays
|
||||
|
||||
2. Build system changes
|
||||
a. Abstract
|
||||
@ -98,6 +99,20 @@ PHP 7.4 INTERNALS UPGRADE NOTES
|
||||
// ...
|
||||
zend_release_properties(ht);
|
||||
|
||||
g. Opcache may make classes and op_arrays immutable. Such classes are marked
|
||||
by ZEND_ACC_IMMUTABLE flag, they are not going to be copied from opcache
|
||||
shard memory to process memory and must not be modified at all.
|
||||
Few related data structures were changed to allow addressing mutable data
|
||||
structures from immutable ones. This access is implemented through
|
||||
ZEND_MAP_PTR... abstraction macros and, basically, uses additional level of
|
||||
indirection. op_array->run_time_cache, op_array->static_variables_ptr,
|
||||
class_entry->static_members_table and class_entry->iterator_funcs_ptr now
|
||||
have to be access through ZEND_MAP_PTR... macros.
|
||||
It's also not allowed to change op_array->reserved[] handles of immutable
|
||||
op_arrays. Instead, now you have to reserve op_array handle using
|
||||
zend_get_op_array_extension_handle() during MINIT and access its value
|
||||
using ZEND_OP_ARRAY_EXTENSION(op_array, handle).
|
||||
|
||||
========================
|
||||
2. Build system changes
|
||||
========================
|
||||
|
126
Zend/zend.c
126
Zend/zend.c
@ -33,6 +33,8 @@
|
||||
#include "zend_smart_string.h"
|
||||
#include "zend_cpuinfo.h"
|
||||
|
||||
static size_t global_map_ptr_last = 0;
|
||||
|
||||
#ifdef ZTS
|
||||
ZEND_API int compiler_globals_id;
|
||||
ZEND_API int executor_globals_id;
|
||||
@ -41,7 +43,6 @@ static HashTable *global_class_table = NULL;
|
||||
static HashTable *global_constants_table = NULL;
|
||||
static HashTable *global_auto_globals_table = NULL;
|
||||
static HashTable *global_persistent_list = NULL;
|
||||
static zend_uintptr_t global_last_static_member = 0;
|
||||
ZEND_TSRMLS_CACHE_DEFINE()
|
||||
# define GLOBAL_FUNCTION_TABLE global_function_table
|
||||
# define GLOBAL_CLASS_TABLE global_class_table
|
||||
@ -626,13 +627,22 @@ static void compiler_globals_ctor(zend_compiler_globals *compiler_globals) /* {{
|
||||
zend_hash_init_ex(compiler_globals->auto_globals, 8, NULL, auto_global_dtor, 1, 0);
|
||||
zend_hash_copy(compiler_globals->auto_globals, global_auto_globals_table, auto_global_copy_ctor);
|
||||
|
||||
compiler_globals->last_static_member = global_last_static_member;
|
||||
if (compiler_globals->last_static_member) {
|
||||
compiler_globals->static_members_table = calloc(compiler_globals->last_static_member + 1, sizeof(zval*));
|
||||
} else {
|
||||
compiler_globals->static_members_table = NULL;
|
||||
}
|
||||
compiler_globals->script_encoding_list = NULL;
|
||||
|
||||
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
|
||||
/* Map region is going to be created and resized at run-time. */
|
||||
compiler_globals->map_ptr_base = NULL;
|
||||
compiler_globals->map_ptr_size = 0;
|
||||
compiler_globals->map_ptr_last = global_map_ptr_last;
|
||||
if (compiler_globals->map_ptr_last) {
|
||||
/* Allocate map_ptr table */
|
||||
compiler_globals->map_ptr_size = ZEND_MM_ALIGNED_SIZE_EX(compiler_globals->map_ptr_last, 4096);
|
||||
compiler_globals->map_ptr_base = pemalloc(compiler_globals->map_ptr_size * sizeof(void*), 1);
|
||||
memset(compiler_globals->map_ptr_base, 0, compiler_globals->map_ptr_last * sizeof(void*));
|
||||
}
|
||||
#else
|
||||
# error "Unknown ZEND_MAP_PTR_KIND"
|
||||
#endif
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -650,13 +660,14 @@ static void compiler_globals_dtor(zend_compiler_globals *compiler_globals) /* {{
|
||||
zend_hash_destroy(compiler_globals->auto_globals);
|
||||
free(compiler_globals->auto_globals);
|
||||
}
|
||||
if (compiler_globals->static_members_table) {
|
||||
free(compiler_globals->static_members_table);
|
||||
}
|
||||
if (compiler_globals->script_encoding_list) {
|
||||
pefree((char*)compiler_globals->script_encoding_list, 1);
|
||||
}
|
||||
compiler_globals->last_static_member = 0;
|
||||
if (compiler_globals->map_ptr_base) {
|
||||
free(compiler_globals->map_ptr_base);
|
||||
compiler_globals->map_ptr_base = NULL;
|
||||
compiler_globals->map_ptr_size = 0;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -879,6 +890,22 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
|
||||
#ifdef ZEND_WIN32
|
||||
zend_get_windows_version_info(&EG(windows_version_info));
|
||||
#endif
|
||||
# if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
|
||||
/* Create a map region, used for indirect pointers from shared to
|
||||
* process memory. It's allocatred once and never resized.
|
||||
* All processes must map it into the same address space.
|
||||
*/
|
||||
CG(map_ptr_size) = 1024 * 1024; // TODO: initial size ???
|
||||
CG(map_ptr_last) = 0;
|
||||
CG(map_ptr_base) = pemalloc(CG(map_ptr_size) * sizeof(void*), 1);
|
||||
# elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
|
||||
/* Map region is going to be created and resized at run-time. */
|
||||
CG(map_ptr_base) = NULL;
|
||||
CG(map_ptr_size) = 0;
|
||||
CG(map_ptr_last) = 0;
|
||||
# else
|
||||
# error "Unknown ZEND_MAP_PTR_KIND"
|
||||
# endif
|
||||
#endif
|
||||
EG(error_reporting) = E_ALL & ~E_NOTICE;
|
||||
|
||||
@ -931,7 +958,7 @@ int zend_post_startup(void) /* {{{ */
|
||||
*GLOBAL_FUNCTION_TABLE = *compiler_globals->function_table;
|
||||
*GLOBAL_CLASS_TABLE = *compiler_globals->class_table;
|
||||
*GLOBAL_CONSTANTS_TABLE = *executor_globals->zend_constants;
|
||||
global_last_static_member = compiler_globals->last_static_member;
|
||||
global_map_ptr_last = compiler_globals->map_ptr_last;
|
||||
|
||||
short_tags_default = CG(short_tags);
|
||||
compiler_options_default = CG(compiler_options);
|
||||
@ -950,6 +977,8 @@ int zend_post_startup(void) /* {{{ */
|
||||
executor_globals_ctor(executor_globals);
|
||||
global_persistent_list = &EG(persistent_list);
|
||||
zend_copy_ini_directives();
|
||||
#else
|
||||
global_map_ptr_last = CG(map_ptr_last);
|
||||
#endif
|
||||
|
||||
if (zend_post_startup_cb) {
|
||||
@ -996,6 +1025,12 @@ void zend_shutdown(void) /* {{{ */
|
||||
GLOBAL_CLASS_TABLE = NULL;
|
||||
GLOBAL_AUTO_GLOBALS_TABLE = NULL;
|
||||
GLOBAL_CONSTANTS_TABLE = NULL;
|
||||
#else
|
||||
if (CG(map_ptr_base)) {
|
||||
free(CG(map_ptr_base));
|
||||
CG(map_ptr_base) = NULL;
|
||||
CG(map_ptr_size) = 0;
|
||||
}
|
||||
#endif
|
||||
zend_destroy_rsrc_list_dtors();
|
||||
}
|
||||
@ -1077,17 +1112,12 @@ ZEND_API void zend_activate(void) /* {{{ */
|
||||
init_compiler();
|
||||
init_executor();
|
||||
startup_scanner();
|
||||
if (CG(map_ptr_last)) {
|
||||
memset(CG(map_ptr_base), 0, CG(map_ptr_last) * sizeof(void*));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
#ifdef ZTS
|
||||
void zend_reset_internal_classes(void) /* {{{ */
|
||||
{
|
||||
CG(last_static_member) = global_last_static_member;
|
||||
}
|
||||
/* }}} */
|
||||
#endif
|
||||
|
||||
void zend_call_destructors(void) /* {{{ */
|
||||
{
|
||||
zend_try {
|
||||
@ -1619,6 +1649,62 @@ void free_estring(char **str_p) /* {{{ */
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void zend_map_ptr_reset(void)
|
||||
{
|
||||
CG(map_ptr_last) = global_map_ptr_last;
|
||||
}
|
||||
|
||||
ZEND_API void *zend_map_ptr_new(void)
|
||||
{
|
||||
void **ptr;
|
||||
|
||||
if (CG(map_ptr_last) >= CG(map_ptr_size)) {
|
||||
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
|
||||
// TODO: error ???
|
||||
ZEND_ASSERT(0);
|
||||
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
|
||||
/* Grow map_ptr table */
|
||||
CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(CG(map_ptr_last) + 1, 4096);
|
||||
CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1);
|
||||
#else
|
||||
# error "Unknown ZEND_MAP_PTR_KIND"
|
||||
#endif
|
||||
}
|
||||
ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last);
|
||||
*ptr = NULL;
|
||||
CG(map_ptr_last)++;
|
||||
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
|
||||
return ptr;
|
||||
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
|
||||
return (void*)((CG(map_ptr_last) * sizeof(void*)) - (sizeof(void*) - 1));
|
||||
#else
|
||||
# error "Unknown ZEND_MAP_PTR_KIND"
|
||||
#endif
|
||||
}
|
||||
|
||||
ZEND_API void zend_map_ptr_extend(size_t last)
|
||||
{
|
||||
if (last > CG(map_ptr_last)) {
|
||||
void **ptr;
|
||||
|
||||
if (last >= CG(map_ptr_size)) {
|
||||
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
|
||||
/* This may never happen */
|
||||
ZEND_ASSERT(0);
|
||||
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
|
||||
/* Grow map_ptr table */
|
||||
CG(map_ptr_size) = ZEND_MM_ALIGNED_SIZE_EX(last, 4096);
|
||||
CG(map_ptr_base) = perealloc(CG(map_ptr_base), CG(map_ptr_size) * sizeof(void*), 1);
|
||||
#else
|
||||
# error "Unknown ZEND_MAP_PTR_KIND"
|
||||
#endif
|
||||
}
|
||||
ptr = (void**)CG(map_ptr_base) + CG(map_ptr_last);
|
||||
memset(ptr, 0, (last - CG(map_ptr_last)) * sizeof(void*));
|
||||
CG(map_ptr_last) = last;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
11
Zend/zend.h
11
Zend/zend.h
@ -25,6 +25,7 @@
|
||||
#define ZEND_ENGINE_3
|
||||
|
||||
#include "zend_types.h"
|
||||
#include "zend_map_ptr.h"
|
||||
#include "zend_errors.h"
|
||||
#include "zend_alloc.h"
|
||||
#include "zend_llist.h"
|
||||
@ -127,10 +128,7 @@ struct _zend_class_entry {
|
||||
int default_static_members_count;
|
||||
zval *default_properties_table;
|
||||
zval *default_static_members_table;
|
||||
union {
|
||||
zval *static_members_table;
|
||||
zend_uintptr_t static_members_table_idx;
|
||||
};
|
||||
ZEND_MAP_PTR_DEF(zval *, static_members_table);
|
||||
HashTable function_table;
|
||||
HashTable properties_info;
|
||||
HashTable constants_table;
|
||||
@ -150,7 +148,7 @@ struct _zend_class_entry {
|
||||
zend_function *unserialize_func;
|
||||
|
||||
/* allocated only if class implements Iterator or IteratorAggregate interface */
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
ZEND_MAP_PTR_DEF(zend_class_iterator_funcs *, iterator_funcs_ptr);
|
||||
|
||||
/* handlers */
|
||||
union {
|
||||
@ -271,9 +269,8 @@ ZEND_API void zend_activate_modules(void);
|
||||
ZEND_API void zend_deactivate_modules(void);
|
||||
ZEND_API void zend_post_deactivate_modules(void);
|
||||
|
||||
void zend_reset_internal_classes(void);
|
||||
|
||||
ZEND_API void free_estring(char **str_p);
|
||||
|
||||
END_EXTERN_C()
|
||||
|
||||
/* output support */
|
||||
|
@ -2795,7 +2795,9 @@ ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zen
|
||||
ce = zend_hash_add_ptr(CG(class_table), lcname, ce);
|
||||
zend_string_release_ex(lcname, 0);
|
||||
if (ce) {
|
||||
ce->refcount++;
|
||||
if (!(ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
|
||||
ce->refcount++;
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
return FAILURE;
|
||||
@ -3696,18 +3698,14 @@ ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, z
|
||||
ce->default_static_members_table = perealloc(ce->default_static_members_table, sizeof(zval) * ce->default_static_members_count, ce->type == ZEND_INTERNAL_CLASS);
|
||||
}
|
||||
ZVAL_COPY_VALUE(&ce->default_static_members_table[property_info->offset], property);
|
||||
if (ce->type == ZEND_USER_CLASS) {
|
||||
ce->static_members_table = ce->default_static_members_table;
|
||||
#ifdef ZTS
|
||||
} else if (!ce->static_members_table_idx) {
|
||||
CG(last_static_member)++;
|
||||
ce->static_members_table_idx = CG(last_static_member);
|
||||
if (CG(static_members_table)) {
|
||||
/* Support for run-time declaration: dl() */
|
||||
CG(static_members_table) = realloc(CG(static_members_table), (CG(last_static_member) + 1) * sizeof(zval*));
|
||||
CG(static_members_table)[ce->static_members_table_idx] = NULL;
|
||||
if (!ZEND_MAP_PTR(ce->static_members_table)) {
|
||||
ZEND_ASSERT(ce->type == ZEND_INTERNAL_CLASS);
|
||||
if (!EG(current_execute_data)) {
|
||||
ZEND_MAP_PTR_NEW(ce->static_members_table);
|
||||
} else {
|
||||
/* internal class loaded by dl() */
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
if ((property_info_ptr = zend_hash_find_ptr(&ce->properties_info, name)) != NULL &&
|
||||
|
@ -219,7 +219,7 @@ typedef struct _zend_fcall_info_cache {
|
||||
class_container.trait_precedences = NULL; \
|
||||
class_container.interfaces = NULL; \
|
||||
class_container.get_iterator = NULL; \
|
||||
class_container.iterator_funcs_ptr = NULL; \
|
||||
ZEND_MAP_PTR_INIT(class_container.iterator_funcs_ptr, NULL); \
|
||||
class_container.info.internal.module = NULL; \
|
||||
class_container.info.internal.builtin_functions = functions; \
|
||||
}
|
||||
@ -228,11 +228,8 @@ typedef struct _zend_fcall_info_cache {
|
||||
#define INIT_NS_CLASS_ENTRY(class_container, ns, class_name, functions) \
|
||||
INIT_CLASS_ENTRY(class_container, ZEND_NS_NAME(ns, class_name), functions)
|
||||
|
||||
#ifdef ZTS
|
||||
# define CE_STATIC_MEMBERS(ce) (((ce)->type==ZEND_USER_CLASS)?(ce)->static_members_table:CG(static_members_table)[(ce)->static_members_table_idx])
|
||||
#else
|
||||
# define CE_STATIC_MEMBERS(ce) ((ce)->static_members_table)
|
||||
#endif
|
||||
#define CE_STATIC_MEMBERS(ce) \
|
||||
((zval*)ZEND_MAP_PTR_GET((ce)->static_members_table))
|
||||
|
||||
#define ZEND_FCI_INITIALIZED(fci) ((fci).size != 0)
|
||||
|
||||
|
@ -1770,7 +1770,7 @@ static int copy_class_or_interface_name(zval *el, int num_args, va_list args, ze
|
||||
|
||||
if ((hash_key->key && ZSTR_VAL(hash_key->key)[0] != 0)
|
||||
&& (comply_mask == (ce->ce_flags & mask))) {
|
||||
if (ce->refcount > 1 &&
|
||||
if ((ce->refcount > 1 || (ce->ce_flags & ZEND_ACC_IMMUTABLE)) &&
|
||||
!same_name(hash_key->key, ce->name)) {
|
||||
add_next_index_str(array, zend_string_copy(hash_key->key));
|
||||
} else {
|
||||
|
@ -151,9 +151,14 @@ ZEND_METHOD(Closure, call)
|
||||
if (ZEND_USER_CODE(my_function.type)
|
||||
&& (closure->func.common.scope != Z_OBJCE_P(newthis)
|
||||
|| (closure->func.common.fn_flags & ZEND_ACC_HEAP_RT_CACHE))) {
|
||||
my_function.op_array.run_time_cache = emalloc(my_function.op_array.cache_size);
|
||||
void *ptr;
|
||||
|
||||
my_function.op_array.fn_flags |= ZEND_ACC_HEAP_RT_CACHE;
|
||||
memset(my_function.op_array.run_time_cache, 0, my_function.op_array.cache_size);
|
||||
ptr = emalloc(sizeof(void*) + my_function.op_array.cache_size);
|
||||
ZEND_MAP_PTR_INIT(my_function.op_array.run_time_cache, ptr);
|
||||
ptr = (char*)ptr + sizeof(void*);
|
||||
ZEND_MAP_PTR_SET(my_function.op_array.run_time_cache, ptr);
|
||||
memset(ptr, 0, my_function.op_array.cache_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -176,7 +181,7 @@ ZEND_METHOD(Closure, call)
|
||||
/* copied upon generator creation */
|
||||
GC_DELREF(&closure->std);
|
||||
} else if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_HEAP_RT_CACHE) {
|
||||
efree(my_function.op_array.run_time_cache);
|
||||
efree(ZEND_MAP_PTR(my_function.op_array.run_time_cache));
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
@ -501,7 +506,8 @@ static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp) /* {{{
|
||||
debug_info = zend_new_array(8);
|
||||
|
||||
if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) {
|
||||
HashTable *static_variables = closure->func.op_array.static_variables;
|
||||
HashTable *static_variables =
|
||||
ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
|
||||
ZVAL_ARR(&val, zend_array_dup(static_variables));
|
||||
zend_hash_update(debug_info, ZSTR_KNOWN(ZEND_STR_STATIC), &val);
|
||||
}
|
||||
@ -559,7 +565,7 @@ static HashTable *zend_closure_get_gc(zval *obj, zval **table, int *n) /* {{{ */
|
||||
*table = Z_TYPE(closure->this_ptr) != IS_NULL ? &closure->this_ptr : NULL;
|
||||
*n = Z_TYPE(closure->this_ptr) != IS_NULL ? 1 : 0;
|
||||
return (closure->func.type == ZEND_USER_FUNCTION) ?
|
||||
closure->func.op_array.static_variables : NULL;
|
||||
ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr) : NULL;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -654,28 +660,44 @@ ZEND_API void zend_create_closure(zval *res, zend_function *func, zend_class_ent
|
||||
if (func->type == ZEND_USER_FUNCTION) {
|
||||
memcpy(&closure->func, func, sizeof(zend_op_array));
|
||||
closure->func.common.fn_flags |= ZEND_ACC_CLOSURE;
|
||||
closure->func.common.fn_flags &= ~ZEND_ACC_IMMUTABLE;
|
||||
|
||||
if (closure->func.op_array.static_variables) {
|
||||
closure->func.op_array.static_variables =
|
||||
zend_array_dup(closure->func.op_array.static_variables);
|
||||
}
|
||||
ZEND_MAP_PTR_INIT(closure->func.op_array.static_variables_ptr,
|
||||
&closure->func.op_array.static_variables);
|
||||
|
||||
/* Runtime cache is scope-dependent, so we cannot reuse it if the scope changed */
|
||||
if (!closure->func.op_array.run_time_cache
|
||||
if (!ZEND_MAP_PTR_GET(closure->func.op_array.run_time_cache)
|
||||
|| func->common.scope != scope
|
||||
|| (func->common.fn_flags & ZEND_ACC_HEAP_RT_CACHE)
|
||||
) {
|
||||
if (!func->op_array.run_time_cache && (func->common.fn_flags & ZEND_ACC_CLOSURE)) {
|
||||
void *ptr;
|
||||
|
||||
if (!ZEND_MAP_PTR_GET(func->op_array.run_time_cache)
|
||||
&& (func->common.fn_flags & ZEND_ACC_CLOSURE)
|
||||
&& (func->common.scope == scope ||
|
||||
!(func->common.fn_flags & ZEND_ACC_IMMUTABLE))) {
|
||||
/* If a real closure is used for the first time, we create a shared runtime cache
|
||||
* and remember which scope it is for. */
|
||||
func->common.scope = scope;
|
||||
func->op_array.run_time_cache = zend_arena_alloc(&CG(arena), func->op_array.cache_size);
|
||||
closure->func.op_array.run_time_cache = func->op_array.run_time_cache;
|
||||
if (func->common.scope != scope) {
|
||||
func->common.scope = scope;
|
||||
}
|
||||
closure->func.op_array.fn_flags &= ~ZEND_ACC_HEAP_RT_CACHE;
|
||||
ptr = zend_arena_alloc(&CG(arena), func->op_array.cache_size);
|
||||
ZEND_MAP_PTR_SET(func->op_array.run_time_cache, ptr);
|
||||
ZEND_MAP_PTR_SET(closure->func.op_array.run_time_cache, ptr);
|
||||
} else {
|
||||
/* Otherwise, we use a non-shared runtime cache */
|
||||
closure->func.op_array.run_time_cache = emalloc(func->op_array.cache_size);
|
||||
closure->func.op_array.fn_flags |= ZEND_ACC_HEAP_RT_CACHE;
|
||||
ptr = emalloc(sizeof(void*) + func->op_array.cache_size);
|
||||
ZEND_MAP_PTR_INIT(closure->func.op_array.run_time_cache, ptr);
|
||||
ptr = (char*)ptr + sizeof(void*);
|
||||
ZEND_MAP_PTR_SET(closure->func.op_array.run_time_cache, ptr);
|
||||
}
|
||||
memset(closure->func.op_array.run_time_cache, 0, func->op_array.cache_size);
|
||||
memset(ptr, 0, func->op_array.cache_size);
|
||||
}
|
||||
if (closure->func.op_array.refcount) {
|
||||
(*closure->func.op_array.refcount)++;
|
||||
@ -728,7 +750,7 @@ ZEND_API void zend_create_fake_closure(zval *res, zend_function *func, zend_clas
|
||||
void zend_closure_bind_var(zval *closure_zv, zend_string *var_name, zval *var) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *) Z_OBJ_P(closure_zv);
|
||||
HashTable *static_variables = closure->func.op_array.static_variables;
|
||||
HashTable *static_variables = ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
|
||||
zend_hash_update(static_variables, var_name, var);
|
||||
}
|
||||
/* }}} */
|
||||
@ -736,7 +758,7 @@ void zend_closure_bind_var(zval *closure_zv, zend_string *var_name, zval *var) /
|
||||
void zend_closure_bind_var_ex(zval *closure_zv, uint32_t offset, zval *val) /* {{{ */
|
||||
{
|
||||
zend_closure *closure = (zend_closure *) Z_OBJ_P(closure_zv);
|
||||
HashTable *static_variables = closure->func.op_array.static_variables;
|
||||
HashTable *static_variables = ZEND_MAP_PTR_GET(closure->func.op_array.static_variables_ptr);
|
||||
zval *var = (zval*)((char*)static_variables->arData + offset);
|
||||
zval_ptr_dtor(var);
|
||||
ZVAL_COPY_VALUE(var, val);
|
||||
|
@ -1021,7 +1021,9 @@ ZEND_API void function_add_ref(zend_function *function) /* {{{ */
|
||||
GC_ADDREF(op_array->static_variables);
|
||||
}
|
||||
}
|
||||
op_array->run_time_cache = NULL;
|
||||
ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void*)));
|
||||
ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
|
||||
} else if (function->type == ZEND_INTERNAL_FUNCTION) {
|
||||
if (function->common.function_name) {
|
||||
zend_string_addref(function->common.function_name);
|
||||
@ -1614,9 +1616,9 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
|
||||
zend_hash_init_ex(&ce->function_table, 8, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, 0);
|
||||
|
||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||
ce->static_members_table = NULL;
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, NULL);
|
||||
} else {
|
||||
ce->static_members_table = ce->default_static_members_table;
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
ce->info.user.doc_comment = NULL;
|
||||
}
|
||||
|
||||
@ -1636,7 +1638,7 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify
|
||||
ce->__tostring = NULL;
|
||||
ce->create_object = NULL;
|
||||
ce->get_iterator = NULL;
|
||||
ce->iterator_funcs_ptr = NULL;
|
||||
ZEND_MAP_PTR_INIT(ce->iterator_funcs_ptr, NULL);
|
||||
ce->get_static_method = NULL;
|
||||
ce->parent = NULL;
|
||||
ce->parent_name = NULL;
|
||||
@ -5867,6 +5869,9 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
|
||||
|
||||
init_op_array(op_array, ZEND_USER_FUNCTION, INITIAL_OP_ARRAY_SIZE);
|
||||
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void*)));
|
||||
ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
|
||||
|
||||
op_array->fn_flags |= (orig_op_array->fn_flags & ZEND_ACC_STRICT_TYPES);
|
||||
op_array->fn_flags |= decl->flags;
|
||||
op_array->line_start = decl->start_lineno;
|
||||
|
@ -389,7 +389,8 @@ struct _zend_op_array {
|
||||
uint32_t last; /* number of opcodes */
|
||||
|
||||
zend_op *opcodes;
|
||||
void **run_time_cache;
|
||||
ZEND_MAP_PTR_DEF(void **, run_time_cache);
|
||||
ZEND_MAP_PTR_DEF(HashTable *, static_variables_ptr);
|
||||
HashTable *static_variables;
|
||||
zend_string **vars; /* names of CV variables */
|
||||
|
||||
@ -660,19 +661,25 @@ struct _zend_execute_data {
|
||||
(node).constant = RT_CONSTANT(opline, node) - (op_array)->literals; \
|
||||
} while (0)
|
||||
|
||||
#define RUN_TIME_CACHE(op_array) \
|
||||
ZEND_MAP_PTR_GET((op_array)->run_time_cache)
|
||||
|
||||
#define ZEND_OP_ARRAY_EXTENSION(op_array, handle) \
|
||||
RUN_TIME_CACHE(op_array)[handle]
|
||||
|
||||
#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; \
|
||||
EX(run_time_cache) = RUN_TIME_CACHE(op_array); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
|
||||
# define EX_RUN_TIME_CACHE() \
|
||||
EX(func)->op_array.run_time_cache
|
||||
RUN_TIME_CACHE(&EX(func)->op_array)
|
||||
|
||||
# define EX_LOAD_RUN_TIME_CACHE(op_array) do { \
|
||||
} while (0)
|
||||
|
@ -2504,39 +2504,20 @@ static zend_always_inline void i_init_func_execute_data(zend_op_array *op_array,
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline void init_func_run_time_cache_i(zend_op_array *op_array) /* {{{ */
|
||||
{
|
||||
void **run_time_cache;
|
||||
|
||||
ZEND_ASSERT(RUN_TIME_CACHE(op_array) == NULL);
|
||||
run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
|
||||
memset(run_time_cache, 0, op_array->cache_size);
|
||||
ZEND_MAP_PTR_SET(op_array->run_time_cache, run_time_cache);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_never_inline void ZEND_FASTCALL init_func_run_time_cache(zend_op_array *op_array) /* {{{ */
|
||||
{
|
||||
ZEND_ASSERT(op_array->run_time_cache == NULL);
|
||||
op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
|
||||
memset(op_array->run_time_cache, 0, op_array->cache_size);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline zend_function* ZEND_FASTCALL init_func_run_time_cache_i(zval *zv) /* {{{ */
|
||||
{
|
||||
zend_op_array *op_array = Z_PTR_P(zv);
|
||||
|
||||
ZEND_ASSERT(op_array->run_time_cache == NULL);
|
||||
if (op_array->fn_flags & ZEND_ACC_IMMUTABLE) {
|
||||
zend_op_array *new_op_array = zend_arena_alloc(&CG(arena), sizeof(zend_op_array) + op_array->cache_size);
|
||||
|
||||
Z_PTR_P(zv) = new_op_array;
|
||||
memcpy(new_op_array, op_array, sizeof(zend_op_array));
|
||||
new_op_array->fn_flags &= ~ZEND_ACC_IMMUTABLE;
|
||||
new_op_array->run_time_cache = (void**)(new_op_array + 1);
|
||||
memset(new_op_array->run_time_cache, 0, new_op_array->cache_size);
|
||||
return (zend_function*)new_op_array;
|
||||
} else {
|
||||
op_array->run_time_cache = zend_arena_alloc(&CG(arena), op_array->cache_size);
|
||||
memset(op_array->run_time_cache, 0, op_array->cache_size);
|
||||
return (zend_function*)op_array;
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_never_inline zend_function* init_func_run_time_cache_ex(zval *zv) /* {{{ */
|
||||
{
|
||||
return init_func_run_time_cache_i(zv);
|
||||
init_func_run_time_cache_i(op_array);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -2547,8 +2528,8 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function(zend_string *name) /*
|
||||
if (EXPECTED(zv != NULL)) {
|
||||
zend_function *fbc = Z_FUNC_P(zv);
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = (zend_function*)init_func_run_time_cache_i(zv);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache_i(&fbc->op_array);
|
||||
}
|
||||
return fbc;
|
||||
}
|
||||
@ -2562,8 +2543,8 @@ ZEND_API zend_function * ZEND_FASTCALL zend_fetch_function_str(const char *name,
|
||||
if (EXPECTED(zv != NULL)) {
|
||||
zend_function *fbc = Z_FUNC_P(zv);
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = (zend_function*)init_func_run_time_cache_i(zv);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache_i(&fbc->op_array);
|
||||
}
|
||||
return fbc;
|
||||
}
|
||||
@ -2580,10 +2561,15 @@ static zend_always_inline void i_init_code_execute_data(zend_execute_data *execu
|
||||
|
||||
zend_attach_symbol_table(execute_data);
|
||||
|
||||
if (!op_array->run_time_cache) {
|
||||
if (!ZEND_MAP_PTR(op_array->run_time_cache)) {
|
||||
void *ptr;
|
||||
|
||||
ZEND_ASSERT(op_array->fn_flags & ZEND_ACC_HEAP_RT_CACHE);
|
||||
op_array->run_time_cache = emalloc(op_array->cache_size);
|
||||
memset(op_array->run_time_cache, 0, op_array->cache_size);
|
||||
ptr = emalloc(op_array->cache_size + sizeof(void*));
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, ptr);
|
||||
ptr = (char*)ptr + sizeof(void*);
|
||||
ZEND_MAP_PTR_SET(op_array->run_time_cache, ptr);
|
||||
memset(ptr, 0, op_array->cache_size);
|
||||
}
|
||||
EX_LOAD_RUN_TIME_CACHE(op_array);
|
||||
|
||||
@ -2602,7 +2588,7 @@ ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array *
|
||||
#endif
|
||||
|
||||
EX(prev_execute_data) = EG(current_execute_data);
|
||||
if (!op_array->run_time_cache) {
|
||||
if (!RUN_TIME_CACHE(op_array)) {
|
||||
init_func_run_time_cache(op_array);
|
||||
}
|
||||
i_init_func_execute_data(op_array, return_value, 1 EXECUTE_DATA_CC);
|
||||
@ -2618,10 +2604,15 @@ ZEND_API void zend_init_func_execute_data(zend_execute_data *ex, zend_op_array *
|
||||
ZEND_API void zend_init_code_execute_data(zend_execute_data *execute_data, zend_op_array *op_array, zval *return_value) /* {{{ */
|
||||
{
|
||||
EX(prev_execute_data) = EG(current_execute_data);
|
||||
if (!op_array->run_time_cache) {
|
||||
if (!ZEND_MAP_PTR(op_array->run_time_cache)) {
|
||||
void *ptr;
|
||||
|
||||
ZEND_ASSERT(op_array->fn_flags & ZEND_ACC_HEAP_RT_CACHE);
|
||||
op_array->run_time_cache = emalloc(op_array->cache_size);
|
||||
memset(op_array->run_time_cache, 0, op_array->cache_size);
|
||||
ptr = emalloc(op_array->cache_size + sizeof(void*));
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, ptr);
|
||||
ptr = (char*)ptr + sizeof(void*);
|
||||
ZEND_MAP_PTR_SET(op_array->run_time_cache, ptr);
|
||||
memset(ptr, 0, op_array->cache_size);
|
||||
}
|
||||
i_init_code_execute_data(execute_data, op_array, return_value);
|
||||
}
|
||||
@ -2964,7 +2955,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
} else {
|
||||
@ -2982,8 +2973,8 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_string(zend_s
|
||||
zend_string_release_ex(lcname, 0);
|
||||
|
||||
fbc = Z_FUNC_P(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = init_func_run_time_cache_ex(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
called_scope = NULL;
|
||||
}
|
||||
@ -3019,7 +3010,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_object(zval *
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
|
||||
@ -3106,7 +3097,7 @@ static zend_never_inline zend_execute_data *zend_init_dynamic_call_array(zend_ar
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
|
||||
|
@ -318,9 +318,6 @@ void shutdown_executor(void) /* {{{ */
|
||||
zend_hash_reverse_apply(EG(zend_constants), clean_non_persistent_constant_full);
|
||||
zend_hash_reverse_apply(EG(function_table), clean_non_persistent_function_full);
|
||||
zend_hash_reverse_apply(EG(class_table), clean_non_persistent_class_full);
|
||||
#ifdef ZTS
|
||||
zend_reset_internal_classes();
|
||||
#endif
|
||||
} else {
|
||||
ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(zend_constants), key, zv) {
|
||||
zend_constant *c = Z_PTR_P(zv);
|
||||
@ -334,6 +331,7 @@ void shutdown_executor(void) /* {{{ */
|
||||
efree(c);
|
||||
zend_string_release_ex(key, 0);
|
||||
} ZEND_HASH_FOREACH_END_DEL();
|
||||
|
||||
ZEND_HASH_REVERSE_FOREACH_STR_KEY_VAL(EG(function_table), key, zv) {
|
||||
zend_function *func = Z_PTR_P(zv);
|
||||
if (_idx == EG(persistent_functions_count)) {
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
ZEND_API zend_llist zend_extensions;
|
||||
ZEND_API uint32_t zend_extension_flags = 0;
|
||||
ZEND_API int zend_op_array_extension_handles = 0;
|
||||
static int last_resource_number;
|
||||
|
||||
int zend_load_extension(const char *path)
|
||||
@ -198,6 +199,7 @@ int zend_startup_extensions_mechanism()
|
||||
{
|
||||
/* Startup extensions mechanism */
|
||||
zend_llist_init(&zend_extensions, sizeof(zend_extension), (void (*)(void *)) zend_extension_dtor, 1);
|
||||
zend_op_array_extension_handles = 0;
|
||||
last_resource_number = 0;
|
||||
return SUCCESS;
|
||||
}
|
||||
@ -257,6 +259,10 @@ ZEND_API int zend_get_resource_handle(zend_extension *extension)
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_API int zend_get_op_array_extension_handle(void)
|
||||
{
|
||||
return zend_op_array_extension_handles++;
|
||||
}
|
||||
|
||||
ZEND_API zend_extension *zend_get_extension(const char *extension_name)
|
||||
{
|
||||
|
@ -111,7 +111,10 @@ struct _zend_extension {
|
||||
};
|
||||
|
||||
BEGIN_EXTERN_C()
|
||||
extern ZEND_API int zend_op_array_extension_handles;
|
||||
|
||||
ZEND_API int zend_get_resource_handle(zend_extension *extension);
|
||||
ZEND_API int zend_get_op_array_extension_handle(void);
|
||||
ZEND_API void zend_extension_dispatch_message(int message, void *arg);
|
||||
END_EXTERN_C()
|
||||
|
||||
|
@ -117,10 +117,9 @@ struct _zend_compiler_globals {
|
||||
|
||||
zend_stack delayed_oplines_stack;
|
||||
|
||||
#ifdef ZTS
|
||||
zval **static_members_table;
|
||||
zend_uintptr_t last_static_member;
|
||||
#endif
|
||||
void *map_ptr_base;
|
||||
size_t map_ptr_size;
|
||||
size_t map_ptr_last;
|
||||
};
|
||||
|
||||
|
||||
|
@ -64,11 +64,16 @@ static zend_function *zend_duplicate_function(zend_function *func, zend_class_en
|
||||
/* reuse the same op_array structure */
|
||||
return func;
|
||||
}
|
||||
if (!(GC_FLAGS(func->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_ADDREF(func->op_array.static_variables);
|
||||
}
|
||||
new_function = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
|
||||
memcpy(new_function, func, sizeof(zend_op_array));
|
||||
if (ZEND_MAP_PTR_GET(func->op_array.static_variables_ptr)) {
|
||||
/* See: Zend/tests/method_static_var.phpt */
|
||||
new_function->op_array.static_variables = ZEND_MAP_PTR_GET(func->op_array.static_variables_ptr);
|
||||
}
|
||||
if (!(GC_FLAGS(new_function->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_ADDREF(new_function->op_array.static_variables);
|
||||
}
|
||||
ZEND_MAP_PTR_INIT(new_function->op_array.static_variables_ptr, &new_function->op_array.static_variables);
|
||||
}
|
||||
return new_function;
|
||||
}
|
||||
@ -87,23 +92,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
|
||||
if (EXPECTED(!ce->get_iterator)) {
|
||||
ce->get_iterator = parent->get_iterator;
|
||||
}
|
||||
if (EXPECTED(!ce->iterator_funcs_ptr) && UNEXPECTED(parent->iterator_funcs_ptr)) {
|
||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||
ce->iterator_funcs_ptr = calloc(1, sizeof(zend_class_iterator_funcs));
|
||||
if (parent->iterator_funcs_ptr->zf_new_iterator) {
|
||||
ce->iterator_funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(&ce->function_table, "getiterator", sizeof("getiterator") - 1);
|
||||
}
|
||||
if (parent->iterator_funcs_ptr->zf_current) {
|
||||
ce->iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&ce->function_table, "rewind", sizeof("rewind") - 1);
|
||||
ce->iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&ce->function_table, "valid", sizeof("valid") - 1);
|
||||
ce->iterator_funcs_ptr->zf_key = zend_hash_str_find_ptr(&ce->function_table, "key", sizeof("key") - 1);
|
||||
ce->iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&ce->function_table, "current", sizeof("current") - 1);
|
||||
ce->iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&ce->function_table, "next", sizeof("next") - 1);
|
||||
}
|
||||
} else {
|
||||
ce->iterator_funcs_ptr = zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs));
|
||||
memset(ce->iterator_funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
|
||||
}
|
||||
if (ZEND_MAP_PTR(parent->iterator_funcs_ptr)) {
|
||||
/* Must be initialized through iface->interface_gets_implemented() */
|
||||
ZEND_ASSERT(ZEND_MAP_PTR(ce->iterator_funcs_ptr) && ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr));
|
||||
}
|
||||
if (EXPECTED(!ce->__get)) {
|
||||
ce->__get = parent->__get;
|
||||
@ -910,7 +901,11 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
||||
}
|
||||
} while (dst != end);
|
||||
} else if (ce->type == ZEND_USER_CLASS) {
|
||||
src = parent_ce->default_static_members_table + parent_ce->default_static_members_count;
|
||||
if (UNEXPECTED(CE_STATIC_MEMBERS(parent_ce) == NULL)) {
|
||||
ZEND_ASSERT(parent_ce->type == ZEND_INTERNAL_CLASS || (parent_ce->ce_flags & ZEND_ACC_IMMUTABLE));
|
||||
zend_class_init_statics(parent_ce);
|
||||
}
|
||||
src = CE_STATIC_MEMBERS(parent_ce) + parent_ce->default_static_members_count;
|
||||
do {
|
||||
dst--;
|
||||
src--;
|
||||
@ -936,18 +931,14 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
||||
} while (dst != end);
|
||||
}
|
||||
ce->default_static_members_count += parent_ce->default_static_members_count;
|
||||
if (ce->type == ZEND_USER_CLASS) {
|
||||
ce->static_members_table = ce->default_static_members_table;
|
||||
#ifdef ZTS
|
||||
} else if (!ce->static_members_table_idx) {
|
||||
CG(last_static_member)++;
|
||||
ce->static_members_table_idx = CG(last_static_member);
|
||||
if (CG(static_members_table)) {
|
||||
/* Support for run-time declaration: dl() */
|
||||
CG(static_members_table) = realloc(CG(static_members_table), (CG(last_static_member) + 1) * sizeof(zval*));
|
||||
CG(static_members_table)[ce->static_members_table_idx] = NULL;
|
||||
if (!ZEND_MAP_PTR(ce->static_members_table)) {
|
||||
ZEND_ASSERT(ce->type == ZEND_INTERNAL_CLASS);
|
||||
if (!EG(current_execute_data)) {
|
||||
ZEND_MAP_PTR_NEW(ce->static_members_table);
|
||||
} else {
|
||||
/* internal class loaded by dl() */
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -1315,6 +1306,10 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
|
||||
} else {
|
||||
new_fn = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
|
||||
memcpy(new_fn, fn, sizeof(zend_op_array));
|
||||
new_fn->op_array.fn_flags &= ~ZEND_ACC_IMMUTABLE;
|
||||
ZEND_MAP_PTR_INIT(new_fn->op_array.run_time_cache, zend_arena_alloc(&CG(arena), sizeof(void*)));
|
||||
ZEND_MAP_PTR_SET(new_fn->op_array.run_time_cache, NULL);
|
||||
ZEND_MAP_PTR_INIT(new_fn->op_array.static_variables_ptr, &new_fn->op_array.static_variables);
|
||||
}
|
||||
fn = zend_hash_update_ptr(&ce->function_table, key, new_fn);
|
||||
zend_add_magic_methods(ce, key, fn);
|
||||
|
@ -119,12 +119,36 @@ ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_fun
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
typedef struct _zend_class_iterator_funcs_ptr {
|
||||
zend_class_iterator_funcs *ptr;
|
||||
zend_class_iterator_funcs data;
|
||||
} zend_class_iterator_funcs_ptr;
|
||||
|
||||
/* iterator interface, c-level functions used by engine */
|
||||
static zend_never_inline zend_class_iterator_funcs* zend_alloc_iterator_funcs_ptr(zend_class_entry *ce) /* {{{ */
|
||||
{
|
||||
zend_class_iterator_funcs *ptr = zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs));
|
||||
memset(ptr, 0, sizeof(zend_class_iterator_funcs));
|
||||
ZEND_MAP_PTR_SET(ce->iterator_funcs_ptr, ptr);
|
||||
return ptr;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_always_inline zend_class_iterator_funcs* zend_get_iterator_funcs_ptr(zend_class_entry *ce) /* {{{ */
|
||||
{
|
||||
if (ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr)) {
|
||||
return ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr);
|
||||
} else {
|
||||
return zend_alloc_iterator_funcs_ptr(ce);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
/* {{{ zend_user_it_new_iterator */
|
||||
ZEND_API void zend_user_it_new_iterator(zend_class_entry *ce, zval *object, zval *retval)
|
||||
{
|
||||
zend_call_method_with_0_params(object, ce, &ce->iterator_funcs_ptr->zf_new_iterator, "getiterator", retval);
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = zend_get_iterator_funcs_ptr(ce);
|
||||
zend_call_method_with_0_params(object, ce, &iterator_funcs_ptr->zf_new_iterator, "getiterator", retval);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -159,8 +183,10 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter)
|
||||
zval *object = &iter->it.data;
|
||||
zval more;
|
||||
int result;
|
||||
zend_class_entry *ce = iter->ce;
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = zend_get_iterator_funcs_ptr(ce);
|
||||
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_valid, "valid", &more);
|
||||
zend_call_method_with_0_params(object, ce, &iterator_funcs_ptr->zf_valid, "valid", &more);
|
||||
result = i_zend_is_true(&more);
|
||||
zval_ptr_dtor(&more);
|
||||
return result ? SUCCESS : FAILURE;
|
||||
@ -176,7 +202,10 @@ ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter)
|
||||
zval *object = &iter->it.data;
|
||||
|
||||
if (Z_ISUNDEF(iter->value)) {
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_current, "current", &iter->value);
|
||||
zend_class_entry *ce = iter->ce;
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = zend_get_iterator_funcs_ptr(ce);
|
||||
|
||||
zend_call_method_with_0_params(object, ce, &iterator_funcs_ptr->zf_current, "current", &iter->value);
|
||||
}
|
||||
return &iter->value;
|
||||
}
|
||||
@ -188,8 +217,10 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zval retval;
|
||||
zend_class_entry *ce = iter->ce;
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = zend_get_iterator_funcs_ptr(ce);
|
||||
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_key, "key", &retval);
|
||||
zend_call_method_with_0_params(object, ce, &iterator_funcs_ptr->zf_key, "key", &retval);
|
||||
|
||||
if (Z_TYPE(retval) != IS_UNDEF) {
|
||||
ZVAL_ZVAL(key, &retval, 1, 1);
|
||||
@ -208,9 +239,11 @@ ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter)
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zend_class_entry *ce = iter->ce;
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = zend_get_iterator_funcs_ptr(ce);
|
||||
|
||||
zend_user_it_invalidate_current(_iter);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_next, "next", NULL);
|
||||
zend_call_method_with_0_params(object, ce, &iterator_funcs_ptr->zf_next, "next", NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -219,9 +252,11 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter)
|
||||
{
|
||||
zend_user_iterator *iter = (zend_user_iterator*)_iter;
|
||||
zval *object = &iter->it.data;
|
||||
zend_class_entry *ce = iter->ce;
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = zend_get_iterator_funcs_ptr(ce);
|
||||
|
||||
zend_user_it_invalidate_current(_iter);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
|
||||
zend_call_method_with_0_params(object, ce, &iterator_funcs_ptr->zf_rewind, "rewind", NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -312,6 +347,7 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
|
||||
{
|
||||
uint32_t i;
|
||||
int t = -1;
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
if (class_type->get_iterator) {
|
||||
if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
@ -340,17 +376,31 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
|
||||
}
|
||||
}
|
||||
class_type->get_iterator = zend_user_it_get_new_iterator;
|
||||
if (class_type->iterator_funcs_ptr != NULL) {
|
||||
class_type->iterator_funcs_ptr->zf_new_iterator = NULL;
|
||||
if (ZEND_MAP_PTR(class_type->iterator_funcs_ptr)) {
|
||||
iterator_funcs_ptr = ZEND_MAP_PTR_GET(class_type->iterator_funcs_ptr);
|
||||
ZEND_ASSERT(iterator_funcs_ptr);
|
||||
if (class_type->type == ZEND_USER_CLASS) {
|
||||
iterator_funcs_ptr->zf_new_iterator = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
} else if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
class_type->iterator_funcs_ptr = calloc(1, sizeof(zend_class_iterator_funcs));
|
||||
/* We can use pointer even in ZTS mode, because this structure is read-only */
|
||||
zend_class_iterator_funcs_ptr *iterator_funcs_ptr_ptr =
|
||||
calloc(1, sizeof(zend_class_iterator_funcs_ptr));
|
||||
ZEND_MAP_PTR_INIT(class_type->iterator_funcs_ptr, &iterator_funcs_ptr_ptr->ptr);
|
||||
iterator_funcs_ptr = &iterator_funcs_ptr_ptr->data;
|
||||
iterator_funcs_ptr_ptr->ptr = iterator_funcs_ptr;
|
||||
} else {
|
||||
class_type->iterator_funcs_ptr = zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs));
|
||||
memset(class_type->iterator_funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
|
||||
}
|
||||
if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
class_type->iterator_funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(&class_type->function_table, "getiterator", sizeof("getiterator") - 1);
|
||||
zend_class_iterator_funcs_ptr *iterator_funcs_ptr_ptr =
|
||||
zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs_ptr));
|
||||
iterator_funcs_ptr_ptr->ptr = &iterator_funcs_ptr_ptr->data;
|
||||
ZEND_MAP_PTR_INIT(class_type->iterator_funcs_ptr, &iterator_funcs_ptr_ptr->ptr);
|
||||
iterator_funcs_ptr = &iterator_funcs_ptr_ptr->data;
|
||||
iterator_funcs_ptr_ptr->ptr = iterator_funcs_ptr;
|
||||
memset(iterator_funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
|
||||
return SUCCESS;
|
||||
}
|
||||
iterator_funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(&class_type->function_table, "getiterator", sizeof("getiterator") - 1);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@ -358,6 +408,8 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
|
||||
/* {{{ zend_implement_iterator */
|
||||
static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry *class_type)
|
||||
{
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
if (class_type->get_iterator && class_type->get_iterator != zend_user_it_get_iterator) {
|
||||
if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
/* inheritance ensures the class has the necessary userland methods */
|
||||
@ -374,25 +426,39 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
|
||||
}
|
||||
}
|
||||
class_type->get_iterator = zend_user_it_get_iterator;
|
||||
if (class_type->iterator_funcs_ptr != NULL) {
|
||||
class_type->iterator_funcs_ptr->zf_valid = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_current = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_key = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_next = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_rewind = NULL;
|
||||
if (ZEND_MAP_PTR(class_type->iterator_funcs_ptr)) {
|
||||
iterator_funcs_ptr = ZEND_MAP_PTR_GET(class_type->iterator_funcs_ptr);
|
||||
ZEND_ASSERT(iterator_funcs_ptr);
|
||||
if (class_type->type == ZEND_USER_CLASS) {
|
||||
iterator_funcs_ptr->zf_valid = NULL;
|
||||
iterator_funcs_ptr->zf_current = NULL;
|
||||
iterator_funcs_ptr->zf_key = NULL;
|
||||
iterator_funcs_ptr->zf_next = NULL;
|
||||
iterator_funcs_ptr->zf_rewind = NULL;
|
||||
return SUCCESS;
|
||||
}
|
||||
} else if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
class_type->iterator_funcs_ptr = calloc(1, sizeof(zend_class_iterator_funcs));
|
||||
/* We can use pointer even in ZTS mode, because this structure is read-only */
|
||||
zend_class_iterator_funcs_ptr *iterator_funcs_ptr_ptr =
|
||||
calloc(1, sizeof(zend_class_iterator_funcs_ptr));
|
||||
ZEND_MAP_PTR_INIT(class_type->iterator_funcs_ptr, &iterator_funcs_ptr_ptr->ptr);
|
||||
iterator_funcs_ptr = &iterator_funcs_ptr_ptr->data;
|
||||
iterator_funcs_ptr_ptr->ptr = iterator_funcs_ptr;
|
||||
} else {
|
||||
class_type->iterator_funcs_ptr = zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs));
|
||||
memset(class_type->iterator_funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
|
||||
}
|
||||
if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
class_type->iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
|
||||
zend_class_iterator_funcs_ptr *iterator_funcs_ptr_ptr =
|
||||
zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs_ptr));
|
||||
iterator_funcs_ptr_ptr->ptr = &iterator_funcs_ptr_ptr->data;
|
||||
ZEND_MAP_PTR_INIT(class_type->iterator_funcs_ptr, &iterator_funcs_ptr_ptr->ptr);
|
||||
iterator_funcs_ptr = &iterator_funcs_ptr_ptr->data;
|
||||
iterator_funcs_ptr_ptr->ptr = iterator_funcs_ptr;
|
||||
memset(iterator_funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
|
||||
return SUCCESS;
|
||||
}
|
||||
iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
|
||||
iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
|
||||
iterator_funcs_ptr->zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
|
||||
iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
|
||||
iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
|
89
Zend/zend_map_ptr.h
Normal file
89
Zend/zend_map_ptr.h
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Zend Engine |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1998-2018 Zend Technologies Ltd. (http://www.zend.com) |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.00 of the Zend license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.zend.com/license/2_00.txt. |
|
||||
| If you did not receive a copy of the Zend license and are unable to |
|
||||
| obtain it through the world-wide-web, please send a note to |
|
||||
| license@zend.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Authors: Dmitry Stogov <dmitry@zend.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#ifndef ZEND_MAP_PTR_H
|
||||
#define ZEND_MAP_PTR_H
|
||||
|
||||
#include "zend_portability.h"
|
||||
|
||||
#define ZEND_MAP_PTR_KIND_PTR 0
|
||||
#define ZEND_MAP_PTR_KIND_PTR_OR_OFFSET 1
|
||||
|
||||
//#if defined(ZTS) || defined(TSRM_WIN32)
|
||||
# define ZEND_MAP_PTR_KIND ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
|
||||
//#else
|
||||
//# define ZEND_MAP_PTR_KIND ZEND_MAP_PTR_KIND_PTR
|
||||
//#endif
|
||||
|
||||
#if ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR
|
||||
# define ZEND_MAP_PTR(ptr) \
|
||||
ptr ## __ptr
|
||||
# define ZEND_MAP_PTR_DEF(type, name) \
|
||||
type * ZEND_MAP_PTR(name)
|
||||
# define ZEND_MAP_PTR_GET(ptr) \
|
||||
(*(ZEND_MAP_PTR(ptr)))
|
||||
# define ZEND_MAP_PTR_SET(ptr, val) do { \
|
||||
(*(ZEND_MAP_PTR(ptr))) = (val); \
|
||||
} while (0)
|
||||
# define ZEND_MAP_PTR_INIT(ptr, val) do { \
|
||||
ZEND_MAP_PTR(ptr) = (val); \
|
||||
} while (0)
|
||||
# define ZEND_MAP_PTR_NEW(ptr) do { \
|
||||
ZEND_MAP_PTR(ptr) = zend_map_ptr_new(); \
|
||||
} while (0)
|
||||
#elif ZEND_MAP_PTR_KIND == ZEND_MAP_PTR_KIND_PTR_OR_OFFSET
|
||||
# define ZEND_MAP_PTR(ptr) \
|
||||
ptr ## __ptr
|
||||
# define ZEND_MAP_PTR_DEF(type, name) \
|
||||
type * ZEND_MAP_PTR(name)
|
||||
# define ZEND_MAP_PTR_GET(ptr) \
|
||||
((((uintptr_t)ZEND_MAP_PTR(ptr)) & 1L) ? \
|
||||
*(void**)((char*)CG(map_ptr_base) + (uintptr_t)ZEND_MAP_PTR(ptr) - 1) : \
|
||||
(void*)(*(ZEND_MAP_PTR(ptr))))
|
||||
# define ZEND_MAP_PTR_SET(ptr, val) do { \
|
||||
if (((uintptr_t)ZEND_MAP_PTR(ptr)) & 1L) { \
|
||||
*(void**)((char*)CG(map_ptr_base) + (uintptr_t)ZEND_MAP_PTR(ptr) - 1) = (val); \
|
||||
} else { \
|
||||
*(ZEND_MAP_PTR(ptr)) = (val); \
|
||||
} \
|
||||
} while (0)
|
||||
# define ZEND_MAP_PTR_INIT(ptr, val) do { \
|
||||
ZEND_MAP_PTR(ptr) = (val); \
|
||||
} while (0)
|
||||
# define ZEND_MAP_PTR_NEW(ptr) do { \
|
||||
ZEND_MAP_PTR(ptr) = zend_map_ptr_new(); \
|
||||
} while (0)
|
||||
#else
|
||||
# error "Unknown ZEND_MAP_PTR_KIND"
|
||||
#endif
|
||||
|
||||
ZEND_API void zend_map_ptr_reset(void);
|
||||
ZEND_API void *zend_map_ptr_new(void);
|
||||
ZEND_API void zend_map_ptr_extend(size_t last);
|
||||
|
||||
#endif /* ZEND_MAP_PTR_H */
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
* c-basic-offset: 4
|
||||
* indent-tabs-mode: t
|
||||
* End:
|
||||
* vim600: sw=4 ts=4 fdm=marker
|
||||
* vim<600: sw=4 ts=4
|
||||
*/
|
@ -1139,6 +1139,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend
|
||||
size_t mname_len;
|
||||
zend_op_array *func;
|
||||
zend_function *fbc = is_static ? ce->__callstatic : ce->__call;
|
||||
static const void *dummy = (void*)(intptr_t)2;
|
||||
|
||||
ZEND_ASSERT(fbc);
|
||||
|
||||
@ -1157,7 +1158,7 @@ ZEND_API zend_function *zend_get_call_trampoline_func(zend_class_entry *ce, zend
|
||||
func->fn_flags |= ZEND_ACC_STATIC;
|
||||
}
|
||||
func->opcodes = &EG(call_trampoline_op);
|
||||
func->run_time_cache = (void*)(intptr_t)-1;
|
||||
ZEND_MAP_PTR_INIT(func->run_time_cache, (void***)&dummy);
|
||||
func->scope = fbc->common.scope;
|
||||
/* reserve space for arguments, local and temorary variables */
|
||||
func->T = (fbc->type == ZEND_USER_FUNCTION)? MAX(fbc->op_array.last_var + fbc->op_array.T, 2) : 2;
|
||||
@ -1352,11 +1353,7 @@ static void zend_intenal_class_init_statics(zend_class_entry *class_type) /* {{{
|
||||
zend_intenal_class_init_statics(class_type->parent);
|
||||
}
|
||||
|
||||
#if ZTS
|
||||
CG(static_members_table)[class_type->static_members_table_idx] = emalloc(sizeof(zval) * class_type->default_static_members_count);
|
||||
#else
|
||||
class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
|
||||
#endif
|
||||
ZEND_MAP_PTR_SET(class_type->static_members_table, emalloc(sizeof(zval) * class_type->default_static_members_count));
|
||||
for (i = 0; i < class_type->default_static_members_count; i++) {
|
||||
p = &class_type->default_static_members_table[i];
|
||||
if (Z_TYPE_P(p) == IS_INDIRECT) {
|
||||
@ -1370,6 +1367,11 @@ static void zend_intenal_class_init_statics(zend_class_entry *class_type) /* {{{
|
||||
}
|
||||
} /* }}} */
|
||||
|
||||
ZEND_API void zend_class_init_statics(zend_class_entry *class_type) /* {{{ */
|
||||
{
|
||||
zend_intenal_class_init_statics(class_type);
|
||||
} /* }}} */
|
||||
|
||||
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent) /* {{{ */
|
||||
{
|
||||
zend_property_info *property_info = zend_hash_find_ptr(&ce->properties_info, property_name);
|
||||
@ -1409,7 +1411,7 @@ ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *p
|
||||
|
||||
/* check if static properties were destroyed */
|
||||
if (UNEXPECTED(CE_STATIC_MEMBERS(ce) == NULL)) {
|
||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||
if (ce->type == ZEND_INTERNAL_CLASS || (ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
|
||||
zend_intenal_class_init_statics(ce);
|
||||
} else {
|
||||
undeclared_property:
|
||||
|
@ -198,6 +198,7 @@ extern const ZEND_API zend_object_handlers std_object_handlers;
|
||||
#define ZEND_PROPERTY_NOT_EMPTY ZEND_ISEMPTY /* Property is not empty */
|
||||
#define ZEND_PROPERTY_EXISTS 0x2 /* Property exists */
|
||||
|
||||
ZEND_API void zend_class_init_statics(zend_class_entry *ce);
|
||||
ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_string *function_name_strval, const zval *key);
|
||||
ZEND_API zval *zend_std_get_static_property(zend_class_entry *ce, zend_string *property_name, zend_bool silent);
|
||||
ZEND_API ZEND_COLD zend_bool zend_std_unset_static_property(zend_class_entry *ce, zend_string *property_name);
|
||||
|
@ -76,6 +76,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
|
||||
op_array->last_live_range = 0;
|
||||
|
||||
op_array->static_variables = NULL;
|
||||
ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
|
||||
op_array->last_try_catch = 0;
|
||||
|
||||
op_array->fn_flags = 0;
|
||||
@ -83,8 +84,8 @@ void init_op_array(zend_op_array *op_array, zend_uchar type, int initial_ops_siz
|
||||
op_array->last_literal = 0;
|
||||
op_array->literals = NULL;
|
||||
|
||||
op_array->run_time_cache = NULL;
|
||||
op_array->cache_size = 0;
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, NULL);
|
||||
op_array->cache_size = zend_op_array_extension_handles * sizeof(void*);
|
||||
|
||||
memset(op_array->reserved, 0, ZEND_MAX_RESERVED_RESOURCES * sizeof(void*));
|
||||
|
||||
@ -145,11 +146,7 @@ ZEND_API void zend_cleanup_internal_class_data(zend_class_entry *ce)
|
||||
zval *p = static_members;
|
||||
zval *end = p + ce->default_static_members_count;
|
||||
|
||||
#ifdef ZTS
|
||||
CG(static_members_table)[ce->static_members_table_idx] = NULL;
|
||||
#else
|
||||
ce->static_members_table = NULL;
|
||||
#endif
|
||||
ZEND_MAP_PTR_SET(ce->static_members_table, NULL);
|
||||
while (p != end) {
|
||||
i_zval_ptr_dtor(p);
|
||||
p++;
|
||||
@ -213,7 +210,21 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||
zend_class_entry *ce = Z_PTR_P(zv);
|
||||
zend_function *fn;
|
||||
|
||||
if (--ce->refcount > 0) {
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
zend_op_array *op_array;
|
||||
|
||||
if (ce->default_static_members_count) {
|
||||
zend_cleanup_internal_class_data(ce);
|
||||
}
|
||||
if (ce->ce_flags & ZEND_HAS_STATIC_IN_METHODS) {
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, op_array) {
|
||||
if (op_array->type == ZEND_USER_FUNCTION) {
|
||||
destroy_op_array(op_array);
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
return;
|
||||
} else if (--ce->refcount > 0) {
|
||||
return;
|
||||
}
|
||||
switch (ce->type) {
|
||||
@ -305,6 +316,9 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||
p++;
|
||||
}
|
||||
free(ce->default_static_members_table);
|
||||
if (ZEND_MAP_PTR(ce->static_members_table) != &ce->default_static_members_table) {
|
||||
zend_cleanup_internal_class_data(ce);
|
||||
}
|
||||
}
|
||||
zend_hash_destroy(&ce->properties_info);
|
||||
zend_string_release_ex(ce->name, 1);
|
||||
@ -333,8 +347,8 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
zend_hash_destroy(&ce->constants_table);
|
||||
}
|
||||
if (ce->iterator_funcs_ptr) {
|
||||
free(ce->iterator_funcs_ptr);
|
||||
if (ZEND_MAP_PTR(ce->iterator_funcs_ptr)) {
|
||||
free(ZEND_MAP_PTR(ce->iterator_funcs_ptr));
|
||||
}
|
||||
if (ce->num_interfaces > 0) {
|
||||
free(ce->interfaces);
|
||||
@ -355,17 +369,18 @@ ZEND_API void destroy_op_array(zend_op_array *op_array)
|
||||
{
|
||||
uint32_t i;
|
||||
|
||||
if (op_array->static_variables &&
|
||||
!(GC_FLAGS(op_array->static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
if (GC_DELREF(op_array->static_variables) == 0) {
|
||||
zend_array_destroy(op_array->static_variables);
|
||||
if (op_array->static_variables) {
|
||||
HashTable *ht = ZEND_MAP_PTR_GET(op_array->static_variables_ptr);
|
||||
if (ht && !(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
|
||||
if (GC_DELREF(ht) == 0) {
|
||||
zend_array_destroy(ht);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (op_array->run_time_cache
|
||||
&& (op_array->fn_flags & ZEND_ACC_HEAP_RT_CACHE)) {
|
||||
efree(op_array->run_time_cache);
|
||||
op_array->run_time_cache = NULL;
|
||||
if ((op_array->fn_flags & ZEND_ACC_HEAP_RT_CACHE)
|
||||
&& ZEND_MAP_PTR(op_array->run_time_cache)) {
|
||||
efree(ZEND_MAP_PTR(op_array->run_time_cache));
|
||||
}
|
||||
|
||||
if (!op_array->refcount || --(*op_array->refcount) > 0) {
|
||||
|
@ -3099,7 +3099,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -3220,7 +3220,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR,
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (OP2_TYPE != IS_CONST) {
|
||||
@ -3236,7 +3236,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, UNUSED|CLASS_FETCH|CONST|VAR,
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -3289,8 +3289,8 @@ ZEND_VM_HOT_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper, function_name, function_name);
|
||||
}
|
||||
fbc = Z_FUNC_P(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = init_func_run_time_cache_ex(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
CACHE_PTR(opline->result.num, fbc);
|
||||
}
|
||||
@ -3410,7 +3410,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV, NUM)
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!func->op_array.run_time_cache)) {
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
|
||||
init_func_run_time_cache(&func->op_array);
|
||||
}
|
||||
} else {
|
||||
@ -3453,8 +3453,8 @@ ZEND_VM_HOT_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST, NUM|CACHE_SLOT)
|
||||
}
|
||||
}
|
||||
fbc = Z_FUNC_P(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = init_func_run_time_cache_ex(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
CACHE_PTR(opline->result.num, fbc);
|
||||
}
|
||||
@ -3484,8 +3484,8 @@ ZEND_VM_HOT_HANDLER(61, ZEND_INIT_FCALL, NUM, CONST, NUM|CACHE_SLOT)
|
||||
ZEND_VM_DISPATCH_TO_HELPER(zend_undefined_function_helper, function_name, fname);
|
||||
}
|
||||
fbc = Z_FUNC_P(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = init_func_run_time_cache_ex(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
CACHE_PTR(opline->result.num, fbc);
|
||||
}
|
||||
@ -4963,7 +4963,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, UNUSED|CLASS_FETCH|CONST|VAR, UNUSED|CACHE_SLOT, N
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
|
||||
init_func_run_time_cache(&constructor->op_array);
|
||||
}
|
||||
/* We are not handling overloaded classes right now */
|
||||
@ -6993,20 +6993,10 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST, UNUSED)
|
||||
zval *zfunc;
|
||||
zval *object;
|
||||
zend_class_entry *called_scope;
|
||||
zend_function *fbc;
|
||||
|
||||
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
|
||||
|
||||
fbc = Z_PTR_P(zfunc);
|
||||
if (fbc->common.fn_flags & ZEND_ACC_IMMUTABLE) {
|
||||
zend_function *new_func = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
|
||||
|
||||
memcpy(new_func, fbc, sizeof(zend_op_array));
|
||||
new_func->common.fn_flags &= ~ZEND_ACC_IMMUTABLE;
|
||||
Z_PTR_P(zfunc) = fbc = new_func;
|
||||
}
|
||||
|
||||
if (Z_TYPE(EX(This)) == IS_OBJECT) {
|
||||
called_scope = Z_OBJCE(EX(This));
|
||||
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
|
||||
@ -7655,7 +7645,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY)
|
||||
fbc = call->func;
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
if (UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
execute_data = call;
|
||||
@ -7781,13 +7771,17 @@ ZEND_VM_HANDLER(183, ZEND_BIND_STATIC, CV, UNUSED, REF)
|
||||
variable_ptr = GET_OP1_ZVAL_PTR_PTR_UNDEF(BP_VAR_W);
|
||||
zval_ptr_dtor(variable_ptr);
|
||||
|
||||
ht = EX(func)->op_array.static_variables;
|
||||
ZEND_ASSERT(ht != NULL);
|
||||
if (GC_REFCOUNT(ht) > 1) {
|
||||
ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
|
||||
if (!ht) {
|
||||
ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_IMMUTABLE);
|
||||
ht = zend_array_dup(EX(func)->op_array.static_variables);
|
||||
ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
|
||||
} else if (GC_REFCOUNT(ht) > 1) {
|
||||
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_DELREF(ht);
|
||||
}
|
||||
EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
|
||||
ht = zend_array_dup(ht);
|
||||
ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
|
||||
}
|
||||
|
||||
value = (zval*)((char*)ht->arData + (opline->extended_value & ~ZEND_BIND_REF));
|
||||
|
@ -1908,7 +1908,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
|
||||
fbc = call->func;
|
||||
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION)) {
|
||||
if (UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
execute_data = call;
|
||||
@ -2026,8 +2026,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_BY_NAME
|
||||
ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(function_name ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
|
||||
}
|
||||
fbc = Z_FUNC_P(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = init_func_run_time_cache_ex(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
CACHE_PTR(opline->result.num, fbc);
|
||||
}
|
||||
@ -2115,8 +2115,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_NS_FCALL_BY_N
|
||||
}
|
||||
}
|
||||
fbc = Z_FUNC_P(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = init_func_run_time_cache_ex(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
CACHE_PTR(opline->result.num, fbc);
|
||||
}
|
||||
@ -2146,8 +2146,8 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_FCALL_SPEC_CO
|
||||
ZEND_VM_TAIL_CALL(zend_undefined_function_helper_SPEC(fname ZEND_OPCODE_HANDLER_ARGS_PASSTHRU_CC));
|
||||
}
|
||||
fbc = Z_FUNC_P(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
fbc = init_func_run_time_cache_ex(func);
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
CACHE_PTR(opline->result.num, fbc);
|
||||
}
|
||||
@ -5066,7 +5066,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -5186,7 +5186,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_CONST != IS_CONST) {
|
||||
@ -5202,7 +5202,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -5290,7 +5290,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!func->op_array.run_time_cache)) {
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
|
||||
init_func_run_time_cache(&func->op_array);
|
||||
}
|
||||
} else {
|
||||
@ -7242,7 +7242,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -7362,7 +7362,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
|
||||
@ -7378,7 +7378,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -7467,7 +7467,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!func->op_array.run_time_cache)) {
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
|
||||
init_func_run_time_cache(&func->op_array);
|
||||
}
|
||||
} else {
|
||||
@ -8595,7 +8595,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_UNUSED != IS_CONST) {
|
||||
@ -8611,7 +8611,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -8753,7 +8753,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_UNUSED_HANDLER(
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
|
||||
init_func_run_time_cache(&constructor->op_array);
|
||||
}
|
||||
/* We are not handling overloaded classes right now */
|
||||
@ -9102,20 +9102,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_DECLARE_LAMBDA_FUNCTION_SPEC_C
|
||||
zval *zfunc;
|
||||
zval *object;
|
||||
zend_class_entry *called_scope;
|
||||
zend_function *fbc;
|
||||
|
||||
zfunc = zend_hash_find_ex(EG(function_table), Z_STR_P(RT_CONSTANT(opline, opline->op1)), 1);
|
||||
ZEND_ASSERT(zfunc != NULL && Z_FUNC_P(zfunc)->type == ZEND_USER_FUNCTION);
|
||||
|
||||
fbc = Z_PTR_P(zfunc);
|
||||
if (fbc->common.fn_flags & ZEND_ACC_IMMUTABLE) {
|
||||
zend_function *new_func = zend_arena_alloc(&CG(arena), sizeof(zend_op_array));
|
||||
|
||||
memcpy(new_func, fbc, sizeof(zend_op_array));
|
||||
new_func->common.fn_flags &= ~ZEND_ACC_IMMUTABLE;
|
||||
Z_PTR_P(zfunc) = fbc = new_func;
|
||||
}
|
||||
|
||||
if (Z_TYPE(EX(This)) == IS_OBJECT) {
|
||||
called_scope = Z_OBJCE(EX(This));
|
||||
if (UNEXPECTED((Z_FUNC_P(zfunc)->common.fn_flags & ZEND_ACC_STATIC) ||
|
||||
@ -10338,7 +10328,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -10458,7 +10448,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_CV != IS_CONST) {
|
||||
@ -10474,7 +10464,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -10562,7 +10552,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!func->op_array.run_time_cache)) {
|
||||
if (EXPECTED(func->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&func->op_array))) {
|
||||
init_func_run_time_cache(&func->op_array);
|
||||
}
|
||||
} else {
|
||||
@ -14056,7 +14046,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -15666,7 +15656,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -17543,7 +17533,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -23691,7 +23681,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_CONST != IS_CONST) {
|
||||
@ -23707,7 +23697,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -26005,7 +25995,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
|
||||
@ -26021,7 +26011,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -27564,7 +27554,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_UNUSED != IS_CONST) {
|
||||
@ -27580,7 +27570,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -27722,7 +27712,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_UNUSED_HANDLER(ZE
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
|
||||
init_func_run_time_cache(&constructor->op_array);
|
||||
}
|
||||
/* We are not handling overloaded classes right now */
|
||||
@ -30002,7 +29992,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_CV != IS_CONST) {
|
||||
@ -30018,7 +30008,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -31969,7 +31959,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -32089,7 +32079,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_CONST != IS_CONST) {
|
||||
@ -32105,7 +32095,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -33700,7 +33690,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -33820,7 +33810,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if ((IS_TMP_VAR|IS_VAR) != IS_CONST) {
|
||||
@ -33836,7 +33826,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -34358,7 +34348,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_UNUSED != IS_CONST) {
|
||||
@ -34374,7 +34364,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -34516,7 +34506,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_UNUSED_UNUSED_HANDLER
|
||||
ZEND_CALL_FUNCTION, (zend_function *) &zend_pass_function,
|
||||
opline->extended_value, NULL, NULL);
|
||||
} else {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!constructor->op_array.run_time_cache)) {
|
||||
if (EXPECTED(constructor->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&constructor->op_array))) {
|
||||
init_func_run_time_cache(&constructor->op_array);
|
||||
}
|
||||
/* We are not handling overloaded classes right now */
|
||||
@ -36075,7 +36065,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -36195,7 +36185,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
EXPECTED(!(fbc->common.fn_flags & (ZEND_ACC_CALL_VIA_TRAMPOLINE|ZEND_ACC_NEVER_CACHE)))) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, ce, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
if (IS_CV != IS_CONST) {
|
||||
@ -36211,7 +36201,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_U
|
||||
HANDLE_EXCEPTION();
|
||||
}
|
||||
fbc = ce->constructor;
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -41082,7 +41072,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -44796,7 +44786,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
@ -47556,13 +47546,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_BIND_STATIC_SPEC_CV_UNUSED_HAN
|
||||
variable_ptr = EX_VAR(opline->op1.var);
|
||||
zval_ptr_dtor(variable_ptr);
|
||||
|
||||
ht = EX(func)->op_array.static_variables;
|
||||
ZEND_ASSERT(ht != NULL);
|
||||
if (GC_REFCOUNT(ht) > 1) {
|
||||
ht = ZEND_MAP_PTR_GET(EX(func)->op_array.static_variables_ptr);
|
||||
if (!ht) {
|
||||
ZEND_ASSERT(EX(func)->op_array.fn_flags & ZEND_ACC_IMMUTABLE);
|
||||
ht = zend_array_dup(EX(func)->op_array.static_variables);
|
||||
ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
|
||||
} else if (GC_REFCOUNT(ht) > 1) {
|
||||
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_DELREF(ht);
|
||||
}
|
||||
EX(func)->op_array.static_variables = ht = zend_array_dup(ht);
|
||||
ht = zend_array_dup(ht);
|
||||
ZEND_MAP_PTR_SET(EX(func)->op_array.static_variables_ptr, ht);
|
||||
}
|
||||
|
||||
value = (zval*)((char*)ht->arData + (opline->extended_value & ~ZEND_BIND_REF));
|
||||
@ -50643,7 +50637,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
|
||||
EXPECTED(obj == orig_obj)) {
|
||||
CACHE_POLYMORPHIC_PTR(opline->result.num, called_scope, fbc);
|
||||
}
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!fbc->op_array.run_time_cache)) {
|
||||
if (EXPECTED(fbc->type == ZEND_USER_FUNCTION) && UNEXPECTED(!RUN_TIME_CACHE(&fbc->op_array))) {
|
||||
init_func_run_time_cache(&fbc->op_array);
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "zend_constants.h"
|
||||
#include "zend_execute.h"
|
||||
#include "zend_vm.h"
|
||||
#include "zend_extensions.h"
|
||||
|
||||
#define DEBUG_COMPACT_LITERALS 0
|
||||
|
||||
@ -505,7 +506,7 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
method_slot = property_slot + j;
|
||||
|
||||
/* Update opcodes to use new literals table */
|
||||
cache_size = 0;
|
||||
cache_size = zend_op_array_extension_handles * sizeof(void*);
|
||||
opline = op_array->opcodes;
|
||||
end = opline + op_array->last;
|
||||
while (opline < end) {
|
||||
|
@ -1374,6 +1374,8 @@ static zend_persistent_script *store_script_in_file_cache(zend_persistent_script
|
||||
ZCG(mem) = zend_arena_alloc(&CG(arena), memory_used);
|
||||
#endif
|
||||
|
||||
zend_shared_alloc_clear_xlat_table();
|
||||
|
||||
/* Copy into memory block */
|
||||
new_persistent_script = zend_accel_script_persist(new_persistent_script, NULL, 0, 0);
|
||||
|
||||
@ -1539,6 +1541,8 @@ static zend_persistent_script *cache_script_in_shared_memory(zend_persistent_scr
|
||||
return new_persistent_script;
|
||||
}
|
||||
|
||||
zend_shared_alloc_clear_xlat_table();
|
||||
|
||||
/* Copy into shared memory */
|
||||
new_persistent_script = zend_accel_script_persist(new_persistent_script, &key, key_length, 1);
|
||||
|
||||
@ -2278,6 +2282,7 @@ static void zend_reset_cache_vars(void)
|
||||
ZSMMG(wasted_shared_memory) = 0;
|
||||
ZCSG(restart_pending) = 0;
|
||||
ZCSG(force_restart_time) = 0;
|
||||
ZCSG(map_ptr_last) = CG(map_ptr_last);
|
||||
}
|
||||
|
||||
static void accel_reset_pcre_cache(void)
|
||||
@ -2374,6 +2379,7 @@ int accel_activate(INIT_FUNC_ARGS)
|
||||
}
|
||||
accel_restart_enter();
|
||||
|
||||
zend_map_ptr_reset();
|
||||
zend_reset_cache_vars();
|
||||
zend_accel_hash_clean(&ZCSG(hash));
|
||||
|
||||
@ -2561,7 +2567,6 @@ static int zend_accel_init_shm(void)
|
||||
ZCSG(last_restart_time) = 0;
|
||||
ZCSG(restart_in_progress) = 0;
|
||||
|
||||
|
||||
for (i = 0; i < -HT_MIN_MASK; i++) {
|
||||
ZCSG(uninitialized_bucket)[i] = HT_INVALID_IDX;
|
||||
}
|
||||
|
@ -240,6 +240,7 @@ typedef struct _zend_accel_globals {
|
||||
void *mem;
|
||||
void *arena_mem;
|
||||
zend_persistent_script *current_persistent_script;
|
||||
zend_bool is_immutable_class;
|
||||
/* cache to save hash lookup on the same INCLUDE opcode */
|
||||
const zend_op *cache_opline;
|
||||
zend_persistent_script *cache_persistent_script;
|
||||
@ -267,6 +268,8 @@ typedef struct _zend_accel_shared_globals {
|
||||
zend_ulong manual_restarts; /* number of restarts scheduled by opcache_reset() */
|
||||
zend_accel_hash hash; /* hash table for cached scripts */
|
||||
|
||||
size_t map_ptr_last;
|
||||
|
||||
/* Directives & Maintenance */
|
||||
time_t start_time;
|
||||
time_t last_restart_time;
|
||||
|
@ -126,11 +126,14 @@ static void zend_hash_clone_constants(HashTable *ht, HashTable *source)
|
||||
end = p + ht->nNumUsed;
|
||||
for (; p != end; p++) {
|
||||
ZEND_ASSERT(Z_TYPE(p->val) != IS_UNDEF);
|
||||
c = ARENA_REALLOC(Z_PTR(p->val));
|
||||
Z_PTR(p->val) = c;
|
||||
c = Z_PTR(p->val);
|
||||
if (IN_ARENA(c)) {
|
||||
c = ARENA_REALLOC(c);
|
||||
Z_PTR(p->val) = c;
|
||||
|
||||
if (IN_ARENA(c->ce)) {
|
||||
c->ce = ARENA_REALLOC(c->ce);
|
||||
if (IN_ARENA(c->ce)) {
|
||||
c->ce = ARENA_REALLOC(c->ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -162,16 +165,21 @@ static void zend_hash_clone_methods(HashTable *ht, HashTable *source, zend_class
|
||||
end = p + ht->nNumUsed;
|
||||
for (; p != end; p++) {
|
||||
ZEND_ASSERT(Z_TYPE(p->val) != IS_UNDEF);
|
||||
new_entry = ARENA_REALLOC(Z_PTR(p->val));
|
||||
Z_PTR(p->val) = new_entry;
|
||||
new_entry = Z_PTR(p->val);
|
||||
if (IN_ARENA(new_entry)) {
|
||||
new_entry = ARENA_REALLOC(new_entry);
|
||||
Z_PTR(p->val) = new_entry;
|
||||
|
||||
if (IN_ARENA(new_entry->scope)) {
|
||||
new_entry->scope = ARENA_REALLOC(new_entry->scope);
|
||||
if (IN_ARENA(new_entry->scope)) {
|
||||
new_entry->scope = ARENA_REALLOC(new_entry->scope);
|
||||
|
||||
/* update prototype */
|
||||
if (new_entry->prototype) {
|
||||
new_entry->prototype = ARENA_REALLOC(new_entry->prototype);
|
||||
/* update prototype */
|
||||
if (IN_ARENA(new_entry->prototype)) {
|
||||
new_entry->prototype = ARENA_REALLOC(new_entry->prototype);
|
||||
}
|
||||
}
|
||||
ZEND_MAP_PTR_INIT(new_entry->run_time_cache, ARENA_REALLOC(ZEND_MAP_PTR(new_entry->run_time_cache)));
|
||||
ZEND_MAP_PTR_INIT(new_entry->static_variables_ptr, &new_entry->static_variables);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -203,11 +211,14 @@ static void zend_hash_clone_prop_info(HashTable *ht, HashTable *source, zend_cla
|
||||
end = p + ht->nNumUsed;
|
||||
for (; p != end; p++) {
|
||||
ZEND_ASSERT(Z_TYPE(p->val) != IS_UNDEF);
|
||||
prop_info = ARENA_REALLOC(Z_PTR(p->val));
|
||||
Z_PTR(p->val) = prop_info;
|
||||
prop_info = Z_PTR(p->val);
|
||||
if (IN_ARENA(prop_info)) {
|
||||
prop_info = ARENA_REALLOC(prop_info);
|
||||
Z_PTR(p->val) = prop_info;
|
||||
|
||||
if (IN_ARENA(prop_info->ce)) {
|
||||
prop_info->ce = ARENA_REALLOC(prop_info->ce);
|
||||
if (IN_ARENA(prop_info->ce)) {
|
||||
prop_info->ce = ARENA_REALLOC(prop_info->ce);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -229,7 +240,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
|
||||
*pce = ce = ARENA_REALLOC(old_ce);
|
||||
ce->refcount = 1;
|
||||
|
||||
if (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
if ((ce->ce_flags & ZEND_ACC_LINKED) && IN_ARENA(ce->parent)) {
|
||||
ce->parent = ARENA_REALLOC(ce->parent);
|
||||
}
|
||||
|
||||
@ -271,7 +282,7 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
|
||||
parent = parent->parent;
|
||||
}
|
||||
}
|
||||
ce->static_members_table = ce->default_static_members_table;
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
|
||||
/* properties_info */
|
||||
zend_hash_clone_prop_info(&ce->properties_info, &old_ce->properties_info, old_ce);
|
||||
@ -282,10 +293,23 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
|
||||
if (ce->num_interfaces) {
|
||||
zend_class_name *interface_names;
|
||||
|
||||
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
|
||||
interface_names = emalloc(sizeof(zend_class_name) * ce->num_interfaces);
|
||||
memcpy(interface_names, ce->interface_names, sizeof(zend_class_name) * ce->num_interfaces);
|
||||
ce->interface_names = interface_names;
|
||||
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
interface_names = emalloc(sizeof(zend_class_name) * ce->num_interfaces);
|
||||
memcpy(interface_names, ce->interface_names, sizeof(zend_class_name) * ce->num_interfaces);
|
||||
ce->interface_names = interface_names;
|
||||
} else {
|
||||
zend_class_entry **interfaces = emalloc(sizeof(zend_class_entry*) * ce->num_interfaces);
|
||||
uint32_t i;
|
||||
|
||||
for (i = 0; i < ce->num_interfaces; i++) {
|
||||
if (IN_ARENA(ce->interfaces[i])) {
|
||||
interfaces[i] = ARENA_REALLOC(ce->interfaces[i]);
|
||||
} else {
|
||||
interfaces[i] = ce->interfaces[i];
|
||||
}
|
||||
}
|
||||
ce->interfaces = interfaces;
|
||||
}
|
||||
}
|
||||
|
||||
zend_update_inherited_handler(constructor);
|
||||
@ -349,6 +373,11 @@ static void zend_class_copy_ctor(zend_class_entry **pce)
|
||||
ce->trait_precedences = trait_precedences;
|
||||
}
|
||||
}
|
||||
|
||||
if (ZEND_MAP_PTR(ce->iterator_funcs_ptr)) {
|
||||
ZEND_MAP_PTR_INIT(ce->iterator_funcs_ptr, ARENA_REALLOC(ZEND_MAP_PTR(ce->iterator_funcs_ptr)));
|
||||
ZEND_MAP_PTR_SET(ce->iterator_funcs_ptr, ARENA_REALLOC(ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr)));
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_accel_function_hash_copy(HashTable *target, HashTable *source)
|
||||
@ -507,7 +536,9 @@ static void zend_accel_class_hash_copy_from_shm(HashTable *target, HashTable *so
|
||||
}
|
||||
} else {
|
||||
t = _zend_hash_append_ptr_ex(target, p->key, Z_PTR(p->val), 1);
|
||||
zend_class_copy_ctor((zend_class_entry**)&Z_PTR_P(t));
|
||||
if (!(((zend_class_entry*)Z_PTR_P(t))->ce_flags & ZEND_ACC_IMMUTABLE)) {
|
||||
zend_class_copy_ctor((zend_class_entry**)&Z_PTR_P(t));
|
||||
}
|
||||
}
|
||||
}
|
||||
target->nInternalPointer = 0;
|
||||
@ -668,6 +699,7 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
|
||||
|
||||
op_array = (zend_op_array *) emalloc(sizeof(zend_op_array));
|
||||
*op_array = persistent_script->script.main_op_array;
|
||||
ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
|
||||
|
||||
if (EXPECTED(from_shared_memory)) {
|
||||
zend_hash_init(&ZCG(bind_hash), 10, NULL, NULL, 0);
|
||||
@ -712,6 +744,7 @@ zend_op_array* zend_accel_load_script(zend_persistent_script *persistent_script,
|
||||
|
||||
zend_hash_destroy(&ZCG(bind_hash));
|
||||
ZCG(current_persistent_script) = NULL;
|
||||
zend_map_ptr_extend(ZCSG(map_ptr_last));
|
||||
} else /* if (!from_shared_memory) */ {
|
||||
if (zend_hash_num_elements(&persistent_script->script.function_table) > 0) {
|
||||
zend_accel_function_hash_copy(CG(function_table), &persistent_script->script.function_table);
|
||||
|
@ -534,6 +534,13 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
|
||||
SERIALIZE_STR(op_array->doc_comment);
|
||||
SERIALIZE_PTR(op_array->try_catch_array);
|
||||
SERIALIZE_PTR(op_array->prototype);
|
||||
|
||||
ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
|
||||
if (op_array->fn_flags & ZEND_ACC_IMMUTABLE) {
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, NULL);
|
||||
} else {
|
||||
SERIALIZE_PTR(ZEND_MAP_PTR(op_array->run_time_cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -749,6 +756,15 @@ static void zend_file_cache_serialize_class(zval *zv,
|
||||
SERIALIZE_PTR(ce->__tostring);
|
||||
SERIALIZE_PTR(ce->__callstatic);
|
||||
SERIALIZE_PTR(ce->__debugInfo);
|
||||
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
if (ZEND_MAP_PTR(ce->iterator_funcs_ptr)) {
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
ZEND_MAP_PTR_INIT(ce->iterator_funcs_ptr, (void*)(uintptr_t)1);
|
||||
} else {
|
||||
SERIALIZE_PTR(ZEND_MAP_PTR(ce->iterator_funcs_ptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_file_cache_serialize(zend_persistent_script *script,
|
||||
@ -1183,6 +1199,18 @@ static void zend_file_cache_unserialize_op_array(zend_op_array *op_arr
|
||||
UNSERIALIZE_STR(op_array->doc_comment);
|
||||
UNSERIALIZE_PTR(op_array->try_catch_array);
|
||||
UNSERIALIZE_PTR(op_array->prototype);
|
||||
|
||||
if (op_array->fn_flags & ZEND_ACC_IMMUTABLE) {
|
||||
if (op_array->static_variables) {
|
||||
ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
|
||||
}
|
||||
ZEND_MAP_PTR_NEW(op_array->run_time_cache);
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
|
||||
UNSERIALIZE_PTR(ZEND_MAP_PTR(op_array->run_time_cache));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1384,6 +1412,20 @@ static void zend_file_cache_unserialize_class(zval *zv,
|
||||
ce->serialize = zend_class_serialize_deny;
|
||||
ce->unserialize = zend_class_unserialize_deny;
|
||||
}
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
if (ce->default_static_members_table) {
|
||||
ZEND_MAP_PTR_NEW(ce->static_members_table);
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
}
|
||||
if (ZEND_MAP_PTR(ce->iterator_funcs_ptr)) {
|
||||
ZEND_MAP_PTR_NEW(ce->iterator_funcs_ptr);
|
||||
}
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
UNSERIALIZE_PTR(ZEND_MAP_PTR(ce->iterator_funcs_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_file_cache_unserialize(zend_persistent_script *script,
|
||||
@ -1546,6 +1588,7 @@ zend_persistent_script *zend_file_cache_script_load(zend_file_handle *file_handl
|
||||
goto use_process_mem;
|
||||
}
|
||||
memcpy(buf, mem, info.mem_size);
|
||||
zend_map_ptr_extend(ZCSG(map_ptr_last));
|
||||
} else {
|
||||
use_process_mem:
|
||||
buf = mem;
|
||||
@ -1576,6 +1619,7 @@ use_process_mem:
|
||||
script->corrupted = 0;
|
||||
|
||||
if (cache_it) {
|
||||
ZCSG(map_ptr_last) = CG(map_ptr_last);
|
||||
script->dynamic_members.checksum = zend_accel_script_checksum(script);
|
||||
script->dynamic_members.last_used = ZCG(request_time);
|
||||
|
||||
|
@ -391,9 +391,14 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
||||
GC_TYPE_INFO(op_array->static_variables) = IS_ARRAY | (IS_ARRAY_IMMUTABLE << GC_FLAGS_SHIFT);
|
||||
}
|
||||
}
|
||||
ZEND_MAP_PTR_INIT(op_array->static_variables_ptr, &op_array->static_variables);
|
||||
|
||||
if (op_array->scope) {
|
||||
op_array->scope = zend_shared_alloc_get_xlat_entry(op_array->scope);
|
||||
zend_class_entry *scope = zend_shared_alloc_get_xlat_entry(op_array->scope);
|
||||
|
||||
if (scope) {
|
||||
op_array->scope = scope;
|
||||
}
|
||||
if (op_array->prototype) {
|
||||
zend_function *ptr = zend_shared_alloc_get_xlat_entry(op_array->prototype);
|
||||
|
||||
@ -557,7 +562,7 @@ static void zend_persist_op_array_ex(zend_op_array *op_array, zend_persistent_sc
|
||||
|
||||
efree(op_array->opcodes);
|
||||
op_array->opcodes = new_opcodes;
|
||||
op_array->run_time_cache = NULL;
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, NULL);
|
||||
}
|
||||
|
||||
if (op_array->function_name && !IS_ACCEL_INTERNED(op_array->function_name)) {
|
||||
@ -633,11 +638,19 @@ static void zend_persist_op_array(zval *zv)
|
||||
zend_op_array *op_array = Z_PTR_P(zv);
|
||||
|
||||
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
|
||||
memcpy(ZCG(mem), Z_PTR_P(zv), sizeof(zend_op_array));
|
||||
Z_PTR_P(zv) = ZCG(mem);
|
||||
ZCG(mem) = (void*)((char*)ZCG(mem) + ZEND_ALIGNED_SIZE(sizeof(zend_op_array)));
|
||||
zend_persist_op_array_ex(Z_PTR_P(zv), NULL);
|
||||
((zend_op_array*)Z_PTR_P(zv))->fn_flags |= ZEND_ACC_IMMUTABLE;
|
||||
op_array = Z_PTR_P(zv) = zend_shared_memdup(Z_PTR_P(zv), sizeof(zend_op_array));
|
||||
zend_persist_op_array_ex(op_array, NULL);
|
||||
if (!ZCG(current_persistent_script)->corrupted) {
|
||||
op_array->fn_flags |= ZEND_ACC_IMMUTABLE;
|
||||
ZEND_MAP_PTR_NEW(op_array->run_time_cache);
|
||||
if (op_array->static_variables) {
|
||||
ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
|
||||
}
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, ZCG(arena_mem));
|
||||
ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(sizeof(void*)));
|
||||
ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_persist_class_method(zval *zv)
|
||||
@ -645,7 +658,35 @@ static void zend_persist_class_method(zval *zv)
|
||||
zend_op_array *op_array = Z_PTR_P(zv);
|
||||
zend_op_array *old_op_array;
|
||||
|
||||
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
|
||||
if (op_array->type != ZEND_USER_FUNCTION) {
|
||||
ZEND_ASSERT(op_array->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (op_array->fn_flags & ZEND_ACC_ARENA_ALLOCATED) {
|
||||
old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
|
||||
if (old_op_array) {
|
||||
Z_PTR_P(zv) = old_op_array;
|
||||
} else {
|
||||
if (ZCG(is_immutable_class)) {
|
||||
op_array = Z_PTR_P(zv) = zend_shared_memdup_put(op_array, sizeof(zend_internal_function));
|
||||
} else {
|
||||
op_array = Z_PTR_P(zv) = zend_shared_memdup_arena_put(op_array, sizeof(zend_internal_function));
|
||||
}
|
||||
if (op_array->scope) {
|
||||
void *persist_ptr;
|
||||
|
||||
if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->scope))) {
|
||||
op_array->scope = (zend_class_entry*)persist_ptr;
|
||||
}
|
||||
if (op_array->prototype) {
|
||||
if ((persist_ptr = zend_shared_alloc_get_xlat_entry(op_array->prototype))) {
|
||||
op_array->prototype = (zend_function*)persist_ptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
|
||||
if (old_op_array) {
|
||||
Z_PTR_P(zv) = old_op_array;
|
||||
@ -654,11 +695,23 @@ static void zend_persist_class_method(zval *zv)
|
||||
}
|
||||
return;
|
||||
}
|
||||
memcpy(ZCG(arena_mem), Z_PTR_P(zv), sizeof(zend_op_array));
|
||||
zend_shared_alloc_register_xlat_entry(Z_PTR_P(zv), ZCG(arena_mem));
|
||||
Z_PTR_P(zv) = ZCG(arena_mem);
|
||||
ZCG(arena_mem) = (void*)((char*)ZCG(arena_mem) + ZEND_ALIGNED_SIZE(sizeof(zend_op_array)));
|
||||
zend_persist_op_array_ex(Z_PTR_P(zv), NULL);
|
||||
if (ZCG(is_immutable_class)) {
|
||||
op_array = Z_PTR_P(zv) = zend_shared_memdup_put(op_array, sizeof(zend_op_array));
|
||||
} else {
|
||||
op_array = Z_PTR_P(zv) = zend_shared_memdup_arena_put(op_array, sizeof(zend_op_array));
|
||||
}
|
||||
zend_persist_op_array_ex(op_array, NULL);
|
||||
if (ZCG(is_immutable_class)) {
|
||||
op_array->fn_flags |= ZEND_ACC_IMMUTABLE;
|
||||
ZEND_MAP_PTR_NEW(op_array->run_time_cache);
|
||||
if (op_array->static_variables) {
|
||||
ZEND_MAP_PTR_NEW(op_array->static_variables_ptr);
|
||||
}
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(op_array->run_time_cache, ZCG(arena_mem));
|
||||
ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(sizeof(void*)));
|
||||
ZEND_MAP_PTR_SET(op_array->run_time_cache, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_persist_property_info(zval *zv)
|
||||
@ -669,10 +722,11 @@ static void zend_persist_property_info(zval *zv)
|
||||
Z_PTR_P(zv) = prop;
|
||||
return;
|
||||
}
|
||||
memcpy(ZCG(arena_mem), Z_PTR_P(zv), sizeof(zend_property_info));
|
||||
zend_shared_alloc_register_xlat_entry(Z_PTR_P(zv), ZCG(arena_mem));
|
||||
prop = Z_PTR_P(zv) = ZCG(arena_mem);
|
||||
ZCG(arena_mem) = (void*)((char*)ZCG(arena_mem) + ZEND_ALIGNED_SIZE(sizeof(zend_property_info)));
|
||||
if (ZCG(is_immutable_class)) {
|
||||
prop = Z_PTR_P(zv) = zend_shared_memdup_put(Z_PTR_P(zv), sizeof(zend_property_info));
|
||||
} else {
|
||||
prop = Z_PTR_P(zv) = zend_shared_memdup_arena_put(Z_PTR_P(zv), sizeof(zend_property_info));
|
||||
}
|
||||
prop->ce = zend_shared_alloc_get_xlat_entry(prop->ce);
|
||||
zend_accel_store_interned_string(prop->name);
|
||||
if (prop->doc_comment) {
|
||||
@ -696,10 +750,11 @@ static void zend_persist_class_constant(zval *zv)
|
||||
Z_PTR_P(zv) = c;
|
||||
return;
|
||||
}
|
||||
memcpy(ZCG(arena_mem), Z_PTR_P(zv), sizeof(zend_class_constant));
|
||||
zend_shared_alloc_register_xlat_entry(Z_PTR_P(zv), ZCG(arena_mem));
|
||||
c = Z_PTR_P(zv) = ZCG(arena_mem);
|
||||
ZCG(arena_mem) = (void*)((char*)ZCG(arena_mem) + ZEND_ALIGNED_SIZE(sizeof(zend_class_constant)));
|
||||
if (ZCG(is_immutable_class)) {
|
||||
c = Z_PTR_P(zv) = zend_shared_memdup_put(Z_PTR_P(zv), sizeof(zend_class_constant));
|
||||
} else {
|
||||
c = Z_PTR_P(zv) = zend_shared_memdup_arena_put(Z_PTR_P(zv), sizeof(zend_class_constant));
|
||||
}
|
||||
zend_persist_zval(&c->value);
|
||||
c->ce = zend_shared_alloc_get_xlat_entry(c->ce);
|
||||
if (c->doc_comment) {
|
||||
@ -726,10 +781,16 @@ static void zend_persist_class_entry(zval *zv)
|
||||
zend_class_entry *ce = Z_PTR_P(zv);
|
||||
|
||||
if (ce->type == ZEND_USER_CLASS) {
|
||||
memcpy(ZCG(arena_mem), Z_PTR_P(zv), sizeof(zend_class_entry));
|
||||
zend_shared_alloc_register_xlat_entry(Z_PTR_P(zv), ZCG(arena_mem));
|
||||
ce = Z_PTR_P(zv) = ZCG(arena_mem);
|
||||
ZCG(arena_mem) = (void*)((char*)ZCG(arena_mem) + ZEND_ALIGNED_SIZE(sizeof(zend_class_entry)));
|
||||
if ((ce->ce_flags & ZEND_ACC_LINKED)
|
||||
&& (ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)
|
||||
&& !ZCG(current_persistent_script)->corrupted) {
|
||||
ZCG(is_immutable_class) = 1;
|
||||
ce = Z_PTR_P(zv) = zend_shared_memdup_put(ce, sizeof(zend_class_entry));
|
||||
ce->ce_flags |= ZEND_ACC_IMMUTABLE;
|
||||
} else {
|
||||
ZCG(is_immutable_class) = 0;
|
||||
ce = Z_PTR_P(zv) = zend_shared_memdup_arena_put(ce, sizeof(zend_class_entry));
|
||||
}
|
||||
zend_accel_store_interned_string(ce->name);
|
||||
if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
zend_accel_store_interned_string(ce->parent_name);
|
||||
@ -754,8 +815,14 @@ static void zend_persist_class_entry(zval *zv)
|
||||
for (; i < ce->default_static_members_count; i++) {
|
||||
zend_persist_zval(&ce->default_static_members_table[i]);
|
||||
}
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
ZEND_MAP_PTR_NEW(ce->static_members_table);
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
}
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
}
|
||||
ce->static_members_table = NULL;
|
||||
|
||||
zend_hash_persist(&ce->constants_table, zend_persist_class_constant);
|
||||
HT_FLAGS(&ce->constants_table) &= (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS);
|
||||
@ -778,10 +845,9 @@ static void zend_persist_class_entry(zval *zv)
|
||||
zend_hash_persist(&ce->properties_info, zend_persist_property_info);
|
||||
HT_FLAGS(&ce->properties_info) &= (HASH_FLAG_INITIALIZED | HASH_FLAG_STATIC_KEYS);
|
||||
|
||||
if (ce->num_interfaces) {
|
||||
if (ce->num_interfaces && !(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
uint32_t i = 0;
|
||||
|
||||
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
|
||||
for (i = 0; i < ce->num_interfaces; i++) {
|
||||
zend_accel_store_interned_string(ce->interface_names[i].name);
|
||||
zend_accel_store_interned_string(ce->interface_names[i].lc_name);
|
||||
@ -838,6 +904,16 @@ static void zend_persist_class_entry(zval *zv)
|
||||
ce->trait_precedences, sizeof(zend_trait_precedence*) * (i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (ZEND_MAP_PTR(ce->iterator_funcs_ptr)) {
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE) {
|
||||
ZEND_MAP_PTR_NEW(ce->iterator_funcs_ptr);
|
||||
} else {
|
||||
ZEND_MAP_PTR_INIT(ce->iterator_funcs_ptr, ZCG(arena_mem));
|
||||
ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(sizeof(void*)));
|
||||
ZEND_MAP_PTR_SET(ce->iterator_funcs_ptr, zend_shared_memdup_arena(ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr), sizeof(zend_class_iterator_funcs)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -853,8 +929,45 @@ static int zend_update_parent_ce(zval *zv)
|
||||
{
|
||||
zend_class_entry *ce = Z_PTR_P(zv);
|
||||
|
||||
if (ce->parent && (ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
ce->parent = zend_shared_alloc_get_xlat_entry(ce->parent);
|
||||
if (ce->ce_flags & ZEND_ACC_LINKED) {
|
||||
if (ce->parent) {
|
||||
int i, end;
|
||||
zend_class_entry *parent = ce->parent;
|
||||
|
||||
if (parent->type == ZEND_USER_CLASS) {
|
||||
zend_class_entry *p = zend_shared_alloc_get_xlat_entry(parent);
|
||||
|
||||
if (p) {
|
||||
ce->parent = parent = p;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create indirections to static properties from parent classes */
|
||||
i = parent->default_static_members_count - 1;
|
||||
while (parent && parent->default_static_members_table) {
|
||||
end = parent->parent ? parent->parent->default_static_members_count : 0;
|
||||
for (; i >= end; i--) {
|
||||
zval *p = &ce->default_static_members_table[i];
|
||||
ZVAL_INDIRECT(p, &parent->default_static_members_table[i]);
|
||||
}
|
||||
|
||||
parent = parent->parent;
|
||||
}
|
||||
}
|
||||
|
||||
if (ce->num_interfaces) {
|
||||
uint32_t i = 0;
|
||||
|
||||
ce->interfaces = zend_shared_memdup_free(ce->interfaces, sizeof(zend_class_entry*) * ce->num_interfaces);
|
||||
for (i = 0; i < ce->num_interfaces; i++) {
|
||||
if (ce->interfaces[i]->type == ZEND_USER_CLASS) {
|
||||
zend_class_entry *tmp = zend_shared_alloc_get_xlat_entry(ce->interfaces[i]);
|
||||
if (tmp != NULL) {
|
||||
ce->interfaces[i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update methods */
|
||||
@ -912,7 +1025,6 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
|
||||
script->mem = ZCG(mem);
|
||||
|
||||
ZEND_ASSERT(((zend_uintptr_t)ZCG(mem) & 0x7) == 0); /* should be 8 byte aligned */
|
||||
zend_shared_alloc_clear_xlat_table();
|
||||
|
||||
script = zend_shared_memdup_free(script, sizeof(zend_persistent_script));
|
||||
if (key && *key) {
|
||||
@ -939,10 +1051,14 @@ zend_persistent_script *zend_accel_script_persist(zend_persistent_script *script
|
||||
script->arena_mem = ZCG(arena_mem) = ZCG(mem);
|
||||
ZCG(mem) = (void*)((char*)ZCG(mem) + script->arena_size);
|
||||
|
||||
zend_map_ptr_extend(ZCSG(map_ptr_last));
|
||||
|
||||
zend_accel_persist_class_table(&script->script.class_table);
|
||||
zend_hash_persist(&script->script.function_table, zend_persist_op_array);
|
||||
zend_persist_op_array_ex(&script->script.main_op_array, script);
|
||||
|
||||
ZCSG(map_ptr_last) = CG(map_ptr_last);
|
||||
|
||||
script->corrupted = 0;
|
||||
ZCG(current_persistent_script) = NULL;
|
||||
|
||||
|
@ -28,8 +28,15 @@
|
||||
|
||||
#define ADD_DUP_SIZE(m,s) ZCG(current_persistent_script)->size += zend_shared_memdup_size((void*)m, s)
|
||||
#define ADD_SIZE(m) ZCG(current_persistent_script)->size += ZEND_ALIGNED_SIZE(m)
|
||||
#define ADD_ARENA_SIZE(m) ZCG(current_persistent_script)->arena_size += ZEND_ALIGNED_SIZE(m)
|
||||
|
||||
#define ADD_ARENA_SIZE(m) ZCG(current_persistent_script)->arena_size += ZEND_ALIGNED_SIZE(m)
|
||||
#define ADD_SIZE_EX(m) do { \
|
||||
if (ZCG(is_immutable_class)) { \
|
||||
ADD_SIZE(m); \
|
||||
} else { \
|
||||
ADD_ARENA_SIZE(m); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
# define ADD_STRING(str) ADD_DUP_SIZE((str), _ZSTR_STRUCT_SIZE(ZSTR_LEN(str)))
|
||||
|
||||
@ -258,6 +265,9 @@ static void zend_persist_op_array_calc(zval *zv)
|
||||
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
|
||||
ADD_SIZE(sizeof(zend_op_array));
|
||||
zend_persist_op_array_calc_ex(Z_PTR_P(zv));
|
||||
if (ZCG(current_persistent_script)->corrupted) {
|
||||
ADD_ARENA_SIZE(sizeof(void*));
|
||||
}
|
||||
}
|
||||
|
||||
static void zend_persist_class_method_calc(zval *zv)
|
||||
@ -265,12 +275,26 @@ static void zend_persist_class_method_calc(zval *zv)
|
||||
zend_op_array *op_array = Z_PTR_P(zv);
|
||||
zend_op_array *old_op_array;
|
||||
|
||||
ZEND_ASSERT(op_array->type == ZEND_USER_FUNCTION);
|
||||
if (op_array->type != ZEND_USER_FUNCTION) {
|
||||
ZEND_ASSERT(op_array->type == ZEND_INTERNAL_FUNCTION);
|
||||
if (op_array->fn_flags & ZEND_ACC_ARENA_ALLOCATED) {
|
||||
old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
|
||||
if (!old_op_array) {
|
||||
ADD_SIZE_EX(sizeof(zend_internal_function));
|
||||
zend_shared_alloc_register_xlat_entry(op_array, Z_PTR_P(zv));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
old_op_array = zend_shared_alloc_get_xlat_entry(op_array);
|
||||
if (!old_op_array) {
|
||||
ADD_ARENA_SIZE(sizeof(zend_op_array));
|
||||
ADD_SIZE_EX(sizeof(zend_op_array));
|
||||
zend_persist_op_array_calc_ex(Z_PTR_P(zv));
|
||||
zend_shared_alloc_register_xlat_entry(op_array, Z_PTR_P(zv));
|
||||
if (!ZCG(is_immutable_class)) {
|
||||
ADD_ARENA_SIZE(sizeof(void*));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -280,7 +304,7 @@ static void zend_persist_property_info_calc(zval *zv)
|
||||
|
||||
if (!zend_shared_alloc_get_xlat_entry(prop)) {
|
||||
zend_shared_alloc_register_xlat_entry(prop, prop);
|
||||
ADD_ARENA_SIZE(sizeof(zend_property_info));
|
||||
ADD_SIZE_EX(sizeof(zend_property_info));
|
||||
ADD_INTERNED_STRING(prop->name, 0);
|
||||
if (ZCG(accel_directives).save_comments && prop->doc_comment) {
|
||||
ADD_STRING(prop->doc_comment);
|
||||
@ -294,7 +318,7 @@ static void zend_persist_class_constant_calc(zval *zv)
|
||||
|
||||
if (!zend_shared_alloc_get_xlat_entry(c)) {
|
||||
zend_shared_alloc_register_xlat_entry(c, c);
|
||||
ADD_ARENA_SIZE(sizeof(zend_class_constant));
|
||||
ADD_SIZE_EX(sizeof(zend_class_constant));
|
||||
zend_persist_zval_calc(&c->value);
|
||||
if (ZCG(accel_directives).save_comments && c->doc_comment) {
|
||||
ADD_STRING(c->doc_comment);
|
||||
@ -302,13 +326,17 @@ static void zend_persist_class_constant_calc(zval *zv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void zend_persist_class_entry_calc(zval *zv)
|
||||
{
|
||||
zend_class_entry *ce = Z_PTR_P(zv);
|
||||
|
||||
if (ce->type == ZEND_USER_CLASS) {
|
||||
ADD_ARENA_SIZE(sizeof(zend_class_entry));
|
||||
ZCG(is_immutable_class) =
|
||||
(ce->ce_flags & ZEND_ACC_LINKED) &&
|
||||
(ce->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) &&
|
||||
!ZCG(current_persistent_script)->corrupted;
|
||||
|
||||
ADD_SIZE_EX(sizeof(zend_class_entry));
|
||||
ADD_INTERNED_STRING(ce->name, 0);
|
||||
if (ce->parent_name && !(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
ADD_INTERNED_STRING(ce->parent_name, 0);
|
||||
@ -346,12 +374,15 @@ static void zend_persist_class_entry_calc(zval *zv)
|
||||
if (ce->num_interfaces) {
|
||||
uint32_t i;
|
||||
|
||||
ZEND_ASSERT(!(ce->ce_flags & ZEND_ACC_LINKED));
|
||||
for (i = 0; i < ce->num_interfaces; i++) {
|
||||
ADD_INTERNED_STRING(ce->interface_names[i].name, 0);
|
||||
ADD_INTERNED_STRING(ce->interface_names[i].lc_name, 0);
|
||||
if (!(ce->ce_flags & ZEND_ACC_LINKED)) {
|
||||
for (i = 0; i < ce->num_interfaces; i++) {
|
||||
ADD_INTERNED_STRING(ce->interface_names[i].name, 0);
|
||||
ADD_INTERNED_STRING(ce->interface_names[i].lc_name, 0);
|
||||
}
|
||||
ADD_SIZE(sizeof(zend_class_name) * ce->num_interfaces);
|
||||
} else {
|
||||
ADD_SIZE(sizeof(zend_class_entry*) * ce->num_interfaces);
|
||||
}
|
||||
ADD_SIZE(sizeof(zend_class_name) * ce->num_interfaces);
|
||||
}
|
||||
|
||||
if (ce->num_traits) {
|
||||
@ -399,6 +430,13 @@ static void zend_persist_class_entry_calc(zval *zv)
|
||||
ADD_SIZE(sizeof(zend_trait_precedence*) * (i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
if (ZEND_MAP_PTR(ce->iterator_funcs_ptr)) {
|
||||
if (!ZCG(is_immutable_class)) {
|
||||
ADD_ARENA_SIZE(sizeof(void*));
|
||||
ADD_ARENA_SIZE(sizeof(zend_class_iterator_funcs));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ int zend_shared_memdup_size(void *source, size_t size)
|
||||
return ZEND_ALIGNED_SIZE(size);
|
||||
}
|
||||
|
||||
static zend_always_inline void *_zend_shared_memdup(void *source, size_t size, zend_bool get_xlat, zend_bool set_xlat, zend_bool free_source)
|
||||
static zend_always_inline void *_zend_shared_memdup(void *source, size_t size, zend_bool arena, zend_bool get_xlat, zend_bool set_xlat, zend_bool free_source)
|
||||
{
|
||||
void *old_p, *retval;
|
||||
zend_ulong key;
|
||||
@ -360,8 +360,13 @@ static zend_always_inline void *_zend_shared_memdup(void *source, size_t size, z
|
||||
return old_p;
|
||||
}
|
||||
}
|
||||
retval = ZCG(mem);
|
||||
ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
|
||||
if (arena) {
|
||||
retval = ZCG(arena_mem);
|
||||
ZCG(arena_mem) = (void*)(((char*)ZCG(arena_mem)) + ZEND_ALIGNED_SIZE(size));
|
||||
} else {
|
||||
retval = ZCG(mem);
|
||||
ZCG(mem) = (void*)(((char*)ZCG(mem)) + ZEND_ALIGNED_SIZE(size));
|
||||
}
|
||||
memcpy(retval, source, size);
|
||||
if (set_xlat) {
|
||||
if (!get_xlat) {
|
||||
@ -378,32 +383,42 @@ static zend_always_inline void *_zend_shared_memdup(void *source, size_t size, z
|
||||
|
||||
void *zend_shared_memdup_get_put_free(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 1, 1, 1);
|
||||
return _zend_shared_memdup(source, size, 0, 1, 1, 1);
|
||||
}
|
||||
|
||||
void *zend_shared_memdup_put_free(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 0, 1, 1);
|
||||
return _zend_shared_memdup(source, size, 0, 0, 1, 1);
|
||||
}
|
||||
|
||||
void *zend_shared_memdup_free(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 0, 0, 1);
|
||||
return _zend_shared_memdup(source, size, 0, 0, 0, 1);
|
||||
}
|
||||
|
||||
void *zend_shared_memdup_get_put(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 1, 1, 0);
|
||||
return _zend_shared_memdup(source, size, 0, 1, 1, 0);
|
||||
}
|
||||
|
||||
void *zend_shared_memdup_put(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 0, 1, 0);
|
||||
return _zend_shared_memdup(source, size, 0, 0, 1, 0);
|
||||
}
|
||||
|
||||
void *zend_shared_memdup(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 0, 0, 0);
|
||||
return _zend_shared_memdup(source, size, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
void *zend_shared_memdup_arena_put(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 1, 0, 1, 0);
|
||||
}
|
||||
|
||||
void *zend_shared_memdup_arena(void *source, size_t size)
|
||||
{
|
||||
return _zend_shared_memdup(source, size, 1, 0, 0, 0);
|
||||
}
|
||||
|
||||
void zend_shared_alloc_safe_unlock(void)
|
||||
@ -483,6 +498,16 @@ void zend_shared_alloc_clear_xlat_table(void)
|
||||
zend_hash_clean(&ZCG(xlat_table));
|
||||
}
|
||||
|
||||
uint32_t zend_shared_alloc_checkpoint_xlat_table(void)
|
||||
{
|
||||
return ZCG(xlat_table).nNumUsed;
|
||||
}
|
||||
|
||||
void zend_shared_alloc_restore_xlat_table(uint32_t checkpoint)
|
||||
{
|
||||
zend_hash_discard(&ZCG(xlat_table), checkpoint);
|
||||
}
|
||||
|
||||
void zend_shared_alloc_register_xlat_entry(const void *old, const void *new)
|
||||
{
|
||||
zend_ulong key = (zend_ulong)old;
|
||||
|
@ -131,6 +131,8 @@ void *zend_shared_memdup_free(void *source, size_t size);
|
||||
void *zend_shared_memdup_get_put(void *source, size_t size);
|
||||
void *zend_shared_memdup_put(void *source, size_t size);
|
||||
void *zend_shared_memdup(void *source, size_t size);
|
||||
void *zend_shared_memdup_arena_put(void *source, size_t size);
|
||||
void *zend_shared_memdup_arena(void *source, size_t size);
|
||||
|
||||
int zend_shared_memdup_size(void *p, size_t size);
|
||||
|
||||
@ -160,6 +162,8 @@ void zend_shared_alloc_safe_unlock(void);
|
||||
void zend_shared_alloc_init_xlat_table(void);
|
||||
void zend_shared_alloc_destroy_xlat_table(void);
|
||||
void zend_shared_alloc_clear_xlat_table(void);
|
||||
uint32_t zend_shared_alloc_checkpoint_xlat_table(void);
|
||||
void zend_shared_alloc_restore_xlat_table(uint32_t checkpoint);
|
||||
void zend_shared_alloc_register_xlat_entry(const void *old, const void *new);
|
||||
void *zend_shared_alloc_get_xlat_entry(const void *old);
|
||||
|
||||
|
@ -685,7 +685,7 @@ static void _function_closure_string(smart_str *str, zend_function *fptr, char*
|
||||
return;
|
||||
}
|
||||
|
||||
static_variables = fptr->op_array.static_variables;
|
||||
static_variables = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr);
|
||||
count = zend_hash_num_elements(static_variables);
|
||||
|
||||
if (!count) {
|
||||
@ -1790,19 +1790,21 @@ ZEND_METHOD(reflection_function, getStaticVariables)
|
||||
|
||||
/* Return an empty array in case no static variables exist */
|
||||
if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.static_variables != NULL) {
|
||||
HashTable *ht;
|
||||
|
||||
array_init(return_value);
|
||||
if (GC_REFCOUNT(fptr->op_array.static_variables) > 1) {
|
||||
if (!(GC_FLAGS(fptr->op_array.static_variables) & IS_ARRAY_IMMUTABLE)) {
|
||||
GC_DELREF(fptr->op_array.static_variables);
|
||||
}
|
||||
fptr->op_array.static_variables = zend_array_dup(fptr->op_array.static_variables);
|
||||
ht = ZEND_MAP_PTR_GET(fptr->op_array.static_variables_ptr);
|
||||
if (!ht) {
|
||||
ZEND_ASSERT(fptr->op_array.fn_flags & ZEND_ACC_IMMUTABLE);
|
||||
ht = zend_array_dup(fptr->op_array.static_variables);
|
||||
ZEND_MAP_PTR_SET(fptr->op_array.static_variables_ptr, ht);
|
||||
}
|
||||
ZEND_HASH_FOREACH_VAL(fptr->op_array.static_variables, val) {
|
||||
ZEND_HASH_FOREACH_VAL(ht, val) {
|
||||
if (UNEXPECTED(zval_update_constant_ex(val, fptr->common.scope) != SUCCESS)) {
|
||||
return;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
zend_hash_copy(Z_ARRVAL_P(return_value), fptr->op_array.static_variables, zval_add_ref);
|
||||
zend_hash_copy(Z_ARRVAL_P(return_value), ht, zval_add_ref);
|
||||
} else {
|
||||
ZVAL_EMPTY_ARRAY(return_value);
|
||||
}
|
||||
|
@ -243,19 +243,22 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zval *
|
||||
/* Cache iterator functions if ArrayIterator or derived. Check current's */
|
||||
/* cache since only current is always required */
|
||||
if (intern->std.handlers == &spl_handler_ArrayIterator) {
|
||||
if (!class_type->iterator_funcs_ptr->zf_current) {
|
||||
class_type->iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr =
|
||||
ZEND_MAP_PTR_GET(class_type->iterator_funcs_ptr);
|
||||
|
||||
if (!iterator_funcs_ptr->zf_current) {
|
||||
iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
|
||||
iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
|
||||
iterator_funcs_ptr->zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
|
||||
iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
|
||||
iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
|
||||
}
|
||||
if (inherited) {
|
||||
if (class_type->iterator_funcs_ptr->zf_rewind->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_REWIND;
|
||||
if (class_type->iterator_funcs_ptr->zf_valid->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_VALID;
|
||||
if (class_type->iterator_funcs_ptr->zf_key->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_KEY;
|
||||
if (class_type->iterator_funcs_ptr->zf_current->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_CURRENT;
|
||||
if (class_type->iterator_funcs_ptr->zf_next->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_NEXT;
|
||||
if (iterator_funcs_ptr->zf_rewind->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_REWIND;
|
||||
if (iterator_funcs_ptr->zf_valid->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_VALID;
|
||||
if (iterator_funcs_ptr->zf_key->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_KEY;
|
||||
if (iterator_funcs_ptr->zf_current->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_CURRENT;
|
||||
if (iterator_funcs_ptr->zf_next->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_NEXT;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,6 +207,7 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
|
||||
spl_fixedarray_object *intern;
|
||||
zend_class_entry *parent = class_type;
|
||||
int inherited = 0;
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
intern = zend_object_alloc(sizeof(spl_fixedarray_object), parent);
|
||||
|
||||
@ -238,27 +239,28 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
|
||||
php_error_docref(NULL, E_COMPILE_ERROR, "Internal compiler error, Class is not child of SplFixedArray");
|
||||
}
|
||||
|
||||
if (!class_type->iterator_funcs_ptr->zf_current) {
|
||||
class_type->iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
|
||||
class_type->iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
|
||||
iterator_funcs_ptr = ZEND_MAP_PTR_GET(class_type->iterator_funcs_ptr);
|
||||
if (!iterator_funcs_ptr->zf_current) {
|
||||
iterator_funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
|
||||
iterator_funcs_ptr->zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
|
||||
iterator_funcs_ptr->zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
|
||||
iterator_funcs_ptr->zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
|
||||
iterator_funcs_ptr->zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
|
||||
}
|
||||
if (inherited) {
|
||||
if (class_type->iterator_funcs_ptr->zf_rewind->common.scope != parent) {
|
||||
if (iterator_funcs_ptr->zf_rewind->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_REWIND;
|
||||
}
|
||||
if (class_type->iterator_funcs_ptr->zf_valid->common.scope != parent) {
|
||||
if (iterator_funcs_ptr->zf_valid->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_VALID;
|
||||
}
|
||||
if (class_type->iterator_funcs_ptr->zf_key->common.scope != parent) {
|
||||
if (iterator_funcs_ptr->zf_key->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_KEY;
|
||||
}
|
||||
if (class_type->iterator_funcs_ptr->zf_current->common.scope != parent) {
|
||||
if (iterator_funcs_ptr->zf_current->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_CURRENT;
|
||||
}
|
||||
if (class_type->iterator_funcs_ptr->zf_next->common.scope != parent) {
|
||||
if (iterator_funcs_ptr->zf_next->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_NEXT;
|
||||
}
|
||||
|
||||
|
@ -494,7 +494,8 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla
|
||||
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "o|lzl", &iterator, &flags, &user_caching_it_flags, &mode) == SUCCESS) {
|
||||
if (instanceof_function(Z_OBJCE_P(iterator), zend_ce_aggregate)) {
|
||||
zend_call_method_with_0_params(iterator, Z_OBJCE_P(iterator), &Z_OBJCE_P(iterator)->iterator_funcs_ptr->zf_new_iterator, "getiterator", &aggregate_retval);
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = ZEND_MAP_PTR_GET(Z_OBJCE_P(iterator)->iterator_funcs_ptr);
|
||||
zend_call_method_with_0_params(iterator, Z_OBJCE_P(iterator), &iterator_funcs_ptr->zf_new_iterator, "getiterator", &aggregate_retval);
|
||||
iterator = &aggregate_retval;
|
||||
} else {
|
||||
Z_ADDREF_P(iterator);
|
||||
@ -522,7 +523,8 @@ static void spl_recursive_it_it_construct(INTERNAL_FUNCTION_PARAMETERS, zend_cla
|
||||
|
||||
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "o|ll", &iterator, &mode, &flags) == SUCCESS) {
|
||||
if (instanceof_function(Z_OBJCE_P(iterator), zend_ce_aggregate)) {
|
||||
zend_call_method_with_0_params(iterator, Z_OBJCE_P(iterator), &Z_OBJCE_P(iterator)->iterator_funcs_ptr->zf_new_iterator, "getiterator", &aggregate_retval);
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = ZEND_MAP_PTR_GET(Z_OBJCE_P(iterator)->iterator_funcs_ptr);
|
||||
zend_call_method_with_0_params(iterator, Z_OBJCE_P(iterator), &iterator_funcs_ptr->zf_new_iterator, "getiterator", &aggregate_retval);
|
||||
iterator = &aggregate_retval;
|
||||
} else {
|
||||
Z_ADDREF_P(iterator);
|
||||
@ -1348,19 +1350,6 @@ static const zend_function_entry spl_funcs_RecursiveTreeIterator[] = {
|
||||
PHP_FE_END
|
||||
};
|
||||
|
||||
#if MBO_0
|
||||
static int spl_dual_it_gets_implemented(zend_class_entry *interface, zend_class_entry *class_type)
|
||||
{
|
||||
class_type->iterator_funcs_ptr->zf_valid = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_current = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_key = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_next = NULL;
|
||||
class_type->iterator_funcs_ptr->zf_rewind = NULL;
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
#endif
|
||||
|
||||
static zend_function *spl_dual_it_get_method(zend_object **object, zend_string *method, const zval *key)
|
||||
{
|
||||
zend_function *function_handler;
|
||||
@ -1513,7 +1502,8 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z
|
||||
ce = ce_cast;
|
||||
}
|
||||
if (instanceof_function(ce, zend_ce_aggregate)) {
|
||||
zend_call_method_with_0_params(zobject, ce, &ce->iterator_funcs_ptr->zf_new_iterator, "getiterator", &retval);
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr = ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr);
|
||||
zend_call_method_with_0_params(zobject, ce, &iterator_funcs_ptr->zf_new_iterator, "getiterator", &retval);
|
||||
if (EG(exception)) {
|
||||
zval_ptr_dtor(&retval);
|
||||
return NULL;
|
||||
|
@ -1028,8 +1028,11 @@ SPL_METHOD(MultipleIterator, rewind)
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
|
||||
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
it = &element->obj;
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
|
||||
iterator_funcs_ptr = ZEND_MAP_PTR_GET(Z_OBJCE_P(it)->iterator_funcs_ptr);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &iterator_funcs_ptr->zf_rewind, "rewind", NULL);
|
||||
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
|
||||
}
|
||||
}
|
||||
@ -1051,8 +1054,11 @@ SPL_METHOD(MultipleIterator, next)
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
|
||||
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
it = &element->obj;
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_next, "next", NULL);
|
||||
iterator_funcs_ptr = ZEND_MAP_PTR_GET(Z_OBJCE_P(it)->iterator_funcs_ptr);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &iterator_funcs_ptr->zf_next, "next", NULL);
|
||||
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
|
||||
}
|
||||
}
|
||||
@ -1081,8 +1087,11 @@ SPL_METHOD(MultipleIterator, valid)
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
|
||||
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
it = &element->obj;
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid, "valid", &retval);
|
||||
iterator_funcs_ptr = ZEND_MAP_PTR_GET(Z_OBJCE_P(it)->iterator_funcs_ptr);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &iterator_funcs_ptr->zf_valid, "valid", &retval);
|
||||
|
||||
if (!Z_ISUNDEF(retval)) {
|
||||
valid = (Z_TYPE(retval) == IS_TRUE);
|
||||
@ -1117,8 +1126,11 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
|
||||
|
||||
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
|
||||
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
it = &element->obj;
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid, "valid", &retval);
|
||||
iterator_funcs_ptr = ZEND_MAP_PTR_GET(Z_OBJCE_P(it)->iterator_funcs_ptr);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &iterator_funcs_ptr->zf_valid, "valid", &retval);
|
||||
|
||||
if (!Z_ISUNDEF(retval)) {
|
||||
valid = Z_TYPE(retval) == IS_TRUE;
|
||||
@ -1129,9 +1141,9 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
|
||||
|
||||
if (valid) {
|
||||
if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) {
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_current, "current", &retval);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &iterator_funcs_ptr->zf_current, "current", &retval);
|
||||
} else {
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_key, "key", &retval);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &iterator_funcs_ptr->zf_key, "key", &retval);
|
||||
}
|
||||
if (Z_ISUNDEF(retval)) {
|
||||
zend_throw_exception(spl_ce_RuntimeException, "Failed to call sub iterator method", 0);
|
||||
|
Loading…
Reference in New Issue
Block a user