4394531f305afa71102321b2e49105a84bcc1385
1 /*******************************************************************************
2 Copyright (c) 2018, Michael Wallner <mike@php.net>.
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *******************************************************************************/
26 #ifndef PSI_LIBFFI_COMPAT_H
27 #define PSI_LIBFFI_COMPAT_H
32 # include "php_config.h"
36 #undef PACKAGE_BUGREPORT
39 #undef PACKAGE_TARNAME
40 #undef PACKAGE_VERSION
44 #ifndef PSI_HAVE_FFI_CLOSURE_ALLOC
49 # include <sys/mman.h>
50 # ifndef MAP_ANONYMOUS
51 # define MAP_ANONYMOUS MAP_ANON
56 static inline void *psi_ffi_closure_alloc(size_t s
, void **code
)
58 #ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
59 return ffi_closure_alloc(s
, code
);
61 *code
= mmap(NULL
, s
, PROT_EXEC
|PROT_WRITE
|PROT_READ
,
62 MAP_PRIVATE
|MAP_ANONYMOUS
, -1, 0);
63 if (MAP_FAILED
== *code
) {
68 # error "Neither ffi_closure_alloc() nor mmap() available"
72 static inline ffi_status
psi_ffi_prep_closure(ffi_closure
**closure
, void **code
, ffi_cif
*sig
, void (*handler
)(ffi_cif
*,void*,void**,void*), void *data
) {
73 *closure
= psi_ffi_closure_alloc(sizeof(ffi_closure
), code
);
74 assert(*closure
!= NULL
);
76 #if PSI_HAVE_FFI_PREP_CLOSURE_LOC
77 return ffi_prep_closure_loc(*closure
, sig
, handler
, data
, *code
);
79 #elif PSI_HAVE_FFI_PREP_CLOSURE
80 return ffi_prep_closure(*code
, sig
, handler
, data
);
82 # error "Neither ffi_prep_closure() nor ffi_prep_closure_loc() is available"
83 abort(); /* fix IDE warning */
87 static inline void psi_ffi_closure_free(void *c
)
89 #ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
92 munmap(c
, sizeof(ffi_closure
));
96 static inline void psi_ffi_prep_va(ffi_cif
*base
, ffi_cif
*signature
, size_t argc
, size_t va_count
,
97 ffi_type
**param_types
) {
100 #ifdef PSI_HAVE_FFI_PREP_CIF_VAR
101 rc
= ffi_prep_cif_var(signature
, base
->abi
, argc
, argc
+ va_count
,
102 base
->rtype
, param_types
);
104 /* FIXME: test in config.m4; assume we can just call anyway */
105 rc
= ffi_prep_cif(signature
, base
->abi
, argc
+ va_count
, base
->rtype
, param_types
);
108 assert(FFI_OK
== rc
);
113 #endif /* LIBFFI_COMPAT_H */