fix char_width decl
[m6w6/ext-psi] / src / libffi_compat.h
1 /*******************************************************************************
2 Copyright (c) 2018, Michael Wallner <mike@php.net>.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
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.
13
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 *******************************************************************************/
25
26 #ifndef PSI_LIBFFI_COMPAT_H
27 #define PSI_LIBFFI_COMPAT_H
28
29 #ifdef HAVE_CONFIG_H
30 # include "config.h"
31 #else
32 # include "php_config.h"
33 #endif
34
35 #undef PACKAGE
36 #undef PACKAGE_BUGREPORT
37 #undef PACKAGE_NAME
38 #undef PACKAGE_STRING
39 #undef PACKAGE_TARNAME
40 #undef PACKAGE_VERSION
41
42 #include <ffi.h>
43
44 #ifndef PSI_HAVE_FFI_CLOSURE_ALLOC
45 # if HAVE_UNISTD_H
46 # include <unistd.h>
47 # endif
48 # if HAVE_SYS_MMAN_H
49 # include <sys/mman.h>
50 # ifndef MAP_ANONYMOUS
51 # define MAP_ANONYMOUS MAP_ANON
52 # endif
53 # endif
54 #endif
55
56 static inline void *psi_ffi_closure_alloc(size_t s, void **code)
57 {
58 #ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
59 return ffi_closure_alloc(s, code);
60 #elif HAVE_MMAP
61 *code = mmap(NULL, s, PROT_EXEC|PROT_WRITE|PROT_READ,
62 MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
63 if (MAP_FAILED == *code) {
64 return NULL;
65 }
66 return *code;
67 #else
68 # error "Neither ffi_closure_alloc() nor mmap() available"
69 #endif
70 }
71
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);
75
76 #if PSI_HAVE_FFI_PREP_CLOSURE_LOC
77 return ffi_prep_closure_loc(*closure, sig, handler, data, *code);
78
79 #elif PSI_HAVE_FFI_PREP_CLOSURE
80 return ffi_prep_closure(*code, sig, handler, data);
81 #else
82 # error "Neither ffi_prep_closure() nor ffi_prep_closure_loc() is available"
83 abort(); /* fix IDE warning */
84 #endif
85 }
86
87 static inline void psi_ffi_closure_free(void *c)
88 {
89 #ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
90 ffi_closure_free(c);
91 #elif HAVE_MMAP
92 munmap(c, sizeof(ffi_closure));
93 #endif
94 }
95
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) {
98 ffi_status rc;
99
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);
103 #else
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);
106 #endif
107
108 assert(FFI_OK == rc);
109 (void) rc;
110 }
111
112
113 #endif /* LIBFFI_COMPAT_H */