mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Use better data structures (incomplete)
This commit is contained in:
parent
4e66abad54
commit
be82a07776
13 changed files with 127 additions and 162 deletions
|
@ -1887,7 +1887,7 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TS
|
|||
{
|
||||
int name_len;
|
||||
zend_string *lcname;
|
||||
//??? zend_module_entry *module_ptr;
|
||||
zend_module_entry *module_ptr;
|
||||
|
||||
if (!module) {
|
||||
return NULL;
|
||||
|
@ -1923,13 +1923,13 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module TS
|
|||
lcname = STR_ALLOC(name_len, 1);
|
||||
zend_str_tolower_copy(lcname->val, module->name, name_len);
|
||||
|
||||
if (zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry)) == NULL) {
|
||||
if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) {
|
||||
zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
|
||||
STR_RELEASE(lcname);
|
||||
return NULL;
|
||||
}
|
||||
STR_RELEASE(lcname);
|
||||
//??? module = module_ptr;
|
||||
module = module_ptr;
|
||||
EG(current_module) = module;
|
||||
|
||||
if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type TSRMLS_CC)==FAILURE) {
|
||||
|
@ -2798,7 +2798,6 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
|
|||
EG(scope) = ce_org;
|
||||
}
|
||||
|
||||
//??? if (!zend_is_callable_check_class(Z_STRVAL_P(callable), clen, fcc, &strict_class, error TSRMLS_CC)) {
|
||||
if (!zend_is_callable_check_class(Z_STR_P(callable), fcc, &strict_class, error TSRMLS_CC)) {
|
||||
EG(scope) = last_scope;
|
||||
return 0;
|
||||
|
@ -3035,11 +3034,12 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
|
|||
if (object_ptr && Z_TYPE_P(object_ptr) != IS_OBJECT) {
|
||||
object_ptr = NULL;
|
||||
}
|
||||
//??? if (object_ptr &&
|
||||
//??? (!EG(objects_store).object_buckets ||
|
||||
//??? !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(object_ptr)].valid)) {
|
||||
//??? return 0;
|
||||
//??? }
|
||||
|
||||
if (object_ptr &&
|
||||
(!EG(objects_store).object_buckets ||
|
||||
!IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(object_ptr)]))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch (Z_TYPE_P(callable)) {
|
||||
case IS_STRING:
|
||||
|
@ -3117,10 +3117,10 @@ ZEND_API zend_bool zend_is_callable_ex(zval *callable, zval *object_ptr, uint ch
|
|||
}
|
||||
|
||||
} else {
|
||||
//??? if (!EG(objects_store).object_buckets ||
|
||||
//??? !EG(objects_store).object_buckets[Z_OBJ_HANDLE_PP(obj)].valid) {
|
||||
//??? return 0;
|
||||
//??? }
|
||||
if (!!EG(objects_store).object_buckets ||
|
||||
!IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(obj)])) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
fcc->calling_scope = Z_OBJCE_P(obj); /* TBFixed: what if it's overloaded? */
|
||||
|
||||
|
@ -3711,7 +3711,7 @@ ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *na
|
|||
ZVAL_COPY_VALUE(property, value);
|
||||
if (Z_REFCOUNT_P(value) > 0) {
|
||||
zval_copy_ctor(property);
|
||||
} else {
|
||||
//??? } else {
|
||||
//??? efree(value);
|
||||
}
|
||||
} else {
|
||||
|
@ -3849,12 +3849,12 @@ ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC)
|
|||
{
|
||||
EG(error_handling) = saved->handling;
|
||||
EG(exception_class) = saved->handling == EH_THROW ? saved->exception : NULL;
|
||||
if (Z_TYPE(saved->user_handler) != IS_UNDEF) {
|
||||
//??? && saved->user_handler != EG(user_error_handler)) {
|
||||
if (Z_TYPE(saved->user_handler) != IS_UNDEF
|
||||
&& memcmp(&saved->user_handler, &EG(user_error_handler), sizeof(zval)) != 0) {
|
||||
zval_ptr_dtor(&EG(user_error_handler));
|
||||
ZVAL_COPY_VALUE(&EG(user_error_handler), &saved->user_handler);
|
||||
//??? } else if (saved->user_handler) {
|
||||
//??? zval_ptr_dtor(&saved->user_handler);
|
||||
} else if (Z_TYPE(saved->user_handler)) {
|
||||
zval_ptr_dtor(&saved->user_handler);
|
||||
}
|
||||
ZVAL_UNDEF(&saved->user_handler);
|
||||
}
|
||||
|
|
|
@ -797,10 +797,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
|
|||
called_scope = fci_cache->called_scope;
|
||||
fci->object_ptr = fci_cache->object_ptr;
|
||||
ZVAL_COPY_VALUE(&EX(object), fci->object_ptr);
|
||||
//??? if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT &&
|
||||
//??? (!EG(objects_store).object_buckets || !EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)].valid)) {
|
||||
//??? return FAILURE;
|
||||
//??? }
|
||||
if (fci->object_ptr && Z_TYPE_P(fci->object_ptr) == IS_OBJECT &&
|
||||
(!EG(objects_store).object_buckets ||
|
||||
!IS_VALID(EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(fci->object_ptr)]))) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (EX(function_state).function->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) {
|
||||
if (EX(function_state).function->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
|
|
|
@ -510,9 +510,6 @@ static zend_always_inline void _zend_hash_del_el_ex(HashTable *ht, uint idx, Buc
|
|||
if (ht->pDestructor) {
|
||||
ht->pDestructor(&p->val);
|
||||
}
|
||||
//??? if (ht->flags & HASH_FLAG_BIG_DATA) {
|
||||
//??? pefree(p->xData, ht->flags & HASH_FLAG_PERSISTENT);
|
||||
//??? }
|
||||
if (p->key) {
|
||||
STR_RELEASE(p->key);
|
||||
}
|
||||
|
@ -665,9 +662,6 @@ ZEND_API void zend_hash_destroy(HashTable *ht)
|
|||
if (ht->pDestructor) {
|
||||
ht->pDestructor(&p->val);
|
||||
}
|
||||
//??? if (ht->flags & HASH_FLAG_BIG_DATA) {
|
||||
//??? pefree(p->xData, ht->flags & HASH_FLAG_PERSISTENT);
|
||||
//??? }
|
||||
if (p->key) {
|
||||
STR_RELEASE(p->key);
|
||||
}
|
||||
|
@ -696,9 +690,6 @@ ZEND_API void zend_hash_clean(HashTable *ht)
|
|||
if (ht->pDestructor) {
|
||||
ht->pDestructor(&p->val);
|
||||
}
|
||||
//??? if (ht->flags & HASH_FLAG_BIG_DATA) {
|
||||
//??? pefree(p->xData, ht->flags & HASH_FLAG_PERSISTENT);
|
||||
//??? }
|
||||
if (p->key) {
|
||||
STR_RELEASE(p->key);
|
||||
}
|
||||
|
|
|
@ -24,8 +24,12 @@
|
|||
|
||||
static zend_class_entry zend_iterator_class_entry;
|
||||
|
||||
static void iter_wrapper_dtor(zend_object *object TSRMLS_DC);
|
||||
|
||||
static zend_object_handlers iterator_object_handlers = {
|
||||
ZEND_OBJECTS_STORE_HANDLERS,
|
||||
iter_wrapper_dtor,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL, /* prop read */
|
||||
NULL, /* prop write */
|
||||
NULL, /* read dim */
|
||||
|
@ -61,20 +65,9 @@ static void iter_wrapper_dtor(zend_object *object TSRMLS_DC)
|
|||
iter->funcs->dtor(iter TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC)
|
||||
ZEND_API void zend_iterator_wrap(zend_object_iterator *iter, zval *wrapped TSRMLS_DC)
|
||||
{
|
||||
//???
|
||||
return NULL;
|
||||
#if 0
|
||||
zval *wrapped;
|
||||
|
||||
MAKE_STD_ZVAL(wrapped);
|
||||
Z_TYPE_P(wrapped) = IS_OBJECT;
|
||||
Z_OBJ_HANDLE_P(wrapped) = zend_objects_store_put(iter, iter_wrapper_dtor, NULL, NULL TSRMLS_CC);
|
||||
Z_OBJ_HT_P(wrapped) = &iterator_object_handlers;
|
||||
|
||||
return wrapped;
|
||||
#endif
|
||||
ZVAL_OBJ(wrapped, &iter->std);
|
||||
}
|
||||
|
||||
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(
|
||||
|
|
|
@ -55,6 +55,7 @@ typedef struct _zend_object_iterator_funcs {
|
|||
} zend_object_iterator_funcs;
|
||||
|
||||
struct _zend_object_iterator {
|
||||
zend_object std;
|
||||
void *data;
|
||||
zend_object_iterator_funcs *funcs;
|
||||
ulong index; /* private to fe_reset/fe_fetch opcodes */
|
||||
|
@ -82,7 +83,7 @@ BEGIN_EXTERN_C()
|
|||
ZEND_API enum zend_object_iterator_kind zend_iterator_unwrap(zval *array_ptr, zend_object_iterator **iter TSRMLS_DC);
|
||||
|
||||
/* given an iterator, wrap it up as a zval for use by the engine opcodes */
|
||||
ZEND_API zval *zend_iterator_wrap(zend_object_iterator *iter TSRMLS_DC);
|
||||
ZEND_API void zend_iterator_wrap(zend_object_iterator *iter, zval *zv TSRMLS_DC);
|
||||
|
||||
ZEND_API void zend_register_iterator_wrapper(TSRMLS_D);
|
||||
END_EXTERN_C()
|
||||
|
|
|
@ -41,14 +41,15 @@
|
|||
|
||||
#define Z_OBJ_PROTECT_RECURSION(zval_p) \
|
||||
do { \
|
||||
if (EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zval_p)].apply_count++ >= 3) { \
|
||||
if (Z_OBJ_APPLY_COUNT_P(zval_p) >= 3) { \
|
||||
zend_error(E_ERROR, "Nesting level too deep - recursive dependency?"); \
|
||||
} \
|
||||
Z_OBJ_INC_APPLY_COUNT_P(zval_p); \
|
||||
} while (0)
|
||||
|
||||
|
||||
#define Z_OBJ_UNPROTECT_RECURSION(zval_p) \
|
||||
EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zval_p)].apply_count--
|
||||
Z_OBJ_DEC_APPLY_COUNT_P(zval_p)
|
||||
|
||||
/*
|
||||
__X accessors explanation:
|
||||
|
@ -1010,8 +1011,6 @@ static union _zend_function *zend_std_get_method(zval *object, zend_string *meth
|
|||
if (EXPECTED(key != NULL)) {
|
||||
lc_method_name = Z_STR(key->constant);
|
||||
} else {
|
||||
/* Create a zend_copy_str_tolower(dest, src, src_length); */
|
||||
//??? lc_method_name = do_alloca(method_len+1, use_heap);
|
||||
lc_method_name = STR_ALLOC(method_name->len, 0);
|
||||
zend_str_tolower_copy(lc_method_name->val, method_name->val, method_name->len);
|
||||
}
|
||||
|
@ -1146,8 +1145,6 @@ ZEND_API zend_function *zend_std_get_static_method(zend_class_entry *ce, zend_st
|
|||
if (EXPECTED(key != NULL)) {
|
||||
lc_function_name = Z_STR(key->constant);
|
||||
} else {
|
||||
//???lc_function_name = do_alloca(function_name_strlen+1, use_heap);
|
||||
/* Create a zend_copy_str_tolower(dest, src, src_length); */
|
||||
lc_function_name = STR_ALLOC(function_name->len, 0);
|
||||
zend_str_tolower_copy(lc_function_name->val, function_name->val, function_name->len);
|
||||
}
|
||||
|
@ -1334,38 +1331,38 @@ static int zend_std_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
|
|||
if (!zobj1->properties && !zobj2->properties) {
|
||||
int i;
|
||||
|
||||
//??? Z_OBJ_PROTECT_RECURSION(o1);
|
||||
//??? Z_OBJ_PROTECT_RECURSION(o2);
|
||||
Z_OBJ_PROTECT_RECURSION(o1);
|
||||
Z_OBJ_PROTECT_RECURSION(o2);
|
||||
for (i = 0; i < zobj1->ce->default_properties_count; i++) {
|
||||
if (Z_TYPE(zobj1->properties_table[i]) != IS_UNDEF) {
|
||||
if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) {
|
||||
zval result;
|
||||
|
||||
if (compare_function(&result, &zobj1->properties_table[i], &zobj2->properties_table[i] TSRMLS_CC)==FAILURE) {
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
return 1;
|
||||
}
|
||||
if (Z_LVAL(result) != 0) {
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
return Z_LVAL(result);
|
||||
}
|
||||
} else {
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) {
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
//??? Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o1);
|
||||
Z_OBJ_UNPROTECT_RECURSION(o2);
|
||||
return 0;
|
||||
} else {
|
||||
if (!zobj1->properties) {
|
||||
|
|
|
@ -25,18 +25,6 @@
|
|||
#include "zend_API.h"
|
||||
#include "zend_objects_API.h"
|
||||
|
||||
#define FREE_BUCKET 1
|
||||
|
||||
#define IS_VALID(o) (!(((zend_uintptr_t)(o)) & FREE_BUCKET))
|
||||
|
||||
#define GET_BUCKET_NUMBER(o) (((zend_uintptr_t)(o)) >> 1)
|
||||
|
||||
#define SET_BUCKET_NUMBER(o, n) do { \
|
||||
(o) = (((zend_uintptr_t)(n)) << 1) | FREE_BUCKET); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
ZEND_API void zend_objects_store_init(zend_objects_store *objects, zend_uint init_size)
|
||||
{
|
||||
objects->object_buckets = (zend_object **) emalloc(init_size * sizeof(zend_object*));
|
||||
|
@ -99,7 +87,7 @@ ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects
|
|||
|
||||
if (IS_VALID(obj)) {
|
||||
gc_remove_zval_from_buffer((zend_refcounted*)obj TSRMLS_CC);
|
||||
//??? objects->object_buckets[i].valid = 0;
|
||||
objects->object_buckets[i] = SET_INVALID(obj);
|
||||
if (obj->handlers->free_obj) {
|
||||
obj->handlers->free_obj(obj TSRMLS_CC);
|
||||
}
|
||||
|
@ -129,72 +117,55 @@ ZEND_API void zend_objects_store_put(zend_object *object TSRMLS_DC)
|
|||
EG(objects_store).object_buckets[handle] = object;
|
||||
}
|
||||
|
||||
#define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST() \
|
||||
EG(objects_store).object_buckets[handle].bucket.free_list.next = EG(objects_store).free_list_head; \
|
||||
EG(objects_store).free_list_head = handle; \
|
||||
EG(objects_store).object_buckets[handle].valid = 0;
|
||||
#define ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(handle) \
|
||||
SET_BUCKET_NUMBER(EG(objects_store).object_buckets[handle], EG(objects_store).free_list_head); \
|
||||
EG(objects_store).free_list_head = handle;
|
||||
|
||||
/*
|
||||
* Delete a reference to an objects store entry given the object handle.
|
||||
*/
|
||||
//???
|
||||
#if 0
|
||||
ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const zend_object_handlers *handlers TSRMLS_DC) /* {{{ */
|
||||
ZEND_API void zend_objects_store_del(zend_object *object TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
struct _store_object *obj;
|
||||
int failure = 0;
|
||||
|
||||
if (!EG(objects_store).object_buckets) {
|
||||
return;
|
||||
}
|
||||
|
||||
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
|
||||
|
||||
/* Make sure we hold a reference count during the destructor call
|
||||
otherwise, when the destructor ends the storage might be freed
|
||||
when the refcount reaches 0 a second time
|
||||
*/
|
||||
if (EG(objects_store).object_buckets[handle].valid) {
|
||||
if (obj->refcount == 1) {
|
||||
if (!EG(objects_store).object_buckets[handle].destructor_called) {
|
||||
EG(objects_store).object_buckets[handle].destructor_called = 1;
|
||||
if (EG(objects_store).object_buckets &&
|
||||
IS_VALID(EG(objects_store).object_buckets[object->handle])) {
|
||||
if (object->gc.refcount == 0) {
|
||||
int failure = 0;
|
||||
|
||||
if (obj->dtor) {
|
||||
if (handlers && !obj->handlers) {
|
||||
obj->handlers = handlers;
|
||||
}
|
||||
if (!(object->gc.u.v.flags & IS_OBJ_DESTRUCTOR_CALLED)) {
|
||||
object->gc.u.v.flags |= IS_OBJ_DESTRUCTOR_CALLED;
|
||||
|
||||
if (object->handlers->dtor_obj) {
|
||||
object->gc.refcount++;
|
||||
zend_try {
|
||||
obj->dtor(obj->object, handle TSRMLS_CC);
|
||||
object->handlers->dtor_obj(object TSRMLS_CC);
|
||||
} zend_catch {
|
||||
failure = 1;
|
||||
} zend_end_try();
|
||||
object->gc.refcount--;
|
||||
}
|
||||
}
|
||||
|
||||
/* re-read the object from the object store as the store might have been reallocated in the dtor */
|
||||
obj = &EG(objects_store).object_buckets[handle].bucket.obj;
|
||||
|
||||
if (obj->refcount == 1) {
|
||||
if (object->gc.refcount == 0) {
|
||||
//??? GC_REMOVE_ZOBJ_FROM_BUFFER(obj);
|
||||
if (obj->free_storage) {
|
||||
if (object->handlers->free_obj) {
|
||||
zend_try {
|
||||
obj->free_storage(obj->object TSRMLS_CC);
|
||||
object->handlers->free_obj(object TSRMLS_CC);
|
||||
} zend_catch {
|
||||
failure = 1;
|
||||
} zend_end_try();
|
||||
}
|
||||
ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST();
|
||||
ZEND_OBJECTS_STORE_ADD_TO_FREE_LIST(object->handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
obj->refcount--;
|
||||
|
||||
if (failure) {
|
||||
zend_bailout();
|
||||
}
|
||||
} else {
|
||||
object->gc.refcount--;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
/* }}} */
|
||||
|
||||
//???
|
||||
|
@ -230,28 +201,18 @@ ZEND_API zend_object *zend_objects_store_clone_obj(zval *zobject TSRMLS_DC)
|
|||
* from the constructor function. You MUST NOT use this function for any other
|
||||
* weird games, or call it at any other time after the object is constructed.
|
||||
* */
|
||||
//???
|
||||
#if 0
|
||||
ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC)
|
||||
ZEND_API void zend_object_store_set_object(zval *zobject, zend_object *object TSRMLS_DC)
|
||||
{
|
||||
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
|
||||
|
||||
EG(objects_store).object_buckets[handle].bucket.obj.object = object;
|
||||
EG(objects_store).object_buckets[Z_OBJ_HANDLE_P(zobject)] = object;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Called when the ctor was terminated by an exception */
|
||||
//???
|
||||
#if 0
|
||||
ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC)
|
||||
{
|
||||
zend_object_handle handle = Z_OBJ_HANDLE_P(zobject);
|
||||
zend_object_store_bucket *obj_bucket = &EG(objects_store).object_buckets[handle];
|
||||
zend_object *obj = Z_OBJ_P(zobject);
|
||||
|
||||
obj_bucket->bucket.obj.handlers = Z_OBJ_HT_P(zobject);;
|
||||
obj_bucket->destructor_called = 1;
|
||||
obj->gc.u.v.flags |= IS_OBJ_DESTRUCTOR_CALLED;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Proxy objects workings */
|
||||
typedef struct _zend_proxy_object {
|
||||
|
|
|
@ -51,6 +51,18 @@
|
|||
//??? } bucket;
|
||||
//???} zend_object_store_bucket;
|
||||
|
||||
#define FREE_BUCKET 1
|
||||
|
||||
#define IS_VALID(o) (!(((zend_uintptr_t)(o)) & FREE_BUCKET))
|
||||
|
||||
#define SET_INVALID(o) ((zend_object*)((((zend_uintptr_t)(o)) | FREE_BUCKET)))
|
||||
|
||||
#define GET_BUCKET_NUMBER(o) (((zend_uintptr_t)(o)) >> 1)
|
||||
|
||||
#define SET_BUCKET_NUMBER(o, n) do { \
|
||||
(o) = (zend_object*)((((zend_uintptr_t)(n)) << 1) | FREE_BUCKET); \
|
||||
} while (0)
|
||||
|
||||
typedef struct _zend_objects_store {
|
||||
zend_object **object_buckets;
|
||||
zend_uint top;
|
||||
|
@ -67,20 +79,10 @@ ZEND_API void zend_objects_store_destroy(zend_objects_store *objects);
|
|||
|
||||
/* Store API functions */
|
||||
ZEND_API void zend_objects_store_put(zend_object *object TSRMLS_DC);
|
||||
ZEND_API void zend_objects_store_del(zend_object *object TSRMLS_DC);
|
||||
|
||||
//???ZEND_API void zend_objects_store_add_ref(zval *object TSRMLS_DC);
|
||||
//???ZEND_API void zend_objects_store_del_ref(zval *object TSRMLS_DC);
|
||||
//???ZEND_API void zend_objects_store_add_ref_by_handle(zend_object_handle handle TSRMLS_DC);
|
||||
//???ZEND_API void zend_objects_store_del_ref_by_handle_ex(zend_object_handle handle, const zend_object_handlers *handlers TSRMLS_DC);
|
||||
//???static zend_always_inline void zend_objects_store_del_ref_by_handle(zend_object_handle handle TSRMLS_DC) {
|
||||
//??? zend_objects_store_del_ref_by_handle_ex(handle, NULL TSRMLS_CC);
|
||||
//???}
|
||||
//???ZEND_API zend_uint zend_objects_store_get_refcount(zval *object TSRMLS_DC);
|
||||
//???ZEND_API zend_object *zend_objects_store_clone_obj(zval *object TSRMLS_DC);
|
||||
//???ZEND_API void *zend_object_store_get_object(const zval *object TSRMLS_DC);
|
||||
//???ZEND_API void *zend_object_store_get_object_by_handle(zend_object_handle handle TSRMLS_DC);
|
||||
/* See comment in zend_objects_API.c before you use this */
|
||||
//???ZEND_API void zend_object_store_set_object(zval *zobject, void *object TSRMLS_DC);
|
||||
ZEND_API void zend_object_store_set_object(zval *zobject, zend_object *object TSRMLS_DC);
|
||||
ZEND_API void zend_object_store_ctor_failed(zval *zobject TSRMLS_DC);
|
||||
|
||||
ZEND_API void zend_objects_store_free_object_storage(zend_objects_store *objects TSRMLS_DC);
|
||||
|
|
|
@ -1484,7 +1484,6 @@ static inline void zend_free_obj_get_result(zval *op TSRMLS_DC) /* {{{ */
|
|||
if (Z_REFCOUNT_P(op) == 0) {
|
||||
GC_REMOVE_ZVAL_FROM_BUFFER(op);
|
||||
zval_dtor(op);
|
||||
//??? FREE_ZVAL(op);
|
||||
} else {
|
||||
zval_ptr_dtor(op);
|
||||
}
|
||||
|
|
|
@ -217,8 +217,28 @@ struct _zend_ast_ref {
|
|||
#define IS_STR_INTERNED (1<<1) /* interned string */
|
||||
#define IS_STR_PERMANENT (1<<2) /* relives request boundary */
|
||||
|
||||
/* string flags (zval.value->gc.u.vflags) */
|
||||
#define IS_OBJ_DESTRUCTOR_CALLED (1<<0)
|
||||
/* object flags (zval.value->gc.u.vflags) */
|
||||
#define IS_OBJ_APPLY_COUNT 0x07
|
||||
#define IS_OBJ_DESTRUCTOR_CALLED (1<<3)
|
||||
|
||||
#define Z_OBJ_APPLY_COUNT(zval) \
|
||||
(Z_OBJ(zval)->gc.u.v.flags & IS_OBJ_APPLY_COUNT)
|
||||
|
||||
#define Z_OBJ_INC_APPLY_COUNT(zval) do { \
|
||||
Z_OBJ(zval)->gc.u.v.flags = \
|
||||
(Z_OBJ(zval)->gc.u.v.flags & ~IS_OBJ_APPLY_COUNT) | \
|
||||
((Z_OBJ(zval)->gc.u.v.flags & IS_OBJ_APPLY_COUNT) + 1); \
|
||||
} while (0)
|
||||
|
||||
#define Z_OBJ_DEC_APPLY_COUNT(zval) do { \
|
||||
Z_OBJ(zval)->gc.u.v.flags = \
|
||||
(Z_OBJ(zval)->gc.u.v.flags & ~IS_OBJ_APPLY_COUNT) | \
|
||||
((Z_OBJ(zval)->gc.u.v.flags & IS_OBJ_APPLY_COUNT) - 1); \
|
||||
} while (0)
|
||||
|
||||
#define Z_OBJ_APPLY_COUNT_P(zv) Z_OBJ_APPLY_COUNT(*(zv))
|
||||
#define Z_OBJ_INC_APPLY_COUNT_P(zv) Z_OBJ_INC_APPLY_COUNT(*(zv))
|
||||
#define Z_OBJ_DEC_APPLY_COUNT_P(zv) Z_OBJ_DEC_APPLY_COUNT(*(zv))
|
||||
|
||||
#define Z_REFCOUNTED(zval) IS_REFCOUNTED(Z_TYPE(zval))
|
||||
#define Z_REFCOUNTED_P(zval_p) Z_REFCOUNTED(*(zval_p))
|
||||
|
|
|
@ -39,23 +39,24 @@ ZEND_API void _zval_dtor_func(zval *zvalue ZEND_FILE_LINE_DC)
|
|||
case IS_CONSTANT_ARRAY: {
|
||||
TSRMLS_FETCH();
|
||||
|
||||
//??? if (zvalue->value.ht && (zvalue->value.ht != &EG(symbol_table))) {
|
||||
if (Z_ARRVAL_P(zvalue) != &EG(symbol_table).ht) {
|
||||
/* break possible cycles */
|
||||
Z_TYPE_P(zvalue) = IS_NULL;
|
||||
zend_hash_destroy(Z_ARRVAL_P(zvalue));
|
||||
FREE_HASHTABLE(Z_ARR_P(zvalue));
|
||||
//??? }
|
||||
efree(Z_ARR_P(zvalue));
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IS_CONSTANT_AST:
|
||||
zend_ast_destroy(Z_AST_P(zvalue)->ast);
|
||||
efree(Z_AST_P(zvalue));
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
{
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (Z_DELREF_P(zvalue) == 0) {
|
||||
// TODO: release object???
|
||||
zend_objects_store_del(Z_OBJ_P(zvalue) TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -216,7 +217,7 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args,
|
|||
}
|
||||
} else {
|
||||
if (is_ref) {
|
||||
//??? SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
|
||||
SEPARATE_ZVAL_TO_MAKE_IS_REF(p);
|
||||
if (!Z_ISREF_P(p)) {
|
||||
if (IS_REFCOUNTED(Z_TYPE_P(p)) && Z_REFCOUNT_P(p) > 1) {
|
||||
Z_DELREF_P(p);
|
||||
|
@ -228,8 +229,7 @@ ZEND_API int zval_copy_static_var(zval *p TSRMLS_DC, int num_args, va_list args,
|
|||
}
|
||||
}
|
||||
} else if (Z_ISREF_P(p)) {
|
||||
//???
|
||||
tmp = *Z_REFVAL_P(p);
|
||||
ZVAL_COPY_VALUE(&tmp, Z_REFVAL_P(p));
|
||||
if (Z_REFCOUNTED(tmp) && Z_REFCOUNT(tmp) > 1) {
|
||||
zval_copy_ctor(&tmp);
|
||||
Z_SET_REFCOUNT(tmp, 0);
|
||||
|
|
|
@ -4158,7 +4158,7 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY)
|
|||
FREE_OP1_IF_VAR();
|
||||
}
|
||||
if (iter && EXPECTED(EG(exception) == NULL)) {
|
||||
array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
|
||||
zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
|
||||
} else {
|
||||
if (OP1_TYPE == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
|
||||
FREE_OP1_VAR_PTR();
|
||||
|
|
|
@ -3021,7 +3021,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A
|
|||
|
||||
}
|
||||
if (iter && EXPECTED(EG(exception) == NULL)) {
|
||||
array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
|
||||
zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
|
||||
} else {
|
||||
if (IS_CONST == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
|
||||
|
||||
|
@ -7995,7 +7995,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
|
||||
}
|
||||
if (iter && EXPECTED(EG(exception) == NULL)) {
|
||||
array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
|
||||
zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
|
||||
} else {
|
||||
if (IS_TMP_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
|
||||
|
||||
|
@ -12989,7 +12989,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG
|
|||
zval_ptr_dtor_nogc(free_op1.var);
|
||||
}
|
||||
if (iter && EXPECTED(EG(exception) == NULL)) {
|
||||
array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
|
||||
zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
|
||||
} else {
|
||||
if (IS_VAR == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
|
||||
if (free_op1.var) {zval_ptr_dtor_nogc(free_op1.var);};
|
||||
|
@ -29534,7 +29534,7 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS
|
|||
|
||||
}
|
||||
if (iter && EXPECTED(EG(exception) == NULL)) {
|
||||
array_ptr = zend_iterator_wrap(iter TSRMLS_CC);
|
||||
zend_iterator_wrap(iter, array_ptr TSRMLS_CC);
|
||||
} else {
|
||||
if (IS_CV == IS_VAR && opline->extended_value & ZEND_FE_RESET_VARIABLE) {
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue