@@ -122,7 +122,6 @@ void zend_init_compiler_data_structures(TSRMLS_D)
122
122
CG (in_compilation ) = 0 ;
123
123
CG (start_lineno ) = 0 ;
124
124
init_compiler_declarables (TSRMLS_C );
125
- CG (throw_list ) = NULL ;
126
125
zend_hash_apply (CG (auto_globals ), (apply_func_t ) zend_auto_global_arm TSRMLS_CC );
127
126
128
127
#ifdef ZEND_MULTIBYTE
@@ -1085,8 +1084,6 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
1085
1084
1086
1085
zend_stack_push (& CG (foreach_copy_stack ), (void * ) & switch_entry .cond , sizeof (znode ));
1087
1086
}
1088
- function_token -> throw_list = CG (throw_list );
1089
- CG (throw_list ) = NULL ;
1090
1087
1091
1088
if (CG (doc_comment )) {
1092
1089
CG (active_op_array )-> doc_comment = estrndup (CG (doc_comment ), CG (doc_comment_len ));
@@ -1095,11 +1092,22 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n
1095
1092
}
1096
1093
}
1097
1094
1095
+ void zend_do_handle_exception (TSRMLS_D )
1096
+ {
1097
+ zend_op * opline = get_next_op (CG (active_op_array ) TSRMLS_CC );
1098
+
1099
+ opline -> opcode = ZEND_HANDLE_EXCEPTION ;
1100
+ SET_UNUSED (opline -> op1 );
1101
+ SET_UNUSED (opline -> op2 );
1102
+ }
1103
+
1098
1104
1099
1105
void zend_do_end_function_declaration (znode * function_token TSRMLS_DC )
1100
1106
{
1101
1107
zend_do_extended_info (TSRMLS_C );
1102
1108
zend_do_return (NULL , 0 TSRMLS_CC );
1109
+ zend_do_handle_exception (TSRMLS_C );
1110
+
1103
1111
pass_two (CG (active_op_array ) TSRMLS_CC );
1104
1112
1105
1113
if (CG (active_class_entry )
@@ -1115,8 +1123,6 @@ void zend_do_end_function_declaration(znode *function_token TSRMLS_DC)
1115
1123
/* Pop the switch and foreach seperators */
1116
1124
zend_stack_del_top (& CG (switch_cond_stack ));
1117
1125
zend_stack_del_top (& CG (foreach_copy_stack ));
1118
-
1119
- CG (throw_list ) = function_token -> throw_list ;
1120
1126
}
1121
1127
1122
1128
@@ -1358,16 +1364,6 @@ void zend_do_end_function_call(znode *function_name, znode *result, znode *argum
1358
1364
* result = opline -> result ;
1359
1365
SET_UNUSED (opline -> op2 );
1360
1366
1361
- /* Check how much this is really needed
1362
- opline->op2.u.constant.value.lval = is_method;
1363
- */
1364
- if (CG (throw_list ) != NULL ) {
1365
- long op_number = get_next_op_number (CG (active_op_array ))- 1 ;
1366
- zend_llist_add_element (CG (throw_list ), & op_number );
1367
- } else {
1368
- opline -> op2 .u .opline_num = -1 ;
1369
- }
1370
-
1371
1367
zend_stack_del_top (& CG (function_call_stack ));
1372
1368
opline -> extended_value = argument_list -> u .constant .value .lval ;
1373
1369
}
@@ -1536,12 +1532,46 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC)
1536
1532
}
1537
1533
1538
1534
1535
+ static int zend_add_try_element (zend_uint try_op TSRMLS_DC )
1536
+ {
1537
+ int try_catch_offset = CG (active_op_array )-> last_try_catch ++ ;
1538
+
1539
+ CG (active_op_array )-> try_catch_array = erealloc (CG (active_op_array )-> try_catch_array , sizeof (zend_try_catch_element )* CG (active_op_array )-> last_try_catch );
1540
+ CG (active_op_array )-> try_catch_array [try_catch_offset ].try_op = try_op ;
1541
+ return try_catch_offset ;
1542
+ }
1543
+
1544
+ static void zend_add_catch_element (int offset , zend_uint catch_op TSRMLS_DC )
1545
+ {
1546
+ CG (active_op_array )-> try_catch_array [offset ].catch_op = catch_op ;
1547
+ }
1548
+
1549
+
1550
+ void zend_do_first_catch (znode * open_parentheses TSRMLS_DC )
1551
+ {
1552
+ open_parentheses -> u .opline_num = get_next_op_number (CG (active_op_array ));
1553
+ }
1554
+
1555
+
1556
+ void zend_initialize_try_catch_element (znode * try_token TSRMLS_DC )
1557
+ {
1558
+ zend_add_catch_element (try_token -> u .opline_num , get_next_op_number (CG (active_op_array )) TSRMLS_CC );
1559
+ }
1560
+
1561
+
1562
+ void zend_do_mark_last_catch (znode * first_catch , znode * last_additional_catch TSRMLS_DC )
1563
+ {
1564
+ if (last_additional_catch -> u .opline_num == -1 ) {
1565
+ CG (active_op_array )-> opcodes [first_catch -> u .opline_num ].op1 .u .EA .type = 1 ;
1566
+ } else {
1567
+ CG (active_op_array )-> opcodes [last_additional_catch -> u .opline_num ].op1 .u .EA .type = 1 ;
1568
+ }
1569
+ }
1570
+
1571
+
1539
1572
void zend_do_try (znode * try_token TSRMLS_DC )
1540
1573
{
1541
- try_token -> throw_list = (void * ) CG (throw_list );
1542
- CG (throw_list ) = (zend_llist * ) emalloc (sizeof (zend_llist ));
1543
- zend_llist_init (CG (throw_list ), sizeof (long ), NULL , 0 );
1544
- /* Initialize try backpatch list used to backpatch throw, do_fcall */
1574
+ try_token -> u .opline_num = zend_add_try_element (get_next_op_number (CG (active_op_array )) TSRMLS_CC );
1545
1575
}
1546
1576
1547
1577
static void throw_list_applier (long * opline_num , long * catch_opline )
@@ -1575,13 +1605,8 @@ void zend_do_begin_catch(znode *try_token, znode *catch_class, znode *catch_var,
1575
1605
opline -> op1 = * catch_class ;
1576
1606
/* SET_UNUSED(opline->op1); */ /* FIXME: Define IS_CLASS or something like that */
1577
1607
opline -> op2 = * catch_var ;
1608
+ opline -> op1 .u .EA .type = 0 ; /* 1 means it's the last catch in the block */
1578
1609
1579
- if (first_catch ) {
1580
- zend_llist_apply_with_argument (CG (throw_list ), (llist_apply_with_arg_func_t ) throw_list_applier , & CG (catch_begin ) TSRMLS_CC );
1581
- zend_llist_destroy (CG (throw_list ));
1582
- efree (CG (throw_list ));
1583
- CG (throw_list ) = (void * ) try_token -> throw_list ;
1584
- }
1585
1610
try_token -> u .opline_num = catch_op_number ;
1586
1611
}
1587
1612
@@ -1599,12 +1624,6 @@ void zend_do_throw(znode *expr TSRMLS_DC)
1599
1624
opline -> opcode = ZEND_THROW ;
1600
1625
opline -> op1 = * expr ;
1601
1626
SET_UNUSED (opline -> op2 );
1602
-
1603
- if (CG (throw_list ) != NULL ) {
1604
- zend_llist_add_element (CG (throw_list ), & throw_op_number );
1605
- } else {
1606
- opline -> op2 .u .opline_num = -1 ;
1607
- }
1608
1627
}
1609
1628
1610
1629
ZEND_API void function_add_ref (zend_function * function )
0 commit comments