Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -853,7 +853,7 @@ jobs:
PHP_BUILD_CACHE_BASE_DIR: C:\build-cache
PHP_BUILD_OBJ_DIR: C:\obj
PHP_BUILD_CACHE_SDK_DIR: C:\build-cache\sdk
PHP_BUILD_SDK_BRANCH: php-sdk-2.8.2
PHP_BUILD_SDK_BRANCH: php-sdk-2.8.4
PHP_BUILD_CRT: ${{ fromJson(inputs.branch).jobs.WINDOWS.config.vs_crt_version }}
PLATFORM: ${{ matrix.x64 && 'x64' || 'x86' }}
THREAD_SAFE: "${{ matrix.zts && '1' || '0' }}"
Expand Down
195 changes: 104 additions & 91 deletions ext/standard/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -7125,114 +7125,127 @@ PHP_FUNCTION(array_map)
}
}

array_init_size(return_value, maxlen);

if (!ZEND_FCI_INITIALIZED(fci)) {
uint32_t *array_pos = ecalloc(n_arrays, sizeof(HashPosition));
zval zv;

/* We iterate through all the arrays at once. */
for (k = 0; k < maxlen; k++) {
if (!maxlen) {
RETURN_EMPTY_ARRAY();
}

/* If no callback, the result will be an array, consisting of current
* entries from all arrays. */
array_init_size(&result, n_arrays);
array_init_size(return_value, maxlen);
zend_hash_real_init_packed(Z_ARRVAL_P(return_value));

for (i = 0; i < n_arrays; i++) {
/* If this array still has elements, add the current one to the
* parameter list, otherwise use null value. */
uint32_t pos = array_pos[i];
if (HT_IS_PACKED(Z_ARRVAL(arrays[i]))) {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZVAL_NULL(&zv);
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arPacked[pos]) != IS_UNDEF) {
ZVAL_COPY(&zv, &Z_ARRVAL(arrays[i])->arPacked[pos]);
array_pos[i] = pos + 1;
break;
}
pos++;
}
} else {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZVAL_NULL(&zv);
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arData[pos].val) != IS_UNDEF) {
ZVAL_COPY(&zv, &Z_ARRVAL(arrays[i])->arData[pos].val);
array_pos[i] = pos + 1;
break;
ZEND_HASH_FILL_PACKED(Z_ARRVAL_P(return_value)) {
if (!ZEND_FCI_INITIALIZED(fci)) {
uint32_t *array_pos = ecalloc(n_arrays, sizeof(HashPosition));
zval zv;

/* We iterate through all the arrays at once. */
for (k = 0; k < maxlen; k++) {

/* If no callback, the result will be an array, consisting of current
* entries from all arrays. */
array_init_size(&result, n_arrays);

zend_hash_real_init_packed(Z_ARRVAL(result));
ZEND_HASH_FILL_PACKED(Z_ARRVAL(result)) {
for (i = 0; i < n_arrays; i++) {
/* If this array still has elements, add the current one to the
* parameter list, otherwise use null value. */
uint32_t pos = array_pos[i];
if (HT_IS_PACKED(Z_ARRVAL(arrays[i]))) {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZEND_HASH_FILL_SET_NULL();
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arPacked[pos]) != IS_UNDEF) {
ZVAL_COPY(&zv, &Z_ARRVAL(arrays[i])->arPacked[pos]);
ZEND_HASH_FILL_SET(&zv);
array_pos[i] = pos + 1;
break;
}
pos++;
}
} else {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZEND_HASH_FILL_SET_NULL();
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arData[pos].val) != IS_UNDEF) {
ZVAL_COPY(&zv, &Z_ARRVAL(arrays[i])->arData[pos].val);
ZEND_HASH_FILL_SET(&zv);
array_pos[i] = pos + 1;
break;
}
pos++;
}
}
pos++;
ZEND_HASH_FILL_NEXT();
}
}
zend_hash_next_index_insert_new(Z_ARRVAL(result), &zv);
}
} ZEND_HASH_FILL_END();

zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &result);
}

efree(array_pos);
} else {
zval *params = (zval *)safe_emalloc(n_arrays, sizeof(zval), 0);

/* Remember next starting point in the array, initialize those as zeros. */
for (i = 0; i < n_arrays; i++) {
Z_EXTRA(params[i]) = 0;
}
ZEND_HASH_FILL_ADD(&result);
}

fci.retval = &result;
fci.param_count = n_arrays;
fci.params = params;
efree(array_pos);
} else {
zval *params = (zval *)safe_emalloc(n_arrays, sizeof(zval), 0);

/* We iterate through all the arrays at once. */
for (k = 0; k < maxlen; k++) {
/* Remember next starting point in the array, initialize those as zeros. */
for (i = 0; i < n_arrays; i++) {
/* If this array still has elements, add the current one to the
* parameter list, otherwise use null value. */
uint32_t pos = Z_EXTRA(params[i]);
if (HT_IS_PACKED(Z_ARRVAL(arrays[i]))) {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZVAL_NULL(&params[i]);
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arPacked[pos]) != IS_UNDEF) {
ZVAL_COPY_VALUE(&params[i], &Z_ARRVAL(arrays[i])->arPacked[pos]);
Z_EXTRA(params[i]) = pos + 1;
break;
Z_EXTRA(params[i]) = 0;
}

fci.retval = &result;
fci.param_count = n_arrays;
fci.params = params;

/* We iterate through all the arrays at once. */
for (k = 0; k < maxlen; k++) {
for (i = 0; i < n_arrays; i++) {
/* If this array still has elements, add the current one to the
* parameter list, otherwise use null value. */
uint32_t pos = Z_EXTRA(params[i]);
if (HT_IS_PACKED(Z_ARRVAL(arrays[i]))) {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZVAL_NULL(&params[i]);
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arPacked[pos]) != IS_UNDEF) {
ZVAL_COPY_VALUE(&params[i], &Z_ARRVAL(arrays[i])->arPacked[pos]);
Z_EXTRA(params[i]) = pos + 1;
break;
}
pos++;
}
pos++;
}
} else {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZVAL_NULL(&params[i]);
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arData[pos].val) != IS_UNDEF) {
ZVAL_COPY_VALUE(&params[i], &Z_ARRVAL(arrays[i])->arData[pos].val);
Z_EXTRA(params[i]) = pos + 1;
break;
} else {
while (1) {
if (pos >= Z_ARRVAL(arrays[i])->nNumUsed) {
ZVAL_NULL(&params[i]);
break;
} else if (Z_TYPE(Z_ARRVAL(arrays[i])->arData[pos].val) != IS_UNDEF) {
ZVAL_COPY_VALUE(&params[i], &Z_ARRVAL(arrays[i])->arData[pos].val);
Z_EXTRA(params[i]) = pos + 1;
break;
}
pos++;
}
pos++;
}
}
}

zend_result ret = zend_call_function(&fci, &fci_cache);
ZEND_ASSERT(ret == SUCCESS);
ZEND_IGNORE_VALUE(ret);
zend_result ret = zend_call_function(&fci, &fci_cache);
ZEND_ASSERT(ret == SUCCESS);
ZEND_IGNORE_VALUE(ret);

if (Z_TYPE(result) == IS_UNDEF) {
efree(params);
RETURN_THROWS();
if (Z_TYPE(result) == IS_UNDEF) {
ZEND_HASH_FILL_FINISH();
efree(params);
RETURN_THROWS();
}

ZEND_HASH_FILL_ADD(&result);
}

zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &result);
efree(params);
}

efree(params);
}
} ZEND_HASH_FILL_END();
}
}
/* }}} */
Expand Down