Commit: 72b9b8f380690357fc29efdfcba183b8a8a81268 Author: Xinchen Hui <larue...@php.net> Sat, 18 Aug 2012 11:44:09 +0800 Parents: 7cf9ac1420ecb1b05a7899e50e91772afe3fcdfb Branches: master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=72b9b8f380690357fc29efdfcba183b8a8a81268 Log: Make the codes clearer, and also check continue statement Changed paths: M Zend/tests/try_finally_008.phpt A Zend/tests/try_finally_009.phpt M Zend/zend_opcode.c M Zend/zend_vm_def.h M Zend/zend_vm_execute.h Diff: diff --git a/Zend/tests/try_finally_008.phpt b/Zend/tests/try_finally_008.phpt index 77ecf4f..9025d88 100644 --- a/Zend/tests/try_finally_008.phpt +++ b/Zend/tests/try_finally_008.phpt @@ -7,15 +7,12 @@ function foo () { try { try { } finally { - goto label; - echo "dummy"; + break; } } catch (Exception $e) { } finally { } } while (0); -label: - echo "label"; } foo(); diff --git a/Zend/tests/try_finally_009.phpt b/Zend/tests/try_finally_009.phpt new file mode 100644 index 0000000..7c3da67 --- /dev/null +++ b/Zend/tests/try_finally_009.phpt @@ -0,0 +1,23 @@ +--TEST-- +Finally with jmp (for continue) +--FILE-- +<?php +function foo () { + for($i = 0; $i < 5; $i++) { + do { + try { + try { + } finally { + } + } catch (Exception $e) { + } finally { + continue; + } + } while (0); + } +} + +foo(); +?> +--EXPECTF-- +Fatal error: jump out of a finally block is disallowed in %stry_finally_009.php on line %d diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index 8cccfe6..86144d6 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -485,6 +485,24 @@ static void zend_extension_op_array_handler(zend_extension *extension, zend_op_a } } +static void zend_check_finally_breakout(zend_op_array *op_array, zend_op *opline, zend_uint dst_num TSRMLS_DC) { + zend_uint i, op_num = opline - op_array->opcodes; + for (i=0; i < op_array->last_try_catch; i++) { + if (op_array->try_catch_array[i].try_op > op_num) { + break; + } + if ((op_num >= op_array->try_catch_array[i].finally_op + && op_num < op_array->try_catch_array[i].finally_end) + && (dst_num >= op_array->try_catch_array[i].finally_end + || dst_num < op_array->try_catch_array[i].finally_op)) { + CG(in_compilation) = 1; + CG(active_op_array) = op_array; + CG(zend_lineno) = opline->lineno; + zend_error(E_COMPILE_ERROR, "jump out of a finally block is disallowed"); + } + } +} + ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC) { zend_op *opline, *end; @@ -529,23 +547,29 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC) /* break omitted intentionally */ case ZEND_JMP: if (op_array->last_try_catch) { + zend_check_finally_breakout(op_array, opline, opline->op1.opline_num TSRMLS_CC); + } + opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num]; + break; + case ZEND_BRK: + case ZEND_CONT: + if (op_array->last_try_catch) { zend_uint i, op_num = opline - op_array->opcodes; - for (i=0; i < op_array->last_try_catch; i++) { - if (op_array->try_catch_array[i].try_op > op_num) { - break; + int nest_levels, array_offset; + zend_brk_cont_element *jmp_to; + + nest_levels = Z_LVAL_P(opline->op2.zv); + array_offset = opline->op1.opline_num; + do { + jmp_to = &op_array->brk_cont_array[array_offset]; + if (nest_levels > 1) { + array_offset = jmp_to->parent; } - if ((op_num >= op_array->try_catch_array[i].finally_op - && op_num < op_array->try_catch_array[i].finally_end) - && (opline->op1.opline_num >= op_array->try_catch_array[i].finally_end - || opline->op1.opline_num < op_array->try_catch_array[i].finally_op)) { - CG(in_compilation) = 1; - CG(active_op_array) = op_array; - CG(zend_lineno) = opline->lineno; - zend_error(E_COMPILE_ERROR, "jump out of a finally block is disallowed"); - } - } + } while (--nest_levels > 0); + if (op_array->last_try_catch) { + zend_check_finally_breakout(op_array, opline, jmp_to->brk TSRMLS_CC); + } } - opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num]; break; case ZEND_JMPZ: case ZEND_JMPNZ: diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 17dfb5f..1da4c12 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -5317,10 +5317,10 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED) ZEND_VM_NEXT_OPCODE(); } -ZEND_VM_HANDLER(159, ZEND_LEAVE, ANY, ANY) { - { +ZEND_VM_HANDLER(159, ZEND_LEAVE, ANY, ANY) +{ USE_OPLINE - zend_uint i, op_num = opline - EG(active_op_array)->opcodes; + zend_uint i, op_num = opline - EG(active_op_array)->opcodes; SAVE_OPLINE(); zend_exception_restore(TSRMLS_C); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 6fd7f07..b5a649d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -1176,9 +1176,9 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS } static int ZEND_FASTCALL ZEND_LEAVE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS) - { +{ USE_OPLINE - zend_uint i, op_num = opline - EG(active_op_array)->opcodes; + zend_uint i, op_num = opline - EG(active_op_array)->opcodes; SAVE_OPLINE(); zend_exception_restore(TSRMLS_C); -- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php