Skip to content

Commit

Permalink
Fix GH-8140: Wrong first class callable by name optimization
Browse files Browse the repository at this point in the history
When optimizing by name function calls, we must not replace
`CALLABLE_CONVERT` opcodes, but have to keep them.

Closes GH-8144.
  • Loading branch information
cmb69 committed Feb 24, 2022
1 parent 5d907df commit 33cd61c
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 2 deletions.
1 change: 1 addition & 0 deletions NEWS
Expand Up @@ -9,6 +9,7 @@ PHP NEWS
variables. (ilutov)
. Fixed bug GH-7958 (Nested CallbackFilterIterator is leaking memory). (cmb)
. Fixed bug GH-8074 (Wrong type inference of range() result). (cmb)
. Fixed bug GH-8140 (Wrong first class callable by name optimization). (cmb)

- GD:
. Fixed libpng warning when loading interlaced images. (Brett)
Expand Down
8 changes: 6 additions & 2 deletions Zend/Optimizer/optimize_func_calls.c
Expand Up @@ -200,14 +200,18 @@ void zend_optimize_func_calls(zend_op_array *op_array, zend_optimizer_ctx *ctx)
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
literal_dtor(&ZEND_OP2_LITERAL(fcall));
fcall->op2.constant = fcall->op2.constant + 1;
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
}
} else if (fcall->opcode == ZEND_INIT_NS_FCALL_BY_NAME) {
fcall->opcode = ZEND_INIT_FCALL;
fcall->op1.num = zend_vm_calc_used_stack(fcall->extended_value, call_stack[call].func);
literal_dtor(&op_array->literals[fcall->op2.constant]);
literal_dtor(&op_array->literals[fcall->op2.constant + 2]);
fcall->op2.constant = fcall->op2.constant + 1;
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
if (opline->opcode != ZEND_CALLABLE_CONVERT) {
opline->opcode = zend_get_call_op(fcall, call_stack[call].func);
}
} else if (fcall->opcode == ZEND_INIT_STATIC_METHOD_CALL
|| fcall->opcode == ZEND_INIT_METHOD_CALL
|| fcall->opcode == ZEND_NEW) {
Expand Down
16 changes: 16 additions & 0 deletions ext/opcache/tests/opt/gh8140a.phpt
@@ -0,0 +1,16 @@
--TEST--
GH-8140 (Wrong first class callable by name optimization)
--FILE--
<?php
namespace Test;

function greeter(string $name) {
echo "Hello, ${name}!";
}

$mycallable = greeter(...);

$mycallable("world");
?>
--EXPECT--
Hello, world!
14 changes: 14 additions & 0 deletions ext/opcache/tests/opt/gh8140b.phpt
@@ -0,0 +1,14 @@
--TEST--
GH-8140 (Wrong first class callable by name optimization)
--FILE--
<?php
$mycallable = greeter(...);

function greeter(string $name) {
echo "Hello, ${name}!";
}

$mycallable("world");
?>
--EXPECT--
Hello, world!

0 comments on commit 33cd61c

Please sign in to comment.