Skip to content

Commit

Permalink
Fix cache slot assignment for ASSIGN_OBJ_OP
Browse files Browse the repository at this point in the history
ASSIGN_OBJ_OP stores the cache slot in OP_DATA, so this ended up
overwriting the binop opcode instread.
  • Loading branch information
nikic committed Sep 30, 2021
1 parent 512dfab commit d0860f6
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
14 changes: 14 additions & 0 deletions Zend/tests/assign_obj_op_cache_slot.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
The ASSIGN_OBJ_OP cache slot is on the OP_DATA opcode
--FILE--
<?php
function test($a) {
$b = "x";
$a->$b = 1;
$a->$b &= 1;
var_dump($a->$b);
}
test(new stdClass);
?>
--EXPECT--
int(1)
7 changes: 6 additions & 1 deletion ext/opcache/Optimizer/zend_optimizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -451,11 +451,16 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_PRE_DEC_OBJ:
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ASSIGN_OBJ_OP:
TO_STRING_NOWARN(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
opline->extended_value = alloc_cache_slots(op_array, 3);
break;
case ZEND_ASSIGN_OBJ_OP:
TO_STRING_NOWARN(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
ZEND_ASSERT((opline + 1)->opcode == ZEND_OP_DATA);
(opline + 1)->extended_value = alloc_cache_slots(op_array, 3);
break;
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
TO_STRING_NOWARN(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
Expand Down

0 comments on commit d0860f6

Please sign in to comment.