Merge branch 'PHP-7.0'

This commit is contained in:
Bob Weinand 2016-02-15 22:43:58 +01:00
commit 77ca527c91
2 changed files with 62 additions and 20 deletions

View File

@ -0,0 +1,40 @@
--TEST--
Bug #71601 (finally block not executed after yield from)
--FILE--
<?php
function gen1() {
try {
yield 1;
yield 2;
return true;
} finally {
echo "Inner finally\n";
}
}
function gen2() {
try {
echo "Entered try/catch\n";
var_dump(yield from gen1());
} finally {
echo "Finally\n";
}
}
$generator = gen2();
var_dump($generator->current());
unset($generator);
echo "Done\n";
?>
--EXPECT--
Entered try/catch
int(1)
Inner finally
Finally
Done

View File

@ -60,11 +60,6 @@ static void zend_generator_cleanup_unfinished_execution(zend_generator *generato
ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished_execution) /* {{{ */
{
if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
zval_ptr_dtor(&generator->values);
ZVAL_UNDEF(&generator->values);
}
if (EXPECTED(generator->execute_data)) {
zend_execute_data *execute_data = generator->execute_data;
@ -110,6 +105,8 @@ ZEND_API void zend_generator_close(zend_generator *generator, zend_bool finished
}
/* }}} */
static zend_generator *zend_generator_get_child(zend_generator_node *node, zend_generator *leaf);
static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
{
zend_generator *generator = (zend_generator*) object;
@ -117,6 +114,22 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
uint32_t op_num, finally_op_num, finally_op_end;
int i;
/* leave yield from mode to properly allow finally execution */
if (UNEXPECTED(Z_TYPE(generator->values) != IS_UNDEF)) {
zval_ptr_dtor(&generator->values);
ZVAL_UNDEF(&generator->values);
}
if (EXPECTED(generator->node.children == 0)) {
zend_generator *root = generator->node.ptr.root, *next;
while (UNEXPECTED(root != generator)) {
next = zend_generator_get_child(&root->node, generator);
OBJ_RELEASE(&root->std);
root = next;
}
generator->node.parent = NULL;
}
if (EXPECTED(!ex) || EXPECTED(!(ex->func->op_array.fn_flags & ZEND_ACC_HAS_FINALLY_BLOCK))) {
return;
}
@ -157,8 +170,6 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
}
/* }}} */
static zend_generator *zend_generator_get_child(zend_generator_node *node, zend_generator *leaf);
static void zend_generator_free_storage(zend_object *object) /* {{{ */
{
zend_generator *generator = (zend_generator*) object;
@ -182,15 +193,6 @@ static void zend_generator_free_storage(zend_object *object) /* {{{ */
if (generator->iterator) {
zend_iterator_dtor(generator->iterator);
}
if (EXPECTED(generator->node.children == 0)) {
zend_generator *root = generator->node.ptr.root, *next;
while (UNEXPECTED(root != generator)) {
next = zend_generator_get_child(&root->node, generator);
OBJ_RELEASE(&root->std);
root = next;
}
}
}
/* }}} */
@ -279,10 +281,10 @@ static HashTable *zend_generator_get_gc(zval *object, zval **table, int *n) /* {
}
if (generator->node.children == 0) {
zend_generator *root = generator->node.ptr.root;
while (root != generator) {
ZVAL_OBJ(gc_buffer++, &root->std);
root = zend_generator_get_child(&root->node, generator);
zend_generator *child = generator, *root = generator->node.ptr.root;
while (root != child) {
ZVAL_OBJ(gc_buffer++, &child->std);
child = child->node.parent;
}
}