@@ -139,6 +139,20 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
139
139
}
140
140
}
141
141
142
+ /* arg_num is 1-based here, to match SEND encoding. */
143
+ static bool has_known_send_mode (const optimizer_call_info * info , uint32_t arg_num )
144
+ {
145
+ if (!info -> func ) {
146
+ return false;
147
+ }
148
+
149
+ /* For prototype functions we should not make assumptions about arguments that are not part of
150
+ * the signature: And inheriting method can add an optional by-ref argument. */
151
+ return !info -> is_prototype
152
+ || arg_num <= info -> func -> common .num_args
153
+ || (info -> func -> common .fn_flags & ZEND_ACC_VARIADIC );
154
+ }
155
+
142
156
void zend_optimize_func_calls (zend_op_array * op_array , zend_optimizer_ctx * ctx )
143
157
{
144
158
zend_op * opline = op_array -> opcodes ;
@@ -251,7 +265,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
251
265
}
252
266
break ;
253
267
case ZEND_SEND_VAL_EX :
254
- if (call_stack [call - 1 ]. func ) {
268
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
255
269
if (opline -> op2_type == IS_CONST ) {
256
270
call_stack [call - 1 ].try_inline = 0 ;
257
271
break ;
@@ -266,7 +280,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
266
280
}
267
281
break ;
268
282
case ZEND_CHECK_FUNC_ARG :
269
- if (call_stack [call - 1 ]. func ) {
283
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
270
284
if (opline -> op2_type == IS_CONST ) {
271
285
call_stack [call - 1 ].try_inline = 0 ;
272
286
call_stack [call - 1 ].func_arg_num = (uint32_t )-1 ;
@@ -279,7 +293,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
279
293
break ;
280
294
case ZEND_SEND_VAR_EX :
281
295
case ZEND_SEND_FUNC_ARG :
282
- if (call_stack [call - 1 ]. func ) {
296
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
283
297
if (opline -> op2_type == IS_CONST ) {
284
298
call_stack [call - 1 ].try_inline = 0 ;
285
299
break ;
@@ -294,7 +308,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
294
308
}
295
309
break ;
296
310
case ZEND_SEND_VAR_NO_REF_EX :
297
- if (call_stack [call - 1 ]. func ) {
311
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
298
312
if (opline -> op2_type == IS_CONST ) {
299
313
call_stack [call - 1 ].try_inline = 0 ;
300
314
break ;
0 commit comments