Skip to content

Commit cf6aa46

Browse files
committed
Fix SSA for ZEND_YIELD
Yield-by-ref defs a ref var, yield-by-var only defs an rc1/rcn var if rc inference is used. Also move BIND_LEXICAL where it belongs in DFG construction.
1 parent 9017bb9 commit cf6aa46

File tree

3 files changed

+29
-1
lines changed

3 files changed

+29
-1
lines changed

ext/opcache/Optimizer/zend_dfg.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
100100
case ZEND_FE_RESET_RW:
101101
case ZEND_ADD_ARRAY_ELEMENT:
102102
case ZEND_INIT_ARRAY:
103-
case ZEND_BIND_LEXICAL:
103+
case ZEND_YIELD:
104104
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) {
105105
// FIXME: include into "use" to ...?
106106
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var));
@@ -157,6 +157,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg
157157
case ZEND_ASSIGN_REF:
158158
case ZEND_FE_FETCH_R:
159159
case ZEND_FE_FETCH_RW:
160+
case ZEND_BIND_LEXICAL:
160161
if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) {
161162
// FIXME: include into "use" to ...?
162163
DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var));

ext/opcache/Optimizer/zend_inference.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3097,6 +3097,25 @@ static void zend_update_type_info(const zend_op_array *op_array,
30973097
}
30983098
}
30993099
break;
3100+
case ZEND_YIELD:
3101+
if (ssa_ops[i].op1_def >= 0) {
3102+
tmp = t1 | MAY_BE_RC1 | MAY_BE_RCN;
3103+
if (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) {
3104+
tmp |= MAY_BE_REF;
3105+
}
3106+
UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def);
3107+
if ((t1 & MAY_BE_OBJECT) && ssa_var_info[ssa_ops[i].op1_use].ce) {
3108+
UPDATE_SSA_OBJ_TYPE(ssa_var_info[ssa_ops[i].op1_use].ce, ssa_var_info[ssa_ops[i].op1_use].is_instanceof, ssa_ops[i].op1_def);
3109+
} else {
3110+
UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_ops[i].op1_def);
3111+
}
3112+
}
3113+
if (ssa_ops[i].result_def >= 0) {
3114+
tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF
3115+
| MAY_BE_RC1 | MAY_BE_RCN;
3116+
UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def);
3117+
}
3118+
break;
31003119
case ZEND_SEND_VAR_EX:
31013120
case ZEND_SEND_VAR_NO_REF:
31023121
case ZEND_SEND_REF:

ext/opcache/Optimizer/zend_ssa.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,14 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags,
407407
ssa_vars_count++;
408408
}
409409
break;
410+
case ZEND_YIELD:
411+
if (opline->op1_type == IS_CV
412+
&& ((op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE)
413+
|| (build_flags & ZEND_SSA_RC_INFERENCE))) {
414+
ssa_ops[k].op1_def = ssa_vars_count;
415+
var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count;
416+
ssa_vars_count++;
417+
}
410418
default:
411419
break;
412420
}

0 commit comments

Comments
 (0)