26
26
#include "zend_closures.h"
27
27
#include "zend_weakrefs.h"
28
28
#include "main/SAPI.h"
29
+ #include "zend_observer.h"
29
30
30
31
#include <ffi.h>
31
32
@@ -5373,6 +5374,25 @@ static zend_result zend_ffi_preload(char *preload) /* {{{ */
5373
5374
}
5374
5375
/* }}} */
5375
5376
5377
+ /* The startup code for observers adds a temporary to each function for internal use.
5378
+ * The "new", "cast", and "type" functions in FFI are both static and non-static.
5379
+ * Only the static versions are in the function table and the non-static versions are not.
5380
+ * This means the non-static versions will be skipped by the observers startup code.
5381
+ * This function fixes that by incrementing the temporary count for the non-static versions.
5382
+ */
5383
+ static zend_result (* prev_zend_post_startup_cb )(void );
5384
+ static zend_result ffi_fixup_temporaries (void ) {
5385
+ if (ZEND_OBSERVER_ENABLED ) {
5386
+ ++ zend_ffi_new_fn .T ;
5387
+ ++ zend_ffi_cast_fn .T ;
5388
+ ++ zend_ffi_type_fn .T ;
5389
+ }
5390
+ if (prev_zend_post_startup_cb ) {
5391
+ return prev_zend_post_startup_cb ();
5392
+ }
5393
+ return SUCCESS ;
5394
+ }
5395
+
5376
5396
/* {{{ ZEND_MINIT_FUNCTION */
5377
5397
ZEND_MINIT_FUNCTION (ffi )
5378
5398
{
@@ -5395,6 +5415,9 @@ ZEND_MINIT_FUNCTION(ffi)
5395
5415
memcpy (& zend_ffi_type_fn , zend_hash_str_find_ptr (& zend_ffi_ce -> function_table , "type" , sizeof ("type" )- 1 ), sizeof (zend_internal_function ));
5396
5416
zend_ffi_type_fn .fn_flags &= ~ZEND_ACC_STATIC ;
5397
5417
5418
+ prev_zend_post_startup_cb = zend_post_startup_cb ;
5419
+ zend_post_startup_cb = ffi_fixup_temporaries ;
5420
+
5398
5421
memcpy (& zend_ffi_handlers , zend_get_std_object_handlers (), sizeof (zend_object_handlers ));
5399
5422
zend_ffi_handlers .get_constructor = zend_fake_get_constructor ;
5400
5423
zend_ffi_handlers .free_obj = zend_ffi_free_obj ;
0 commit comments