rice 1.0.2 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +2 -2
- data/Doxyfile +1 -1
- data/Makefile.in +8 -3
- data/Rakefile +3 -3
- data/config.guess +30 -49
- data/config.sub +4 -22
- data/configure +319 -104
- data/configure.ac +6 -2
- data/doxygen.ac +2 -2
- data/extconf.rb +22 -0
- data/post-autoconf.rb +3 -3
- data/post-automake.rb +2 -2
- data/rice/Array.ipp +7 -6
- data/rice/Critical_Guard.hpp +6 -0
- data/rice/Critical_Guard.ipp +6 -0
- data/rice/Data_Object.hpp +1 -120
- data/rice/Data_Object.ipp +5 -1
- data/rice/Data_Object_defn.hpp +132 -0
- data/rice/Data_Type.ipp +18 -2
- data/rice/Enum.ipp +3 -3
- data/rice/Exception.hpp +1 -61
- data/rice/Exception_Base.hpp +2 -24
- data/rice/Exception_Base.ipp +2 -0
- data/rice/Exception_Base_defn.hpp +27 -0
- data/rice/Exception_defn.hpp +69 -0
- data/rice/Hash.hpp +5 -1
- data/rice/Hash.ipp +7 -7
- data/rice/Makefile.am +20 -3
- data/rice/Makefile.in +39 -4
- data/rice/Module.cpp +11 -3
- data/rice/Module_impl.hpp +20 -9
- data/rice/Module_impl.ipp +84 -87
- data/rice/Object.cpp +1 -1
- data/rice/VM.cpp +14 -1
- data/rice/VM.hpp +6 -1
- data/rice/config.hpp +24 -3
- data/rice/config.hpp.in +21 -0
- data/rice/detail/Auto_Function_Wrapper.hpp +97 -65
- data/rice/detail/Auto_Function_Wrapper.ipp +160 -128
- data/rice/detail/Auto_Member_Function_Wrapper.hpp +96 -64
- data/rice/detail/Auto_Member_Function_Wrapper.ipp +160 -128
- data/rice/detail/Exception_Handler.hpp +2 -112
- data/rice/detail/Exception_Handler.ipp +68 -0
- data/rice/detail/Exception_Handler_defn.hpp +96 -0
- data/rice/detail/Iterator.hpp +93 -0
- data/rice/detail/check_ruby_type.cpp +8 -2
- data/rice/detail/creation_funcs.ipp +2 -2
- data/rice/detail/define_method_and_auto_wrap.hpp +4 -2
- data/rice/detail/define_method_and_auto_wrap.ipp +14 -5
- data/rice/detail/env.hpp +4 -0
- data/rice/detail/method_data.cpp +362 -75
- data/rice/detail/method_data.cpp.rpp +301 -0
- data/rice/detail/method_data.hpp +6 -18
- data/rice/detail/mininode.cpp +1220 -0
- data/rice/detail/mininode.cpp.rpp +62 -0
- data/rice/detail/mininode.hpp +320 -0
- data/rice/detail/mininode.hpp.rpp +119 -0
- data/rice/detail/protect.cpp +4 -2
- data/rice/detail/ruby.hpp +44 -18
- data/rice/detail/ruby_version_code.hpp +6 -0
- data/rice/detail/ruby_version_code.hpp.in +6 -0
- data/rice/detail/rubysig.hpp +6 -0
- data/rice/detail/st.hpp +6 -2
- data/rice/detail/wrap_function.hpp +50 -48
- data/rice/detail/wrap_function.ipp +48 -48
- data/rice/generate_code.rb +43 -293
- data/rice/global_function.hpp +10 -4
- data/rice/global_function.ipp +1 -2
- data/rice/ruby_mark.hpp +13 -0
- data/rice/ruby_try_catch.hpp +1 -1
- data/rice/rubypp.rb +97 -0
- data/rice/to_from_ruby.ipp +3 -3
- data/ruby.ac +44 -8
- data/ruby/Makefile.in +2 -0
- data/ruby/lib/Makefile.in +2 -0
- data/ruby/lib/mkmf-rice.rb.in +4 -1
- data/ruby/lib/version.rb +3 -0
- data/sample/Makefile.am +2 -2
- data/sample/Makefile.in +4 -2
- data/test/Makefile.am +2 -1
- data/test/Makefile.in +7 -2
- data/test/test_Array.cpp +2 -2
- data/test/test_Class.cpp +4 -1
- data/test/test_Critical_Guard.cpp +4 -0
- data/test/test_Data_Object.cpp +43 -3
- data/test/test_Hash.cpp +3 -3
- data/test/test_String.cpp +8 -8
- data/test/test_VM.cpp +1 -1
- data/test/test_global_functions.cpp +45 -0
- data/test/test_rice.rb +5 -0
- metadata +115 -98
- data/rice/detail/Iterator_Definer.hpp +0 -98
data/rice/detail/env.hpp
CHANGED
data/rice/detail/method_data.cpp
CHANGED
@@ -1,105 +1,392 @@
|
|
1
1
|
#include "method_data.hpp"
|
2
2
|
|
3
|
-
|
4
|
-
#
|
3
|
+
// TODO: This is silly, autoconf...
|
4
|
+
#undef PACKAGE_NAME
|
5
|
+
#undef PACKAGE_STRING
|
6
|
+
#undef PACKAGE_TARNAME
|
7
|
+
#undef PACKAGE_VERSION
|
5
8
|
|
6
|
-
#include
|
9
|
+
#include "../config.hpp"
|
10
|
+
|
11
|
+
|
12
|
+
#if defined(HAVE_NODE_H)
|
13
|
+
/* pre-YARV */
|
14
|
+
#include <node.h>
|
15
|
+
#elif defined(REALLY_HAVE_RUBY_NODE_H)
|
16
|
+
/* YARV */
|
17
|
+
#include <ruby/node.h>
|
18
|
+
#else
|
19
|
+
/* YARV without node.h */
|
20
|
+
#include "mininode.hpp"
|
21
|
+
using namespace Rice::detail::Mininode;
|
22
|
+
#endif
|
7
23
|
|
8
24
|
#include "env.hpp"
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
// NODE_METHOD
|
14
|
-
// |- (u1) noex - method visibility
|
15
|
-
// +- (u2) body
|
16
|
-
// +- NODE_CFUNC
|
17
|
-
// |- (u1) cfnc - function to call
|
18
|
-
// +- (u2) argc - number of arguments
|
19
|
-
//
|
20
|
-
// We use the unused third member (u3) of the CFUNC node to store method
|
21
|
-
// data.
|
22
|
-
//
|
23
|
-
// We could use the unused third member of the METHOD node, but then the
|
24
|
-
// method data would not be copied when the method is aliased. The
|
25
|
-
// result then would be a segfault whenver the method is called.
|
26
|
-
//
|
27
|
-
// Using the third member of the METHOD node would also prevent adding
|
28
|
-
// the method atomically (rather, the method would be added and then the
|
29
|
-
// node later modified to contain the data).
|
30
|
-
//
|
31
|
-
// When the function is called, it can retrieve the defined data by
|
32
|
-
// calling method_data(). We then do a lookup in the class to find the
|
33
|
-
// node for the method's bdoy. This is necessary, because there's no
|
34
|
-
// way to get the node of a called function directly. However, by using
|
35
|
-
// the class's method table, we can do one lookup instead of two (one to
|
36
|
-
// find the class data and another to find the method data).
|
25
|
+
|
26
|
+
#ifdef RUBY_VM
|
27
|
+
|
28
|
+
/* YARV */
|
37
29
|
|
38
30
|
namespace
|
39
31
|
{
|
40
32
|
|
41
|
-
|
33
|
+
struct rb_thread_struct
|
34
|
+
{
|
35
|
+
VALUE self;
|
36
|
+
void *vm;
|
37
|
+
VALUE *stack;
|
38
|
+
unsigned long stack_size;
|
39
|
+
VALUE *cfp;
|
40
|
+
/* ... */
|
41
|
+
};
|
42
|
+
|
43
|
+
typedef struct rb_thread_struct rb_thread_t;
|
44
|
+
|
45
|
+
} // namespace
|
46
|
+
|
47
|
+
extern "C" rb_thread_t * ruby_current_thread;
|
48
|
+
|
49
|
+
#endif
|
50
|
+
|
51
|
+
namespace
|
42
52
|
{
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
53
|
+
|
54
|
+
#ifdef RUBY_VM
|
55
|
+
|
56
|
+
/* YARV */
|
57
|
+
|
58
|
+
#define CFP_DATA_MEMO_NODE_AND_PC cfp[0]
|
59
|
+
#define CFP_METHOD_CLASS cfp[11]
|
60
|
+
|
61
|
+
/* On YARV, we store the method data on the stack. We don't have to pop
|
62
|
+
* it off the stack, because the stack pointer will be reset to the
|
63
|
+
* previous frame's stack pointer when the function returns.
|
64
|
+
*/
|
65
|
+
static void fix_frame()
|
66
|
+
{
|
67
|
+
do {
|
68
|
+
VALUE * cfp = ruby_current_thread->cfp;
|
69
|
+
CFP_DATA_MEMO_NODE_AND_PC = RBASIC(CFP_METHOD_CLASS)->klass;
|
70
|
+
|
71
|
+
if(rb_type(CFP_DATA_MEMO_NODE_AND_PC) != T_NODE)
|
72
|
+
{
|
73
|
+
/* This can happen for module functions that are created after
|
74
|
+
* the stub function */
|
75
|
+
rb_raise(
|
76
|
+
rb_eRuntimeError,
|
77
|
+
"Cannot find method data for module function");
|
78
|
+
}
|
79
|
+
else
|
80
|
+
{
|
81
|
+
CFP_METHOD_CLASS = RCLASS_SUPER(CFP_METHOD_CLASS);
|
82
|
+
}
|
83
|
+
} while(0);
|
52
84
|
}
|
53
85
|
|
54
|
-
|
86
|
+
#define FIX_FRAME() \
|
87
|
+
fix_frame()
|
88
|
+
|
89
|
+
static NODE * data_memo_node()
|
55
90
|
{
|
56
|
-
|
91
|
+
VALUE * cfp = ruby_current_thread->cfp;
|
92
|
+
return (NODE *)CFP_DATA_MEMO_NODE_AND_PC;
|
93
|
+
}
|
57
94
|
|
58
|
-
|
59
|
-
{
|
60
|
-
throw std::runtime_error("Method has no body");
|
61
|
-
}
|
95
|
+
#else
|
62
96
|
|
63
|
-
|
97
|
+
/* pre-YARV */
|
98
|
+
|
99
|
+
/* Okay to not pop this temporary frame, since it will be popped by the
|
100
|
+
* caller
|
101
|
+
*/
|
102
|
+
#define FIX_FRAME() \
|
103
|
+
struct FRAME _frame = *ruby_frame; \
|
104
|
+
_frame.last_class = RCLASS(ruby_frame->last_class)->super; \
|
105
|
+
_frame.prev = ruby_frame; \
|
106
|
+
ruby_frame = &_frame; \
|
107
|
+
|
108
|
+
static NODE * data_memo_node()
|
109
|
+
{
|
110
|
+
return (NODE *)(RBASIC(ruby_frame->prev->last_class)->klass);
|
64
111
|
}
|
65
112
|
|
66
|
-
|
113
|
+
#endif
|
67
114
|
|
68
|
-
|
69
|
-
|
115
|
+
typedef VALUE (*Method_Func)(ANYARGS);
|
116
|
+
|
117
|
+
static Method_Func actual_cfunc()
|
118
|
+
{
|
119
|
+
return data_memo_node()->nd_cfnc;
|
120
|
+
}
|
121
|
+
|
122
|
+
static VALUE data_wrapper_m1(int argc, VALUE * argv, VALUE self)
|
70
123
|
{
|
71
|
-
|
72
|
-
|
73
|
-
|
124
|
+
VALUE result;
|
125
|
+
FIX_FRAME();
|
126
|
+
result = (*actual_cfunc())(argc, argv, self);
|
127
|
+
return result;
|
128
|
+
}
|
74
129
|
|
75
|
-
|
130
|
+
static VALUE data_wrapper_0(VALUE self)
|
131
|
+
{
|
132
|
+
VALUE result;
|
133
|
+
FIX_FRAME();
|
134
|
+
result = (*actual_cfunc())(self);
|
135
|
+
return result;
|
76
136
|
}
|
77
137
|
|
78
|
-
|
138
|
+
static VALUE data_wrapper_1(VALUE self, VALUE arg1)
|
139
|
+
{
|
140
|
+
VALUE result;
|
141
|
+
FIX_FRAME();
|
142
|
+
result = (*actual_cfunc())(self, arg1);
|
143
|
+
return result;
|
144
|
+
}
|
145
|
+
static VALUE data_wrapper_2(VALUE self, VALUE arg1, VALUE arg2)
|
146
|
+
{
|
147
|
+
VALUE result;
|
148
|
+
FIX_FRAME();
|
149
|
+
result = (*actual_cfunc())(self, arg1, arg2);
|
150
|
+
return result;
|
151
|
+
}
|
152
|
+
static VALUE data_wrapper_3(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3)
|
153
|
+
{
|
154
|
+
VALUE result;
|
155
|
+
FIX_FRAME();
|
156
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3);
|
157
|
+
return result;
|
158
|
+
}
|
159
|
+
static VALUE data_wrapper_4(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4)
|
160
|
+
{
|
161
|
+
VALUE result;
|
162
|
+
FIX_FRAME();
|
163
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4);
|
164
|
+
return result;
|
165
|
+
}
|
166
|
+
static VALUE data_wrapper_5(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5)
|
167
|
+
{
|
168
|
+
VALUE result;
|
169
|
+
FIX_FRAME();
|
170
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5);
|
171
|
+
return result;
|
172
|
+
}
|
173
|
+
static VALUE data_wrapper_6(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6)
|
174
|
+
{
|
175
|
+
VALUE result;
|
176
|
+
FIX_FRAME();
|
177
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6);
|
178
|
+
return result;
|
179
|
+
}
|
180
|
+
static VALUE data_wrapper_7(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7)
|
181
|
+
{
|
182
|
+
VALUE result;
|
183
|
+
FIX_FRAME();
|
184
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
|
185
|
+
return result;
|
186
|
+
}
|
187
|
+
static VALUE data_wrapper_8(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8)
|
188
|
+
{
|
189
|
+
VALUE result;
|
190
|
+
FIX_FRAME();
|
191
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
|
192
|
+
return result;
|
193
|
+
}
|
194
|
+
static VALUE data_wrapper_9(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9)
|
195
|
+
{
|
196
|
+
VALUE result;
|
197
|
+
FIX_FRAME();
|
198
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
|
199
|
+
return result;
|
200
|
+
}
|
201
|
+
static VALUE data_wrapper_10(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10)
|
202
|
+
{
|
203
|
+
VALUE result;
|
204
|
+
FIX_FRAME();
|
205
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10);
|
206
|
+
return result;
|
207
|
+
}
|
208
|
+
static VALUE data_wrapper_11(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11)
|
209
|
+
{
|
210
|
+
VALUE result;
|
211
|
+
FIX_FRAME();
|
212
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11);
|
213
|
+
return result;
|
214
|
+
}
|
215
|
+
static VALUE data_wrapper_12(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12)
|
216
|
+
{
|
217
|
+
VALUE result;
|
218
|
+
FIX_FRAME();
|
219
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12);
|
220
|
+
return result;
|
221
|
+
}
|
222
|
+
static VALUE data_wrapper_13(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12, VALUE arg13)
|
223
|
+
{
|
224
|
+
VALUE result;
|
225
|
+
FIX_FRAME();
|
226
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13);
|
227
|
+
return result;
|
228
|
+
}
|
229
|
+
static VALUE data_wrapper_14(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12, VALUE arg13, VALUE arg14)
|
230
|
+
{
|
231
|
+
VALUE result;
|
232
|
+
FIX_FRAME();
|
233
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
|
234
|
+
return result;
|
235
|
+
}
|
236
|
+
static VALUE data_wrapper_15(VALUE self, VALUE arg1, VALUE arg2, VALUE arg3, VALUE arg4, VALUE arg5, VALUE arg6, VALUE arg7, VALUE arg8, VALUE arg9, VALUE arg10, VALUE arg11, VALUE arg12, VALUE arg13, VALUE arg14, VALUE arg15)
|
237
|
+
{
|
238
|
+
VALUE result;
|
239
|
+
FIX_FRAME();
|
240
|
+
result = (*actual_cfunc())(self, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14, arg15);
|
241
|
+
return result;
|
242
|
+
}
|
243
|
+
|
244
|
+
} // namespace
|
245
|
+
|
246
|
+
/* Define a method and attach data to it.
|
247
|
+
*
|
248
|
+
* The method looks to ruby like a normal aliased CFUNC, with a modified
|
249
|
+
* origin class:
|
250
|
+
*
|
251
|
+
* NODE_FBODY
|
252
|
+
* |- (u1) orig - origin class
|
253
|
+
* | |- basic
|
254
|
+
* | | |- flags - origin class flags + FL_SINGLETON
|
255
|
+
* | | +- klass - NODE_MEMO
|
256
|
+
* | | |- (u1) cfnc - actual C function to call
|
257
|
+
* | | |- (u2) rval - stored data
|
258
|
+
* | | +- (u3) 0
|
259
|
+
* | |- iv_tbl - 0
|
260
|
+
* | |- m_tbl - 0
|
261
|
+
* | +- super - actual origin class
|
262
|
+
* |- (u2) mid - name of the method
|
263
|
+
* +- (u3) head - NODE_CFUNC
|
264
|
+
* |- (u1) cfnc - wrapper function to call
|
265
|
+
* +- (u2) argc - function arity
|
266
|
+
*
|
267
|
+
* Or, on YARV:
|
268
|
+
*
|
269
|
+
* NODE_FBODY
|
270
|
+
* |- (u1) oid - name of the method
|
271
|
+
* +- (u2) body - NODE_METHOD
|
272
|
+
* |- (u1) clss - origin class
|
273
|
+
* | |- basic
|
274
|
+
* | | |- flags - origin class flags + FL_SINGLETON
|
275
|
+
* | | +- klass - NODE_MEMO
|
276
|
+
* | | |- (u1) cfnc - actual C function to call
|
277
|
+
* | | |- (u2) rval - stored data
|
278
|
+
* | | +- (u3) 0
|
279
|
+
* | |- ptr - rb_classext_t
|
280
|
+
* | | |- super - actual origin class
|
281
|
+
* | | +- iv_tbl - 0
|
282
|
+
* | |- m_tbl - 0
|
283
|
+
* | +- iv_index_tbl - 0?
|
284
|
+
* |- (u2) body - NODE_CFUNC
|
285
|
+
* | |- (u1) cfnc - wrapper function to call
|
286
|
+
* | |- (u2) argc - function arity
|
287
|
+
* +- (u3) noex - NOEX_PUBLIC
|
288
|
+
*
|
289
|
+
* When the wrapper function is called, last_class is set to the origin
|
290
|
+
* class found in the FBODY node. So that the method data will be
|
291
|
+
* accessible, and so last_class will point to klass and not to our MEMO
|
292
|
+
* node, it is necessary to "fix" the current frame.
|
293
|
+
*
|
294
|
+
* Pre-YARV, this means we duplicate the current frame and set last_class:
|
295
|
+
*
|
296
|
+
* ruby_frame
|
297
|
+
* |- last_class - klass
|
298
|
+
* |- prev
|
299
|
+
* | |- last_class - NODE_MEMO
|
300
|
+
* | | |- (u1) cfnc - actual C function to call
|
301
|
+
* | | |- (u2) rval - stored data
|
302
|
+
* | | +- (u3) 0
|
303
|
+
* | |- prev - the real previous frame
|
304
|
+
* | +- ...
|
305
|
+
* +- ...
|
306
|
+
*
|
307
|
+
* The method data is then accessible via
|
308
|
+
* ruby_frame->prev->last_class->rval.
|
309
|
+
*
|
310
|
+
* On YARV, the current frame is not duplicated; rather, the method data
|
311
|
+
* is placed on the stack and is referenced by one of the unused members
|
312
|
+
* of the control frame (the program counter):
|
313
|
+
*
|
314
|
+
* ruby_current_thread->cfp
|
315
|
+
* |- pc - NODE_MEMO
|
316
|
+
* | |- (u1) cfnc - actual C function to call
|
317
|
+
* | |- (u2) rval - stored data
|
318
|
+
* | +- (u3) 0
|
319
|
+
* |- method_class - klass
|
320
|
+
* +- ...
|
321
|
+
*
|
322
|
+
*/
|
323
|
+
VALUE
|
324
|
+
Rice::detail::
|
79
325
|
define_method_with_data(
|
80
|
-
VALUE klass,
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
{
|
86
|
-
NODE * node = NEW_CFUNC(func, num_args);
|
87
|
-
node->nd_entry = (global_entry *)data;
|
88
|
-
#if RUBY_VERSION_CODE >= 180
|
89
|
-
rb_add_method(klass, rb_intern(name), node, NOEX_PUBLIC);
|
326
|
+
VALUE klass, ID id, VALUE (*cfunc)(ANYARGS), int arity, VALUE data)
|
327
|
+
{
|
328
|
+
/* TODO: origin should have #to_s and #inspect methods defined */
|
329
|
+
#ifdef HAVE_RB_CLASS_BOOT
|
330
|
+
VALUE origin = rb_class_boot(klass);
|
90
331
|
#else
|
91
|
-
|
92
|
-
rb_enable_super(klass, name);
|
332
|
+
VALUE origin = rb_class_new(klass);
|
93
333
|
#endif
|
334
|
+
NODE * node;
|
335
|
+
|
336
|
+
VALUE (*data_wrapper)(ANYARGS);
|
337
|
+
switch(arity)
|
338
|
+
{
|
339
|
+
case 0: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_0); break;
|
340
|
+
case 1: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_1); break;
|
341
|
+
case 2: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_2); break;
|
342
|
+
case 3: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_3); break;
|
343
|
+
case 4: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_4); break;
|
344
|
+
case 5: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_5); break;
|
345
|
+
case 6: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_6); break;
|
346
|
+
case 7: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_7); break;
|
347
|
+
case 8: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_8); break;
|
348
|
+
case 9: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_9); break;
|
349
|
+
case 10: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_10); break;
|
350
|
+
case 11: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_11); break;
|
351
|
+
case 12: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_12); break;
|
352
|
+
case 13: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_13); break;
|
353
|
+
case 14: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_14); break;
|
354
|
+
case 15: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_15); break;
|
355
|
+
case -1: data_wrapper = RUBY_METHOD_FUNC(data_wrapper_m1); break;
|
356
|
+
default: rb_raise(rb_eArgError, "unsupported arity %d", arity);
|
357
|
+
}
|
358
|
+
|
359
|
+
FL_SET(origin, FL_SINGLETON);
|
360
|
+
rb_singleton_class_attached(origin, klass);
|
361
|
+
rb_name_class(origin, SYM2ID(rb_class_name(klass)));
|
362
|
+
|
363
|
+
RBASIC(origin)->klass = (VALUE)NEW_NODE(NODE_MEMO, cfunc, data, 0);
|
364
|
+
|
365
|
+
#ifdef RUBY_VM
|
366
|
+
/* YARV */
|
367
|
+
node = NEW_FBODY(
|
368
|
+
NEW_METHOD(
|
369
|
+
NEW_CFUNC(data_wrapper, arity),
|
370
|
+
origin,
|
371
|
+
NOEX_PUBLIC),
|
372
|
+
id);
|
373
|
+
st_insert(RCLASS_M_TBL(klass), id, (st_data_t)node);
|
374
|
+
#else
|
375
|
+
/* pre-YARV */
|
376
|
+
node = NEW_FBODY(
|
377
|
+
NEW_CFUNC(data_wrapper, arity),
|
378
|
+
id,
|
379
|
+
origin);
|
380
|
+
rb_add_method(klass, id, node, NOEX_PUBLIC);
|
381
|
+
#endif
|
382
|
+
|
383
|
+
return Qnil;
|
94
384
|
}
|
95
385
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
char const * name,
|
100
|
-
void * data)
|
386
|
+
VALUE
|
387
|
+
Rice::detail::
|
388
|
+
method_data()
|
101
389
|
{
|
102
|
-
|
103
|
-
node->nd_entry = (global_entry *)data;
|
390
|
+
return data_memo_node()->nd_rval;
|
104
391
|
}
|
105
392
|
|