fiddle 1.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
data/ext/fiddle/fiddle.c CHANGED
@@ -1,3 +1,5 @@
1
+ #include <stdbool.h>
2
+
1
3
  #include <fiddle.h>
2
4
 
3
5
  VALUE mFiddle;
@@ -58,18 +60,16 @@ rb_fiddle_free(VALUE self, VALUE addr)
58
60
  /*
59
61
  * call-seq: Fiddle.dlunwrap(addr)
60
62
  *
61
- * Returns the hexadecimal representation of a memory pointer address +addr+
63
+ * Returns the Ruby object stored at the memory address +addr+
62
64
  *
63
65
  * Example:
64
66
  *
65
- * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
66
- * => #<Fiddle::Handle:0x00000001342460>
67
- *
68
- * lib['strcpy'].to_s(16)
69
- * => "7f59de6dd240"
70
- *
71
- * Fiddle.dlunwrap(Fiddle.dlwrap(lib['strcpy'].to_s(16)))
72
- * => "7f59de6dd240"
67
+ * x = Object.new
68
+ * # => #<Object:0x0000000107c7d870>
69
+ * Fiddle.dlwrap(x)
70
+ * # => 4425504880
71
+ * Fiddle.dlunwrap(_)
72
+ * # => #<Object:0x0000000107c7d870>
73
73
  */
74
74
  VALUE
75
75
  rb_fiddle_ptr2value(VALUE self, VALUE addr)
@@ -80,15 +80,22 @@ rb_fiddle_ptr2value(VALUE self, VALUE addr)
80
80
  /*
81
81
  * call-seq: Fiddle.dlwrap(val)
82
82
  *
83
- * Returns a memory pointer of a function's hexadecimal address location +val+
83
+ * Returns the memory address of the Ruby object stored at +val+
84
84
  *
85
85
  * Example:
86
86
  *
87
- * lib = Fiddle.dlopen('/lib64/libc-2.15.so')
88
- * => #<Fiddle::Handle:0x00000001342460>
87
+ * x = Object.new
88
+ * # => #<Object:0x0000000107c7d870>
89
+ * Fiddle.dlwrap(x)
90
+ * # => 4425504880
91
+ *
92
+ * In the case +val+ is not a heap allocated object, this method will return
93
+ * the tagged pointer value.
94
+ *
95
+ * Example:
89
96
  *
90
- * Fiddle.dlwrap(lib['strcpy'].to_s(16))
91
- * => 25522520
97
+ * Fiddle.dlwrap(123)
98
+ * # => 247
92
99
  */
93
100
  static VALUE
94
101
  rb_fiddle_value2ptr(VALUE self, VALUE val)
@@ -164,137 +171,199 @@ Init_fiddle(void)
164
171
  */
165
172
  rb_eFiddleDLError = rb_define_class_under(mFiddle, "DLError", rb_eFiddleError);
166
173
 
167
- /* Document-const: TYPE_VOID
174
+ VALUE mFiddleTypes = rb_define_module_under(mFiddle, "Types");
175
+
176
+ /* Document-const: Fiddle::Types::VOID
168
177
  *
169
178
  * C type - void
170
179
  */
171
- rb_define_const(mFiddle, "TYPE_VOID", INT2NUM(TYPE_VOID));
180
+ rb_define_const(mFiddleTypes, "VOID", INT2NUM(TYPE_VOID));
172
181
 
173
- /* Document-const: TYPE_VOIDP
182
+ /* Document-const: Fiddle::Types::VOIDP
174
183
  *
175
184
  * C type - void*
176
185
  */
177
- rb_define_const(mFiddle, "TYPE_VOIDP", INT2NUM(TYPE_VOIDP));
186
+ rb_define_const(mFiddleTypes, "VOIDP", INT2NUM(TYPE_VOIDP));
178
187
 
179
- /* Document-const: TYPE_CHAR
188
+ /* Document-const: Fiddle::Types::CHAR
180
189
  *
181
190
  * C type - char
182
191
  */
