fiddle 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +52 -1
- data/Rakefile +3 -5
- data/bin/downloader.rb +331 -0
- data/bin/extlibs.rb +262 -0
- data/ext/fiddle/closure.c +5 -4
- data/ext/fiddle/conversions.c +161 -16
- data/ext/fiddle/conversions.h +14 -4
- data/ext/fiddle/depend +83 -0
- data/ext/fiddle/extconf.rb +54 -28
- data/ext/fiddle/extlibs +10 -2
- data/ext/fiddle/fiddle.c +46 -35
- data/ext/fiddle/fiddle.h +35 -1
- data/ext/fiddle/function.c +220 -81
- data/ext/fiddle/handle.c +10 -12
- data/ext/fiddle/pinned.c +123 -0
- data/ext/fiddle/pointer.c +106 -24
- data/ext/fiddle/win32/fficonfig.h +0 -0
- data/ext/fiddle/win32/libffi-config.rb +1 -1
- data/ext/fiddle/win32/libffi.mk.tmpl +0 -0
- data/fiddle.gemspec +46 -4
- data/lib/fiddle.rb +3 -1
- data/lib/fiddle/cparser.rb +29 -2
- data/lib/fiddle/import.rb +11 -9
- data/lib/fiddle/pack.rb +14 -7
- data/lib/fiddle/struct.rb +267 -43
- data/lib/fiddle/value.rb +18 -9
- data/lib/fiddle/version.rb +3 -0
- metadata +13 -12
- data/.gitignore +0 -13
- data/.travis.yml +0 -7
- data/Gemfile +0 -4
- data/bin/console +0 -14
- data/bin/setup +0 -8
data/ext/fiddle/handle.c
CHANGED
@@ -1,8 +1,6 @@
|
|
1
1
|
#include <ruby.h>
|
2
2
|
#include <fiddle.h>
|
3
3
|
|
4
|
-
#define SafeStringValueCStr(v) (rb_check_safe_obj(rb_string_value(&v)), StringValueCStr(v))
|
5
|
-
|
6
4
|
VALUE rb_cHandle;
|
7
5
|
|
8
6
|
struct dl_handle {
|
@@ -76,14 +74,14 @@ rb_fiddle_handle_close(VALUE self)
|
|
76
74
|
/* Check dlclose for successful return value */
|
77
75
|
if(ret) {
|
78
76
|
#if defined(HAVE_DLERROR)
|
79
|
-
rb_raise(
|
77
|
+
rb_raise(rb_eFiddleDLError, "%s", dlerror());
|
80
78
|
#else
|
81
|
-
rb_raise(
|
79
|
+
rb_raise(rb_eFiddleDLError, "could not close handle");
|
82
80
|
#endif
|
83
81
|
}
|
84
82
|
return INT2NUM(ret);
|
85
83
|
}
|
86
|
-
rb_raise(
|
84
|
+
rb_raise(rb_eFiddleDLError, "dlclose() called too many times");
|
87
85
|
|
88
86
|
UNREACHABLE;
|
89
87
|
}
|
@@ -145,11 +143,11 @@ rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self)
|
|
145
143
|
cflag = RTLD_LAZY | RTLD_GLOBAL;
|
146
144
|
break;
|
147
145
|
case 1:
|
148
|
-
clib = NIL_P(lib) ? NULL :
|
146
|
+
clib = NIL_P(lib) ? NULL : StringValueCStr(lib);
|
149
147
|
cflag = RTLD_LAZY | RTLD_GLOBAL;
|
150
148
|
break;
|
151
149
|
case 2:
|
152
|
-
clib = NIL_P(lib) ? NULL :
|
150
|
+
clib = NIL_P(lib) ? NULL : StringValueCStr(lib);
|
153
151
|
cflag = NUM2INT(flag);
|
154
152
|
break;
|
155
153
|
default:
|
@@ -179,12 +177,12 @@ rb_fiddle_handle_initialize(int argc, VALUE argv[], VALUE self)
|
|
179
177
|
ptr = dlopen(clib, cflag);
|
180
178
|
#if defined(HAVE_DLERROR)
|
181
179
|
if( !ptr && (err = dlerror()) ){
|
182
|
-
rb_raise(
|
180
|
+
rb_raise(rb_eFiddleDLError, "%s", err);
|
183
181
|
}
|
184
182
|
#else
|
185
183
|
if( !ptr ){
|
186
184
|
err = dlerror();
|
187
|
-
rb_raise(
|
185
|
+
rb_raise(rb_eFiddleDLError, "%s", err);
|
188
186
|
}
|
189
187
|
#endif
|
190
188
|
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
|
@@ -280,7 +278,7 @@ rb_fiddle_handle_sym(VALUE self, VALUE sym)
|
|
280
278
|
|
281
279
|
TypedData_Get_Struct(self, struct dl_handle, &fiddle_handle_data_type, fiddle_handle);
|
282
280
|
if( ! fiddle_handle->open ){
|
283
|
-
rb_raise(
|
281
|
+
rb_raise(rb_eFiddleDLError, "closed handle");
|
284
282
|
}
|
285
283
|
|
286
284
|
return fiddle_handle_sym(fiddle_handle->ptr, sym);
|
@@ -319,7 +317,7 @@ fiddle_handle_sym(void *handle, VALUE symbol)
|
|
319
317
|
# define CHECK_DLERROR
|
320
318
|
#endif
|
321
319
|
void (*func)();
|
322
|
-
const char *name =
|
320
|
+
const char *name = StringValueCStr(symbol);
|
323
321
|
|
324
322
|
#ifdef HAVE_DLERROR
|
325
323
|
dlerror();
|
@@ -368,7 +366,7 @@ fiddle_handle_sym(void *handle, VALUE symbol)
|
|
368
366
|
}
|
369
367
|
#endif
|
370
368
|
if( !func ){
|
371
|
-
rb_raise(
|
369
|
+
rb_raise(rb_eFiddleDLError, "unknown symbol \"%"PRIsVALUE"\"", symbol);
|
372
370
|
}
|
373
371
|
|
374
372
|
return PTR2NUM(func);
|
data/ext/fiddle/pinned.c
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
#include <fiddle.h>
|
2
|
+
|
3
|
+
VALUE rb_cPinned;
|
4
|
+
VALUE rb_eFiddleClearedReferenceError;
|
5
|
+
|
6
|
+
struct pinned_data {
|
7
|
+
VALUE ptr;
|
8
|
+
};
|
9
|
+
|
10
|
+
static void
|
11
|
+
pinned_mark(void *ptr)
|
12
|
+
{
|
13
|
+
struct pinned_data *data = (struct pinned_data*)ptr;
|
14
|
+
/* Ensure reference is pinned */
|
15
|
+
if (data->ptr) {
|
16
|
+
rb_gc_mark(data->ptr);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
static size_t
|
21
|
+
pinned_memsize(const void *ptr)
|
22
|
+
{
|
23
|
+
return sizeof(struct pinned_data);
|
24
|
+
}
|
25
|
+
|
26
|
+
static const rb_data_type_t pinned_data_type = {
|
27
|
+
"fiddle/pinned",
|
28
|
+
{pinned_mark, xfree, pinned_memsize, },
|
29
|
+
0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
|
30
|
+
};
|
31
|
+
|
32
|
+
static VALUE
|
33
|
+
allocate(VALUE klass)
|
34
|
+
{
|
35
|
+
struct pinned_data *data;
|
36
|
+
VALUE obj = TypedData_Make_Struct(klass, struct pinned_data, &pinned_data_type, data);
|
37
|
+
data->ptr = 0;
|
38
|
+
return obj;
|
39
|
+
}
|
40
|
+
|
41
|
+
/*
|
42
|
+
* call-seq:
|
43
|
+
* Fiddle::Pinned.new(object) => pinned_object
|
44
|
+
*
|
45
|
+
* Create a new pinned object reference. The Fiddle::Pinned instance will
|
46
|
+
* prevent the GC from moving +object+.
|
47
|
+
*/
|
48
|
+
static VALUE
|
49
|
+
initialize(VALUE self, VALUE ref)
|
50
|
+
{
|
51
|
+
struct pinned_data *data;
|
52
|
+
TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
|
53
|
+
RB_OBJ_WRITE(self, &data->ptr, ref);
|
54
|
+
return self;
|
55
|
+
}
|
56
|
+
|
57
|
+
/*
|
58
|
+
* call-seq: ref
|
59
|
+
*
|
60
|
+
* Return the object that this pinned instance references.
|
61
|
+
*/
|
62
|
+
static VALUE
|
63
|
+
ref(VALUE self)
|
64
|
+
{
|
65
|
+
struct pinned_data *data;
|
66
|
+
TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
|
67
|
+
if (data->ptr) {
|
68
|
+
return data->ptr;
|
69
|
+
} else {
|
70
|
+
rb_raise(rb_eFiddleClearedReferenceError, "`ref` called on a cleared object");
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
/*
|
75
|
+
* call-seq: clear
|
76
|
+
*
|
77
|
+
* Clear the reference to the object this is pinning.
|
78
|
+
*/
|
79
|
+
static VALUE
|
80
|
+
clear(VALUE self)
|
81
|
+
{
|
82
|
+
struct pinned_data *data;
|
83
|
+
TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
|
84
|
+
data->ptr = 0;
|
85
|
+
return self;
|
86
|
+
}
|
87
|
+
|
88
|
+
/*
|
89
|
+
* call-seq: cleared?
|
90
|
+
*
|
91
|
+
* Returns true if the reference has been cleared, otherwise returns false.
|
92
|
+
*/
|
93
|
+
static VALUE
|
94
|
+
cleared_p(VALUE self)
|
95
|
+
{
|
96
|
+
struct pinned_data *data;
|
97
|
+
TypedData_Get_Struct(self, struct pinned_data, &pinned_data_type, data);
|
98
|
+
if (data->ptr) {
|
99
|
+
return Qfalse;
|
100
|
+
} else {
|
101
|
+
return Qtrue;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
|
105
|
+
extern VALUE rb_eFiddleError;
|
106
|
+
|
107
|
+
void
|
108
|
+
Init_fiddle_pinned(void)
|
109
|
+
{
|
110
|
+
rb_cPinned = rb_define_class_under(mFiddle, "Pinned", rb_cObject);
|
111
|
+
rb_define_alloc_func(rb_cPinned, allocate);
|
112
|
+
rb_define_method(rb_cPinned, "initialize", initialize, 1);
|
113
|
+
rb_define_method(rb_cPinned, "ref", ref, 0);
|
114
|
+
rb_define_method(rb_cPinned, "clear", clear, 0);
|
115
|
+
rb_define_method(rb_cPinned, "cleared?", cleared_p, 0);
|
116
|
+
|
117
|
+
/*
|
118
|
+
* Document-class: Fiddle::ClearedReferenceError
|
119
|
+
*
|
120
|
+
* Cleared reference exception
|
121
|
+
*/
|
122
|
+
rb_eFiddleClearedReferenceError = rb_define_class_under(mFiddle, "ClearedReferenceError", rb_eFiddleError);
|
123
|
+
}
|
data/ext/fiddle/pointer.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
* $Id$
|
3
3
|
*/
|
4
4
|
|
5
|
+
#include <stdbool.h>
|
5
6
|
#include <ruby/ruby.h>
|
6
7
|
#include <ruby/io.h>
|
7
8
|
#include <ctype.h>
|
@@ -24,6 +25,7 @@ struct ptr_data {
|
|
24
25
|
void *ptr;
|
25
26
|
long size;
|
26
27
|
freefunc_t free;
|
28
|
+
bool freed;
|
27
29
|
VALUE wrap[2];
|
28
30
|
};
|
29
31
|
|
@@ -57,14 +59,19 @@ fiddle_ptr_mark(void *ptr)
|
|
57
59
|
}
|
58
60
|
|
59
61
|
static void
|
60
|
-
|
62
|
+
fiddle_ptr_free_ptr(void *ptr)
|
61
63
|
{
|
62
64
|
struct ptr_data *data = ptr;
|
63
|
-
if (data->ptr) {
|
64
|
-
|
65
|
-
|
66
|
-
}
|
65
|
+
if (data->ptr && data->free && !data->freed) {
|
66
|
+
data->freed = true;
|
67
|
+
(*(data->free))(data->ptr);
|
67
68
|
}
|
69
|
+
}
|
70
|
+
|
71
|
+
static void
|
72
|
+
fiddle_ptr_free(void *ptr)
|
73
|
+
{
|
74
|
+
fiddle_ptr_free_ptr(ptr);
|
68
75
|
xfree(ptr);
|
69
76
|
}
|
70
77
|
|
@@ -89,8 +96,8 @@ rb_fiddle_ptr_new2(VALUE klass, void *ptr, long size, freefunc_t func)
|
|
89
96
|
val = TypedData_Make_Struct(klass, struct ptr_data, &fiddle_ptr_data_type, data);
|
90
97
|
data->ptr = ptr;
|
91
98
|
data->free = func;
|
99
|
+
data->freed = false;
|
92
100
|
data->size = size;
|
93
|
-
OBJ_TAINT(val);
|
94
101
|
|
95
102
|
return val;
|
96
103
|
}
|
@@ -102,13 +109,13 @@ rb_fiddle_ptr_new(void *ptr, long size, freefunc_t func)
|
|
102
109
|
}
|
103
110
|
|
104
111
|
static VALUE
|
105
|
-
rb_fiddle_ptr_malloc(long size, freefunc_t func)
|
112
|
+
rb_fiddle_ptr_malloc(VALUE klass, long size, freefunc_t func)
|
106
113
|
{
|
107
114
|
void *ptr;
|
108
115
|
|
109
116
|
ptr = ruby_xmalloc((size_t)size);
|
110
117
|
memset(ptr,0,(size_t)size);
|
111
|
-
return
|
118
|
+
return rb_fiddle_ptr_new2(klass, ptr, size, func);
|
112
119
|
}
|
113
120
|
|
114
121
|
static void *
|
@@ -141,6 +148,7 @@ rb_fiddle_ptr_s_allocate(VALUE klass)
|
|
141
148
|
data->ptr = 0;
|
142
149
|
data->size = 0;
|
143
150
|
data->free = 0;
|
151
|
+
data->freed = false;
|
144
152
|
|
145
153
|
return obj;
|
146
154
|
}
|
@@ -192,16 +200,53 @@ rb_fiddle_ptr_initialize(int argc, VALUE argv[], VALUE self)
|
|
192
200
|
return Qnil;
|
193
201
|
}
|
194
202
|
|
203
|
+
static VALUE
|
204
|
+
rb_fiddle_ptr_call_free(VALUE self);
|
205
|
+
|
195
206
|
/*
|
196
207
|
* call-seq:
|
197
|
-
*
|
198
208
|
* Fiddle::Pointer.malloc(size, freefunc = nil) => fiddle pointer instance
|
209
|
+
* Fiddle::Pointer.malloc(size, freefunc) { |pointer| ... } => ...
|
210
|
+
*
|
211
|
+
* == Examples
|
212
|
+
*
|
213
|
+
* # Automatically freeing the pointer when the block is exited - recommended
|
214
|
+
* Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE) do |pointer|
|
215
|
+
* ...
|
216
|
+
* end
|
217
|
+
*
|
218
|
+
* # Manually freeing but relying on the garbage collector otherwise
|
219
|
+
* pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
|
220
|
+
* ...
|
221
|
+
* pointer.call_free
|
222
|
+
*
|
223
|
+
* # Relying on the garbage collector - may lead to unlimited memory allocated before freeing any, but safe
|
224
|
+
* pointer = Fiddle::Pointer.malloc(size, Fiddle::RUBY_FREE)
|
225
|
+
* ...
|
226
|
+
*
|
227
|
+
* # Only manually freeing
|
228
|
+
* pointer = Fiddle::Pointer.malloc(size)
|
229
|
+
* begin
|
230
|
+
* ...
|
231
|
+
* ensure
|
232
|
+
* Fiddle.free pointer
|
233
|
+
* end
|
234
|
+
*
|
235
|
+
* # No free function and no call to free - the native memory will leak if the pointer is garbage collected
|
236
|
+
* pointer = Fiddle::Pointer.malloc(size)
|
237
|
+
* ...
|
199
238
|
*
|
200
239
|
* Allocate +size+ bytes of memory and associate it with an optional
|
201
|
-
* +freefunc
|
240
|
+
* +freefunc+.
|
241
|
+
*
|
242
|
+
* If a block is supplied, the pointer will be yielded to the block instead of
|
243
|
+
* being returned, and the return value of the block will be returned. A
|
244
|
+
* +freefunc+ must be supplied if a block is.
|
202
245
|
*
|
203
|
-
* +freefunc+
|
204
|
-
*
|
246
|
+
* If a +freefunc+ is supplied it will be called once, when the pointer is
|
247
|
+
* garbage collected or when the block is left if a block is supplied or
|
248
|
+
* when the user calls +call_free+, whichever happens first. +freefunc+ must be
|
249
|
+
* an address pointing to a function or an instance of +Fiddle::Function+.
|
205
250
|
*/
|
206
251
|
static VALUE
|
207
252
|
rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
|
@@ -223,10 +268,17 @@ rb_fiddle_ptr_s_malloc(int argc, VALUE argv[], VALUE klass)
|
|
223
268
|
rb_bug("rb_fiddle_ptr_s_malloc");
|
224
269
|
}
|
225
270
|
|
226
|
-
obj = rb_fiddle_ptr_malloc(s,f);
|
271
|
+
obj = rb_fiddle_ptr_malloc(klass, s,f);
|
227
272
|
if (wrap) RPTR_DATA(obj)->wrap[1] = wrap;
|
228
273
|
|
229
|
-
|
274
|
+
if (rb_block_given_p()) {
|
275
|
+
if (!f) {
|
276
|
+
rb_raise(rb_eArgError, "a free function must be supplied to Fiddle::Pointer.malloc when it is called with a block");
|
277
|
+
}
|
278
|
+
return rb_ensure(rb_yield, obj, rb_fiddle_ptr_call_free, obj);
|
279
|
+
} else {
|
280
|
+
return obj;
|
281
|
+
}
|
230
282
|
}
|
231
283
|
|
232
284
|
/*
|
@@ -351,6 +403,34 @@ rb_fiddle_ptr_free_get(VALUE self)
|
|
351
403
|
return rb_fiddle_new_function(address, arg_types, ret_type);
|
352
404
|
}
|
353
405
|
|
406
|
+
/*
|
407
|
+
* call-seq: call_free => nil
|
408
|
+
*
|
409
|
+
* Call the free function for this pointer. Calling more than once will do
|
410
|
+
* nothing. Does nothing if there is no free function attached.
|
411
|
+
*/
|
412
|
+
static VALUE
|
413
|
+
rb_fiddle_ptr_call_free(VALUE self)
|
414
|
+
{
|
415
|
+
struct ptr_data *pdata;
|
416
|
+
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata);
|
417
|
+
fiddle_ptr_free_ptr(pdata);
|
418
|
+
return Qnil;
|
419
|
+
}
|
420
|
+
|
421
|
+
/*
|
422
|
+
* call-seq: freed? => bool
|
423
|
+
*
|
424
|
+
* Returns if the free function for this pointer has been called.
|
425
|
+
*/
|
426
|
+
static VALUE
|
427
|
+
rb_fiddle_ptr_freed_p(VALUE self)
|
428
|
+
{
|
429
|
+
struct ptr_data *pdata;
|
430
|
+
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, pdata);
|
431
|
+
return pdata->freed ? Qtrue : Qfalse;
|
432
|
+
}
|
433
|
+
|
354
434
|
/*
|
355
435
|
* call-seq:
|
356
436
|
*
|
@@ -376,11 +456,11 @@ rb_fiddle_ptr_to_s(int argc, VALUE argv[], VALUE self)
|
|
376
456
|
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
|
377
457
|
switch (rb_scan_args(argc, argv, "01", &arg1)) {
|
378
458
|
case 0:
|
379
|
-
val =
|
459
|
+
val = rb_str_new2((char*)(data->ptr));
|
380
460
|
break;
|
381
461
|
case 1:
|
382
462
|
len = NUM2INT(arg1);
|
383
|
-
val =
|
463
|
+
val = rb_str_new((char*)(data->ptr), len);
|
384
464
|
break;
|
385
465
|
default:
|
386
466
|
rb_bug("rb_fiddle_ptr_to_s");
|
@@ -414,11 +494,11 @@ rb_fiddle_ptr_to_str(int argc, VALUE argv[], VALUE self)
|
|
414
494
|
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
|
415
495
|
switch (rb_scan_args(argc, argv, "01", &arg1)) {
|
416
496
|
case 0:
|
417
|
-
val =
|
497
|
+
val = rb_str_new((char*)(data->ptr),data->size);
|
418
498
|
break;
|
419
499
|
case 1:
|
420
500
|
len = NUM2INT(arg1);
|
421
|
-
val =
|
501
|
+
val = rb_str_new((char*)(data->ptr), len);
|
422
502
|
break;
|
423
503
|
default:
|
424
504
|
rb_bug("rb_fiddle_ptr_to_str");
|
@@ -440,7 +520,7 @@ rb_fiddle_ptr_inspect(VALUE self)
|
|
440
520
|
|
441
521
|
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
|
442
522
|
return rb_sprintf("#<%"PRIsVALUE":%p ptr=%p size=%ld free=%p>",
|
443
|
-
RB_OBJ_CLASSNAME(self), data, data->ptr, data->size, data->free);
|
523
|
+
RB_OBJ_CLASSNAME(self), (void *)data, data->ptr, data->size, (void *)data->free);
|
444
524
|
}
|
445
525
|
|
446
526
|
/*
|
@@ -542,7 +622,7 @@ rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
|
|
542
622
|
struct ptr_data *data;
|
543
623
|
|
544
624
|
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
|
545
|
-
if (!data->ptr) rb_raise(
|
625
|
+
if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference");
|
546
626
|
switch( rb_scan_args(argc, argv, "11", &arg0, &arg1) ){
|
547
627
|
case 1:
|
548
628
|
offset = NUM2ULONG(arg0);
|
@@ -551,7 +631,7 @@ rb_fiddle_ptr_aref(int argc, VALUE argv[], VALUE self)
|
|
551
631
|
case 2:
|
552
632
|
offset = NUM2ULONG(arg0);
|
553
633
|
len = NUM2ULONG(arg1);
|
554
|
-
retval =
|
634
|
+
retval = rb_str_new((char *)data->ptr + offset, len);
|
555
635
|
break;
|
556
636
|
default:
|
557
637
|
rb_bug("rb_fiddle_ptr_aref()");
|
@@ -580,7 +660,7 @@ rb_fiddle_ptr_aset(int argc, VALUE argv[], VALUE self)
|
|
580
660
|
struct ptr_data *data;
|
581
661
|
|
582
662
|
TypedData_Get_Struct(self, struct ptr_data, &fiddle_ptr_data_type, data);
|
583
|
-
if (!data->ptr) rb_raise(
|
663
|
+
if (!data->ptr) rb_raise(rb_eFiddleDLError, "NULL pointer dereference");
|
584
664
|
switch( rb_scan_args(argc, argv, "21", &arg0, &arg1, &arg2) ){
|
585
665
|
case 2:
|
586
666
|
offset = NUM2ULONG(arg0);
|
@@ -661,7 +741,7 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
|
|
661
741
|
wrap = 0;
|
662
742
|
}
|
663
743
|
else{
|
664
|
-
rb_raise(
|
744
|
+
rb_raise(rb_eFiddleDLError, "to_ptr should return a Fiddle::Pointer object");
|
665
745
|
}
|
666
746
|
}
|
667
747
|
else{
|
@@ -669,7 +749,6 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
|
|
669
749
|
if (num == val) wrap = 0;
|
670
750
|
ptr = rb_fiddle_ptr_new(NUM2PTR(num), 0, NULL);
|
671
751
|
}
|
672
|
-
OBJ_INFECT(ptr, val);
|
673
752
|
if (wrap) RPTR_DATA(ptr)->wrap[0] = wrap;
|
674
753
|
return ptr;
|
675
754
|
}
|
@@ -677,6 +756,7 @@ rb_fiddle_ptr_s_to_ptr(VALUE self, VALUE val)
|
|
677
756
|
void
|
678
757
|
Init_fiddle_pointer(void)
|
679
758
|
{
|
759
|
+
#undef rb_intern
|
680
760
|
id_to_ptr = rb_intern("to_ptr");
|
681
761
|
|
682
762
|
/* Document-class: Fiddle::Pointer
|
@@ -692,6 +772,8 @@ Init_fiddle_pointer(void)
|
|
692
772
|
rb_define_method(rb_cPointer, "initialize", rb_fiddle_ptr_initialize, -1);
|
693
773
|
rb_define_method(rb_cPointer, "free=", rb_fiddle_ptr_free_set, 1);
|
694
774
|
rb_define_method(rb_cPointer, "free", rb_fiddle_ptr_free_get, 0);
|
775
|
+
rb_define_method(rb_cPointer, "call_free", rb_fiddle_ptr_call_free, 0);
|
776
|
+
rb_define_method(rb_cPointer, "freed?", rb_fiddle_ptr_freed_p, 0);
|
695
777
|
rb_define_method(rb_cPointer, "to_i", rb_fiddle_ptr_to_i, 0);
|
696
778
|
rb_define_method(rb_cPointer, "to_int", rb_fiddle_ptr_to_i, 0);
|
697
779
|
rb_define_method(rb_cPointer, "to_value", rb_fiddle_ptr_to_value, 0);
|