@@ -44,11 +44,13 @@ zend_llist zend_observer_error_callbacks;
4444int zend_observer_fcall_op_array_extension = -1 ;
4545
4646ZEND_TLS zend_arena * fcall_handlers_arena = NULL ;
47+ ZEND_TLS zend_execute_data * first_observed_frame = NULL ;
48+ ZEND_TLS zend_execute_data * current_observed_frame = NULL ;
4749
4850// Call during minit/startup ONLY
4951ZEND_API void zend_observer_fcall_register (zend_observer_fcall_init init ) {
50- /* We don't want to get an extension handle unless an ext installs an observer */
5152 if (!ZEND_OBSERVER_ENABLED ) {
53+ /* We don't want to get an extension handle unless an ext installs an observer */
5254 zend_observer_fcall_op_array_extension =
5355 zend_get_op_array_extension_handle ("Zend Observer" );
5456
@@ -160,6 +162,11 @@ static void ZEND_FASTCALL _zend_observe_fcall_begin(zend_execute_data *execute_d
160162 return ;
161163 }
162164
165+ if (first_observed_frame == NULL ) {
166+ first_observed_frame = execute_data ;
167+ }
168+ current_observed_frame = execute_data ;
169+
163170 end = fcall_data -> end ;
164171 for (handlers = fcall_data -> handlers ; handlers != end ; ++ handlers ) {
165172 if (handlers -> begin ) {
@@ -208,6 +215,25 @@ ZEND_API void ZEND_FASTCALL zend_observer_fcall_end(
208215 handlers -> end (execute_data , return_value );
209216 }
210217 }
218+
219+ if (first_observed_frame == execute_data ) {
220+ first_observed_frame = NULL ;
221+ current_observed_frame = NULL ;
222+ } else {
223+ current_observed_frame = execute_data -> prev_execute_data ;
224+ }
225+ }
226+
227+ ZEND_API void zend_observer_fcall_end_all (void )
228+ {
229+ zend_execute_data * ex = current_observed_frame ;
230+ while (ex != NULL ) {
231+ if (ex -> func -> type != ZEND_INTERNAL_FUNCTION ) {
232+ zend_observer_fcall_end (ex , NULL );
233+ }
234+ ex = ex -> prev_execute_data ;
235+ }
236+ current_observed_frame = NULL ;
211237}
212238
213239ZEND_API void zend_observer_error_register (zend_observer_error_cb cb )
0 commit comments