@@ -13,11 +13,25 @@ typedef struct {
1313 ffi_type * * argv ;
1414} fiddle_closure ;
1515
16+ #if defined(USE_FFI_CLOSURE_ALLOC )
17+ #elif defined(__OpenBSD__ ) || defined(__APPLE__ ) || defined(__linux__ )
18+ # define USE_FFI_CLOSURE_ALLOC 0
19+ #elif defined(RUBY_LIBFFI_MODVERSION ) && RUBY_LIBFFI_MODVERSION < 3000005 && \
20+ (defined(__i386__ ) || defined(__x86_64__ ) || defined(_M_IX86 ) || defined(_M_AMD64 ))
21+ # define USE_FFI_CLOSURE_ALLOC 0
22+ #else
23+ # define USE_FFI_CLOSURE_ALLOC 1
24+ #endif
25+
1626static void
1727dealloc (void * ptr )
1828{
1929 fiddle_closure * cls = (fiddle_closure * )ptr ;
30+ #if USE_FFI_CLOSURE_ALLOC
2031 ffi_closure_free (cls -> pcl );
32+ #else
33+ munmap (cls -> pcl , sizeof (* cls -> pcl ));
34+ #endif
2135 if (cls -> argv ) xfree (cls -> argv );
2236 xfree (cls );
2337}
@@ -191,7 +205,12 @@ allocate(VALUE klass)
191205 VALUE i = TypedData_Make_Struct (klass , fiddle_closure ,
192206 & closure_data_type , closure );
193207
208+ #if USE_FFI_CLOSURE_ALLOC
194209 closure -> pcl = ffi_closure_alloc (sizeof (ffi_closure ), & closure -> code );
210+ #else
211+ closure -> pcl = mmap (NULL , sizeof (ffi_closure ), PROT_READ | PROT_WRITE ,
212+ MAP_ANON | MAP_PRIVATE , -1 , 0 );
213+ #endif
195214
196215 return i ;
197216}
@@ -238,8 +257,17 @@ initialize(int rbargc, VALUE argv[], VALUE self)
238257 if (FFI_OK != result )
239258 rb_raise (rb_eRuntimeError , "error prepping CIF %d" , result );
240259
260+ #if USE_FFI_CLOSURE_ALLOC
241261 result = ffi_prep_closure_loc (pcl , cif , callback ,
242262 (void * )self , cl -> code );
263+ #else
264+ result = ffi_prep_closure (pcl , cif , callback , (void * )self );
265+ cl -> code = (void * )pcl ;
266+ i = mprotect (pcl , sizeof (* pcl ), PROT_READ | PROT_EXEC );
267+ if (i ) {
268+ rb_sys_fail ("mprotect" );
269+ }
270+ #endif
243271
244272 if (FFI_OK != result )
245273 rb_raise (rb_eRuntimeError , "error prepping closure %d" , result );
0 commit comments