Permalink
Browse files

Fixed bug that jmp in try block jmp over finally block

Refactor the implemention,  make codes clear
  • Loading branch information...
1 parent 3d4f91d commit 60a29791e4b66844e5dfff698141074d48fc3da8 @laruence laruence committed Aug 22, 2012
@@ -1,5 +1,5 @@
--TEST--
-Try catch finally
+Try catch finally (basic test)
--FILE--
<?php
function foo ($throw = FALSE) {
@@ -1,5 +1,5 @@
--TEST--
-Try catch finally return
+Try catch finally (basic test with return)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Try catch finally multi-return
+Try catch finally (with multi-returns)
--FILE--
<?php
function dummy($msg) {
@@ -1,5 +1,5 @@
--TEST--
-Nesting try catch finally
+Try catch finally (nesting try-catch-finally)
--FILE--
<?php
@@ -1,5 +1,5 @@
--TEST--
-Try catch finally with return
+Try catch finally (with multi-returns and exception)
--FILE--
<?php
function foo ($a) {
@@ -1,5 +1,5 @@
--TEST--
-Try catch finally: re-throw exception in catch block
+Try catch finally (re-throw exception in catch block)
--FILE--
<?php
function foo ($a) {
@@ -0,0 +1,52 @@
+--TEST--
+Try catch finally (break / cont in try block)
+--CREDITS--
+adoy
+--FILE--
+<?php
+for ($i = 0; $i < 100 ; $i ++) {
+ try {
+ break;
+ } finally {
+ var_dump("break");
+ }
+}
+
+
+for ($i = 0; $i < 2; $i ++) {
+ try {
+ continue;
+ } finally {
+ var_dump("continue1");
+ }
+}
+
+for ($i = 0; $i < 3; $i ++) {
+ try {
+ try {
+ continue;
+ } finally {
+ var_dump("continue2");
+ if ($i == 1) {
+ throw new Exception("continue exception");
+ }
+ }
+ } catch (Exception $e) {
+ var_dump("cactched");
+ } finally {
+ var_dump("finally");
+ }
+}
+
+?>
+--EXPECTF--
+string(5) "break"
+string(9) "continue1"
+string(9) "continue1"
+string(9) "continue2"
+string(7) "finally"
+string(9) "continue2"
+string(8) "cactched"
+string(7) "finally"
+string(9) "continue2"
+string(7) "finally"
@@ -0,0 +1,39 @@
+--TEST--
+Try catch finally (goto in try/catch block)
+--CREDITS--
+adoy
+--FILE--
+<?php
+function foo($ex = NULL) {
+ try {
+ try {
+ goto label;
+ } finally {
+ var_dump("finally1");
+ if ($ex) throw $ex;
+ }
+ } catch (Exception $e) {
+ var_dump("catched");
+ if ($ex) return "return1";
+ } finally {
+ var_dump("finally2");
+ }
+
+label:
+ var_dump("label");
+ return "return2";
+}
+
+var_dump(foo());
+var_dump(foo(new Exception()));
+
+?>
+--EXPECTF--
+string(8) "finally1"
+string(8) "finally2"
+string(5) "label"
+string(7) "return2"
+string(8) "finally1"
+string(7) "catched"
+string(8) "finally2"
+string(7) "return1"
@@ -0,0 +1,46 @@
+--TEST--
+Try catch finally (goto in try/catch block)
+--CREDITS--
+adoy
+--FILE--
+<?php
+function foo($ret = FALSE) {
+ try {
+ try {
+ do {
+ goto label;
+ } while(0);
+ foreach (array() as $val) {
+ continue;
+ }
+ } finally {
+ var_dump("finally1");
+ throw new Exception("exception");
+ }
+ } catch (Exception $e) {
+ goto local;
+local:
+ var_dump("catched");
+ if ($ret) return "return";
+ } finally {
+ var_dump("finally2");
+ }
+
+label:
+ var_dump("label");
+}
+
+var_dump(foo());
+var_dump(foo(true));
+
+?>
+--EXPECTF--
+string(8) "finally1"
+string(7) "catched"
+string(8) "finally2"
+string(5) "label"
+NULL
+string(8) "finally1"
+string(7) "catched"
+string(8) "finally2"
+string(6) "return"
@@ -1,5 +1,5 @@
--TEST--
-Try finally
+Try finally (basic test)
--FILE--
<?php
function foo ($a) {
@@ -20,4 +20,3 @@ Stack trace:
#0 %stry_finally_001.php(%d): foo('finally')
#1 {main}
thrown in %stry_finally_001.php on line %d
-
@@ -1,5 +1,5 @@
--TEST--
-Try finally
+Try finally (re-throw exception in finally block)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Try finally
+Try finally (call sequence test)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Try without catch/finally block
+Try finally (without catch/finally block)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Finally with long goto
+Try finally (with long goto)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Finally with near goto
+Try finally (with near goto)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Finally with goto previous label
+Try finally (with goto previous label)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Finally with jmp (do while)
+Try finally (with break in do...while)
--FILE--
<?php
function foo () {
@@ -1,5 +1,5 @@
--TEST--
-Finally with jmp (for continue)
+Try finally (with for continue)
--FILE--
<?php
function foo () {
View
@@ -2696,7 +2696,7 @@ void zend_initialize_try_catch_element(znode *catch_token TSRMLS_DC) /* {{{ */
zend_stack_top(&CG(bp_stack), (void **) &jmp_list_ptr);
zend_llist_add_element(jmp_list_ptr, &jmp_op_number);
- catch_token->EA = get_next_op_number(CG(active_op_array));
+ catch_token->EA = get_next_op_number(CG(active_op_array));
}
/* }}} */
@@ -2792,7 +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;
+ CG(active_op_array)->has_finally_block = 1;
opline->opcode = ZEND_LEAVE;
SET_UNUSED(opline->op1);
@@ -4059,9 +4059,9 @@ static void zend_traits_init_trait_structures(zend_class_entry *ce TSRMLS_DC) /*
/** And, ensure that the referenced method is resolvable, too. */
lcname = zend_str_tolower_dup(cur_method_ref->method_name,
- cur_method_ref->mname_len);
+ cur_method_ref->mname_len);
method_exists = zend_hash_exists(&cur_method_ref->ce->function_table,
- lcname, cur_method_ref->mname_len + 1);
+ lcname, cur_method_ref->mname_len + 1);
efree(lcname);
if (!method_exists) {
@@ -5043,11 +5043,11 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name
opline->op2_type = IS_CONST;
if (doing_inheritance) {
- /* Make sure a trait does not try to extend a class */
- if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
- zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name);
- }
-
+ /* Make sure a trait does not try to extend a class */
+ if ((new_class_entry->ce_flags & ZEND_ACC_TRAIT) == ZEND_ACC_TRAIT) {
+ zend_error(E_COMPILE_ERROR, "A trait (%s) cannot extend a class. Traits can only be composed from other traits with the 'use' keyword. Error", new_class_entry->name);
+ }
+
opline->extended_value = parent_class_name->u.op.var;
opline->opcode = ZEND_DECLARE_INHERITED_CLASS;
} else {
@@ -6998,9 +6998,9 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{
lcname = zend_str_tolower_dup(Z_STRVAL_P(name), Z_STRLEN_P(name));
if (((Z_STRLEN_P(name) == sizeof("self")-1) &&
- !memcmp(lcname, "self", sizeof("self")-1)) ||
- ((Z_STRLEN_P(name) == sizeof("parent")-1) &&
- !memcmp(lcname, "parent", sizeof("parent")-1))) {
+ !memcmp(lcname, "self", sizeof("self")-1)) ||
+ ((Z_STRLEN_P(name) == sizeof("parent")-1) &&
+ !memcmp(lcname, "parent", sizeof("parent")-1))) {
zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because '%s' is a special class name", Z_STRVAL_P(ns), Z_STRVAL_P(name), Z_STRVAL_P(name));
}
View
@@ -281,7 +281,7 @@ struct _zend_op_array {
zend_try_catch_element *try_catch_array;
int last_try_catch;
- zend_bool has_finally_block;
+ zend_bool has_finally_block;
/* static variables support */
HashTable *static_variables;
@@ -384,8 +384,8 @@ struct _zend_execute_data {
zend_class_entry *current_called_scope;
zval *current_this;
zval *current_object;
- zend_uint leaving;
- zend_uint leaving_dest;
+ zend_uint leaving;
+ zend_uint leaving_dest;
};
#define EX(element) execute_data.element
View
@@ -87,7 +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->has_finally_block = 0;
op_array->this_var = -1;
@@ -552,8 +552,8 @@ ZEND_API int pass_two(zend_op_array *op_array TSRMLS_DC)
}
opline->op1.jmp_addr = &op_array->opcodes[opline->op1.opline_num];
break;
- case ZEND_BRK:
- case ZEND_CONT:
+ case ZEND_BRK:
+ case ZEND_CONT:
if (op_array->last_try_catch) {
int nest_levels, array_offset;
zend_brk_cont_element *jmp_to;
Oops, something went wrong.

0 comments on commit 60a2979

Please sign in to comment.