]> granicus.if.org Git - php/commitdiff
@ Allow a series of consecutive catch() statements (Andi, Zend Engine)
authorAndi Gutmans <andi@php.net>
Wed, 13 Feb 2002 19:26:07 +0000 (19:26 +0000)
committerAndi Gutmans <andi@php.net>
Wed, 13 Feb 2002 19:26:07 +0000 (19:26 +0000)
<?php
class MyException1 {

}

class MyException2 {

}

try {
throw new MyException2();
} catch (MyException1 $m) {
print "Caught MyException1";
} catch (MyException2 $m) {
print "Caught MyException2";
}

Zend/zend_compile.c
Zend/zend_compile.h
Zend/zend_language_parser.y

index b4010ea1a4038da22104c8a0b99ee2fa44f43589..865cdfc1dc8df73f00a11a027342cb5305ba3bc2 100644 (file)
@@ -1255,7 +1255,7 @@ static void throw_list_applier(long *opline_num, long *catch_opline)
        }
 }
 
-void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var TSRMLS_DC)
+void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, zend_bool first_catch TSRMLS_DC)
 {
        long catch_op_number = get_next_op_number(CG(active_op_array));
        zend_op *opline;
@@ -1266,11 +1266,12 @@ void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var
        SET_UNUSED(opline->op1); /* FIXME: Define IS_CLASS or something like that */
        opline->op2 = *catch_var;
 
-       zend_llist_apply_with_argument(CG(throw_list), (llist_apply_with_arg_func_t) throw_list_applier, &CG(catch_begin) TSRMLS_CC);
-       zend_llist_destroy(CG(throw_list));
-       efree(CG(throw_list));
-       CG(throw_list) = (void *) try_token->throw_list;
-
+       if (first_catch) {
+               zend_llist_apply_with_argument(CG(throw_list), (llist_apply_with_arg_func_t) throw_list_applier, &CG(catch_begin) TSRMLS_CC);
+               zend_llist_destroy(CG(throw_list));
+               efree(CG(throw_list));
+               CG(throw_list) = (void *) try_token->throw_list;
+       }
        try_token->u.opline_num = catch_op_number;
 }
 
index 52d43d2b8806bea504799916eada2447eaf61ba2..0a07932ee7a0ce3e5e71042d595c14895dd20e3f 100644 (file)
@@ -279,7 +279,7 @@ void zend_do_end_function_call(znode *function_name, znode *result, znode *argum
 void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC);
 
 void zend_do_try(znode *try_token TSRMLS_DC);
-void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var TSRMLS_DC);
+void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var, zend_bool first_catch TSRMLS_DC);
 void zend_do_end_catch(znode *try_token TSRMLS_DC);
 void zend_do_throw(znode *expr TSRMLS_DC);
 
index 8d61e973ca0a704bc4ea3da2947fa0a26394301f..30f04d874ae132d043bf0c5e5bed7591b3efcf23 100644 (file)
@@ -206,11 +206,17 @@ unticked_statement:
        |       T_DECLARE { zend_do_declare_begin(TSRMLS_C); } '(' declare_list ')' declare_statement { zend_do_declare_end(TSRMLS_C); }
        |       ';'             /* empty statement */
        |       T_TRY { zend_do_try(&$1 TSRMLS_CC); } '{' inner_statement_list '}'
-                       T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$8, &$9 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+                       catches
        |       T_THROW expr ';' { zend_do_throw(&$2 TSRMLS_CC); }
        |       T_DELETE  cvar  ';' { zend_do_end_variable_parse(BP_VAR_UNSET, 0 TSRMLS_CC); zend_do_unset(&$1, ZEND_UNSET_OBJ TSRMLS_CC); }
 ;
 
+catches:
+               catches T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$2, &$4, &$5, 0 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$2 TSRMLS_CC); }
+       |       T_CATCH '(' catch_class_entry T_VARIABLE ')' { zend_do_begin_catch(&$1, &$3, &$4, 1 TSRMLS_CC); } '{' inner_statement_list '}' { zend_do_end_catch(&$1 TSRMLS_CC); }
+;
+
+
 unset_variables:
                unset_variable
        |       unset_variables ',' unset_variable