diff options
author | Nikita Popov <nikic@php.net> | 2012-08-20 13:37:53 +0200 |
---|---|---|
committer | Nikita Popov <nikic@php.net> | 2012-08-20 13:37:53 +0200 |
commit | 1823b16fa15894f72fc01724766289dbecf5a62a (patch) | |
tree | 1b7d21c15a1003a8c5631a15393d906c0ef3482f /Zend/zend_opcode.c | |
parent | 9003cd142553384c3d271b12407186d5352868ad (diff) | |
parent | 9ccf85419849db587a973673e382faf3b3a9db43 (diff) | |
download | php-git-1823b16fa15894f72fc01724766289dbecf5a62a.tar.gz |
Merge remote-tracking branch 'php-src/master' into addGeneratorsSupport
Merging master to fix Windows build
Conflicts:
Zend/zend_language_scanner.c
Zend/zend_language_scanner_defs.h
Zend/zend_vm_def.h
Diffstat (limited to 'Zend/zend_opcode.c')
-rw-r--r-- | Zend/zend_opcode.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index a8c07e9493..080e7a38c9 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; @@ -528,8 +546,30 @@ 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) { + 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; + } + } while (--nest_levels > 0); + if (op_array->last_try_catch) { + zend_check_finally_breakout(op_array, opline, jmp_to->brk TSRMLS_CC); + } + } + break; case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: |