Skip to content

Commit ef7a0e6

Browse files
committed
Fix tssa ce type inference
1 parent e6f42c1 commit ef7a0e6

File tree

5 files changed

+41
-23
lines changed

5 files changed

+41
-23
lines changed

Zend/Optimizer/zend_inference.c

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2368,7 +2368,7 @@ static uint32_t zend_convert_type_declaration_mask(uint32_t type_mask) {
23682368
return result_mask;
23692369
}
23702370

2371-
static uint32_t zend_convert_type(const zend_script *script, zend_type type, zend_class_entry **pce)
2371+
static uint32_t zend_convert_type(const zend_script *script, zend_type type, zend_class_entry **pce, zend_string *filename)
23722372
{
23732373
if (pce) {
23742374
*pce = NULL;
@@ -2387,7 +2387,7 @@ static uint32_t zend_convert_type(const zend_script *script, zend_type type, zen
23872387
if (ZEND_TYPE_HAS_NAME(type)) {
23882388
zend_string *lcname = zend_string_tolower(ZEND_TYPE_NAME(type));
23892389
// TODO: Pass through op_array.
2390-
*pce = zend_optimizer_get_class_entry(script, NULL, lcname);
2390+
*pce = zend_optimizer_get_class_entry_ex(script, NULL, lcname, filename);
23912391
zend_string_release_ex(lcname, 0);
23922392
}
23932393
}
@@ -2398,9 +2398,14 @@ static uint32_t zend_convert_type(const zend_script *script, zend_type type, zen
23982398
return tmp;
23992399
}
24002400

2401+
ZEND_API uint32_t zend_fetch_arg_info_type_ex(const zend_script *script, const zend_arg_info *arg_info, zend_class_entry **pce, zend_string *filename)
2402+
{
2403+
return zend_convert_type(script, arg_info->type, pce, filename);
2404+
}
2405+
24012406
ZEND_API uint32_t zend_fetch_arg_info_type(const zend_script *script, const zend_arg_info *arg_info, zend_class_entry **pce)
24022407
{
2403-
return zend_convert_type(script, arg_info->type, pce);
2408+
return zend_fetch_arg_info_type_ex(script, arg_info, pce, NULL);
24042409
}
24052410

24062411
static const zend_property_info *lookup_prop_info(const zend_class_entry *ce, zend_string *name, zend_class_entry *scope) {
@@ -2489,7 +2494,7 @@ static const zend_property_info *zend_fetch_static_prop_info(const zend_script *
24892494
return prop_info;
24902495
}
24912496

2492-
static uint32_t zend_fetch_prop_type(const zend_script *script, const zend_property_info *prop_info, zend_class_entry **pce)
2497+
static uint32_t zend_fetch_prop_type(const zend_script *script, const zend_property_info *prop_info, zend_class_entry **pce, zend_string *filename)
24932498
{
24942499
if (!prop_info) {
24952500
if (pce) {
@@ -2498,7 +2503,7 @@ static uint32_t zend_fetch_prop_type(const zend_script *script, const zend_prope
24982503
return MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF | MAY_BE_RC1 | MAY_BE_RCN;
24992504
}
25002505

2501-
return zend_convert_type(script, prop_info->type, pce);
2506+
return zend_convert_type(script, prop_info->type, pce, NULL);
25022507
}
25032508

25042509
static bool result_may_be_separated(zend_ssa *ssa, zend_ssa_op *ssa_op)
@@ -2748,7 +2753,7 @@ static zend_always_inline zend_result _zend_update_type_info(
27482753
if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
27492754
prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
27502755
orig = t1;
2751-
t1 = zend_fetch_prop_type(script, prop_info, NULL);
2756+
t1 = zend_fetch_prop_type(script, prop_info, NULL, op_array->filename);
27522757
t2 = OP1_DATA_INFO();
27532758
} else if (opline->opcode == ZEND_ASSIGN_DIM_OP) {
27542759
if (t1 & MAY_BE_ARRAY_OF_REF) {
@@ -2759,7 +2764,7 @@ static zend_always_inline zend_result _zend_update_type_info(
27592764
t2 = OP1_DATA_INFO();
27602765
} else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) {
27612766
prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline);
2762-
t1 = zend_fetch_prop_type(script, prop_info, NULL);
2767+
t1 = zend_fetch_prop_type(script, prop_info, NULL, op_array->filename);
27632768
t2 = OP1_DATA_INFO();
27642769
} else {
27652770
if (t1 & MAY_BE_REF) {
@@ -2821,7 +2826,7 @@ static zend_always_inline zend_result _zend_update_type_info(
28212826
} else if (opline->opcode == ZEND_ASSIGN_OBJ_OP) {
28222827
/* The return value must also satisfy the property type */
28232828
if (prop_info) {
2824-
t1 = zend_fetch_prop_type(script, prop_info, &ce);
2829+
t1 = zend_fetch_prop_type(script, prop_info, &ce, op_array->filename);
28252830
if ((t1 & (MAY_BE_LONG|MAY_BE_DOUBLE)) == MAY_BE_LONG
28262831
&& (tmp & (MAY_BE_LONG|MAY_BE_DOUBLE)) == MAY_BE_DOUBLE) {
28272832
/* DOUBLE may be auto-converted to LONG */
@@ -2840,7 +2845,7 @@ static zend_always_inline zend_result _zend_update_type_info(
28402845
} else if (opline->opcode == ZEND_ASSIGN_STATIC_PROP_OP) {
28412846
/* The return value must also satisfy the property type */
28422847
if (prop_info) {
2843-
t1 = zend_fetch_prop_type(script, prop_info, &ce);
2848+
t1 = zend_fetch_prop_type(script, prop_info, &ce, op_array->filename);
28442849
if ((t1 & (MAY_BE_LONG|MAY_BE_DOUBLE)) == MAY_BE_LONG
28452850
&& (tmp & (MAY_BE_LONG|MAY_BE_DOUBLE)) == MAY_BE_DOUBLE) {
28462851
/* DOUBLE may be auto-converted to LONG */
@@ -3037,7 +3042,7 @@ static zend_always_inline zend_result _zend_update_type_info(
30373042
if (ssa_op->result_def >= 0) {
30383043
// TODO: If there is no __set we might do better
30393044
tmp = zend_fetch_prop_type(script,
3040-
zend_fetch_prop_info(op_array, ssa, opline, ssa_op), &ce);
3045+
zend_fetch_prop_info(op_array, ssa, opline, ssa_op), &ce, op_array->filename);
30413046
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
30423047
if (ce) {
30433048
UPDATE_SSA_OBJ_TYPE(ce, 1, ssa_op->result_def);
@@ -3307,7 +3312,7 @@ static zend_always_inline zend_result _zend_update_type_info(
33073312
zend_arg_info *arg_info = &op_array->arg_info[opline->op1.num-1];
33083313

33093314
ce = NULL;
3310-
tmp = zend_fetch_arg_info_type(script, arg_info, &ce);
3315+
tmp = zend_fetch_arg_info_type_ex(script, arg_info, &ce, op_array->filename);
33113316
if (ZEND_ARG_SEND_MODE(arg_info)) {
33123317
tmp |= MAY_BE_REF;
33133318
ce = NULL;
@@ -3780,7 +3785,7 @@ static zend_always_inline zend_result _zend_update_type_info(
37803785
}
37813786
if (opline->op1_type == IS_UNUSED || (t1 & MAY_BE_OBJECT)) {
37823787
const zend_property_info *prop_info = zend_fetch_prop_info(op_array, ssa, opline, ssa_op);
3783-
tmp |= zend_fetch_prop_type(script, prop_info, &ce);
3788+
tmp |= zend_fetch_prop_type(script, prop_info, &ce, op_array->filename);
37843789
if (opline->opcode != ZEND_FETCH_OBJ_R && opline->opcode != ZEND_FETCH_OBJ_IS) {
37853790
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
37863791
if ((opline->extended_value & ZEND_FETCH_OBJ_FLAGS) == ZEND_FETCH_DIM_WRITE) {
@@ -3822,7 +3827,7 @@ static zend_always_inline zend_result _zend_update_type_info(
38223827
case ZEND_FETCH_STATIC_PROP_UNSET:
38233828
case ZEND_FETCH_STATIC_PROP_FUNC_ARG:
38243829
tmp = zend_fetch_prop_type(script,
3825-
zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce);
3830+
zend_fetch_static_prop_info(script, op_array, ssa, opline), &ce, op_array->filename);
38263831
if (opline->opcode != ZEND_FETCH_STATIC_PROP_R
38273832
&& opline->opcode != ZEND_FETCH_STATIC_PROP_IS) {
38283833
tmp |= MAY_BE_REF | MAY_BE_INDIRECT;
@@ -3914,7 +3919,7 @@ static zend_always_inline zend_result _zend_update_type_info(
39143919
UPDATE_SSA_TYPE(MAY_BE_RC1|MAY_BE_RCN|MAY_BE_ANY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY, ssa_op->result_def);
39153920
break;
39163921
}
3917-
UPDATE_SSA_TYPE(zend_convert_type(script, cc->type, &ce), ssa_op->result_def);
3922+
UPDATE_SSA_TYPE(zend_convert_type(script, cc->type, &ce, op_array->filename), ssa_op->result_def);
39183923
if (ce) {
39193924
UPDATE_SSA_OBJ_TYPE(ce, /* is_instanceof */ true, ssa_op->result_def);
39203925
}
@@ -3962,7 +3967,7 @@ static zend_always_inline zend_result _zend_update_type_info(
39623967
ce = NULL;
39633968
} else {
39643969
zend_arg_info *ret_info = op_array->arg_info - 1;
3965-
tmp = zend_fetch_arg_info_type(script, ret_info, &ce);
3970+
tmp = zend_fetch_arg_info_type_ex(script, ret_info, &ce, op_array->filename);
39663971
if ((tmp & MAY_BE_NULL) && opline->op1_type == IS_CV) {
39673972
tmp |= MAY_BE_UNDEF;
39683973
}
@@ -4018,7 +4023,7 @@ static zend_always_inline zend_result _zend_update_type_info(
40184023
if (ssa_op->result_def >= 0) {
40194024
const zend_property_info *prop_info = zend_fetch_static_prop_info(script, op_array, ssa, opline);
40204025
zend_class_entry *prop_ce;
4021-
tmp = zend_fetch_prop_type(script, prop_info, &prop_ce);
4026+
tmp = zend_fetch_prop_type(script, prop_info, &prop_ce, op_array->filename);
40224027
/* Internal objects may result in essentially anything. */
40234028
if (tmp & MAY_BE_OBJECT) {
40244029
goto unknown_opcode;
@@ -4516,6 +4521,7 @@ uint32_t zend_get_return_info_from_signature_only(
45164521
(use_tentative_return_info || !ZEND_ARG_TYPE_IS_TENTATIVE(func->common.arg_info - 1))
45174522
) {
45184523
zend_arg_info *ret_info = func->common.arg_info - 1;
4524+
// FIXME: Script file check?
45194525
type = zend_fetch_arg_info_type(script, ret_info, ce);
45204526
*ce_is_instanceof = ce != NULL;
45214527
} else {

Zend/Optimizer/zend_inference.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,8 @@ ZEND_API bool zend_inference_propagate_range(const zend_op_array *op_array, cons
227227

228228
ZEND_API uint32_t zend_fetch_arg_info_type(
229229
const zend_script *script, const zend_arg_info *arg_info, zend_class_entry **pce);
230+
ZEND_API uint32_t zend_fetch_arg_info_type_ex(
231+
const zend_script *script, const zend_arg_info *arg_info, zend_class_entry **pce, zend_string *filename);
230232
ZEND_API void zend_init_func_return_info(
231233
const zend_op_array *op_array, const zend_script *script, zend_ssa_var_info *ret);
232234
uint32_t zend_get_return_info_from_signature_only(

Zend/Optimizer/zend_optimizer.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -830,15 +830,18 @@ static bool zend_optimizer_ignore_function(zval *fbc_zv, zend_string *filename)
830830
}
831831
}
832832

833-
zend_class_entry *zend_optimizer_get_class_entry(
834-
const zend_script *script, const zend_op_array *op_array, zend_string *lcname) {
833+
zend_class_entry *zend_optimizer_get_class_entry_ex(
834+
const zend_script *script, const zend_op_array *op_array, zend_string *lcname, zend_string *filename) {
835835
zend_class_entry *ce = script ? zend_hash_find_ptr(&script->class_table, lcname) : NULL;
836836
if (ce) {
837837
return ce;
838838
}
839839

840+
if (!filename && op_array) {
841+
filename = op_array->filename;
842+
}
840843
zval *ce_zv = zend_hash_find(CG(class_table), lcname);
841-
if (ce_zv && !zend_optimizer_ignore_class(ce_zv, op_array ? op_array->filename : NULL)) {
844+
if (ce_zv && !zend_optimizer_ignore_class(ce_zv, filename)) {
842845
return Z_PTR_P(ce_zv);
843846
}
844847

@@ -849,6 +852,11 @@ zend_class_entry *zend_optimizer_get_class_entry(
849852
return NULL;
850853
}
851854

855+
zend_class_entry *zend_optimizer_get_class_entry(
856+
const zend_script *script, const zend_op_array *op_array, zend_string *lcname) {
857+
return zend_optimizer_get_class_entry_ex(script, op_array, lcname, NULL);
858+
}
859+
852860
zend_class_entry *zend_optimizer_get_class_entry_from_op1(
853861
const zend_script *script, const zend_op_array *op_array, const zend_op *opline) {
854862
if (opline->op1_type == IS_CONST) {

Zend/Optimizer/zend_optimizer_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ bool zend_optimizer_replace_by_const(zend_op_array *op_array,
103103
zend_op *zend_optimizer_get_loop_var_def(const zend_op_array *op_array, zend_op *free_opline);
104104
zend_class_entry *zend_optimizer_get_class_entry(
105105
const zend_script *script, const zend_op_array *op_array, zend_string *lcname);
106+
zend_class_entry *zend_optimizer_get_class_entry_ex(
107+
const zend_script *script, const zend_op_array *op_array, zend_string *lcname, zend_string *filename);
106108
zend_class_entry *zend_optimizer_get_class_entry_from_op1(
107109
const zend_script *script, const zend_op_array *op_array, const zend_op *opline);
108110
const zend_class_constant *zend_fetch_class_const_info(

ext/opcache/jit/zend_jit_trace.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1683,7 +1683,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
16831683
if (op_array->arg_info && i < trace_buffer[1].opline - op_array->opcodes) {
16841684
zend_arg_info *arg_info = &op_array->arg_info[i];
16851685
zend_class_entry *ce;
1686-
uint32_t tmp = zend_fetch_arg_info_type(script, arg_info, &ce);
1686+
uint32_t tmp = zend_fetch_arg_info_type_ex(script, arg_info, &ce, op_array->filename);
16871687

16881688
if (ZEND_ARG_SEND_MODE(arg_info)) {
16891689
tmp |= MAY_BE_REF;
@@ -2144,7 +2144,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
21442144
arg_info = &frame->call->func->op_array.arg_info[opline->op2.num - 1];
21452145
if (ZEND_TYPE_IS_SET(arg_info->type)) {
21462146
zend_class_entry *ce;
2147-
uint32_t tmp = zend_fetch_arg_info_type(script, arg_info, &ce);
2147+
uint32_t tmp = zend_fetch_arg_info_type_ex(script, arg_info, &ce, op_array->filename);
21482148
info &= tmp;
21492149
if (!info) {
21502150
break;
@@ -2480,7 +2480,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
24802480
if (op_array->arg_info) {
24812481
zend_arg_info *arg_info = &op_array->arg_info[i];
24822482
zend_class_entry *ce;
2483-
uint32_t tmp = zend_fetch_arg_info_type(script, arg_info, &ce);
2483+
uint32_t tmp = zend_fetch_arg_info_type_ex(script, arg_info, &ce, op_array->filename);
24842484

24852485
if (ZEND_ARG_SEND_MODE(arg_info)) {
24862486
tmp |= MAY_BE_REF;
@@ -2647,7 +2647,7 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
26472647
zend_class_entry *ce;
26482648
const zend_function *func = p->func;
26492649
zend_arg_info *ret_info = func->common.arg_info - 1;
2650-
uint32_t ret_type = zend_fetch_arg_info_type(NULL, ret_info, &ce);
2650+
uint32_t ret_type = zend_fetch_arg_info_type_ex(NULL, ret_info, &ce, op_array->filename);
26512651

26522652
ssa_var_info[ssa_ops[idx-1].result_def].type &= ret_type;
26532653
}

0 commit comments

Comments
 (0)