Skip to content

Commit 34534cf

Browse files
committed
Use _IS_ERROR as placeholder, improve type inference
1 parent 510a7ce commit 34534cf

File tree

4 files changed

+43
-8
lines changed

4 files changed

+43
-8
lines changed

Zend/Optimizer/zend_inference.c

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,7 +2105,9 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
21052105
} else if (HT_IS_PACKED(ht)) {
21062106
tmp |= MAY_BE_ARRAY_PACKED;
21072107
ZEND_HASH_PACKED_FOREACH_VAL(ht, val) {
2108-
tmp |= 1 << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT);
2108+
if (Z_TYPE_P(val) != _IS_ERROR) {
2109+
tmp |= 1 << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT);
2110+
}
21092111
} ZEND_HASH_FOREACH_END();
21102112
} else {
21112113
ZEND_HASH_MAP_FOREACH_STR_KEY_VAL(ht, str, val) {
@@ -2114,7 +2116,9 @@ ZEND_API uint32_t ZEND_FASTCALL zend_array_type_info(const zval *zv)
21142116
} else {
21152117
tmp |= MAY_BE_ARRAY_NUMERIC_HASH;
21162118
}
2117-
tmp |= 1 << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT);
2119+
if (Z_TYPE_P(val) != _IS_ERROR) {
2120+
tmp |= 1 << (Z_TYPE_P(val) + MAY_BE_ARRAY_SHIFT);
2121+
}
21182122
} ZEND_HASH_FOREACH_END();
21192123
}
21202124
return tmp;
@@ -3443,12 +3447,36 @@ static zend_always_inline zend_result _zend_update_type_info(
34433447
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
34443448
}
34453449
break;
3446-
case ZEND_ARRAY_DUP:
3447-
case ZEND_ARRAY_SET_PLACEHOLDER:
3448-
/* FIXME: This can of course be more specific. However, one challenge
3449-
* will be removing filled NULL slots from type inference. */
3450-
UPDATE_SSA_TYPE(MAY_BE_RC1|MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_ANY|MAY_BE_ARRAY_OF_ANY, ssa_op->result_def);
3450+
case ZEND_ARRAY_DUP: {
3451+
ZEND_ASSERT(opline->op1_type == IS_CONST);
3452+
zval *template = CRT_CONSTANT_EX(op_array, opline, opline->op1);
3453+
uint32_t tmp = zend_array_type_info(template);
3454+
tmp &= ~MAY_BE_RCN;
3455+
tmp |= MAY_BE_RC1;
3456+
if (!(tmp & MAY_BE_ARRAY_OF_ANY)) {
3457+
tmp |= MAY_BE_ARRAY_OF_ANY;
3458+
}
3459+
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
34513460
break;
3461+
}
3462+
case ZEND_ARRAY_SET_PLACEHOLDER: {
3463+
// FIXME: op1 RC inference
3464+
uint32_t tmp = RES_USE_INFO();
3465+
if ((tmp & MAY_BE_ARRAY_OF_ANY) == MAY_BE_ARRAY_OF_ANY) {
3466+
ZEND_ASSERT(ssa_op->result_use != -1);
3467+
zend_op *dup_op = op_array->opcodes + ssa_vars[ssa_op->result_use].definition;
3468+
if (dup_op->opcode == ZEND_ARRAY_DUP) {
3469+
zval *template = CRT_CONSTANT_EX(op_array, dup_op, dup_op->op1);
3470+
tmp = zend_array_type_info(template);
3471+
tmp &= ~MAY_BE_RCN;
3472+
tmp |= MAY_BE_RC1;
3473+
}
3474+
}
3475+
uint32_t dim_type = ((tmp & MAY_BE_ARRAY_KEY_LONG) ? MAY_BE_LONG : 0) | ((tmp & MAY_BE_ARRAY_KEY_STRING) ? MAY_BE_STRING : 0);
3476+
tmp |= assign_dim_array_result_type(tmp, dim_type, t1, IS_CONST);
3477+
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
3478+
break;
3479+
}
34523480
case ZEND_ADD_ARRAY_UNPACK:
34533481
tmp = ssa_var_info[ssa_op->result_use].type;
34543482
ZEND_ASSERT(tmp & MAY_BE_ARRAY);

Zend/zend_compile.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9860,7 +9860,8 @@ static bool zend_try_ct_eval_array(zval *result, zend_ast *ast, bool allow_templ
98609860
zval tmp;
98619861
zval *value;
98629862
if (value_ast->kind != ZEND_AST_ZVAL) {
9863-
ZVAL_NULL(&tmp);
9863+
/* Replaced at runtime by ZEND_ARRAY_SET_PLACEHOLDER. */
9864+
ZVAL_ERROR(&tmp);
98649865
value = &tmp;
98659866
} else {
98669867
value = zend_ast_get_zval(value_ast);

ext/opcache/zend_persist.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,9 @@ static void zend_persist_zval(zval *z)
267267
efree(old_ref);
268268
}
269269
break;
270+
case _IS_ERROR:
271+
/* Allowed for array templates. */
272+
break;
270273
default:
271274
ZEND_ASSERT(Z_TYPE_P(z) < IS_STRING);
272275
break;

ext/opcache/zend_persist_calc.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,9 @@ static void zend_persist_zval_calc(zval *z)
147147
}
148148
}
149149
break;
150+
case _IS_ERROR:
151+
/* Allowed for array templates. */
152+
break;
150153
default:
151154
ZEND_ASSERT(Z_TYPE_P(z) < IS_STRING);
152155
break;

0 commit comments

Comments
 (0)