]> granicus.if.org Git - php/commitdiff
Use better data structures (incomplete)
authorDmitry Stogov <dmitry@zend.com>
Fri, 21 Feb 2014 18:59:51 +0000 (22:59 +0400)
committerDmitry Stogov <dmitry@zend.com>
Fri, 21 Feb 2014 18:59:51 +0000 (22:59 +0400)
Zend/zend_exceptions.c
Zend/zend_object_handlers.c
Zend/zend_objects_API.h
Zend/zend_operators.c
ext/standard/type.c
ext/standard/var.c

index 48779b47ec7ac410043a7ee7384a09c1974be27e..791f7a25c5173b49a4d2a90080d1b2b9320ff683 100644 (file)
@@ -409,9 +409,15 @@ static int _build_trace_args(zval *arg TSRMLS_DC, int num_args, va_list args, ze
                                TRACE_APPEND_STR("false, ");
                        }
                        break;
-               case IS_RESOURCE:
+               case IS_RESOURCE: {
+                       long lval = Z_RES_HANDLE_P(arg);
+                       char s_tmp[MAX_LENGTH_OF_LONG + 1];
+                       int l_tmp = zend_sprintf(s_tmp, "%ld", lval);  /* SAFE */
                        TRACE_APPEND_STR("Resource id #");
-                       /* break; */
+                       TRACE_APPEND_STRL(s_tmp, l_tmp);
+                       TRACE_APPEND_STR(", ");
+                       break;
+               }
                case IS_LONG: {
                        long lval = Z_LVAL_P(arg);
                        char s_tmp[MAX_LENGTH_OF_LONG + 1];
index fea71d644a4af37f79aa2e2f6d788c5b52d42332..bdb18879d7f2b3ba54b360cf4e868b4d4d735ddd 100644 (file)
@@ -72,7 +72,6 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
 {
        if (!zobj->properties) {
                HashPosition pos;
-               zval tmp;
                zend_property_info *prop_info;
                zend_class_entry *ce = zobj->ce;
 
@@ -86,8 +85,8 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
                                    (prop_info->flags & ZEND_ACC_STATIC) == 0 &&
                                    prop_info->offset >= 0 &&
                                    Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) {
-                                   ZVAL_INDIRECT(&tmp, &zobj->properties_table[prop_info->offset]);
-                                       zend_hash_add(zobj->properties, prop_info->name, &tmp);
+                                       zval *zv = zend_hash_add(zobj->properties, prop_info->name, &zobj->properties_table[prop_info->offset]);
+                                       ZVAL_INDIRECT(&zobj->properties_table[prop_info->offset], zv);
                                }
                        }
                        while (ce->parent && ce->parent->default_properties_count) {
@@ -100,8 +99,8 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */
                                            (prop_info->flags & ZEND_ACC_PRIVATE) != 0 &&
                                            prop_info->offset >= 0 &&
                                                Z_TYPE(zobj->properties_table[prop_info->offset]) != IS_UNDEF) {
-                                               ZVAL_INDIRECT(&tmp, &zobj->properties_table[prop_info->offset]);
-                                               zend_hash_add(zobj->properties, prop_info->name, &tmp);
+                                               zval *zv = zend_hash_add(zobj->properties, prop_info->name, &zobj->properties_table[prop_info->offset]);
+                                               ZVAL_INDIRECT(&zobj->properties_table[prop_info->offset], zv);
                                        }
                                }
                        }