183
- rb_define_const(mFiddle, "TYPE_CHAR", INT2NUM(TYPE_CHAR));
192
+ rb_define_const(mFiddleTypes, "CHAR", INT2NUM(TYPE_CHAR));
184
193
 
185
- /* Document-const: TYPE_SHORT
194
+ /* Document-const: Fiddle::Types::UCHAR
195
+ *
196
+ * C type - unsigned char
197
+ */
198
+ rb_define_const(mFiddleTypes, "UCHAR", INT2NUM(TYPE_UCHAR));
199
+
200
+ /* Document-const: Fiddle::Types::SHORT
186
201
  *
187
202
  * C type - short
188
203
  */
189
- rb_define_const(mFiddle, "TYPE_SHORT", INT2NUM(TYPE_SHORT));
204
+ rb_define_const(mFiddleTypes, "SHORT", INT2NUM(TYPE_SHORT));
190
205
 
191
- /* Document-const: TYPE_INT
206
+ /* Document-const: Fiddle::Types::USHORT
207
+ *
208
+ * C type - unsigned short
209
+ */
210
+ rb_define_const(mFiddleTypes, "USHORT", INT2NUM(TYPE_USHORT));
211
+
212
+ /* Document-const: Fiddle::Types::INT
192
213
  *
193
214
  * C type - int
194
215
  */
195
- rb_define_const(mFiddle, "TYPE_INT", INT2NUM(TYPE_INT));
216
+ rb_define_const(mFiddleTypes, "INT", INT2NUM(TYPE_INT));
217
+
218
+ /* Document-const: Fiddle::Types::UINT
219
+ *
220
+ * C type - unsigned int
221
+ */
222
+ rb_define_const(mFiddleTypes, "UINT", INT2NUM(TYPE_UINT));
196
223
 
197
- /* Document-const: TYPE_LONG
224
+ /* Document-const: Fiddle::Types::LONG
198
225
  *
199
226
  * C type - long
200
227
  */
201
- rb_define_const(mFiddle, "TYPE_LONG", INT2NUM(TYPE_LONG));
228
+ rb_define_const(mFiddleTypes, "LONG", INT2NUM(TYPE_LONG));
229
+
230
+ /* Document-const: Fiddle::Types::ULONG
231
+ *
232
+ * C type - long
233
+ */
234
+ rb_define_const(mFiddleTypes, "ULONG", INT2NUM(TYPE_ULONG));
202
235
 
203
236
  #if HAVE_LONG_LONG
204
- /* Document-const: TYPE_LONG_LONG
237
+ /* Document-const: Fiddle::Types::LONG_LONG
238
+ *
239
+ * C type - long long
240
+ */
241
+ rb_define_const(mFiddleTypes, "LONG_LONG", INT2NUM(TYPE_LONG_LONG));
242
+
243
+ /* Document-const: Fiddle::Types::ULONG_LONG
205
244
  *
206
245
  * C type - long long
207
246
  */
208
- rb_define_const(mFiddle, "TYPE_LONG_LONG", INT2NUM(TYPE_LONG_LONG));
247
+ rb_define_const(mFiddleTypes, "ULONG_LONG", INT2NUM(TYPE_ULONG_LONG));
209
248
  #endif
210
249
 
211
250
  #ifdef TYPE_INT8_T
212
- /* Document-const: TYPE_INT8_T
251
+ /* Document-const: Fiddle::Types::INT8_T
213
252
  *
214
253
  * C type - int8_t
215
254
  */
216
- rb_define_const(mFiddle, "TYPE_INT8_T", INT2NUM(TYPE_INT8_T));
255
+ rb_define_const(mFiddleTypes, "INT8_T", INT2NUM(TYPE_INT8_T));
256
+
257
+ /* Document-const: Fiddle::Types::UINT8_T
258
+ *
259
+ * C type - uint8_t
260
+ */
261
+ rb_define_const(mFiddleTypes, "UINT8_T", INT2NUM(TYPE_UINT8_T));
217
262
  #endif
218
263
 
219
264
  #ifdef TYPE_INT16_T
