diff options
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r-- | Zend/zend_API.c | 95 |
1 files changed, 93 insertions, 2 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c index eec4ab0bb..529092ab9 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1022,6 +1022,41 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties, int destro } /* }}} */ +static int zval_update_class_constant(zval **pp, int is_static, int offset TSRMLS_DC) /* {{{ */ +{ + if ((Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT || + (Z_TYPE_PP(pp) & IS_CONSTANT_TYPE_MASK) == IS_CONSTANT_ARRAY) { + zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry); + + if ((*scope)->parent) { + zend_class_entry *ce = *scope; + HashPosition pos; + zend_property_info *prop_info; + + do { + for (zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); + zend_hash_get_current_data_ex(&ce->properties_info, (void **) &prop_info, &pos) == SUCCESS; + zend_hash_move_forward_ex(&ce->properties_info, &pos)) { + if (is_static == ((prop_info->flags & ZEND_ACC_STATIC) != 0) && + offset == prop_info->offset) { + int ret; + zend_class_entry *old_scope = *scope; + *scope = prop_info->ce; + ret = zval_update_constant(pp, (void*)1 TSRMLS_CC); + *scope = old_scope; + return ret; + } + } + ce = ce->parent; + } while (ce); + + } + return zval_update_constant(pp, (void*)1 TSRMLS_CC); + } + return 0; +} +/* }}} */ + ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC) /* {{{ */ { if ((class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED) == 0 || (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count)) { @@ -1034,7 +1069,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC for (i = 0; i < class_type->default_properties_count; i++) { if (class_type->default_properties_table[i]) { - zval_update_constant(&class_type->default_properties_table[i], (void**)1 TSRMLS_CC); + zval_update_class_constant(&class_type->default_properties_table[i], 0, i TSRMLS_CC); } } @@ -1075,7 +1110,7 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC } for (i = 0; i < class_type->default_static_members_count; i++) { - zval_update_constant(&CE_STATIC_MEMBERS(class_type)[i], (void**)1 TSRMLS_CC); + zval_update_class_constant(&CE_STATIC_MEMBERS(class_type)[i], 1, i TSRMLS_CC); } *scope = old_scope; @@ -3878,6 +3913,62 @@ ZEND_API void zend_restore_error_handling(zend_error_handling *saved TSRMLS_DC) } /* }}} */ +ZEND_API const char* zend_find_alias_name(zend_class_entry *ce, const char *name, zend_uint len) /* {{{ */ +{ + zend_trait_alias *alias, **alias_ptr; + + alias_ptr = ce->trait_aliases; + alias = *alias_ptr; + while (alias) { + if (alias->alias_len == len && + !strncasecmp(name, alias->alias, alias->alias_len)) { + return alias->alias; + } + alias_ptr++; + alias = *alias_ptr; + } + + return name; +} +/* }}} */ + +ZEND_API const char* zend_resolve_method_name(zend_class_entry *ce, zend_function *f) /* {{{ */ +{ + zend_function *func; + HashPosition iterator; + HashTable *function_table; + + if (f->common.type != ZEND_USER_FUNCTION || + *(f->op_array.refcount) < 2 || + !f->common.scope || + !f->common.scope->trait_aliases) { + return f->common.function_name; + } + + function_table = &ce->function_table; + zend_hash_internal_pointer_reset_ex(function_table, &iterator); + while (zend_hash_get_current_data_ex(function_table, (void **)&func, &iterator) == SUCCESS) { + if (func == f) { + char *name; + uint len; + ulong idx; + + if (zend_hash_get_current_key_ex(function_table, &name, &len, &idx, 0, &iterator) != HASH_KEY_IS_STRING) { + return f->common.function_name; + } + --len; + if (len == strlen(f->common.function_name) && + !strncasecmp(name, f->common.function_name, len)) { + return f->common.function_name; + } + return zend_find_alias_name(f->common.scope, name, len); + } + zend_hash_move_forward_ex(function_table, &iterator); + } + return f->common.function_name; +} +/* }}} */ + /* * Local variables: * tab-width: 4 |