} else {
compiler_globals->global_u_auto_globals_table = NULL;
}
+
+ compiler_globals->last_static_member = zend_hash_num_elements(compiler_globals->class_table);
+ if (compiler_globals->last_static_member) {
+ compiler_globals->static_members = (HashTable**)calloc(compiler_globals->last_static_member, sizeof(HashTable*));
+ } else {
+ compiler_globals->static_members = NULL;
+ }
}
free(compiler_globals->global_u_auto_globals_table);
}
}
+ if (compiler_globals->static_members) {
+ free(compiler_globals->static_members);
+ }
+ compiler_globals->last_static_member = 0;
}
ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC)
{
- if (!class_type->constants_updated || !class_type->static_members) {
+ if (!class_type->constants_updated || !CE_STATIC_MEMBERS(class_type)) {
zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
zend_class_entry *old_scope = *scope;
*scope = class_type;
zend_hash_apply_with_argument(&class_type->default_properties, (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
- if (!class_type->static_members) {
+ if (!CE_STATIC_MEMBERS(class_type)) {
HashPosition pos;
zval **p;
if (class_type->parent) {
zend_update_class_constants(class_type->parent TSRMLS_CC);
}
+#if ZTS
+ ALLOC_HASHTABLE(CG(static_members)[(long)(class_type->static_members)]);
+#else
ALLOC_HASHTABLE(class_type->static_members);
- zend_u_hash_init(class_type->static_members, 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
+#endif
+ zend_u_hash_init(CE_STATIC_MEMBERS(class_type), 0, NULL, ZVAL_PTR_DTOR, 0, UG(unicode));
zend_hash_internal_pointer_reset_ex(&class_type->default_static_members, &pos);
while (zend_hash_get_current_data_ex(&class_type->default_static_members, (void**)&p, &pos) == SUCCESS) {
class_type->parent &&
zend_u_hash_find(&class_type->parent->default_static_members, utype, str_index, str_length, (void**)&q) == SUCCESS &&
*p == *q &&
- zend_u_hash_find(class_type->parent->static_members, utype, str_index, str_length, (void**)&q) == SUCCESS) {
+ zend_u_hash_find(CE_STATIC_MEMBERS(class_type->parent), utype, str_index, str_length, (void**)&q) == SUCCESS) {
(*q)->refcount++;
(*q)->is_ref = 1;
- zend_u_hash_add(class_type->static_members, utype, str_index, str_length, (void**)q, sizeof(zval*), NULL);
+ zend_u_hash_add(CE_STATIC_MEMBERS(class_type), utype, str_index, str_length, (void**)q, sizeof(zval*), NULL);
} else {
zval *q;
*q = **p;
INIT_PZVAL(q);
zval_copy_ctor(q);
- zend_u_hash_add(class_type->static_members, utype, str_index, str_length, (void**)&q, sizeof(zval*), NULL);
+ zend_u_hash_add(CE_STATIC_MEMBERS(class_type), utype, str_index, str_length, (void**)&q, sizeof(zval*), NULL);
}
zend_hash_move_forward_ex(&class_type->default_static_members, &pos);
}
}
- 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(CE_STATIC_MEMBERS(class_type), (apply_func_arg_t) zval_update_constant, (void *) 1 TSRMLS_CC);
*scope = old_scope;
class_type->constants_updated = 1;
#define INIT_OVERLOADED_CLASS_ENTRY(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset) \
INIT_OVERLOADED_CLASS_ENTRY_EX(class_container, class_name, functions, handle_fcall, handle_propget, handle_propset, NULL, NULL)
+#ifdef ZTS
+# define CE_STATIC_MEMBERS(ce) (((ce)->type==ZEND_USER_CLASS)?(ce)->static_members:CG(static_members)[(long)(ce)->static_members])
+#else
+# define CE_STATIC_MEMBERS(ce) ((ce)->static_members)
+#endif
+
int zend_next_free_module(void);
BEGIN_EXTERN_C()
array_init(return_value);
add_class_vars(*pce, &(*pce)->default_properties, return_value TSRMLS_CC);
zend_update_class_constants(*pce TSRMLS_CC);
- add_class_vars(*pce, (*pce)->static_members, return_value TSRMLS_CC);
+ add_class_vars(*pce, CE_STATIC_MEMBERS(*pce), return_value TSRMLS_CC);
}
}
/* }}} */
if (parent_ce->type != ce->type) {
/* User class extends internal class */
- ht = parent_ce->static_members;
+ ht = CE_STATIC_MEMBERS(parent_ce);
} else {
ht = &parent_ce->default_static_members;
}
if (parent_ce->type != ce->type) {
/* User class extends internal class */
zend_update_class_constants(parent_ce TSRMLS_CC);
- zend_hash_merge(&ce->default_static_members, parent_ce->static_members, (void (*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
+ zend_hash_merge(&ce->default_static_members, CE_STATIC_MEMBERS(parent_ce), (void (*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
} else {
zend_hash_merge(&ce->default_static_members, &parent_ce->default_static_members, (void (*)(void *)) inherit_static_prop, NULL, sizeof(zval *), 0);
}
zend_u_hash_init_ex(&ce->constants_table, 0, NULL, zval_ptr_dtor_func, persistent_hashes, UG(unicode), 0);
zend_u_hash_init_ex(&ce->function_table, 0, NULL, ZEND_FUNCTION_DTOR, persistent_hashes, UG(unicode), 0);
- ce->static_members = (ce->type == ZEND_INTERNAL_CLASS) ? NULL : &ce->default_static_members;
+ if (ce->type == ZEND_INTERNAL_CLASS) {
+#ifdef ZTS
+ int n = zend_hash_num_elements(CG(class_table));
+
+ if (CG(static_members) && n >= CG(last_static_member)) {
+ /* Support for run-time declaration: dl() */
+ CG(last_static_member) = n+1;
+ CG(static_members) = realloc(CG(static_members), (n+1)*sizeof(HashTable*));
+ CG(static_members)[n] = NULL;
+ }
+ ce->static_members = (HashTable*)n;
+#else
+ ce->static_members = NULL;
+#endif
+ } else {
+ ce->static_members = &ce->default_static_members;
+ }
if (nullify_handlers) {
ce->constructor = NULL;
HashTable *global_u_function_table;
HashTable *global_u_class_table;
HashTable *global_u_auto_globals_table;
+
+ HashTable **static_members;
+ int last_static_member;
#endif
};
zend_update_class_constants(tmp_ce TSRMLS_CC);
- zend_u_hash_quick_find(tmp_ce->static_members, UG(unicode)?IS_UNICODE:IS_STRING, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval);
+ zend_u_hash_quick_find(CE_STATIC_MEMBERS(tmp_ce), UG(unicode)?IS_UNICODE:IS_STRING, property_info->name, property_info->name_length+1, property_info->h, (void **) &retval);
if (!retval) {
if (silent) {
ZEND_API int zend_cleanup_class_data(zend_class_entry **pce TSRMLS_DC)
{
- if ((*pce)->static_members) {
- if ((*pce)->static_members != &(*pce)->default_static_members) {
- zend_hash_destroy((*pce)->static_members);
- FREE_HASHTABLE((*pce)->static_members);
- }
- (*pce)->static_members = NULL;
- }
if ((*pce)->type == ZEND_USER_CLASS) {
/* 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_apply(&(*pce)->function_table, (apply_func_t) zend_cleanup_function_data TSRMLS_CC);
+ (*pce)->static_members = NULL;
+ } else if (CE_STATIC_MEMBERS(*pce)) {
+ zend_hash_destroy(CE_STATIC_MEMBERS(*pce));
+ FREE_HASHTABLE(CE_STATIC_MEMBERS(*pce));
+#ifdef ZTS
+ CG(static_members)[(long)((*pce)->static_members)] = NULL;
+#else
+ (*pce)->static_members = NULL;
+#endif
}
return 0;
}
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_MEMBERS(ce), (copy_ctor_func_t) zval_add_ref, (void *) &tmp_copy, sizeof(zval *));
}
/* }}} */
if ((ref->prop->flags & ZEND_ACC_STATIC)) {
zend_update_class_constants(intern->ce TSRMLS_CC);
- if (zend_u_hash_quick_find(intern->ce->static_members, utype, ref->prop->name, ref->prop->name_length + 1, ref->prop->h, (void **) &member) == FAILURE) {
+ if (zend_u_hash_quick_find(CE_STATIC_MEMBERS(intern->ce), utype, 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 %v", ref->prop->name);
/* Bails out */
}
}
}
zend_update_class_constants(intern->ce TSRMLS_CC);
- prop_table = intern->ce->static_members;
+ prop_table = CE_STATIC_MEMBERS(intern->ce);
} else {
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "oz", &object, &value) == FAILURE) {
return;
#include "php_fopen_wrappers.h"
#include "streamsfuncs.h"
+static zend_class_entry *incomplete_class_entry = NULL;
+
static
ZEND_BEGIN_ARG_INFO(first_and_second__args_force_ref, 0)
ZEND_ARG_PASS_INFO(1)
memset(&BG(mblen_state), 0, sizeof(BG(mblen_state)));
#endif
- BG(incomplete_class) = php_create_incomplete_class(TSRMLS_C);
+ BG(incomplete_class) = incomplete_class_entry;
}
#endif
#endif
+ BG(incomplete_class) = incomplete_class_entry = php_create_incomplete_class(TSRMLS_C);
+
REGISTER_LONG_CONSTANT("CONNECTION_ABORTED", PHP_CONNECTION_ABORTED, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CONNECTION_NORMAL", PHP_CONNECTION_NORMAL, CONST_CS | CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CONNECTION_TIMEOUT", PHP_CONNECTION_TIMEOUT, CONST_CS | CONST_PERSISTENT);