Skip to content

Commit

Permalink
Support trivial finally in generators (no yield, no return)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
nikic committed Aug 13, 2012
1 parent f4ce364 commit ae71693
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 24 deletions.
24 changes: 12 additions & 12 deletions Zend/zend_vm_def.h
Expand Up @@ -2513,6 +2513,18 @@ ZEND_VM_HELPER(zend_leave_helper, ANY, ANY)
zend_bool nested;
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(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
Expand Down Expand Up @@ -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_CONTINUE();
} 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);
}
}
Expand Down
24 changes: 12 additions & 12 deletions Zend/zend_vm_execute.h
Expand Up @@ -496,6 +496,18 @@ static int ZEND_FASTCALL zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS)
zend_bool nested;
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(opline_ptr) = NULL;
if (!EG(active_symbol_table)) {
Expand Down Expand Up @@ -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_CONTINUE();
} 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);
}
}
Expand Down

0 comments on commit ae71693

Please sign in to comment.