@@ -37,8 +37,8 @@ typedef struct {
37
37
} dd_closure_list ;
38
38
39
39
typedef struct {
40
- zend_object * begin ;
41
- zend_object * end ;
40
+ dd_uhook_callback begin ;
41
+ dd_uhook_callback end ;
42
42
bool running ;
43
43
zend_long id ;
44
44
@@ -75,6 +75,33 @@ typedef struct {
75
75
dd_hook_data * hook_data ;
76
76
} dd_uhook_dynamic ;
77
77
78
+ void dd_uhook_callback_apply_scope (dd_uhook_callback * cb , zend_class_entry * scope ) {
79
+ zend_function * func = (zend_function * )zend_get_closure_method_def (cb -> closure );
80
+ if (!cb -> fcc .function_handler ) {
81
+ cb -> is_static = func -> common .fn_flags & ZEND_ACC_STATIC ;
82
+ if (cb -> is_static ) {
83
+ goto end ;
84
+ }
85
+ }
86
+ if (GC_REFCOUNT (cb -> closure ) == 1 ) {
87
+ func -> common .scope = scope ;
88
+ if (!(func -> common .fn_flags & ZEND_ACC_HEAP_RT_CACHE )) {
89
+ func -> op_array .fn_flags |= ZEND_ACC_HEAP_RT_CACHE ;
90
+ ZEND_MAP_PTR_INIT (func -> op_array .run_time_cache , emalloc (func -> op_array .cache_size ));
91
+ }
92
+ } else {
93
+ zval zv ;
94
+ zend_create_closure (& zv , func , scope , scope , NULL );
95
+ OBJ_RELEASE (cb -> closure );
96
+ cb -> closure = Z_OBJ (zv );
97
+ func = (zend_function * )zend_get_closure_method_def (cb -> closure );
98
+ }
99
+ memset (ZEND_MAP_PTR_GET (func -> op_array .run_time_cache ), 0 , func -> op_array .cache_size );
100
+ end :
101
+ cb -> fcc .function_handler = func ;
102
+ cb -> fcc .called_scope = func -> common .scope ;
103
+ }
104
+
78
105
static zend_object * dd_hook_data_create (zend_class_entry * class_type ) {
79
106
dd_hook_data * hook_data = ecalloc (1 , sizeof (* hook_data ));
80
107
zend_object_std_init (& hook_data -> std , class_type );
@@ -192,20 +219,18 @@ void dd_uhook_report_sandbox_error(zend_execute_data *execute_data, zend_object
192
219
})
193
220
}
194
221
195
- static bool dd_uhook_call_hook (zend_execute_data * execute_data , zend_object * closure , dd_hook_data * hook_data ) {
196
- zval closure_zv , hook_data_zv ;
197
- ZVAL_OBJ (& closure_zv , closure );
222
+ static bool dd_uhook_call_hook (zend_execute_data * execute_data , dd_uhook_callback * callback , dd_hook_data * hook_data ) {
223
+ zval hook_data_zv ;
198
224
ZVAL_OBJ (& hook_data_zv , & hook_data -> std );
199
225
200
- bool has_this = getThis () != NULL ;
201
226
zval rv ;
202
227
zai_sandbox sandbox ;
203
228
zai_sandbox_open (& sandbox );
204
- bool success = zai_symbol_call ( has_this ? ZAI_SYMBOL_SCOPE_OBJECT : ZAI_SYMBOL_SCOPE_GLOBAL , has_this ? & EX ( This ) : NULL ,
205
- ZAI_SYMBOL_FUNCTION_CLOSURE , & closure_zv ,
206
- & rv , 1 | ZAI_SYMBOL_SANDBOX , & sandbox , & hook_data_zv );
229
+ dd_uhook_callback_ensure_scope ( callback , execute_data );
230
+ zend_fcall_info fci = dd_fcall_info ( 1 , & hook_data_zv , & rv );
231
+ bool success = zai_sandbox_call ( & sandbox , & fci , & callback -> fcc );
207
232
if (!success || PG (last_error_message )) {
208
- dd_uhook_report_sandbox_error (execute_data , closure );
233
+ dd_uhook_report_sandbox_error (execute_data , callback -> closure );
209
234
}
210
235
zai_sandbox_close (& sandbox );
211
236
zval_ptr_dtor (& rv );
@@ -298,7 +323,7 @@ static bool dd_uhook_begin(zend_ulong invocation, zend_execute_data *execute_dat
298
323
ZVAL_ARR (& dyn -> hook_data -> property_args , dd_uhook_collect_args (execute_data ));
299
324
}
300
325
301
- if (def -> begin && !def -> running ) {
326
+ if (def -> begin . closure && !def -> running ) {
302
327
dyn -> hook_data -> execute_data = execute_data ;
303
328
// We support it for PHP 8 for now, given we need this for PHP 8.1+ right now.
304
329
// Bringing it to PHP 7.1-7.4 is possible, but not done yet.
@@ -310,10 +335,10 @@ static bool dd_uhook_begin(zend_ulong invocation, zend_execute_data *execute_dat
310
335
}
311
336
#endif
312
337
313
- LOGEV (HOOK_TRACE , dd_uhook_log_invocation (log , execute_data , "begin" , def -> begin ););
338
+ LOGEV (HOOK_TRACE , dd_uhook_log_invocation (log , execute_data , "begin" , def -> begin . closure ););
314
339
315
340
def -> running = true;
316
- dd_uhook_call_hook (execute_data , def -> begin , dyn -> hook_data );
341
+ dd_uhook_call_hook (execute_data , & def -> begin , dyn -> hook_data );
317
342
def -> running = false;
318
343
dyn -> hook_data -> retval_ptr = NULL ;
319
344
}
@@ -395,7 +420,7 @@ static void dd_uhook_end(zend_ulong invocation, zend_execute_data *execute_data,
395
420
396
421
bool keep_span = true;
397
422
398
- if (def -> end && !def -> running && get_DD_TRACE_ENABLED ()) {
423
+ if (def -> end . closure && !def -> running && get_DD_TRACE_ENABLED ()) {
399
424
zval tmp ;
400
425
401
426
/* If the profiler doesn't handle a potential pending interrupt before
@@ -432,11 +457,11 @@ static void dd_uhook_end(zend_ulong invocation, zend_execute_data *execute_data,
432
457
}
433
458
zval_ptr_dtor (& tmp );
434
459
435
- LOGEV (HOOK_TRACE , dd_uhook_log_invocation (log , execute_data , "end" , def -> end ););
460
+ LOGEV (HOOK_TRACE , dd_uhook_log_invocation (log , execute_data , "end" , def -> end . closure ););
436
461
437
462
def -> running = true;
438
463
dyn -> hook_data -> retval_ptr = retval ;
439
- keep_span = dd_uhook_call_hook (execute_data , def -> end , dyn -> hook_data );
464
+ keep_span = dd_uhook_call_hook (execute_data , & def -> end , dyn -> hook_data );
440
465
dyn -> hook_data -> retval_ptr = NULL ;
441
466
def -> running = false;
442
467
}
@@ -485,11 +510,11 @@ static void dd_uhook_end(zend_ulong invocation, zend_execute_data *execute_data,
485
510
486
511
static void dd_uhook_dtor (void * data ) {
487
512
dd_uhook_def * def = data ;
488
- if (def -> begin ) {
489
- OBJ_RELEASE (def -> begin );
513
+ if (def -> begin . closure ) {
514
+ OBJ_RELEASE (def -> begin . closure );
490
515
}
491
- if (def -> end ) {
492
- OBJ_RELEASE (def -> end );
516
+ if (def -> end . closure ) {
517
+ OBJ_RELEASE (def -> end . closure );
493
518
}
494
519
if (def -> function ) {
495
520
zend_string_release (def -> function );
@@ -581,13 +606,15 @@ PHP_FUNCTION(DDTrace_install_hook) {
581
606
dd_uhook_def * def = emalloc (sizeof (* def ));
582
607
def -> closure = NULL ;
583
608
def -> running = false;
584
- def -> begin = begin ? Z_OBJ_P (begin ) : NULL ;
585
- if (def -> begin ) {
586
- GC_ADDREF (def -> begin );
609
+ def -> begin .fcc .function_handler = NULL ;
610
+ def -> begin .closure = begin ? Z_OBJ_P (begin ) : NULL ;
611
+ if (def -> begin .closure ) {
612
+ GC_ADDREF (def -> begin .closure );
587
613
}
588
- def -> end = end ? Z_OBJ_P (end ) : NULL ;
589
- if (def -> end ) {
590
- GC_ADDREF (def -> end );
614
+ def -> end .fcc .function_handler = NULL ;
615
+ def -> end .closure = end ? Z_OBJ_P (end ) : NULL ;
616
+ if (def -> end .closure ) {
617
+ GC_ADDREF (def -> end .closure );
591
618
}
592
619
def -> id = -1 ;
593
620
0 commit comments