24
24
#include "zend_optimizer_internal.h"
25
25
#include "zend_sort.h"
26
26
27
- static void zend_mark_reachable (zend_op * opcodes , zend_cfg * cfg , zend_basic_block * b ) /* {{{ */
27
+ static zend_result zend_mark_reachable (zend_op * opcodes , zend_cfg * cfg , zend_basic_block * b ) /* {{{ */
28
28
{
29
29
zend_basic_block * blocks = cfg -> blocks ;
30
30
31
+ if (UNEXPECTED (zend_call_stack_overflowed (EG (stack_limit )))) {
32
+ return FAILURE ;
33
+ }
34
+
31
35
while (1 ) {
32
36
int i ;
33
37
34
38
b -> flags |= ZEND_BB_REACHABLE ;
35
39
if (b -> successors_count == 0 ) {
36
40
b -> flags |= ZEND_BB_EXIT ;
37
- return ;
41
+ return SUCCESS ;
38
42
}
39
43
40
44
for (i = 0 ; i < b -> successors_count ; i ++ ) {
@@ -89,28 +93,32 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
89
93
if (i == b -> successors_count - 1 ) {
90
94
/* Tail call optimization */
91
95
if (succ -> flags & ZEND_BB_REACHABLE ) {
92
- return ;
96
+ return SUCCESS ;
93
97
}
94
98
95
99
b = succ ;
96
100
break ;
97
101
} else {
98
102
/* Recursively check reachability */
99
103
if (!(succ -> flags & ZEND_BB_REACHABLE )) {
100
- zend_mark_reachable (opcodes , cfg , succ );
104
+ if (zend_mark_reachable (opcodes , cfg , succ ) != SUCCESS ) {
105
+ return FAILURE ;
106
+ }
101
107
}
102
108
}
103
109
}
104
110
}
105
111
}
106
112
/* }}} */
107
113
108
- static void zend_mark_reachable_blocks (const zend_op_array * op_array , zend_cfg * cfg , int start ) /* {{{ */
114
+ static zend_result zend_mark_reachable_blocks (const zend_op_array * op_array , zend_cfg * cfg , int start ) /* {{{ */
109
115
{
110
116
zend_basic_block * blocks = cfg -> blocks ;
111
117
112
118
blocks [start ].flags = ZEND_BB_START ;
113
- zend_mark_reachable (op_array -> opcodes , cfg , blocks + start );
119
+ if (zend_mark_reachable (op_array -> opcodes , cfg , blocks + start ) != SUCCESS ) {
120
+ return FAILURE ;
121
+ }
114
122
115
123
if (op_array -> last_try_catch ) {
116
124
zend_basic_block * b ;
@@ -146,7 +154,9 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
146
154
if (b -> flags & ZEND_BB_REACHABLE ) {
147
155
op_array -> try_catch_array [j ].try_op = op_array -> try_catch_array [j ].catch_op ;
148
156
changed = 1 ;
149
- zend_mark_reachable (op_array -> opcodes , cfg , blocks + block_map [op_array -> try_catch_array [j ].try_op ]);
157
+ if (zend_mark_reachable (op_array -> opcodes , cfg , blocks + block_map [op_array -> try_catch_array [j ].try_op ]) != SUCCESS ) {
158
+ return FAILURE ;
159
+ }
150
160
break ;
151
161
}
152
162
b ++ ;
@@ -163,23 +173,29 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
163
173
b -> flags |= ZEND_BB_CATCH ;
164
174
if (!(b -> flags & ZEND_BB_REACHABLE )) {
165
175
changed = 1 ;
166
- zend_mark_reachable (op_array -> opcodes , cfg , b );
176
+ if (zend_mark_reachable (op_array -> opcodes , cfg , b ) != SUCCESS ) {
177
+ return FAILURE ;
178
+ }
167
179
}
168
180
}
169
181
if (op_array -> try_catch_array [j ].finally_op ) {
170
182
b = blocks + block_map [op_array -> try_catch_array [j ].finally_op ];
171
183
b -> flags |= ZEND_BB_FINALLY ;
172
184
if (!(b -> flags & ZEND_BB_REACHABLE )) {
173
185
changed = 1 ;
174
- zend_mark_reachable (op_array -> opcodes , cfg , b );
186
+ if (zend_mark_reachable (op_array -> opcodes , cfg , b ) != SUCCESS ) {
187
+ return FAILURE ;
188
+ }
175
189
}
176
190
}
177
191
if (op_array -> try_catch_array [j ].finally_end ) {
178
192
b = blocks + block_map [op_array -> try_catch_array [j ].finally_end ];
179
193
b -> flags |= ZEND_BB_FINALLY_END ;
180
194
if (!(b -> flags & ZEND_BB_REACHABLE )) {
181
195
changed = 1 ;
182
- zend_mark_reachable (op_array -> opcodes , cfg , b );
196
+ if (zend_mark_reachable (op_array -> opcodes , cfg , b ) != SUCCESS ) {
197
+ return FAILURE ;
198
+ }
183
199
}
184
200
}
185
201
} else {
@@ -223,10 +239,12 @@ static void zend_mark_reachable_blocks(const zend_op_array *op_array, zend_cfg *
223
239
}
224
240
}
225
241
}
242
+
243
+ return SUCCESS ;
226
244
}
227
245
/* }}} */
228
246
229
- void zend_cfg_remark_reachable_blocks (const zend_op_array * op_array , zend_cfg * cfg ) /* {{{ */
247
+ zend_result zend_cfg_remark_reachable_blocks (const zend_op_array * op_array , zend_cfg * cfg ) /* {{{ */
230
248
{
231
249
zend_basic_block * blocks = cfg -> blocks ;
232
250
int i ;
@@ -245,7 +263,7 @@ void zend_cfg_remark_reachable_blocks(const zend_op_array *op_array, zend_cfg *c
245
263
blocks [i ].flags = 0 ;
246
264
}
247
265
248
- zend_mark_reachable_blocks (op_array , cfg , start );
266
+ return zend_mark_reachable_blocks (op_array , cfg , start );
249
267
}
250
268
/* }}} */
251
269
@@ -267,7 +285,7 @@ static void initialize_block(zend_basic_block *block) {
267
285
block_map[i]++; \
268
286
} while (0)
269
287
270
- ZEND_API void zend_build_cfg (zend_arena * * arena , const zend_op_array * op_array , uint32_t build_flags , zend_cfg * cfg ) /* {{{ */
288
+ ZEND_API zend_result zend_build_cfg (zend_arena * * arena , const zend_op_array * op_array , uint32_t build_flags , zend_cfg * cfg ) /* {{{ */
271
289
{
272
290
uint32_t flags = 0 ;
273
291
uint32_t i ;
@@ -587,7 +605,7 @@ ZEND_API void zend_build_cfg(zend_arena **arena, const zend_op_array *op_array,
587
605
588
606
/* Build CFG, Step 4, Mark Reachable Basic Blocks */
589
607
cfg -> flags |= flags ;
590
- zend_mark_reachable_blocks (op_array , cfg , 0 );
608
+ return zend_mark_reachable_blocks (op_array , cfg , 0 );
591
609
}
592
610
/* }}} */
593
611
0 commit comments