1 | #include "mruby.h"
|
---|
2 | #include "mruby/array.h"
|
---|
3 | #include "mruby/class.h"
|
---|
4 | #include "mruby/variable.h"
|
---|
5 | #include "mruby/proc.h"
|
---|
6 | #include "mruby/string.h"
|
---|
7 |
|
---|
8 | static struct RObject *
|
---|
9 | method_object_alloc(mrb_state *mrb, struct RClass *mclass)
|
---|
10 | {
|
---|
11 | return (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mclass);
|
---|
12 | }
|
---|
13 |
|
---|
14 | static void
|
---|
15 | bind_check(mrb_state *mrb, mrb_value recv, mrb_value owner)
|
---|
16 | {
|
---|
17 | if (!mrb_module_p(owner) &&
|
---|
18 | mrb_class_ptr(owner) != mrb_obj_class(mrb, recv) &&
|
---|
19 | !mrb_obj_is_kind_of(mrb, recv, mrb_class_ptr(owner))) {
|
---|
20 | if (mrb_sclass_p(owner)) {
|
---|
21 | mrb_raise(mrb, E_TYPE_ERROR, "singleton method called for a different object");
|
---|
22 | } else {
|
---|
23 | mrb_raisef(mrb, E_TYPE_ERROR, "bind argument must be an instance of %v", owner);
|
---|
24 | }
|
---|
25 | }
|
---|
26 | }
|
---|
27 |
|
---|
28 | static mrb_value
|
---|
29 | unbound_method_bind(mrb_state *mrb, mrb_value self)
|
---|
30 | {
|
---|
31 | struct RObject *me;
|
---|
32 | mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
---|
33 | mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
---|
34 | mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
---|
35 | mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
---|
36 | mrb_value recv;
|
---|
37 |
|
---|
38 | mrb_get_args(mrb, "o", &recv);
|
---|
39 | bind_check(mrb, recv, owner);
|
---|
40 | me = method_object_alloc(mrb, mrb_class_get(mrb, "Method"));
|
---|
41 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), owner);
|
---|
42 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), recv);
|
---|
43 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), name);
|
---|
44 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), proc);
|
---|
45 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), klass);
|
---|
46 |
|
---|
47 | return mrb_obj_value(me);
|
---|
48 | }
|
---|
49 |
|
---|
50 | #define IV_GET(value, name) mrb_iv_get(mrb, value, mrb_intern_lit(mrb, name))
|
---|
51 | static mrb_value
|
---|
52 | method_eql(mrb_state *mrb, mrb_value self)
|
---|
53 | {
|
---|
54 | mrb_value other, receiver, orig_proc, other_proc;
|
---|
55 | struct RClass *owner, *klass;
|
---|
56 | struct RProc *orig_rproc, *other_rproc;
|
---|
57 |
|
---|
58 | mrb_get_args(mrb, "o", &other);
|
---|
59 | if (!mrb_obj_is_instance_of(mrb, other, mrb_class(mrb, self)))
|
---|
60 | return mrb_false_value();
|
---|
61 |
|
---|
62 | if (mrb_class(mrb, self) != mrb_class(mrb, other))
|
---|
63 | return mrb_false_value();
|
---|
64 |
|
---|
65 | klass = mrb_class_ptr(IV_GET(self, "_klass"));
|
---|
66 | if (klass != mrb_class_ptr(IV_GET(other, "_klass")))
|
---|
67 | return mrb_false_value();
|
---|
68 |
|
---|
69 | owner = mrb_class_ptr(IV_GET(self, "_owner"));
|
---|
70 | if (owner != mrb_class_ptr(IV_GET(other, "_owner")))
|
---|
71 | return mrb_false_value();
|
---|
72 |
|
---|
73 | receiver = IV_GET(self, "_recv");
|
---|
74 | if (!mrb_obj_equal(mrb, receiver, IV_GET(other, "_recv")))
|
---|
75 | return mrb_false_value();
|
---|
76 |
|
---|
77 | orig_proc = IV_GET(self, "_proc");
|
---|
78 | other_proc = IV_GET(other, "_proc");
|
---|
79 | if (mrb_nil_p(orig_proc) && mrb_nil_p(other_proc)) {
|
---|
80 | if (mrb_symbol(IV_GET(self, "_name")) == mrb_symbol(IV_GET(other, "_name")))
|
---|
81 | return mrb_true_value();
|
---|
82 | else
|
---|
83 | return mrb_false_value();
|
---|
84 | }
|
---|
85 |
|
---|
86 | if (mrb_nil_p(orig_proc))
|
---|
87 | return mrb_false_value();
|
---|
88 | if (mrb_nil_p(other_proc))
|
---|
89 | return mrb_false_value();
|
---|
90 |
|
---|
91 | orig_rproc = mrb_proc_ptr(orig_proc);
|
---|
92 | other_rproc = mrb_proc_ptr(other_proc);
|
---|
93 | if (MRB_PROC_CFUNC_P(orig_rproc)) {
|
---|
94 | if (!MRB_PROC_CFUNC_P(other_rproc))
|
---|
95 | return mrb_false_value();
|
---|
96 | if (orig_rproc->body.func != other_rproc->body.func)
|
---|
97 | return mrb_false_value();
|
---|
98 | }
|
---|
99 | else {
|
---|
100 | if (MRB_PROC_CFUNC_P(other_rproc))
|
---|
101 | return mrb_false_value();
|
---|
102 | if (orig_rproc->body.irep != other_rproc->body.irep)
|
---|
103 | return mrb_false_value();
|
---|
104 | }
|
---|
105 |
|
---|
106 | return mrb_true_value();
|
---|
107 | }
|
---|
108 |
|
---|
109 | #undef IV_GET
|
---|
110 |
|
---|
111 | static mrb_value
|
---|
112 | mcall(mrb_state *mrb, mrb_value recv, mrb_value proc, mrb_value name, struct RClass *owner,
|
---|
113 | int argc, mrb_value *argv, mrb_value block)
|
---|
114 | {
|
---|
115 | mrb_value ret;
|
---|
116 | mrb_sym orig_mid = mrb->c->ci->mid;
|
---|
117 |
|
---|
118 | mrb->c->ci->mid = mrb_symbol(name);
|
---|
119 | if (mrb_nil_p(proc)) {
|
---|
120 | mrb_value missing_argv = mrb_ary_new_from_values(mrb, argc, argv);
|
---|
121 | mrb_ary_unshift(mrb, missing_argv, name);
|
---|
122 | ret = mrb_funcall_argv(mrb, recv, mrb_intern_lit(mrb, "method_missing"), argc + 1, RARRAY_PTR(missing_argv));
|
---|
123 | }
|
---|
124 | else if (!mrb_nil_p(block)) {
|
---|
125 | /*
|
---|
126 | workaround since `mrb_yield_with_class` does not support passing block as parameter
|
---|
127 | need new API that initializes `mrb->c->stack[argc+1]` with block passed by argument
|
---|
128 | */
|
---|
129 | ret = mrb_funcall_with_block(mrb, recv, mrb_symbol(name), argc, argv, block);
|
---|
130 | }
|
---|
131 | else {
|
---|
132 | ret = mrb_yield_with_class(mrb, proc, argc, argv, recv, owner);
|
---|
133 | }
|
---|
134 | mrb->c->ci->mid = orig_mid;
|
---|
135 | return ret;
|
---|
136 | }
|
---|
137 |
|
---|
138 | static mrb_value
|
---|
139 | method_call(mrb_state *mrb, mrb_value self)
|
---|
140 | {
|
---|
141 | mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
---|
142 | mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
---|
143 | mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
---|
144 | struct RClass *owner = mrb_class_ptr(mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner")));
|
---|
145 | mrb_int argc;
|
---|
146 | mrb_value *argv, block;
|
---|
147 |
|
---|
148 | mrb_get_args(mrb, "*&", &argv, &argc, &block);
|
---|
149 | return mcall(mrb, recv, proc, name, owner, argc, argv, block);
|
---|
150 | }
|
---|
151 |
|
---|
152 | static mrb_value
|
---|
153 | method_bcall(mrb_state *mrb, mrb_value self)
|
---|
154 | {
|
---|
155 | mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
---|
156 | mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
---|
157 | mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
---|
158 | mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
---|
159 | mrb_int argc;
|
---|
160 | mrb_value *argv, block;
|
---|
161 |
|
---|
162 | mrb_get_args(mrb, "o*&", &recv, &argv, &argc, &block);
|
---|
163 | bind_check(mrb, recv, owner);
|
---|
164 | return mcall(mrb, recv, proc, name, mrb_class_ptr(owner), argc, argv, block);
|
---|
165 | }
|
---|
166 |
|
---|
167 | static mrb_value
|
---|
168 | method_unbind(mrb_state *mrb, mrb_value self)
|
---|
169 | {
|
---|
170 | struct RObject *ume;
|
---|
171 | mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
---|
172 | mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
---|
173 | mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
---|
174 | mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
---|
175 |
|
---|
176 | ume = method_object_alloc(mrb, mrb_class_get(mrb, "UnboundMethod"));
|
---|
177 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_owner"), owner);
|
---|
178 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_recv"), mrb_nil_value());
|
---|
179 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_name"), name);
|
---|
180 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_proc"), proc);
|
---|
181 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_klass"), klass);
|
---|
182 |
|
---|
183 | return mrb_obj_value(ume);
|
---|
184 | }
|
---|
185 |
|
---|
186 | static struct RProc *
|
---|
187 | method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
|
---|
188 | {
|
---|
189 | mrb_method_t m = mrb_method_search_vm(mrb, cp, mid);
|
---|
190 | if (MRB_METHOD_UNDEF_P(m))
|
---|
191 | return NULL;
|
---|
192 | if (MRB_METHOD_PROC_P(m))
|
---|
193 | return MRB_METHOD_PROC(m);
|
---|
194 | return mrb_proc_new_cfunc(mrb, MRB_METHOD_FUNC(m));
|
---|
195 | }
|
---|
196 |
|
---|
197 | static mrb_value
|
---|
198 | method_super_method(mrb_state *mrb, mrb_value self)
|
---|
199 | {
|
---|
200 | mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
---|
201 | mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
---|
202 | mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
---|
203 | mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
---|
204 | struct RClass *super, *rklass;
|
---|
205 | struct RProc *proc;
|
---|
206 | struct RObject *me;
|
---|
207 |
|
---|
208 | switch (mrb_type(klass)) {
|
---|
209 | case MRB_TT_SCLASS:
|
---|
210 | super = mrb_class_ptr(klass)->super->super;
|
---|
211 | break;
|
---|
212 | case MRB_TT_ICLASS:
|
---|
213 | super = mrb_class_ptr(klass)->super;
|
---|
214 | break;
|
---|
215 | default:
|
---|
216 | super = mrb_class_ptr(owner)->super;
|
---|
217 | break;
|
---|
218 | }
|
---|
219 |
|
---|
220 | proc = method_search_vm(mrb, &super, mrb_symbol(name));
|
---|
221 | if (!proc)
|
---|
222 | return mrb_nil_value();
|
---|
223 |
|
---|
224 | rklass = super;
|
---|
225 | while (super->tt == MRB_TT_ICLASS)
|
---|
226 | super = super->c;
|
---|
227 |
|
---|
228 | me = method_object_alloc(mrb, mrb_obj_class(mrb, self));
|
---|
229 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(super));
|
---|
230 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), recv);
|
---|
231 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), name);
|
---|
232 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), mrb_obj_value(proc));
|
---|
233 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), mrb_obj_value(rklass));
|
---|
234 |
|
---|
235 | return mrb_obj_value(me);
|
---|
236 | }
|
---|
237 |
|
---|
238 | static mrb_value
|
---|
239 | method_arity(mrb_state *mrb, mrb_value self)
|
---|
240 | {
|
---|
241 | mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
---|
242 | mrb_int arity = mrb_nil_p(proc) ? -1 : mrb_proc_arity(mrb_proc_ptr(proc));
|
---|
243 | return mrb_fixnum_value(arity);
|
---|
244 | }
|
---|
245 |
|
---|
246 | static mrb_value
|
---|
247 | method_source_location(mrb_state *mrb, mrb_value self)
|
---|
248 | {
|
---|
249 | mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
---|
250 | struct RProc *rproc;
|
---|
251 | struct RClass *orig;
|
---|
252 | mrb_value ret;
|
---|
253 |
|
---|
254 | if (mrb_nil_p(proc))
|
---|
255 | return mrb_nil_value();
|
---|
256 |
|
---|
257 | rproc = mrb_proc_ptr(proc);
|
---|
258 | orig = rproc->c;
|
---|
259 | rproc->c = mrb->proc_class;
|
---|
260 | ret = mrb_funcall(mrb, proc, "source_location", 0);
|
---|
261 | rproc->c = orig;
|
---|
262 | return ret;
|
---|
263 | }
|
---|
264 |
|
---|
265 | static mrb_value
|
---|
266 | method_parameters(mrb_state *mrb, mrb_value self)
|
---|
267 | {
|
---|
268 | mrb_value proc = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_proc"));
|
---|
269 | struct RProc *rproc;
|
---|
270 | struct RClass *orig;
|
---|
271 | mrb_value ret;
|
---|
272 |
|
---|
273 | if (mrb_nil_p(proc)) {
|
---|
274 | mrb_value rest = mrb_symbol_value(mrb_intern_lit(mrb, "rest"));
|
---|
275 | mrb_value arest = mrb_ary_new_from_values(mrb, 1, &rest);
|
---|
276 | return mrb_ary_new_from_values(mrb, 1, &arest);
|
---|
277 | }
|
---|
278 |
|
---|
279 | rproc = mrb_proc_ptr(proc);
|
---|
280 | orig = rproc->c;
|
---|
281 | rproc->c = mrb->proc_class;
|
---|
282 | ret = mrb_funcall(mrb, proc, "parameters", 0);
|
---|
283 | rproc->c = orig;
|
---|
284 | return ret;
|
---|
285 | }
|
---|
286 |
|
---|
287 | static mrb_value
|
---|
288 | method_to_s(mrb_state *mrb, mrb_value self)
|
---|
289 | {
|
---|
290 | mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
---|
291 | mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_klass"));
|
---|
292 | mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
---|
293 | mrb_value str = mrb_str_new_lit(mrb, "#<");
|
---|
294 | struct RClass *rklass;
|
---|
295 |
|
---|
296 | mrb_str_cat_cstr(mrb, str, mrb_obj_classname(mrb, self));
|
---|
297 | mrb_str_cat_lit(mrb, str, ": ");
|
---|
298 | rklass = mrb_class_ptr(klass);
|
---|
299 | if (mrb_class_ptr(owner) == rklass) {
|
---|
300 | mrb_str_concat(mrb, str, owner);
|
---|
301 | mrb_str_cat_lit(mrb, str, "#");
|
---|
302 | mrb_str_concat(mrb, str, name);
|
---|
303 | }
|
---|
304 | else {
|
---|
305 | mrb_str_cat_cstr(mrb, str, mrb_class_name(mrb, rklass));
|
---|
306 | mrb_str_cat_lit(mrb, str, "(");
|
---|
307 | mrb_str_concat(mrb, str, owner);
|
---|
308 | mrb_str_cat_lit(mrb, str, ")#");
|
---|
309 | mrb_str_concat(mrb, str, name);
|
---|
310 | }
|
---|
311 | mrb_str_cat_lit(mrb, str, ">");
|
---|
312 | return str;
|
---|
313 | }
|
---|
314 |
|
---|
315 | static void
|
---|
316 | mrb_search_method_owner(mrb_state *mrb, struct RClass *c, mrb_value obj, mrb_sym name, struct RClass **owner, struct RProc **proc, mrb_bool unbound)
|
---|
317 | {
|
---|
318 | mrb_value ret;
|
---|
319 |
|
---|
320 | *owner = c;
|
---|
321 | *proc = method_search_vm(mrb, owner, name);
|
---|
322 | if (!*proc) {
|
---|
323 | if (unbound) {
|
---|
324 | goto name_error;
|
---|
325 | }
|
---|
326 | if (!mrb_respond_to(mrb, obj, mrb_intern_lit(mrb, "respond_to_missing?"))) {
|
---|
327 | goto name_error;
|
---|
328 | }
|
---|
329 | ret = mrb_funcall(mrb, obj, "respond_to_missing?", 2, mrb_symbol_value(name), mrb_true_value());
|
---|
330 | if (!mrb_test(ret)) {
|
---|
331 | goto name_error;
|
---|
332 | }
|
---|
333 | *owner = c;
|
---|
334 | }
|
---|
335 |
|
---|
336 | while ((*owner)->tt == MRB_TT_ICLASS)
|
---|
337 | *owner = (*owner)->c;
|
---|
338 |
|
---|
339 | return;
|
---|
340 |
|
---|
341 | name_error:
|
---|
342 | mrb_raisef(mrb, E_NAME_ERROR, "undefined method '%n' for class '%C'", name, c);
|
---|
343 | }
|
---|
344 |
|
---|
345 | static mrb_value
|
---|
346 | mrb_kernel_method(mrb_state *mrb, mrb_value self)
|
---|
347 | {
|
---|
348 | struct RClass *owner;
|
---|
349 | struct RProc *proc;
|
---|
350 | struct RObject *me;
|
---|
351 | mrb_sym name;
|
---|
352 |
|
---|
353 | mrb_get_args(mrb, "n", &name);
|
---|
354 |
|
---|
355 | mrb_search_method_owner(mrb, mrb_class(mrb, self), self, name, &owner, &proc, FALSE);
|
---|
356 |
|
---|
357 | me = method_object_alloc(mrb, mrb_class_get(mrb, "Method"));
|
---|
358 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(owner));
|
---|
359 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_recv"), self);
|
---|
360 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_name"), mrb_symbol_value(name));
|
---|
361 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
|
---|
362 | mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "_klass"), mrb_obj_value(mrb_class(mrb, self)));
|
---|
363 |
|
---|
364 | return mrb_obj_value(me);
|
---|
365 | }
|
---|
366 |
|
---|
367 | static mrb_value
|
---|
368 | mrb_module_instance_method(mrb_state *mrb, mrb_value self)
|
---|
369 | {
|
---|
370 | struct RClass *owner;
|
---|
371 | struct RProc *proc;
|
---|
372 | struct RObject *ume;
|
---|
373 | mrb_sym name;
|
---|
374 |
|
---|
375 | mrb_get_args(mrb, "n", &name);
|
---|
376 |
|
---|
377 | mrb_search_method_owner(mrb, mrb_class_ptr(self), self, name, &owner, &proc, TRUE);
|
---|
378 |
|
---|
379 | ume = method_object_alloc(mrb, mrb_class_get(mrb, "UnboundMethod"));
|
---|
380 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_owner"), mrb_obj_value(owner));
|
---|
381 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_recv"), mrb_nil_value());
|
---|
382 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_name"), mrb_symbol_value(name));
|
---|
383 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_proc"), proc ? mrb_obj_value(proc) : mrb_nil_value());
|
---|
384 | mrb_obj_iv_set(mrb, ume, mrb_intern_lit(mrb, "_klass"), self);
|
---|
385 |
|
---|
386 | return mrb_obj_value(ume);
|
---|
387 | }
|
---|
388 |
|
---|
389 | static mrb_value
|
---|
390 | method_owner(mrb_state *mrb, mrb_value self)
|
---|
391 | {
|
---|
392 | return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_owner"));
|
---|
393 | }
|
---|
394 |
|
---|
395 | static mrb_value
|
---|
396 | method_receiver(mrb_state *mrb, mrb_value self)
|
---|
397 | {
|
---|
398 | return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_recv"));
|
---|
399 | }
|
---|
400 |
|
---|
401 | static mrb_value
|
---|
402 | method_name(mrb_state *mrb, mrb_value self)
|
---|
403 | {
|
---|
404 | return mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "_name"));
|
---|
405 | }
|
---|
406 |
|
---|
407 | void
|
---|
408 | mrb_mruby_method_gem_init(mrb_state* mrb)
|
---|
409 | {
|
---|
410 | struct RClass *unbound_method = mrb_define_class(mrb, "UnboundMethod", mrb->object_class);
|
---|
411 | struct RClass *method = mrb_define_class(mrb, "Method", mrb->object_class);
|
---|
412 |
|
---|
413 | mrb_undef_class_method(mrb, unbound_method, "new");
|
---|
414 | mrb_define_method(mrb, unbound_method, "bind", unbound_method_bind, MRB_ARGS_REQ(1));
|
---|
415 | mrb_define_method(mrb, unbound_method, "super_method", method_super_method, MRB_ARGS_NONE());
|
---|
416 | mrb_define_method(mrb, unbound_method, "==", method_eql, MRB_ARGS_REQ(1));
|
---|
417 | mrb_define_method(mrb, unbound_method, "eql?", method_eql, MRB_ARGS_REQ(1));
|
---|
418 | mrb_define_method(mrb, unbound_method, "to_s", method_to_s, MRB_ARGS_NONE());
|
---|
419 | mrb_define_method(mrb, unbound_method, "inspect", method_to_s, MRB_ARGS_NONE());
|
---|
420 | mrb_define_method(mrb, unbound_method, "arity", method_arity, MRB_ARGS_NONE());
|
---|
421 | mrb_define_method(mrb, unbound_method, "source_location", method_source_location, MRB_ARGS_NONE());
|
---|
422 | mrb_define_method(mrb, unbound_method, "parameters", method_parameters, MRB_ARGS_NONE());
|
---|
423 | mrb_define_method(mrb, unbound_method, "bind_call", method_bcall, MRB_ARGS_REQ(1)|MRB_ARGS_ANY());
|
---|
424 | mrb_define_method(mrb, unbound_method, "owner", method_owner, MRB_ARGS_NONE());
|
---|
425 | mrb_define_method(mrb, unbound_method, "name", method_name, MRB_ARGS_NONE());
|
---|
426 |
|
---|
427 | mrb_undef_class_method(mrb, method, "new");
|
---|
428 | mrb_define_method(mrb, method, "==", method_eql, MRB_ARGS_REQ(1));
|
---|
429 | mrb_define_method(mrb, method, "eql?", method_eql, MRB_ARGS_REQ(1));
|
---|
430 | mrb_define_method(mrb, method, "to_s", method_to_s, MRB_ARGS_NONE());
|
---|
431 | mrb_define_method(mrb, method, "inspect", method_to_s, MRB_ARGS_NONE());
|
---|
432 | mrb_define_method(mrb, method, "call", method_call, MRB_ARGS_ANY());
|
---|
433 | mrb_define_method(mrb, method, "[]", method_call, MRB_ARGS_ANY());
|
---|
434 | mrb_define_method(mrb, method, "unbind", method_unbind, MRB_ARGS_NONE());
|
---|
435 | mrb_define_method(mrb, method, "super_method", method_super_method, MRB_ARGS_NONE());
|
---|
436 | mrb_define_method(mrb, method, "arity", method_arity, MRB_ARGS_NONE());
|
---|
437 | mrb_define_method(mrb, method, "source_location", method_source_location, MRB_ARGS_NONE());
|
---|
438 | mrb_define_method(mrb, method, "parameters", method_parameters, MRB_ARGS_NONE());
|
---|
439 | mrb_define_method(mrb, method, "owner", method_owner, MRB_ARGS_NONE());
|
---|
440 | mrb_define_method(mrb, method, "receiver", method_receiver, MRB_ARGS_NONE());
|
---|
441 | mrb_define_method(mrb, method, "name", method_name, MRB_ARGS_NONE());
|
---|
442 |
|
---|
443 | mrb_define_method(mrb, mrb->kernel_module, "method", mrb_kernel_method, MRB_ARGS_REQ(1));
|
---|
444 |
|
---|
445 | mrb_define_method(mrb, mrb->module_class, "instance_method", mrb_module_instance_method, MRB_ARGS_REQ(1));
|
---|
446 | }
|
---|
447 |
|
---|
448 | void
|
---|
449 | mrb_mruby_method_gem_final(mrb_state* mrb)
|
---|
450 | {
|
---|
451 | }
|
---|