@@ -970,38 +970,85 @@ static void spl_deque_shrink_capacity(spl_deque_entries *array, size_t new_capac
970970
971971PHP_METHOD (Deque , push )
972972{
973+ const zval * args ;
974+ uint32_t argc ;
973975 zval * value ;
974976
975- ZEND_PARSE_PARAMETERS_START (1 , 1 )
976- Z_PARAM_ZVAL ( value )
977+ ZEND_PARSE_PARAMETERS_START (0 , - 1 )
978+ Z_PARAM_VARIADIC ( '+' , args , argc )
977979 ZEND_PARSE_PARAMETERS_END ();
978980
979- spl_deque_push_back (Z_DEQUE_P (ZEND_THIS ), value );
981+ if (UNEXPECTED (argc == 0 )) {
982+ return ;
983+ }
984+
985+ spl_deque * intern = Z_DEQUE_P (ZEND_THIS );
986+ size_t old_size = intern -> array .size ;
987+ const size_t new_size = old_size + argc ;
988+ size_t mask = intern -> array .mask ;
989+ const size_t old_capacity = mask ? mask + 1 : 0 ;
990+
991+ if (new_size > old_capacity ) {
992+ const size_t new_capacity = spl_deque_next_pow2_capacity (new_size );
993+ spl_deque_raise_capacity (& intern -> array , new_capacity );
994+ mask = intern -> array .mask ;
995+ }
996+ zval * const circular_buffer = intern -> array .circular_buffer ;
997+ const size_t old_offset = intern -> array .offset ;
998+
999+ while (1 ) {
1000+ zval * dest = & circular_buffer [(old_offset + old_size ) & mask ];
1001+ ZVAL_COPY (dest , args );
1002+ if (++ old_size >= new_size ) {
1003+ break ;
1004+ }
1005+ args ++ ;
1006+ }
1007+ intern -> array .size = new_size ;
9801008}
9811009
9821010PHP_METHOD (Deque , unshift )
9831011{
1012+ const zval * args ;
1013+ uint32_t argc ;
9841014 zval * value ;
9851015
986- ZEND_PARSE_PARAMETERS_START (1 , 1 )
987- Z_PARAM_ZVAL ( value )
1016+ ZEND_PARSE_PARAMETERS_START (0 , - 1 )
1017+ Z_PARAM_VARIADIC ( '+' , args , argc )
9881018 ZEND_PARSE_PARAMETERS_END ();
9891019
1020+ if (UNEXPECTED (argc == 0 )) {
1021+ return ;
1022+ }
1023+
9901024 spl_deque * intern = Z_DEQUE_P (ZEND_THIS );
991- const size_t old_size = intern -> array .size ;
992- const size_t old_mask = intern -> array .mask ;
993- const size_t old_capacity = old_mask ? old_mask + 1 : 0 ;
1025+ size_t old_size = intern -> array .size ;
1026+ const size_t new_size = old_size + argc ;
1027+ size_t mask = intern -> array .mask ;
1028+ const size_t old_capacity = mask ? mask + 1 : 0 ;
9941029
995- if (old_size >= old_capacity ) {
996- ZEND_ASSERT (old_size == old_capacity );
997- const size_t new_capacity = old_capacity > 0 ? old_capacity * 2 : 4 ;
1030+ if (new_size > old_capacity ) {
1031+ const size_t new_capacity = spl_deque_next_pow2_capacity (new_size );
9981032 spl_deque_raise_capacity (& intern -> array , new_capacity );
1033+ mask = intern -> array .mask ;
9991034 }
1000- intern -> array .offset = (intern -> array .offset - 1 ) & intern -> array .mask ;
1001- intern -> array .size ++ ;
1035+ size_t offset = intern -> array .offset ;
1036+ zval * const circular_buffer = intern -> array .circular_buffer ;
1037+
1038+ do {
1039+ offset = (offset - 1 ) & mask ;
1040+ zval * dest = & circular_buffer [offset ];
1041+ ZVAL_COPY (dest , args );
1042+ if (-- argc == 0 ) {
1043+ break ;
1044+ }
1045+ args ++ ;
1046+ } while (1 );
1047+
1048+ intern -> array .offset = offset ;
1049+ intern -> array .size = new_size ;
1050+
10021051 DEBUG_ASSERT_CONSISTENT_DEQUE (& intern -> array );
1003- zval * dest = & intern -> array .circular_buffer [intern -> array .offset ];
1004- ZVAL_COPY (dest , value );
10051052}
10061053
10071054static zend_always_inline void spl_deque_try_shrink_capacity (spl_deque * intern , size_t old_size )
0 commit comments