Skip to content

Commit 3df0f4e

Browse files
Move min/max array fallback into array.c
1 parent 6cdf46f commit 3df0f4e

4 files changed

Lines changed: 20 additions & 72 deletions

File tree

UPGRADING.INTERNALS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ PHP 8.6 INTERNALS UPGRADE NOTES
3535
. The zval_dtor() alias of zval_ptr_dtor_nogc() has been removed.
3636
Call zval_ptr_dtor_nogc() directly instead.
3737
. The internal zend_copy_parameters_array() function is no longer exposed.
38+
. The internal zend_hash_minmax() function is no longer exposed. Scan the
39+
HashTable directly and use zend_compare() for value comparisons instead.
3840
. The zend_make_callable() function has been removed, if a callable zval
3941
needs to be obtained use the zend_get_callable_zval_from_fcc() function
4042
instead. If this was used to store a callable, then an FCC should be

Zend/zend_hash.c

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3238,73 +3238,6 @@ ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_fun
32383238
}
32393239

32403240

3241-
ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag)
3242-
{
3243-
uint32_t idx;
3244-
zval *res;
3245-
3246-
IS_CONSISTENT(ht);
3247-
3248-
if (ht->nNumOfElements == 0 ) {
3249-
return NULL;
3250-
}
3251-
3252-
if (HT_IS_PACKED(ht)) {
3253-
zval *zv;
3254-
3255-
idx = 0;
3256-
while (1) {
3257-
if (idx == ht->nNumUsed) {
3258-
return NULL;
3259-
}
3260-
if (Z_TYPE(ht->arPacked[idx]) != IS_UNDEF) break;
3261-
idx++;
3262-
}
3263-
res = ht->arPacked + idx;
3264-
for (; idx < ht->nNumUsed; idx++) {
3265-
zv = ht->arPacked + idx;
3266-
if (UNEXPECTED(Z_TYPE_P(zv) == IS_UNDEF)) continue;
3267-
3268-
if (flag) {
3269-
if (compar(res, zv) < 0) { /* max */
3270-
res = zv;
3271-
}
3272-
} else {
3273-
if (compar(res, zv) > 0) { /* min */
3274-
res = zv;
3275-
}
3276-
}
3277-
}
3278-
} else {
3279-
Bucket *p;
3280-
3281-
idx = 0;
3282-
while (1) {
3283-
if (idx == ht->nNumUsed) {
3284-
return NULL;
3285-
}
3286-
if (Z_TYPE(ht->arData[idx].val) != IS_UNDEF) break;
3287-
idx++;
3288-
}
3289-
res = &ht->arData[idx].val;
3290-
for (; idx < ht->nNumUsed; idx++) {
3291-
p = ht->arData + idx;
3292-
if (UNEXPECTED(Z_TYPE(p->val) == IS_UNDEF)) continue;
3293-
3294-
if (flag) {
3295-
if (compar(res, &p->val) < 0) { /* max */
3296-
res = &p->val;
3297-
}
3298-
} else {
3299-
if (compar(res, &p->val) > 0) { /* min */
3300-
res = &p->val;
3301-
}
3302-
}
3303-
}
3304-
}
3305-
return res;
3306-
}
3307-
33083241
ZEND_API bool ZEND_FASTCALL _zend_handle_numeric_str_ex(const char *key, size_t length, zend_ulong *idx)
33093242
{
33103243
const char *tmp = key;

Zend/zend_hash.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ typedef int (*bucket_compare_func_t)(Bucket *a, Bucket *b);
303303
ZEND_API int zend_hash_compare(HashTable *ht1, const HashTable *ht2, compare_func_t compar, bool ordered);
304304
ZEND_API void ZEND_FASTCALL zend_hash_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber);
305305
ZEND_API void ZEND_FASTCALL zend_array_sort_ex(HashTable *ht, sort_func_t sort_func, bucket_compare_func_t compare_func, bool renumber);
306-
ZEND_API zval* ZEND_FASTCALL zend_hash_minmax(const HashTable *ht, compare_func_t compar, uint32_t flag);
307306

308307
static zend_always_inline void ZEND_FASTCALL zend_hash_sort(HashTable *ht, bucket_compare_func_t compare_func, bool renumber) {
309308
zend_hash_sort_ex(ht, zend_sort, compare_func, renumber);

ext/standard/array.c

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,9 +1089,23 @@ PHP_FUNCTION(key)
10891089
}
10901090
/* }}} */
10911091

1092-
static int php_data_compare(const void *f, const void *s) /* {{{ */
1092+
static zval *php_array_data_minmax(HashTable *array, bool max) /* {{{ */
10931093
{
1094-
return zend_compare((zval*)f, (zval*)s);
1094+
zval *entry, *result = NULL;
1095+
1096+
ZEND_HASH_FOREACH_VAL(array, entry) {
1097+
if (!result) {
1098+
result = entry;
1099+
continue;
1100+
}
1101+
1102+
int cmp = zend_compare(result, entry);
1103+
if (max ? cmp < 0 : cmp > 0) {
1104+
result = entry;
1105+
}
1106+
} ZEND_HASH_FOREACH_END();
1107+
1108+
return result;
10951109
}
10961110
/* }}} */
10971111

@@ -1114,7 +1128,7 @@ PHP_FUNCTION(min)
11141128
zend_argument_type_error(1, "must be of type array, %s given", zend_zval_value_name(&args[0]));
11151129
RETURN_THROWS();
11161130
} else {
1117-
zval *result = zend_hash_minmax(Z_ARRVAL(args[0]), php_data_compare, 0);
1131+
zval *result = php_array_data_minmax(Z_ARRVAL(args[0]), false);
11181132
if (result) {
11191133
RETURN_COPY_DEREF(result);
11201134
} else {
@@ -1242,7 +1256,7 @@ PHP_FUNCTION(max)
12421256
zend_argument_type_error(1, "must be of type array, %s given", zend_zval_value_name(&args[0]));
12431257
RETURN_THROWS();
12441258
} else {
1245-
zval *result = zend_hash_minmax(Z_ARRVAL(args[0]), php_data_compare, 1);
1259+
zval *result = php_array_data_minmax(Z_ARRVAL(args[0]), true);
12461260
if (result) {
12471261
RETURN_COPY_DEREF(result);
12481262
} else {

0 commit comments

Comments
 (0)