@@ -302,35 +302,41 @@ PHP_FUNCTION(opencensus_trace_add_message_event)
302302 RETURN_FALSE ;
303303}
304304
305- /**
306- * Call the provided callback with the provided parameters to the traced
307- * function. The callback must return an array or an E_WARNING is raised.
308- */
309- static int opencensus_trace_call_user_function_callback (zend_execute_data * execute_data , opencensus_trace_span_t * span , zval * callback , zval * callback_result TSRMLS_DC )
305+ static void opencensus_copy_args (zend_execute_data * execute_data , zval * * args , int * ret_num_args )
310306{
311- int i , num_args = EX_NUM_ARGS (), has_scope = 0 ;
312- zval * args = emalloc ((num_args + 1 ) * sizeof (zval ));
307+ int i , num_args = ZEND_CALL_NUM_ARGS (execute_data ), has_scope = 0 ;
308+ zval * arguments = emalloc ((num_args + 1 ) * sizeof (zval ));
309+ * args = arguments ;
313310
314311 if (getThis () != NULL ) {
315312 has_scope = 1 ;
316- ZVAL_COPY (& args [0 ], getThis ());
313+ ZVAL_COPY (& arguments [0 ], getThis ());
317314 }
318315
319316 for (i = 0 ; i < num_args ; i ++ ) {
320- ZVAL_COPY (& args [i + has_scope ], EX_VAR_NUM ( i ));
317+ ZVAL_COPY (& arguments [i + has_scope ], ZEND_CALL_VAR_NUM ( execute_data , i ));
321318 }
319+ * ret_num_args = num_args + has_scope ;
320+ }
322321
323- if (call_user_function_ex (EG (function_table ), NULL , callback , callback_result , num_args + has_scope , args , 0 , NULL ) != SUCCESS ) {
324- for (i = 0 ; i < num_args + has_scope ; i ++ ) {
325- ZVAL_DESTRUCTOR (& args [i ]);
326- }
327- efree (args );
328- return FAILURE ;
329- }
330- for (i = 0 ; i < num_args + has_scope ; i ++ ) {
322+ static void opencensus_free_args (zval * args , int num_args )
323+ {
324+ int i ;
325+ for (i = 0 ; i < num_args ; i ++ ) {
331326 ZVAL_DESTRUCTOR (& args [i ]);
332327 }
333328 efree (args );
329+ }
330+
331+ /**
332+ * Call the provided callback with the provided parameters to the traced
333+ * function. The callback must return an array or an E_WARNING is raised.
334+ */
335+ static int opencensus_trace_call_user_function_callback (zval * args , int num_args , zend_execute_data * execute_data , opencensus_trace_span_t * span , zval * callback , zval * callback_result TSRMLS_DC )
336+ {
337+ if (call_user_function_ex (EG (function_table ), NULL , callback , callback_result , num_args , args , 0 , NULL ) != SUCCESS ) {
338+ return FAILURE ;
339+ }
334340
335341 if (EG (exception ) != NULL ) {
336342 php_error_docref (NULL , E_WARNING , "Exception in trace callback" );
@@ -347,29 +353,6 @@ static int opencensus_trace_call_user_function_callback(zend_execute_data *execu
347353 return SUCCESS ;
348354}
349355
350- /**
351- * Handle the callback for the traced method depending on the type
352- * - if the zval is an associative array, then assume it's the trace span initialization
353- * options
354- * - if the zval is an array that looks like a callable, then assume it's a callable
355- * - if the zval is a Closure, then execute the closure and take the results as
356- * the trace span initialization options
357- */
358- static void opencensus_trace_execute_callback (opencensus_trace_span_t * span , zend_execute_data * execute_data , zval * span_options TSRMLS_DC )
359- {
360- zend_string * callback_name = NULL ;
361- if (zend_is_callable (span_options , 0 , & callback_name )) {
362- zval callback_result ;
363- if (opencensus_trace_call_user_function_callback (execute_data , span , span_options , & callback_result TSRMLS_CC ) == SUCCESS ) {
364- opencensus_trace_span_apply_span_options (span , & callback_result );
365- }
366- ZVAL_DESTRUCTOR (& callback_result );
367- } else if (Z_TYPE_P (span_options ) == IS_ARRAY ) {
368- opencensus_trace_span_apply_span_options (span , span_options );
369- }
370- zend_string_release (callback_name );
371- }
372-
373356/**
374357 * Force the random span id to be positive. php_mt_rand() generates 32 bits
375358 * of randomness. On 32-bit systems, we must cast to an unsigned int before
@@ -491,12 +474,12 @@ PHP_FUNCTION(opencensus_trace_begin)
491474 if (span_options == NULL ) {
492475 array_init (& default_span_options );
493476 span = opencensus_trace_begin (function_name , execute_data , NULL TSRMLS_CC );
494- opencensus_trace_execute_callback (span , execute_data , & default_span_options TSRMLS_CC );
477+ opencensus_trace_span_apply_span_options (span , & default_span_options );
495478 ZVAL_DESTRUCTOR (& default_span_options );
496479 } else {
497480 span_id = span_id_from_options (Z_ARR_P (span_options ));
498481 span = opencensus_trace_begin (function_name , execute_data , span_id TSRMLS_CC );
499- opencensus_trace_execute_callback (span , execute_data , span_options TSRMLS_CC );
482+ opencensus_trace_span_apply_span_options (span , span_options );
500483 }
501484
502485 RETURN_TRUE ;
@@ -614,22 +597,46 @@ void opencensus_trace_execute_ex (zend_execute_data *execute_data TSRMLS_DC) {
614597 );
615598 zval * trace_handler ;
616599 opencensus_trace_span_t * span ;
600+ zend_string * callback_name = NULL ;
601+
602+ /* Some functions have no names - just execute them */
603+ if (function_name == NULL ) {
604+ opencensus_original_zend_execute_ex (execute_data TSRMLS_CC );
605+ return ;
606+ }
617607
618- if (function_name ) {
619- trace_handler = zend_hash_find (OPENCENSUS_TRACE_G (user_traced_functions ), function_name );
608+ trace_handler = zend_hash_find (OPENCENSUS_TRACE_G (user_traced_functions ), function_name );
620609
621- if (trace_handler != NULL ) {
622- span = opencensus_trace_begin (function_name , execute_data , NULL TSRMLS_CC );
623- opencensus_original_zend_execute_ex (execute_data TSRMLS_CC );
624- opencensus_trace_execute_callback (span , execute_data , trace_handler TSRMLS_CC );
625- opencensus_trace_finish ();
626- } else {
627- opencensus_original_zend_execute_ex (execute_data TSRMLS_CC );
628- }
610+ /* Function is not registered for execution - continue normal execution */
611+ if (trace_handler == NULL ) {
612+ opencensus_original_zend_execute_ex (execute_data TSRMLS_CC );
629613 zend_string_release (function_name );
614+ return ;
615+ }
616+
617+ span = opencensus_trace_begin (function_name , execute_data , NULL TSRMLS_CC );
618+ zend_string_release (function_name );
619+
620+ if (zend_is_callable (trace_handler , 0 , & callback_name )) {
621+ /* Registered handler is callable - execute the callback */
622+ zval callback_result , * args ;
623+ int num_args ;
624+ opencensus_copy_args (execute_data , & args , & num_args );
625+ opencensus_original_zend_execute_ex (execute_data TSRMLS_CC );
626+ if (opencensus_trace_call_user_function_callback (args , num_args , execute_data , span , trace_handler , & callback_result TSRMLS_CC ) == SUCCESS ) {
627+ opencensus_trace_span_apply_span_options (span , & callback_result );
628+ }
629+ opencensus_free_args (args , num_args );
630+ ZVAL_DESTRUCTOR (& callback_result );
630631 } else {
632+ /* Registered handler is span options array */
631633 opencensus_original_zend_execute_ex (execute_data TSRMLS_CC );
634+ if (Z_TYPE_P (trace_handler ) == IS_ARRAY ) {
635+ opencensus_trace_span_apply_span_options (span , trace_handler );
636+ }
632637 }
638+ zend_string_release (callback_name );
639+ opencensus_trace_finish ();
633640}
634641
635642/**
@@ -657,22 +664,46 @@ void opencensus_trace_execute_internal(INTERNAL_FUNCTION_PARAMETERS)
657664 );
658665 zval * trace_handler ;
659666 opencensus_trace_span_t * span ;
667+ zend_string * callback_name = NULL ;
660668
661- if (function_name ) {
662- trace_handler = zend_hash_find (OPENCENSUS_TRACE_G (user_traced_functions ), function_name );
669+ /* Some functions have no names - just execute them */
670+ if (function_name == NULL ) {
671+ resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
672+ return ;
673+ }
663674
664- if (trace_handler ) {
665- span = opencensus_trace_begin (function_name , execute_data , NULL TSRMLS_CC );
666- resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
667- opencensus_trace_execute_callback (span , execute_data , trace_handler TSRMLS_CC );
668- opencensus_trace_finish ();
669- } else {
670- resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
671- }
675+ trace_handler = zend_hash_find (OPENCENSUS_TRACE_G (user_traced_functions ), function_name );
676+
677+ /* Function is not registered for execution - continue normal execution */
678+ if (trace_handler == NULL ) {
679+ resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
672680 zend_string_release (function_name );
681+ return ;
682+ }
683+
684+ span = opencensus_trace_begin (function_name , execute_data , NULL TSRMLS_CC );
685+ zend_string_release (function_name );
686+
687+ if (zend_is_callable (trace_handler , 0 , & callback_name )) {
688+ /* Registered handler is callable - execute the callback */
689+ zval callback_result , * args ;
690+ int num_args ;
691+ opencensus_copy_args (execute_data , & args , & num_args );
692+ resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
693+ if (opencensus_trace_call_user_function_callback (args , num_args , execute_data , span , trace_handler , & callback_result TSRMLS_CC ) == SUCCESS ) {
694+ opencensus_trace_span_apply_span_options (span , & callback_result );
695+ }
696+ opencensus_free_args (args , num_args );
697+ ZVAL_DESTRUCTOR (& callback_result );
673698 } else {
699+ /* Registered handler is span options array */
674700 resume_execute_internal (INTERNAL_FUNCTION_PARAM_PASSTHRU );
701+ if (Z_TYPE_P (trace_handler ) == IS_ARRAY ) {
702+ opencensus_trace_span_apply_span_options (span , trace_handler );
703+ }
675704 }
705+ zend_string_release (callback_name );
706+ opencensus_trace_finish ();
676707}
677708
678709/**
0 commit comments