Skip to content

Commit

Permalink
Fix phpGH-15834: Segfault with hook "simple get" cache slot and minim…
Browse files Browse the repository at this point in the history
…al JIT

The FETCH_OBJ_R VM handler has an optimization that directly enters into
a hook if it is a simpler getter hook. This is not compatible with the
minimal JIT because the minimal JIT will try to continue executing the
opcodes after the FETCH_OBJ_R.
To solve this, we check whether the opcode is still the expected one
after the execution of the VM handler. If it is not, we know that we are
going to execute a simple hook. In that case, exit to the VM.
  • Loading branch information
nielsdos committed Feb 23, 2025
1 parent 2c911e4 commit 8a896ef
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
17 changes: 17 additions & 0 deletions ext/opcache/jit/zend_jit.c
Original file line number Diff line number Diff line change
Expand Up @@ -2709,6 +2709,23 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
/* We skip over the DO_FCALL, so decrement call_level ourselves. */
call_level--;
}
break;
case ZEND_FETCH_OBJ_R:
if (!zend_jit_handler(&ctx, opline,
zend_may_throw(opline, ssa_op, op_array, ssa))) {
goto jit_failure;
}

/* If a simple hook is called, exit to the VM. */
ir_ref if_hook_enter = ir_IF(jit_CMP_IP(jit, IR_EQ, opline + 1));
ir_IF_FALSE(if_hook_enter);
if (GCC_GLOBAL_REGS || zend_jit_vm_kind == ZEND_VM_KIND_HYBRID) {
ir_TAILCALL(IR_VOID, ir_LOAD_A(jit_IP(jit)));
} else {
ir_RETURN(ir_CONST_I32(1)); /* ZEND_VM_ENTER */
}
ir_IF_TRUE(if_hook_enter);

break;
default:
if (!zend_jit_handler(&ctx, opline,
Expand Down
23 changes: 23 additions & 0 deletions ext/opcache/tests/jit/gh15834.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
--TEST--
GH-15834 (Segfault with hook "simple get" cache slot and minimal JIT)
--EXTENSIONS--
opcache
--INI--
opcache.jit=1111
--FILE--
<?php
class A {
public $_prop = 1;
public $prop {
get => $this->_prop;
}
}

$a = new A;
for ($i=0;$i<5;$i++) {
echo $a->prop;
$a->_prop++;
}
?>
--EXPECT--
12345

0 comments on commit 8a896ef

Please sign in to comment.