Browse Source

Fully fix typed generator returns

pull/1126/merge
Bob Weinand 11 years ago
parent
commit
7ca85d8875
  1. 5
      Zend/tests/generators/generator_return_return_type.phpt
  2. 2
      Zend/zend_compile.c
  3. 29
      Zend/zend_opcode.c

5
Zend/tests/generators/generator_return_return_type.phpt

@ -4,8 +4,9 @@ Generators must return a valid variable with return type specified
<?php <?php
$gen = (function (): Generator { $gen = (function (): Generator {
return true;
yield;
1 + $a = 1; // force a temporary
return true;
yield;
})(); })();
var_dump($gen->valid()); var_dump($gen->valid());

2
Zend/zend_compile.c

@ -3610,7 +3610,7 @@ void zend_resolve_goto_label(zend_op_array *op_array, znode *label_node, zend_op
znode *loop_var = NULL; znode *loop_var = NULL;
if (pass2_opline) { if (pass2_opline) {
label = RT_CONSTANT(op_array, pass2_opline->op2);
label = CT_CONSTANT_EX(op_array, pass2_opline->op2.constant);
} else { } else {
label = &label_node->u.constant; label = &label_node->u.constant;
} }

29
Zend/zend_opcode.c

@ -693,7 +693,6 @@ static void zend_resolve_finally_calls(zend_op_array *op_array)
break; break;
case ZEND_GOTO: case ZEND_GOTO:
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) { if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) {
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
zend_resolve_goto_label(op_array, NULL, opline); zend_resolve_goto_label(op_array, NULL, opline);
} }
/* break omitted intentionally */ /* break omitted intentionally */
@ -744,19 +743,6 @@ ZEND_API int pass_two(zend_op_array *op_array)
opline = op_array->opcodes; opline = op_array->opcodes;
end = opline + op_array->last; end = opline + op_array->last;
while (opline < end) { while (opline < end) {
if (opline->op1_type == IS_CONST) {
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
} else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
opline->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op1.var);
}
if (opline->op2_type == IS_CONST) {
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
} else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
opline->op2.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op2.var);
}
if (opline->result_type & (IS_VAR|IS_TMP_VAR)) {
opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->result.var);
}
switch (opline->opcode) { switch (opline->opcode) {
case ZEND_DECLARE_ANON_INHERITED_CLASS: case ZEND_DECLARE_ANON_INHERITED_CLASS:
ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1); ZEND_PASS_TWO_UPDATE_JMP_TARGET(op_array, opline, opline->op1);
@ -776,7 +762,7 @@ ZEND_API int pass_two(zend_op_array *op_array)
} }
break; break;
case ZEND_GOTO: case ZEND_GOTO:
if (Z_TYPE_P(RT_CONSTANT(op_array, opline->op2)) != IS_LONG) {
if (Z_TYPE_P(CT_CONSTANT_EX(op_array, opline->op2.constant)) != IS_LONG) {
zend_resolve_goto_label(op_array, NULL, opline); zend_resolve_goto_label(op_array, NULL, opline);
} }
/* break omitted intentionally */ /* break omitted intentionally */
@ -821,6 +807,19 @@ ZEND_API int pass_two(zend_op_array *op_array)
} }
break; break;
} }
if (opline->op1_type == IS_CONST) {
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op1);
} else if (opline->op1_type & (IS_VAR|IS_TMP_VAR)) {
opline->op1.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op1.var);
}
if (opline->op2_type == IS_CONST) {
ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline->op2);
} else if (opline->op2_type & (IS_VAR|IS_TMP_VAR)) {
opline->op2.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->op2.var);
}
if (opline->result_type & (IS_VAR|IS_TMP_VAR)) {
opline->result.var = (uint32_t)(zend_intptr_t)ZEND_CALL_VAR_NUM(NULL, op_array->last_var + opline->result.var);
}
ZEND_VM_SET_OPCODE_HANDLER(opline); ZEND_VM_SET_OPCODE_HANDLER(opline);
opline++; opline++;
} }

Loading…
Cancel
Save