mirror of
https://github.com/php/php-src.git
synced 2025-08-18 15:08:55 +02:00
Support trivial finally in generators (no yield, no return)
The finally clause is now properly run when an exception is thrown in the try-block. It is not yet run on `return` and also not run when the generator is claused within a try block. I'll add those two things as soon as laruence refactored the finally code.
This commit is contained in:
parent
f4ce364628
commit
ae716939eb
2 changed files with 24 additions and 24 deletions
|
@ -2513,6 +2513,18 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
|
||||||
zend_bool nested;
|
zend_bool nested;
|
||||||
zend_op_array *op_array = EX(op_array);
|
zend_op_array *op_array = EX(op_array);
|
||||||
|
|
||||||
|
/* Generators go throw a different cleanup process */
|
||||||
|
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
||||||
|
/* The generator object is stored in return_value_ptr_ptr */
|
||||||
|
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||||
|
|
||||||
|
/* Close the generator to free up resources */
|
||||||
|
zend_generator_close(generator, 1 TSRMLS_CC);
|
||||||
|
|
||||||
|
/* Pass execution back to handling code */
|
||||||
|
ZEND_VM_RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
EG(current_execute_data) = EX(prev_execute_data);
|
EG(current_execute_data) = EX(prev_execute_data);
|
||||||
EG(opline_ptr) = NULL;
|
EG(opline_ptr) = NULL;
|
||||||
if (!EG(active_symbol_table)) {
|
if (!EG(active_symbol_table)) {
|
||||||
|
@ -5213,18 +5225,6 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
|
||||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||||
ZEND_VM_CONTINUE();
|
ZEND_VM_CONTINUE();
|
||||||
} else {
|
} else {
|
||||||
/* For generators skip the leave handler and return directly */
|
|
||||||
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
|
||||||
/* The generator object is stored in return_value_ptr_ptr */
|
|
||||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
|
||||||
|
|
||||||
/* Close the generator to free up resources */
|
|
||||||
zend_generator_close(generator, 1 TSRMLS_CC);
|
|
||||||
|
|
||||||
/* Pass execution back to handling code */
|
|
||||||
ZEND_VM_RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -496,6 +496,18 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
|
||||||
zend_bool nested;
|
zend_bool nested;
|
||||||
zend_op_array *op_array = EX(op_array);
|
zend_op_array *op_array = EX(op_array);
|
||||||
|
|
||||||
|
/* Generators go throw a different cleanup process */
|
||||||
|
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
||||||
|
/* The generator object is stored in return_value_ptr_ptr */
|
||||||
|
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
||||||
|
|
||||||
|
/* Close the generator to free up resources */
|
||||||
|
zend_generator_close(generator, 1 TSRMLS_CC);
|
||||||
|
|
||||||
|
/* Pass execution back to handling code */
|
||||||
|
ZEND_VM_RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
EG(current_execute_data) = EX(prev_execute_data);
|
EG(current_execute_data) = EX(prev_execute_data);
|
||||||
EG(opline_ptr) = NULL;
|
EG(opline_ptr) = NULL;
|
||||||
if (!EG(active_symbol_table)) {
|
if (!EG(active_symbol_table)) {
|
||||||
|
@ -1177,18 +1189,6 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
|
||||||
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
|
||||||
ZEND_VM_CONTINUE();
|
ZEND_VM_CONTINUE();
|
||||||
} else {
|
} else {
|
||||||
/* For generators skip the leave handler and return directly */
|
|
||||||
if (EX(op_array)->fn_flags & ZEND_ACC_GENERATOR) {
|
|
||||||
/* The generator object is stored in return_value_ptr_ptr */
|
|
||||||
zend_generator *generator = (zend_generator *) EG(return_value_ptr_ptr);
|
|
||||||
|
|
||||||
/* Close the generator to free up resources */
|
|
||||||
zend_generator_close(generator, 1 TSRMLS_CC);
|
|
||||||
|
|
||||||
/* Pass execution back to handling code */
|
|
||||||
ZEND_VM_RETURN();
|
|
||||||
}
|
|
||||||
|
|
||||||
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue