fiddle 1.0.0.beta2 → 1.0.4
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 +5 -5
- data/README.md +72 -3
- data/Rakefile +4 -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 +205 -16
- data/ext/fiddle/conversions.h +14 -4
- data/ext/fiddle/depend +85 -0
- data/ext/fiddle/extconf.rb +60 -29
- data/ext/fiddle/extlibs +10 -2
- data/ext/fiddle/fiddle.c +133 -34
- data/ext/fiddle/fiddle.h +96 -32
- data/ext/fiddle/function.c +261 -93
- data/ext/fiddle/handle.c +10 -12
- data/ext/fiddle/memory_view.c +254 -0
- data/ext/fiddle/pinned.c +123 -0
- data/ext/fiddle/pointer.c +147 -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 +50 -5
- data/lib/fiddle.rb +3 -1
- data/lib/fiddle/cparser.rb +93 -25
- data/lib/fiddle/function.rb +5 -0
- 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 +18 -15
- data/.gitignore +0 -13
- data/.travis.yml +0 -5
- 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);
|
@@ -0,0 +1,254 @@
|
|
1
|
+
#include <stdbool.h>
|
2
|
+
#include <ruby/ruby.h>
|
3
|
+
|
4
|
+
#ifdef HAVE_RUBY_MEMORY_VIEW_H
|
5
|
+
# include <ruby/memory_view.h>
|
6
|
+
#endif
|
7
|
+
|
8
|
+
#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
|
9
|
+
# define INTPTR2NUM LL2NUM
|
10
|
+
# define UINTPTR2NUM ULL2NUM
|
11
|
+
#elif SIZEOF_INTPTR_T == SIZEOF_LONG
|
12
|
+
# define INTPTR2NUM LONG2NUM
|
13
|
+
# define UINTPTR2NUM ULONG2NUM
|
14
|
+
#else
|
15
|
+
# define INTPTR2NUM INT2NUM
|
16
|
+
# define UINTPTR2NUM UINT2NUM
|
17
|
+
#endif
|
18
|
+
|
19
|
+
#include <fiddle.h>
|
20
|
+
|
21
|
+
#ifdef FIDDLE_MEMORY_VIEW
|
22
|
+
VALUE rb_cMemoryView = Qnil;
|
23
|
+
|
24
|
+
struct memview_data {
|
25
|
+
rb_memory_view_t view;
|
26
|
+
rb_memory_view_item_component_t *members;
|
27
|
+
size_t n_members;
|
28
|
+
};
|
29
|
+
|
30
|
+
static void
|
31
|
+
fiddle_memview_mark(void *ptr)
|
32
|
+
{
|
33
|
+
const struct memview_data *data = ptr;
|
34
|
+
rb_gc_mark(data->view.obj);
|
35
|
+
}
|
36
|
+
|
37
|
+
static void
|
38
|
+
fiddle_memview_free(void *ptr)
|
39
|
+
{
|
40
|
+
struct memview_data *data = ptr;
|
41
|
+
rb_memory_view_release(&data->view);
|
42
|
+
if (data->members)
|
43
|
+
xfree(data->members);
|
44
|
+
xfree(ptr);
|
45
|
+
}
|
46
|
+
|
47
|
+
static size_t
|
48
|
+
fiddle_memview_memsize(const void *ptr)
|
49
|
+
{
|
50
|
+
const struct memview_data *data = ptr;
|
51
|
+
return sizeof(*data) + sizeof(rb_memory_view_item_component_t)*data->n_members + (size_t)data->view.len;
|
52
|
+
}
|
53
|
+
|
54
|
+
static const rb_data_type_t fiddle_memview_data_type = {
|
55
|
+
"fiddle/memory_view",
|
56
|
+
{fiddle_memview_mark, fiddle_memview_free, fiddle_memview_memsize,},
|
57
|
+
};
|
58
|
+
|
59
|
+
static VALUE
|
60
|
+
rb_fiddle_memview_s_allocate(VALUE klass)
|
61
|
+
{
|
62
|
+
struct memview_data *data;
|
63
|
+
VALUE obj = TypedData_Make_Struct(klass, struct memview_data, &fiddle_memview_data_type, data);
|
64
|
+
data->view.obj = Qnil;
|
65
|
+
data->members = NULL;
|
66
|
+
data->n_members = 0;
|
67
|
+
return obj;
|
68
|
+
}
|
69
|
+
|
70
|
+
static VALUE
|
71
|
+
rb_fiddle_memview_initialize(VALUE obj, VALUE target)
|
72
|
+
{
|
73
|
+
struct memview_data *data;
|
74
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
75
|
+
|
76
|
+
if (!rb_memory_view_get(target, &data->view, 0)) {
|
77
|
+
rb_raise(rb_eArgError, "Unable to get a memory view from %+"PRIsVALUE, target);
|
78
|
+
}
|
79
|
+
|
80
|
+
return Qnil;
|
81
|
+
}
|
82
|
+
|
83
|
+
static VALUE
|
84
|
+
rb_fiddle_memview_get_obj(VALUE obj)
|
85
|
+
{
|
86
|
+
struct memview_data *data;
|
87
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
88
|
+
|
89
|
+
return data->view.obj;
|
90
|
+
}
|
91
|
+
|
92
|
+
static VALUE
|
93
|
+
rb_fiddle_memview_get_length(VALUE obj)
|
94
|
+
{
|
95
|
+
struct memview_data *data;
|
96
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
97
|
+
|
98
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
99
|
+
return SSIZET2NUM(data->view.len);
|
100
|
+
}
|
101
|
+
|
102
|
+
static VALUE
|
103
|
+
rb_fiddle_memview_get_readonly(VALUE obj)
|
104
|
+
{
|
105
|
+
struct memview_data *data;
|
106
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
107
|
+
|
108
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
109
|
+
return data->view.readonly ? Qtrue : Qfalse;
|
110
|
+
}
|
111
|
+
|
112
|
+
static VALUE
|
113
|
+
rb_fiddle_memview_get_format(VALUE obj)
|
114
|
+
{
|
115
|
+
struct memview_data *data;
|
116
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
117
|
+
|
118
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
119
|
+
return data->view.format == NULL ? Qnil : rb_str_new_cstr(data->view.format);
|
120
|
+
}
|
121
|
+
|
122
|
+
static VALUE
|
123
|
+
rb_fiddle_memview_get_item_size(VALUE obj)
|
124
|
+
{
|
125
|
+
struct memview_data *data;
|
126
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
127
|
+
|
128
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
129
|
+
return SSIZET2NUM(data->view.item_size);
|
130
|
+
}
|
131
|
+
|
132
|
+
static VALUE
|
133
|
+
rb_fiddle_memview_get_ndim(VALUE obj)
|
134
|
+
{
|
135
|
+
struct memview_data *data;
|
136
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
137
|
+
|
138
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
139
|
+
return SSIZET2NUM(data->view.ndim);
|
140
|
+
}
|
141
|
+
|
142
|
+
static VALUE
|
143
|
+
rb_fiddle_memview_get_shape(VALUE obj)
|
144
|
+
{
|
145
|
+
struct memview_data *data;
|
146
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
147
|
+
|
148
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
149
|
+
if (data->view.shape == NULL) return Qnil;
|
150
|
+
|
151
|
+
const ssize_t ndim = data->view.ndim;
|
152
|
+
VALUE shape = rb_ary_new_capa(ndim);
|
153
|
+
ssize_t i;
|
154
|
+
for (i = 0; i < ndim; ++i) {
|
155
|
+
rb_ary_push(shape, SSIZET2NUM(data->view.shape[i]));
|
156
|
+
}
|
157
|
+
return shape;
|
158
|
+
}
|
159
|
+
|
160
|
+
static VALUE
|
161
|
+
rb_fiddle_memview_get_strides(VALUE obj)
|
162
|
+
{
|
163
|
+
struct memview_data *data;
|
164
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
165
|
+
|
166
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
167
|
+
if (data->view.strides == NULL) return Qnil;
|
168
|
+
|
169
|
+
const ssize_t ndim = data->view.ndim;
|
170
|
+
VALUE strides = rb_ary_new_capa(ndim);
|
171
|
+
ssize_t i;
|
172
|
+
for (i = 0; i < ndim; ++i) {
|
173
|
+
rb_ary_push(strides, SSIZET2NUM(data->view.strides[i]));
|
174
|
+
}
|
175
|
+
return strides;
|
176
|
+
}
|
177
|
+
|
178
|
+
static VALUE
|
179
|
+
rb_fiddle_memview_get_sub_offsets(VALUE obj)
|
180
|
+
{
|
181
|
+
struct memview_data *data;
|
182
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
183
|
+
|
184
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
185
|
+
if (data->view.sub_offsets == NULL) return Qnil;
|
186
|
+
|
187
|
+
const ssize_t ndim = data->view.ndim;
|
188
|
+
VALUE sub_offsets = rb_ary_new_capa(ndim);
|
189
|
+
ssize_t i;
|
190
|
+
for (i = 0; i < ndim; ++i) {
|
191
|
+
rb_ary_push(sub_offsets, SSIZET2NUM(data->view.sub_offsets[i]));
|
192
|
+
}
|
193
|
+
return sub_offsets;
|
194
|
+
}
|
195
|
+
|
196
|
+
static VALUE
|
197
|
+
rb_fiddle_memview_aref(int argc, VALUE *argv, VALUE obj)
|
198
|
+
{
|
199
|
+
struct memview_data *data;
|
200
|
+
TypedData_Get_Struct(obj, struct memview_data, &fiddle_memview_data_type, data);
|
201
|
+
|
202
|
+
if (NIL_P(data->view.obj)) return Qnil;
|
203
|
+
|
204
|
+
const ssize_t ndim = data->view.ndim;
|
205
|
+
if (argc != ndim) {
|
206
|
+
rb_raise(rb_eIndexError, "wrong number of index (%d for %"PRIdSIZE")", argc, ndim);
|
207
|
+
}
|
208
|
+
|
209
|
+
VALUE indices_v = 0;
|
210
|
+
ssize_t *indices = ALLOCV_N(ssize_t, indices_v, ndim);
|
211
|
+
|
212
|
+
ssize_t i;
|
213
|
+
for (i = 0; i < ndim; ++i) {
|
214
|
+
ssize_t x = NUM2SSIZET(argv[i]);
|
215
|
+
indices[i] = x;
|
216
|
+
}
|
217
|
+
|
218
|
+
uint8_t *ptr = rb_memory_view_get_item_pointer(&data->view, indices);
|
219
|
+
ALLOCV_END(indices_v);
|
220
|
+
|
221
|
+
if (data->view.format == NULL) {
|
222
|
+
return INT2FIX(*ptr);
|
223
|
+
}
|
224
|
+
|
225
|
+
if (!data->members) {
|
226
|
+
const char *err;
|
227
|
+
if (rb_memory_view_parse_item_format(data->view.format, &data->members, &data->n_members, &err) < 0) {
|
228
|
+
rb_raise(rb_eRuntimeError, "Unable to recognize item format at %"PRIdSIZE" in \"%s\"",
|
229
|
+
err - data->view.format, data->view.format);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
|
233
|
+
return rb_memory_view_extract_item_members(ptr, data->members, data->n_members);
|
234
|
+
}
|
235
|
+
|
236
|
+
void
|
237
|
+
Init_fiddle_memory_view(void)
|
238
|
+
{
|
239
|
+
rb_cMemoryView = rb_define_class_under(mFiddle, "MemoryView", rb_cObject);
|
240
|
+
rb_define_alloc_func(rb_cMemoryView, rb_fiddle_memview_s_allocate);
|
241
|
+
rb_define_method(rb_cMemoryView, "initialize", rb_fiddle_memview_initialize, 1);
|
242
|
+
rb_define_method(rb_cMemoryView, "obj", rb_fiddle_memview_get_obj, 0);
|
243
|
+
rb_define_method(rb_cMemoryView, "length", rb_fiddle_memview_get_length, 0);
|
244
|
+
rb_define_method(rb_cMemoryView, "readonly?", rb_fiddle_memview_get_readonly, 0);
|
245
|
+
rb_define_method(rb_cMemoryView, "format", rb_fiddle_memview_get_format, 0);
|
246
|
+
rb_define_method(rb_cMemoryView, "item_size", rb_fiddle_memview_get_item_size, 0);
|
247
|
+
rb_define_method(rb_cMemoryView, "ndim", rb_fiddle_memview_get_ndim, 0);
|
248
|
+
rb_define_method(rb_cMemoryView, "shape", rb_fiddle_memview_get_shape, 0);
|
249
|
+
rb_define_method(rb_cMemoryView, "strides", rb_fiddle_memview_get_strides, 0);
|
250
|
+
rb_define_method(rb_cMemoryView, "sub_offsets", rb_fiddle_memview_get_sub_offsets, 0);
|
251
|
+
rb_define_method(rb_cMemoryView, "[]", rb_fiddle_memview_aref, -1);
|
252
|
+
}
|
253
|
+
|
254
|
+
#endif /* FIDDLE_MEMORY_VIEW */
|
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
|
+
}
|