220
- /* Document-const: TYPE_INT16_T
265
+ /* Document-const: Fiddle::Types::INT16_T
221
266
  *
222
267
  * C type - int16_t
223
268
  */
224
- rb_define_const(mFiddle, "TYPE_INT16_T", INT2NUM(TYPE_INT16_T));
269
+ rb_define_const(mFiddleTypes, "INT16_T", INT2NUM(TYPE_INT16_T));
270
+
271
+ /* Document-const: Fiddle::Types::UINT16_T
272
+ *
273
+ * C type - uint16_t
274
+ */
275
+ rb_define_const(mFiddleTypes, "UINT16_T", INT2NUM(TYPE_UINT16_T));
225
276
  #endif
226
277
 
227
278
  #ifdef TYPE_INT32_T
228
- /* Document-const: TYPE_INT32_T
279
+ /* Document-const: Fiddle::Types::INT32_T
229
280
  *
230
281
  * C type - int32_t
231
282
  */
232
- rb_define_const(mFiddle, "TYPE_INT32_T", INT2NUM(TYPE_INT32_T));
283
+ rb_define_const(mFiddleTypes, "INT32_T", INT2NUM(TYPE_INT32_T));
284
+
285
+ /* Document-const: Fiddle::Types::UINT32_T
286
+ *
287
+ * C type - uint32_t
288
+ */
289
+ rb_define_const(mFiddleTypes, "UINT32_T", INT2NUM(TYPE_UINT32_T));
233
290
  #endif
234
291
 
235
292
  #ifdef TYPE_INT64_T
236
- /* Document-const: TYPE_INT64_T
293
+ /* Document-const: Fiddle::Types::INT64_T
237
294
  *
238
295
  * C type - int64_t
239
296
  */
240
- rb_define_const(mFiddle, "TYPE_INT64_T", INT2NUM(TYPE_INT64_T));
297
+ rb_define_const(mFiddleTypes, "INT64_T", INT2NUM(TYPE_INT64_T));
298
+
299
+ /* Document-const: Fiddle::Types::UINT64_T
300
+ *
301
+ * C type - uint64_t
302
+ */
303
+ rb_define_const(mFiddleTypes, "UINT64_T", INT2NUM(TYPE_UINT64_T));
241
304
  #endif
242
305
 
243
- /* Document-const: TYPE_FLOAT
306
+ /* Document-const: Fiddle::Types::FLOAT
244
307
  *
245
308
  * C type - float
246
309
  */
247
- rb_define_const(mFiddle, "TYPE_FLOAT", INT2NUM(TYPE_FLOAT));
310
+ rb_define_const(mFiddleTypes, "FLOAT", INT2NUM(TYPE_FLOAT));
248
311
 
249
- /* Document-const: TYPE_DOUBLE
312
+ /* Document-const: Fiddle::Types::DOUBLE
250
313
  *
251
314
  * C type - double
252
315
  */
253
- rb_define_const(mFiddle, "TYPE_DOUBLE", INT2NUM(TYPE_DOUBLE));
316
+ rb_define_const(mFiddleTypes, "DOUBLE", INT2NUM(TYPE_DOUBLE));
254
317
 
255
318
  #ifdef HAVE_FFI_PREP_CIF_VAR
256
- /* Document-const: TYPE_VARIADIC
319
+ /* Document-const: Fiddle::Types::VARIADIC
257
320
  *
258
321
  * C type - ...
259
322
  */
260
- rb_define_const(mFiddle, "TYPE_VARIADIC", INT2NUM(TYPE_VARIADIC));
323
+ rb_define_const(mFiddleTypes, "VARIADIC", INT2NUM(TYPE_VARIADIC));
261
324
  #endif
262
325
 
263
- /* Document-const: TYPE_CONST_STRING
326
+ /* Document-const: Fiddle::Types::CONST_STRING
264
327
  *
265
328
  * C type - const char* ('\0' terminated const char*)
266
329
  */
267
- rb_define_const(mFiddle, "TYPE_CONST_STRING", INT2NUM(TYPE_CONST_STRING));
330
+ rb_define_const(mFiddleTypes, "CONST_STRING", INT2NUM(TYPE_CONST_STRING));
268
331
 
