Commit: 703a4e390de277afb85d722a0792912d0b2d2d46
Author: Xinchen Hui <larue...@php.net> Wed, 22 Aug 2012 13:51:44
+0800
Parents: c4fecc1c5d44481a4088f6028ce6910f2ce4e0dc
Branches: master
Link:
http://git.php.net/?p=php-src.git;a=commitdiff;h=703a4e390de277afb85d722a0792912d0b2d2d46
Log:
stash
Changed paths:
M Zend/zend_compile.c
M Zend/zend_compile.h
M Zend/zend_opcode.c
M Zend/zend_vm_def.h
M Zend/zend_vm_execute.h
diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c
index 33d1d37..2ae8cc5 100644
--- a/Zend/zend_compile.c
+++ b/Zend/zend_compile.c
@@ -2792,6 +2792,7 @@ void zend_do_end_finally(znode *try_token, znode*
catch_token, znode *finally_to
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_op =
finally_token->u.op.opline_num;
CG(active_op_array)->try_catch_array[try_token->u.op.opline_num].finally_end =
get_next_op_number(CG(active_op_array));
+ CG(active_op_array)->has_finally_block = 1;
opline->opcode = ZEND_LEAVE;
SET_UNUSED(opline->op1);
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index 8919fdc..80e02ab 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -281,6 +281,7 @@ struct _zend_op_array {
zend_try_catch_element *try_catch_array;
int last_try_catch;
+ zend_bool has_finally_block;
/* static variables support */
HashTable *static_variables;
@@ -383,7 +384,8 @@ struct _zend_execute_data {
zend_class_entry *current_called_scope;
zval *current_this;
zval *current_object;
- zend_bool leaving;
+ zend_uint leaving;
+ zend_uint leaving_dest;
};
#define EX(element) execute_data.element
diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c
index 7cbc15b..2552d2e 100644
--- a/Zend/zend_opcode.c
+++ b/Zend/zend_opcode.c
@@ -87,6 +87,7 @@ void init_op_array(zend_op_array *op_array, zend_uchar type,
int initial_ops_siz
op_array->static_variables = NULL;
op_array->last_try_catch = 0;
+ op_array->has_finally_block = 0;
op_array->this_var = -1;
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index 1da4c12..d921f81 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -2878,49 +2878,10 @@ ZEND_VM_HANDLER(62, ZEND_RETURN, CONST|TMP|VAR|CV, ANY)
}
FREE_OP1_IF_VAR();
- if (!(EG(active_op_array)->last_try_catch)) {
- ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type,
ZEND_RETURN);
+ }
+ ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF, CONST|TMP|VAR|CV, ANY)
@@ -2993,49 +2954,10 @@ ZEND_VM_HANDLER(111, ZEND_RETURN_BY_REF,
CONST|TMP|VAR|CV, ANY)
FREE_OP1_IF_VAR();
- if (!(EG(active_op_array)->last_try_catch)) {
- ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type,
ZEND_RETURN_BY_REF);
+ }
+ ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
}
ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
@@ -3370,6 +3292,93 @@ ZEND_VM_HANDLER(52, ZEND_BOOL, CONST|TMP|VAR|CV, ANY)
ZEND_VM_NEXT_OPCODE();
}
+ZEND_VM_HELPER_EX(zend_finally_handler_leaving, ANY, ANY, int type)
+{
+ USE_OPLINE
+ zend_uint i, op_num = opline - EX(op_array)->opcodes;
+ zend_uint catch_op_num = 0, finally_op_num = 0;
+
+ SAVE_OPLINE();
+
+ switch (type) {
+ case ZEND_THROW:
+ case ZEND_RETURN:
+ case ZEND_RETURN_BY_REF:
+ {
+ if (EG(prev_exception)) {
+ for (i=0;
i<EG(active_op_array)->last_try_catch; i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
+ catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
+ }
+ }
+ } else {
+ for (i=0;
i<EG(active_op_array)->last_try_catch; i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ }
+ }
+
+ if (catch_op_num && finally_op_num) {
+ /* EG(exception) || EG(prev_exception)
*/
+ if (catch_op_num > finally_op_num) {
+ EX(leaving) = ZEND_THROW;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ }
+ } else if (catch_op_num) {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ } else if (finally_op_num) {
+ EX(leaving) = type;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else if (EX(leaving)) {
+ /* leave it to ZEND_LEAVE */
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+ }
+ }
+ break;
+ case ZEND_BRK:
+ case ZEND_CONT:
+ case ZEND_GOTO:
+ {
+ for (i=0;
i<EG(active_op_array)->last_try_catch; i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op
+ && (EX(leaving_dest) <
EG(active_op_array)->try_catch_array[i].try_op
+ || EX(leaving_dest) >=
EG(active_op_array)->try_catch_array[i].finally_end)) {
+ finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ }
+
+ if (finally_op_num) {
+ EX(leaving) = type;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[EX(leaving_dest)]);
+ }
+ }
+ break;
+ }
+ ZEND_VM_CONTINUE();
+}
+
ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
{
USE_OPLINE
@@ -3379,6 +3388,10 @@ ZEND_VM_HANDLER(50, ZEND_BRK, ANY, CONST)
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
EX(op_array), EX_Ts() TSRMLS_CC);
FREE_OP2();
+ if (EG(active_op_array)->has_finally_block) {
+ EX(leaving_dest) = el->brk;
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type,
ZEND_BRK);
+ }
ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}
@@ -3391,6 +3404,10 @@ ZEND_VM_HANDLER(51, ZEND_CONT, ANY, CONST)
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
EX(op_array), EX_Ts() TSRMLS_CC);
FREE_OP2();
+ if (EG(active_op_array)->has_finally_block) {
+ EX(leaving_dest) = el->cont;
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type,
ZEND_CONT);
+ }
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}
@@ -3418,6 +3435,10 @@ ZEND_VM_HANDLER(100, ZEND_GOTO, ANY, CONST)
}
break;
}
+ if ((EG(active_op_array)->has_finally_block)) {
+ EX(leaving_dest) = opline->op1.jmp_addr - EG(active_op_array)->opcodes;
+ ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type,
ZEND_GOTO);
+ }
ZEND_VM_JMP(opline->op1.jmp_addr);
}
@@ -5184,7 +5205,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
ZEND_VM_CONTINUE();
} else {
zend_exception_save(TSRMLS_C);
- EX(leaving) = finally;
+ EX(leaving) = ZEND_THROW;
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
}
@@ -5194,7 +5215,7 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
ZEND_VM_CONTINUE();
} else if (finally) {
zend_exception_save(TSRMLS_C);
- EX(leaving) = finally;
+ EX(leaving) = ZEND_THROW;
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
} else {
@@ -5284,7 +5305,7 @@ ZEND_VM_HANDLER(153, ZEND_DECLARE_LAMBDA_FUNCTION, CONST,
UNUSED)
zend_function *op_array;
SAVE_OPLINE();
-
+
if (UNEXPECTED(zend_hash_quick_find(EG(function_table),
Z_STRVAL_P(opline->op1.zv), Z_STRLEN_P(opline->op1.zv),
Z_HASH_P(opline->op1.zv), (void *) &op_array) == FAILURE) ||
UNEXPECTED(op_array->type != ZEND_USER_FUNCTION)) {
zend_error_noreturn(E_ERROR, "Base lambda function for closure
not found");
@@ -5320,47 +5341,68 @@ ZEND_VM_HANDLER(156, ZEND_SEPARATE, VAR, UNUSED)
ZEND_VM_HANDLER(159, ZEND_LEAVE, ANY, ANY)
{
USE_OPLINE
- zend_uint i, op_num = opline - EG(active_op_array)->opcodes;
-
- SAVE_OPLINE();
zend_exception_restore(TSRMLS_C);
- if (EX(leaving)) {
+
+ if (!EX(leaving)) {
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_uint i, op_num = opline - EX(op_array)->opcodes;
zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i = 0; i < EX(leaving); i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(exception)) {
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
+ switch (EX(leaving)) {
+ case ZEND_RETURN:
+ case ZEND_RETURN_BY_REF:
+ case ZEND_THROW:
+ {
+ if (EG(exception)) {
+ for (i = 0; i < EX(leaving);
i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num
= EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
+ catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
+ }
+ }
+ } else {
+ for (i = 0; i < EX(leaving);
i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num
= EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ }
+ }
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+ if (catch_op_num && finally_op_num) {
+ if (catch_op_num >
finally_op_num) {
+ EX(leaving) =
ZEND_THROW;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ }
+ } else if (catch_op_num) {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ } else if (finally_op_num) {
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+
ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper);
+ }
+ }
+ break;
+ case ZEND_BRK:
+ case ZEND_CONT:
+ case ZEND_GOTO:
+
ZEND_VM_DISPATCH_TO_HELPER_EX(zend_finally_handler_leaving, type, EX(leaving));
+ break;
}
- } else {
- ZEND_VM_NEXT_OPCODE();
}
+
+ ZEND_VM_CONTINUE();
}
ZEND_VM_EXPORT_HELPER(zend_do_fcall, zend_do_fcall_common_helper)
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index b5a649d..9818583 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -794,6 +794,93 @@ static int ZEND_FASTCALL
ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
ZEND_VM_NEXT_OPCODE();
}
+static int ZEND_FASTCALL zend_finally_handler_leaving_SPEC(int type,
ZEND_OPCODE_HANDLER_ARGS)
+{
+ USE_OPLINE
+ zend_uint i, op_num = opline - EX(op_array)->opcodes;
+ zend_uint catch_op_num = 0, finally_op_num = 0;
+
+ SAVE_OPLINE();
+
+ switch (type) {
+ case ZEND_THROW:
+ case ZEND_RETURN:
+ case ZEND_RETURN_BY_REF:
+ {
+ if (EG(prev_exception)) {
+ for (i=0;
i<EG(active_op_array)->last_try_catch; i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
+ catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
+ }
+ }
+ } else {
+ for (i=0;
i<EG(active_op_array)->last_try_catch; i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ }
+ }
+
+ if (catch_op_num && finally_op_num) {
+ /* EG(exception) || EG(prev_exception)
*/
+ if (catch_op_num > finally_op_num) {
+ EX(leaving) = ZEND_THROW;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ }
+ } else if (catch_op_num) {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ } else if (finally_op_num) {
+ EX(leaving) = type;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else if (EX(leaving)) {
+ /* leave it to ZEND_LEAVE */
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ }
+ break;
+ case ZEND_BRK:
+ case ZEND_CONT:
+ case ZEND_GOTO:
+ {
+ for (i=0;
i<EG(active_op_array)->last_try_catch; i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op
+ && (EX(leaving_dest) <
EG(active_op_array)->try_catch_array[i].try_op
+ || EX(leaving_dest) >=
EG(active_op_array)->try_catch_array[i].finally_end)) {
+ finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ }
+
+ if (finally_op_num) {
+ EX(leaving) = type;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[EX(leaving_dest)]);
+ }
+ }
+ break;
+ }
+ ZEND_VM_CONTINUE();
+}
+
static int ZEND_FASTCALL ZEND_NEW_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
{
USE_OPLINE
@@ -1122,7 +1209,7 @@ static int ZEND_FASTCALL
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
ZEND_VM_CONTINUE();
} else {
zend_exception_save(TSRMLS_C);
- EX(leaving) = finally;
+ EX(leaving) = ZEND_THROW;
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
}
@@ -1132,7 +1219,7 @@ static int ZEND_FASTCALL
ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER
ZEND_VM_CONTINUE();
} else if (finally) {
zend_exception_save(TSRMLS_C);
- EX(leaving) = finally;
+ EX(leaving) = ZEND_THROW;
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
ZEND_VM_CONTINUE();
} else {
@@ -1178,47 +1265,68 @@ 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;
-
- SAVE_OPLINE();
zend_exception_restore(TSRMLS_C);
- if (EX(leaving)) {
+
+ if (!EX(leaving)) {
+ ZEND_VM_NEXT_OPCODE();
+ } else {
+ zend_uint i, op_num = opline - EX(op_array)->opcodes;
zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i = 0; i < EX(leaving); i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(exception)) {
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
+ switch (EX(leaving)) {
+ case ZEND_RETURN:
+ case ZEND_RETURN_BY_REF:
+ case ZEND_THROW:
+ {
+ if (EG(exception)) {
+ for (i = 0; i < EX(leaving);
i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num
= EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
+ catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
+ }
+ }
+ } else {
+ for (i = 0; i < EX(leaving);
i++) {
+ if
(EG(active_op_array)->try_catch_array[i].try_op > op_num) {
+ break;
+ }
+ if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
+ finally_op_num
= EG(active_op_array)->try_catch_array[i].finally_op;
+ }
+ }
+ }
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ if (catch_op_num && finally_op_num) {
+ if (catch_op_num >
finally_op_num) {
+ EX(leaving) =
ZEND_THROW;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ }
+ } else if (catch_op_num) {
+ EX(leaving) = 0;
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
+ } else if (finally_op_num) {
+
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
+ } else {
+ return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ }
+ break;
+ case ZEND_BRK:
+ case ZEND_CONT:
+ case ZEND_GOTO:
+ return
zend_finally_handler_leaving_SPEC(EX(leaving),
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ break;
}
- } else {
- ZEND_VM_NEXT_OPCODE();
}
+
+ ZEND_VM_CONTINUE();
}
static int ZEND_FASTCALL
ZEND_FETCH_CLASS_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -1455,6 +1563,10 @@ static int ZEND_FASTCALL
ZEND_BRK_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
EX(op_array), EX_Ts() TSRMLS_CC);
+ if (EG(active_op_array)->has_finally_block) {
+ EX(leaving_dest) = el->brk;
+ return zend_finally_handler_leaving_SPEC(ZEND_BRK,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
ZEND_VM_JMP(EX(op_array)->opcodes + el->brk);
}
@@ -1467,6 +1579,10 @@ static int ZEND_FASTCALL
ZEND_CONT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
el = zend_brk_cont(Z_LVAL_P(opline->op2.zv), opline->op1.opline_num,
EX(op_array), EX_Ts() TSRMLS_CC);
+ if (EG(active_op_array)->has_finally_block) {
+ EX(leaving_dest) = el->cont;
+ return zend_finally_handler_leaving_SPEC(ZEND_CONT,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
ZEND_VM_JMP(EX(op_array)->opcodes + el->cont);
}
@@ -1494,6 +1610,10 @@ static int ZEND_FASTCALL
ZEND_GOTO_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
break;
}
+ if ((EG(active_op_array)->has_finally_block)) {
+ EX(leaving_dest) = opline->op1.jmp_addr - EG(active_op_array)->opcodes;
+ return zend_finally_handler_leaving_SPEC(ZEND_CONT,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
ZEND_VM_JMP(opline->op1.jmp_addr);
}
@@ -2345,49 +2465,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARG
*EG(return_value_ptr_ptr) = ret;
}
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -2458,49 +2539,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND
}
} while (0);
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL
ZEND_THROW_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -6973,49 +7015,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = ret;
}
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -7086,49 +7089,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLE
}
} while (0);
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_THROW_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -11507,49 +11471,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
}
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -11622,49 +11547,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLE
if (free_op1.var) {zval_ptr_dtor(&free_op1.var);};
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_THROW_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -27604,49 +27490,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
*EG(return_value_ptr_ptr) = ret;
}
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -27717,49 +27564,10 @@ static int ZEND_FASTCALL
ZEND_RETURN_BY_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER
}
} while (0);
- if (!(EG(active_op_array)->last_try_catch)) {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- } else {
- zend_uint i, op_num = opline - EX(op_array)->opcodes;
- zend_uint catch_op_num = 0, finally_op_num = 0;
- for (i=0; i<EG(active_op_array)->last_try_catch; i++) {
- if (EG(active_op_array)->try_catch_array[i].try_op >
op_num) {
- break;
- }
- if (op_num <
EG(active_op_array)->try_catch_array[i].finally_op) {
- finally_op_num =
EG(active_op_array)->try_catch_array[i].finally_op;
- }
- if (EG(prev_exception)) {
- /* leaving */
- if (op_num <
EG(active_op_array)->try_catch_array[i].catch_op) {
- catch_op_num =
EG(active_op_array)->try_catch_array[i].catch_op;
- }
- }
- }
-
- if (catch_op_num && finally_op_num) {
- if (catch_op_num > finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else {
- EX(leaving) = 0;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- }
- } else if (catch_op_num) {
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[catch_op_num]);
- ZEND_VM_CONTINUE();
- } else if (finally_op_num) {
- EX(leaving) = 1;
-
ZEND_VM_SET_OPCODE(&EX(op_array)->opcodes[finally_op_num]);
- ZEND_VM_CONTINUE();
- } else if (EX(leaving)) {
- ZEND_VM_NEXT_OPCODE();
- } else {
- return
zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
- }
- }
+ if (EG(active_op_array)->has_finally_block) {
+ return zend_finally_handler_leaving_SPEC(ZEND_RETURN_BY_REF,
ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
+ }
+ return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
}
static int ZEND_FASTCALL ZEND_THROW_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php