Skip to content

Commit 12c0375

Browse files
committed
Fix JIT for overridden properties with added hooks
Fixes GH-17376
1 parent 7149362 commit 12c0375

File tree

3 files changed

+50
-6
lines changed

3 files changed

+50
-6
lines changed

Zend/tests/gh17376.phpt

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
--TEST--
2+
GH-17376: Child classes may add hooks to plain properties
3+
--FILE--
4+
<?php
5+
6+
class A {
7+
public $prop = 1;
8+
}
9+
10+
class B extends A {
11+
public $prop {
12+
get => 2;
13+
}
14+
}
15+
16+
function test(A $a) {
17+
var_dump($a->prop);
18+
}
19+
20+
test(new A);
21+
test(new B);
22+
23+
?>
24+
--EXPECT--
25+
int(1)
26+
int(2)

Zend/zend_inheritance.c

-5
Original file line numberDiff line numberDiff line change
@@ -1653,11 +1653,6 @@ void zend_build_properties_info_table(zend_class_entry *ce)
16531653
table, parent_table,
16541654
sizeof(zend_property_info *) * ce->parent->default_properties_count
16551655
);
1656-
1657-
/* Child did not add any new properties, we are done */
1658-
if (ce->default_properties_count == ce->parent->default_properties_count) {
1659-
return;
1660-
}
16611656
}
16621657

16631658
ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {

ext/opcache/jit/zend_jit_ir.c

+24-1
Original file line numberDiff line numberDiff line change
@@ -14291,6 +14291,29 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
1429114291
}
1429214292
}
1429314293
} else {
14294+
/* Child classes may add hooks to property. */
14295+
if (ce_is_instanceof && !(prop_info->flags & ZEND_ACC_FINAL)) {
14296+
int prop_info_offset =
14297+
(((prop_info->offset - (sizeof(zend_object) - sizeof(zval))) / sizeof(zval)) * sizeof(void*));
14298+
ir_ref prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_object, ce)));
14299+
prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(prop_info_ref, offsetof(zend_class_entry, properties_info_table)));
14300+
prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(prop_info_ref, prop_info_offset));
14301+
ir_ref is_same_prop_info = ir_EQ(prop_info_ref, ir_CONST_ADDR(prop_info));
14302+
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
14303+
int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
14304+
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
14305+
if (!exit_addr) {
14306+
return 0;
14307+
}
14308+
ir_GUARD(is_same_prop_info, ir_CONST_ADDR(exit_addr));
14309+
} else {
14310+
ir_ref if_same_prop_info = ir_IF(is_same_prop_info);
14311+
ir_IF_FALSE_cold(if_same_prop_info);
14312+
ir_END_list(slow_inputs);
14313+
ir_IF_TRUE(if_same_prop_info);
14314+
}
14315+
}
14316+
1429414317
prop_ref = ir_ADD_OFFSET(obj_ref, prop_info->offset);
1429514318
prop_addr = ZEND_ADDR_REF_ZVAL(prop_ref);
1429614319
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
@@ -14435,7 +14458,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
1443514458
SET_STACK_REG(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
1443614459
}
1443714460

14438-
if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || !prop_info) {
14461+
if (slow_inputs) {
1443914462
ir_MERGE_list(slow_inputs);
1444014463
jit_SET_EX_OPLINE(jit, opline);
1444114464

0 commit comments

Comments
 (0)