summaryrefslogtreecommitdiff
path: root/Zend/zend_opcode.c
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2012-08-20 13:37:53 +0200
committerNikita Popov <nikic@php.net>2012-08-20 13:37:53 +0200
commit1823b16fa15894f72fc01724766289dbecf5a62a (patch)
tree1b7d21c15a1003a8c5631a15393d906c0ef3482f /Zend/zend_opcode.c
parent9003cd142553384c3d271b12407186d5352868ad (diff)
parent9ccf85419849db587a973673e382faf3b3a9db43 (diff)
downloadphp-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.c40
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: