Commit cfe77b82a65 for php

commit cfe77b82a65a4750e32b1ca1ccfad90a32190fdb
Author: waroad <dohanam2@illinois.edu>
Date:   Sun Oct 18 04:33:18 2026 -0500

    JIT: Fix function JIT level 1 crash on FETCH_OBJ_FUNC_ARG of a hooked property

    Assisted-by: Claude

    Closes GH-24402.

diff --git a/NEWS b/NEWS
index 12d15e699f1..9336ed394c3 100644
--- a/NEWS
+++ b/NEWS
@@ -83,6 +83,8 @@ PHP                                                                        NEWS
     reference check). (ndossche)
   . Fixed bug GH-24437 (JIT: Fix OP_DATA read from an unwritten slot in
     zend_jit_assign_dim_op()). (waroad)
+  . Fixed bug GH-24398 (JIT: minimal JIT segfault when a hooked property is
+    passed to a run-time-resolved function). (waroad)

 - PDO:
   . Fixed invalid ATTR_ORACLE_NULLS values being accepted and truncated.
diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c
index fa729dfa2c4..679b7db269f 100644
--- a/ext/opcache/jit/zend_jit.c
+++ b/ext/opcache/jit/zend_jit.c
@@ -2739,6 +2739,8 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op
 						call_level--;
 					}
 					break;
+				/* FETCH_OBJ_FUNC_ARG may dispatch into the FETCH_OBJ_R handler (if sent by value). */
+				case ZEND_FETCH_OBJ_FUNC_ARG:
 				case ZEND_FETCH_OBJ_R:
 					if (!zend_jit_handler(&ctx, opline,
 						zend_may_throw(opline, ssa_op, op_array, ssa))) {
diff --git a/ext/opcache/jit/zend_jit_trace.c b/ext/opcache/jit/zend_jit_trace.c
index b179cced8d2..7c218a62306 100644
--- a/ext/opcache/jit/zend_jit_trace.c
+++ b/ext/opcache/jit/zend_jit_trace.c
@@ -333,6 +333,8 @@ static int zend_jit_trace_may_exit(const zend_op_array *op_array, const zend_op
 			// TODO: recompilation may change target ???
 			return 0;
 #endif
+		/* FETCH_OBJ_FUNC_ARG may dispatch into the FETCH_OBJ_R handler (if sent by value). */
+		case ZEND_FETCH_OBJ_FUNC_ARG:
 		case ZEND_FETCH_OBJ_R:
 			if (opline->op2_type == IS_CONST) {
 				const zend_class_entry *ce = opline->op1_type == IS_UNUSED ? op_array->scope : NULL;
diff --git a/ext/opcache/tests/jit/gh24398.phpt b/ext/opcache/tests/jit/gh24398.phpt
new file mode 100644
index 00000000000..948ac8f1b26
--- /dev/null
+++ b/ext/opcache/tests/jit/gh24398.phpt
@@ -0,0 +1,36 @@
+--TEST--
+GH-24398: Function JIT level 1 crash on FETCH_OBJ_FUNC_ARG of a hooked property
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.jit_buffer_size=64M
+opcache.jit=1201
+--EXTENSIONS--
+opcache
+--FILE--
+<?php
+
+class C {
+    public $prop {
+        get => 5;
+    }
+}
+
+if (true) {
+    function g($x) {
+        return $x;
+    }
+}
+
+function f($o) {
+    return g($o->prop);
+}
+
+$c = new C();
+var_dump(f($c));
+var_dump(f($c));
+
+?>
+--EXPECT--
+int(5)
+int(5)
diff --git a/ext/opcache/tests/jit/gh24398_002.phpt b/ext/opcache/tests/jit/gh24398_002.phpt
new file mode 100644
index 00000000000..b8b0c0481c7
--- /dev/null
+++ b/ext/opcache/tests/jit/gh24398_002.phpt
@@ -0,0 +1,44 @@
+--TEST--
+GH-24398 (tracing): FETCH_OBJ_FUNC_ARG of a hooked property with unknown send mode
+--INI--
+opcache.enable=1
+opcache.enable_cli=1
+opcache.jit_buffer_size=64M
+opcache.jit=tracing
+opcache.jit_hot_loop=1
+--EXTENSIONS--
+opcache
+--FILE--
+<?php
+
+class A {
+    public $prop = 5;
+}
+
+class B {
+    public $prop {
+        get => 5;
+    }
+}
+
+if (true) {
+    function g($x) {
+        return $x;
+    }
+}
+
+function f($o) {
+    // The named argument leaves the send mode unknown to the tracing JIT,
+    // so FETCH_OBJ_FUNC_ARG is executed by the VM handler.
+    return g(x: $o->prop);
+}
+
+$sum = 0;
+foreach ([new A, new A, new A, new B, new B, new B] as $o) {
+    $sum += f($o);
+}
+var_dump($sum);
+
+?>
+--EXPECT--
+int(30)