269
- /* Document-const: TYPE_SIZE_T
332
+ /* Document-const: Fiddle::Types::SIZE_T
270
333
  *
271
334
  * C type - size_t
272
335
  */
273
- rb_define_const(mFiddle, "TYPE_SIZE_T", INT2NUM(TYPE_SIZE_T));
336
+ rb_define_const(mFiddleTypes, "SIZE_T", INT2NUM(TYPE_SIZE_T));
274
337
 
275
- /* Document-const: TYPE_SSIZE_T
338
+ /* Document-const: Fiddle::Types::SSIZE_T
276
339
  *
277
340
  * C type - ssize_t
278
341
  */
279
- rb_define_const(mFiddle, "TYPE_SSIZE_T", INT2NUM(TYPE_SSIZE_T));
342
+ rb_define_const(mFiddleTypes, "SSIZE_T", INT2NUM(TYPE_SSIZE_T));
280
343
 
281
- /* Document-const: TYPE_PTRDIFF_T
344
+ /* Document-const: Fiddle::Types::PTRDIFF_T
282
345
  *
283
346
  * C type - ptrdiff_t
284
347
  */
285
- rb_define_const(mFiddle, "TYPE_PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T));
348
+ rb_define_const(mFiddleTypes, "PTRDIFF_T", INT2NUM(TYPE_PTRDIFF_T));
286
349
 
287
- /* Document-const: TYPE_INTPTR_T
350
+ /* Document-const: Fiddle::Types::INTPTR_T
288
351
  *
289
352
  * C type - intptr_t
290
353
  */
291
- rb_define_const(mFiddle, "TYPE_INTPTR_T", INT2NUM(TYPE_INTPTR_T));
354
+ rb_define_const(mFiddleTypes, "INTPTR_T", INT2NUM(TYPE_INTPTR_T));
292
355
 
293
- /* Document-const: TYPE_UINTPTR_T
356
+ /* Document-const: Fiddle::Types::UINTPTR_T
294
357
  *
295
358
  * C type - uintptr_t
296
359
  */
297
- rb_define_const(mFiddle, "TYPE_UINTPTR_T", INT2NUM(TYPE_UINTPTR_T));
360
+ rb_define_const(mFiddleTypes, "UINTPTR_T", INT2NUM(TYPE_UINTPTR_T));
361
+
362
+ /* Document-const: Fiddle::Types::BOOL
363
+ *
364
+ * C type - bool
365
+ */
366
+ rb_define_const(mFiddleTypes, "BOOL" , INT2NUM(TYPE_BOOL));
298
367
 
299
368
  /* Document-const: ALIGN_VOIDP
300
369
  *
@@ -400,6 +469,12 @@ Init_fiddle(void)
400
469
  */
401
470
  rb_define_const(mFiddle, "ALIGN_UINTPTR_T", INT2NUM(ALIGN_OF(uintptr_t)));
402
471
 
472
+ /* Document-const: ALIGN_BOOL
473
+ *
474
+ * The alignment size of a bool
475
+ */
476
+ rb_define_const(mFiddle, "ALIGN_BOOL", INT2NUM(ALIGN_OF(bool)));
477
+
403
478
  /* Document-const: WINDOWS
404
479
  *
405
480
  * Returns a boolean regarding whether the host is WIN32
@@ -422,30 +497,60 @@ Init_fiddle(void)
422
497
  */
423
498
  rb_define_const(mFiddle, "SIZEOF_CHAR", INT2NUM(sizeof(char)));
424
499
 
500
+ /* Document-const: SIZEOF_UCHAR
501
+ *
502
+ * size of a unsigned char
503
+ */
504
+ rb_define_const(mFiddle, "SIZEOF_UCHAR", INT2NUM(sizeof(unsigned char)));
505
+
425
506
  /* Document-const: SIZEOF_SHORT
426
507
  *
427
508
  * size of a short
428
509
  */
429
510
  rb_define_const(mFiddle, "SIZEOF_SHORT", INT2NUM(sizeof(short)));
430
511
 
512
+ /* Document-const: SIZEOF_USHORT
513
+ *
514
+ * size of a unsigned short
515
+ */
516
+ rb_define_const(mFiddle, "SIZEOF_USHORT", INT2NUM(sizeof(unsigned short)));
517
+
431
518
  /* Document-const: SIZEOF_INT
432
519
  *
433
520
  * size of an int
434
521
  */
435
522
  rb_define_const(mFiddle, "SIZEOF_INT", INT2NUM(sizeof(int)));
436
523
 
524
+ /* Document-const: SIZEOF_UINT
525
+ *
526
+ * size of an unsigned int
527
+ */
528
+ rb_define_const(mFiddle, "SIZEOF_UINT", INT2NUM(sizeof(unsigned int)));
529
+
437
530
  /* Document-const: SIZEOF_LONG
438
531
  *
439
532
  * size of a long
440
533
  */
441
534
  rb_define_const(mFiddle, "SIZEOF_LONG", INT2NUM(sizeof(long)));
442
535
 
536
+ /* Document-const: SIZEOF_ULONG
537
+ *
538
+ * size of a unsigned long
539
+ */
540
+ rb_define_const(mFiddle, "SIZEOF_ULONG", INT2NUM(sizeof(unsigned long)));
541
+
443
542
  #if HAVE_LONG_LONG
444
543
  /* Document-const: SIZEOF_LONG_LONG
445
544
  *
446
545
  * size of a long long
447
546
  */
448
547
  rb_define_const(mFiddle, "SIZEOF_LONG_LONG", INT2NUM(sizeof(LONG_LONG)));
548
+
549
+ /* Document-const: SIZEOF_ULONG_LONG
550
+ *
551
+ * size of a unsigned long long
552
+ */
553
+ rb_define_const(mFiddle, "SIZEOF_ULONG_LONG", INT2NUM(sizeof(unsigned LONG_LONG)));
449
554
  #endif
450
555
 
451
556
  /* Document-const: SIZEOF_INT8_T
@@ -454,24 +559,48 @@ Init_fiddle(void)
454
559
  */
455
560
  rb_define_const(mFiddle, "SIZEOF_INT8_T", INT2NUM(sizeof(int8_t)));
456
561
 
562
+ /* Document-const: SIZEOF_UINT8_T
563
+ *
564
+ * size of a uint8_t
565
+ */
566
+ rb_define_const(mFiddle, "SIZEOF_UINT8_T", INT2NUM(sizeof(uint8_t)));
567
+
457
568
  /* Document-const: SIZEOF_INT16_T
458
569
  *
459
570
  * size of a int16_t
460
571
  */
461
572
  rb_define_const(mFiddle, "SIZEOF_INT16_T", INT2NUM(sizeof(int16_t)));
462
573
 
574
+ /* Document-const: SIZEOF_UINT16_T
575
+ *
576
+ * size of a uint16_t
577
+ */
578
+ rb_define_const(mFiddle, "SIZEOF_UINT16_T", INT2NUM(sizeof(uint16_t)));
579
+
463
580
  /* Document-const: SIZEOF_INT32_T
464
581
  *
465
582
  * size of a int32_t
466
583
  */
467
584
  rb_define_const(mFiddle, "SIZEOF_INT32_T", INT2NUM(sizeof(int32_t)));
468
585
 
586
+ /* Document-const: SIZEOF_UINT32_T
587
+ *
588
+ * size of a uint32_t
589
+ */
590
+ rb_define_const(mFiddle, "SIZEOF_UINT32_T", INT2NUM(sizeof(uint32_t)));
591
+
469
592
  /* Document-const: SIZEOF_INT64_T
470
593
  *
471
594
  * size of a int64_t
472
595
  */
473
596
  rb_define_const(mFiddle, "SIZEOF_INT64_T", INT2NUM(sizeof(int64_t)));
474
597
 
598
+ /* Document-const: SIZEOF_UINT64_T
599
+ *
600
+ * size of a uint64_t
601
+ */
602
+ rb_define_const(mFiddle, "SIZEOF_UINT64_T", INT2NUM(sizeof(uint64_t)));
603
+
475
604
  /* Document-const: SIZEOF_FLOAT
476
605
  *
477
606
  * size of a float
@@ -520,6 +649,12 @@ Init_fiddle(void)
520
649
  */
521
650
  rb_define_const(mFiddle, "SIZEOF_CONST_STRING", INT2NUM(sizeof(const char*)));
522
651
 
652
+ /* Document-const: SIZEOF_BOOL
653
+ *
654
+ * size of a bool
655
+ */
656
+ rb_define_const(mFiddle, "SIZEOF_BOOL", INT2NUM(sizeof(bool)));
657
+
523
658
  /* Document-const: RUBY_FREE
524
659
  *
525
660
  * Address of the ruby_xfree() function
@@ -540,6 +675,30 @@ Init_fiddle(void)
540
675
  rb_define_module_function(mFiddle, "realloc", rb_fiddle_realloc, 2);
541
676
  rb_define_module_function(mFiddle, "free", rb_fiddle_free, 1);
542
677
 
678
+ /* Document-const: Qtrue
679
+ *
680
+ * The value of Qtrue
681
+ */
682
+ rb_define_const(mFiddle, "Qtrue", INT2NUM(Qtrue));
683
+
684
+ /* Document-const: Qfalse
685
+ *
686
+ * The value of Qfalse
687
+ */
688
+ rb_define_const(mFiddle, "Qfalse", INT2NUM(Qfalse));
689
+
690
+ /* Document-const: Qnil
691
+ *
692
+ * The value of Qnil
693
+ */
694
+ rb_define_const(mFiddle, "Qnil", INT2NUM(Qnil));
695
+
696
+ /* Document-const: Qundef
697
+ *
698
+ * The value of Qundef
699
+ */
700
+ rb_define_const(mFiddle, "Qundef", INT2NUM(Qundef));
701
+
543
702
  Init_fiddle_function();
544
703
  Init_fiddle_closure();
545
704
  Init_fiddle_handle();
data/ext/fiddle/fiddle.h CHANGED
@@ -111,23 +111,36 @@
111
111
  #define TYPE_VOID 0
112
112
  #define TYPE_VOIDP 1
113
113
  #define TYPE_CHAR 2
114
+ #define TYPE_UCHAR -TYPE_CHAR
114
115
  #define TYPE_SHORT 3
116
+ #define TYPE_USHORT -TYPE_SHORT
115
117
  #define TYPE_INT 4
118
+ #define TYPE_UINT -TYPE_INT
116
119
  #define TYPE_LONG 5
117
- #if HAVE_LONG_LONG
120
+ #define TYPE_ULONG -TYPE_LONG
121
+ #ifdef HAVE_LONG_LONG
118
122
  #define TYPE_LONG_LONG 6
123
+ #define TYPE_ULONG_LONG -TYPE_LONG_LONG
119
124
  #endif
120
125
  #define TYPE_FLOAT 7
121
126
  #define TYPE_DOUBLE 8
122
127
  #define TYPE_VARIADIC 9
123
128
  #define TYPE_CONST_STRING 10
129
+ #define TYPE_BOOL 11
124
130
 
125
131
  #define TYPE_INT8_T TYPE_CHAR
132
+ #define TYPE_UINT8_T -TYPE_INT8_T
133
+
126
134
  #if SIZEOF_SHORT == 2
127
135
  # define TYPE_INT16_T TYPE_SHORT
128
136
  #elif SIZEOF_INT == 2
129
137
  # define TYPE_INT16_T TYPE_INT
130
138
  #endif
139
+
140
+ #ifdef TYPE_INT16_T
141
+ # define TYPE_UINT16_T -TYPE_INT16_T
142
+ #endif
143
+
131
144
  #if SIZEOF_SHORT == 4
132
145
  # define TYPE_INT32_T TYPE_SHORT
133
146
  #elif SIZEOF_INT == 4
@@ -135,6 +148,11 @@
135
148
  #elif SIZEOF_LONG == 4
136
149
  # define TYPE_INT32_T TYPE_LONG
137
150
  #endif
151
+
152
+ #ifdef TYPE_INT32_T
153
+ #define TYPE_UINT32_T -TYPE_INT32_T
154
+ #endif
155
+
138
156
  #if SIZEOF_INT == 8
139
157
  # define TYPE_INT64_T TYPE_INT
140
158
  #elif SIZEOF_LONG == 8
@@ -143,6 +161,10 @@
143
161
  # define TYPE_INT64_T TYPE_LONG_LONG
144
162
  #endif
145
163
 
164
+ #ifdef TYPE_INT64_T
165
+ #define TYPE_UINT64_T -TYPE_INT64_T
166
+ #endif
167
+
146
168
  #ifndef TYPE_SSIZE_T
147
169
  # if SIZEOF_SIZE_T == SIZEOF_INT
148
170
  # define TYPE_SSIZE_T TYPE_INT
@@ -175,7 +197,20 @@
175
197
  #endif
176
198
  #define TYPE_UINTPTR_T (-TYPE_INTPTR_T)
177
199
 
178
- #define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
200
+ /* GCC releases before GCC 4.9 had a bug in _Alignof. See GCC bug 52023
201
+ <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52023>.
202
+ clang versions < 8.0.0 have the same bug. */
203
+ #if defined(HAVE__ALIGNOF)
204
+ # /* Autoconf detected availability of a sane `_Alignof()`. */
205
+ # define ALIGN_OF(type) RB_GNUC_EXTENSION(_Alignof(type))
206
+ #elif (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112 \
207
+ || (defined(__GNUC__) && __GNUC__ < 4 + (__GNUC_MINOR__ < 9) \
208
+ && !defined(__clang__)) \
209
+ || (defined(__clang__) && __clang_major__ < 8))
210
+ # define ALIGN_OF(type) offsetof(struct {char align_c; type align_x;}, align_x)
211
+ #else
212
+ # define ALIGN_OF(type) _Alignof(type)
213
+ #endif
179
214
 
