@@ -235,9 +235,16 @@ get_raw(VALUE self)
235
235
return closure ;
236
236
}
237
237
238
+ typedef struct {
239
+ VALUE self ;
240
+ int argc ;
241
+ VALUE * argv ;
242
+ } initialize_data ;
243
+
238
244
static VALUE
239
- initialize ( int rbargc , VALUE argv [], VALUE self )
245
+ initialize_body ( VALUE user_data )
240
246
{
247
+ initialize_data * data = (initialize_data * )user_data ;
241
248
VALUE ret ;
242
249
VALUE args ;
243
250
VALUE normalized_args ;
@@ -248,14 +255,14 @@ initialize(int rbargc, VALUE argv[], VALUE self)
248
255
ffi_status result ;
249
256
int i , argc ;
250
257
251
- if (2 == rb_scan_args (rbargc , argv , "21" , & ret , & args , & abi ))
252
- abi = INT2NUM (FFI_DEFAULT_ABI );
258
+ if (2 == rb_scan_args (data -> argc , data -> argv , "21" , & ret , & args , & abi ))
259
+ abi = INT2NUM (FFI_DEFAULT_ABI );
253
260
254
261
Check_Type (args , T_ARRAY );
255
262
256
263
argc = RARRAY_LENINT (args );
257
264
258
- TypedData_Get_Struct (self , fiddle_closure , & closure_data_type , cl );
265
+ TypedData_Get_Struct (data -> self , fiddle_closure , & closure_data_type , cl );
259
266
260
267
cl -> argv = (ffi_type * * )xcalloc (argc + 1 , sizeof (ffi_type * ));
261
268
@@ -268,8 +275,8 @@ initialize(int rbargc, VALUE argv[], VALUE self)
268
275
cl -> argv [argc ] = NULL ;
269
276
270
277
ret = rb_fiddle_type_ensure (ret );
271
- rb_iv_set (self , "@ctype" , ret );
272
- rb_iv_set (self , "@args" , normalized_args );
278
+ rb_iv_set (data -> self , "@ctype" , ret );
279
+ rb_iv_set (data -> self , "@args" , normalized_args );
273
280
274
281
cif = & cl -> cif ;
275
282
pcl = cl -> pcl ;
@@ -280,25 +287,48 @@ initialize(int rbargc, VALUE argv[], VALUE self)
280
287
rb_fiddle_int_to_ffi_type (NUM2INT (ret )),
281
288
cl -> argv );
282
289
283
- if (FFI_OK != result )
284
- rb_raise (rb_eRuntimeError , "error prepping CIF %d" , result );
290
+ if (FFI_OK != result ) {
291
+ rb_raise (rb_eRuntimeError , "error prepping CIF %d" , result );
292
+ }
285
293
286
294
#if USE_FFI_CLOSURE_ALLOC
287
295
result = ffi_prep_closure_loc (pcl , cif , callback ,
288
- (void * )self , cl -> code );
296
+ (void * )( data -> self ) , cl -> code );
289
297
#else
290
298
result = ffi_prep_closure (pcl , cif , callback , (void * )self );
291
299
cl -> code = (void * )pcl ;
292
300
i = mprotect (pcl , sizeof (* pcl ), PROT_READ | PROT_EXEC );
293
301
if (i ) {
294
- rb_sys_fail ("mprotect" );
302
+ rb_sys_fail ("mprotect" );
295
303
}
296
304
#endif
297
305
298
- if (FFI_OK != result )
299
- rb_raise (rb_eRuntimeError , "error prepping closure %d" , result );
306
+ if (FFI_OK != result ) {
307
+ rb_raise (rb_eRuntimeError , "error prepping closure %d" , result );
308
+ }
309
+
310
+ return data -> self ;
311
+ }
300
312
301
- return self ;
313
+ static VALUE
314
+ initialize_rescue (VALUE user_data , VALUE exception )
315
+ {
316
+ initialize_data * data = (initialize_data * )user_data ;
317
+ dealloc (RTYPEDDATA_DATA (data -> self ));
318
+ RTYPEDDATA_DATA (data -> self ) = NULL ;
319
+ rb_exc_raise (exception );
320
+ return data -> self ;
321
+ }
322
+
323
+ static VALUE
324
+ initialize (int argc , VALUE * argv , VALUE self )
325
+ {
326
+ initialize_data data ;
327
+ data .self = self ;
328
+ data .argc = argc ;
329
+ data .argv = argv ;
330
+ return rb_rescue (initialize_body , (VALUE )& data ,
331
+ initialize_rescue , (VALUE )& data );
302
332
}
303
333
304
334
static VALUE
0 commit comments