diff options
| author | Dmitry Stogov <dmitry@php.net> | 2010-05-24 14:11:39 +0000 |
|---|---|---|
| committer | Dmitry Stogov <dmitry@php.net> | 2010-05-24 14:11:39 +0000 |
| commit | c5237d82bf01a762bb38f80def59b9c16cb84dc1 (patch) | |
| tree | 6e769820ba97ef669765c6ecfeabb08faf9e6ebc /ext | |
| parent | 1cabc8cd3a3bf5c12a8ece9efb59e3f5381f1ae5 (diff) | |
| download | php-git-c5237d82bf01a762bb38f80def59b9c16cb84dc1.tar.gz | |
Added caches to eliminate repeatable run-time bindings of functions, classes, constants, methods and properties
Diffstat (limited to 'ext')
28 files changed, 738 insertions, 174 deletions
diff --git a/ext/date/php_date.c b/ext/date/php_date.c index a9df4e476c..c974846a73 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -2011,7 +2011,6 @@ static inline zend_object_value date_object_new_date_ex(zend_class_entry *class_ { php_date_obj *intern; zend_object_value retval; - zval *tmp; intern = emalloc(sizeof(php_date_obj)); memset(intern, 0, sizeof(php_date_obj)); @@ -2020,7 +2019,7 @@ static inline zend_object_value date_object_new_date_ex(zend_class_entry *class_ } zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_date, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_date; @@ -2084,7 +2083,7 @@ static HashTable *date_object_get_properties(zval *object TSRMLS_DC) dateobj = (php_date_obj *) zend_object_store_get_object(object TSRMLS_CC); - props = dateobj->std.properties; + props = zend_std_get_properties(object TSRMLS_CC); if (!dateobj->time || GC_G(gc_active)) { return props; @@ -2132,7 +2131,6 @@ static inline zend_object_value date_object_new_timezone_ex(zend_class_entry *cl { php_timezone_obj *intern; zend_object_value retval; - zval *tmp; intern = emalloc(sizeof(php_timezone_obj)); memset(intern, 0, sizeof(php_timezone_obj)); @@ -2141,7 +2139,7 @@ static inline zend_object_value date_object_new_timezone_ex(zend_class_entry *cl } zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_timezone, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_timezone; @@ -2184,7 +2182,6 @@ static inline zend_object_value date_object_new_interval_ex(zend_class_entry *cl { php_interval_obj *intern; zend_object_value retval; - zval *tmp; intern = emalloc(sizeof(php_interval_obj)); memset(intern, 0, sizeof(php_interval_obj)); @@ -2193,7 +2190,7 @@ static inline zend_object_value date_object_new_interval_ex(zend_class_entry *cl } zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_interval, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_interval; @@ -2227,7 +2224,7 @@ static HashTable *date_object_get_properties_interval(zval *object TSRMLS_DC) intervalobj = (php_interval_obj *) zend_object_store_get_object(object TSRMLS_CC); - props = intervalobj->std.properties; + props = zend_std_get_properties(object TSRMLS_CC); if (!intervalobj->initialized || GC_G(gc_active)) { return props; @@ -2260,7 +2257,6 @@ static inline zend_object_value date_object_new_period_ex(zend_class_entry *clas { php_period_obj *intern; zend_object_value retval; - zval *tmp; intern = emalloc(sizeof(php_period_obj)); memset(intern, 0, sizeof(php_period_obj)); @@ -2269,7 +2265,7 @@ static inline zend_object_value date_object_new_period_ex(zend_class_entry *clas } zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) date_object_free_storage_period, NULL TSRMLS_CC); retval.handlers = &date_object_handlers_period; diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index eb364a73b2..9a6367c23d 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -1053,7 +1053,6 @@ void dom_namednode_iter(dom_object *basenode, int ntype, dom_object *intern, xml static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool hash_copy TSRMLS_DC) /* {{{ */ { zend_class_entry *base_class; - zval *tmp; dom_object *intern; if (instanceof_function(class_type, dom_xpath_class_entry TSRMLS_CC)) { @@ -1075,7 +1074,7 @@ static dom_object* dom_objects_set_class(zend_class_entry *class_type, zend_bool zend_object_std_init(&intern->std, class_type TSRMLS_CC); if (hash_copy) { - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); } return intern; diff --git a/ext/fileinfo/fileinfo.c b/ext/fileinfo/fileinfo.c index 81ee428e94..f9b4c30051 100644 --- a/ext/fileinfo/fileinfo.c +++ b/ext/fileinfo/fileinfo.c @@ -98,13 +98,12 @@ PHP_FILEINFO_API zend_object_value finfo_objects_new(zend_class_entry *class_typ { zend_object_value retval; struct finfo_object *intern; - zval *tmp; intern = emalloc(sizeof(struct finfo_object)); memset(intern, 0, sizeof(struct finfo_object)); zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); intern->ptr = NULL; diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index a82a3f1716..66b1f6f7d9 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -484,7 +484,6 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_ { zend_object_value retval; mysqli_object *intern; - zval *tmp; zend_class_entry *mysqli_base_class; zend_objects_free_object_storage_t free_storage; @@ -502,8 +501,7 @@ PHP_MYSQLI_EXPORT(zend_object_value) mysqli_objects_new(zend_class_entry *class_ (void **) &intern->prop_handler); zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, - (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); /* link object */ if (instanceof_function(class_type, mysqli_link_class_entry TSRMLS_CC)) { diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 404619e9c1..1573290420 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -1552,12 +1552,12 @@ zend_object_value pdo_dbh_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; pdo_dbh_t *dbh; - zval *tmp; dbh = emalloc(sizeof(*dbh)); memset(dbh, 0, sizeof(*dbh)); zend_object_std_init(&dbh->std, ce TSRMLS_CC); - zend_hash_copy(dbh->std.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&dbh->std, ce); + rebuild_object_properties(&dbh->std); dbh->refcount = 1; dbh->def_stmt_ce = pdo_dbstmt_ce; diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 40d10c54b3..5e761053f1 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -2313,14 +2313,13 @@ static int dbstmt_compare(zval *object1, zval *object2 TSRMLS_DC) static zend_object_value dbstmt_clone_obj(zval *zobject TSRMLS_DC) { zend_object_value retval; - zval *tmp; pdo_stmt_t *stmt; pdo_stmt_t *old_stmt; zend_object_handle handle = Z_OBJ_HANDLE_P(zobject); stmt = ecalloc(1, sizeof(*stmt)); zend_object_std_init(&stmt->std, Z_OBJCE_P(zobject) TSRMLS_CC); - zend_hash_copy(stmt->std.properties, &stmt->std.ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&stmt->std, Z_OBJCE_P(zobject)); stmt->refcount = 1; old_stmt = (pdo_stmt_t *)zend_object_store_get_object(zobject TSRMLS_CC); @@ -2436,13 +2435,12 @@ void pdo_dbstmt_free_storage(pdo_stmt_t *stmt TSRMLS_DC) zend_object_value pdo_dbstmt_new(zend_class_entry *ce TSRMLS_DC) { zend_object_value retval; - zval *tmp; pdo_stmt_t *stmt; stmt = emalloc(sizeof(*stmt)); memset(stmt, 0, sizeof(*stmt)); zend_object_std_init(&stmt->std, ce TSRMLS_CC); - zend_hash_copy(stmt->std.properties, &ce->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&stmt->std, ce); stmt->refcount = 1; retval.handle = zend_objects_store_put(stmt, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t)pdo_dbstmt_free_storage, (zend_objects_store_clone_t)dbstmt_clone_obj TSRMLS_CC); @@ -2680,6 +2678,9 @@ static HashTable *row_get_properties(zval *object TSRMLS_DC) return NULL; } + if (!stmt->std.properties) { + rebuild_object_properties(&stmt->std); + } for (i = 0; i < stmt->column_count; i++) { zval *val; MAKE_STD_ZVAL(val); diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 315580615d..c1919afb5f 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -41,6 +41,15 @@ #include "zend_closures.h" #include "zend_extensions.h" +#define reflection_update_property(object, name, value) do { \ + zval *member; \ + MAKE_STD_ZVAL(member); \ + ZVAL_STRINGL(member, name, sizeof(name)-1, 1); \ + zend_std_write_property(object, member, value, NULL TSRMLS_CC); \ + Z_DELREF_P(value); \ + zval_ptr_dtor(&member); \ + } while (0) + /* Class entry pointers */ PHPAPI zend_class_entry *reflector_ptr; PHPAPI zend_class_entry *reflection_exception_ptr; @@ -296,7 +305,6 @@ static void reflection_free_objects_storage(void *object TSRMLS_DC) static zend_object_value reflection_objects_new(zend_class_entry *class_type TSRMLS_DC) { - zval tmp; zend_object_value retval; reflection_object *intern; @@ -304,7 +312,7 @@ static zend_object_value reflection_objects_new(zend_class_entry *class_type TSR intern->zo.ce = class_type; zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); retval.handle = zend_objects_store_put(intern, NULL, reflection_free_objects_storage, NULL TSRMLS_CC); retval.handlers = &reflection_object_handlers; return retval; @@ -1157,7 +1165,7 @@ PHPAPI void zend_reflection_class_factory(zend_class_entry *ce, zval *object TSR intern->ptr = ce; intern->ref_type = REF_TYPE_OTHER; intern->ce = ce; - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); } /* }}} */ @@ -1186,7 +1194,7 @@ static void reflection_extension_factory(zval *object, const char *name_str TSRM intern->ptr = module; intern->ref_type = REF_TYPE_OTHER; intern->ce = NULL; - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); } /* }}} */ @@ -1217,7 +1225,7 @@ static void reflection_parameter_factory(zend_function *fptr, zval *closure_obje intern->ref_type = REF_TYPE_PARAMETER; intern->ce = fptr->common.scope; intern->obj = closure_object; - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); } /* }}} */ @@ -1239,7 +1247,7 @@ static void reflection_function_factory(zend_function *function, zval *closure_o intern->ref_type = REF_TYPE_FUNCTION; intern->ce = NULL; intern->obj = closure_object; - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); } /* }}} */ @@ -1263,8 +1271,8 @@ static void reflection_method_factory(zend_class_entry *ce, zend_function *metho intern->ref_type = REF_TYPE_FUNCTION; intern->ce = ce; intern->obj = closure_object; - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); - zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); + reflection_update_property(object, "class", classname); } /* }}} */ @@ -1310,8 +1318,8 @@ static void reflection_property_factory(zend_class_entry *ce, zend_property_info intern->ref_type = REF_TYPE_PROPERTY; intern->ce = ce; intern->ignore_visibility = 0; - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); - zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); + reflection_update_property(object, "class", classname); } /* }}} */ @@ -1556,7 +1564,7 @@ ZEND_METHOD(reflection_function, __construct) MAKE_STD_ZVAL(name); ZVAL_STRING(name, fptr->common.function_name, 1); - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name TSRMLS_CC); intern->ptr = fptr; intern->ref_type = REF_TYPE_FUNCTION; intern->obj = closure; @@ -2185,7 +2193,7 @@ ZEND_METHOD(reflection_parameter, __construct) } else { ZVAL_NULL(name); } - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); ref = (parameter_reference*) emalloc(sizeof(parameter_reference)); ref->arg_info = &arg_info[position]; @@ -2663,11 +2671,11 @@ ZEND_METHOD(reflection_method, __construct) MAKE_STD_ZVAL(classname); ZVAL_STRINGL(classname, mptr->common.scope->name, mptr->common.scope->name_length, 1); - zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL); + reflection_update_property(object, "class", classname); MAKE_STD_ZVAL(name); ZVAL_STRING(name, mptr->common.function_name, 1); - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); intern->ptr = mptr; intern->ref_type = REF_TYPE_FUNCTION; intern->ce = ce; @@ -3202,7 +3210,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob if (Z_TYPE_P(argument) == IS_OBJECT) { MAKE_STD_ZVAL(classname); ZVAL_STRINGL(classname, Z_OBJCE_P(argument)->name, Z_OBJCE_P(argument)->name_length, 1); - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL); + reflection_update_property(object, "name", classname); intern->ptr = Z_OBJCE_P(argument); if (is_object) { intern->obj = argument; @@ -3219,7 +3227,7 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob MAKE_STD_ZVAL(classname); ZVAL_STRINGL(classname, (*ce)->name, (*ce)->name_length, 1); - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &classname, sizeof(zval *), NULL); + reflection_update_property(object, "name", classname); intern->ptr = *ce; } @@ -3235,14 +3243,63 @@ ZEND_METHOD(reflection_class, __construct) } /* }}} */ +/* {{{ add_class_vars */ +static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC) +{ + HashPosition pos; + zend_property_info *prop_info; + zval *prop, *prop_copy; + char *key; + uint key_len; + ulong num_index; + + zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); + while (zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS) { + zend_hash_get_current_key_ex(&ce->properties_info, &key, &key_len, &num_index, 0, &pos); + zend_hash_move_forward_ex(&ce->properties_info, &pos); + if (((prop_info->flags & ZEND_ACC_SHADOW) && + prop_info->ce != ce) || + ((prop_info->flags & ZEND_ACC_PROTECTED) && + !zend_check_protected(prop_info->ce, ce)) || + ((prop_info->flags & ZEND_ACC_PRIVATE) && + prop_info->ce != ce)) { + continue; + } + prop = NULL; + if (prop_info->offset >= 0) { + if (statics && (prop_info->flags & ZEND_ACC_STATIC) != 0) { + prop = ce->default_static_members_table[prop_info->offset]; + } else if (!statics && (prop_info->flags & ZEND_ACC_STATIC) == 0) { + prop = ce->default_properties_table[prop_info->offset]; + } + } + if (!prop) { + continue; + } + + /* copy: enforce read only access */ + ALLOC_ZVAL(prop_copy); + *prop_copy = *prop; + zval_copy_ctor(prop_copy); + INIT_PZVAL(prop_copy); + + /* this is necessary to make it able to work with default array + * properties, returned to user */ + if (Z_TYPE_P(prop_copy) == IS_CONSTANT_ARRAY || (Z_TYPE_P(prop_copy) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT) { + zval_update_constant(&prop_copy, 1 TSRMLS_CC); + } + + add_assoc_zval(return_value, key, prop_copy); + } +} +/* }}} */ + /* {{{ proto public array ReflectionClass::getStaticProperties() Returns an associative array containing all static property values of the class */ ZEND_METHOD(reflection_class, getStaticProperties) { reflection_object *intern; zend_class_entry *ce; - HashPosition pos; - zval **value; if (zend_parse_parameters_none() == FAILURE) { return; @@ -3253,31 +3310,7 @@ ZEND_METHOD(reflection_class, getStaticProperties) zend_update_class_constants(ce TSRMLS_CC); array_init(return_value); - - zend_hash_internal_pointer_reset_ex(CE_STATIC_MEMBERS(ce), &pos); - - while (zend_hash_get_current_data_ex(CE_STATIC_MEMBERS(ce), (void **) &value, &pos) == SUCCESS) { - uint key_len; - char *key; - ulong num_index; - - if (zend_hash_get_current_key_ex(CE_STATIC_MEMBERS(ce), &key, &key_len, &num_index, 0, &pos) != FAILURE && key) { - char *prop_name, *class_name; - zval *prop_copy; - - zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name); - - /* filter privates from base classes */ - if (!(class_name && class_name[0] != '*' && strcmp(class_name, ce->name))) { - /* copy: enforce read only access */ - ALLOC_ZVAL(prop_copy); - MAKE_COPY_ZVAL(value, prop_copy); - - add_assoc_zval(return_value, prop_name, prop_copy); - } - } - zend_hash_move_forward_ex(CE_STATIC_MEMBERS(ce), &pos); - } + add_class_vars(ce, 1, return_value TSRMLS_CC); } /* }}} */ @@ -3355,51 +3388,15 @@ ZEND_METHOD(reflection_class, getDefaultProperties) { reflection_object *intern; zend_class_entry *ce; - int count, i; - HashTable *ht_list[3]; if (zend_parse_parameters_none() == FAILURE) { return; } GET_REFLECTION_OBJECT_PTR(ce); array_init(return_value); - zend_update_class_constants(ce TSRMLS_CC); - - ht_list[0] = CE_STATIC_MEMBERS(ce); - ht_list[1] = &ce->default_properties; - ht_list[2] = NULL; - - for (i = 0; ht_list[i] != NULL; i++) { - - count = zend_hash_num_elements(ht_list[i]); - if (count > 0) { - HashPosition pos; - zval **prop; - - zend_hash_internal_pointer_reset_ex(ht_list[i], &pos); - while (zend_hash_get_current_data_ex(ht_list[i], (void **) &prop, &pos) == SUCCESS) { - char *key, *class_name, *prop_name; - uint key_len; - ulong num_index; - zval *prop_copy; - - zend_hash_get_current_key_ex(ht_list[i], &key, &key_len, &num_index, 0, &pos); - zend_hash_move_forward_ex(ht_list[i], &pos); - zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name); - if (class_name && class_name[0] != '*' && strcmp(class_name, ce->name)) { - /* filter privates from base classes */ - continue; - } - - /* copy: enforce read only access */ - ALLOC_ZVAL(prop_copy); - MAKE_COPY_ZVAL(prop, prop_copy); - - add_assoc_zval(return_value, prop_name, prop_copy); - } - } - } + add_class_vars(ce, 1, return_value TSRMLS_CC); + add_class_vars(ce, 0, return_value TSRMLS_CC); } /* }}} */ @@ -4564,8 +4561,8 @@ ZEND_METHOD(reflection_property, __construct) ZVAL_STRINGL(classname, ce->name, ce->name_length, 1); ZVAL_STRINGL(propname, name_str, name_len, 1); } - zend_hash_update(Z_OBJPROP_P(object), "class", sizeof("class"), (void **) &classname, sizeof(zval *), NULL); - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &propname, sizeof(zval *), NULL); + reflection_update_property(object, "class", classname); + reflection_update_property(object, "name", propname); reference = (property_reference*) emalloc(sizeof(property_reference)); if (dynam_prop) { @@ -4690,7 +4687,7 @@ ZEND_METHOD(reflection_property, getValue) reflection_object *intern; property_reference *ref; zval *object, name; - zval **member = NULL, *member_p = NULL; + zval *member_p = NULL; METHOD_NOTSTATIC(reflection_property_ptr); GET_REFLECTION_OBJECT_PTR(ref); @@ -4705,11 +4702,13 @@ ZEND_METHOD(reflection_property, getValue) if ((ref->prop.flags & ZEND_ACC_STATIC)) { zend_update_class_constants(intern->ce TSRMLS_CC); - if (zend_hash_quick_find(CE_STATIC_MEMBERS(intern->ce), ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &member) == FAILURE) { + if (!CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name); /* Bails out */ } - MAKE_COPY_ZVAL(member, return_value); + *return_value= *CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]; + zval_copy_ctor(return_value); + INIT_PZVAL(return_value); } else { char *class_name, *prop_name; @@ -4738,7 +4737,6 @@ ZEND_METHOD(reflection_property, setValue) zval *value; int setter_done = 0; zval *tmp; - HashTable *prop_table; METHOD_NOTSTATIC(reflection_property_ptr); GET_REFLECTION_OBJECT_PTR(ref); @@ -4758,33 +4756,34 @@ ZEND_METHOD(reflection_property, setValue) } } zend_update_class_constants(intern->ce TSRMLS_CC); - prop_table = CE_STATIC_MEMBERS(intern->ce); - if (zend_hash_quick_find(prop_table, ref->prop.name, ref->prop.name_length + 1, ref->prop.h, (void **) &variable_ptr) == FAILURE) { + if (!CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]) { php_error_docref(NULL TSRMLS_CC, E_ERROR, "Internal error: Could not find the property %s::%s", intern->ce->name, ref->prop.name); /* Bails out */ } - if (*variable_ptr == value) { - setter_done = 1; - } else { + variable_ptr = &CE_STATIC_MEMBERS(intern->ce)[ref->prop.offset]; + if (*variable_ptr != value) { if (PZVAL_IS_REF(*variable_ptr)) { - zval_dtor(*variable_ptr); - (*variable_ptr)->type = value->type; + zval garbage = **variable_ptr; /* old value should be destroyed */ + + /* To check: can't *variable_ptr be some system variable like error_zval here? */ + Z_TYPE_PP(variable_ptr) = Z_TYPE_P(value); (*variable_ptr)->value = value->value; if (Z_REFCOUNT_P(value) > 0) { zval_copy_ctor(*variable_ptr); } - setter_done = 1; - } - } - if (!setter_done) { - zval **foo; + zval_dtor(&garbage); + } else { + zval *garbage = *variable_ptr; - Z_ADDREF_P(value); - if (PZVAL_IS_REF(value)) { - SEPARATE_ZVAL(&value); + /* if we assign referenced variable, we should separate it */ + Z_ADDREF_P(value); + if (PZVAL_IS_REF(value)) { + SEPARATE_ZVAL(&value); + } + *variable_ptr = value; + zval_ptr_dtor(&garbage); } - zend_hash_quick_update(prop_table, ref->prop.name, ref->prop.name_length+1, ref->prop.h, &value, sizeof(zval *), (void **) &foo); } } else { char *class_name, *prop_name; @@ -4917,7 +4916,7 @@ ZEND_METHOD(reflection_extension, __construct) free_alloca(lcname, use_heap); MAKE_STD_ZVAL(name); ZVAL_STRING(name, module->name, 1); - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property( object, "name", name); intern->ptr = module; intern->ref_type = REF_TYPE_OTHER; intern->ce = NULL; @@ -5269,7 +5268,7 @@ ZEND_METHOD(reflection_zend_extension, __construct) } MAKE_STD_ZVAL(name); ZVAL_STRING(name, extension->name, 1); - zend_hash_update(Z_OBJPROP_P(object), "name", sizeof("name"), (void **) &name, sizeof(zval *), NULL); + reflection_update_property(object, "name", name); intern->ptr = extension; intern->ref_type = REF_TYPE_OTHER; intern->ce = NULL; @@ -5783,7 +5782,7 @@ static zend_object_handlers *zend_std_obj_handlers; static void _reflection_write_property(zval *object, zval *member, zval *value, const zend_literal *key TSRMLS_DC) { if ((Z_TYPE_P(member) == IS_STRING) - && zend_hash_exists(&Z_OBJCE_P(object)->default_properties, Z_STRVAL_P(member), Z_STRLEN_P(member)+1) + && zend_hash_exists(&Z_OBJCE_P(object)->properties_info, Z_STRVAL_P(member), Z_STRLEN_P(member)+1) && ((Z_STRLEN_P(member) == sizeof("name") - 1 && !memcmp(Z_STRVAL_P(member), "name", sizeof("name"))) || (Z_STRLEN_P(member) == sizeof("class") - 1 && !memcmp(Z_STRVAL_P(member), "class", sizeof("class"))))) { diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt index 733c4c7e4d..ffd81ffb87 100644 --- a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt +++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001.phpt @@ -3,6 +3,8 @@ ReflectionClass::getStaticPropertyValue() --CREDITS-- Robin Fernandes <robinf@php.net> Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.3 or below needed'); ?> --FILE-- <?php class A { diff --git a/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt new file mode 100644 index 0000000000..c299412e13 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_getStaticPropertyValue_001_2_4.phpt @@ -0,0 +1,61 @@ +--TEST-- +ReflectionClass::getStaticPropertyValue() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?> +--FILE-- +<?php +class A { + static private $privateOverridden = "original private"; + static protected $protectedOverridden = "original protected"; + static public $publicOverridden = "original public"; +} + +class B extends A { + static private $privateOverridden = "changed private"; + static protected $protectedOverridden = "changed protected"; + static public $publicOverridden = "changed public"; +} + +echo "Retrieving static values from A:\n"; +$rcA = new ReflectionClass('A'); +var_dump($rcA->getStaticPropertyValue("privateOverridden", "default value")); +var_dump($rcA->getStaticPropertyValue("\0A\0privateOverridden")); +var_dump($rcA->getStaticPropertyValue("protectedOverridden", "default value")); +var_dump($rcA->getStaticPropertyValue("\0*\0protectedOverridden")); +var_dump($rcA->getStaticPropertyValue("publicOverridden")); + +echo "\nRetrieving static values from B:\n"; +$rcB = new ReflectionClass('B'); +var_dump($rcB->getStaticPropertyValue("\0A\0privateOverridden")); +var_dump($rcB->getStaticPropertyValue("\0B\0privateOverridden")); +var_dump($rcB->getStaticPropertyValue("\0*\0protectedOverridden")); +var_dump($rcB->getStaticPropertyValue("publicOverridden")); + +echo "\nRetrieving non-existent values from A with no default value:\n"; +try { + var_dump($rcA->getStaticPropertyValue("protectedOverridden")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump($rcA->getStaticPropertyValue("privateOverridden")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Retrieving static values from A: +string(13) "default value" + +Fatal error: Uncaught exception 'ReflectionException' with message 'Class A does not have a property named ' in %sReflectionClass_getStaticPropertyValue_001_2_4.php:%d +Stack trace: +#0 %sReflectionClass_getStaticPropertyValue_001_2_4.php(%d): ReflectionClass->getStaticPropertyValue('?A?privateOverr...') +#1 {main} + thrown in %sReflectionClass_getStaticPropertyValue_001_2_4.php on line %d diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt index 082ef676cd..9e8f01e679 100644 --- a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt @@ -3,6 +3,8 @@ ReflectionClass::setStaticPropertyValue() --CREDITS-- Robin Fernandes <robinf@php.net> Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.3 or below needed'); ?> --FILE-- <?php class A { diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt new file mode 100644 index 0000000000..1092f6553d --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001_2_4.phpt @@ -0,0 +1,61 @@ +--TEST-- +ReflectionClass::setStaticPropertyValue() +--CREDITS-- +Robin Fernandes <robinf@php.net> +Steve Seear <stevseea@php.net> +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?> +--FILE-- +<?php +class A { + static private $privateOverridden = "original private"; + static protected $protectedOverridden = "original protected"; + static public $publicOverridden = "original public"; +} + +class B extends A { + static private $privateOverridden = "changed private"; + static protected $protectedOverridden = "changed protected"; + static public $publicOverridden = "changed public"; +} + +echo "Set static values in A:\n"; +$rcA = new ReflectionClass('A'); +$rcA->setStaticPropertyValue("\0A\0privateOverridden", "new value 1"); +$rcA->setStaticPropertyValue("\0*\0protectedOverridden", "new value 2"); +$rcA->setStaticPropertyValue("publicOverridden", "new value 3"); +print_r($rcA->getStaticProperties()); + +echo "\nSet static values in B:\n"; +$rcB = new ReflectionClass('B'); +$rcB->setStaticPropertyValue("\0A\0privateOverridden", "new value 4"); +$rcB->setStaticPropertyValue("\0B\0privateOverridden", "new value 5"); +$rcB->setStaticPropertyValue("\0*\0protectedOverridden", "new value 6"); +$rcB->setStaticPropertyValue("publicOverridden", "new value 7"); +print_r($rcA->getStaticProperties()); +print_r($rcB->getStaticProperties()); + +echo "\nSet non-existent values from A with no default value:\n"; +try { + var_dump($rcA->setStaticPropertyValue("protectedOverridden", "new value 8")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump($rcA->setStaticPropertyValue("privateOverridden", "new value 9")); + echo "you should not see this"; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +Set static values in A: + +Fatal error: Uncaught exception 'ReflectionException' with message 'Class A does not have a property named ' in %sReflectionClass_setStaticPropertyValue_001_2_4.php:%d +Stack trace: +#0 %sReflectionClass_setStaticPropertyValue_001_2_4.php(%d): ReflectionClass->setStaticPropertyValue('?A?privateOverr...', 'new value 1') +#1 {main} + thrown in %sReflectionClass_setStaticPropertyValue_001_2_4.php on line %d diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index b061125f97..f98e8fa16e 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -81,11 +81,17 @@ typedef struct _spl_array_object { static inline HashTable *spl_array_get_hash_table(spl_array_object* intern, int check_std_props TSRMLS_DC) { /* {{{ */ if ((intern->ar_flags & SPL_ARRAY_IS_SELF) != 0) { + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } return intern->std.properties; } else if ((intern->ar_flags & SPL_ARRAY_USE_OTHER) && (check_std_props == 0 || (intern->ar_flags & SPL_ARRAY_STD_PROP_LIST) == 0) && Z_TYPE_P(intern->array) == IS_OBJECT) { spl_array_object *other = (spl_array_object*)zend_object_store_get_object(intern->array TSRMLS_CC); return spl_array_get_hash_table(other, check_std_props TSRMLS_CC); } else if ((intern->ar_flags & ((check_std_props ? SPL_ARRAY_STD_PROP_LIST : 0) | SPL_ARRAY_IS_SELF)) != 0) { + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } return intern->std.properties; } else { return HASH_OF(intern->array); @@ -173,7 +179,7 @@ static zend_object_value spl_array_object_new_ex(zend_class_entry *class_type, s ALLOC_INIT_ZVAL(intern->retval); zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); intern->ar_flags = 0; intern->serialize_data = NULL; @@ -728,6 +734,10 @@ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* *is_temp = 0; + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } + if (HASH_OF(intern->array) == intern->std.properties) { return intern->std.properties; } else { @@ -1584,6 +1594,9 @@ smart_str spl_array_serialize_helper(spl_array_object *intern, php_serialize_dat /* members */ smart_str_appendl(&buf, "m:", 2); INIT_PZVAL(&members); + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } Z_ARRVAL(members) = intern->std.properties; Z_TYPE(members) = IS_ARRAY; pmembers = &members; @@ -1719,6 +1732,9 @@ void spl_array_unserialize_helper(spl_array_object *intern, const unsigned char } /* copy members */ + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } zend_hash_copy(intern->std.properties, Z_ARRVAL_P(pmembers), (copy_ctor_func_t) zval_add_ref, (void *) NULL, sizeof(zval *)); zval_ptr_dtor(&pmembers); diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index 23044122a9..cc049a1e27 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -136,7 +136,6 @@ static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_ty { zend_object_value retval; spl_filesystem_object *intern; - zval *tmp; intern = emalloc(sizeof(spl_filesystem_object)); memset(intern, 0, sizeof(spl_filesystem_object)); @@ -146,7 +145,7 @@ static zend_object_value spl_filesystem_object_new_ex(zend_class_entry *class_ty if (obj) *obj = intern; zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t) zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_filesystem_object_free_storage, NULL TSRMLS_CC); retval.handlers = &spl_filesystem_object_handlers; @@ -549,6 +548,10 @@ static HashTable* spl_filesystem_object_get_debug_info(zval *obj, int *is_temp T *is_temp = 1; + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } + ALLOC_HASHTABLE(rv); ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 3, 0); diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index af7389cf65..d3b0b38b91 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -367,7 +367,6 @@ static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type, { zend_object_value retval; spl_dllist_object *intern; - zval *tmp; zend_class_entry *parent = class_type; int inherited = 0; @@ -376,7 +375,7 @@ static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type, ALLOC_INIT_ZVAL(intern->retval); zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); intern->flags = 0; intern->traverse_position = 0; @@ -523,6 +522,9 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp TSRML INIT_PZVAL(&zrv); Z_ARRVAL(zrv) = intern->debug_info; + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 783c854e5e..73f5fcbd01 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -150,21 +150,22 @@ static void spl_fixedarray_copy(spl_fixedarray *to, spl_fixedarray *from TSRMLS_ static HashTable* spl_fixedarray_object_get_properties(zval *obj TSRMLS_DC) /* {{{{ */ { spl_fixedarray_object *intern = (spl_fixedarray_object*)zend_object_store_get_object(obj TSRMLS_CC); + HashTable *ht = zend_std_get_properties(obj TSRMLS_CC); int i = 0; if (intern->array) { for (i = 0; i < intern->array->size; i++) { if (intern->array->elements[i]) { - zend_hash_index_update(intern->std.properties, i, (void *)&intern->array->elements[i], sizeof(zval *), NULL); + zend_hash_index_update(ht, i, (void *)&intern->array->elements[i], sizeof(zval *), NULL); Z_ADDREF_P(intern->array->elements[i]); } else { - zend_hash_index_update(intern->std.properties, i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL); + zend_hash_index_update(ht, i, (void *)&EG(uninitialized_zval_ptr), sizeof(zval *), NULL); Z_ADDREF_P(EG(uninitialized_zval_ptr)); } } } - return intern->std.properties; + return ht; } /* }}}} */ @@ -199,7 +200,6 @@ static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_ty { zend_object_value retval; spl_fixedarray_object *intern; - zval *tmp; zend_class_entry *parent = class_type; int inherited = 0; @@ -208,7 +208,7 @@ static zend_object_value spl_fixedarray_object_new_ex(zend_class_entry *class_ty ALLOC_INIT_ZVAL(intern->retval); zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); intern->current = 0; intern->flags = 0; diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index 6f11ef92cf..45ec68096a 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -385,7 +385,6 @@ static zend_object_value spl_heap_object_new_ex(zend_class_entry *class_type, sp { zend_object_value retval; spl_heap_object *intern; - zval *tmp; zend_class_entry *parent = class_type; int inherited = 0; @@ -394,7 +393,7 @@ static zend_object_value spl_heap_object_new_ex(zend_class_entry *class_type, sp ALLOC_INIT_ZVAL(intern->retval); zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); intern->flags = 0; intern->fptr_cmp = NULL; @@ -529,6 +528,10 @@ static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zv *is_temp = 0; + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } + if (intern->debug_info == NULL) { ALLOC_HASHTABLE(intern->debug_info); ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index d71f4e80da..c8d0e64461 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -810,7 +810,6 @@ static zend_object_value spl_RecursiveIteratorIterator_new_ex(zend_class_entry * { zend_object_value retval; spl_recursive_it_object *intern; - zval *tmp; intern = emalloc(sizeof(spl_recursive_it_object)); memset(intern, 0, sizeof(spl_recursive_it_object)); @@ -825,7 +824,7 @@ static zend_object_value spl_RecursiveIteratorIterator_new_ex(zend_class_entry * } zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_RecursiveIteratorIterator_free_storage, NULL TSRMLS_CC); retval.handlers = &spl_handlers_rec_it_it; @@ -1960,14 +1959,13 @@ static zend_object_value spl_dual_it_new(zend_class_entry *class_type TSRMLS_DC) { zend_object_value retval; spl_dual_it_object *intern; - zval *tmp; intern = emalloc(sizeof(spl_dual_it_object)); memset(intern, 0, sizeof(spl_dual_it_object)); intern->dit_type = DIT_Unknown; zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) spl_dual_it_free_storage, NULL TSRMLS_CC); retval.handlers = &spl_handlers_dual_it; diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index c8f80a1fda..1e09ca98b9 100755 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -253,14 +253,13 @@ static zend_object_value spl_object_storage_new_ex(zend_class_entry *class_type, zend_object_value retval; spl_SplObjectStorage *intern; zend_class_entry *parent = class_type; - zval *tmp; intern = emalloc(sizeof(spl_SplObjectStorage)); memset(intern, 0, sizeof(spl_SplObjectStorage)); *obj = intern; zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); zend_hash_init(&intern->storage, 0, NULL, (void (*)(void *))spl_object_storage_dtor, 0); @@ -669,7 +668,7 @@ SPL_METHOD(SplObjectStorage, serialize) /* members */ smart_str_appendl(&buf, "m:", 2); INIT_PZVAL(&members); - Z_ARRVAL(members) = intern->std.properties; + Z_ARRVAL(members) = zend_std_get_properties(getThis() TSRMLS_CC); Z_TYPE(members) = IS_ARRAY; pmembers = &members; php_var_serialize(&buf, &pmembers, &var_hash TSRMLS_CC); /* finishes the string */ @@ -767,6 +766,9 @@ SPL_METHOD(SplObjectStorage, unserialize) } /* copy members */ + if (!intern->std.properties) { + rebuild_object_properties(&intern->std); + } zend_hash_copy(intern->std.properties, Z_ARRVAL_P(pmembers), (copy_ctor_func_t) zval_add_ref, (void *) NULL, sizeof(zval *)); zval_ptr_dtor(&pmembers); diff --git a/ext/sqlite/sqlite.c b/ext/sqlite/sqlite.c index db0dab40ba..1f33caf43b 100644 --- a/ext/sqlite/sqlite.c +++ b/ext/sqlite/sqlite.c @@ -1154,14 +1154,13 @@ static void sqlite_object_free_storage(void *object TSRMLS_DC) static void sqlite_object_new(zend_class_entry *class_type, zend_object_handlers *handlers, zend_object_value *retval TSRMLS_DC) { sqlite_object *intern; - zval *tmp; intern = emalloc(sizeof(sqlite_object)); memset(intern, 0, sizeof(sqlite_object)); zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - + object_properties_init(&intern->std, class_type); + retval->handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) sqlite_object_free_storage, NULL TSRMLS_CC); retval->handlers = handlers; } diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index 00364b0dd4..643e1a07bc 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -1933,7 +1933,6 @@ static void php_sqlite3_result_object_free_storage(void *object TSRMLS_DC) /* {{ static zend_object_value php_sqlite3_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { - zval *tmp; zend_object_value retval; php_sqlite3_db_object *intern; @@ -1946,7 +1945,7 @@ static zend_object_value php_sqlite3_object_new(zend_class_entry *class_type TSR zend_llist_init(&(intern->free_list), sizeof(php_sqlite3_free_list *), (llist_dtor_func_t)php_sqlite3_free_list_dtor, 0); zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_object_free_storage, NULL TSRMLS_CC); retval.handlers = (zend_object_handlers *) &sqlite3_object_handlers; @@ -1957,7 +1956,6 @@ static zend_object_value php_sqlite3_object_new(zend_class_entry *class_type TSR static zend_object_value php_sqlite3_stmt_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { - zval *tmp; zend_object_value retval; php_sqlite3_stmt *intern; @@ -1968,7 +1966,7 @@ static zend_object_value php_sqlite3_stmt_object_new(zend_class_entry *class_typ intern->db_obj_zval = NULL; zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_stmt_object_free_storage, NULL TSRMLS_CC); retval.handlers = (zend_object_handlers *) &sqlite3_stmt_object_handlers; @@ -1979,7 +1977,6 @@ static zend_object_value php_sqlite3_stmt_object_new(zend_class_entry *class_typ static zend_object_value php_sqlite3_result_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { - zval *tmp; zend_object_value retval; php_sqlite3_result *intern; @@ -1992,7 +1989,7 @@ static zend_object_value php_sqlite3_result_object_new(zend_class_entry *class_t intern->stmt_obj_zval = NULL; zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref,(void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); retval.handle = zend_objects_store_put(intern, NULL, (zend_objects_free_object_storage_t) php_sqlite3_result_object_free_storage, NULL TSRMLS_CC); retval.handlers = (zend_object_handlers *) &sqlite3_result_object_handlers; diff --git a/ext/standard/incomplete_class.c b/ext/standard/incomplete_class.c index ce9a95375a..f42c64d8b9 100644 --- a/ext/standard/incomplete_class.c +++ b/ext/standard/incomplete_class.c @@ -109,8 +109,6 @@ static zend_object_value php_create_incomplete_object(zend_class_entry *class_ty value = zend_objects_new(&object, class_type TSRMLS_CC); value.handlers = &php_incomplete_object_handlers; - ALLOC_HASHTABLE(object->properties); - zend_hash_init(object->properties, 0, NULL, ZVAL_PTR_DTOR, 0); return value; } diff --git a/ext/standard/tests/array/array_fill_object.phpt b/ext/standard/tests/array/array_fill_object.phpt index 48aac60b55..86773b17f8 100644 --- a/ext/standard/tests/array/array_fill_object.phpt +++ b/ext/standard/tests/array/array_fill_object.phpt @@ -1,5 +1,7 @@ --TEST-- Test array_fill() function : usage variations - various object values for 'val' argument +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '>=')) die('skip ZendEngine 2.3 or below needed'); ?> --FILE-- <?php /* Prototype : array array_fill(int $start_key, int $num, mixed $val) diff --git a/ext/standard/tests/array/array_fill_object_2_4.phpt b/ext/standard/tests/array/array_fill_object_2_4.phpt new file mode 100644 index 0000000000..fb8179766c --- /dev/null +++ b/ext/standard/tests/array/array_fill_object_2_4.phpt @@ -0,0 +1,434 @@ +--TEST-- +Test array_fill() function : usage variations - various object values for 'val' argument +--SKIPIF-- +<?php if (version_compare(zend_version(), '2.4.0', '<')) die('skip ZendEngine 2.4 needed'); ?> +--FILE-- +<?php +/* Prototype : array array_fill(int $start_key, int $num, mixed $val) + * Description: Create an array containing num elements starting with index start_key each initialized to val + * Source code: ext/standard/array.c + */ + +/* + * testing array_fill() by passing various object values for 'val' argument + */ + +echo "*** Testing array_fill() : usage variations ***\n"; + +// Initialise function arguments not being substituted +$start_key = 0; +$num = 2; + +// class without a member +class Test +{ +} + +//class with public member, static member , constant and consturctor to initialize the public member +class Test1 +{ + const test1_constant = "test1"; + public static $test1_static = 0; + public $member1; + var $var1 = 30; + var $var2; + + function __construct($value1 , $value2) + { + $this->member1 = $value1; + $this->var2 = $value2; + } +} + +// child class which inherits parent class test1 +class Child_test1 extends Test1 +{ + public $member2; + + function __construct($value1 , $value2 , $value3) + { + parent::__construct($value1 , $value2); + $this->member2 = $value3; + } +} + +//class with private member, static member, constant and constructor to initialize the private member +class Test2 +{ + const test2_constant = "test2"; + public static $test2_static = 0; + private $member1; + var $var1 = 30; + var $var2; + + function __construct($value1 , $value2) + { + $this->member1 = $value1; + $this->var2 = $value2; + } +} + +// child class which inherits parent class test2 +class Child_test2 extends Test2 +{ + private $member1; + + function __construct($value1 , $value2 , $value3) + { + parent::__construct($value1 , $value2); + $this->member1 = $value3; + } +} + +// class with protected member, static member, constant and consturctor to initialize the protected member +class Test3 +{ + const test3_constant = "test3"; + public static $test3_static = 0; + protected $member1; + var $var1 = 30; + var $var2; + + function __construct($value1 , $value2) + { + $this->member1 = $value1; + $this->var2 = $value2; + } +} + +// child class which inherits parent class test3 +class Child_test3 extends Test3 +{ + protected $member1; + + function __construct($value1 , $value2 , $value3) + { + parent::__construct($value1 , $value2); + $this->member1 = $value3; + } +} + +// class with public, private, protected members, static, constant members and constructor to initialize all the members +class Test4 +{ + const test4_constant = "test4"; + public static $test4_static = 0; + public $member1; + private $member2; + protected $member3; + + function __construct($value1 , $value2 , $value3) + { + $this->member1 = $value1; + $this->member2 = $value2; + $this->member3 = $value3; + } +} + +// child class which inherits parent class test4 +class Child_test4 extends Test4 +{ + var $var1; + + function __construct($value1 , $value2 , $value3 , $value4) + { + parent::__construct($value1 , $value2 , $value3); + $this->var1 = $value4; + } +} + +// abstract class with public, private, protected members +abstract class AbstractClass +{ + public $member1; + private $member2; + protected $member3; + var $var1 = 30; + + abstract protected function display(); +} + +// implement abstract 'AbstractClass' class +class ConcreteClass1 extends AbstractClass +{ + protected function display() + { + echo "class name is ConcreteClass1 \n"; + } +} + + +// declarationn of the interface 'iTemplate' +interface iTemplate +{ + public function display(); +} + +// implement the interface 'iTemplate' +class Template1 implements iTemplate +{ + public function display() + { + echo "class name is Template1\n"; + } +} + +//array of object values for 'val' argument +$objects = array( + + /* 1 */ new Test(), + new Test1(100 , 101), + new Child_test1(100 , 101 , 102), + new Test2(100 , 101), + /* 5 */ new Child_test2(100 , 101 , 102), + new Test3(100 , 101), + new Child_test3(100 , 101 , 102), + new Test4( 100 , 101 , 102), + new Child_test4(100 , 101 , 102 , 103), + new ConcreteClass1(), + /* 11 */ new Template1() +); + +// loop through each element of the array for 'val' argument +// check the working of array_fill() +echo "--- Testing array_fill() with different object values for 'val' argument ---\n"; +$counter = 1; +for($index = 0; $index < count($objects); $index ++) +{ + echo "-- Iteration $counter --\n"; + $val = $objects[$index]; + + var_dump( array_fill($start_key,$num,$val) ); + + $counter++; +} + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_fill() : usage variations *** +--- Testing array_fill() with different object values for 'val' argument --- +-- Iteration 1 -- +array(2) { + [0]=> + object(Test)#%d (0) { + } + [1]=> + object(Test)#%d (0) { + } +} +-- Iteration 2 -- +array(2) { + [0]=> + object(Test1)#%d (3) { + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Test1)#%d (3) { + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 3 -- +array(2) { + [0]=> + object(Child_test1)#%d (4) { + ["member2"]=> + int(102) + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Child_test1)#%d (4) { + ["member2"]=> + int(102) + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 4 -- +array(2) { + [0]=> + object(Test2)#%d (3) { + ["member1":"Test2":private]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Test2)#%d (3) { + ["member1":"Test2":private]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 5 -- +array(2) { + [0]=> + object(Child_test2)#%d (4) { + ["member1":"Child_test2":private]=> + int(102) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + ["member1":"Test2":private]=> + int(100) + } + [1]=> + object(Child_test2)#%d (4) { + ["member1":"Child_test2":private]=> + int(102) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + ["member1":"Test2":private]=> + int(100) + } +} +-- Iteration 6 -- +array(2) { + [0]=> + object(Test3)#%d (3) { + ["member1":protected]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Test3)#%d (3) { + ["member1":protected]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 7 -- +array(2) { + [0]=> + object(Child_test3)#%d (3) { + ["member1":protected]=> + int(102) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Child_test3)#%d (3) { + ["member1":protected]=> + int(102) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 8 -- +array(2) { + [0]=> + object(Test4)#%d (3) { + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + } + [1]=> + object(Test4)#%d (3) { + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + } +} +-- Iteration 9 -- +array(2) { + [0]=> + object(Child_test4)#%d (4) { + ["var1"]=> + int(103) + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + } + [1]=> + object(Child_test4)#%d (4) { + ["var1"]=> + int(103) + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + } +} +-- Iteration 10 -- +array(2) { + [0]=> + object(ConcreteClass1)#%d (4) { + ["member1"]=> + NULL + ["member2":"AbstractClass":private]=> + NULL + ["member3":protected]=> + NULL + ["var1"]=> + int(30) + } + [1]=> + object(ConcreteClass1)#%d (4) { + ["member1"]=> + NULL + ["member2":"AbstractClass":private]=> + NULL + ["member3":protected]=> + NULL + ["var1"]=> + int(30) + } +} +-- Iteration 11 -- +array(2) { + [0]=> + object(Template1)#%d (0) { + } + [1]=> + object(Template1)#%d (0) { + } +} +Done diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index 85d9740821..f48b4f5bf1 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -676,13 +676,11 @@ static void tidy_object_new(zend_class_entry *class_type, zend_object_handlers * zend_object_value *retval, tidy_obj_type objtype TSRMLS_DC) { PHPTidyObj *intern; - zval *tmp; intern = emalloc(sizeof(PHPTidyObj)); memset(intern, 0, sizeof(PHPTidyObj)); zend_object_std_init(&intern->std, class_type TSRMLS_CC); - - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); switch(objtype) { case is_node: diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index a151062184..30de80f41d 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -391,7 +391,6 @@ zend_object_value xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC) { zend_object_value retval; xmlreader_object *intern; - zval *tmp; intern = emalloc(sizeof(xmlreader_object)); memset(&intern->std, 0, sizeof(zend_object)); @@ -401,7 +400,7 @@ zend_object_value xmlreader_objects_new(zend_class_entry *class_type TSRMLS_DC) intern->prop_handler = &xmlreader_prop_handlers; zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); retval.handle = zend_objects_store_put(intern, (zend_objects_store_dtor_t)zend_objects_destroy_object, (zend_objects_free_object_storage_t) xmlreader_objects_free_storage, xmlreader_objects_clone TSRMLS_CC); intern->handle = retval.handle; retval.handlers = &xmlreader_object_handlers; diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index e26c6dc7e1..365fc82429 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -143,7 +143,6 @@ static void xmlwriter_object_free_storage(void *object TSRMLS_DC) static zend_object_value xmlwriter_object_new(zend_class_entry *class_type TSRMLS_DC) { ze_xmlwriter_object *intern; - zval *tmp; zend_object_value retval; intern = emalloc(sizeof(ze_xmlwriter_object)); @@ -151,8 +150,7 @@ static zend_object_value xmlwriter_object_new(zend_class_entry *class_type TSRML intern->xmlwriter_ptr = NULL; zend_object_std_init(&intern->zo, class_type TSRMLS_CC); - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, - (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); retval.handle = zend_objects_store_put(intern, NULL, diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index f177f42e66..53e5e06b8d 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -115,7 +115,6 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC) { zend_object_value retval; xsl_object *intern; - zval *tmp; intern = emalloc(sizeof(xsl_object)); intern->ptr = NULL; @@ -129,7 +128,7 @@ zend_object_value xsl_objects_new(zend_class_entry *class_type TSRMLS_DC) intern->profiling = NULL; zend_object_std_init(&intern->std, class_type TSRMLS_CC); - zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->std, class_type); ALLOC_HASHTABLE(intern->parameter); zend_hash_init(intern->parameter, 0, NULL, ZVAL_PTR_DTOR, 0); ALLOC_HASHTABLE(intern->registered_phpfunctions); diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index ba89cce5f3..7645c56ada 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -971,7 +971,7 @@ static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */ ulong num_key; obj = (ze_zip_object *)zend_objects_get_address(object TSRMLS_CC); - props = obj->zo.properties; + props = zend_std_get_properties(object TSRMLS_CC); if (obj->prop_handler == NULL) { return NULL; @@ -988,7 +988,7 @@ static HashTable *php_zip_get_properties(zval *object TSRMLS_DC)/* {{{ */ zend_hash_update(props, key, key_len, (void *)&val, sizeof(zval *), NULL); zend_hash_move_forward_ex(obj->prop_handler, &pos); } - return obj->zo.properties; + return props; } /* }}} */ @@ -1040,7 +1040,6 @@ static void php_zip_object_free_storage(void *object TSRMLS_DC) /* {{{ */ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { ze_zip_object *intern; - zval *tmp; zend_object_value retval; intern = emalloc(sizeof(ze_zip_object)); @@ -1060,8 +1059,7 @@ static zend_object_value php_zip_object_new(zend_class_entry *class_type TSRMLS_ intern->zo.ce = class_type; #endif - zend_hash_copy(intern->zo.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, - (void *) &tmp, sizeof(zval *)); + object_properties_init(&intern->zo, class_type); retval.handle = zend_objects_store_put(intern, NULL, |