180
215
  #define ALIGN_VOIDP ALIGN_OF(void*)
181
216
  #define ALIGN_CHAR ALIGN_OF(char)
@@ -53,8 +53,13 @@ function_memsize(const void *p)
53
53
  }
54
54
 
55
55
  const rb_data_type_t function_data_type = {
56
- "fiddle/function",
57
- {0, deallocate, function_memsize,},
56
+ .wrap_struct_name = "fiddle/function",
57
+ .function = {
58
+ .dmark = 0,
59
+ .dfree = deallocate,
60
+ .dsize = function_memsize
61
+ },
62
+ .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED,
58
63
  };
59
64
 
60
65
  static VALUE
data/ext/fiddle/handle.c CHANGED
@@ -50,8 +50,13 @@ fiddle_handle_memsize(const void *ptr)
50
50
  }
51
51
 
52
52
  static const rb_data_type_t fiddle_handle_data_type = {
53
- "fiddle/handle",
54
- {0, fiddle_handle_free, fiddle_handle_memsize,},
53
+ .wrap_struct_name = "fiddle/handle",
54
+ .function = {
55
+ .dmark = 0,
56
+ .dfree = fiddle_handle_free,
57
+ .dsize = fiddle_handle_memsize
58
+ },
59
+ .flags = RUBY_TYPED_WB_PROTECTED,
55
60
  };
