mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Use new zend_hash iteration API
This commit is contained in:
parent
e181798405
commit
bd10db271c
3 changed files with 66 additions and 90 deletions
|
@ -1144,9 +1144,13 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC
|
|||
zend_class_entry **scope = EG(in_execution)?&EG(scope):&CG(active_class_entry);
|
||||
zend_class_entry *old_scope = *scope;
|
||||
int i;
|
||||
zval *val;
|
||||
|
||||
*scope = class_type;
|
||||
zend_hash_apply_with_argument(&class_type->constants_table, (apply_func_arg_t) zval_update_constant, (void *)1 TSRMLS_CC);
|
||||
|
||||
ZEND_HASH_FOREACH_VAL(&class_type->constants_table, val) {
|
||||
zval_update_constant(val, 1 TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
for (i = 0; i < class_type->default_properties_count; i++) {
|
||||
if (Z_TYPE(class_type->default_properties_table[i]) != IS_UNDEF) {
|
||||
|
|
|
@ -3710,24 +3710,18 @@ ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_
|
|||
zval_add_ref
|
||||
#endif
|
||||
|
||||
static int do_inherit_class_constant(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
|
||||
static void do_inherit_class_constant(zend_string *name, zval *zv, zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_class_entry *ce = va_arg(args, zend_class_entry *);
|
||||
zend_class_entry *parent_ce = va_arg(args, zend_class_entry *);
|
||||
|
||||
if (hash_key->key) {
|
||||
if (!Z_ISREF_P(zv)) {
|
||||
if (parent_ce->type == ZEND_INTERNAL_CLASS) {
|
||||
ZVAL_NEW_PERSISTENT_REF(zv, zv);
|
||||
} else {
|
||||
ZVAL_NEW_REF(zv, zv);
|
||||
}
|
||||
}
|
||||
if (zend_hash_add(&ce->constants_table, hash_key->key, zv)) {
|
||||
Z_ADDREF_P(zv);
|
||||
if (!Z_ISREF_P(zv)) {
|
||||
if (parent_ce->type == ZEND_INTERNAL_CLASS) {
|
||||
ZVAL_NEW_PERSISTENT_REF(zv, zv);
|
||||
} else {
|
||||
ZVAL_NEW_REF(zv, zv);
|
||||
}
|
||||
}
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
if (zend_hash_add(&ce->constants_table, name, zv)) {
|
||||
Z_ADDREF_P(zv);
|
||||
}
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -3736,6 +3730,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
|||
zend_property_info *property_info;
|
||||
zend_function *func;
|
||||
zend_string *key;
|
||||
zval *zv;
|
||||
|
||||
if ((ce->ce_flags & ZEND_ACC_INTERFACE)
|
||||
&& !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) {
|
||||
|
@ -3843,7 +3838,9 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
|||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
zend_hash_apply_with_arguments(&parent_ce->constants_table TSRMLS_CC, do_inherit_class_constant, 2, ce, parent_ce);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(&parent_ce->constants_table, key, zv) {
|
||||
do_inherit_class_constant(key, zv, ce, parent_ce TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(&parent_ce->function_table, key, func) {
|
||||
if (do_inherit_method_check(&ce->function_table, func, key, ce)) {
|
||||
|
@ -3864,15 +3861,15 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static zend_bool do_inherit_constant_check(HashTable *child_constants_table, zval *parent_constant, const zend_hash_key *hash_key, const zend_class_entry *iface) /* {{{ */
|
||||
static zend_bool do_inherit_constant_check(HashTable *child_constants_table, zval *parent_constant, zend_string *name, const zend_class_entry *iface) /* {{{ */
|
||||
{
|
||||
zval *old_constant;
|
||||
|
||||
if ((old_constant = zend_hash_find(child_constants_table, hash_key->key)) != NULL) {
|
||||
if ((old_constant = zend_hash_find(child_constants_table, name)) != NULL) {
|
||||
if (!Z_ISREF_P(old_constant) ||
|
||||
!Z_ISREF_P(parent_constant) ||
|
||||
Z_REFVAL_P(old_constant) != Z_REFVAL_P(parent_constant)) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", hash_key->key->val, iface->name->val);
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Cannot inherit previously-inherited or override constant %s from interface %s", name->val, iface->name->val);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -3880,27 +3877,13 @@ static zend_bool do_inherit_constant_check(HashTable *child_constants_table, zva
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static int do_interface_constant_check(zval *val TSRMLS_DC, int num_args, va_list args, zend_hash_key *key) /* {{{ */
|
||||
static void do_inherit_iface_constant(zend_string *name, zval *zv, zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_class_entry **iface = va_arg(args, zend_class_entry**);
|
||||
|
||||
do_inherit_constant_check(&(*iface)->constants_table, val, key, *iface);
|
||||
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int do_inherit_iface_constant(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
|
||||
{
|
||||
zend_class_entry *ce = va_arg(args, zend_class_entry *);
|
||||
zend_class_entry *iface = va_arg(args, zend_class_entry *);
|
||||
|
||||
if (hash_key->key && do_inherit_constant_check(&ce->constants_table, zv, hash_key, iface)) {
|
||||
if (do_inherit_constant_check(&ce->constants_table, zv, name, iface)) {
|
||||
ZVAL_MAKE_REF(zv);
|
||||
Z_ADDREF_P(zv);
|
||||
zend_hash_update(&ce->constants_table, hash_key->key, zv);
|
||||
zend_hash_update(&ce->constants_table, name, zv);
|
||||
}
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
@ -3911,6 +3894,7 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
|
|||
zend_uint parent_iface_num = ce->parent ? ce->parent->num_interfaces : 0;
|
||||
zend_function *func;
|
||||
zend_string *key;
|
||||
zval *zv;
|
||||
|
||||
for (i = 0; i < ce->num_interfaces; i++) {
|
||||
if (ce->interfaces[i] == NULL) {
|
||||
|
@ -3926,7 +3910,9 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
|
|||
}
|
||||
if (ignore) {
|
||||
/* Check for attempt to redeclare interface constants */
|
||||
zend_hash_apply_with_arguments(&ce->constants_table TSRMLS_CC, do_interface_constant_check, 1, &iface);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(&ce->constants_table, key, zv) {
|
||||
do_inherit_constant_check(&iface->constants_table, zv, key, iface);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
} else {
|
||||
if (ce->num_interfaces >= current_iface_num) {
|
||||
if (ce->type == ZEND_INTERNAL_CLASS) {
|
||||
|
@ -3937,7 +3923,9 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry
|
|||
}
|
||||
ce->interfaces[ce->num_interfaces++] = iface;
|
||||
|
||||
zend_hash_apply_with_arguments(&iface->constants_table TSRMLS_CC, do_inherit_iface_constant, 2, ce, iface);
|
||||
ZEND_HASH_FOREACH_STR_KEY_VAL(&iface->constants_table, key, zv) {
|
||||
do_inherit_iface_constant(key, zv, ce, iface TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(&iface->function_table, key, func) {
|
||||
if (do_inherit_method_check(&ce->function_table, func, key, ce)) {
|
||||
|
@ -4108,11 +4096,8 @@ static void zend_add_trait_method(zend_class_entry *ce, const char *name, zend_s
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static int zend_fixup_trait_method(zval *zv, void *arg TSRMLS_DC) /* {{{ */
|
||||
static void zend_fixup_trait_method(zend_function *fn, zend_class_entry *ce) /* {{{ */
|
||||
{
|
||||
zend_function *fn = Z_PTR_P(zv);
|
||||
zend_class_entry *ce = (zend_class_entry *)arg;
|
||||
|
||||
if ((fn->common.scope->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
|
||||
|
||||
fn->common.scope = ce;
|
||||
|
@ -4124,27 +4109,15 @@ static int zend_fixup_trait_method(zval *zv, void *arg TSRMLS_DC) /* {{{ */
|
|||
ce->ce_flags |= ZEND_HAS_STATIC_IN_METHODS;
|
||||
}
|
||||
}
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
static int zend_traits_copy_functions(zval *zv TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) /* {{{ */
|
||||
static int zend_traits_copy_functions(zend_string *fnname, zend_function *fn, zend_class_entry *ce, HashTable **overriden, HashTable *exclude_table TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_function *fn = Z_PTR_P(zv);
|
||||
zend_class_entry *ce;
|
||||
HashTable **overriden;
|
||||
zend_trait_alias *alias, **alias_ptr;
|
||||
HashTable *exclude_table;
|
||||
zend_string *lcname;
|
||||
unsigned int fnname_len;
|
||||
zend_function fn_copy;
|
||||
|
||||
ce = va_arg(args, zend_class_entry*);
|
||||
overriden = va_arg(args, HashTable**);
|
||||
exclude_table = va_arg(args, HashTable*);
|
||||
|
||||
fnname_len = hash_key->key->len;
|
||||
|
||||
/* apply aliases which are qualified with a class name, there should not be any ambiguity */
|
||||
if (ce->trait_aliases) {
|
||||
alias_ptr = ce->trait_aliases;
|
||||
|
@ -4153,8 +4126,8 @@ static int zend_traits_copy_functions(zval *zv TSRMLS_DC, int num_args, va_list
|
|||
/* Scope unset or equal to the function we compare to, and the alias applies to fn */
|
||||
if (alias->alias != NULL
|
||||
&& (!alias->trait_method->ce || fn->common.scope == alias->trait_method->ce)
|
||||
&& alias->trait_method->method_name->len == fnname_len
|
||||
&& (zend_binary_strcasecmp(alias->trait_method->method_name->val, alias->trait_method->method_name->len, hash_key->key->val, fnname_len) == 0)) {
|
||||
&& alias->trait_method->method_name->len == fnname->len
|
||||
&& (zend_binary_strcasecmp(alias->trait_method->method_name->val, alias->trait_method->method_name->len, fnname->val, fnname->len) == 0)) {
|
||||
fn_copy = *fn;
|
||||
|
||||
/* if it is 0, no modifieres has been changed */
|
||||
|
@ -4177,9 +4150,7 @@ static int zend_traits_copy_functions(zval *zv TSRMLS_DC, int num_args, va_list
|
|||
}
|
||||
}
|
||||
|
||||
lcname = hash_key->key;
|
||||
|
||||
if (exclude_table == NULL || zend_hash_find(exclude_table, lcname) == NULL) {
|
||||
if (exclude_table == NULL || zend_hash_find(exclude_table, fnname) == NULL) {
|
||||
/* is not in hashtable, thus, function is not to be excluded */
|
||||
fn_copy = *fn;
|
||||
|
||||
|
@ -4191,8 +4162,8 @@ static int zend_traits_copy_functions(zval *zv TSRMLS_DC, int num_args, va_list
|
|||
/* Scope unset or equal to the function we compare to, and the alias applies to fn */
|
||||
if (alias->alias == NULL && alias->modifiers != 0
|
||||
&& (!alias->trait_method->ce || fn->common.scope == alias->trait_method->ce)
|
||||
&& (alias->trait_method->method_name->len == fnname_len)
|
||||
&& (zend_binary_strcasecmp(alias->trait_method->method_name->val, alias->trait_method->method_name->len, lcname->val, fnname_len) == 0)) {
|
||||
&& (alias->trait_method->method_name->len == fnname->len)
|
||||
&& (zend_binary_strcasecmp(alias->trait_method->method_name->val, alias->trait_method->method_name->len, fnname->val, fnname->len) == 0)) {
|
||||
|
||||
fn_copy.common.fn_flags = alias->modifiers | (fn->common.fn_flags ^ (fn->common.fn_flags & ZEND_ACC_PPP_MASK));
|
||||
|
||||
|
@ -4206,7 +4177,7 @@ static int zend_traits_copy_functions(zval *zv TSRMLS_DC, int num_args, va_list
|
|||
}
|
||||
}
|
||||
|
||||
zend_add_trait_method(ce, fn->common.function_name->val, lcname, &fn_copy, overriden TSRMLS_CC);
|
||||
zend_add_trait_method(ce, fn->common.function_name->val, fnname, &fn_copy, overriden TSRMLS_CC);
|
||||
}
|
||||
|
||||
return ZEND_HASH_APPLY_KEEP;
|
||||
|
@ -4365,6 +4336,8 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{
|
|||
{
|
||||
zend_uint i;
|
||||
HashTable *overriden = NULL;
|
||||
zend_string *key;
|
||||
zend_function *fn;
|
||||
|
||||
for (i = 0; i < ce->num_traits; i++) {
|
||||
if (ce->trait_precedences) {
|
||||
|
@ -4376,15 +4349,21 @@ static void zend_do_traits_method_binding(zend_class_entry *ce TSRMLS_DC) /* {{{
|
|||
zend_traits_compile_exclude_table(&exclude_table, ce->trait_precedences, ce->traits[i]);
|
||||
|
||||
/* copies functions, applies defined aliasing, and excludes unused trait methods */
|
||||
zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, zend_traits_copy_functions, 3, ce, &overriden, &exclude_table);
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->traits[i]->function_table, key, fn) {
|
||||
zend_traits_copy_functions(key, fn, ce, &overriden, &exclude_table TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
zend_hash_destroy(&exclude_table);
|
||||
} else {
|
||||
zend_hash_apply_with_arguments(&ce->traits[i]->function_table TSRMLS_CC, zend_traits_copy_functions, 3, ce, &overriden, NULL);
|
||||
ZEND_HASH_FOREACH_STR_KEY_PTR(&ce->traits[i]->function_table, key, fn) {
|
||||
zend_traits_copy_functions(key, fn, ce, &overriden, NULL TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
}
|
||||
|
||||
zend_hash_apply_with_argument(&ce->function_table, zend_fixup_trait_method, ce TSRMLS_CC);
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, fn) {
|
||||
zend_fixup_trait_method(fn, ce);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (overriden) {
|
||||
zend_hash_destroy(overriden);
|
||||
|
@ -5920,7 +5899,6 @@ void zend_do_end_array(znode *result, const znode *array_node TSRMLS_DC) /* {{{
|
|||
int i;
|
||||
int constant_array = 0;
|
||||
zval array;
|
||||
zend_constant *c;
|
||||
|
||||
/* check if constructed array consists only from constants */
|
||||
if ((init_opline->op1_type & (IS_UNUSED | IS_CONST)) &&
|
||||
|
@ -6949,24 +6927,19 @@ int zend_register_auto_global(zend_string *name, zend_bool jit, zend_auto_global
|
|||
}
|
||||
/* }}} */
|
||||
|
||||
static int zend_auto_global_init(zval *zv TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_auto_global *auto_global = Z_PTR_P(zv);
|
||||
|
||||
if (auto_global->jit) {
|
||||
auto_global->armed = 1;
|
||||
} else if (auto_global->auto_global_callback) {
|
||||
auto_global->armed = auto_global->auto_global_callback(auto_global->name TSRMLS_CC);
|
||||
} else {
|
||||
auto_global->armed = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
ZEND_API void zend_activate_auto_globals(TSRMLS_D) /* {{{ */
|
||||
{
|
||||
zend_hash_apply(CG(auto_globals), zend_auto_global_init TSRMLS_CC);
|
||||
zend_auto_global *auto_global;
|
||||
|
||||
ZEND_HASH_FOREACH_PTR(CG(auto_globals), auto_global) {
|
||||
if (auto_global->jit) {
|
||||
auto_global->armed = 1;
|
||||
} else if (auto_global->auto_global_callback) {
|
||||
auto_global->armed = auto_global->auto_global_callback(auto_global->name TSRMLS_CC);
|
||||
} else {
|
||||
auto_global->armed = 0;
|
||||
}
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
|
|
|
@ -1524,11 +1524,8 @@ typedef struct _zend_abstract_info {
|
|||
int ctor;
|
||||
} zend_abstract_info;
|
||||
|
||||
static int zend_verify_abstract_class_function(zval *zv, void *arg TSRMLS_DC) /* {{{ */
|
||||
static void zend_verify_abstract_class_function(zend_function *fn, zend_abstract_info *ai TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_function *fn = (zend_function *)Z_PTR_P(zv);
|
||||
zend_abstract_info *ai = (zend_abstract_info *)arg;
|
||||
|
||||
if (fn->common.fn_flags & ZEND_ACC_ABSTRACT) {
|
||||
if (ai->cnt < MAX_ABSTRACT_INFO_CNT) {
|
||||
ai->afn[ai->cnt] = fn;
|
||||
|
@ -1544,18 +1541,20 @@ static int zend_verify_abstract_class_function(zval *zv, void *arg TSRMLS_DC) /*
|
|||
ai->cnt++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
/* }}} */
|
||||
|
||||
void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC) /* {{{ */
|
||||
{
|
||||
zend_function *func;
|
||||
zend_abstract_info ai;
|
||||
|
||||
if ((ce->ce_flags & ZEND_ACC_IMPLICIT_ABSTRACT_CLASS) && !(ce->ce_flags & ZEND_ACC_EXPLICIT_ABSTRACT_CLASS)) {
|
||||
memset(&ai, 0, sizeof(ai));
|
||||
|
||||
zend_hash_apply_with_argument(&ce->function_table, zend_verify_abstract_class_function, &ai TSRMLS_CC);
|
||||
ZEND_HASH_FOREACH_PTR(&ce->function_table, func) {
|
||||
zend_verify_abstract_class_function(func, &ai TSRMLS_CC);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
if (ai.cnt) {
|
||||
zend_error(E_ERROR, "Class %s contains %d abstract method%s and must therefore be declared abstract or implement the remaining methods (" MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT MAX_ABSTRACT_INFO_FMT ")",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue