From: Dmitry Stogov Date: Fri, 21 Feb 2014 18:59:51 +0000 (+0400) Subject: Use better data structures (incomplete) X-Git-Tag: POST_PHPNG_MERGE~412^2~590 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6454684212b4687167cc058ad77972f2d456cf20;p=php Use better data structures (incomplete) --- diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 48779b47ec..791f7a25c5 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -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]; diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index fea71d644a..bdb18879d7 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -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)) { diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index 0695d68c7c..647bfeaee5 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -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); \ diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 8ead9201ed..1803d5075d 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -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: diff --git a/ext/standard/type.c b/ext/standard/type.c index facb1bad02..a876657f43 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -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")) { diff --git a/ext/standard/var.c b/ext/standard/var.c index 2ce76cced1..e6ea7064c7 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -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");