@@ -149,6 +149,20 @@ static void zend_try_inline_call(zend_op_array *op_array, zend_op *fcall, zend_o
149
149
}
150
150
}
151
151
152
+ /* arg_num is 1-based here, to match SEND encoding. */
153
+ static bool has_known_send_mode (const optimizer_call_info * info , uint32_t arg_num )
154
+ {
155
+ if (!info -> func ) {
156
+ return false;
157
+ }
158
+
159
+ /* For prototype functions we should not make assumptions about arguments that are not part of
160
+ * the signature: And inheriting method can add an optional by-ref argument. */
161
+ return !info -> is_prototype
162
+ || arg_num <= info -> func -> common .num_args
163
+ || (info -> func -> common .fn_flags & ZEND_ACC_VARIADIC );
164
+ }
165
+
152
166
void zend_optimize_func_calls (zend_op_array * op_array , zend_optimizer_ctx * ctx )
153
167
{
154
168
zend_op * opline = op_array -> opcodes ;
@@ -261,7 +275,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
261
275
}
262
276
break ;
263
277
case ZEND_SEND_VAL_EX :
264
- if (call_stack [call - 1 ]. func ) {
278
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
265
279
if (opline -> op2_type == IS_CONST ) {
266
280
call_stack [call - 1 ].try_inline = 0 ;
267
281
break ;
@@ -276,7 +290,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
276
290
}
277
291
break ;
278
292
case ZEND_CHECK_FUNC_ARG :
279
- if (call_stack [call - 1 ]. func ) {
293
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
280
294
if (opline -> op2_type == IS_CONST ) {
281
295
call_stack [call - 1 ].try_inline = 0 ;
282
296
call_stack [call - 1 ].func_arg_num = (uint32_t )-1 ;
@@ -289,7 +303,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
289
303
break ;
290
304
case ZEND_SEND_VAR_EX :
291
305
case ZEND_SEND_FUNC_ARG :
292
- if (call_stack [call - 1 ]. func ) {
306
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
293
307
if (opline -> op2_type == IS_CONST ) {
294
308
call_stack [call - 1 ].try_inline = 0 ;
295
309
break ;
@@ -304,7 +318,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
304
318
}
305
319
break ;
306
320
case ZEND_SEND_VAR_NO_REF_EX :
307
- if (call_stack [call - 1 ]. func ) {
321
+ if (has_known_send_mode ( & call_stack [call - 1 ], opline -> op2 . num ) ) {
308
322
if (opline -> op2_type == IS_CONST ) {
309
323
call_stack [call - 1 ].try_inline = 0 ;
310
324
break ;
0 commit comments