@@ -11995,12 +11995,16 @@ static int zend_jit_fetch_obj(dasm_State **Dst,
11995
11995
if (!prop_info && trace_ce && (trace_ce->ce_flags & ZEND_ACC_IMMUTABLE)) {
11996
11996
prop_info = zend_get_known_property_info(trace_ce, Z_STR_P(member), opline->op1_type == IS_UNUSED, op_array->filename);
11997
11997
if (prop_info) {
11998
+ ce = trace_ce;
11999
+ ce_is_instanceof = 0;
11998
12000
if (!(op1_info & MAY_BE_CLASS_GUARD)) {
11999
12001
if (!zend_jit_class_guard(Dst, opline, trace_ce)) {
12000
12002
return 0;
12001
12003
}
12002
12004
if (ssa->var_info && ssa_op->op1_use >= 0) {
12003
12005
ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD;
12006
+ ssa->var_info[ssa_op->op1_use].ce = ce;
12007
+ ssa->var_info[ssa_op->op1_use].is_instanceof = ce_is_instanceof;
12004
12008
}
12005
12009
}
12006
12010
}
@@ -12322,6 +12326,7 @@ static int zend_jit_assign_obj(dasm_State **Dst,
12322
12326
zend_jit_addr res_addr = 0;
12323
12327
zend_jit_addr this_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, offsetof(zend_execute_data, This));
12324
12328
zend_jit_addr prop_addr;
12329
+ zend_bool needs_slow_path = 0;
12325
12330
12326
12331
if (RETURN_VALUE_USED(opline)) {
12327
12332
res_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FP, opline->result.var);
@@ -12399,12 +12404,21 @@ static int zend_jit_assign_obj(dasm_State **Dst,
12399
12404
}
12400
12405
if (ssa->var_info && ssa_op->op1_use >= 0) {
12401
12406
ssa->var_info[ssa_op->op1_use].type |= MAY_BE_CLASS_GUARD;
12407
+ ssa->var_info[ssa_op->op1_use].ce = ce;
12408
+ ssa->var_info[ssa_op->op1_use].is_instanceof = ce_is_instanceof;
12409
+ }
12410
+ if (ssa->var_info && ssa_op->op1_def >= 0) {
12411
+ ssa->var_info[ssa_op->op1_def].type |= MAY_BE_CLASS_GUARD;
12412
+ ssa->var_info[ssa_op->op1_def].ce = ce;
12413
+ ssa->var_info[ssa_op->op1_def].is_instanceof = ce_is_instanceof;
12402
12414
}
12403
12415
}
12404
12416
}
12405
12417
}
12406
12418
12407
12419
if (!prop_info) {
12420
+ needs_slow_path = 1;
12421
+
12408
12422
| mov r0, EX->run_time_cache
12409
12423
| mov r2, aword [r0 + opline->extended_value]
12410
12424
| cmp r2, aword [FCARG1a + offsetof(zend_object, ce)]
@@ -12464,17 +12478,20 @@ static int zend_jit_assign_obj(dasm_State **Dst,
12464
12478
}
12465
12479
} else {
12466
12480
prop_addr = ZEND_ADDR_MEM_ZVAL(ZREG_FCARG1a, prop_info->offset);
12467
- // Undefined property with magic __get()/__set()
12468
- if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
12469
- int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
12470
- const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12481
+ if (!ce || ce_is_instanceof || !(ce->ce_flags & ZEND_ACC_IMMUTABLE) || ce->__get || ce->__set) {
12482
+ // Undefined property with magic __get()/__set()
12483
+ if (JIT_G(trigger) == ZEND_JIT_ON_HOT_TRACE) {
12484
+ int32_t exit_point = zend_jit_trace_get_exit_point(opline, ZEND_JIT_EXIT_TO_VM);
12485
+ const void *exit_addr = zend_jit_trace_get_exit_addr(exit_point);
12471
12486
12472
- if (!exit_addr) {
12473
- return 0;
12487
+ if (!exit_addr) {
12488
+ return 0;
12489
+ }
12490
+ | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, &exit_addr
12491
+ } else {
12492
+ | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, >5
12493
+ needs_slow_path = 1;
12474
12494
}
12475
- | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, &exit_addr
12476
- } else {
12477
- | IF_TYPE byte [FCARG1a + prop_info->offset + 8], IS_UNDEF, >5
12478
12495
}
12479
12496
if (ZEND_TYPE_IS_SET(prop_info->type)) {
12480
12497
uint32_t info = val_info;
@@ -12536,7 +12553,7 @@ static int zend_jit_assign_obj(dasm_State **Dst,
12536
12553
}
12537
12554
}
12538
12555
12539
- if (!prop_info || JIT_G(trigger) != ZEND_JIT_ON_HOT_TRACE ) {
12556
+ if (needs_slow_path ) {
12540
12557
|.cold_code
12541
12558
|5:
12542
12559
| SET_EX_OPLINE opline, r0
0 commit comments