Skip to content

Commit

Permalink
Fix JIT for overridden properties with added hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
iluuu1994 committed Jan 8, 2025
1 parent 7149362 commit 2f30e3d
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 6 deletions.
26 changes: 26 additions & 0 deletions Zend/tests/gh17376.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
--TEST--
GH-17376: Child classes may add hooks to plain properties
--FILE--
<?php

class A {
public $prop = 1;
}

class B extends A {
public $prop {
get => 2;
}
}

function test(A $a) {
var_dump($a->prop);
}

test(new A);
test(new B);

?>
--EXPECT--
int(1)
int(2)
5 changes: 0 additions & 5 deletions Zend/zend_inheritance.c
Original file line number Diff line number Diff line change
Expand Up @@ -1653,11 +1653,6 @@ void zend_build_properties_info_table(zend_class_entry *ce)
table, parent_table,
sizeof(zend_property_info *) * ce->parent->default_properties_count
);

/* Child did not add any new properties, we are done */
if (ce->default_properties_count == ce->parent->default_properties_count) {
return;
}
}

ZEND_HASH_MAP_FOREACH_PTR(&ce->properties_info, prop) {
Expand Down
25 changes: 24 additions & 1 deletion ext/opcache/jit/zend_jit_ir.c
Original file line number Diff line number Diff line change
Expand Up @@ -14291,8 +14291,31 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
}
}
} else {
/* Child classes may add hooks to property. */
if (ce_is_instanceof && !(prop_info->flags & ZEND_ACC_FINAL)) {
int prop_info_offset =
(((prop_info->offset - (sizeof(zend_object) - sizeof(zval))) / sizeof(zval)) * sizeof(void*));
ir_ref prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(obj_ref, offsetof(zend_object, ce)));
prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(prop_info_ref, offsetof(zend_class_entry, properties_info_table)));
prop_info_ref = ir_LOAD_A(ir_ADD_OFFSET(prop_info_ref, prop_info_offset));
ir_ref is_same_prop_info = ir_EQ(prop_info_ref, ir_CONST_ADDR(prop_info));
if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
if (!exit_addr) {
return 0;
}
ir_GUARD(is_same_prop_info, ir_CONST_ADDR(exit_addr));
} else {
ir_ref if_same_prop_info = ir_IF(is_same_prop_info);
ir_IF_FALSE_cold(if_same_prop_info);
ir_END_list(slow_inputs);
ir_IF_TRUE(if_same_prop_info);
}
}
prop_ref = ir_ADD_OFFSET(obj_ref, prop_info->offset);
prop_addr = ZEND_ADDR_REF_ZVAL(prop_ref);

if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
if (opline->opcode == ZEND_FETCH_OBJ_W || !(res_info & MAY_BE_GUARD) || !JIT_G(current_frame)) {
/* perform IS_UNDEF check only after result type guard (during deoptimization) */
Expand Down Expand Up @@ -14435,7 +14458,7 @@ static int zend_jit_fetch_obj(zend_jit_ctx *jit,
SET_STACK_REG(JIT_G(current_frame)->stack, EX_VAR_TO_NUM(opline->op1.var), ZREG_NONE);
}

if (JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE || !prop_info) {
if (slow_inputs) {
ir_MERGE_list(slow_inputs);
jit_SET_EX_OPLINE(jit, opline);

Expand Down

0 comments on commit 2f30e3d

Please sign in to comment.