@@ -13,11 +13,25 @@ typedef struct {
13
13
ffi_type * * argv ;
14
14
} fiddle_closure ;
15
15
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
+
16
26
static void
17
27
dealloc (void * ptr )
18
28
{
19
29
fiddle_closure * cls = (fiddle_closure * )ptr ;
30
+ #if USE_FFI_CLOSURE_ALLOC
20
31
ffi_closure_free (cls -> pcl );
32
+ #else
33
+ munmap (cls -> pcl , sizeof (* cls -> pcl ));
34
+ #endif
21
35
if (cls -> argv ) xfree (cls -> argv );
22
36
xfree (cls );
23
37
}
@@ -191,7 +205,12 @@ allocate(VALUE klass)
191
205
VALUE i = TypedData_Make_Struct (klass , fiddle_closure ,
192
206
& closure_data_type , closure );
193
207
208
+ #if USE_FFI_CLOSURE_ALLOC
194
209
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
195
214
196
215
return i ;
197
216
}
@@ -238,8 +257,17 @@ initialize(int rbargc, VALUE argv[], VALUE self)
238
257
if (FFI_OK != result )
239
258
rb_raise (rb_eRuntimeError , "error prepping CIF %d" , result );
240
259
260
+ #if USE_FFI_CLOSURE_ALLOC
241
261
result = ffi_prep_closure_loc (pcl , cif , callback ,
242
262
(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
243
271
244
272
if (FFI_OK != result )
245
273
rb_raise (rb_eRuntimeError , "error prepping closure %d" , result );
0 commit comments