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