@@ -447,6 +446,9 @@ zval *zend_std_read_property(zval *object, zval *member, int type, const zend_li
                    property_info->offset >= 0 &&
                    Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
                        retval = &zobj->properties_table[property_info->offset];
+                       if (Z_TYPE_P(retval) == IS_INDIRECT) {
+                               retval = Z_INDIRECT_P(retval);
+                       }
                        goto exit;
                }
                if (UNEXPECTED(!zobj->properties)) {
@@ -543,6 +545,9 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, c
                    property_info->offset >= 0 &&
                    Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
                        variable_ptr = &zobj->properties_table[property_info->offset];
+                       if (Z_TYPE_P(variable_ptr) == IS_INDIRECT) {
+                               variable_ptr = Z_INDIRECT_P(variable_ptr);
+                       }
                        goto found;
                }
                if (EXPECTED(zobj->properties != NULL)) {
@@ -618,12 +623,11 @@ found:
                if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
                    property_info->offset >= 0) {
 
-                       ZVAL_COPY_VALUE(&zobj->properties_table[property_info->offset], value);
                        if (zobj->properties) {
-                       zval tmp;
-
-                           ZVAL_INDIRECT(&tmp, &zobj->properties_table[property_info->offset]);
-                               zend_hash_update(zobj->properties, property_info->name, &tmp);
+                               zval *zv = zend_hash_update(zobj->properties, property_info->name, value);
+                           ZVAL_INDIRECT(&zobj->properties_table[property_info->offset], zv);
+                       } else {
+                               ZVAL_COPY_VALUE(&zobj->properties_table[property_info->offset], value);
                        }
                } else {
                        if (!zobj->properties) {
@@ -756,6 +760,9 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type,
                    property_info->offset >= 0 &&
                    Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
                        retval = &zobj->properties_table[property_info->offset];
+                       if (Z_TYPE_P(retval) == IS_INDIRECT) {
+                               retval = Z_INDIRECT_P(retval);
+                       }
                        goto exit;
                }
                if (UNEXPECTED(!zobj->properties)) {
@@ -774,12 +781,15 @@ static zval *zend_std_get_property_ptr_ptr(zval *object, zval *member, int type,
                }
                if (EXPECTED((property_info->flags & ZEND_ACC_STATIC) == 0) &&
                    property_info->offset >= 0) {
-                       retval = &zobj->properties_table[property_info->offset];
-                       ZVAL_NULL(retval);
-                       if (zobj->properties) {
+                       if (zobj->properties) {                         
                                zval tmp;
-                           ZVAL_INDIRECT(&tmp, retval);
-                               zend_hash_update(zobj->properties, property_info->name, &tmp);
+
+                               ZVAL_NULL(&tmp);
+                               retval = zend_hash_update(zobj->properties, property_info->name, &tmp);
+                           ZVAL_INDIRECT(&zobj->properties_table[property_info->offset], retval);
+                       } else {
+                               retval = &zobj->properties_table[property_info->offset];
+                               ZVAL_NULL(retval);
                        }
                } else {
                        if (!zobj->properties) {
@@ -1343,8 +1353,16 @@ static int zend_std_compare_objects(zval *o1, zval *o2 TSRMLS_DC) /* {{{ */
                        if (Z_TYPE(zobj1->properties_table[i]) != IS_UNDEF) {
                                if (Z_TYPE(zobj2->properties_table[i]) != IS_UNDEF) {
                                        zval result;
+                                       zval *p1 = &zobj1->properties_table[i];
+                                       zval *p2 = &zobj2->properties_table[i];
 
-                                       if (compare_function(&result, &zobj1->properties_table[i], &zobj2->properties_table[i] TSRMLS_CC)==FAILURE) {
+                                       if (Z_TYPE_P(p1) == IS_INDIRECT) {
+                                               p1 = Z_INDIRECT_P(p1);
+                                       }
+                                       if (Z_TYPE_P(p2) == IS_INDIRECT) {
+                                               p1 = Z_INDIRECT_P(p2);
+                                       }
+                                       if (compare_function(&result, p1, p2 TSRMLS_CC)==FAILURE) {
                                                Z_OBJ_UNPROTECT_RECURSION(o1);
                                                Z_OBJ_UNPROTECT_RECURSION(o2);
                                                return 1;
@@ -1407,6 +1425,9 @@ static int zend_std_has_property(zval *object, zval *member, int has_set_exists,
                    property_info->offset >= 0 &&
                    Z_TYPE(zobj->properties_table[property_info->offset]) != IS_UNDEF) {
                        value = &zobj->properties_table[property_info->offset];
+                       if (Z_TYPE_P(value) == IS_INDIRECT) {
+                               value = Z_INDIRECT_P(value);
+                       }
                        goto found;
                }
                if (UNEXPECTED(zobj->properties != NULL)) {
index 0695d68c7c6b86ed1a0a913530f10c64f81ab157..647bfeaee57f8a790ef7df6eee7c554e95b47840 100644 (file)
@@ -57,7 +57,7 @@
 
 #define SET_INVALID(o)                 ((zend_object*)((((zend_uintptr_t)(o)) | FREE_BUCKET)))
 
-#define GET_BUCKET_NUMBER(o)   (((zend_uintptr_t)(o)) >> 1)
+#define GET_BUCKET_NUMBER(o)   (((zend_intptr_t)(o)) >> 1)
 
 #define SET_BUCKET_NUMBER(o, n)        do { \
                (o) = (zend_object*)((((zend_uintptr_t)(n)) << 1) | FREE_BUCKET); \
index 8ead9201edcb4beb36720eb01debf451d5aadfc9..1803d5075d9c3ca363b597cb87e9671caaa20fca 100644 (file)
@@ -610,7 +610,7 @@ ZEND_API void _convert_to_string(zval *op ZEND_FILE_LINE_DC) /* {{{ */
                        }
                        break;
                case IS_RESOURCE: {
-                       long tmp = Z_LVAL_P(op);
+                       long tmp = Z_RES_HANDLE_P(op);
                        char *str;
                        int len;
                        TSRMLS_FETCH();
@@ -747,7 +747,14 @@ ZEND_API void convert_to_object(zval *op) /* {{{ */
        switch (Z_TYPE_P(op)) {
                case IS_ARRAY:
                        {
-                               object_and_properties_init(op, zend_standard_class_def, Z_ARRVAL_P(op));
+                               HashTable *properties = emalloc(sizeof(HashTable));
+                               zend_array *arr = Z_ARR_P(op);
+
+                               memcpy(properties, Z_ARRVAL_P(op), sizeof(HashTable));
+                               object_and_properties_init(op, zend_standard_class_def, properties);
+                               if (--arr->gc.refcount == 0) {
+                                       efree(arr);
+                               }
                                break;
                        }
                case IS_OBJECT:
index facb1bad0255e70569db7173cf393df4e7bc2c2d..a876657f4366131f0163bb542110c34f39ffe2de 100644 (file)
@@ -98,6 +98,10 @@ PHP_FUNCTION(settype)
                return;
        }
 
+       if (Z_TYPE_P(var)) {
+               var = Z_REFVAL_P(var);
+       }
+
        if (!strcasecmp(type, "integer")) {
                convert_to_long(var);
        } else if (!strcasecmp(type, "int")) {
index 2ce76cced147becabf81632201dc5a650b29d9ac..e6ea7064c75e5b95921b8e14fa63de737399eb6b 100644 (file)
@@ -32,7 +32,7 @@
 #include "basic_functions.h"
 #include "php_incomplete_class.h"
 
-#define COMMON (Z_ISREF_P(struc) ? "&" : "")
+#define COMMON (is_ref ? "&" : "")
 /* }}} */
 
 static int php_array_element_dump(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
@@ -90,11 +90,17 @@ PHPAPI void php_var_dump(zval *struc, int level TSRMLS_DC) /* {{{ */
        zend_string *class_name;
        int (*php_element_dump_func)(zval* TSRMLS_DC, int, va_list, zend_hash_key*);
        int is_temp;
+       int is_ref = 0;
 
        if (level > 1) {
                php_printf("%*c", level - 1, ' ');
        }
 
+       if (Z_TYPE_P(struc) == IS_REFERENCE) {
+               is_ref = 1;
+               struc = Z_REFVAL_P(struc);
+       }
+       
        switch (Z_TYPE_P(struc)) {
        case IS_BOOL:
                php_printf("%sbool(%s)\n", COMMON, Z_LVAL_P(struc) ? "true" : "false");
@@ -244,11 +250,17 @@ PHPAPI void php_debug_zval_dump(zval *struc, int level TSRMLS_DC) /* {{{ */
        zend_string *class_name;
        int (*zval_element_dump_func)(zval* TSRMLS_DC, int, va_list, zend_hash_key*);
        int is_temp = 0;
+       int is_ref = 0;
 
        if (level > 1) {
                php_printf("%*c", level - 1, ' ');
        }
 
+       if (Z_TYPE_P(struc) == IS_REFERENCE) {
+               is_ref = 1;
+               struc = Z_REFVAL_P(struc);
+       }
+
        switch (Z_TYPE_P(struc)) {
        case IS_BOOL:
                php_printf("%sbool(%s)\n", COMMON, Z_LVAL_P(struc)?"true":"false");