Marcus Boerger schrieb:

regarding static props the solution is to define another hash table
in the class_entry that holdes the initial values for the static
variables. During minit these would be copied to the used hash table,
done. But even though the solution is pretty easy i do not know if we
really want to support that. We have default properties and all that
stuff already.

I attached a patch, which fixes the static property issue for me,
though I didn't test as a webserver module yet.

> Can't we simply check if default values for static
> properties wouldn't do the job and if there is something missing in
> that?

Huh? I even think that zend_std_get_static_property() is not enough...
This forces you to have real zvals for your static properties.
Maybe a minor issue (but still an issue :)

> class consts should be easy and we two times had a patch for that.
> And i definitively ask to support that since otherwise we flood our
> namespace, see pdo, spl and the amount of defines there. With a peep
> to pecl i see tons of more consts (especially in http).

The patch also contains API for class constants, tough valgrind reports
some odd errors about the constants_table (among "some" others...)

Anyway, I'd be glad if the patch could be reviewed, fixed (as it's most
probably not totally accurate) and -even partially- applied.

Thanks,
Michael
Index: Zend/zend.h
===================================================================
RCS file: /repository/ZendEngine2/zend.h,v
retrieving revision 1.293
diff -u -r1.293 zend.h
--- Zend/zend.h 3 Aug 2005 13:30:46 -0000       1.293
+++ Zend/zend.h 9 Aug 2005 21:56:06 -0000
@@ -331,7 +331,8 @@
        HashTable function_table;
        HashTable default_properties;
        HashTable properties_info;
-       HashTable *static_members;
+       HashTable default_static_properties;
+       HashTable static_properties;
        HashTable constants_table;
        struct _zend_function_entry *builtin_functions;
 