56
61
 
57
62
  /*
@@ -321,8 +326,10 @@ rb_fiddle_handle_s_sym(VALUE self, VALUE sym)
321
326
  return fiddle_handle_sym(RTLD_NEXT, sym);
322
327
  }
323
328
 
324
- static VALUE
325
- fiddle_handle_sym(void *handle, VALUE symbol)
329
+ typedef void (*fiddle_void_func)(void);
330
+
331
+ static fiddle_void_func
332
+ fiddle_handle_find_func(void *handle, VALUE symbol)
326
333
  {
327
334
  #if defined(HAVE_DLERROR)
328
335
  const char *err;
@@ -330,13 +337,13 @@ fiddle_handle_sym(void *handle, VALUE symbol)
330
337
  #else
331
338
  # define CHECK_DLERROR
332
339
  #endif
333
- void (*func)();
340
+ fiddle_void_func func;
334
341
  const char *name = StringValueCStr(symbol);
335
342
 
336
343
  #ifdef HAVE_DLERROR
337
344
  dlerror();
338
345
  #endif
339
- func = (void (*)())(VALUE)dlsym(handle, name);
346
+ func = (fiddle_void_func)(VALUE)dlsym(handle, name);
340
347
  CHECK_DLERROR;
341
348
  #if defined(FUNC_STDCALL)
342
349
  if( !func ){
@@ -379,6 +386,53 @@ fiddle_handle_sym(void *handle, VALUE symbol)
379
386
  xfree(name_n);
380
387
  }
381
388
  #endif
389
+
390
+ return func;
391
+ }
392
+
393
+ static VALUE
394
+ rb_fiddle_handle_s_sym_defined(VALUE self, VALUE sym)
395
+ {
396
+ fiddle_void_func func;
397
+
398
+ func = fiddle_handle_find_func(RTLD_NEXT, sym);
399
+
400
+ if( func ) {
401
+ return PTR2NUM(func);
402
+ }
403
+ else {
404
+ return Qnil;
405
+ }
406
+ }
407
+
408
+ static VALUE
409
+ rb_fiddle_handle_sym_defined(VALUE self, VALUE sym)
410
+ {
411
+ struct dl_handle *fiddle_handle;
412
+ fiddle_void_func func;
413
+
414
+ TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
415
+ if( ! fiddle_handle->open ){
416
+ rb_raise(rb_eFiddleDLError, "closed handle");
417
+ }
418
+
419
+ func = fiddle_handle_find_func(fiddle_handle->ptr, sym);
420
+
421
+ if( func ) {
422
+ return PTR2NUM(func);
423
+ }
424
+ else {
425
+ return Qnil;
426
+ }
427
+ }
428
+
429
+ static VALUE
430
+ fiddle_handle_sym(void *handle, VALUE symbol)
431
+ {
432
+ fiddle_void_func func;
433
+
434
+ func = fiddle_handle_find_func(handle, symbol);
435
+
382
436
  if( !func ){
383
437
  rb_raise(rb_eFiddleDLError, "unknown symbol \"%"PRIsVALUE"\"", symbol);
384
438
  }
@@ -468,6 +522,7 @@ Init_fiddle_handle(void)
468
522
  rb_cHandle = rb_define_class_under(mFiddle, "Handle", rb_cObject);
469
523
  rb_define_alloc_func(rb_cHandle, rb_fiddle_handle_s_allocate);
470
524
  rb_define_singleton_method(rb_cHandle, "sym", rb_fiddle_handle_s_sym, 1);
525
+ rb_define_singleton_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_s_sym_defined, 1);
471
526
  rb_define_singleton_method(rb_cHandle, "[]", rb_fiddle_handle_s_sym, 1);
472
527
 
473
528
  /* Document-const: NEXT
@@ -526,6 +581,7 @@ Init_fiddle_handle(void)
526
581
  rb_define_method(rb_cHandle, "close", rb_fiddle_handle_close, 0);
527
582
  rb_define_method(rb_cHandle, "sym", rb_fiddle_handle_sym, 1);
528
583
  rb_define_method(rb_cHandle, "[]", rb_fiddle_handle_sym, 1);
584
+ rb_define_method(rb_cHandle, "sym_defined?", rb_fiddle_handle_sym_defined, 1);
529
585
  rb_define_method(rb_cHandle, "file_name", rb_fiddle_handle_file_name, 0);
530
586
  rb_define_method(rb_cHandle, "disable_close", rb_fiddle_handle_disable_close, 0);
531
587
  rb_define_method(rb_cHandle, "enable_close", rb_fiddle_handle_enable_close, 0);