Skip to content

Commit acdafc0

Browse files
committed
Prevent inlining through call_user_func() and call_user_func_array()
1 parent f2e4fc3 commit acdafc0

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

ext/opcache/Optimizer/optimize_func_calls.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
typedef struct _optimizer_call_info {
4040
zend_function *func;
4141
zend_op *opline;
42+
zend_bool try_inline;
4243
} optimizer_call_info;
4344

4445
static void zend_delete_call_instructions(zend_op *opline)
@@ -159,6 +160,7 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
159160
case ZEND_INIT_FCALL:
160161
call_stack[call].func = zend_optimizer_get_called_func(
161162
ctx->script, op_array, opline, 0);
163+
call_stack[call].try_inline = 1;
162164
/* break missing intentionally */
163165
case ZEND_NEW:
164166
case ZEND_INIT_DYNAMIC_CALL:
@@ -198,12 +200,14 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
198200
ZEND_ASSERT(0);
199201
}
200202

201-
if (ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level) {
203+
if ((ZEND_OPTIMIZER_PASS_16 & ctx->optimization_level)
204+
&& call_stack[call].try_inline) {
202205
zend_try_inline_call(op_array, fcall, opline, call_stack[call].func);
203206
}
204207
}
205208
call_stack[call].func = NULL;
206209
call_stack[call].opline = NULL;
210+
call_stack[call].try_inline = 0;
207211
break;
208212
case ZEND_FETCH_FUNC_ARG:
209213
case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
@@ -257,17 +261,10 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
257261
}
258262
}
259263
break;
260-
#if 0
261-
case ZEND_SEND_REF:
262-
if (call_stack[call - 1].func) {
263-
/* We won't handle run-time pass by reference */
264-
call_stack[call - 1].opline = NULL;
265-
}
266-
break;
267-
#endif
268264
case ZEND_SEND_UNPACK:
269-
call_stack[call - 1].func = NULL;
270-
call_stack[call - 1].opline = NULL;
265+
case ZEND_SEND_USER:
266+
case ZEND_SEND_ARRAY:
267+
call_stack[call - 1].try_inline = 0;
271268
break;
272269
default:
273270
break;
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Inlining throgh call_user_func()
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
opcache.optimization_level=-1
7+
--SKIPIF--
8+
<?php require_once('skipif.inc'); ?>
9+
--FILE--
10+
<?php
11+
function get_const() {
12+
return 42;
13+
}
14+
15+
function test() {
16+
$x = new stdClass;
17+
var_dump(call_user_func('get_const', $x));
18+
}
19+
20+
test();
21+
?>
22+
--EXPECTF--
23+
int(42)

0 commit comments

Comments
 (0)