Index: Zend/zend_API.c
===================================================================
RCS file: /repository/ZendEngine2/zend_API.c,v
retrieving revision 1.296
diff -u -r1.296 zend_API.c
--- Zend/zend_API.c     8 Aug 2005 14:25:05 -0000       1.296
+++ Zend/zend_API.c     9 Aug 2005 21:56:11 -0000
@@ -759,7 +759,7 @@
 
                *scope = class_type;
                zend_hash_apply_with_argument(&class_type->default_properties, 
(apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
-               zend_hash_apply_with_argument(class_type->static_members, 
(apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
+               
zend_hash_apply_with_argument(&class_type->default_static_properties, 
(apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
                *scope = old_scope;
                class_type->constants_updated = 1;
        }
@@ -2126,7 +2126,7 @@
                access_type |= ZEND_ACC_PUBLIC;
        }
        if (access_type & ZEND_ACC_STATIC) {
-               target_symbol_table = ce->static_members;
+               target_symbol_table = &ce->default_static_properties;
        } else {
                target_symbol_table = &ce->default_properties;
        }
@@ -2382,6 +2382,155 @@
        return value;
 }
 
+
+static inline zval *new_zval(zend_bool persistent)
+{
+       zval *z = pemalloc(sizeof(zval), persistent);
+       INIT_PZVAL(z);
+       return z;
+}
+
+static inline zval *tmp_zval(void)
+{
+       zval *z;
+       ALLOC_ZVAL(z);
+       z->is_ref = 0;
+       z->refcount = 0;
+       return z;
+}
+
+ZEND_API int zend_declare_class_constant(zend_class_entry *ce, char *name, 
size_t name_length, zval *value TSRMLS_DC)
+{
+       return zend_hash_update(&ce->constants_table, name, name_length, 
&value, sizeof(zval *), NULL);
+}
+
+ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, char 
*name, size_t name_length, long value TSRMLS_DC)
+{
+       zval *constant = new_zval(ce->type & ZEND_INTERNAL_CLASS);
+       ZVAL_LONG(constant, value);
+       return zend_declare_class_constant(ce, name, name_length, constant 
TSRMLS_CC);
+}
+
+ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, char 
*name, size_t name_length, zend_bool value TSRMLS_DC)
+{
+       zval *constant = new_zval(ce->type & ZEND_INTERNAL_CLASS);
+       ZVAL_BOOL(constant, value);
+       return zend_declare_class_constant(ce, name, name_length, constant 
TSRMLS_CC);
+}
+
+ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, char 
*name, size_t name_length, double value TSRMLS_DC)
+{
+       zval *constant = new_zval(ce->type & ZEND_INTERNAL_CLASS);
+       ZVAL_DOUBLE(constant, value);
+       return zend_declare_class_constant(ce, name, name_length, constant 
TSRMLS_CC);
+}
+
+ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, char 
*name, size_t name_length, char *value TSRMLS_DC)
+{
+       return zend_declare_class_constant_stringl(ce, name, name_length, 
value, strlen(value) TSRMLS_CC);
+}
+
+ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, char 
*name, size_t name_length, char *value, size_t value_length TSRMLS_DC)
+{
+       zval *constant = new_zval(ce->type & ZEND_INTERNAL_CLASS);
+       if (ce->type & ZEND_INTERNAL_CLASS) {
+               ZVAL_STRINGL(constant, zend_strndup(value, value_length), 
value_length, 0);
+       } else {
+               ZVAL_STRINGL(constant, value, value_length, 1);
+       }
+       return zend_declare_class_constant(ce, name, name_length, constant 
TSRMLS_CC);
+}
+
+
+ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, 
size_t name_len, zval *value TSRMLS_DC)
+{
+       int retval;
+       zval **property = NULL;
+       zend_class_entry *old_scope = EG(scope);
+       
+       EG(scope) = scope;
+       
+       if (!(property = zend_std_get_static_property(scope, name, name_len, 0 
TSRMLS_CC))) {
+               retval = FAILURE;
+       } else if (*property == value) {
+               retval = SUCCESS;
+       } else {
+               if (PZVAL_IS_REF(*property)) {
+                       zval_dtor(*property);
+                       (*property)->type = value->type;
+                       (*property)->value = value->value;
+                       
+                       if (value->refcount) {
+                               zval_copy_ctor(*property);
+                       }
+                       
+                       retval = SUCCESS;
+               } else {
+                       value->refcount++;
+                       if (PZVAL_IS_REF(value)) {
+                               SEPARATE_ZVAL(&value);
+                       }
+                       
+                       retval = zend_hash_update(&scope->static_properties, 
name, name_len, &value, sizeof(zval *), NULL);
+               }
+       }
+       
+       if (!value->refcount) {
+               zval_dtor(value);
+               FREE_ZVAL(value);
+       }
+       
+       EG(scope) = old_scope;
+       
+       return retval;
+}
+
+ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char 
*name, size_t name_len, zend_bool value TSRMLS_DC)
+{
+       zval *tmp = tmp_zval();
+       ZVAL_BOOL(tmp, value);
+       return zend_update_static_property(scope, name, name_len, tmp 
TSRMLS_CC);
+}
+
+ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char 
*name, size_t name_len, long value TSRMLS_DC)
+{
+       zval *tmp = tmp_zval();
+       ZVAL_LONG(tmp, value);
+       return zend_update_static_property(scope, name, name_len, tmp 
TSRMLS_CC);
+}
+
+ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char 
*name, size_t name_len, double value TSRMLS_DC)
+{
+       zval *tmp = tmp_zval();
+       ZVAL_DOUBLE(tmp, value);
+       return zend_update_static_property(scope, name, name_len, tmp 
TSRMLS_CC);
+}
+
+ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char 
*name, size_t name_len, char *value TSRMLS_DC)
+{
+       zval *tmp = tmp_zval();
+       ZVAL_STRING(tmp, value, 1);
+       return zend_update_static_property(scope, name, name_len, tmp 
TSRMLS_CC);
+}
+
+ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char 
*name, size_t name_len, char *value, size_t value_len TSRMLS_DC)
+{
+       zval *tmp = tmp_zval();
+       ZVAL_STRINGL(tmp, value, value_len, 1);
+       return zend_update_static_property(scope, name, name_len, tmp 
TSRMLS_CC);
+}
+
+ZEND_API void zend_init_properties(void *zo TSRMLS_DC)
+{
+       zend_object *o = (zend_object *) zo;
+       ALLOC_HASHTABLE(o->properties);
+       zend_hash_copy(o->properties, &o->ce->default_properties, 
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+}
+
+ZEND_API void zend_init_static_properties(zend_class_entry *ce TSRMLS_DC)
+{
+       zend_hash_copy(&ce->static_properties, &ce->default_static_properties, 
(copy_ctor_func_t) zval_add_ref, NULL, sizeof(zval *));
+}
 /*
  * Local variables:
  * tab-width: 4
Index: Zend/zend_API.h
===================================================================
RCS file: /repository/ZendEngine2/zend_API.h,v
retrieving revision 1.207
diff -u -r1.207 zend_API.h
--- Zend/zend_API.h     3 Aug 2005 13:30:47 -0000       1.207
+++ Zend/zend_API.h     9 Aug 2005 21:56:14 -0000
@@ -221,6 +221,24 @@
 ZEND_API void zend_update_property_string(zend_class_entry *scope, zval 
*object, char *name, int name_length, char *value TSRMLS_DC);
 ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval 
*object, char *name, int name_length, char *value, int value_length TSRMLS_DC);
 
+ZEND_API int zend_declare_class_constant(zend_class_entry *ce, char *name, 
size_t name_length, zval *value TSRMLS_DC);
+ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, char 
*name, size_t name_length TSRMLS_DC);
+ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, char 
*name, size_t name_length, long value TSRMLS_DC);
+ZEND_API int zend_declare_class_constant_bool(zend_class_entry *ce, char 
*name, size_t name_length, zend_bool value TSRMLS_DC);
+ZEND_API int zend_declare_class_constant_double(zend_class_entry *ce, char 
*name, size_t name_length, double value TSRMLS_DC);
+ZEND_API int zend_declare_class_constant_string(zend_class_entry *ce, char 
*name, size_t name_length, char *value TSRMLS_DC);
+ZEND_API int zend_declare_class_constant_stringl(zend_class_entry *ce, char 
*name, size_t name_length, char *value, size_t value_length TSRMLS_DC);
+
+ZEND_API int zend_update_static_property(zend_class_entry *scope, char *name, 
size_t name_len, zval *value TSRMLS_DC);
+ZEND_API int zend_update_static_property_bool(zend_class_entry *scope, char 
*name, size_t name_len, zend_bool value TSRMLS_DC);
+ZEND_API int zend_update_static_property_long(zend_class_entry *scope, char 
*name, size_t name_len, long value TSRMLS_DC);
+ZEND_API int zend_update_static_property_double(zend_class_entry *scope, char 
*name, size_t name_len, double value TSRMLS_DC);
+ZEND_API int zend_update_static_property_string(zend_class_entry *scope, char 
*name, size_t name_len, char *value TSRMLS_DC);
+ZEND_API int zend_update_static_property_stringl(zend_class_entry *scope, char 
*name, size_t name_len, char *value, size_t value_len TSRMLS_DC);
+
+ZEND_API void zend_init_properties(void *zo TSRMLS_DC);
+ZEND_API void zend_init_static_properties(zend_class_entry *ce TSRMLS_DC);
+
 ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, char 
*name, int name_length, zend_bool silent TSRMLS_DC);
 
 ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC);
Index: Zend/zend_builtin_functions.c
===================================================================
RCS file: /repository/ZendEngine2/zend_builtin_functions.c,v
retrieving revision 1.277
diff -u -r1.277 zend_builtin_functions.c
--- Zend/zend_builtin_functions.c       3 Aug 2005 13:30:47 -0000       1.277
+++ Zend/zend_builtin_functions.c       9 Aug 2005 21:56:20 -0000
@@ -736,7 +736,7 @@
        } else {
                array_init(return_value);
                add_class_vars(*pce, &(*pce)->default_properties, return_value 
TSRMLS_CC);
-               add_class_vars(*pce, (*pce)->static_members, return_value 
TSRMLS_CC);
+               add_class_vars(*pce, &(*pce)->default_static_properties, 
return_value TSRMLS_CC);
        }
 }
 /* }}} */
Index: Zend/zend_compile.c
===================================================================
RCS file: /repository/ZendEngine2/zend_compile.c,v
retrieving revision 1.647
diff -u -r1.647 zend_compile.c
--- Zend/zend_compile.c 4 Aug 2005 14:04:36 -0000       1.647
+++ Zend/zend_compile.c 9 Aug 2005 21:56:30 -0000
@@ -2034,9 +2034,9 @@
                        zend_mangle_property_name(&prot_name, 
&prot_name_length, "*", 1, child_info->name, child_info->name_length, ce->type 
& ZEND_INTERNAL_CLASS);
                        if (child_info->flags & ZEND_ACC_STATIC) {
                                zval **prop;
-                               if (zend_hash_find(parent_ce->static_members, 
prot_name, prot_name_length+1, (void**)&prop) == SUCCESS) {
+                               if 
(zend_hash_find(&parent_ce->static_properties, prot_name, prot_name_length+1, 
(void**)&prop) == SUCCESS) {
                                        zval **new_prop;
-                                       if (zend_hash_find(ce->static_members, 
child_info->name, child_info->name_length+1, (void**)&new_prop) == SUCCESS) {
+                                       if 
(zend_hash_find(&ce->static_properties, child_info->name, 
child_info->name_length+1, (void**)&new_prop) == SUCCESS) {
                                                if (Z_TYPE_PP(new_prop) != 
IS_NULL && Z_TYPE_PP(prop) != IS_NULL) {
                                                        char *prop_name, *tmp;
                                                        
zend_unmangle_property_name(child_info->name, &tmp, &prop_name);
@@ -2046,8 +2046,8 @@
                                                }
                                        }
                                        (*prop)->refcount++;
-                                       zend_hash_update(ce->static_members, 
child_info->name, child_info->name_length+1, (void**)prop, sizeof(zval*), NULL);
-                                       zend_hash_del(ce->static_members, 
prot_name, prot_name_length+1);
+                                       
zend_hash_update(&ce->static_properties, child_info->name, 
child_info->name_length+1, (void**)prop, sizeof(zval*), NULL);
+                                       zend_hash_del(&ce->static_properties, 
prot_name, prot_name_length+1);
                                }
                        } else {
                                zend_hash_del(&ce->default_properties, 
prot_name, prot_name_length+1);
@@ -2133,7 +2133,8 @@
 
        /* Inherit properties */
        zend_hash_merge(&ce->default_properties, 
&parent_ce->default_properties, (void (*)(void *)) zval_add_ref, NULL, 
sizeof(zval *), 0);
-       zend_hash_merge(ce->static_members, parent_ce->static_members, (void 
(*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
+       zend_hash_merge(&ce->default_static_properties, 
&parent_ce->default_static_properties, (void (*)(void *)) zval_add_ref, NULL, 
sizeof(zval *), 0);
+       zend_hash_merge(&ce->static_properties, &parent_ce->static_properties, 
(void (*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
        zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, 
(copy_ctor_func_t) (ce->type & ZEND_INTERNAL_CLASS ? 
zend_duplicate_property_info_internal : zend_duplicate_property_info), 
sizeof(zend_property_info), (merge_checker_func_t) 
do_inherit_property_access_check, ce);
 
        zend_hash_merge(&ce->constants_table, &parent_ce->constants_table, 
(void (*)(void *)) zval_add_ref, NULL, sizeof(zval *), 0);
@@ -2263,7 +2264,8 @@
                zend_hash_destroy(&ce->function_table);
                zend_hash_destroy(&ce->default_properties);
                zend_hash_destroy(&ce->properties_info);
-               zend_hash_destroy(ce->static_members);
+               zend_hash_destroy(&ce->default_static_properties);
+               zend_hash_destroy(&ce->static_properties);
                zend_hash_destroy(&ce->constants_table);
                return NULL;
        }
@@ -2718,6 +2720,8 @@
                        zend_error(E_COMPILE_ERROR, "Clone method %s::%s() 
cannot be static", ce->name, ce->clone->common.function_name);
                }
        }
+       
+       zend_init_static_properties(ce TSRMLS_CC);
 
        ce->line_end = zend_get_compiled_lineno(TSRMLS_C);
 
@@ -3927,14 +3931,8 @@
 
        zend_hash_init_ex(&ce->default_properties, 0, NULL, zval_ptr_dtor_func, 
persistent_hashes, 0);
        zend_hash_init_ex(&ce->properties_info, 0, NULL, (dtor_func_t) 
(persistent_hashes ? zend_destroy_property_info_internal : 
zend_destroy_property_info), persistent_hashes, 0);
-
-       if (persistent_hashes) {
-               ce->static_members = (HashTable *) malloc(sizeof(HashTable));
-       } else {
-               ALLOC_HASHTABLE(ce->static_members);
-       }
-
-       zend_hash_init_ex(ce->static_members, 0, NULL, zval_ptr_dtor_func, 
persistent_hashes, 0);
+       zend_hash_init_ex(&ce->default_static_properties, 0, NULL, 
zval_ptr_dtor_func, persistent_hashes, 0);
+       zend_hash_init_ex(&ce->static_properties, 0, NULL, ZVAL_PTR_DTOR, 
persistent_hashes, 0);
        zend_hash_init_ex(&ce->constants_table, 0, NULL, zval_ptr_dtor_func, 
persistent_hashes, 0);
        zend_hash_init_ex(&ce->function_table, 0, NULL, ZEND_FUNCTION_DTOR, 
persistent_hashes, 0);
 
Index: Zend/zend_object_handlers.c
===================================================================
RCS file: /repository/ZendEngine2/zend_object_handlers.c,v
retrieving revision 1.135
diff -u -r1.135 zend_object_handlers.c
--- Zend/zend_object_handlers.c 3 Aug 2005 13:30:55 -0000       1.135
+++ Zend/zend_object_handlers.c 9 Aug 2005 21:56:53 -0000
@@ -820,7 +820,7 @@
                return NULL;
        }
 
-       zend_hash_quick_find(tmp_ce->static_members, property_info->name, 
property_info->name_length+1, property_info->h, (void **) &retval);
+       zend_hash_quick_find(&tmp_ce->static_properties, property_info->name, 
property_info->name_length+1, property_info->h, (void **) &retval);
 
        if (!retval) {
                if (silent) {
Index: Zend/zend_opcode.c
===================================================================
RCS file: /repository/ZendEngine2/zend_opcode.c,v
retrieving revision 1.110
diff -u -r1.110 zend_opcode.c
--- Zend/zend_opcode.c  3 Aug 2005 13:30:56 -0000       1.110
+++ Zend/zend_opcode.c  9 Aug 2005 21:56:55 -0000
@@ -142,9 +142,11 @@
                /* Clean all parts that can contain run-time data */
                /* Note that only run-time accessed data need to be cleaned up, 
pre-defined data can
                   not contain objects and thus are not probelmatic */
-               zend_hash_clean((*pce)->static_members);
                zend_hash_apply(&(*pce)->function_table, (apply_func_t) 
zend_cleanup_function_data TSRMLS_CC);
        }
+       /* static properties *can* contain run-time data -
+               they ain't constants */
+       zend_hash_clean(&(*pce)->static_properties);
        return 0;
 }
 
@@ -159,11 +161,11 @@
                case ZEND_USER_CLASS:
                        zend_hash_destroy(&ce->default_properties);
                        zend_hash_destroy(&ce->properties_info);
-                       zend_hash_destroy(ce->static_members);
-                       efree(ce->name);
+                       zend_hash_destroy(&ce->default_static_properties);
+                       zend_hash_destroy(&ce->static_properties);
                        zend_hash_destroy(&ce->function_table);
-                       FREE_HASHTABLE(ce->static_members);
                        zend_hash_destroy(&ce->constants_table);
+                       efree(ce->name);
                        if (ce->num_interfaces > 0 && ce->interfaces) {
                                efree(ce->interfaces);
                        }
@@ -175,11 +177,11 @@
                case ZEND_INTERNAL_CLASS:
                        zend_hash_destroy(&ce->default_properties);
                        zend_hash_destroy(&ce->properties_info);
-                       zend_hash_destroy(ce->static_members);
-                       free(ce->name);
+                       zend_hash_destroy(&ce->default_static_properties);
+                       zend_hash_destroy(&ce->static_properties);
                        zend_hash_destroy(&ce->function_table);
-                       free(ce->static_members);
                        zend_hash_destroy(&ce->constants_table);
+                       free(ce->name);
                        if (ce->num_interfaces > 0) {
                                free(ce->interfaces);
                        }
Index: Zend/zend_reflection_api.c
===================================================================
RCS file: /repository/ZendEngine2/zend_reflection_api.c,v
retrieving revision 1.164
diff -u -r1.164 zend_reflection_api.c
--- Zend/zend_reflection_api.c  3 Aug 2005 13:30:56 -0000       1.164
+++ Zend/zend_reflection_api.c  9 Aug 2005 21:57:06 -0000
@@ -2356,7 +2356,7 @@
        zend_update_class_constants(ce TSRMLS_CC);
 
        array_init(return_value);
-       zend_hash_copy(Z_ARRVAL_P(return_value), ce->static_members, 
(copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
+       zend_hash_copy(Z_ARRVAL_P(return_value), &ce->static_properties, 
(copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
 }
 /* }}} */
 
@@ -3432,7 +3432,7 @@
 
        if ((ref->prop->flags & ZEND_ACC_STATIC)) {
                zend_update_class_constants(intern->ce TSRMLS_CC);
-               if (zend_hash_quick_find(intern->ce->static_members, 
ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) 
== FAILURE) {
+               if (zend_hash_quick_find(&intern->ce->static_properties, 
ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) 
== FAILURE) {
                        zend_error(E_ERROR, "Internal error: Could not find the 
property %s", ref->prop->name);
                        /* Bails out */
                }
@@ -3478,7 +3478,7 @@
                                return;
                        }
                }
-               prop_table = intern->ce->static_members;
+               prop_table = &intern->ce->static_properties;
        } else {
                if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", 
&object, &value) == FAILURE) {
                        return;

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to