@@ -78,7 +78,8 @@ ZEND_COLD static zend_never_inline void zend_partial_args_overflow(
7878
7979static zend_result zp_args_check (const zend_function * function ,
8080 uint32_t argc , const zval * argv ,
81- const zend_array * extra_named_args ) {
81+ const zend_array * extra_named_args ,
82+ bool uses_variadic_placeholder ) {
8283
8384 if (extra_named_args ) {
8485 zval * arg ;
@@ -93,13 +94,11 @@ static zend_result zp_args_check(const zend_function *function,
9394 } ZEND_HASH_FOREACH_END ();
9495 }
9596
96- /* Z_EXTRA(ZEND_CALL_ARG(call, 1)) is set by ZEND_SEND_PLACEHOLDER */
97- bool variadic = Z_EXTRA (argv [0 ]) == _IS_PLACEHOLDER_VARIADIC ;
98-
99- uint32_t num = argc + (variadic ? -1 : 0 );
97+ // TODO: should be just 'argc', since the placeholder param doesn't increase argc?
98+ uint32_t num = argc + (uses_variadic_placeholder ? -1 : 0 );
10099
101100 if (num < function -> common .required_num_args ) {
102- if (variadic ) {
101+ if (uses_variadic_placeholder ) {
103102 return SUCCESS ;
104103 }
105104
@@ -674,7 +673,8 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
674673 uint32_t argc , zval * argv , zend_array * extra_named_params ,
675674 const zend_array * named_positions ,
676675 const zend_op_array * declaring_op_array ,
677- const zend_op * declaring_opline , void * * cache_slot ) {
676+ const zend_op * declaring_opline , void * * cache_slot ,
677+ bool uses_variadic_placeholder ) {
678678
679679 zend_op_array * op_array = NULL ;
680680
@@ -684,7 +684,7 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
684684 return NULL ;
685685 }
686686
687- if (UNEXPECTED (zp_args_check (function , argc , argv , extra_named_params ) != SUCCESS )) {
687+ if (UNEXPECTED (zp_args_check (function , argc , argv , extra_named_params , uses_variadic_placeholder ) != SUCCESS )) {
688688 ZEND_ASSERT (EG (exception ));
689689 return NULL ;
690690 }
@@ -702,16 +702,14 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
702702 int orig_lineno = CG (zend_lineno );
703703 CG (zend_lineno ) = zend_get_executed_lineno ();
704704
705- bool variadic_partial = false;
706705 int new_argc = argc ;
707706
708- /* Z_EXTRA(ZEND_CALL_ARG(call, 1)) is set in ZEND_SEND_PLACEHOLDER */
709- if (Z_EXTRA (argv [0 ]) == _IS_PLACEHOLDER_VARIADIC ) {
710- variadic_partial = true;
707+ if (uses_variadic_placeholder ) {
711708 new_argc = MAX (new_argc , function -> common .num_args );
712709 }
713710
714711 zval * tmp = zend_arena_alloc (& CG (arena ), new_argc * sizeof (zval ));
712+ // TODO: should be argc * sizeof(zval) ?
715713 memcpy (tmp , argv , new_argc * sizeof (zval ));
716714 argv = tmp ;
717715
@@ -754,7 +752,7 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
754752 offset , param_offset , num_required );
755753 }
756754
757- if (variadic_partial ) {
755+ if (uses_variadic_placeholder ) {
758756 /* Handle implicit placeholders added by '...' */
759757 for (uint32_t offset = 0 ; offset < new_argc ; offset ++ ) {
760758 if (offset < argc && !Z_ISUNDEF (argv [offset ])) {
@@ -780,13 +778,13 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
780778
781779 /* Assign variable names */
782780
783- uint32_t num_names = argc + variadic_partial + (extra_named_params != NULL )
781+ uint32_t num_names = argc + uses_variadic_placeholder + (extra_named_params != NULL )
784782 + ((function -> common .fn_flags & ZEND_ACC_CLOSURE ) != 0 );
785783 zend_string * * param_names = zend_arena_calloc (& CG (arena ),
786784 num_names , sizeof (zend_string * ));
787785 memset (param_names , 0 , sizeof (zend_string * ) * num_names );
788786 zp_assign_names (param_names , num_names , argc , argv , function ,
789- variadic_partial , extra_named_params );
787+ uses_variadic_placeholder , extra_named_params );
790788
791789 /* Generate AST */
792790
@@ -801,7 +799,7 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
801799 /* Must be first, as this is assumed in do_closure_bind() */
802800 if (function -> common .fn_flags & ZEND_ACC_CLOSURE ) {
803801 zend_ast * lexical_var_ast = zend_ast_create_zval_from_str (
804- zend_string_copy (param_names [argc + variadic_partial + (extra_named_params != NULL )]));
802+ zend_string_copy (param_names [argc + uses_variadic_placeholder + (extra_named_params != NULL )]));
805803 lexical_vars_ast = zend_ast_list_add (lexical_vars_ast , lexical_var_ast );
806804 }
807805
@@ -858,13 +856,13 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
858856
859857 if (extra_named_params ) {
860858 zend_ast * lexical_var_ast = zend_ast_create_zval_from_str (
861- zend_string_copy (param_names [argc + variadic_partial ]));
859+ zend_string_copy (param_names [argc + uses_variadic_placeholder ]));
862860 lexical_vars_ast = zend_ast_list_add (lexical_vars_ast , lexical_var_ast );
863861 }
864862
865863 /* If we have a variadic placeholder and the underlying function is
866864 * variadic, add a variadic param. */
867- if (variadic_partial
865+ if (uses_variadic_placeholder
868866 && (function -> common .fn_flags & ZEND_ACC_VARIADIC )) {
869867 zend_arg_info * arg_info = & function -> common .arg_info [function -> common .num_args ];
870868 int param_flags = ZEND_PARAM_VARIADIC ;
@@ -901,13 +899,13 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
901899 * The func_num_args() call should be compiled to a single FUNC_NUM_ARGS op.
902900 */
903901
904- if (variadic_partial && !(function -> common .fn_flags & ZEND_ACC_VARIADIC )) {
902+ if (uses_variadic_placeholder && !(function -> common .fn_flags & ZEND_ACC_VARIADIC )) {
905903 zend_ast * no_forwarding_ast = zend_ast_create_list (0 , ZEND_AST_STMT_LIST );
906904 zend_ast * forwarding_ast = zend_ast_create_list (0 , ZEND_AST_STMT_LIST );
907905
908906 no_forwarding_ast = zp_compile_forwarding_call (this_ptr , function ,
909907 argc , argv , extra_named_params ,
910- param_names , variadic_partial , num_params ,
908+ param_names , uses_variadic_placeholder , num_params ,
911909 called_scope , return_type , false, no_forwarding_ast );
912910
913911 if (!no_forwarding_ast ) {
@@ -917,7 +915,7 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
917915
918916 forwarding_ast = zp_compile_forwarding_call (this_ptr , function ,
919917 argc , argv , extra_named_params ,
920- param_names , variadic_partial , num_params ,
918+ param_names , uses_variadic_placeholder , num_params ,
921919 called_scope , return_type , true, forwarding_ast );
922920
923921 if (!forwarding_ast ) {
@@ -944,7 +942,7 @@ zend_op_array *zp_compile(zval *this_ptr, zend_function *function,
944942 } else {
945943 stmts_ast = zp_compile_forwarding_call (this_ptr , function ,
946944 argc , argv , extra_named_params ,
947- param_names , variadic_partial , num_params ,
945+ param_names , uses_variadic_placeholder , num_params ,
948946 called_scope , return_type , false, stmts_ast );
949947
950948 if (!stmts_ast ) {
@@ -1024,7 +1022,8 @@ zend_op_array *zp_get_op_array(zval *this_ptr, zend_function *function,
10241022 uint32_t argc , zval * argv , zend_array * extra_named_params ,
10251023 const zend_array * named_positions ,
10261024 const zend_op_array * declaring_op_array ,
1027- const zend_op * declaring_opline , void * * cache_slot ) {
1025+ const zend_op * declaring_opline , void * * cache_slot ,
1026+ bool uses_variadic_placeholder ) {
10281027
10291028 if (EXPECTED (function -> type == ZEND_INTERNAL_FUNCTION
10301029 ? cache_slot [0 ] == function
@@ -1038,7 +1037,7 @@ zend_op_array *zp_get_op_array(zval *this_ptr, zend_function *function,
10381037 if (UNEXPECTED (!op_array )) {
10391038 op_array = zp_compile (this_ptr , function , argc , argv ,
10401039 extra_named_params , named_positions , declaring_op_array , declaring_opline ,
1041- cache_slot );
1040+ cache_slot , uses_variadic_placeholder );
10421041 }
10431042
10441043 if (EXPECTED (op_array )) {
@@ -1103,12 +1102,13 @@ void zend_partial_create(zval *result, zval *this_ptr, zend_function *function,
11031102 uint32_t argc , zval * argv , zend_array * extra_named_params ,
11041103 const zend_array * named_positions ,
11051104 const zend_op_array * declaring_op_array ,
1106- const zend_op * declaring_opline , void * * cache_slot ) {
1105+ const zend_op * declaring_opline , void * * cache_slot ,
1106+ bool uses_variadic_placeholder ) {
11071107
11081108 zend_op_array * op_array = zp_get_op_array (this_ptr , function , argc , argv ,
11091109 extra_named_params , named_positions ,
11101110 declaring_op_array , declaring_opline ,
1111- cache_slot );
1111+ cache_slot , uses_variadic_placeholder );
11121112
11131113 if (UNEXPECTED (!op_array )) {
11141114 ZEND_ASSERT (EG (exception ));
0 commit comments