]> granicus.if.org Git - php/commitdiff
Fix SSA for ZEND_YIELD
authorNikita Popov <nikic@php.net>
Fri, 22 Jan 2016 14:38:38 +0000 (15:38 +0100)
committerNikita Popov <nikic@php.net>
Sun, 24 Jan 2016 22:03:50 +0000 (23:03 +0100)
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
ext/opcache/Optimizer/zend_inference.c
ext/opcache/Optimizer/zend_ssa.c

index 9e71e00b65acc29a33cb3c6a6354d35afa45e194..4bf5d7913fe5d0c71d79f0de3e4be272359045da 100644 (file)
@@ -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));
index beec91924c2720cf51d8611e0025bdb9cb361e2b..aa78e3e7c34b0b05b0813fc9c472bed1ce379f3c 100644 (file)
@@ -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:
index 16d22dd258efdd421695cf44efc14e4dd823a0bf..b984d41bad7b214597d53b40e57343d14645e9a7 100644 (file)
@@ -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;
                        }