]> granicus.if.org Git - php/commitdiff
- Fix a bug in method calls.
authorAndi Gutmans <andi@php.net>
Thu, 16 Aug 2001 14:04:04 +0000 (14:04 +0000)
committerAndi Gutmans <andi@php.net>
Thu, 16 Aug 2001 14:04:04 +0000 (14:04 +0000)
- Try to get the old copying behavior of objects to work (doesn't work yet).

Zend/zend.h
Zend/zend_execute.c
Zend/zend_objects.c
Zend/zend_objects.h
Zend/zend_operators.c
Zend/zend_operators.h
Zend/zend_variables.c

index c55e3a3b83fc5055e61da61c499dbf524cad0990..619ac2a0509eeb7c6a317c8e35a1783d43a731a3 100644 (file)
@@ -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 {
index 51410c6e12fccc9c990b4367a58552689ad12a93..766f1334e9f1b136d945d53c2fa9691bb3dc3f96 100644 (file)
@@ -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)) {
index 38348df54c7c2f04e50259235f113abe3ad8cb48..8c82e3a31e3b0b8b1a460fd27605fd8efbe65c85 100644 (file)
@@ -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;
+}
index 04b0626edd14302537654d9bb6ef29a493107344..c4d39a7784173ff6526e2a7c2a62959e0c8553fe 100644 (file)
@@ -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
index 42f09726005fa3c38c8496e7dde1c976dddaade3..a37fcc9066f0595272fe2d1e4d95e61f659b7240 100644 (file)
@@ -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;
index 3cc733a70d10af38d8af03d731f3900d617ef008..2e93e2cd5379a041ec02ab89f22c059067def3de 100644 (file)
@@ -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
index f919fb8c85f2d0c4184e8a544fccfe962684a647..61043583828b210c1b46732d698aaa4387c277ef 100644 (file)
@@ -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;