From cf6aa46dbd70539c66a722d7f165cac242c9e1db Mon Sep 17 00:00:00 2001 From: Nikita Popov Date: Fri, 22 Jan 2016 15:38:38 +0100 Subject: [PATCH] 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. --- ext/opcache/Optimizer/zend_dfg.c | 3 ++- ext/opcache/Optimizer/zend_inference.c | 19 +++++++++++++++++++ ext/opcache/Optimizer/zend_ssa.c | 8 ++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/ext/opcache/Optimizer/zend_dfg.c b/ext/opcache/Optimizer/zend_dfg.c index 9e71e00b65..4bf5d7913f 100644 --- a/ext/opcache/Optimizer/zend_dfg.c +++ b/ext/opcache/Optimizer/zend_dfg.c @@ -100,7 +100,7 @@ int zend_build_dfg(const zend_op_array *op_array, const zend_cfg *cfg, zend_dfg case ZEND_FE_RESET_RW: case ZEND_ADD_ARRAY_ELEMENT: case ZEND_INIT_ARRAY: - case ZEND_BIND_LEXICAL: + case ZEND_YIELD: if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op1.var))) { // FIXME: include into "use" to ...? 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 case ZEND_ASSIGN_REF: case ZEND_FE_FETCH_R: case ZEND_FE_FETCH_RW: + case ZEND_BIND_LEXICAL: if (!DFG_ISSET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var))) { // FIXME: include into "use" to ...? DFG_SET(use, set_size, j, EX_VAR_TO_NUM(opline->op2.var)); diff --git a/ext/opcache/Optimizer/zend_inference.c b/ext/opcache/Optimizer/zend_inference.c index beec91924c..aa78e3e7c3 100644 --- a/ext/opcache/Optimizer/zend_inference.c +++ b/ext/opcache/Optimizer/zend_inference.c @@ -3097,6 +3097,25 @@ static void zend_update_type_info(const zend_op_array *op_array, } } break; + case ZEND_YIELD: + if (ssa_ops[i].op1_def >= 0) { + tmp = t1 | MAY_BE_RC1 | MAY_BE_RCN; + if (op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) { + tmp |= MAY_BE_REF; + } + UPDATE_SSA_TYPE(tmp, ssa_ops[i].op1_def); + if ((t1 & MAY_BE_OBJECT) && ssa_var_info[ssa_ops[i].op1_use].ce) { + 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); + } else { + UPDATE_SSA_OBJ_TYPE(NULL, 0, ssa_ops[i].op1_def); + } + } + if (ssa_ops[i].result_def >= 0) { + tmp = MAY_BE_ANY | MAY_BE_ARRAY_KEY_ANY | MAY_BE_ARRAY_OF_ANY | MAY_BE_ARRAY_OF_REF + | MAY_BE_RC1 | MAY_BE_RCN; + UPDATE_SSA_TYPE(tmp, ssa_ops[i].result_def); + } + break; case ZEND_SEND_VAR_EX: case ZEND_SEND_VAR_NO_REF: case ZEND_SEND_REF: diff --git a/ext/opcache/Optimizer/zend_ssa.c b/ext/opcache/Optimizer/zend_ssa.c index 16d22dd258..b984d41bad 100644 --- a/ext/opcache/Optimizer/zend_ssa.c +++ b/ext/opcache/Optimizer/zend_ssa.c @@ -407,6 +407,14 @@ static int zend_ssa_rename(const zend_op_array *op_array, uint32_t build_flags, ssa_vars_count++; } break; + case ZEND_YIELD: + if (opline->op1_type == IS_CV + && ((op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) + || (build_flags & ZEND_SSA_RC_INFERENCE))) { + ssa_ops[k].op1_def = ssa_vars_count; + var[EX_VAR_TO_NUM(opline->op1.var)] = ssa_vars_count; + ssa_vars_count++; + } default: break; } -- 2.40.0