fiddle 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|