mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
- Fix a bug in method calls.
- Try to get the old copying behavior of objects to work (doesn't work yet).
This commit is contained in:
parent
3510482971
commit
ea48c0c46a
7 changed files with 62 additions and 23 deletions
14
Zend/zend.h
14
Zend/zend.h
|
@ -177,11 +177,19 @@ typedef struct _zend_object {
|
|||
|
||||
typedef unsigned int zend_object_handle;
|
||||
|
||||
typedef struct _zend_object_handlers zend_object_handlers;
|
||||
|
||||
typedef struct _zend_object_value {
|
||||
zend_object_handle handle;
|
||||
zend_object_handlers *handlers;
|
||||
} zend_object_value;
|
||||
|
||||
typedef zend_object *(*get_address_t)(zend_object_handle handle); /* Don't return zval ** so that we can't change it */
|
||||
typedef zval **(*get_property_address_t)(zend_object_handle handle, zval *offset, int type);
|
||||
typedef void (*add_ref_t)(zend_object_handle handle);
|
||||
typedef void (*del_ref_t)(zend_object_handle handle);
|
||||
typedef void (*delete_obj_t)(zend_object_handle handle);
|
||||
typedef zend_object_value (*clone_obj_t)(zend_object_handle handle);
|
||||
|
||||
typedef struct _zend_object_handlers {
|
||||
get_address_t get_address;
|
||||
|
@ -189,13 +197,9 @@ typedef struct _zend_object_handlers {
|
|||
add_ref_t add_ref;
|
||||
del_ref_t del_ref;
|
||||
delete_obj_t delete_obj;
|
||||
clone_obj_t clone_obj;
|
||||
} zend_object_handlers;
|
||||
|
||||
typedef struct _zend_object_value {
|
||||
zend_object_handle handle;
|
||||
zend_object_handlers handlers;
|
||||
} zend_object_value;
|
||||
|
||||
#include "zend_objects.h"
|
||||
|
||||
typedef union _zvalue_value {
|
||||
|
|
|
@ -139,7 +139,6 @@ static inline zval *_get_object_zval_ptr(znode *node, temp_variable *Ts, int *sh
|
|||
if (Ts[node->u.var].var.ptr_ptr) {
|
||||
PZVAL_UNLOCK(*Ts[node->u.var].var.ptr_ptr);
|
||||
*should_free = 0;
|
||||
SEPARATE_ZVAL_IF_NOT_REF(Ts[node->u.var].var.ptr_ptr);
|
||||
return *Ts[node->u.var].var.ptr_ptr;
|
||||
} else {
|
||||
if (Ts[node->u.var].EA.type==IS_STRING_OFFSET) {
|
||||
|
@ -2185,7 +2184,7 @@ send_by_ref:
|
|||
if (Z_TYPE_PP(object) != IS_OBJECT) {
|
||||
zend_error(E_ERROR, "Cannot call delete on non-object type");
|
||||
}
|
||||
(*object)->value.obj.handlers.delete_obj((*object)->value.obj.handle);
|
||||
(*object)->value.obj.handlers->delete_obj((*object)->value.obj.handle);
|
||||
}
|
||||
|
||||
zend_hash_del(EG(active_symbol_table), variable->value.str.val, variable->value.str.len+1);
|
||||
|
@ -2240,7 +2239,7 @@ send_by_ref:
|
|||
if (Z_TYPE_PP(object) != IS_OBJECT) {
|
||||
zend_error(E_ERROR, "Cannot call delete on non-object type");
|
||||
}
|
||||
(*object)->value.obj.handlers.delete_obj((*object)->value.obj.handle);
|
||||
(*object)->value.obj.handlers->delete_obj((*object)->value.obj.handle);
|
||||
}
|
||||
|
||||
zend_hash_index_del(ht, index);
|
||||
|
@ -2254,7 +2253,7 @@ send_by_ref:
|
|||
if (Z_TYPE_PP(object) != IS_OBJECT) {
|
||||
zend_error(E_ERROR, "Cannot call delete on non-object type");
|
||||
}
|
||||
(*object)->value.obj.handlers.delete_obj((*object)->value.obj.handle);
|
||||
(*object)->value.obj.handlers->delete_obj((*object)->value.obj.handle);
|
||||
}
|
||||
|
||||
zend_hash_del(ht, offset->value.str.val, offset->value.str.len+1);
|
||||
|
@ -2267,7 +2266,7 @@ send_by_ref:
|
|||
if (Z_TYPE_PP(object) != IS_OBJECT) {
|
||||
zend_error(E_ERROR, "Cannot call delete on non-object type");
|
||||
}
|
||||
(*object)->value.obj.handlers.delete_obj((*object)->value.obj.handle);
|
||||
(*object)->value.obj.handlers->delete_obj((*object)->value.obj.handle);
|
||||
}
|
||||
|
||||
zend_hash_del(ht, "", sizeof(""));
|
||||
|
@ -2373,7 +2372,7 @@ send_by_ref:
|
|||
}
|
||||
|
||||
object_zval = get_zval_ptr(&opline->op1, Ts, &EG(free_op1), BP_VAR_R);
|
||||
object = object_zval->value.obj.handlers.get_address(object_zval->value.obj.handle);
|
||||
object = object_zval->value.obj.handlers->get_address(object_zval->value.obj.handle);
|
||||
|
||||
if (!object->ce->handle_function_call
|
||||
&& !zend_hash_exists(&object->ce->function_table, object->ce->name, object->ce->name_length+1)) {
|
||||
|
|
|
@ -9,7 +9,8 @@ static zend_object_handlers zoh = {
|
|||
NULL,
|
||||
zend_objects_add_ref,
|
||||
zend_objects_del_ref,
|
||||
zend_objects_delete_obj
|
||||
zend_objects_delete_obj,
|
||||
zend_objects_clone_obj
|
||||
};
|
||||
|
||||
void zend_objects_init(zend_objects *objects, zend_uint init_size)
|
||||
|
@ -50,7 +51,7 @@ zend_object_value zend_objects_new(zend_object **object, zend_class_entry *class
|
|||
(*object)->ce = class_type;
|
||||
|
||||
retval.handle = handle;
|
||||
retval.handlers = zoh;
|
||||
retval.handlers = &zoh;
|
||||
#if ZEND_DEBUG_OBJECTS
|
||||
fprintf(stderr, "Allocated object id #%d\n", handle);
|
||||
#endif
|
||||
|
@ -125,3 +126,27 @@ void zend_objects_del_ref(zend_object_handle handle)
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
zend_object_value zend_objects_clone_obj(zend_object_handle handle)
|
||||
{
|
||||
zend_object_value retval;
|
||||
zend_object *old_object;
|
||||
zend_object *new_object;
|
||||
|
||||
TSRMLS_FETCH();
|
||||
|
||||
if (!EG(objects).object_buckets[handle].valid) {
|
||||
zend_error(E_ERROR, "Trying to clone invalid object");
|
||||
}
|
||||
|
||||
old_object = &EG(objects).object_buckets[handle].bucket.obj.object;
|
||||
retval = zend_objects_new(&new_object, old_object->ce);
|
||||
ALLOC_HASHTABLE(new_object->properties);
|
||||
zend_hash_init(new_object->properties, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(new_object->properties, old_object->properties, (copy_ctor_func_t) zval_add_ref, (void *) NULL /* Not used anymore */, sizeof(zval *));
|
||||
|
||||
#if ZEND_DEBUG_OBJECTS
|
||||
fprintf(stderr, "Allocated object id #%d\n", handle);
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
|
|
@ -30,5 +30,6 @@ zend_object *zend_objects_get_address(zend_object_handle handle);
|
|||
void zend_objects_add_ref(zend_object_handle handle);
|
||||
void zend_objects_del_ref(zend_object_handle handle);
|
||||
void zend_objects_delete_obj(zend_object_handle handle);
|
||||
zend_object_value zend_objects_clone_obj(zend_object_handle handle);
|
||||
|
||||
#endif /* ZEND_OBJECTS_H */
|
|
@ -514,10 +514,19 @@ ZEND_API void convert_to_array(zval *op)
|
|||
case IS_ARRAY:
|
||||
return;
|
||||
break;
|
||||
/* OBJECTS_FIXME */
|
||||
/* OBJECTS_OPTIMIZE */
|
||||
case IS_OBJECT:
|
||||
op->type = IS_ARRAY;
|
||||
op->value.ht = Z_OBJPROP_P(op);
|
||||
{
|
||||
zval *tmp;
|
||||
HashTable *ht;
|
||||
|
||||
ALLOC_HASHTABLE(ht);
|
||||
zend_hash_init(ht, 0, NULL, ZVAL_PTR_DTOR, 0);
|
||||
zend_hash_copy(ht, Z_OBJPROP_P(op), (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *));
|
||||
zval_dtor(op);
|
||||
op->type = IS_ARRAY;
|
||||
op->value.ht = ht;
|
||||
}
|
||||
return;
|
||||
case IS_NULL:
|
||||
ALLOC_HASHTABLE(op->value.ht);
|
||||
|
@ -1240,7 +1249,6 @@ ZEND_API int is_identical_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
|
|||
}
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
/* OBJECTS_FIXME */
|
||||
if (Z_OBJCE_P(op1) != Z_OBJCE_P(op2)) {
|
||||
result->value.lval = 0;
|
||||
} else {
|
||||
|
@ -1695,7 +1703,6 @@ ZEND_API void zend_compare_arrays(zval *result, zval *a1, zval *a2 TSRMLS_DC)
|
|||
|
||||
ZEND_API void zend_compare_objects(zval *result, zval *o1, zval *o2 TSRMLS_DC)
|
||||
{
|
||||
/* OBJECTS_FIXME */
|
||||
if (Z_OBJCE_P(o1) != Z_OBJCE_P(o2)) {
|
||||
result->value.lval = 1; /* Comparing objects of different types is pretty much meaningless */
|
||||
result->type = IS_LONG;
|
||||
|
|
|
@ -232,7 +232,7 @@ ZEND_API int zend_atoi(const char *str, int str_len);
|
|||
#define Z_STRVAL(zval) (zval).value.str.val
|
||||
#define Z_STRLEN(zval) (zval).value.str.len
|
||||
#define Z_ARRVAL(zval) (zval).value.ht
|
||||
#define Z_OBJ(zval) (zval).value.obj.handlers.get_address((zval).value.obj.handle)
|
||||
#define Z_OBJ(zval) (zval).value.obj.handlers->get_address((zval).value.obj.handle)
|
||||
#define Z_OBJPROP(zval) Z_OBJ(zval)->properties
|
||||
#define Z_OBJCE(zval) Z_OBJ(zval)->ce
|
||||
#define Z_RESVAL(zval) (zval).value.lval
|
||||
|
|
|
@ -54,7 +54,7 @@ ZEND_API void _zval_dtor(zval *zvalue ZEND_FILE_LINE_DC)
|
|||
}
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
zvalue->value.obj.handlers.del_ref(zvalue->value.obj.handle);
|
||||
zvalue->value.obj.handlers->del_ref(zvalue->value.obj.handle);
|
||||
break;
|
||||
case IS_RESOURCE: {
|
||||
TSRMLS_FETCH();
|
||||
|
@ -119,7 +119,11 @@ ZEND_API int _zval_copy_ctor(zval *zvalue ZEND_FILE_LINE_DC)
|
|||
}
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
zvalue->value.obj.handlers.add_ref(zvalue->value.obj.handle);
|
||||
#if 0
|
||||
zvalue->value.obj = zvalue->value.obj.handlers->clone_obj(zvalue->value.obj.handle);
|
||||
#else
|
||||
zvalue->value.obj.handlers->add_ref(zvalue->value.obj.handle);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
return SUCCESS;
|
||||
|
@ -152,8 +156,7 @@ ZEND_API int zval_persist(zval *zvalue TSRMLS_DC)
|
|||
zend_hash_apply(zvalue->value.ht, (apply_func_t) zval_persist TSRMLS_CC);
|
||||
break;
|
||||
case IS_OBJECT:
|
||||
persist_alloc(zvalue->value.obj.properties);
|
||||
zend_hash_apply(zvalue->value.obj.properties, (apply_func_t) zval_persist TSRMLS_CC);
|
||||
return FAILURE; /* objects cannot be persisted */
|
||||
break;
|
||||
}
|
||||
return SUCCESS;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue