mirror of
https://github.com/php/php-src.git
synced 2024-11-24 02:15:04 +08:00
Internal classes can now have default properties.
This commit is contained in:
parent
5e77dc44dc
commit
baaa4c903d
@ -1632,7 +1632,7 @@ ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_le
|
||||
char *priv_name;
|
||||
int priv_name_length;
|
||||
|
||||
mangle_property_name(&priv_name, &priv_name_length, ce->name, ce->name_length, name, name_length);
|
||||
mangle_property_name(&priv_name, &priv_name_length, ce->name, ce->name_length, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
|
||||
zend_hash_update(target_symbol_table, priv_name, priv_name_length+1, &property, sizeof(zval *), NULL);
|
||||
property_info.name = priv_name;
|
||||
property_info.name_length = priv_name_length;
|
||||
@ -1642,7 +1642,7 @@ ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_le
|
||||
char *prot_name;
|
||||
int prot_name_length;
|
||||
|
||||
mangle_property_name(&prot_name, &prot_name_length, "*", 1, name, name_length);
|
||||
mangle_property_name(&prot_name, &prot_name_length, "*", 1, name, name_length, ce->type & ZEND_INTERNAL_CLASS);
|
||||
zend_hash_update(target_symbol_table, prot_name, prot_name_length+1, &property, sizeof(zval *), NULL);
|
||||
property_info.name = prot_name;
|
||||
property_info.name_length = prot_name_length;
|
||||
@ -1650,7 +1650,7 @@ ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_le
|
||||
break;
|
||||
case ZEND_ACC_PUBLIC:
|
||||
zend_hash_update(target_symbol_table, name, name_length+1, &property, sizeof(zval *), NULL);
|
||||
property_info.name = estrndup(name, name_length);
|
||||
property_info.name = ce->type & ZEND_INTERNAL_CLASS ? zend_strndup(name, name_length) : estrndup(name, name_length);
|
||||
property_info.name_length = name_length;
|
||||
break;
|
||||
}
|
||||
@ -1661,6 +1661,83 @@ ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_le
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
ZEND_API int zend_declare_property_null(zend_class_entry *ce, char *name, int name_length, int access_type)
|
||||
{
|
||||
zval *property;
|
||||
|
||||
if (ce->type & ZEND_INTERNAL_CLASS) {
|
||||
property = malloc(sizeof(zval));
|
||||
} else {
|
||||
ALLOC_ZVAL(property);
|
||||
}
|
||||
INIT_ZVAL(*property);
|
||||
return zend_declare_property(ce, name, name_length, property, access_type);
|
||||
}
|
||||
|
||||
ZEND_API int zend_declare_property_long(zend_class_entry *ce, char *name, int name_length, long value, int access_type)
|
||||
{
|
||||
zval *property;
|
||||
|
||||
if (ce->type & ZEND_INTERNAL_CLASS) {
|
||||
property = malloc(sizeof(zval));
|
||||
} else {
|
||||
ALLOC_ZVAL(property);
|
||||
}
|
||||
INIT_PZVAL(property);
|
||||
ZVAL_LONG(property, value);
|
||||
return zend_declare_property(ce, name, name_length, property, access_type);
|
||||
}
|
||||
|
||||
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC)
|
||||
{
|
||||
zval property;
|
||||
zend_class_entry *old_scope = EG(scope);
|
||||
|
||||
EG(scope) = scope;
|
||||
|
||||
if (!Z_OBJ_HT_P(object)->write_property) {
|
||||
zend_error(E_CORE_ERROR, "Property %s of class %s cannot be updated", Z_OBJCE_P(object)->name, name);
|
||||
}
|
||||
ZVAL_STRINGL(&property, name, name_length, 0);
|
||||
Z_OBJ_HT_P(object)->write_property(object, &property, value TSRMLS_CC);
|
||||
|
||||
EG(scope) = old_scope;
|
||||
}
|
||||
|
||||
ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC)
|
||||
{
|
||||
zval *tmp;
|
||||
|
||||
ALLOC_ZVAL(tmp);
|
||||
tmp->is_ref = 0;
|
||||
tmp->refcount = 0;
|
||||
ZVAL_NULL(tmp);
|
||||
zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC)
|
||||
{
|
||||
zval *tmp;
|
||||
|
||||
ALLOC_ZVAL(tmp);
|
||||
tmp->is_ref = 0;
|
||||
tmp->refcount = 0;
|
||||
ZVAL_LONG(tmp, value);
|
||||
zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
|
||||
}
|
||||
|
||||
ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, char *value TSRMLS_DC)
|
||||
{
|
||||
zval *tmp;
|
||||
|
||||
ALLOC_ZVAL(tmp);
|
||||
tmp->is_ref = 0;
|
||||
tmp->refcount = 0;
|
||||
ZVAL_STRING(tmp, value, 1);
|
||||
zend_update_property(scope, object, name, name_length, tmp TSRMLS_CC);
|
||||
}
|
||||
|
||||
/*
|
||||
* Local variables:
|
||||
* tab-width: 4
|
||||
|
@ -164,7 +164,13 @@ ZEND_API void zend_wrong_param_count(TSRMLS_D);
|
||||
ZEND_API zend_bool zend_is_callable(zval *callable, zend_bool syntax_only, char **callable_name);
|
||||
ZEND_API char *zend_get_module_version(char *module_name);
|
||||
ZEND_API int zend_declare_property(zend_class_entry *ce, char *name, int name_length, zval *property, int access_type);
|
||||
ZEND_API int zend_declare_property_null(zend_class_entry *ce, char *name, int name_length, int access_type);
|
||||
ZEND_API int zend_declare_property_long(zend_class_entry *ce, char *name, int name_length, long value, int access_type);
|
||||
|
||||
ZEND_API void zend_update_property(zend_class_entry *scope, zval *object, char *name, int name_length, zval *value TSRMLS_DC);
|
||||
ZEND_API void zend_update_property_null(zend_class_entry *scope, zval *object, char *name, int name_length TSRMLS_DC);
|
||||
ZEND_API void zend_update_property_long(zend_class_entry *scope, zval *object, char *name, int name_length, long value TSRMLS_DC);
|
||||
ZEND_API void zend_update_property_string(zend_class_entry *scope, zval *object, char *name, int name_length, char *value TSRMLS_DC);
|
||||
|
||||
ZEND_API zend_class_entry *zend_get_class_entry(zval *zobject TSRMLS_DC);
|
||||
|
||||
|
@ -39,6 +39,29 @@ ZEND_API zend_compiler_globals compiler_globals;
|
||||
ZEND_API zend_executor_globals executor_globals;
|
||||
#endif
|
||||
|
||||
static void zend_duplicate_property_info(zend_property_info *property_info)
|
||||
{
|
||||
property_info->name = estrndup(property_info->name, property_info->name_length);
|
||||
}
|
||||
|
||||
|
||||
static void zend_duplicate_property_info_internal(zend_property_info *property_info)
|
||||
{
|
||||
property_info->name = zend_strndup(property_info->name, property_info->name_length);
|
||||
}
|
||||
|
||||
|
||||
static void zend_destroy_property_info(zend_property_info *property_info)
|
||||
{
|
||||
efree(property_info->name);
|
||||
}
|
||||
|
||||
|
||||
static void zend_destroy_property_info_internal(zend_property_info *property_info)
|
||||
{
|
||||
free(property_info->name);
|
||||
}
|
||||
|
||||
static void build_runtime_defined_function_key(zval *result, char *name, int name_length, zend_op *opline TSRMLS_DC)
|
||||
{
|
||||
char lineno_buf[32];
|
||||
@ -1779,7 +1802,7 @@ void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce)
|
||||
|
||||
/* Inherit properties */
|
||||
zend_hash_merge(&ce->default_properties, &parent_ce->default_properties, (void (*)(void *)) zval_add_ref, NULL, sizeof(zval *), 0);
|
||||
zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, (copy_ctor_func_t) zend_duplicate_property_info, sizeof(zend_property_info), (merge_checker_func_t) do_inherit_property_access_check, ce);
|
||||
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);
|
||||
|
||||
/* STATIC_MEMBERS_FIXME */
|
||||
/* zend_hash_merge(ce->static_members, parent_ce->static_members, (void (*)(void *)) zval_add_ref, (void *) &tmp, sizeof(zval *), 0); */
|
||||
@ -2285,13 +2308,13 @@ void zend_do_implements_interface(znode *interface_znode TSRMLS_DC)
|
||||
}
|
||||
|
||||
|
||||
void mangle_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length)
|
||||
void mangle_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length, int internal)
|
||||
{
|
||||
char *prop_name;
|
||||
int prop_name_length;
|
||||
|
||||
prop_name_length = 1 + src1_length + 1 + src2_length;
|
||||
prop_name = emalloc(prop_name_length+1);
|
||||
prop_name = internal ? malloc(prop_name_length + 1) : emalloc(prop_name_length + 1);
|
||||
prop_name[0] = '\0';
|
||||
memcpy(prop_name + 1, src1, src1_length+1);
|
||||
memcpy(prop_name + 1 + src1_length + 1, src2, src2_length+1);
|
||||
@ -3383,16 +3406,21 @@ again:
|
||||
}
|
||||
|
||||
|
||||
void zend_duplicate_property_info(zend_property_info *property_info)
|
||||
static void zval_ptr_dtor_internal(zval **zval_ptr)
|
||||
{
|
||||
property_info->name = estrndup(property_info->name, property_info->name_length);
|
||||
#if DEBUG_ZEND>=2
|
||||
printf("Reducing refcount for %x (%x): %d->%d\n", *zval_ptr, zval_ptr, (*zval_ptr)->refcount, (*zval_ptr)->refcount-1);
|
||||
#endif
|
||||
(*zval_ptr)->refcount--;
|
||||
if ((*zval_ptr)->refcount==0) {
|
||||
zval_dtor(*zval_ptr);
|
||||
free(*zval_ptr);
|
||||
} else if ((*zval_ptr)->refcount == 1) {
|
||||
(*zval_ptr)->is_ref = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void zend_destroy_property_info(zend_property_info *property_info)
|
||||
{
|
||||
efree(property_info->name);
|
||||
}
|
||||
#define ZVAL_PTR_DTOR_INTERNAL (void (*)(void *)) zval_ptr_dtor_internal
|
||||
|
||||
void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC)
|
||||
{
|
||||
@ -3405,8 +3433,8 @@ void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers
|
||||
ce->doc_comment = NULL;
|
||||
ce->doc_comment_len = 0;
|
||||
|
||||
zend_hash_init_ex(&ce->default_properties, 0, NULL, ZVAL_PTR_DTOR, persistent_hashes, 0);
|
||||
zend_hash_init_ex(&ce->properties_info, 0, NULL, (dtor_func_t) zend_destroy_property_info, persistent_hashes, 0);
|
||||
zend_hash_init_ex(&ce->default_properties, 0, NULL, persistent_hashes ? ZVAL_PTR_DTOR_INTERNAL : ZVAL_PTR_DTOR, 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));
|
||||
|
@ -465,10 +465,8 @@ ZEND_API void destroy_zend_function(zend_function *function TSRMLS_DC);
|
||||
ZEND_API void destroy_zend_class(zend_class_entry **pce);
|
||||
void zend_class_add_ref(zend_class_entry **ce);
|
||||
|
||||
void mangle_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length);
|
||||
void mangle_property_name(char **dest, int *dest_length, char *src1, int src1_length, char *src2, int src2_length, int internal);
|
||||
void unmangle_property_name(char *mangled_property, char **prop_name, char **class_name);
|
||||
void zend_duplicate_property_info(zend_property_info *property_info);
|
||||
void zend_destroy_property_info(zend_property_info *property_info);
|
||||
|
||||
#define ZEND_FUNCTION_DTOR (void (*)(void *)) destroy_zend_function
|
||||
#define ZEND_CLASS_DTOR (void (*)(void *)) destroy_zend_class
|
||||
|
Loading…
Reference in New Issue
Block a user