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