@@ -6747,41 +6747,73 @@ PHP_FUNCTION(array_map)
6747
6747
ZEND_PARSE_PARAMETERS_END ();
6748
6748
6749
6749
if (n_arrays == 1 ) {
6750
- zend_ulong num_key ;
6751
- zend_string * str_key ;
6752
-
6753
6750
if (Z_TYPE (arrays [0 ]) != IS_ARRAY ) {
6754
6751
zend_argument_type_error (2 , "must be of type array, %s given" , zend_zval_value_name (& arrays [0 ]));
6755
6752
RETURN_THROWS ();
6756
6753
}
6757
- maxlen = zend_hash_num_elements (Z_ARRVAL (arrays [0 ]));
6754
+ const HashTable * input = Z_ARRVAL (arrays [0 ]);
6755
+ maxlen = zend_hash_num_elements (input );
6758
6756
6759
6757
/* Short-circuit: if no callback and only one array, just return it. */
6760
6758
if (!ZEND_FCI_INITIALIZED (fci ) || !maxlen ) {
6761
6759
ZVAL_COPY (return_value , & arrays [0 ]);
6762
6760
return ;
6763
6761
}
6764
6762
6765
- array_init_size (return_value , maxlen );
6766
- zend_hash_real_init (Z_ARRVAL_P (return_value ), HT_IS_PACKED (Z_ARRVAL (arrays [0 ])));
6767
-
6768
6763
fci .retval = & result ;
6769
6764
fci .param_count = 1 ;
6770
6765
6771
- ZEND_HASH_FOREACH_KEY_VAL (Z_ARRVAL (arrays [0 ]), num_key , str_key , fci .params ) {
6772
- zend_result ret = zend_call_function (& fci , & fci_cache );
6773
- ZEND_ASSERT (ret == SUCCESS );
6774
- ZEND_IGNORE_VALUE (ret );
6775
- if (Z_TYPE (result ) == IS_UNDEF ) {
6776
- zend_array_destroy (Z_ARR_P (return_value ));
6777
- RETURN_NULL ();
6778
- }
6779
- if (str_key ) {
6780
- _zend_hash_append (Z_ARRVAL_P (return_value ), str_key , & result );
6781
- } else {
6782
- zend_hash_index_add_new (Z_ARRVAL_P (return_value ), num_key , & result );
6783
- }
6784
- } ZEND_HASH_FOREACH_END ();
6766
+ if (HT_IS_PACKED (input )) {
6767
+ array_init_size (return_value , input -> nNumUsed );
6768
+ HashTable * output = Z_ARRVAL_P (return_value );
6769
+ zend_hash_real_init_packed (output );
6770
+
6771
+ uint32_t undefs = 0 ;
6772
+ ZEND_HASH_FILL_PACKED (output ) {
6773
+ /* Can't use ZEND_HASH_PACKED_FOREACH_VAL() because we need to also account for the UNDEF values
6774
+ * so the keys in the output array will match those of the input array. */
6775
+ for (zval * cur = input -> arPacked , * end = input -> arPacked + input -> nNumUsed ; cur != end ; cur ++ ) {
6776
+ if (EXPECTED (!Z_ISUNDEF_P (cur ))) {
6777
+ fci .params = cur ;
6778
+ zend_result ret = zend_call_function (& fci , & fci_cache );
6779
+ ZEND_ASSERT (ret == SUCCESS );
6780
+ ZEND_IGNORE_VALUE (ret );
6781
+ if (UNEXPECTED (Z_ISUNDEF (result ))) {
6782
+ ZEND_HASH_FILL_FINISH ();
6783
+ zend_array_destroy (output );
6784
+ RETURN_NULL ();
6785
+ }
6786
+ } else {
6787
+ ZVAL_UNDEF (& result );
6788
+ undefs ++ ;
6789
+ }
6790
+ ZEND_HASH_FILL_ADD (& result );
6791
+ }
6792
+ } ZEND_HASH_FILL_END ();
6793
+ output -> nNumOfElements -= undefs ;
6794
+ } else {
6795
+ zend_ulong num_key ;
6796
+ zend_string * str_key ;
6797
+
6798
+ array_init_size (return_value , maxlen );
6799
+ HashTable * output = Z_ARRVAL_P (return_value );
6800
+ zend_hash_real_init_mixed (output );
6801
+
6802
+ ZEND_HASH_MAP_FOREACH_KEY_VAL (input , num_key , str_key , fci .params ) {
6803
+ zend_result ret = zend_call_function (& fci , & fci_cache );
6804
+ ZEND_ASSERT (ret == SUCCESS );
6805
+ ZEND_IGNORE_VALUE (ret );
6806
+ if (UNEXPECTED (Z_ISUNDEF (result ))) {
6807
+ zend_array_destroy (output );
6808
+ RETURN_NULL ();
6809
+ }
6810
+ if (str_key ) {
6811
+ _zend_hash_append (output , str_key , & result );
6812
+ } else {
6813
+ zend_hash_index_add_new (output , num_key , & result );
6814
+ }
6815
+ } ZEND_HASH_FOREACH_END ();
6816
+ }
6785
6817
} else {
6786
6818
uint32_t * array_pos = (HashPosition * )ecalloc (n_arrays , sizeof (HashPosition ));
6787
6819
0 commit comments