mirror of
https://github.com/php/php-src.git
synced 2024-11-23 09:54:15 +08:00
Reverted back ce->iterator_funcs_ptr. Initialize ce->iterator_funcs_ptr fields in immutable classes.
This commit is contained in:
parent
ad7a78b253
commit
4740dabb84
@ -128,9 +128,9 @@ PHP 7.4 INTERNALS UPGRADE NOTES
|
||||
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 accessed through ZEND_MAP_PTR... macros.
|
||||
indirection. op_array->run_time_cache, op_array->static_variables_ptr and
|
||||
class_entry->static_members_table now have to be accessed 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
|
||||
|
@ -148,7 +148,7 @@ struct _zend_class_entry {
|
||||
zend_function *unserialize_func;
|
||||
|
||||
/* allocated only if class implements Iterator or IteratorAggregate interface */
|
||||
ZEND_MAP_PTR_DEF(zend_class_iterator_funcs *, iterator_funcs_ptr);
|
||||
zend_class_iterator_funcs *iterator_funcs_ptr;
|
||||
|
||||
/* handlers */
|
||||
union {
|
||||
|
@ -219,7 +219,7 @@ typedef struct _zend_fcall_info_cache {
|
||||
class_container.trait_precedences = NULL; \
|
||||
class_container.interfaces = NULL; \
|
||||
class_container.get_iterator = NULL; \
|
||||
ZEND_MAP_PTR_INIT(class_container.iterator_funcs_ptr, NULL); \
|
||||
class_container.iterator_funcs_ptr = NULL; \
|
||||
class_container.info.internal.module = NULL; \
|
||||
class_container.info.internal.builtin_functions = functions; \
|
||||
}
|
||||
|
@ -1638,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;
|
||||
ZEND_MAP_PTR_INIT(ce->iterator_funcs_ptr, NULL);
|
||||
ce->iterator_funcs_ptr = NULL;
|
||||
ce->get_static_method = NULL;
|
||||
ce->parent = NULL;
|
||||
ce->parent_name = NULL;
|
||||
|
@ -92,9 +92,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */
|
||||
if (EXPECTED(!ce->get_iterator)) {
|
||||
ce->get_iterator = parent->get_iterator;
|
||||
}
|
||||
if (ZEND_MAP_PTR(parent->iterator_funcs_ptr)) {
|
||||
if (parent->iterator_funcs_ptr) {
|
||||
/* Must be initialized through iface->interface_gets_implemented() */
|
||||
ZEND_ASSERT(ZEND_MAP_PTR_GET(ce->iterator_funcs_ptr));
|
||||
ZEND_ASSERT(ce->iterator_funcs_ptr);
|
||||
}
|
||||
if (EXPECTED(!ce->__get)) {
|
||||
ce->__get = parent->__get;
|
||||
|
@ -119,36 +119,12 @@ 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_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);
|
||||
zend_call_method_with_0_params(object, ce, &ce->iterator_funcs_ptr->zf_new_iterator, "getiterator", retval);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -183,10 +159,8 @@ 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, ce, &iterator_funcs_ptr->zf_valid, "valid", &more);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_valid, "valid", &more);
|
||||
result = i_zend_is_true(&more);
|
||||
zval_ptr_dtor(&more);
|
||||
return result ? SUCCESS : FAILURE;
|
||||
@ -202,10 +176,7 @@ ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter)
|
||||
zval *object = &iter->it.data;
|
||||
|
||||
if (Z_ISUNDEF(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);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_current, "current", &iter->value);
|
||||
}
|
||||
return &iter->value;
|
||||
}
|
||||
@ -217,10 +188,8 @@ 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, ce, &iterator_funcs_ptr->zf_key, "key", &retval);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_key, "key", &retval);
|
||||
|
||||
if (Z_TYPE(retval) != IS_UNDEF) {
|
||||
ZVAL_ZVAL(key, &retval, 1, 1);
|
||||
@ -239,11 +208,9 @@ 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, ce, &iterator_funcs_ptr->zf_next, "next", NULL);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_next, "next", NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -252,11 +219,9 @@ 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, ce, &iterator_funcs_ptr->zf_rewind, "rewind", NULL);
|
||||
zend_call_method_with_0_params(object, iter->ce, &iter->ce->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
@ -347,7 +312,6 @@ 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) {
|
||||
@ -376,31 +340,17 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
|
||||
}
|
||||
}
|
||||
class_type->get_iterator = zend_user_it_get_new_iterator;
|
||||
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;
|
||||
}
|
||||
if (class_type->iterator_funcs_ptr != NULL) {
|
||||
class_type->iterator_funcs_ptr->zf_new_iterator = NULL;
|
||||
} else if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
/* 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;
|
||||
class_type->iterator_funcs_ptr = calloc(1, sizeof(zend_class_iterator_funcs));
|
||||
} else {
|
||||
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;
|
||||
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);
|
||||
}
|
||||
iterator_funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(&class_type->function_table, "getiterator", sizeof("getiterator") - 1);
|
||||
return SUCCESS;
|
||||
}
|
||||
/* }}} */
|
||||
@ -408,8 +358,6 @@ 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 */
|
||||
@ -426,39 +374,25 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
|
||||
}
|
||||
}
|
||||
class_type->get_iterator = zend_user_it_get_iterator;
|
||||
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;
|
||||
}
|
||||
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;
|
||||
} else if (class_type->type == ZEND_INTERNAL_CLASS) {
|
||||
/* 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;
|
||||
class_type->iterator_funcs_ptr = calloc(1, sizeof(zend_class_iterator_funcs));
|
||||
} else {
|
||||
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;
|
||||
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);
|
||||
}
|
||||
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;
|
||||
}
|
||||
/* }}} */
|
||||
|
@ -347,8 +347,8 @@ ZEND_API void destroy_zend_class(zval *zv)
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
zend_hash_destroy(&ce->constants_table);
|
||||
}
|
||||
if (ZEND_MAP_PTR(ce->iterator_funcs_ptr)) {
|
||||
free(ZEND_MAP_PTR(ce->iterator_funcs_ptr));
|
||||
if (ce->iterator_funcs_ptr) {
|
||||
free(ce->iterator_funcs_ptr);
|
||||
}
|
||||
if (ce->num_interfaces > 0) {
|
||||
free(ce->interfaces);
|
||||
|
@ -373,11 +373,6 @@ 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)
|
||||
|
@ -757,14 +757,17 @@ static void zend_file_cache_serialize_class(zval *zv,
|
||||
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));
|
||||
}
|
||||
if (ce->iterator_funcs_ptr) {
|
||||
SERIALIZE_PTR(ce->iterator_funcs_ptr->zf_new_iterator);
|
||||
SERIALIZE_PTR(ce->iterator_funcs_ptr->zf_rewind);
|
||||
SERIALIZE_PTR(ce->iterator_funcs_ptr->zf_valid);
|
||||
SERIALIZE_PTR(ce->iterator_funcs_ptr->zf_key);
|
||||
SERIALIZE_PTR(ce->iterator_funcs_ptr->zf_current);
|
||||
SERIALIZE_PTR(ce->iterator_funcs_ptr->zf_next);
|
||||
SERIALIZE_PTR(ce->iterator_funcs_ptr);
|
||||
}
|
||||
|
||||
ZEND_MAP_PTR_INIT(ce->static_members_table, &ce->default_static_members_table);
|
||||
}
|
||||
|
||||
static void zend_file_cache_serialize(zend_persistent_script *script,
|
||||
@ -1413,18 +1416,20 @@ static void zend_file_cache_unserialize_class(zval *zv,
|
||||
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);
|
||||
}
|
||||
if (ce->iterator_funcs_ptr) {
|
||||
UNSERIALIZE_PTR(ce->iterator_funcs_ptr);
|
||||
UNSERIALIZE_PTR(ce->iterator_funcs_ptr->zf_new_iterator);
|
||||
UNSERIALIZE_PTR(ce->iterator_funcs_ptr->zf_rewind);
|
||||
UNSERIALIZE_PTR(ce->iterator_funcs_ptr->zf_valid);
|
||||
UNSERIALIZE_PTR(ce->iterator_funcs_ptr->zf_key);
|
||||
UNSERIALIZE_PTR(ce->iterator_funcs_ptr->zf_current);
|
||||
UNSERIALIZE_PTR(ce->iterator_funcs_ptr->zf_next);
|
||||
}
|
||||
|
||||
if (ce->ce_flags & ZEND_ACC_IMMUTABLE && 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);
|
||||
UNSERIALIZE_PTR(ZEND_MAP_PTR(ce->iterator_funcs_ptr));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "zend_vm.h"
|
||||
#include "zend_constants.h"
|
||||
#include "zend_operators.h"
|
||||
#include "zend_interfaces.h"
|
||||
|
||||
#ifdef HAVE_OPCACHE_FILE_CACHE
|
||||
#define zend_set_str_gc_flags(str) do { \
|
||||
@ -905,14 +906,8 @@ static void zend_persist_class_entry(zval *zv)
|
||||
}
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
if (ce->iterator_funcs_ptr) {
|
||||
ce->iterator_funcs_ptr = zend_shared_memdup(ce->iterator_funcs_ptr, sizeof(zend_class_iterator_funcs));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -968,6 +963,20 @@ static int zend_update_parent_ce(zval *zv)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ce->iterator_funcs_ptr) {
|
||||
memset(ce->iterator_funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
|
||||
if (instanceof_function_ex(ce, zend_ce_aggregate, 1)) {
|
||||
ce->iterator_funcs_ptr->zf_new_iterator = zend_hash_str_find_ptr(&ce->function_table, "getiterator", sizeof("getiterator") - 1);
|
||||
}
|
||||
if (instanceof_function_ex(ce, zend_ce_iterator, 1)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* update methods */
|
||||
|
@ -431,11 +431,8 @@ static void zend_persist_class_entry_calc(zval *zv)
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
if (ce->iterator_funcs_ptr) {
|
||||
ADD_SIZE(sizeof(zend_class_iterator_funcs));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -243,22 +243,19 @@ 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) {
|
||||
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 (!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);
|
||||
}
|
||||
if (inherited) {
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,7 +207,6 @@ 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);
|
||||
|
||||
@ -239,28 +238,27 @@ 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");
|
||||
}
|
||||
|
||||
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 (!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);
|
||||
}
|
||||
if (inherited) {
|
||||
if (iterator_funcs_ptr->zf_rewind->common.scope != parent) {
|
||||
if (class_type->iterator_funcs_ptr->zf_rewind->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_REWIND;
|
||||
}
|
||||
if (iterator_funcs_ptr->zf_valid->common.scope != parent) {
|
||||
if (class_type->iterator_funcs_ptr->zf_valid->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_VALID;
|
||||
}
|
||||
if (iterator_funcs_ptr->zf_key->common.scope != parent) {
|
||||
if (class_type->iterator_funcs_ptr->zf_key->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_KEY;
|
||||
}
|
||||
if (iterator_funcs_ptr->zf_current->common.scope != parent) {
|
||||
if (class_type->iterator_funcs_ptr->zf_current->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_CURRENT;
|
||||
}
|
||||
if (iterator_funcs_ptr->zf_next->common.scope != parent) {
|
||||
if (class_type->iterator_funcs_ptr->zf_next->common.scope != parent) {
|
||||
intern->flags |= SPL_FIXEDARRAY_OVERLOADED_NEXT;
|
||||
}
|
||||
|
||||
|
@ -494,8 +494,7 @@ 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_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);
|
||||
zend_call_method_with_0_params(iterator, Z_OBJCE_P(iterator), &Z_OBJCE_P(iterator)->iterator_funcs_ptr->zf_new_iterator, "getiterator", &aggregate_retval);
|
||||
iterator = &aggregate_retval;
|
||||
} else {
|
||||
Z_ADDREF_P(iterator);
|
||||
@ -523,8 +522,7 @@ 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_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);
|
||||
zend_call_method_with_0_params(iterator, Z_OBJCE_P(iterator), &Z_OBJCE_P(iterator)->iterator_funcs_ptr->zf_new_iterator, "getiterator", &aggregate_retval);
|
||||
iterator = &aggregate_retval;
|
||||
} else {
|
||||
Z_ADDREF_P(iterator);
|
||||
@ -1348,6 +1346,19 @@ 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;
|
||||
@ -1500,8 +1511,7 @@ static spl_dual_it_object* spl_dual_it_construct(INTERNAL_FUNCTION_PARAMETERS, z
|
||||
ce = ce_cast;
|
||||
}
|
||||
if (instanceof_function(ce, zend_ce_aggregate)) {
|
||||
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);
|
||||
zend_call_method_with_0_params(zobject, ce, &ce->iterator_funcs_ptr->zf_new_iterator, "getiterator", &retval);
|
||||
if (EG(exception)) {
|
||||
zval_ptr_dtor(&retval);
|
||||
return NULL;
|
||||
|
@ -1028,11 +1028,8 @@ 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;
|
||||
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_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
|
||||
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
|
||||
}
|
||||
}
|
||||
@ -1054,11 +1051,8 @@ 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;
|
||||
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_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_next, "next", NULL);
|
||||
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
|
||||
}
|
||||
}
|
||||
@ -1087,11 +1081,8 @@ 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;
|
||||
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);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid, "valid", &retval);
|
||||
|
||||
if (!Z_ISUNDEF(retval)) {
|
||||
valid = (Z_TYPE(retval) == IS_TRUE);
|
||||
@ -1126,11 +1117,8 @@ 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;
|
||||
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);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_valid, "valid", &retval);
|
||||
|
||||
if (!Z_ISUNDEF(retval)) {
|
||||
valid = Z_TYPE(retval) == IS_TRUE;
|
||||
@ -1141,9 +1129,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), &iterator_funcs_ptr->zf_current, "current", &retval);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &Z_OBJCE_P(it)->iterator_funcs_ptr->zf_current, "current", &retval);
|
||||
} else {
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(it), &iterator_funcs_ptr->zf_key, "key", &retval);
|
||||
zend_call_method_with_0_params(it, Z_OBJCE_P(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