diff options
author | Andi Gutmans <andi@php.net> | 2001-08-16 14:04:04 +0000 |
---|---|---|
committer | Andi Gutmans <andi@php.net> | 2001-08-16 14:04:04 +0000 |
commit | ea48c0c46acc1d7ca6e9fb5cc078f0393b4e63ac (patch) | |
tree | f927a3dd4705d0ecb3a53021ac02b0a393755388 /Zend | |
parent | 351048297185f37175170cf3ac970bac94f915da (diff) | |
download | php-git-ea48c0c46acc1d7ca6e9fb5cc078f0393b4e63ac.tar.gz |
- Fix a bug in method calls.
- Try to get the old copying behavior of objects to work (doesn't work yet).
Diffstat (limited to 'Zend')
-rw-r--r-- | Zend/zend.h | 14 | ||||
-rw-r--r-- | Zend/zend_execute.c | 11 | ||||
-rw-r--r-- | Zend/zend_objects.c | 29 | ||||
-rw-r--r-- | Zend/zend_objects.h | 1 | ||||
-rw-r--r-- | Zend/zend_operators.c | 17 | ||||
-rw-r--r-- | Zend/zend_operators.h | 2 | ||||
-rw-r--r-- | Zend/zend_variables.c | 11 |
7 files changed, 62 insertions, 23 deletions
diff --git a/Zend/zend.h b/Zend/zend.h index c55e3a3b83..619ac2a050 100644 --- a/Zend/zend.h +++ b/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 { diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 51410c6e12..766f1334e9 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -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)) { diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 38348df54c..8c82e3a31e 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -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; +} diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h index 04b0626edd..c4d39a7784 100644 --- a/Zend/zend_objects.h +++ b/Zend/zend_objects.h @@ -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 */
\ No newline at end of file diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 42f0972600..a37fcc9066 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -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; diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 3cc733a70d..2e93e2cd53 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -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 diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index f919fb8c85..6104358382 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -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; |