@@ -3730,102 +3730,142 @@ PHPAPI int php_array_replace_recursive(HashTable *dest, HashTable *src) /* {{{ *
3730
3730
}
3731
3731
/* }}} */
3732
3732
3733
- static inline void php_array_merge_or_replace_wrapper (INTERNAL_FUNCTION_PARAMETERS , int recursive , int replace ) /* {{{ */
3733
+ static zend_always_inline void php_array_replace_wrapper (INTERNAL_FUNCTION_PARAMETERS , int recursive ) /* {{{ */
3734
3734
{
3735
3735
zval * args = NULL ;
3736
3736
zval * arg ;
3737
3737
int argc , i ;
3738
+ HashTable * dest ;
3738
3739
3739
3740
ZEND_PARSE_PARAMETERS_START (1 , -1 )
3740
3741
Z_PARAM_VARIADIC ('+' , args , argc )
3741
3742
ZEND_PARSE_PARAMETERS_END ();
3742
3743
3743
3744
3744
- if (replace ) {
3745
- HashTable * dest ;
3746
-
3747
- for (i = 0 ; i < argc ; i ++ ) {
3748
- zval * arg = args + i ;
3745
+ for (i = 0 ; i < argc ; i ++ ) {
3746
+ zval * arg = args + i ;
3749
3747
3750
- if (Z_TYPE_P (arg ) != IS_ARRAY ) {
3751
- php_error_docref (NULL , E_WARNING , "Expected parameter %d to be an array, %s given" , i + 1 , zend_zval_type_name (arg ));
3752
- RETURN_NULL ();
3753
- }
3748
+ if (Z_TYPE_P (arg ) != IS_ARRAY ) {
3749
+ php_error_docref (NULL , E_WARNING , "Expected parameter %d to be an array, %s given" , i + 1 , zend_zval_type_name (arg ));
3750
+ RETURN_NULL ();
3754
3751
}
3752
+ }
3755
3753
3756
- /* copy first array */
3757
- arg = args ;
3758
- dest = zend_array_dup (Z_ARRVAL_P (arg ));
3759
- ZVAL_ARR (return_value , dest );
3760
- if (recursive ) {
3761
- for (i = 1 ; i < argc ; i ++ ) {
3762
- arg = args + i ;
3763
- php_array_replace_recursive (dest , Z_ARRVAL_P (arg ));
3764
- }
3765
- } else {
3766
- for (i = 1 ; i < argc ; i ++ ) {
3767
- arg = args + i ;
3768
- zend_hash_merge (dest , Z_ARRVAL_P (arg ), zval_add_ref , 1 );
3769
- }
3754
+ /* copy first array */
3755
+ arg = args ;
3756
+ dest = zend_array_dup (Z_ARRVAL_P (arg ));
3757
+ ZVAL_ARR (return_value , dest );
3758
+ if (recursive ) {
3759
+ for (i = 1 ; i < argc ; i ++ ) {
3760
+ arg = args + i ;
3761
+ php_array_replace_recursive (dest , Z_ARRVAL_P (arg ));
3770
3762
}
3771
3763
} else {
3772
- zval * src_entry ;
3773
- HashTable * src , * dest ;
3774
- uint32_t count = 0 ;
3764
+ for (i = 1 ; i < argc ; i ++ ) {
3765
+ arg = args + i ;
3766
+ zend_hash_merge (dest , Z_ARRVAL_P (arg ), zval_add_ref , 1 );
3767
+ }
3768
+ }
3769
+ }
3770
+ /* }}} */
3771
+
3772
+ static zend_always_inline void php_array_merge_wrapper (INTERNAL_FUNCTION_PARAMETERS , int recursive ) /* {{{ */
3773
+ {
3774
+ zval * args = NULL ;
3775
+ zval * arg ;
3776
+ int argc , i ;
3777
+ zval * src_entry ;
3778
+ HashTable * src , * dest ;
3779
+ uint32_t count = 0 ;
3775
3780
3776
- for (i = 0 ; i < argc ; i ++ ) {
3777
- zval * arg = args + i ;
3781
+ ZEND_PARSE_PARAMETERS_START (1 , -1 )
3782
+ Z_PARAM_VARIADIC ('+' , args , argc )
3783
+ ZEND_PARSE_PARAMETERS_END ();
3778
3784
3779
- if (Z_TYPE_P (arg ) != IS_ARRAY ) {
3780
- php_error_docref (NULL , E_WARNING , "Expected parameter %d to be an array, %s given" , i + 1 , zend_zval_type_name (arg ));
3781
- RETURN_NULL ();
3782
- }
3783
- count += zend_hash_num_elements (Z_ARRVAL_P (arg ));
3784
- }
3785
-
3786
- arg = args ;
3787
- src = Z_ARRVAL_P (arg );
3788
- /* copy first array */
3789
- array_init_size (return_value , count );
3790
- dest = Z_ARRVAL_P (return_value );
3791
- if (HT_FLAGS (src ) & HASH_FLAG_PACKED ) {
3792
- zend_hash_real_init_packed (dest );
3793
- ZEND_HASH_FILL_PACKED (dest ) {
3794
- ZEND_HASH_FOREACH_VAL (src , src_entry ) {
3795
- if (UNEXPECTED (Z_ISREF_P (src_entry ) &&
3796
- Z_REFCOUNT_P (src_entry ) == 1 )) {
3797
- src_entry = Z_REFVAL_P (src_entry );
3785
+ for (i = 0 ; i < argc ; i ++ ) {
3786
+ zval * arg = args + i ;
3787
+
3788
+ if (Z_TYPE_P (arg ) != IS_ARRAY ) {
3789
+ php_error_docref (NULL , E_WARNING , "Expected parameter %d to be an array, %s given" , i + 1 , zend_zval_type_name (arg ));
3790
+ RETURN_NULL ();
3791
+ }
3792
+ count += zend_hash_num_elements (Z_ARRVAL_P (arg ));
3793
+ }
3794
+
3795
+ if (argc == 2 ) {
3796
+ zval * ret = NULL ;
3797
+
3798
+ if (zend_hash_num_elements (Z_ARRVAL (args [0 ])) == 0 ) {
3799
+ ret = & args [1 ];
3800
+ } else if (zend_hash_num_elements (Z_ARRVAL (args [1 ])) == 0 ) {
3801
+ ret = & args [0 ];
3802
+ }
3803
+ if (ret ) {
3804
+ if (HT_FLAGS (Z_ARRVAL_P (ret )) & HASH_FLAG_PACKED ) {
3805
+ if (HT_IS_WITHOUT_HOLES (Z_ARRVAL_P (ret ))) {
3806
+ ZVAL_COPY (return_value , ret );
3807
+ return ;
3808
+ }
3809
+ } else {
3810
+ zend_bool copy = 1 ;
3811
+ zend_string * string_key ;
3812
+
3813
+ ZEND_HASH_FOREACH_STR_KEY (Z_ARRVAL_P (ret ), string_key ) {
3814
+ if (!string_key ) {
3815
+ copy = 0 ;
3816
+ break ;
3798
3817
}
3799
- Z_TRY_ADDREF_P (src_entry );
3800
- ZEND_HASH_FILL_ADD (src_entry );
3801
3818
} ZEND_HASH_FOREACH_END ();
3802
- } ZEND_HASH_FILL_END ();
3803
- } else {
3804
- zend_string * string_key ;
3805
- zend_hash_real_init_mixed (dest );
3806
- ZEND_HASH_FOREACH_STR_KEY_VAL (src , string_key , src_entry ) {
3819
+ if (copy ) {
3820
+ ZVAL_COPY (return_value , ret );
3821
+ return ;
3822
+ }
3823
+ }
3824
+ }
3825
+ }
3826
+
3827
+ arg = args ;
3828
+ src = Z_ARRVAL_P (arg );
3829
+ /* copy first array */
3830
+ array_init_size (return_value , count );
3831
+ dest = Z_ARRVAL_P (return_value );
3832
+ if (HT_FLAGS (src ) & HASH_FLAG_PACKED ) {
3833
+ zend_hash_real_init_packed (dest );
3834
+ ZEND_HASH_FILL_PACKED (dest ) {
3835
+ ZEND_HASH_FOREACH_VAL (src , src_entry ) {
3807
3836
if (UNEXPECTED (Z_ISREF_P (src_entry ) &&
3808
3837
Z_REFCOUNT_P (src_entry ) == 1 )) {
3809
3838
src_entry = Z_REFVAL_P (src_entry );
3810
3839
}
3811
3840
Z_TRY_ADDREF_P (src_entry );
3812
- if (EXPECTED (string_key )) {
3813
- _zend_hash_append (dest , string_key , src_entry );
3814
- } else {
3815
- zend_hash_next_index_insert_new (dest , src_entry );
3816
- }
3841
+ ZEND_HASH_FILL_ADD (src_entry );
3817
3842
} ZEND_HASH_FOREACH_END ();
3818
- }
3819
- if (recursive ) {
3820
- for (i = 1 ; i < argc ; i ++ ) {
3821
- arg = args + i ;
3822
- php_array_merge_recursive (dest , Z_ARRVAL_P (arg ));
3843
+ } ZEND_HASH_FILL_END ();
3844
+ } else {
3845
+ zend_string * string_key ;
3846
+ zend_hash_real_init_mixed (dest );
3847
+ ZEND_HASH_FOREACH_STR_KEY_VAL (src , string_key , src_entry ) {
3848
+ if (UNEXPECTED (Z_ISREF_P (src_entry ) &&
3849
+ Z_REFCOUNT_P (src_entry ) == 1 )) {
3850
+ src_entry = Z_REFVAL_P (src_entry );
3823
3851
}
3824
- } else {
3825
- for (i = 1 ; i < argc ; i ++ ) {
3826
- arg = args + i ;
3827
- php_array_merge (dest , Z_ARRVAL_P (arg ));
3852
+ Z_TRY_ADDREF_P (src_entry );
3853
+ if (EXPECTED (string_key )) {
3854
+ _zend_hash_append (dest , string_key , src_entry );
3855
+ } else {
3856
+ zend_hash_next_index_insert_new (dest , src_entry );
3828
3857
}
3858
+ } ZEND_HASH_FOREACH_END ();
3859
+ }
3860
+ if (recursive ) {
3861
+ for (i = 1 ; i < argc ; i ++ ) {
3862
+ arg = args + i ;
3863
+ php_array_merge_recursive (dest , Z_ARRVAL_P (arg ));
3864
+ }
3865
+ } else {
3866
+ for (i = 1 ; i < argc ; i ++ ) {
3867
+ arg = args + i ;
3868
+ php_array_merge (dest , Z_ARRVAL_P (arg ));
3829
3869
}
3830
3870
}
3831
3871
}
@@ -3835,31 +3875,31 @@ static inline void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETE
3835
3875
Merges elements from passed arrays into one array */
3836
3876
PHP_FUNCTION (array_merge )
3837
3877
{
3838
- php_array_merge_or_replace_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 , 0 );
3878
+ php_array_merge_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 );
3839
3879
}
3840
3880
/* }}} */
3841
3881
3842
3882
/* {{{ proto array array_merge_recursive(array arr1 [, array ...])
3843
3883
Recursively merges elements from passed arrays into one array */
3844
3884
PHP_FUNCTION (array_merge_recursive )
3845
3885
{
3846
- php_array_merge_or_replace_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 , 0 );
3886
+ php_array_merge_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 );
3847
3887
}
3848
3888
/* }}} */
3849
3889
3850
3890
/* {{{ proto array array_replace(array arr1 [, array ...])
3851
3891
Replaces elements from passed arrays into one array */
3852
3892
PHP_FUNCTION (array_replace )
3853
3893
{
3854
- php_array_merge_or_replace_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 , 1 );
3894
+ php_array_replace_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 0 );
3855
3895
}
3856
3896
/* }}} */
3857
3897
3858
3898
/* {{{ proto array array_replace_recursive(array arr1 [, array ...])
3859
3899
Recursively replaces elements from passed arrays into one array */
3860
3900
PHP_FUNCTION (array_replace_recursive )
3861
3901
{
3862
- php_array_merge_or_replace_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 , 1 );
3902
+ php_array_replace_wrapper (INTERNAL_FUNCTION_PARAM_PASSTHRU , 1 );
3863
3903
}
3864
3904
/* }}} */
3865
3905
0 commit comments