From 7652a977a88b825f66959e91a7c8c54b720a50bc Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 18 Apr 2014 19:18:11 +0400 Subject: [PATCH] Use ZEND_FETCH_FOREACH_* macros to iterate over HashTables instead of zend_hash_move_forward() and family. --- Zend/zend.c | 69 ++--- Zend/zend_API.c | 70 ++--- Zend/zend_builtin_functions.c | 85 ++---- Zend/zend_compile.c | 12 +- Zend/zend_hash.h | 100 +++++++ Zend/zend_list.c | 7 +- Zend/zend_object_handlers.c | 13 +- Zend/zend_objects.c | 18 +- ext/pcre/php_pcre.c | 44 +-- ext/standard/array.c | 476 ++++++++++++------------------ ext/standard/basic_functions.c | 25 +- ext/standard/file.c | 15 +- ext/standard/filters.c | 7 +- ext/standard/formatted_print.c | 6 +- ext/standard/http.c | 23 +- ext/standard/http_fopen_wrapper.c | 15 +- ext/standard/proc_open.c | 81 ++--- ext/standard/streamsfuncs.c | 82 ++--- ext/standard/string.c | 74 ++--- ext/standard/url.c | 10 +- ext/standard/user_filters.c | 11 +- ext/standard/var.c | 44 +-- 22 files changed, 525 insertions(+), 762 deletions(-) diff --git a/Zend/zend.c b/Zend/zend.c index 57344547d51..cef24c085ba 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -142,12 +142,10 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, } ZEND_PUTS_EX("(\n"); indent += PRINT_ZVAL_INDENT; - zend_hash_internal_pointer_reset_ex(ht, &iterator); - while ((tmp = zend_hash_get_current_data_ex(ht, &iterator)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, string_key, tmp) { if (Z_TYPE_P(tmp) == IS_INDIRECT) { tmp = Z_INDIRECT_P(tmp); if (Z_TYPE_P(tmp) == IS_UNDEF) { - zend_hash_move_forward_ex(ht, &iterator); continue; } } @@ -155,40 +153,34 @@ static void print_hash(zend_write_func_t write_func, HashTable *ht, int indent, ZEND_PUTS_EX(" "); } ZEND_PUTS_EX("["); - switch (zend_hash_get_current_key_ex(ht, &string_key, &num_key, 0, &iterator)) { - case HASH_KEY_IS_STRING: - if (is_object) { - const char *prop_name, *class_name; - int prop_len; - int mangled = zend_unmangle_property_name_ex(string_key->val, string_key->len, &class_name, &prop_name, &prop_len); + if (string_key) { + if (is_object) { + const char *prop_name, *class_name; + int prop_len; + int mangled = zend_unmangle_property_name_ex(string_key->val, string_key->len, &class_name, &prop_name, &prop_len); - ZEND_WRITE_EX(prop_name, prop_len); - if (class_name && mangled == SUCCESS) { - if (class_name[0]=='*') { - ZEND_PUTS_EX(":protected"); - } else { - ZEND_PUTS_EX(":"); - ZEND_PUTS_EX(class_name); - ZEND_PUTS_EX(":private"); - } + ZEND_WRITE_EX(prop_name, prop_len); + if (class_name && mangled == SUCCESS) { + if (class_name[0]=='*') { + ZEND_PUTS_EX(":protected"); + } else { + ZEND_PUTS_EX(":"); + ZEND_PUTS_EX(class_name); + ZEND_PUTS_EX(":private"); } - } else { - ZEND_WRITE_EX(string_key->val, string_key->len); } - break; - case HASH_KEY_IS_LONG: - { - char key[25]; - snprintf(key, sizeof(key), "%ld", num_key); - ZEND_PUTS_EX(key); - } - break; + } else { + ZEND_WRITE_EX(string_key->val, string_key->len); + } + } else { + char key[25]; + snprintf(key, sizeof(key), "%ld", num_key); + ZEND_PUTS_EX(key); } ZEND_PUTS_EX("] => "); zend_print_zval_r_ex(write_func, tmp, indent+PRINT_ZVAL_INDENT TSRMLS_CC); ZEND_PUTS_EX("\n"); - zend_hash_move_forward_ex(ht, &iterator); - } + } ZEND_HASH_FOREACH_END(); indent -= PRINT_ZVAL_INDENT; for (i = 0; i < indent; i++) { ZEND_PUTS_EX(" "); @@ -205,24 +197,19 @@ static void print_flat_hash(HashTable *ht TSRMLS_DC) /* {{{ */ ulong num_key; int i = 0; - zend_hash_internal_pointer_reset_ex(ht, &iterator); - while ((tmp = zend_hash_get_current_data_ex(ht, &iterator)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(ht, num_key, string_key, tmp) { if (i++ > 0) { ZEND_PUTS(","); } ZEND_PUTS("["); - switch (zend_hash_get_current_key_ex(ht, &string_key, &num_key, 0, &iterator)) { - case HASH_KEY_IS_STRING: - ZEND_WRITE(string_key->val, string_key->len); - break; - case HASH_KEY_IS_LONG: - zend_printf("%ld", num_key); - break; + if (string_key) { + ZEND_WRITE(string_key->val, string_key->len); + } else { + zend_printf("%ld", num_key); } ZEND_PUTS("] => "); zend_print_flat_zval_r(tmp TSRMLS_CC); - zend_hash_move_forward_ex(ht, &iterator); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ diff --git a/Zend/zend_API.c b/Zend/zend_API.c index f16d07b0048..7d79d99beef 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -1119,13 +1119,10 @@ static int zval_update_class_constant(zval *pp, int is_static, int offset TSRMLS 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); - (prop_info = zend_hash_get_current_data_ptr_ex(&ce->properties_info, &pos)) != NULL; - zend_hash_move_forward_ex(&ce->properties_info, &pos)) { + ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { if (is_static == ((prop_info->flags & ZEND_ACC_STATIC) != 0) && offset == prop_info->offset) { int ret; @@ -1135,7 +1132,7 @@ static int zval_update_class_constant(zval *pp, int is_static, int offset TSRMLS *scope = old_scope; return ret; } - } + } ZEND_HASH_FOREACH_END(); ce = ce->parent; } while (ce); @@ -1223,17 +1220,12 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti { object->properties = properties; if (object->ce->default_properties_count) { - HashPosition pos; zval *prop, tmp; zend_string *key; ulong num_key; zend_property_info *property_info; - for (zend_hash_internal_pointer_reset_ex(properties, &pos); - (prop = zend_hash_get_current_data_ex(properties, &pos)) != NULL && - zend_hash_get_current_key_ex(properties, &key, &num_key, 0, &pos) == HASH_KEY_IS_STRING; - zend_hash_move_forward_ex(properties, &pos)) { - + ZEND_HASH_FOREACH_KEY_VAL(properties, num_key, key, prop) { ZVAL_STR(&tmp, key); property_info = zend_get_property_info(object->ce, &tmp, 1 TSRMLS_CC); if (property_info && @@ -1242,24 +1234,19 @@ ZEND_API void object_properties_init_ex(zend_object *object, HashTable *properti ZVAL_COPY_VALUE(&object->properties_table[property_info->offset], prop); ZVAL_INDIRECT(prop, &object->properties_table[property_info->offset]); } - } + } ZEND_HASH_FOREACH_END(); } } /* }}} */ ZEND_API void object_properties_load(zend_object *object, HashTable *properties TSRMLS_DC) /* {{{ */ { - HashPosition pos; zval *prop, tmp; zend_string *key; ulong num_key; zend_property_info *property_info; - for (zend_hash_internal_pointer_reset_ex(properties, &pos); - (prop = zend_hash_get_current_data_ex(properties, &pos)) != NULL && - zend_hash_get_current_key_ex(properties, &key, &num_key, 0, &pos) == HASH_KEY_IS_STRING; - zend_hash_move_forward_ex(properties, &pos)) { - + ZEND_HASH_FOREACH_KEY_VAL(properties, num_key, key, prop) { ZVAL_STR(&tmp, key); property_info = zend_get_property_info(object->ce, &tmp, 1 TSRMLS_CC); if (property_info && @@ -1279,7 +1266,7 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties prop = zend_hash_update(object->properties, key, prop); zval_add_ref(prop); } - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -1892,7 +1879,6 @@ try_again: ZEND_API void zend_collect_module_handlers(TSRMLS_D) /* {{{ */ { - HashPosition pos; zend_module_entry *module; int startup_count = 0; int shutdown_count = 0; @@ -1901,9 +1887,7 @@ ZEND_API void zend_collect_module_handlers(TSRMLS_D) /* {{{ */ int class_count = 0; /* Collect extensions with request startup/shutdown handlers */ - for (zend_hash_internal_pointer_reset_ex(&module_registry, &pos); - (module = zend_hash_get_current_data_ptr_ex(&module_registry, &pos)) != NULL; - zend_hash_move_forward_ex(&module_registry, &pos)) { + ZEND_HASH_FOREACH_PTR(&module_registry, module) { if (module->request_startup_func) { startup_count++; } @@ -1913,7 +1897,7 @@ ZEND_API void zend_collect_module_handlers(TSRMLS_D) /* {{{ */ if (module->post_deactivate_func) { post_deactivate_count++; } - } + } ZEND_HASH_FOREACH_END(); module_request_startup_handlers = (zend_module_entry**)malloc( sizeof(zend_module_entry*) * (startup_count + 1 + @@ -1926,9 +1910,7 @@ ZEND_API void zend_collect_module_handlers(TSRMLS_D) /* {{{ */ module_post_deactivate_handlers[post_deactivate_count] = NULL; startup_count = 0; - for (zend_hash_internal_pointer_reset_ex(&module_registry, &pos); - (module = zend_hash_get_current_data_ptr_ex(&module_registry, &pos)) != NULL; - zend_hash_move_forward_ex(&module_registry, &pos)) { + ZEND_HASH_FOREACH_PTR(&module_registry, module) { if (module->request_startup_func) { module_request_startup_handlers[startup_count++] = module; } @@ -1938,17 +1920,15 @@ ZEND_API void zend_collect_module_handlers(TSRMLS_D) /* {{{ */ if (module->post_deactivate_func) { module_post_deactivate_handlers[--post_deactivate_count] = module; } - } + } ZEND_HASH_FOREACH_END(); /* Collect internal classes with static members */ - for (zend_hash_internal_pointer_reset_ex(CG(class_table), &pos); - (ce = zend_hash_get_current_data_ptr_ex(CG(class_table), &pos)) != NULL; - zend_hash_move_forward_ex(CG(class_table), &pos)) { + ZEND_HASH_FOREACH_PTR(CG(class_table), ce) { if (ce->type == ZEND_INTERNAL_CLASS && ce->default_static_members_count > 0) { class_count++; } - } + } ZEND_HASH_FOREACH_END(); class_cleanup_handlers = (zend_class_entry**)malloc( sizeof(zend_class_entry*) * @@ -1956,14 +1936,12 @@ ZEND_API void zend_collect_module_handlers(TSRMLS_D) /* {{{ */ class_cleanup_handlers[class_count] = NULL; if (class_count) { - for (zend_hash_internal_pointer_reset_ex(CG(class_table), &pos); - (ce = zend_hash_get_current_data_ptr_ex(CG(class_table), &pos)) != NULL; - zend_hash_move_forward_ex(CG(class_table), &pos)) { + ZEND_HASH_FOREACH_PTR(CG(class_table), ce) { if (ce->type == ZEND_INTERNAL_CLASS && ce->default_static_members_count > 0) { class_cleanup_handlers[--class_count] = ce; } - } + } ZEND_HASH_FOREACH_END(); } } /* }}} */ @@ -3407,7 +3385,6 @@ ZEND_API void zend_fcall_info_args_restore(zend_fcall_info *fci, int param_count ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC) /* {{{ */ { - HashPosition pos; zval *arg, *params; zend_fcall_info_args_clear(fci, !args); @@ -3423,12 +3400,10 @@ ZEND_API int zend_fcall_info_args(zend_fcall_info *fci, zval *args TSRMLS_DC) /* fci->param_count = zend_hash_num_elements(Z_ARRVAL_P(args)); fci->params = params = (zval *) erealloc(fci->params, fci->param_count * sizeof(zval)); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(args), &pos); - while ((arg = zend_hash_get_current_data_ex(Z_ARRVAL_P(args), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) { ZVAL_COPY(params, arg); params++; - zend_hash_move_forward_ex(Z_ARRVAL_P(args), &pos); - } + } ZEND_HASH_FOREACH_END(); return SUCCESS; } @@ -4026,6 +4001,8 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi zend_function *func; HashPosition iterator; HashTable *function_table; + zend_string *name; + ulong idx; if (f->common.type != ZEND_USER_FUNCTION || *(f->op_array.refcount) < 2 || @@ -4035,13 +4012,9 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi } function_table = &ce->function_table; - zend_hash_internal_pointer_reset_ex(function_table, &iterator); - while ((func = zend_hash_get_current_data_ptr_ex(function_table, &iterator)) != NULL) { + ZEND_HASH_FOREACH_KEY_PTR(function_table, idx, name, func) { if (func == f) { - zend_string *name; - ulong idx; - - if (zend_hash_get_current_key_ex(function_table, &name, &idx, 0, &iterator) != HASH_KEY_IS_STRING) { + if (!name) { return f->common.function_name; } if (name->len == f->common.function_name->len && @@ -4050,8 +4023,7 @@ ZEND_API zend_string *zend_resolve_method_name(zend_class_entry *ce, zend_functi } return zend_find_alias_name(f->common.scope, name); } - zend_hash_move_forward_ex(function_table, &iterator); - } + } ZEND_HASH_FOREACH_END(); return f->common.function_name; } /* }}} */ diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index cffe0b4c78b..182c34f9ab0 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -903,16 +903,12 @@ ZEND_FUNCTION(is_a) /* {{{ add_class_vars */ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value TSRMLS_DC) { - HashPosition pos; zend_property_info *prop_info; zval *prop, prop_copy; zend_string *key; ulong num_index; - zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); - while ((prop_info = zend_hash_get_current_data_ptr_ex(&ce->properties_info, &pos)) != NULL) { - zend_hash_get_current_key_ex(&ce->properties_info, &key, &num_index, 0, &pos); - zend_hash_move_forward_ex(&ce->properties_info, &pos); + ZEND_HASH_FOREACH_KEY_PTR(&ce->properties_info, num_index, key, prop_info) { if (((prop_info->flags & ZEND_ACC_SHADOW) && prop_info->ce != EG(scope)) || ((prop_info->flags & ZEND_ACC_PROTECTED) && @@ -944,7 +940,7 @@ static void add_class_vars(zend_class_entry *ce, int statics, zval *return_value } zend_hash_update(Z_ARRVAL_P(return_value), key, &prop_copy); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -980,7 +976,6 @@ ZEND_FUNCTION(get_object_vars) zval *obj; zval *value; HashTable *properties; - HashPosition pos; zend_string *key; const char *prop_name, *class_name; uint prop_len; @@ -1005,17 +1000,8 @@ ZEND_FUNCTION(get_object_vars) array_init(return_value); - zend_hash_internal_pointer_reset_ex(properties, &pos); - - while ((value = zend_hash_get_current_data_ex(properties, &pos)) != NULL) { - if (Z_TYPE_P(value) == IS_INDIRECT) { - value = Z_INDIRECT_P(value); - if (Z_TYPE_P(value) == IS_UNDEF) { - zend_hash_move_forward_ex(properties, &pos); - continue; - } - } - if (zend_hash_get_current_key_ex(properties, &key, &num_index, 0, &pos) == HASH_KEY_IS_STRING) { + ZEND_HASH_FOREACH_KEY_VAL_IND(properties, num_index, key, value) { + if (key) { if (zend_check_property_access(zobj, key TSRMLS_CC) == SUCCESS) { /* Not separating references */ if (Z_REFCOUNTED_P(value)) Z_ADDREF_P(value); @@ -1027,8 +1013,7 @@ ZEND_FUNCTION(get_object_vars) } } } - zend_hash_move_forward_ex(properties, &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -1047,8 +1032,9 @@ ZEND_FUNCTION(get_class_methods) zval *klass; zval method_name; zend_class_entry *ce = NULL; - HashPosition pos; zend_function *mptr; + zend_string *key; + ulong num_index; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &klass) == FAILURE) { return; @@ -1069,21 +1055,19 @@ ZEND_FUNCTION(get_class_methods) } array_init(return_value); - zend_hash_internal_pointer_reset_ex(&ce->function_table, &pos); - while ((mptr = zend_hash_get_current_data_ptr_ex(&ce->function_table, &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_PTR(&ce->function_table, num_index, key, mptr) { + if ((mptr->common.fn_flags & ZEND_ACC_PUBLIC) || (EG(scope) && (((mptr->common.fn_flags & ZEND_ACC_PROTECTED) && zend_check_protected(mptr->common.scope, EG(scope))) || ((mptr->common.fn_flags & ZEND_ACC_PRIVATE) && EG(scope) == mptr->common.scope)))) { - zend_string *key; - ulong num_index; uint len = mptr->common.function_name->len; /* Do not display old-style inherited constructors */ - if (zend_hash_get_current_key_ex(&ce->function_table, &key, &num_index, 0, &pos) != HASH_KEY_IS_STRING) { + if (!key) { // TODO: we have to duplicate it, becaise it may be stored in opcache SHM ??? ZVAL_STR(&method_name, STR_DUP(mptr->common.function_name, 0)); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &method_name); @@ -1104,8 +1088,7 @@ ZEND_FUNCTION(get_class_methods) } } } - zend_hash_move_forward_ex(&ce->function_table, &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -1443,17 +1426,18 @@ ZEND_FUNCTION(crash) ZEND_FUNCTION(get_included_files) { zend_string *entry; + ulong num_idx; if (zend_parse_parameters_none() == FAILURE) { return; } array_init(return_value); - zend_hash_internal_pointer_reset(&EG(included_files)); - while (zend_hash_get_current_key(&EG(included_files), &entry, NULL, 0) == HASH_KEY_IS_STRING) { - add_next_index_str(return_value, STR_COPY(entry)); - zend_hash_move_forward(&EG(included_files)); - } + ZEND_HASH_FOREACH_KEY(&EG(included_files), num_idx, entry) { + if (entry) { + add_next_index_str(return_value, STR_COPY(entry)); + } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -1928,7 +1912,6 @@ ZEND_FUNCTION(get_defined_constants) array_init(return_value); if (categorize) { - HashPosition pos; zend_constant *val; int module_number; zval *modules; @@ -1940,28 +1923,25 @@ ZEND_FUNCTION(get_defined_constants) module_names = emalloc((zend_hash_num_elements(&module_registry) + 2) * sizeof(char *)); module_names[0] = "internal"; - zend_hash_internal_pointer_reset_ex(&module_registry, &pos); - while ((module = zend_hash_get_current_data_ptr_ex(&module_registry, &pos)) != NULL) { + ZEND_HASH_FOREACH_PTR(&module_registry, module) { module_names[module->module_number] = (char *)module->name; i++; - zend_hash_move_forward_ex(&module_registry, &pos); - } + } ZEND_HASH_FOREACH_END(); module_names[i] = "user"; - zend_hash_internal_pointer_reset_ex(EG(zend_constants), &pos); - while ((val = zend_hash_get_current_data_ptr_ex(EG(zend_constants), &pos)) != NULL) { + ZEND_HASH_FOREACH_PTR(EG(zend_constants), val) { zval const_val; if (!val->name) { /* skip special constants */ - goto next_constant; + continue; } if (val->module_number == PHP_USER_CONSTANT) { module_number = i; } else if (val->module_number > i || val->module_number < 0) { /* should not happen */ - goto next_constant; + continue; } else { module_number = val->module_number; } @@ -1974,9 +1954,8 @@ ZEND_FUNCTION(get_defined_constants) ZVAL_DUP_DEREF(&const_val, &val->value); zend_hash_update(Z_ARRVAL(modules[module_number]), val->name, &const_val); -next_constant: - zend_hash_move_forward_ex(EG(zend_constants), &pos); - } + } ZEND_HASH_FOREACH_END(); + efree(module_names); efree(modules); } else { @@ -2009,17 +1988,14 @@ static void debug_backtrace_get_args(zval *curpos, zval *arg_array TSRMLS_DC) void debug_print_backtrace_args(zval *arg_array TSRMLS_DC) { zval *tmp; - HashPosition iterator; int i = 0; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arg_array), &iterator); - while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(arg_array), &iterator)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arg_array), tmp) { if (i++) { ZEND_PUTS(", "); } zend_print_flat_zval_r(tmp TSRMLS_CC); - zend_hash_move_forward_ex(Z_ARRVAL_P(arg_array), &iterator); - } + } ZEND_HASH_FOREACH_END(); } /* {{{ proto void debug_print_backtrace([int options[, int limit]]) */ @@ -2402,8 +2378,8 @@ ZEND_FUNCTION(get_extension_funcs) zend_string *lcname; int extension_name_len, array; zend_module_entry *module; - HashPosition iterator; zend_function *zif; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &extension_name, &extension_name_len) == FAILURE) { return; } @@ -2419,7 +2395,6 @@ ZEND_FUNCTION(get_extension_funcs) RETURN_FALSE; } - zend_hash_internal_pointer_reset_ex(CG(function_table), &iterator); if (module->functions) { /* avoid BC break, if functions list is empty, will return an empty array */ array_init(return_value); @@ -2427,7 +2402,8 @@ ZEND_FUNCTION(get_extension_funcs) } else { array = 0; } - while ((zif = zend_hash_get_current_data_ptr_ex(CG(function_table), &iterator)) != NULL) { + + ZEND_HASH_FOREACH_PTR(CG(function_table), zif) { if (zif->common.type == ZEND_INTERNAL_FUNCTION && zif->internal_function.module == module) { if (!array) { @@ -2437,8 +2413,7 @@ ZEND_FUNCTION(get_extension_funcs) // TODO: we have to duplicate it, becaise it may be stored in opcache SHM ??? add_next_index_str(return_value, STR_DUP(zif->common.function_name, 0)); } - zend_hash_move_forward_ex(CG(function_table), &iterator); - } + } ZEND_HASH_FOREACH_END(); if (!array) { RETURN_FALSE; diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 8ccab3942e2..14d937bb558 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -3847,9 +3847,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent } } - for (zend_hash_internal_pointer_reset(&ce->properties_info); - (property_info = zend_hash_get_current_data_ptr(&ce->properties_info)) != NULL; - zend_hash_move_forward(&ce->properties_info)) { + ZEND_HASH_FOREACH_PTR(&ce->properties_info, property_info) { if (property_info->ce == ce) { if (property_info->flags & ZEND_ACC_STATIC) { property_info->offset += parent_ce->default_static_members_count; @@ -3857,7 +3855,7 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent property_info->offset += parent_ce->default_properties_count; } } - } + } ZEND_HASH_FOREACH_END(); zend_hash_merge_ex(&ce->properties_info, &parent_ce->properties_info, (ce->type & ZEND_INTERNAL_CLASS ? zend_duplicate_property_info_internal_zval : zend_duplicate_property_info_zval), (merge_checker_func_t) do_inherit_property_access_check, ce); @@ -4430,9 +4428,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { * - if compatible, then strict notice */ for (i = 0; i < ce->num_traits; i++) { - for (zend_hash_internal_pointer_reset(&ce->traits[i]->properties_info); - (property_info = zend_hash_get_current_data_ptr(&ce->traits[i]->properties_info)) != NULL; - zend_hash_move_forward(&ce->traits[i]->properties_info)) { + ZEND_HASH_FOREACH_PTR(&ce->traits[i]->properties_info, property_info) { /* first get the unmangeld name if necessary, * then check whether the property is already there */ @@ -4507,7 +4503,7 @@ static void zend_do_traits_property_binding(zend_class_entry *ce TSRMLS_DC) /* { prop_value, flags, doc_comment TSRMLS_CC); STR_RELEASE(prop_name); - } + } ZEND_HASH_FOREACH_END(); } } /* }}} */ diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 11dc92d3c3c..ba0b28bd7b0 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -533,6 +533,106 @@ static inline void *zend_hash_get_current_data_ptr_ex(HashTable *ht, HashPositio #define zend_hash_get_current_data_ptr(ht) \ zend_hash_get_current_data_ptr_ex(ht, &(ht)->nInternalPointer) +#define ZEND_HASH_FOREACH_VAL(_ht, _val) do { \ + uint _idx; \ + Bucket *_p; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + if (Z_TYPE(_p->val) == IS_UNDEF) continue; \ + _val = &_p->val; + +#define ZEND_HASH_FOREACH_VAL_IND(_ht, _val) do { \ + uint _idx; \ + Bucket *_p; \ + zval *_z; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + _z = &_p->val; \ + if (Z_TYPE_P(_z) == IS_INDIRECT) { \ + _z = Z_INDIRECT_P(_z); \ + } \ + if (Z_TYPE_P(_z) == IS_UNDEF) continue; \ + _val = _z; + +#define ZEND_HASH_FOREACH_PTR(_ht, _ptr) do { \ + uint _idx; \ + Bucket *_p; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + if (Z_TYPE(_p->val) == IS_UNDEF) continue; \ + _ptr = Z_PTR(_p->val); + +#define ZEND_HASH_FOREACH_KEY(_ht, _h, _key) do { \ + uint _idx; \ + Bucket *_p; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + if (Z_TYPE(_p->val) == IS_UNDEF) continue; \ + _h = _p->h; \ + _key = _p->key; \ + +#define ZEND_HASH_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \ + uint _idx; \ + Bucket *_p; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + if (Z_TYPE(_p->val) == IS_UNDEF) continue; \ + _h = _p->h; \ + _key = _p->key; \ + _val = &_p->val; + +#define ZEND_HASH_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \ + uint _idx; \ + Bucket *_p; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + if (Z_TYPE(_p->val) == IS_UNDEF) continue; \ + _h = _p->h; \ + _key = _p->key; \ + _val = &_p->val; + +#define ZEND_HASH_FOREACH_KEY_VAL_IND(_ht, _h, _key, _val) do { \ + uint _idx; \ + Bucket *_p; \ + zval *_z; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + _z = &_p->val; \ + if (Z_TYPE_P(_z) == IS_INDIRECT) { \ + _z = Z_INDIRECT_P(_z); \ + } \ + if (Z_TYPE_P(_z) == IS_UNDEF) continue; \ + _h = _p->h; \ + _key = _p->key; \ + _val = _z; + +#define ZEND_HASH_FOREACH_KEY_PTR(_ht, _h, _key, _ptr) do { \ + uint _idx; \ + Bucket *_p; \ + for (_idx = 0; _idx < (_ht)->nNumUsed; _idx++) { \ + _p = (_ht)->arData + _idx; \ + if (Z_TYPE(_p->val) == IS_UNDEF) continue; \ + _h = _p->h; \ + _key = _p->key; \ + _ptr = Z_PTR(_p->val); + + +#define ZEND_HASH_REVERSE_FOREACH_KEY_VAL(_ht, _h, _key, _val) do { \ + uint _idx; \ + Bucket *_p; \ + for (_idx = (_ht)->nNumUsed; _idx > 0; _idx--) { \ + _p = (_ht)->arData + _idx - 1; \ + if (Z_TYPE(_p->val) == IS_UNDEF) continue; \ + _h = _p->h; \ + _key = _p->key; \ + _val = &_p->val; + +#define ZEND_HASH_FOREACH_END() \ + } \ + } while (0) + + + #endif /* ZEND_HASH_H */ /* diff --git a/Zend/zend_list.c b/Zend/zend_list.c index 5521964588a..acd756bc995 100644 --- a/Zend/zend_list.c +++ b/Zend/zend_list.c @@ -315,15 +315,12 @@ ZEND_API int zend_register_list_destructors_ex(rsrc_dtor_func_t ld, rsrc_dtor_fu ZEND_API int zend_fetch_list_dtor_id(const char *type_name) { zend_rsrc_list_dtors_entry *lde; - HashPosition pos; - zend_hash_internal_pointer_reset_ex(&list_destructors, &pos); - while ((lde = zend_hash_get_current_data_ptr_ex(&list_destructors, &pos)) != NULL) { + ZEND_HASH_FOREACH_PTR(&list_destructors, lde) { if (lde->type_name && (strcmp(type_name, lde->type_name) == 0)) { return lde->resource_id; } - zend_hash_move_forward_ex(&list_destructors, &pos); - } + } ZEND_HASH_FOREACH_END(); return 0; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 47ee60f5b8e..6350e7ed09c 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -71,16 +71,13 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ { if (!zobj->properties) { - HashPosition pos; zend_property_info *prop_info; zend_class_entry *ce = zobj->ce; ALLOC_HASHTABLE(zobj->properties); zend_hash_init(zobj->properties, 0, NULL, ZVAL_PTR_DTOR, 0); if (ce->default_properties_count) { - for (zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); - (prop_info = zend_hash_get_current_data_ptr_ex(&ce->properties_info, &pos)) != NULL; - zend_hash_move_forward_ex(&ce->properties_info, &pos)) { + ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { if (/*prop_info->ce == ce &&*/ (prop_info->flags & ZEND_ACC_STATIC) == 0 && prop_info->offset >= 0 && @@ -90,12 +87,10 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]); zend_hash_add(zobj->properties, prop_info->name, &zv); } - } + } ZEND_HASH_FOREACH_END(); while (ce->parent && ce->parent->default_properties_count) { ce = ce->parent; - for (zend_hash_internal_pointer_reset_ex(&ce->properties_info, &pos); - (prop_info = zend_hash_get_current_data_ptr_ex(&ce->properties_info, &pos)) != NULL; - zend_hash_move_forward_ex(&ce->properties_info, &pos)) { + ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) { if (prop_info->ce == ce && (prop_info->flags & ZEND_ACC_STATIC) == 0 && (prop_info->flags & ZEND_ACC_PRIVATE) != 0 && @@ -106,7 +101,7 @@ ZEND_API void rebuild_object_properties(zend_object *zobj) /* {{{ */ ZVAL_INDIRECT(&zv, &zobj->properties_table[prop_info->offset]); zend_hash_add(zobj->properties, prop_info->name, &zv); } - } + } ZEND_HASH_FOREACH_END(); } } } diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 390d6fc0266..2ffec7cd8e6 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -148,7 +148,6 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o } } if (old_object->properties) { - HashPosition pos; zval *prop, new_prop; ulong num_key; zend_string *key; @@ -158,24 +157,19 @@ ZEND_API void zend_objects_clone_members(zend_object *new_object, zend_object *o zend_hash_init(new_object->properties, 0, NULL, ZVAL_PTR_DTOR, 0); } - for (zend_hash_internal_pointer_reset_ex(old_object->properties, &pos); - (prop = zend_hash_get_current_data_ex(old_object->properties, &pos)) != NULL; - zend_hash_move_forward_ex(old_object->properties, &pos)) { + ZEND_HASH_FOREACH_KEY_VAL(old_object->properties, num_key, key, prop) { if (Z_TYPE_P(prop) == IS_INDIRECT) { ZVAL_INDIRECT(&new_prop, new_object->properties_table + (Z_INDIRECT_P(prop) - old_object->properties_table)); } else { ZVAL_COPY_VALUE(&new_prop, prop); zval_add_ref(&new_prop); } - switch (zend_hash_get_current_key_ex(old_object->properties, &key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - zend_hash_update(new_object->properties, key, &new_prop); - break; - case HASH_KEY_IS_LONG: - zend_hash_index_update(new_object->properties, num_key, &new_prop); - break; + if (key) { + zend_hash_update(new_object->properties, key, &new_prop); + } else { + zend_hash_index_update(new_object->properties, num_key, &new_prop); } - } + } ZEND_HASH_FOREACH_END(); } if (old_object->ce->clone) { diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index a38c5cdebdd..724b667bdec 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -1250,14 +1250,12 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub /* Duplicate subject string for repeated replacement */ subject_value = STR_INIT(Z_STRVAL_P(subject), Z_STRLEN_P(subject), 0); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(regex)); - replace_value = replace; if (Z_TYPE_P(replace) == IS_ARRAY && !is_callable_replace) zend_hash_internal_pointer_reset(Z_ARRVAL_P(replace)); /* For each entry in the regex array, get the entry */ - while ((regex_entry = zend_hash_get_current_data(Z_ARRVAL_P(regex))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(regex), regex_entry) { /* Make sure we're dealing with strings. */ convert_to_string_ex(regex_entry); @@ -1293,8 +1291,7 @@ static zend_string *php_replace_in_subject(zval *regex, zval *replace, zval *sub return NULL; } - zend_hash_move_forward(Z_ARRVAL_P(regex)); - } + } ZEND_HASH_FOREACH_END(); zval_ptr_dtor(&tmp_subject); return subject_value; @@ -1365,32 +1362,24 @@ static void preg_replace_impl(INTERNAL_FUNCTION_PARAMETERS, int is_callable_repl /* if subject is an array */ if (Z_TYPE_P(subject) == IS_ARRAY) { array_init(return_value); - zend_hash_internal_pointer_reset(Z_ARRVAL_P(subject)); /* For each subject entry, convert it to string, then perform replacement and add the result to the return_value array. */ - while ((subject_entry = zend_hash_get_current_data(Z_ARRVAL_P(subject))) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(subject), num_key, string_key, subject_entry) { old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject_entry, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { if (!is_filter || replace_count > old_replace_count) { /* Add to return array */ - switch(zend_hash_get_current_key(Z_ARRVAL_P(subject), &string_key, &num_key, 0)) - { - case HASH_KEY_IS_STRING: + if (string_key) { add_assoc_str_ex(return_value, string_key->val, string_key->len, result); - break; - - case HASH_KEY_IS_LONG: + } else { add_index_str(return_value, num_key, result); - break; } } else { STR_FREE(result); } } - - zend_hash_move_forward(Z_ARRVAL_P(subject)); - } + } ZEND_HASH_FOREACH_END(); } else { /* if subject is not an array */ old_replace_count = replace_count; if ((result = php_replace_in_subject(regex, replace, subject, limit_val, is_callable_replace, &replace_count TSRMLS_CC)) != NULL) { @@ -1781,8 +1770,7 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return PCRE_G(error_code) = PHP_PCRE_NO_ERROR; /* Go through the input array */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); - while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(input))) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) { zval subject, *ref_entry = entry; if (Z_ISREF_P(entry)) { @@ -1818,15 +1806,10 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return } /* Add to return array */ - switch (zend_hash_get_current_key(Z_ARRVAL_P(input), &string_key, &num_key, 0)) - { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); - break; - - case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, ref_entry); + } else { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, ref_entry); } } @@ -1834,9 +1817,8 @@ PHPAPI void php_pcre_grep_impl(pcre_cache_entry *pce, zval *input, zval *return zval_dtor(&subject); } - zend_hash_move_forward(Z_ARRVAL_P(input)); - } - zend_hash_internal_pointer_reset(Z_ARRVAL_P(input)); + } ZEND_HASH_FOREACH_END(); + /* Clean up */ efree(offsets); } diff --git a/ext/standard/array.c b/ext/standard/array.c index 20ad3d9986c..dfa6471660e 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -281,17 +281,12 @@ static int php_count_recursive(zval *array, long mode TSRMLS_DC) /* {{{ */ cnt = zend_hash_num_elements(Z_ARRVAL_P(array)); if (mode == COUNT_RECURSIVE) { - HashPosition pos; - - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - (element = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), element) { Z_ARRVAL_P(array)->nApplyCount++; ZVAL_DEREF(element); cnt += php_count_recursive(element, COUNT_RECURSIVE TSRMLS_CC); Z_ARRVAL_P(array)->nApplyCount--; - } + } ZEND_HASH_FOREACH_END(); } } @@ -1218,7 +1213,8 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ *array, /* array to check in */ *entry, /* pointer to array entry */ res; /* comparison result */ - HashPosition pos; /* hash iterator */ + ulong num_idx; + zend_string *str_idx; zend_bool strict = 0; /* strict comparison or not */ int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; @@ -1230,19 +1226,21 @@ static void php_search_array(INTERNAL_FUNCTION_PARAMETERS, int behavior) /* {{{ is_equal_func = is_identical_function; } - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { is_equal_func(&res, value, entry TSRMLS_CC); if (Z_LVAL(res)) { if (behavior == 0) { RETURN_TRUE; } else { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), return_value, &pos); + if (str_idx) { + RETVAL_STR(STR_COPY(str_idx)); + } else { + RETVAL_LONG(num_idx); + } return; } } - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos); - } + } ZEND_HASH_FOREACH_END(); RETURN_FALSE; } @@ -1324,9 +1322,8 @@ PHP_FUNCTION(extract) zval *entry, data; zend_string *var_name; ulong num_key; - int var_exists, key_type, count = 0; + int var_exists, count = 0; int extract_refs = 0; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|lz/", &var_array, &extract_type, &prefix) == FAILURE) { return; @@ -1364,26 +1361,15 @@ PHP_FUNCTION(extract) SEPARATE_ARG_IF_REF(var_array); } - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(var_array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(var_array), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(var_array), num_key, var_name, entry) { zval final_name; - if (Z_TYPE_P(entry) == IS_INDIRECT) { - entry = Z_INDIRECT_P(entry); - if (Z_TYPE_P(entry) == IS_UNDEF) { - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); - continue; - } - } - ZVAL_NULL(&final_name); - - key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(var_array), &var_name, &num_key, 0, &pos); var_exists = 0; - if (key_type == HASH_KEY_IS_STRING) { + if (var_name) { var_exists = zend_hash_exists_ind(&EG(active_symbol_table)->ht, var_name); - } else if (key_type == HASH_KEY_IS_LONG && (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID)) { + } else if (extract_type == EXTR_PREFIX_ALL || extract_type == EXTR_PREFIX_INVALID) { zval num; ZVAL_LONG(&num, num_key); @@ -1391,7 +1377,6 @@ PHP_FUNCTION(extract) php_prefix_varname(&final_name, prefix, Z_STRVAL(num), Z_STRLEN(num), 1 TSRMLS_CC); zval_dtor(&num); } else { - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); continue; } @@ -1469,9 +1454,7 @@ PHP_FUNCTION(extract) count++; } zval_dtor(&final_name); - - zend_hash_move_forward_ex(Z_ARRVAL_P(var_array), &pos); - } + } ZEND_HASH_FOREACH_END(); if (!extract_refs) { zval_ptr_dtor(var_array); @@ -1492,8 +1475,6 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu zend_hash_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } } else if (Z_TYPE_P(entry) == IS_ARRAY) { - HashPosition pos; - if ((Z_ARRVAL_P(entry)->nApplyCount > 1)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); return; @@ -1501,18 +1482,9 @@ static void php_compact_var(HashTable *eg_active_symbol_table, zval *return_valu Z_ARRVAL_P(entry)->nApplyCount++; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(entry), &pos); - while ((value_ptr = zend_hash_get_current_data_ex(Z_ARRVAL_P(entry), &pos)) != NULL) { - if (Z_TYPE_P(value_ptr) == IS_INDIRECT) { - value_ptr = Z_INDIRECT_P(value_ptr); - if (Z_TYPE_P(value_ptr) == IS_UNDEF) { - zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos); - continue; - } - } + ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL_P(entry), value_ptr) { php_compact_var(eg_active_symbol_table, return_value, value_ptr TSRMLS_CC); - zend_hash_move_forward_ex(Z_ARRVAL_P(entry), &pos); - } + } ZEND_HASH_FOREACH_END(); Z_ARRVAL_P(entry)->nApplyCount--; } } @@ -1592,7 +1564,6 @@ PHP_FUNCTION(array_fill) PHP_FUNCTION(array_fill_keys) { zval *keys, *val, *entry; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "az", &keys, &val) == FAILURE) { return; @@ -1601,8 +1572,7 @@ PHP_FUNCTION(array_fill_keys) /* Initialize return array */ array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(keys))); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(keys), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(keys), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(keys), entry) { ZVAL_DEREF(entry); if (Z_TYPE_P(entry) == IS_LONG) { zval_add_ref(val); @@ -1623,9 +1593,7 @@ PHP_FUNCTION(array_fill_keys) zval_dtor(&key); } } - - zend_hash_move_forward_ex(Z_ARRVAL_P(keys), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2285,87 +2253,80 @@ PHPAPI int php_array_merge(HashTable *dest, HashTable *src, int recursive TSRMLS zval *src_entry, *dest_entry; zend_string *string_key; ulong num_key; - HashPosition pos; - zend_hash_internal_pointer_reset_ex(src, &pos); - while ((src_entry = zend_hash_get_current_data_ex(src, &pos)) != NULL) { - switch (zend_hash_get_current_key_ex(src, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (recursive && (dest_entry = zend_hash_find(dest, string_key)) != NULL) { - zval *src_zval = src_entry; - zval *dest_zval = dest_entry; - HashTable *thash; - zval tmp; + ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) { + if (string_key) { + if (recursive && (dest_entry = zend_hash_find(dest, string_key)) != NULL) { + zval *src_zval = src_entry; + zval *dest_zval = dest_entry; + HashTable *thash; + zval tmp; - ZVAL_DEREF(src_zval); - ZVAL_DEREF(dest_zval); - thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL; - if ((thash && thash->nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); - return 0; - } + ZVAL_DEREF(src_zval); + ZVAL_DEREF(dest_zval); + thash = Z_TYPE_P(dest_zval) == IS_ARRAY ? Z_ARRVAL_P(dest_zval) : NULL; + if ((thash && thash->nApplyCount > 1) || (src_entry == dest_entry && Z_ISREF_P(dest_entry) && (Z_REFCOUNT_P(dest_entry) % 2))) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "recursion detected"); + return 0; + } - if (Z_ISREF_P(dest_entry)) { - if (Z_REFCOUNT_P(dest_entry) == 1) { - ZVAL_UNREF(dest_entry); - } else { - Z_DELREF_P(dest_entry); - ZVAL_DUP(dest_entry, dest_zval); - } - dest_zval = dest_entry; + if (Z_ISREF_P(dest_entry)) { + if (Z_REFCOUNT_P(dest_entry) == 1) { + ZVAL_UNREF(dest_entry); } else { - SEPARATE_ZVAL(dest_zval); + Z_DELREF_P(dest_entry); + ZVAL_DUP(dest_entry, dest_zval); } + dest_zval = dest_entry; + } else { + SEPARATE_ZVAL(dest_zval); + } - if (Z_TYPE_P(dest_zval) == IS_NULL) { - convert_to_array_ex(dest_zval); - add_next_index_null(dest_zval); - } else { - convert_to_array_ex(dest_zval); + if (Z_TYPE_P(dest_zval) == IS_NULL) { + convert_to_array_ex(dest_zval); + add_next_index_null(dest_zval); + } else { + convert_to_array_ex(dest_zval); + } + ZVAL_UNDEF(&tmp); + if (Z_TYPE_P(src_zval) == IS_OBJECT) { + ZVAL_DUP(&tmp, src_zval); + convert_to_array(&tmp); + src_zval = &tmp; + } + if (Z_TYPE_P(src_zval) == IS_ARRAY) { + if (thash) { + thash->nApplyCount++; } - ZVAL_UNDEF(&tmp); - if (Z_TYPE_P(src_zval) == IS_OBJECT) { - ZVAL_DUP(&tmp, src_zval); - convert_to_array(&tmp); - src_zval = &tmp; - } - if (Z_TYPE_P(src_zval) == IS_ARRAY) { - if (thash) { - thash->nApplyCount++; - } - if (!php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) { - if (thash) { - thash->nApplyCount--; - } - return 0; - } + if (!php_array_merge(Z_ARRVAL_P(dest_zval), Z_ARRVAL_P(src_zval), recursive TSRMLS_CC)) { if (thash) { thash->nApplyCount--; } - } else { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } - zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval); + return 0; + } + if (thash) { + thash->nApplyCount--; } - zval_ptr_dtor(&tmp); } else { if (Z_REFCOUNTED_P(src_entry)) { Z_ADDREF_P(src_entry); } - zend_hash_update(dest, string_key, src_entry); + zend_hash_next_index_insert(Z_ARRVAL_P(dest_zval), src_zval); } - break; - - case HASH_KEY_IS_LONG: + zval_ptr_dtor(&tmp); + } else { if (Z_REFCOUNTED_P(src_entry)) { Z_ADDREF_P(src_entry); } - zend_hash_next_index_insert(dest, src_entry); - break; + zend_hash_update(dest, string_key, src_entry); + } + } else { + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); + } + zend_hash_next_index_insert(dest, src_entry); } - zend_hash_move_forward_ex(src, &pos); - } + } ZEND_HASH_FOREACH_END(); return 1; } /* }}} */ @@ -2375,44 +2336,36 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC zval *src_entry, *dest_entry, *src_zval, *dest_zval; zend_string *string_key; ulong num_key; - HashPosition pos; - - for (zend_hash_internal_pointer_reset_ex(src, &pos); - (src_entry = zend_hash_get_current_data_ex(src, &pos)) != NULL; - zend_hash_move_forward_ex(src, &pos)) { + ZEND_HASH_FOREACH_KEY_VAL(src, num_key, string_key, src_entry) { src_zval = src_entry; ZVAL_DEREF(src_zval); - switch (zend_hash_get_current_key_ex(src, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (Z_TYPE_P(src_zval) != IS_ARRAY || - (dest_entry = zend_hash_find(dest, string_key)) == NULL || - (Z_TYPE_P(dest_entry) != IS_ARRAY && - (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { + if (string_key) { + if (Z_TYPE_P(src_zval) != IS_ARRAY || + (dest_entry = zend_hash_find(dest, string_key)) == NULL || + (Z_TYPE_P(dest_entry) != IS_ARRAY && + (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } - zend_hash_update(dest, string_key, src_entry); - - continue; + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); } - break; + zend_hash_update(dest, string_key, src_entry); - case HASH_KEY_IS_LONG: - if (Z_TYPE_P(src_zval) != IS_ARRAY || - (dest_entry = zend_hash_index_find(dest, num_key)) == NULL || - (Z_TYPE_P(dest_entry) != IS_ARRAY && - (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { + continue; + } + } else { + if (Z_TYPE_P(src_zval) != IS_ARRAY || + (dest_entry = zend_hash_index_find(dest, num_key)) == NULL || + (Z_TYPE_P(dest_entry) != IS_ARRAY && + (!Z_ISREF_P(dest_entry) || Z_TYPE_P(Z_REFVAL_P(dest_entry)) != IS_ARRAY))) { - if (Z_REFCOUNTED_P(src_entry)) { - Z_ADDREF_P(src_entry); - } - zend_hash_index_update(dest, num_key, src_entry); - - continue; + if (Z_REFCOUNTED_P(src_entry)) { + Z_ADDREF_P(src_entry); } - break; + zend_hash_index_update(dest, num_key, src_entry); + + continue; + } } dest_zval = dest_entry; @@ -2435,7 +2388,7 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src TSRMLS_DC } Z_ARRVAL_P(dest_zval)->nApplyCount--; Z_ARRVAL_P(src_zval)->nApplyCount--; - } + } ZEND_HASH_FOREACH_END(); return 1; } @@ -2526,7 +2479,8 @@ PHP_FUNCTION(array_keys) new_val; /* New value */ int add_key; /* Flag to indicate whether a key should be added */ zend_bool strict = 0; /* do strict comparison */ - HashPosition pos; + ulong num_idx; + zend_string *str_idx; int (*is_equal_func)(zval *, zval *, zval * TSRMLS_DC) = is_equal_function; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|zb", &input, &search_value, &strict) == FAILURE) { @@ -2546,20 +2500,21 @@ PHP_FUNCTION(array_keys) add_key = 1; /* Go through input array and add keys to the return array */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_idx, str_idx, entry) { if (search_value != NULL) { is_equal_func(&res, search_value, entry TSRMLS_CC); add_key = zval_is_true(&res); } if (add_key) { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(input), &new_val, &pos); + if (str_idx) { + ZVAL_STR(&new_val, STR_COPY(str_idx)); + } else { + ZVAL_LONG(&new_val, num_idx); + } zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &new_val); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2569,7 +2524,6 @@ PHP_FUNCTION(array_values) { zval *input, /* Input array */ *entry; /* An entry in the input array */ - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { return; @@ -2579,12 +2533,10 @@ PHP_FUNCTION(array_values) array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input))); /* Go through input array and add values to the return array */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) { zval_add_ref(entry); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2596,7 +2548,6 @@ PHP_FUNCTION(array_count_values) *entry, /* An entry in the input array */ *tmp; HashTable *myht; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { return; @@ -2607,8 +2558,7 @@ PHP_FUNCTION(array_count_values) /* Go through input array and add values to the return array */ myht = Z_ARRVAL_P(input); - zend_hash_internal_pointer_reset_ex(myht, &pos); - while ((entry = zend_hash_get_current_data_ex(myht, &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(myht, entry) { if (Z_TYPE_P(entry) == IS_LONG) { if ((tmp = zend_hash_index_find(Z_ARRVAL_P(return_value), Z_LVAL_P(entry))) == NULL) { zval data; @@ -2628,9 +2578,7 @@ PHP_FUNCTION(array_count_values) } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only count STRING and INTEGER values!"); } - - zend_hash_move_forward_ex(myht, &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2666,7 +2614,6 @@ PHP_FUNCTION(array_column) { zval *zcolumn = NULL, *zkey = NULL, *data; HashTable *arr_hash; - HashPosition pointer; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "hz!|z!", &arr_hash, &zcolumn, &zkey) == FAILURE) { return; @@ -2678,9 +2625,7 @@ PHP_FUNCTION(array_column) } array_init(return_value); - for (zend_hash_internal_pointer_reset_ex(arr_hash, &pointer); - (data = zend_hash_get_current_data_ex(arr_hash, &pointer)) != NULL; - zend_hash_move_forward_ex(arr_hash, &pointer)) { + ZEND_HASH_FOREACH_VAL(arr_hash, data) { zval *zcolval, *zkeyval = NULL; HashTable *ht; @@ -2726,7 +2671,7 @@ PHP_FUNCTION(array_column) } else { add_next_index_zval(return_value, zcolval); } - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2739,7 +2684,6 @@ PHP_FUNCTION(array_reverse) zend_string *string_key; ulong num_key; zend_bool preserve_keys = 0; /* whether to preserve keys */ - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|b", &input, &preserve_keys) == FAILURE) { return; @@ -2748,26 +2692,19 @@ PHP_FUNCTION(array_reverse) /* Initialize return array */ array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(input))); - zend_hash_internal_pointer_end_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + ZEND_HASH_REVERSE_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, string_key, entry) { zval_add_ref(entry); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); - break; - - case HASH_KEY_IS_LONG: - if (preserve_keys) { - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); - } else { - zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); - } - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, entry); + } else { + if (preserve_keys) { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + } else { + zend_hash_next_index_insert(Z_ARRVAL_P(return_value), entry); + } } - - zend_hash_move_backwards_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2844,7 +2781,8 @@ PHP_FUNCTION(array_pad) PHP_FUNCTION(array_flip) { zval *array, *entry, data; - HashPosition pos; + ulong num_idx; + zend_string *str_idx; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &array) == FAILURE) { return; @@ -2852,21 +2790,25 @@ PHP_FUNCTION(array_flip) array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array))); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) { - zend_hash_get_current_key_zval_ex(Z_ARRVAL_P(array), &data, &pos); - + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_idx, str_idx, entry) { if (Z_TYPE_P(entry) == IS_LONG) { + if (str_idx) { + ZVAL_STR(&data, STR_COPY(str_idx)); + } else { + ZVAL_LONG(&data, num_idx); + } zend_hash_index_update(Z_ARRVAL_P(return_value), Z_LVAL_P(entry), &data); } else if (Z_TYPE_P(entry) == IS_STRING) { + if (str_idx) { + ZVAL_STR(&data, STR_COPY(str_idx)); + } else { + ZVAL_LONG(&data, num_idx); + } zend_symtable_update(Z_ARRVAL_P(return_value), Z_STR_P(entry), &data); } else { - zval_ptr_dtor(&data); /* will free also zval structure */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can only flip STRING and INTEGER values!"); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -2879,7 +2821,6 @@ PHP_FUNCTION(array_change_key_case) zend_string *new_key; ulong num_key; long change_to_upper=0; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &array, &change_to_upper) == FAILURE) { return; @@ -2887,28 +2828,22 @@ PHP_FUNCTION(array_change_key_case) array_init_size(return_value, zend_hash_num_elements(Z_ARRVAL_P(array))); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, entry) { zval_add_ref(entry); - switch (zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); - break; - case HASH_KEY_IS_STRING: - new_key = STR_INIT(string_key->val, string_key->len, 0); - if (change_to_upper) { - php_strtoupper(new_key->val, new_key->len); - } else { - php_strtolower(new_key->val, new_key->len); - } - zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry); - STR_RELEASE(new_key); - break; + if (!string_key) { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, entry); + } else { + new_key = STR_INIT(string_key->val, string_key->len, 0); + if (change_to_upper) { + php_strtoupper(new_key->val, new_key->len); + } else { + php_strtolower(new_key->val, new_key->len); + } + zend_hash_update(Z_ARRVAL_P(return_value), new_key, entry); + STR_RELEASE(new_key); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4116,10 +4051,9 @@ PHP_FUNCTION(array_rand) { zval *input; long randval, num_req = 1; - int num_avail, key_type; + int num_avail; zend_string *string_key; ulong num_key; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|l", &input, &num_req) == FAILURE) { return; @@ -4140,22 +4074,24 @@ PHP_FUNCTION(array_rand) } /* We can't use zend_hash_index_find() because the array may have string keys or gaps. */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while (num_req && (key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &string_key, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT) { + ZEND_HASH_FOREACH_KEY(Z_ARRVAL_P(input), num_key, string_key) { + if (!num_req) { + break; + } randval = php_rand(TSRMLS_C); if ((double) (randval / (PHP_RAND_MAX + 1.0)) < (double) num_req / (double) num_avail) { /* If we are returning a single result, just do it. */ if (Z_TYPE_P(return_value) != IS_ARRAY) { - if (key_type == HASH_KEY_IS_STRING) { + if (string_key) { RETURN_STR(STR_COPY(string_key)); } else { RETURN_LONG(num_key); } } else { /* Append the result to the return value. */ - if (key_type == HASH_KEY_IS_STRING) { + if (string_key) { add_next_index_str(return_value, STR_COPY(string_key)); } else { add_next_index_long(return_value, num_key); @@ -4164,8 +4100,7 @@ PHP_FUNCTION(array_rand) num_req--; } num_avail--; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4176,7 +4111,6 @@ PHP_FUNCTION(array_sum) zval *input, *entry, entry_n; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { return; @@ -4184,17 +4118,14 @@ PHP_FUNCTION(array_sum) ZVAL_LONG(return_value, 0); - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) { if (Z_TYPE_P(entry) == IS_ARRAY || Z_TYPE_P(entry) == IS_OBJECT) { continue; } ZVAL_DUP(&entry_n, entry); convert_scalar_to_number(&entry_n TSRMLS_CC); fast_add_function(return_value, return_value, &entry_n TSRMLS_CC); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4205,7 +4136,6 @@ PHP_FUNCTION(array_product) zval *input, *entry, entry_n; - HashPosition pos; double dval; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &input) == FAILURE) { @@ -4217,10 +4147,7 @@ PHP_FUNCTION(array_product) return; } - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - (entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(input), entry) { if (Z_TYPE_P(entry) == IS_ARRAY || Z_TYPE_P(entry) == IS_OBJECT) { continue; } @@ -4237,7 +4164,7 @@ PHP_FUNCTION(array_product) convert_to_double(return_value); convert_to_double(&entry_n); Z_DVAL_P(return_value) *= Z_DVAL(entry_n); - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4253,7 +4180,6 @@ PHP_FUNCTION(array_reduce) zend_fcall_info fci; zend_fcall_info_cache fci_cache = empty_fcall_info_cache; zval *initial = NULL; - HashPosition pos; HashTable *htbl; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "af|z", &input, &fci, &fci_cache, &initial) == FAILURE) { @@ -4280,8 +4206,7 @@ PHP_FUNCTION(array_reduce) fci.param_count = 2; fci.no_separation = 0; - zend_hash_internal_pointer_reset_ex(htbl, &pos); - while ((operand = zend_hash_get_current_data_ex(htbl, &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(htbl, operand) { ZVAL_COPY_VALUE(&args[0], &result); ZVAL_COPY_VALUE(&args[1], operand); fci.params = args; @@ -4293,8 +4218,8 @@ PHP_FUNCTION(array_reduce) php_error_docref(NULL TSRMLS_CC, E_WARNING, "An error occurred while invoking the reduction callback"); return; } - zend_hash_move_forward_ex(htbl, &pos); - } + } ZEND_HASH_FOREACH_END(); + RETVAL_ZVAL(&result, 1, 1); } /* }}} */ @@ -4313,7 +4238,6 @@ PHP_FUNCTION(array_filter) zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fci_cache = empty_fcall_info_cache; ulong num_key; - HashPosition pos; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a|fl", &array, &fci, &fci_cache, &use_type) == FAILURE) { return; @@ -4331,32 +4255,23 @@ PHP_FUNCTION(array_filter) fci.param_count = 1; } - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); - (operand = zend_hash_get_current_data_ex(Z_ARRVAL_P(array), &pos)) != NULL; - zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos) - ) { - int key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(array), &string_key, &num_key, 0, &pos); - + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(array), num_key, string_key, operand) { if (have_callback) { if (use_type) { /* Set up the key */ - switch (key_type) { - case HASH_KEY_IS_LONG: - if (use_type == ARRAY_FILTER_USE_BOTH) { - fci.param_count = 2; - ZVAL_LONG(&args[1], num_key); - } else if (use_type == ARRAY_FILTER_USE_KEY) { - ZVAL_LONG(&args[0], num_key); - } - break; - - case HASH_KEY_IS_STRING: - if (use_type == ARRAY_FILTER_USE_BOTH) { - ZVAL_STR(&args[1], STR_COPY(string_key)); - } else if (use_type == ARRAY_FILTER_USE_KEY) { - ZVAL_STR(&args[0], STR_COPY(string_key)); - } - break; + if (!string_key) { + if (use_type == ARRAY_FILTER_USE_BOTH) { + fci.param_count = 2; + ZVAL_LONG(&args[1], num_key); + } else if (use_type == ARRAY_FILTER_USE_KEY) { + ZVAL_LONG(&args[0], num_key); + } + } else { + if (use_type == ARRAY_FILTER_USE_BOTH) { + ZVAL_STR(&args[1], STR_COPY(string_key)); + } else if (use_type == ARRAY_FILTER_USE_KEY) { + ZVAL_STR(&args[0], STR_COPY(string_key)); + } } } if (use_type != ARRAY_FILTER_USE_KEY) { @@ -4392,16 +4307,12 @@ PHP_FUNCTION(array_filter) } zval_add_ref(operand); - switch (key_type) { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand); - break; - - case HASH_KEY_IS_LONG: - zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand); - break; + if (string_key) { + zend_hash_update(Z_ARRVAL_P(return_value), string_key, operand); + } else { + zend_hash_index_update(Z_ARRVAL_P(return_value), num_key, operand); } - } + } ZEND_HASH_FOREACH_END(); } /* }}} */ @@ -4584,7 +4495,6 @@ PHP_FUNCTION(array_chunk) zval *input = NULL; zval chunk; zval *entry; - HashPosition pos; if (zend_parse_parameters(argc TSRMLS_CC, "al|b", &input, &size, &preserve_keys) == FAILURE) { return; @@ -4604,8 +4514,8 @@ PHP_FUNCTION(array_chunk) array_init_size(return_value, ((num_in - 1) / size) + 1); ZVAL_UNDEF(&chunk); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(input), &pos); - while ((entry = zend_hash_get_current_data_ex(Z_ARRVAL_P(input), &pos)) != NULL) { + + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(input), num_key, str_key, entry) { /* If new chunk, create and initialize it. */ if (Z_TYPE(chunk) == IS_UNDEF) { array_init_size(&chunk, size); @@ -4615,14 +4525,10 @@ PHP_FUNCTION(array_chunk) zval_add_ref(entry); if (preserve_keys) { - key_type = zend_hash_get_current_key_ex(Z_ARRVAL_P(input), &str_key, &num_key, 0, &pos); - switch (key_type) { - case HASH_KEY_IS_STRING: - zend_hash_update(Z_ARRVAL(chunk), str_key, entry); - break; - default: - add_index_zval(&chunk, num_key, entry); - break; + if (str_key) { + zend_hash_update(Z_ARRVAL(chunk), str_key, entry); + } else { + add_index_zval(&chunk, num_key, entry); } } else { add_next_index_zval(&chunk, entry); @@ -4634,9 +4540,7 @@ PHP_FUNCTION(array_chunk) add_next_index_zval(return_value, &chunk); ZVAL_UNDEF(&chunk); } - - zend_hash_move_forward_ex(Z_ARRVAL_P(input), &pos); - } + } ZEND_HASH_FOREACH_END(); /* Add the final chunk if there is one. */ if (Z_TYPE(chunk) != IS_UNDEF) { diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 9d6878817e8..bf9a5a94db5 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -4281,11 +4281,8 @@ PHP_FUNCTION(getopt) * and a trailing NULL */ argv = (char **) safe_emalloc(sizeof(char *), (argc + 1), 0); - /* Reset the array indexes. */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(args)); - /* Iterate over the hash to construct the argv array. */ - while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(args))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), entry) { zval arg, *arg_ptr = entry; if (Z_TYPE_P(entry) != IS_STRING) { @@ -4299,9 +4296,7 @@ PHP_FUNCTION(getopt) if (arg_ptr != entry) { zval_dtor(&arg); } - - zend_hash_move_forward(Z_ARRVAL_P(args)); - } + } ZEND_HASH_FOREACH_END(); /* The C Standard requires argv[argc] to be NULL - this might * keep some getopt implementations happy. */ @@ -4327,11 +4322,8 @@ PHP_FUNCTION(getopt) memset(opts, 0, count * sizeof(opt_struct)); - /* Reset the array indexes. */ - zend_hash_internal_pointer_reset(Z_ARRVAL_P(p_longopts)); - /* Iterate over the hash to construct the argv array. */ - while ((entry = zend_hash_get_current_data(Z_ARRVAL_P(p_longopts))) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(p_longopts), entry) { zval arg, *arg_ptr = entry; if (Z_TYPE_P(entry) != IS_STRING) { @@ -4357,9 +4349,7 @@ PHP_FUNCTION(getopt) if (arg_ptr != entry) { zval_dtor(&arg); } - - zend_hash_move_forward(Z_ARRVAL_P(p_longopts)); - } + } ZEND_HASH_FOREACH_END(); } else { opts = (opt_struct*) erealloc(opts, sizeof(opt_struct) * (len + 1)); orig_opts = opts; @@ -4877,13 +4867,10 @@ PHP_FUNCTION(call_user_method_array) num_elems = zend_hash_num_elements(params_ar); method_args = (zval *) safe_emalloc(sizeof(zval), num_elems, 0); - for (zend_hash_internal_pointer_reset(params_ar); - (zv = zend_hash_get_current_data(params_ar)) != NULL; - zend_hash_move_forward(params_ar) - ) { + ZEND_HASH_FOREACH_VAL(params_ar, zv) { ZVAL_COPY_VALUE(&method_args[element], zv); element++; - } + } ZEND_HASH_FOREACH_END(); if (call_user_function_ex(EG(function_table), object, callback, &retval, num_elems, method_args, 0, NULL TSRMLS_CC) == SUCCESS) { if (Z_TYPE(retval) != IS_UNDEF) { diff --git a/ext/standard/file.c b/ext/standard/file.c index 7dbd8fdf1a5..75197463a1f 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -647,10 +647,8 @@ PHP_FUNCTION(file_put_contents) if (zend_hash_num_elements(Z_ARRVAL_P(data))) { int bytes_written; zval *tmp; - HashPosition pos; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(data), &pos); - while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(data), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(data), tmp) { if (Z_TYPE_P(tmp) != IS_STRING) { SEPARATE_ZVAL(tmp); convert_to_string(tmp); @@ -668,8 +666,7 @@ PHP_FUNCTION(file_put_contents) break; } } - zend_hash_move_forward_ex(Z_ARRVAL_P(data), &pos); - } + } ZEND_HASH_FOREACH_END(); } break; @@ -1882,11 +1879,9 @@ PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char en int count, i = 0, ret; zval *field_tmp = NULL, field; smart_str csvline = {0}; - HashPosition pos; count = zend_hash_num_elements(Z_ARRVAL_P(fields)); - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(fields), &pos); - while ((field_tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(fields), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(fields), field_tmp) { ZVAL_COPY_VALUE(&field, field_tmp); if (Z_TYPE(field) != IS_STRING) { @@ -1927,12 +1922,10 @@ PHPAPI int php_fputcsv(php_stream *stream, zval *fields, char delimiter, char en if (++i != count) { smart_str_appendl(&csvline, &delimiter, 1); } - zend_hash_move_forward_ex(Z_ARRVAL_P(fields), &pos); - if (Z_TYPE_P(field_tmp) != IS_STRING) { zval_dtor(&field); } - } + } ZEND_HASH_FOREACH_END(); smart_str_appendc(&csvline, '\n'); smart_str_0(&csvline); diff --git a/ext/standard/filters.c b/ext/standard/filters.c index 55737c97af9..6897cde0946 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -258,17 +258,14 @@ static php_stream_filter *strfilter_strip_tags_create(const char *filtername, zv if (filterparams != NULL) { if (Z_TYPE_P(filterparams) == IS_ARRAY) { - HashPosition pos; zval *tmp; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(filterparams), &pos); - while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(filterparams), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(filterparams), tmp) { convert_to_string_ex(tmp); smart_str_appendc(&tags_ss, '<'); smart_str_appendl(&tags_ss, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)); smart_str_appendc(&tags_ss, '>'); - zend_hash_move_forward_ex(Z_ARRVAL_P(filterparams), &pos); - } + } ZEND_HASH_FOREACH_END(); smart_str_0(&tags_ss); } else { /* FIXME: convert_to_* may clutter zvals and lead it into segfault ? */ diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 2e6e2f672b1..622fbfbb3fc 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -404,12 +404,10 @@ php_formatted_print(int param_count, int use_array, int format_offset TSRMLS_DC) newargs = (zval *)safe_emalloc(argc, sizeof(zval), 0); ZVAL_COPY_VALUE(&newargs[0], z_format); - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(array)); - (zv = zend_hash_get_current_data(Z_ARRVAL_P(array))) != NULL; - zend_hash_move_forward(Z_ARRVAL_P(array))) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(array), zv) { ZVAL_COPY_VALUE(&newargs[i], zv); i++; - } + } ZEND_HASH_FOREACH_END(); args = newargs; format_offset = 0; } diff --git a/ext/standard/http.c b/ext/standard/http.c index 46af753ecc2..b839a4cb973 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -33,7 +33,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, { zend_string *key = NULL; char *newprefix, *p, *prop_name; - int arg_sep_len, key_type, newprefix_len, prop_len; + int arg_sep_len, newprefix_len, prop_len; ulong idx; zval *zdata = NULL, copyzval; @@ -54,10 +54,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } arg_sep_len = strlen(arg_sep); - for (zend_hash_internal_pointer_reset(ht); - (key_type = zend_hash_get_current_key(ht, &key, &idx, 0)) != HASH_KEY_NON_EXISTENT; - zend_hash_move_forward(ht) - ) { + ZEND_HASH_FOREACH_KEY_VAL_IND(ht, idx, key, zdata) { /* handling for private & protected object properties */ if (key) { if (key->val[0] == '\0' && type != NULL) { @@ -78,18 +75,8 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, prop_len = 0; } - if ((zdata = zend_hash_get_current_data(ht)) == NULL) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Error traversing form data array"); - return FAILURE; - } - if (Z_TYPE_P(zdata) == IS_INDIRECT) { - zdata = Z_INDIRECT_P(zdata); - if (Z_TYPE_P(zdata) == IS_UNDEF) { - continue; - } - } if (Z_TYPE_P(zdata) == IS_ARRAY || Z_TYPE_P(zdata) == IS_OBJECT) { - if (key_type == HASH_KEY_IS_STRING) { + if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); @@ -160,7 +147,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } /* Simple key=value */ smart_str_appendl(formstr, key_prefix, key_prefix_len); - if (key_type == HASH_KEY_IS_STRING) { + if (key) { zend_string *ekey; if (enc_type == PHP_QUERY_RFC3986) { ekey = php_raw_url_encode(prop_name, prop_len); @@ -230,7 +217,7 @@ PHPAPI int php_url_encode_hash_ex(HashTable *ht, smart_str *formstr, } } } - } + } ZEND_HASH_FOREACH_END(); return SUCCESS; } diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index 9e7a906ce24..7ac15a69ca5 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -237,12 +237,9 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *s, *p; if (Z_TYPE_P(tmpzval) == IS_ARRAY) { - HashPosition pos; zval *tmpheader = NULL; - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(tmpzval), &pos); - NULL != (tmpheader = zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpzval), &pos)); - zend_hash_move_forward_ex(Z_ARRVAL_P(tmpzval), &pos)) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(tmpzval), tmpheader) { if (Z_TYPE_P(tmpheader) == IS_STRING) { s = Z_STRVAL_P(tmpheader); do { @@ -266,7 +263,7 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, while (*s == '\r' || *s == '\n') s++; } while (*s != 0); } - } + } ZEND_HASH_FOREACH_END(); } else if (Z_TYPE_P(tmpzval) == IS_STRING && Z_STRLEN_P(tmpzval)) { s = Z_STRVAL_P(tmpzval); do { @@ -423,19 +420,15 @@ finish: tmp = NULL; if (Z_TYPE_P(tmpzval) == IS_ARRAY) { - HashPosition pos; zval *tmpheader = NULL; smart_str tmpstr = {0}; - for (zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(tmpzval), &pos); - NULL != (tmpheader = zend_hash_get_current_data_ex(Z_ARRVAL_P(tmpzval), &pos)); - zend_hash_move_forward_ex(Z_ARRVAL_P(tmpzval), &pos) - ) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(tmpzval), tmpheader) { if (Z_TYPE_P(tmpheader) == IS_STRING) { smart_str_appendl(&tmpstr, Z_STRVAL_P(tmpheader), Z_STRLEN_P(tmpheader)); smart_str_appendl(&tmpstr, "\r\n", sizeof("\r\n") - 1); } - } + } ZEND_HASH_FOREACH_END(); smart_str_0(&tmpstr); /* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */ if (tmpstr.s) { diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index c18077a2d51..d5eb85d371f 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -85,7 +85,6 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent uint cnt, l, sizeenv=0, el_len; ulong num_key; HashTable *target_hash; - HashPosition pos; memset(&env, 0, sizeof(env)); @@ -109,10 +108,7 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent } /* first, we have to get the size of all the elements in the hash */ - for (zend_hash_internal_pointer_reset_ex(target_hash, &pos); - (element = zend_hash_get_current_data_ex(target_hash, &pos)) != NULL; - zend_hash_move_forward_ex(target_hash, &pos)) { - + ZEND_HASH_FOREACH_KEY_VAL(target_hash, num_key, string_key, element) { convert_to_string_ex(element); el_len = Z_STRLEN_P(element); if (el_len == 0) { @@ -121,25 +117,20 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent sizeenv += el_len+1; - switch (zend_hash_get_current_key_ex(target_hash, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (string_key->len == 0) { - continue; - } - sizeenv += string_key->len + 2; - break; + if (string_key) { + if (string_key->len == 0) { + continue; + } + sizeenv += string_key->len + 2; } - } + } ZEND_HASH_FOREACH_END(); #ifndef PHP_WIN32 ep = env.envarray = (char **) pecalloc(cnt + 1, sizeof(char *), is_persistent); #endif p = env.envp = (char *) pecalloc(sizeenv + 4, 1, is_persistent); - for (zend_hash_internal_pointer_reset_ex(target_hash, &pos); - (element = zend_hash_get_current_data_ex(target_hash, &pos)) != NULL; - zend_hash_move_forward_ex(target_hash, &pos)) { - + ZEND_HASH_FOREACH_KEY_VAL(target_hash, num_key, string_key, element) { convert_to_string_ex(element); el_len = Z_STRLEN_P(element); @@ -148,40 +139,34 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent } data = Z_STRVAL_P(element); - switch (zend_hash_get_current_key_ex(target_hash, &string_key, &num_key, 0, &pos)) { - case HASH_KEY_IS_STRING: - if (string_key->len == 0) { - continue; - } - l = string_key->len + el_len + 2; - memcpy(p, string_key->val, string_key->len); - strncat(p, "=", 1); - strncat(p, data, el_len); + if (string_key) { + if (string_key->len == 0) { + continue; + } + + l = string_key->len + el_len + 2; + memcpy(p, string_key->val, string_key->len); + strncat(p, "=", 1); + strncat(p, data, el_len); #ifndef PHP_WIN32 - *ep = p; - ++ep; + *ep = p; + ++ep; #endif - p += l; - break; - case HASH_KEY_IS_LONG: - memcpy(p,data,el_len); + p += l; + } else { + memcpy(p,data,el_len); #ifndef PHP_WIN32 - *ep = p; - ++ep; + *ep = p; + ++ep; #endif - p += el_len + 1; - break; - case HASH_KEY_NON_EXISTENT: - break; + p += el_len + 1; } - } + } ZEND_HASH_FOREACH_END(); assert((uint)(p - env.envp) <= sizeenv); - zend_hash_internal_pointer_reset_ex(target_hash, &pos); - return env; } /* }}} */ @@ -442,7 +427,8 @@ PHP_FUNCTION(proc_open) int ndesc = 0; int i; zval *descitem = NULL; - HashPosition pos; + zend_string *str_index; + ulong nindex; struct php_proc_open_descriptor_item descriptors[PHP_PROC_OPEN_MAX_DESCRIPTORS]; #ifdef PHP_WIN32 PROCESS_INFORMATION pi; @@ -519,15 +505,9 @@ PHP_FUNCTION(proc_open) #endif /* walk the descriptor spec and set up files/pipes */ - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(descriptorspec), &pos); - while ((descitem = zend_hash_get_current_data_ex(Z_ARRVAL_P(descriptorspec), &pos)) != NULL) { - zend_string *str_index; - ulong nindex; + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(descriptorspec), nindex, str_index, descitem) { zval *ztype; - str_index = NULL; - zend_hash_get_current_key_ex(Z_ARRVAL_P(descriptorspec), &str_index, &nindex, 0, &pos); - if (str_index) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "descriptor spec must be an integer indexed array"); goto exit_fail; @@ -685,10 +665,9 @@ PHP_FUNCTION(proc_open) } } - zend_hash_move_forward_ex(Z_ARRVAL_P(descriptorspec), &pos); if (++ndesc == PHP_PROC_OPEN_MAX_DESCRIPTORS) break; - } + } ZEND_HASH_FOREACH_END(); #ifdef PHP_WIN32 if (cwd == NULL) { diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index e668b973b48..c39a9f3310d 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -555,14 +555,10 @@ PHP_FUNCTION(stream_get_transports) } if ((stream_xport_hash = php_stream_xport_get_hash())) { - HashPosition pos; array_init(return_value); - zend_hash_internal_pointer_reset_ex(stream_xport_hash, &pos); - while (zend_hash_get_current_key_ex(stream_xport_hash, - &stream_xport, &num_key, 0, &pos) == HASH_KEY_IS_STRING) { + ZEND_HASH_FOREACH_KEY(stream_xport_hash, num_key, stream_xport) { add_next_index_str(return_value, STR_COPY(stream_xport)); - zend_hash_move_forward_ex(stream_xport_hash, &pos); - } + } ZEND_HASH_FOREACH_END(); } else { RETURN_FALSE; } @@ -583,15 +579,12 @@ PHP_FUNCTION(stream_get_wrappers) } if ((url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash())) { - HashPosition pos; array_init(return_value); - for (zend_hash_internal_pointer_reset_ex(url_stream_wrappers_hash, &pos); - (key_flags = zend_hash_get_current_key_ex(url_stream_wrappers_hash, &stream_protocol, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTENT; - zend_hash_move_forward_ex(url_stream_wrappers_hash, &pos)) { - if (key_flags == HASH_KEY_IS_STRING) { - add_next_index_str(return_value, STR_COPY(stream_protocol)); - } - } + ZEND_HASH_FOREACH_KEY(url_stream_wrappers_hash, num_key, stream_protocol) { + if (key_flags == HASH_KEY_IS_STRING) { + add_next_index_str(return_value, STR_COPY(stream_protocol)); + } + } ZEND_HASH_FOREACH_END(); } else { RETURN_FALSE; } @@ -610,10 +603,7 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t return 0; } - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); - (elem = zend_hash_get_current_data(Z_ARRVAL_P(stream_array))) != NULL; - zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { - + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) { /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast() would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave the higher bits of a SOCKET variable uninitialized on systems with little endian. */ @@ -639,7 +629,8 @@ static int stream_array_to_fd_set(zval *stream_array, fd_set *fds, php_socket_t } cnt++; } - } + } ZEND_HASH_FOREACH_END(); + return cnt ? 1 : 0; } @@ -648,6 +639,8 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) zval *elem, *dest_elem, new_array; php_stream *stream; int ret = 0; + zend_string *key; + ulong num_ind; if (Z_TYPE_P(stream_array) != IS_ARRAY) { return 0; @@ -655,26 +648,12 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) ZVAL_NEW_ARR(&new_array); zend_hash_init(Z_ARRVAL(new_array), zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0); - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); - zend_hash_has_more_elements(Z_ARRVAL_P(stream_array)) == SUCCESS; - zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { - - int type; - zend_string *key; - ulong num_ind; + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(stream_array), num_ind, key, elem) { /* Temporary int fd is needed for the STREAM data type on windows, passing this_fd directly to php_stream_cast() would eventually bring a wrong result on x64. php_stream_cast() casts to int internally, and this will leave the higher bits of a SOCKET variable uninitialized on systems with little endian. */ int tmp_fd; - - type = zend_hash_get_current_key(Z_ARRVAL_P(stream_array), - &key, &num_ind, 0); - if (type == HASH_KEY_NON_EXISTENT || - (elem = zend_hash_get_current_data(Z_ARRVAL_P(stream_array))) == NULL) { - continue; /* should not happen */ - } - php_stream_from_zval_no_verify(stream, elem); if (stream == NULL) { continue; @@ -689,9 +668,9 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) php_socket_t this_fd = (php_socket_t)tmp_fd; if (PHP_SAFE_FD_ISSET(this_fd, fds)) { - if (type == HASH_KEY_IS_LONG) { + if (!key) { dest_elem = zend_hash_index_update(Z_ARRVAL(new_array), num_ind, elem); - } else { /* HASH_KEY_IS_STRING */ + } else { dest_elem = zend_hash_update(Z_ARRVAL(new_array), key, elem); } @@ -702,14 +681,13 @@ static int stream_array_from_fd_set(zval *stream_array, fd_set *fds TSRMLS_DC) continue; } } - } + } ZEND_HASH_FOREACH_END(); /* destroy old array and add new one */ zend_hash_destroy(Z_ARRVAL_P(stream_array)); GC_REMOVE_FROM_BUFFER(Z_ARR_P(stream_array)); efree(Z_ARR_P(stream_array)); - zend_hash_internal_pointer_reset(Z_ARRVAL(new_array)); Z_ARR_P(stream_array) = Z_ARR(new_array); return ret; @@ -727,10 +705,7 @@ static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC) ZVAL_NEW_ARR(&new_array); zend_hash_init(Z_ARRVAL(new_array), zend_hash_num_elements(Z_ARRVAL_P(stream_array)), NULL, ZVAL_PTR_DTOR, 0); - for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(stream_array)); - (elem = zend_hash_get_current_data(Z_ARRVAL_P(stream_array))) != NULL; - zend_hash_move_forward(Z_ARRVAL_P(stream_array))) { - + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(stream_array), elem) { php_stream_from_zval_no_verify(stream, elem); if (stream == NULL) { continue; @@ -749,14 +724,12 @@ static int stream_array_emulate_read_fd_set(zval *stream_array TSRMLS_DC) ret++; continue; } - } + } ZEND_HASH_FOREACH_END(); if (ret > 0) { /* destroy old array and add new one */ zend_hash_destroy(Z_ARRVAL_P(stream_array)); efree(Z_ARR_P(stream_array)); - - zend_hash_internal_pointer_reset(Z_ARRVAL(new_array)); Z_ARR_P(stream_array) = Z_ARR(new_array); } else { zend_hash_destroy(Z_ARRVAL(new_array)); @@ -911,31 +884,24 @@ static void user_space_stream_notifier_dtor(php_stream_notifier *notifier) static int parse_context_options(php_stream_context *context, zval *options TSRMLS_DC) { - HashPosition pos, opos; zval *wval, *oval; zend_string *wkey, *okey; int ret = SUCCESS; ulong num_key; - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(options), &pos); - while (NULL != (wval = zend_hash_get_current_data_ex(Z_ARRVAL_P(options), &pos))) { - if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(options), &wkey, &num_key, 0, &pos) - && Z_TYPE_P(wval) == IS_ARRAY) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(options), num_key, wkey, wval) { + if (wkey && Z_TYPE_P(wval) == IS_ARRAY) { - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(wval), &opos); - while (NULL != (oval = zend_hash_get_current_data_ex(Z_ARRVAL_P(wval), &opos))) { - - if (HASH_KEY_IS_STRING == zend_hash_get_current_key_ex(Z_ARRVAL_P(wval), &okey, &num_key, 0, &opos)) { + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(wval), num_key, okey, oval) { + if (okey) { php_stream_context_set_option(context, wkey->val, okey->val, oval); } - zend_hash_move_forward_ex(Z_ARRVAL_P(wval), &opos); - } + } ZEND_HASH_FOREACH_END(); } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "options should have the form [\"wrappername\"][\"optionname\"] = $value"); } - zend_hash_move_forward_ex(Z_ARRVAL_P(options), &pos); - } + } ZEND_HASH_FOREACH_END(); return ret; } diff --git a/ext/standard/string.c b/ext/standard/string.c index 764f82150ce..8f07c332a32 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -1121,7 +1121,6 @@ PHP_FUNCTION(explode) PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC) { zval *tmp; - HashPosition pos; smart_str implstr = {0}; int numelems, i = 0; zval tmp_val; @@ -1133,9 +1132,7 @@ PHPAPI void php_implode(zval *delim, zval *arr, zval *return_value TSRMLS_DC) RETURN_EMPTY_STRING(); } - zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(arr), &pos); - - while ((tmp = zend_hash_get_current_data_ex(Z_ARRVAL_P(arr), &pos)) != NULL) { + ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), tmp) { again: switch (Z_TYPE_P(tmp)) { case IS_STRING: @@ -1191,8 +1188,8 @@ again: if (++i != numelems) { smart_str_appendl(&implstr, Z_STRVAL_P(delim), Z_STRLEN_P(delim)); } - zend_hash_move_forward_ex(Z_ARRVAL_P(arr), &pos); - } + } ZEND_HASH_FOREACH_END(); + smart_str_0(&implstr); if (implstr.s) { @@ -2871,56 +2868,49 @@ static void php_strtr_free_strp(void *strp) static PATNREPL *php_strtr_array_prepare_repls(int slen, HashTable *pats, zend_llist **allocs, int *outsize) { PATNREPL *patterns; - HashPosition hpos; zval *entry; int num_pats = zend_hash_num_elements(pats), - i; + i = 0; + zend_string *string_key; + ulong num_key; patterns = safe_emalloc(num_pats, sizeof(*patterns), 0); *allocs = emalloc(sizeof **allocs); zend_llist_init(*allocs, sizeof(zend_string*), &php_strtr_free_strp, 0); - for (i = 0, zend_hash_internal_pointer_reset_ex(pats, &hpos); - (entry = zend_hash_get_current_data_ex(pats, &hpos)) != NULL; - zend_hash_move_forward_ex(pats, &hpos)) { - zend_string *string_key; - ulong num_key; + ZEND_HASH_FOREACH_KEY_VAL(pats, num_key, string_key, entry) { zval tzv; - switch (zend_hash_get_current_key_ex(pats, &string_key, &num_key, 0, &hpos)) { - case HASH_KEY_IS_LONG: { + if (!string_key) { char buf[MAX_LENGTH_OF_LONG]; int len = snprintf(buf, sizeof(buf), "%ld", num_key); string_key = STR_INIT(buf, len, 0); zend_llist_add_element(*allocs, &string_key); - /* break missing intentionally */ - } - case HASH_KEY_IS_STRING: - if (string_key->len == 0) { /* empty string given as pattern */ - efree(patterns); - zend_llist_destroy(*allocs); - efree(*allocs); - *allocs = NULL; - return NULL; - } - if (string_key->len > slen) { /* this pattern can never match */ - continue; - } - - if (Z_TYPE_P(entry) != IS_STRING) { - ZVAL_DUP(&tzv, entry); - convert_to_string(&tzv); - entry = &tzv; - zend_llist_add_element(*allocs, &Z_STR_P(entry)); - } - - S(&patterns[i].pat) = string_key->val; - L(&patterns[i].pat) = string_key->len; - S(&patterns[i].repl) = Z_STRVAL_P(entry); - L(&patterns[i].repl) = Z_STRLEN_P(entry); - i++; } - } + if (string_key->len == 0) { /* empty string given as pattern */ + efree(patterns); + zend_llist_destroy(*allocs); + efree(*allocs); + *allocs = NULL; + return NULL; + } + if (string_key->len > slen) { /* this pattern can never match */ + continue; + } + + if (Z_TYPE_P(entry) != IS_STRING) { + ZVAL_DUP(&tzv, entry); + convert_to_string(&tzv); + entry = &tzv; + zend_llist_add_element(*allocs, &Z_STR_P(entry)); + } + + S(&patterns[i].pat) = string_key->val; + L(&patterns[i].pat) = string_key->len; + S(&patterns[i].repl) = Z_STRVAL_P(entry); + L(&patterns[i].repl) = Z_STRLEN_P(entry); + i++; + } ZEND_HASH_FOREACH_END(); *outsize = i; return patterns; diff --git a/ext/standard/url.c b/ext/standard/url.c index fc49dc32645..c7149dd9f31 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -694,7 +694,6 @@ PHP_FUNCTION(get_headers) php_stream_context *context; php_stream *stream; zval *prev_val, *hdr = NULL, *h; - HashPosition pos; HashTable *hashT; long format = 0; @@ -726,10 +725,8 @@ PHP_FUNCTION(get_headers) hashT = HASH_OF(&stream->wrapperdata); } - zend_hash_internal_pointer_reset_ex(hashT, &pos); - while ((hdr = zend_hash_get_current_data_ex(hashT, &pos)) != NULL) { - if (!hdr || Z_TYPE_P(hdr) != IS_STRING) { - zend_hash_move_forward_ex(hashT, &pos); + ZEND_HASH_FOREACH_VAL(hashT, hdr) { + if (Z_TYPE_P(hdr) != IS_STRING) { continue; } if (!format) { @@ -759,8 +756,7 @@ no_name_header: goto no_name_header; } } - zend_hash_move_forward_ex(hashT, &pos); - } + } ZEND_HASH_FOREACH_END(); php_stream_close(stream); } diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index 7c03d1767a4..762b65387a3 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -543,12 +543,11 @@ PHP_FUNCTION(stream_get_filters) filters_hash = php_get_stream_filters_hash(); if (filters_hash) { - for(zend_hash_internal_pointer_reset(filters_hash); - (key_flags = zend_hash_get_current_key(filters_hash, &filter_name, &num_key, 0)) != HASH_KEY_NON_EXISTENT; - zend_hash_move_forward(filters_hash)) - if (key_flags == HASH_KEY_IS_STRING) { - add_next_index_str(return_value, STR_COPY(filter_name)); - } + ZEND_HASH_FOREACH_VAL(filters_hash, key_flags) { + if (key_flags == HASH_KEY_IS_STRING) { + add_next_index_str(return_value, STR_COPY(filter_name)); + } + } ZEND_HASH_FOREACH_END(); } /* It's okay to return an empty array if no filters are registered */ } diff --git a/ext/standard/var.c b/ext/standard/var.c index 3f669dbda10..a4e556abdc0 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -717,27 +717,18 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt zend_string *key; zval *d, *name; ulong index; - HashPosition pos; int i; zval nval, *nvalp; - HashTable *propers; + HashTable *propers, *ht; ZVAL_NULL(&nval); nvalp = &nval; - zend_hash_internal_pointer_reset_ex(HASH_OF(retval_ptr), &pos); - - for (;; zend_hash_move_forward_ex(HASH_OF(retval_ptr), &pos)) { - i = zend_hash_get_current_key_ex(HASH_OF(retval_ptr), &key, &index, 0, &pos); - - if (i == HASH_KEY_NON_EXISTENT) { - break; - } - + ht = HASH_OF(retval_ptr); + ZEND_HASH_FOREACH_KEY_VAL(ht, index, key, name) { if (incomplete_class && strcmp(key->val, MAGIC_MEMBER) == 0) { continue; } - name = zend_hash_get_current_data_ex(HASH_OF(retval_ptr), &pos); if (Z_TYPE_P(name) != IS_STRING) { php_error_docref(NULL TSRMLS_CC, E_NOTICE, "__sleep should return an array only containing the names of instance-variables to serialize."); @@ -802,7 +793,7 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC); } } - } + } ZEND_HASH_FOREACH_END(); } smart_str_appendc(buf, '}'); } @@ -954,32 +945,17 @@ again: zend_string *key; zval *data; ulong index; - HashPosition pos; - zend_hash_internal_pointer_reset_ex(myht, &pos); - for (;; zend_hash_move_forward_ex(myht, &pos)) { - data = zend_hash_get_current_data_ex(myht, &pos); - if (!data) { - break; - } else if (Z_TYPE_P(data) == IS_INDIRECT) { - data = Z_INDIRECT_P(data); - if (Z_TYPE_P(data) == IS_UNDEF) { - continue; - } - } + ZEND_HASH_FOREACH_KEY_VAL_IND(myht, index, key, data) { - i = zend_hash_get_current_key_ex(myht, &key, &index, 0, &pos); if (incomplete_class && strcmp(key->val, MAGIC_MEMBER) == 0) { continue; } - switch (i) { - case HASH_KEY_IS_LONG: - php_var_serialize_long(buf, index); - break; - case HASH_KEY_IS_STRING: - php_var_serialize_string(buf, key->val, key->len); - break; + if (!key) { + php_var_serialize_long(buf, index); + } else { + php_var_serialize_string(buf, key->val, key->len); } /* we should still add element even if it's not OK, @@ -997,7 +973,7 @@ again: Z_ARRVAL_P(data)->nApplyCount--; } } - } + } ZEND_HASH_FOREACH_END(); } smart_str_appendc(buf, '}'); return;