1 /*
2 ** class.c - Class class
3 **
4 ** See Copyright Notice in mruby.h
5 */
6
7 #include <stdarg.h>
8 #include <mruby.h>
9 #include <mruby/array.h>
10 #include <mruby/class.h>
11 #include <mruby/numeric.h>
12 #include <mruby/proc.h>
13 #include <mruby/string.h>
14 #include <mruby/variable.h>
15 #include <mruby/error.h>
16 #include <mruby/data.h>
17 #include <mruby/istruct.h>
18
KHASH_DEFINE(mt,mrb_sym,mrb_method_t,TRUE,kh_int_hash_func,kh_int_hash_equal)19 KHASH_DEFINE(mt, mrb_sym, mrb_method_t, TRUE, kh_int_hash_func, kh_int_hash_equal)
20
21 void
22 mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
23 {
24 khiter_t k;
25 khash_t(mt) *h = c->mt;
26
27 if (!h) return;
28 for (k = kh_begin(h); k != kh_end(h); k++) {
29 if (kh_exist(h, k)) {
30 mrb_method_t m = kh_value(h, k);
31
32 if (MRB_METHOD_PROC_P(m)) {
33 struct RProc *p = MRB_METHOD_PROC(m);
34 mrb_gc_mark(mrb, (struct RBasic*)p);
35 }
36 }
37 }
38 }
39
40 size_t
mrb_gc_mark_mt_size(mrb_state * mrb,struct RClass * c)41 mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c)
42 {
43 khash_t(mt) *h = c->mt;
44
45 if (!h) return 0;
46 return kh_size(h);
47 }
48
49 void
mrb_gc_free_mt(mrb_state * mrb,struct RClass * c)50 mrb_gc_free_mt(mrb_state *mrb, struct RClass *c)
51 {
52 kh_destroy(mt, mrb, c->mt);
53 }
54
55 void
mrb_class_name_class(mrb_state * mrb,struct RClass * outer,struct RClass * c,mrb_sym id)56 mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
57 {
58 mrb_value name;
59 mrb_sym nsym = mrb_intern_lit(mrb, "__classname__");
60
61 if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return;
62 if (outer == NULL || outer == mrb->object_class) {
63 name = mrb_symbol_value(id);
64 }
65 else {
66 name = mrb_class_path(mrb, outer);
67 if (mrb_nil_p(name)) { /* unnamed outer class */
68 if (outer != mrb->object_class && outer != c) {
69 mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"),
70 mrb_obj_value(outer));
71 }
72 return;
73 }
74 mrb_str_cat_cstr(mrb, name, "::");
75 mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id));
76 }
77 mrb_obj_iv_set(mrb, (struct RObject*)c, nsym, name);
78 }
79
80 static void
setup_class(mrb_state * mrb,struct RClass * outer,struct RClass * c,mrb_sym id)81 setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
82 {
83 mrb_class_name_class(mrb, outer, c, id);
84 mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c));
85 }
86
87 #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
88
89 static void
prepare_singleton_class(mrb_state * mrb,struct RBasic * o)90 prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
91 {
92 struct RClass *sc, *c;
93
94 if (o->c->tt == MRB_TT_SCLASS) return;
95 sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class);
96 sc->flags |= MRB_FL_CLASS_IS_INHERITED;
97 sc->mt = kh_init(mt, mrb);
98 sc->iv = 0;
99 if (o->tt == MRB_TT_CLASS) {
100 c = (struct RClass*)o;
101 if (!c->super) {
102 sc->super = mrb->class_class;
103 }
104 else {
105 sc->super = c->super->c;
106 }
107 }
108 else if (o->tt == MRB_TT_SCLASS) {
109 c = (struct RClass*)o;
110 while (c->super->tt == MRB_TT_ICLASS)
111 c = c->super;
112 make_metaclass(mrb, c->super);
113 sc->super = c->super->c;
114 }
115 else {
116 sc->super = o->c;
117 prepare_singleton_class(mrb, (struct RBasic*)sc);
118 }
119 o->c = sc;
120 mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc);
121 mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o);
122 mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o));
123 }
124
125 static mrb_value
class_name_str(mrb_state * mrb,struct RClass * c)126 class_name_str(mrb_state *mrb, struct RClass* c)
127 {
128 mrb_value path = mrb_class_path(mrb, c);
129 if (mrb_nil_p(path)) {
130 path = c->tt == MRB_TT_MODULE ? mrb_str_new_lit(mrb, "#<Module:") :
131 mrb_str_new_lit(mrb, "#<Class:");
132 mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c));
133 mrb_str_cat_lit(mrb, path, ">");
134 }
135 return path;
136 }
137
138 static struct RClass*
class_from_sym(mrb_state * mrb,struct RClass * klass,mrb_sym id)139 class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
140 {
141 mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
142
143 mrb_check_type(mrb, c, MRB_TT_CLASS);
144 return mrb_class_ptr(c);
145 }
146
147 static struct RClass*
module_from_sym(mrb_state * mrb,struct RClass * klass,mrb_sym id)148 module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
149 {
150 mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
151
152 mrb_check_type(mrb, c, MRB_TT_MODULE);
153 return mrb_class_ptr(c);
154 }
155
156 static mrb_bool
class_ptr_p(mrb_value obj)157 class_ptr_p(mrb_value obj)
158 {
159 switch (mrb_type(obj)) {
160 case MRB_TT_CLASS:
161 case MRB_TT_SCLASS:
162 case MRB_TT_MODULE:
163 return TRUE;
164 default:
165 return FALSE;
166 }
167 }
168
169 static void
check_if_class_or_module(mrb_state * mrb,mrb_value obj)170 check_if_class_or_module(mrb_state *mrb, mrb_value obj)
171 {
172 if (!class_ptr_p(obj)) {
173 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj));
174 }
175 }
176
177 static struct RClass*
define_module(mrb_state * mrb,mrb_sym name,struct RClass * outer)178 define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer)
179 {
180 struct RClass *m;
181
182 if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
183 return module_from_sym(mrb, outer, name);
184 }
185 m = mrb_module_new(mrb);
186 setup_class(mrb, outer, m, name);
187
188 return m;
189 }
190
191 MRB_API struct RClass*
mrb_define_module_id(mrb_state * mrb,mrb_sym name)192 mrb_define_module_id(mrb_state *mrb, mrb_sym name)
193 {
194 return define_module(mrb, name, mrb->object_class);
195 }
196
197 MRB_API struct RClass*
mrb_define_module(mrb_state * mrb,const char * name)198 mrb_define_module(mrb_state *mrb, const char *name)
199 {
200 return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class);
201 }
202
203 MRB_API struct RClass*
mrb_vm_define_module(mrb_state * mrb,mrb_value outer,mrb_sym id)204 mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id)
205 {
206 check_if_class_or_module(mrb, outer);
207 if (mrb_const_defined_at(mrb, outer, id)) {
208 mrb_value old = mrb_const_get(mrb, outer, id);
209
210 if (mrb_type(old) != MRB_TT_MODULE) {
211 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old));
212 }
213 return mrb_class_ptr(old);
214 }
215 return define_module(mrb, id, mrb_class_ptr(outer));
216 }
217
218 MRB_API struct RClass*
mrb_define_module_under(mrb_state * mrb,struct RClass * outer,const char * name)219 mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
220 {
221 mrb_sym id = mrb_intern_cstr(mrb, name);
222 struct RClass * c = define_module(mrb, id, outer);
223
224 setup_class(mrb, outer, c, id);
225 return c;
226 }
227
228 static struct RClass*
find_origin(struct RClass * c)229 find_origin(struct RClass *c)
230 {
231 MRB_CLASS_ORIGIN(c);
232 return c;
233 }
234
235 static struct RClass*
define_class(mrb_state * mrb,mrb_sym name,struct RClass * super,struct RClass * outer)236 define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer)
237 {
238 struct RClass * c;
239
240 if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
241 c = class_from_sym(mrb, outer, name);
242 MRB_CLASS_ORIGIN(c);
243 if (super && mrb_class_real(c->super) != super) {
244 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)",
245 mrb_sym2str(mrb, name),
246 mrb_obj_value(c->super), mrb_obj_value(super));
247 }
248 return c;
249 }
250
251 c = mrb_class_new(mrb, super);
252 setup_class(mrb, outer, c, name);
253
254 return c;
255 }
256
257 MRB_API struct RClass*
mrb_define_class_id(mrb_state * mrb,mrb_sym name,struct RClass * super)258 mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
259 {
260 if (!super) {
261 mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name));
262 }
263 return define_class(mrb, name, super, mrb->object_class);
264 }
265
266 MRB_API struct RClass*
mrb_define_class(mrb_state * mrb,const char * name,struct RClass * super)267 mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
268 {
269 return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
270 }
271
272 static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value);
273 #ifdef MRB_METHOD_CACHE
274 static void mc_clear_all(mrb_state *mrb);
275 static void mc_clear_by_class(mrb_state *mrb, struct RClass*);
276 static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym);
277 #else
278 #define mc_clear_all(mrb)
279 #define mc_clear_by_class(mrb,c)
280 #define mc_clear_by_id(mrb,c,s)
281 #endif
282
283 static void
mrb_class_inherited(mrb_state * mrb,struct RClass * super,struct RClass * klass)284 mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
285 {
286 mrb_value s;
287 mrb_sym mid;
288
289 if (!super)
290 super = mrb->object_class;
291 super->flags |= MRB_FL_CLASS_IS_INHERITED;
292 s = mrb_obj_value(super);
293 mc_clear_by_class(mrb, klass);
294 mid = mrb_intern_lit(mrb, "inherited");
295 if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) {
296 mrb_value c = mrb_obj_value(klass);
297 mrb_funcall_argv(mrb, s, mid, 1, &c);
298 }
299 }
300
301 MRB_API struct RClass*
mrb_vm_define_class(mrb_state * mrb,mrb_value outer,mrb_value super,mrb_sym id)302 mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
303 {
304 struct RClass *s;
305 struct RClass *c;
306
307 if (!mrb_nil_p(super)) {
308 if (mrb_type(super) != MRB_TT_CLASS) {
309 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)",
310 mrb_inspect(mrb, super));
311 }
312 s = mrb_class_ptr(super);
313 }
314 else {
315 s = 0;
316 }
317 check_if_class_or_module(mrb, outer);
318 if (mrb_const_defined_at(mrb, outer, id)) {
319 mrb_value old = mrb_const_get(mrb, outer, id);
320
321 if (mrb_type(old) != MRB_TT_CLASS) {
322 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old));
323 }
324 c = mrb_class_ptr(old);
325 if (s) {
326 /* check super class */
327 if (mrb_class_real(c->super) != s) {
328 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old);
329 }
330 }
331 return c;
332 }
333 c = define_class(mrb, id, s, mrb_class_ptr(outer));
334 mrb_class_inherited(mrb, mrb_class_real(c->super), c);
335
336 return c;
337 }
338
339 MRB_API mrb_bool
mrb_class_defined(mrb_state * mrb,const char * name)340 mrb_class_defined(mrb_state *mrb, const char *name)
341 {
342 mrb_value sym = mrb_check_intern_cstr(mrb, name);
343 if (mrb_nil_p(sym)) {
344 return FALSE;
345 }
346 return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_symbol(sym));
347 }
348
349 MRB_API mrb_bool
mrb_class_defined_under(mrb_state * mrb,struct RClass * outer,const char * name)350 mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name)
351 {
352 mrb_value sym = mrb_check_intern_cstr(mrb, name);
353 if (mrb_nil_p(sym)) {
354 return FALSE;
355 }
356 return mrb_const_defined_at(mrb, mrb_obj_value(outer), mrb_symbol(sym));
357 }
358
359 MRB_API struct RClass*
mrb_class_get_under(mrb_state * mrb,struct RClass * outer,const char * name)360 mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
361 {
362 return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
363 }
364
365 MRB_API struct RClass*
mrb_class_get(mrb_state * mrb,const char * name)366 mrb_class_get(mrb_state *mrb, const char *name)
367 {
368 return mrb_class_get_under(mrb, mrb->object_class, name);
369 }
370
371 MRB_API struct RClass*
mrb_exc_get(mrb_state * mrb,const char * name)372 mrb_exc_get(mrb_state *mrb, const char *name)
373 {
374 struct RClass *exc, *e;
375 mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class),
376 mrb_intern_cstr(mrb, name));
377
378 if (mrb_type(c) != MRB_TT_CLASS) {
379 mrb_raise(mrb, mrb->eException_class, "exception corrupted");
380 }
381 exc = e = mrb_class_ptr(c);
382
383 while (e) {
384 if (e == mrb->eException_class)
385 return exc;
386 e = e->super;
387 }
388 return mrb->eException_class;
389 }
390
391 MRB_API struct RClass*
mrb_module_get_under(mrb_state * mrb,struct RClass * outer,const char * name)392 mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
393 {
394 return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
395 }
396
397 MRB_API struct RClass*
mrb_module_get(mrb_state * mrb,const char * name)398 mrb_module_get(mrb_state *mrb, const char *name)
399 {
400 return mrb_module_get_under(mrb, mrb->object_class, name);
401 }
402
403 /*!
404 * Defines a class under the namespace of \a outer.
405 * \param outer a class which contains the new class.
406 * \param id name of the new class
407 * \param super a class from which the new class will derive.
408 * NULL means \c Object class.
409 * \return the created class
410 * \throw TypeError if the constant name \a name is already taken but
411 * the constant is not a \c Class.
412 * \throw NameError if the class is already defined but the class can not
413 * be reopened because its superclass is not \a super.
414 * \post top-level constant named \a name refers the returned class.
415 *
416 * \note if a class named \a name is already defined and its superclass is
417 * \a super, the function just returns the defined class.
418 */
419 MRB_API struct RClass*
mrb_define_class_under(mrb_state * mrb,struct RClass * outer,const char * name,struct RClass * super)420 mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
421 {
422 mrb_sym id = mrb_intern_cstr(mrb, name);
423 struct RClass * c;
424
425 #if 0
426 if (!super) {
427 mrb_warn(mrb, "no super class for '%S::%S', Object assumed",
428 mrb_obj_value(outer), mrb_sym2str(mrb, id));
429 }
430 #endif
431 c = define_class(mrb, id, super, outer);
432 setup_class(mrb, outer, c, id);
433 return c;
434 }
435
436 MRB_API void
mrb_define_method_raw(mrb_state * mrb,struct RClass * c,mrb_sym mid,mrb_method_t m)437 mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_t m)
438 {
439 khash_t(mt) *h;
440 khiter_t k;
441 MRB_CLASS_ORIGIN(c);
442 h = c->mt;
443
444 if (MRB_FROZEN_P(c)) {
445 if (c->tt == MRB_TT_MODULE)
446 mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen module");
447 else
448 mrb_raise(mrb, E_FROZEN_ERROR, "can't modify frozen class");
449 }
450 if (!h) h = c->mt = kh_init(mt, mrb);
451 k = kh_put(mt, mrb, h, mid);
452 kh_value(h, k) = m;
453 if (MRB_METHOD_PROC_P(m) && !MRB_METHOD_UNDEF_P(m)) {
454 struct RProc *p = MRB_METHOD_PROC(m);
455
456 p->flags |= MRB_PROC_SCOPE;
457 p->c = NULL;
458 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p);
459 if (!MRB_PROC_ENV_P(p)) {
460 MRB_PROC_SET_TARGET_CLASS(p, c);
461 }
462 }
463 mc_clear_by_id(mrb, c, mid);
464 }
465
466 MRB_API void
mrb_define_method_id(mrb_state * mrb,struct RClass * c,mrb_sym mid,mrb_func_t func,mrb_aspec aspec)467 mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
468 {
469 mrb_method_t m;
470 int ai = mrb_gc_arena_save(mrb);
471
472 MRB_METHOD_FROM_FUNC(m, func);
473 mrb_define_method_raw(mrb, c, mid, m);
474 mrb_gc_arena_restore(mrb, ai);
475 }
476
477 MRB_API void
mrb_define_method(mrb_state * mrb,struct RClass * c,const char * name,mrb_func_t func,mrb_aspec aspec)478 mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
479 {
480 mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
481 }
482
483 /* a function to raise NotImplementedError with current method name */
484 MRB_API void
mrb_notimplement(mrb_state * mrb)485 mrb_notimplement(mrb_state *mrb)
486 {
487 mrb_callinfo *ci = mrb->c->ci;
488
489 if (ci->mid) {
490 mrb_value str = mrb_sym2str(mrb, ci->mid);
491 mrb_raisef(mrb, E_NOTIMP_ERROR, "%S() function is unimplemented on this machine", str);
492 }
493 }
494
495 /* a function to be replacement of unimplemented method */
496 MRB_API mrb_value
mrb_notimplement_m(mrb_state * mrb,mrb_value self)497 mrb_notimplement_m(mrb_state *mrb, mrb_value self)
498 {
499 mrb_notimplement(mrb);
500 /* not reached */
501 return mrb_nil_value();
502 }
503
504 #define CHECK_TYPE(mrb, val, t, c) do { \
505 if (mrb_type(val) != (t)) {\
506 mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_lit(mrb, c));\
507 }\
508 } while (0)
509
510 static mrb_value
to_str(mrb_state * mrb,mrb_value val)511 to_str(mrb_state *mrb, mrb_value val)
512 {
513 CHECK_TYPE(mrb, val, MRB_TT_STRING, "String");
514 return val;
515 }
516
517 static mrb_value
to_ary(mrb_state * mrb,mrb_value val)518 to_ary(mrb_state *mrb, mrb_value val)
519 {
520 CHECK_TYPE(mrb, val, MRB_TT_ARRAY, "Array");
521 return val;
522 }
523
524 static mrb_value
to_hash(mrb_state * mrb,mrb_value val)525 to_hash(mrb_state *mrb, mrb_value val)
526 {
527 CHECK_TYPE(mrb, val, MRB_TT_HASH, "Hash");
528 return val;
529 }
530
531 #define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss)
532
533 MRB_API mrb_int
mrb_get_argc(mrb_state * mrb)534 mrb_get_argc(mrb_state *mrb)
535 {
536 mrb_int argc = mrb->c->ci->argc;
537
538 if (argc < 0) {
539 struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
540
541 argc = ARY_LEN(a);
542 }
543 return argc;
544 }
545
546 MRB_API mrb_value*
mrb_get_argv(mrb_state * mrb)547 mrb_get_argv(mrb_state *mrb)
548 {
549 mrb_int argc = mrb->c->ci->argc;
550 mrb_value *array_argv;
551 if (argc < 0) {
552 struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]);
553
554 array_argv = ARY_PTR(a);
555 }
556 else {
557 array_argv = NULL;
558 }
559 return array_argv;
560 }
561
562 /*
563 retrieve arguments from mrb_state.
564
565 mrb_get_args(mrb, format, ...)
566
567 returns number of arguments parsed.
568
569 format specifiers:
570
571 string mruby type C type note
572 ----------------------------------------------------------------------------------------------
573 o: Object [mrb_value]
574 C: class/module [mrb_value]
575 S: String [mrb_value] when ! follows, the value may be nil
576 A: Array [mrb_value] when ! follows, the value may be nil
577 H: Hash [mrb_value] when ! follows, the value may be nil
578 s: String [char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil
579 z: String [char*] NUL terminated string; z! gives NULL for nil
580 a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil
581 f: Float [mrb_float]
582 i: Integer [mrb_int]
583 b: Boolean [mrb_bool]
584 n: Symbol [mrb_sym]
585 d: Data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified
586 I: Inline struct [void*]
587 &: Block [mrb_value] &! raises exception if no block given
588 *: rest argument [mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
589 |: optional Following arguments are optional
590 ?: optional given [mrb_bool] true if preceding argument (optional) is given
591 */
592 MRB_API mrb_int
mrb_get_args(mrb_state * mrb,const char * format,...)593 mrb_get_args(mrb_state *mrb, const char *format, ...)
594 {
595 const char *fmt = format;
596 char c;
597 mrb_int i = 0;
598 va_list ap;
599 mrb_int argc = mrb_get_argc(mrb);
600 mrb_int arg_i = 0;
601 mrb_value *array_argv = mrb_get_argv(mrb);
602 mrb_bool opt = FALSE;
603 mrb_bool opt_skip = TRUE;
604 mrb_bool given = TRUE;
605
606 va_start(ap, format);
607
608 #define ARGV \
609 (array_argv ? array_argv : (mrb->c->stack + 1))
610
611 while ((c = *fmt++)) {
612 switch (c) {
613 case '|':
614 opt = TRUE;
615 break;
616 case '*':
617 opt_skip = FALSE;
618 goto check_exit;
619 case '!':
620 break;
621 case '&': case '?':
622 if (opt) opt_skip = FALSE;
623 break;
624 default:
625 break;
626 }
627 }
628
629 check_exit:
630 opt = FALSE;
631 i = 0;
632 while ((c = *format++)) {
633 switch (c) {
634 case '|': case '*': case '&': case '?':
635 break;
636 default:
637 if (argc <= i) {
638 if (opt) {
639 given = FALSE;
640 }
641 else {
642 mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
643 }
644 }
645 break;
646 }
647
648 switch (c) {
649 case 'o':
650 {
651 mrb_value *p;
652
653 p = va_arg(ap, mrb_value*);
654 if (i < argc) {
655 *p = ARGV[arg_i++];
656 i++;
657 }
658 }
659 break;
660 case 'C':
661 {
662 mrb_value *p;
663
664 p = va_arg(ap, mrb_value*);
665 if (i < argc) {
666 mrb_value ss;
667
668 ss = ARGV[arg_i++];
669 if (!class_ptr_p(ss)) {
670 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss);
671 }
672 *p = ss;
673 i++;
674 }
675 }
676 break;
677 case 'S':
678 {
679 mrb_value *p;
680
681 p = va_arg(ap, mrb_value*);
682 if (*format == '!') {
683 format++;
684 if (i < argc && mrb_nil_p(ARGV[arg_i])) {
685 *p = ARGV[arg_i++];
686 i++;
687 break;
688 }
689 }
690 if (i < argc) {
691 *p = to_str(mrb, ARGV[arg_i++]);
692 i++;
693 }
694 }
695 break;
696 case 'A':
697 {
698 mrb_value *p;
699
700 p = va_arg(ap, mrb_value*);
701 if (*format == '!') {
702 format++;
703 if (i < argc && mrb_nil_p(ARGV[arg_i])) {
704 *p = ARGV[arg_i++];
705 i++;
706 break;
707 }
708 }
709 if (i < argc) {
710 *p = to_ary(mrb, ARGV[arg_i++]);
711 i++;
712 }
713 }
714 break;
715 case 'H':
716 {
717 mrb_value *p;
718
719 p = va_arg(ap, mrb_value*);
720 if (*format == '!') {
721 format++;
722 if (i < argc && mrb_nil_p(ARGV[arg_i])) {
723 *p = ARGV[arg_i++];
724 i++;
725 break;
726 }
727 }
728 if (i < argc) {
729 *p = to_hash(mrb, ARGV[arg_i++]);
730 i++;
731 }
732 }
733 break;
734 case 's':
735 {
736 mrb_value ss;
737 char **ps = 0;
738 mrb_int *pl = 0;
739
740 ps = va_arg(ap, char**);
741 pl = va_arg(ap, mrb_int*);
742 if (*format == '!') {
743 format++;
744 if (i < argc && mrb_nil_p(ARGV[arg_i])) {
745 *ps = NULL;
746 *pl = 0;
747 i++; arg_i++;
748 break;
749 }
750 }
751 if (i < argc) {
752 ss = to_str(mrb, ARGV[arg_i++]);
753 *ps = RSTRING_PTR(ss);
754 *pl = RSTRING_LEN(ss);
755 i++;
756 }
757 }
758 break;
759 case 'z':
760 {
761 mrb_value ss;
762 const char **ps;
763
764 ps = va_arg(ap, const char**);
765 if (*format == '!') {
766 format++;
767 if (i < argc && mrb_nil_p(ARGV[arg_i])) {
768 *ps = NULL;
769 i++; arg_i++;
770 break;
771 }
772 }
773 if (i < argc) {
774 ss = to_str(mrb, ARGV[arg_i++]);
775 *ps = mrb_string_value_cstr(mrb, &ss);
776 i++;
777 }
778 }
779 break;
780 case 'a':
781 {
782 mrb_value aa;
783 struct RArray *a;
784 mrb_value **pb;
785 mrb_int *pl;
786
787 pb = va_arg(ap, mrb_value**);
788 pl = va_arg(ap, mrb_int*);
789 if (*format == '!') {
790 format++;
791 if (i < argc && mrb_nil_p(ARGV[arg_i])) {
792 *pb = 0;
793 *pl = 0;
794 i++; arg_i++;
795 break;
796 }
797 }
798 if (i < argc) {
799 aa = to_ary(mrb, ARGV[arg_i++]);
800 a = mrb_ary_ptr(aa);
801 *pb = ARY_PTR(a);
802 *pl = ARY_LEN(a);
803 i++;
804 }
805 }
806 break;
807 case 'I':
808 {
809 void* *p;
810 mrb_value ss;
811
812 p = va_arg(ap, void**);
813 if (i < argc) {
814 ss = ARGV[arg_i];
815 if (mrb_type(ss) != MRB_TT_ISTRUCT)
816 {
817 mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss);
818 }
819 *p = mrb_istruct_ptr(ss);
820 arg_i++;
821 i++;
822 }
823 }
824 break;
825 #ifndef MRB_WITHOUT_FLOAT
826 case 'f':
827 {
828 mrb_float *p;
829
830 p = va_arg(ap, mrb_float*);
831 if (i < argc) {
832 *p = mrb_to_flo(mrb, ARGV[arg_i]);
833 arg_i++;
834 i++;
835 }
836 }
837 break;
838 #endif
839 case 'i':
840 {
841 mrb_int *p;
842
843 p = va_arg(ap, mrb_int*);
844 if (i < argc) {
845 switch (mrb_type(ARGV[arg_i])) {
846 case MRB_TT_FIXNUM:
847 *p = mrb_fixnum(ARGV[arg_i]);
848 break;
849 #ifndef MRB_WITHOUT_FLOAT
850 case MRB_TT_FLOAT:
851 {
852 mrb_float f = mrb_float(ARGV[arg_i]);
853
854 if (!FIXABLE_FLOAT(f)) {
855 mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
856 }
857 *p = (mrb_int)f;
858 }
859 break;
860 #endif
861 case MRB_TT_STRING:
862 mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer");
863 break;
864 default:
865 *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i]));
866 break;
867 }
868 arg_i++;
869 i++;
870 }
871 }
872 break;
873 case 'b':
874 {
875 mrb_bool *boolp = va_arg(ap, mrb_bool*);
876
877 if (i < argc) {
878 mrb_value b = ARGV[arg_i++];
879 *boolp = mrb_test(b);
880 i++;
881 }
882 }
883 break;
884 case 'n':
885 {
886 mrb_sym *symp;
887
888 symp = va_arg(ap, mrb_sym*);
889 if (i < argc) {
890 mrb_value ss;
891
892 ss = ARGV[arg_i++];
893 *symp = to_sym(mrb, ss);
894 i++;
895 }
896 }
897 break;
898 case 'd':
899 {
900 void** datap;
901 struct mrb_data_type const* type;
902
903 datap = va_arg(ap, void**);
904 type = va_arg(ap, struct mrb_data_type const*);
905 if (*format == '!') {
906 format++;
907 if (i < argc && mrb_nil_p(ARGV[arg_i])) {
908 *datap = 0;
909 i++; arg_i++;
910 break;
911 }
912 }
913 if (i < argc) {
914 *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type);
915 ++i;
916 }
917 }
918 break;
919
920 case '&':
921 {
922 mrb_value *p, *bp;
923
924 p = va_arg(ap, mrb_value*);
925 if (mrb->c->ci->argc < 0) {
926 bp = mrb->c->stack + 2;
927 }
928 else {
929 bp = mrb->c->stack + mrb->c->ci->argc + 1;
930 }
931 if (*format == '!') {
932 format ++;
933 if (mrb_nil_p(*bp)) {
934 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
935 }
936 }
937 *p = *bp;
938 }
939 break;
940 case '|':
941 if (opt_skip && i == argc) return argc;
942 opt = TRUE;
943 break;
944 case '?':
945 {
946 mrb_bool *p;
947
948 p = va_arg(ap, mrb_bool*);
949 *p = given;
950 }
951 break;
952
953 case '*':
954 {
955 mrb_value **var;
956 mrb_int *pl;
957 mrb_bool nocopy = array_argv ? TRUE : FALSE;
958
959 if (*format == '!') {
960 format++;
961 nocopy = TRUE;
962 }
963 var = va_arg(ap, mrb_value**);
964 pl = va_arg(ap, mrb_int*);
965 if (argc > i) {
966 *pl = argc-i;
967 if (*pl > 0) {
968 if (nocopy) {
969 *var = ARGV+arg_i;
970 }
971 else {
972 mrb_value args = mrb_ary_new_from_values(mrb, *pl, ARGV+arg_i);
973 RARRAY(args)->c = NULL;
974 *var = RARRAY_PTR(args);
975 }
976 }
977 i = argc;
978 arg_i += *pl;
979 }
980 else {
981 *pl = 0;
982 *var = NULL;
983 }
984 }
985 break;
986 default:
987 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1));
988 break;
989 }
990 }
991
992 #undef ARGV
993
994 if (!c && argc > i) {
995 mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
996 }
997 va_end(ap);
998 return i;
999 }
1000
1001 static struct RClass*
boot_defclass(mrb_state * mrb,struct RClass * super)1002 boot_defclass(mrb_state *mrb, struct RClass *super)
1003 {
1004 struct RClass *c;
1005
1006 c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class);
1007 if (super) {
1008 c->super = super;
1009 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
1010 }
1011 else {
1012 c->super = mrb->object_class;
1013 }
1014 c->mt = kh_init(mt, mrb);
1015 return c;
1016 }
1017
1018 static void
boot_initmod(mrb_state * mrb,struct RClass * mod)1019 boot_initmod(mrb_state *mrb, struct RClass *mod)
1020 {
1021 if (!mod->mt) {
1022 mod->mt = kh_init(mt, mrb);
1023 }
1024 }
1025
1026 static struct RClass*
include_class_new(mrb_state * mrb,struct RClass * m,struct RClass * super)1027 include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super)
1028 {
1029 struct RClass *ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class);
1030 if (m->tt == MRB_TT_ICLASS) {
1031 m = m->c;
1032 }
1033 MRB_CLASS_ORIGIN(m);
1034 ic->iv = m->iv;
1035 ic->mt = m->mt;
1036 ic->super = super;
1037 if (m->tt == MRB_TT_ICLASS) {
1038 ic->c = m->c;
1039 }
1040 else {
1041 ic->c = m;
1042 }
1043 return ic;
1044 }
1045
1046 static int
include_module_at(mrb_state * mrb,struct RClass * c,struct RClass * ins_pos,struct RClass * m,int search_super)1047 include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super)
1048 {
1049 struct RClass *p, *ic;
1050 void *klass_mt = find_origin(c)->mt;
1051
1052 while (m) {
1053 int superclass_seen = 0;
1054
1055 if (m->flags & MRB_FL_CLASS_IS_PREPENDED)
1056 goto skip;
1057
1058 if (klass_mt && klass_mt == m->mt)
1059 return -1;
1060
1061 p = c->super;
1062 while (p) {
1063 if (p->tt == MRB_TT_ICLASS) {
1064 if (p->mt == m->mt) {
1065 if (!superclass_seen) {
1066 ins_pos = p; /* move insert point */
1067 }
1068 goto skip;
1069 }
1070 } else if (p->tt == MRB_TT_CLASS) {
1071 if (!search_super) break;
1072 superclass_seen = 1;
1073 }
1074 p = p->super;
1075 }
1076
1077 ic = include_class_new(mrb, m, ins_pos->super);
1078 m->flags |= MRB_FL_CLASS_IS_INHERITED;
1079 ins_pos->super = ic;
1080 mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
1081 mc_clear_by_class(mrb, ins_pos);
1082 ins_pos = ic;
1083 skip:
1084 m = m->super;
1085 }
1086 mc_clear_all(mrb);
1087 return 0;
1088 }
1089
1090 MRB_API void
mrb_include_module(mrb_state * mrb,struct RClass * c,struct RClass * m)1091 mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
1092 {
1093 int changed = include_module_at(mrb, c, find_origin(c), m, 1);
1094 if (changed < 0) {
1095 mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
1096 }
1097 }
1098
1099 MRB_API void
mrb_prepend_module(mrb_state * mrb,struct RClass * c,struct RClass * m)1100 mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
1101 {
1102 struct RClass *origin;
1103 int changed = 0;
1104
1105 if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
1106 origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c);
1107 origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED;
1108 origin->super = c->super;
1109 c->super = origin;
1110 origin->mt = c->mt;
1111 c->mt = kh_init(mt, mrb);
1112 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin);
1113 c->flags |= MRB_FL_CLASS_IS_PREPENDED;
1114 }
1115 changed = include_module_at(mrb, c, c, m, 0);
1116 if (changed < 0) {
1117 mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected");
1118 }
1119 }
1120
1121 static mrb_value
mrb_mod_prepend_features(mrb_state * mrb,mrb_value mod)1122 mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod)
1123 {
1124 mrb_value klass;
1125
1126 mrb_check_type(mrb, mod, MRB_TT_MODULE);
1127 mrb_get_args(mrb, "C", &klass);
1128 mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
1129 return mod;
1130 }
1131
1132 static mrb_value
mrb_mod_append_features(mrb_state * mrb,mrb_value mod)1133 mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
1134 {
1135 mrb_value klass;
1136
1137 mrb_check_type(mrb, mod, MRB_TT_MODULE);
1138 mrb_get_args(mrb, "C", &klass);
1139 mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod));
1140 return mod;
1141 }
1142
1143 /* 15.2.2.4.28 */
1144 /*
1145 * call-seq:
1146 * mod.include?(module) -> true or false
1147 *
1148 * Returns <code>true</code> if <i>module</i> is included in
1149 * <i>mod</i> or one of <i>mod</i>'s ancestors.
1150 *
1151 * module A
1152 * end
1153 * class B
1154 * include A
1155 * end
1156 * class C < B
1157 * end
1158 * B.include?(A) #=> true
1159 * C.include?(A) #=> true
1160 * A.include?(A) #=> false
1161 */
1162 static mrb_value
mrb_mod_include_p(mrb_state * mrb,mrb_value mod)1163 mrb_mod_include_p(mrb_state *mrb, mrb_value mod)
1164 {
1165 mrb_value mod2;
1166 struct RClass *c = mrb_class_ptr(mod);
1167
1168 mrb_get_args(mrb, "C", &mod2);
1169 mrb_check_type(mrb, mod2, MRB_TT_MODULE);
1170
1171 while (c) {
1172 if (c->tt == MRB_TT_ICLASS) {
1173 if (c->c == mrb_class_ptr(mod2)) return mrb_true_value();
1174 }
1175 c = c->super;
1176 }
1177 return mrb_false_value();
1178 }
1179
1180 static mrb_value
mrb_mod_ancestors(mrb_state * mrb,mrb_value self)1181 mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
1182 {
1183 mrb_value result;
1184 struct RClass *c = mrb_class_ptr(self);
1185 result = mrb_ary_new(mrb);
1186 while (c) {
1187 if (c->tt == MRB_TT_ICLASS) {
1188 mrb_ary_push(mrb, result, mrb_obj_value(c->c));
1189 }
1190 else if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
1191 mrb_ary_push(mrb, result, mrb_obj_value(c));
1192 }
1193 c = c->super;
1194 }
1195
1196 return result;
1197 }
1198
1199 static mrb_value
mrb_mod_extend_object(mrb_state * mrb,mrb_value mod)1200 mrb_mod_extend_object(mrb_state *mrb, mrb_value mod)
1201 {
1202 mrb_value obj;
1203
1204 mrb_check_type(mrb, mod, MRB_TT_MODULE);
1205 mrb_get_args(mrb, "o", &obj);
1206 mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod));
1207 return mod;
1208 }
1209
1210 static mrb_value
mrb_mod_initialize(mrb_state * mrb,mrb_value mod)1211 mrb_mod_initialize(mrb_state *mrb, mrb_value mod)
1212 {
1213 mrb_value b;
1214 struct RClass *m = mrb_class_ptr(mod);
1215 boot_initmod(mrb, m); /* bootstrap a newly initialized module */
1216 mrb_get_args(mrb, "|&", &b);
1217 if (!mrb_nil_p(b)) {
1218 mrb_yield_with_class(mrb, b, 1, &mod, mod, m);
1219 }
1220 return mod;
1221 }
1222
1223 /* implementation of module_eval/class_eval */
1224 mrb_value mrb_mod_module_eval(mrb_state*, mrb_value);
1225
1226 static mrb_value
mrb_mod_dummy_visibility(mrb_state * mrb,mrb_value mod)1227 mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
1228 {
1229 return mod;
1230 }
1231
1232 MRB_API mrb_value
mrb_singleton_class(mrb_state * mrb,mrb_value v)1233 mrb_singleton_class(mrb_state *mrb, mrb_value v)
1234 {
1235 struct RBasic *obj;
1236
1237 switch (mrb_type(v)) {
1238 case MRB_TT_FALSE:
1239 if (mrb_nil_p(v))
1240 return mrb_obj_value(mrb->nil_class);
1241 return mrb_obj_value(mrb->false_class);
1242 case MRB_TT_TRUE:
1243 return mrb_obj_value(mrb->true_class);
1244 case MRB_TT_CPTR:
1245 return mrb_obj_value(mrb->object_class);
1246 case MRB_TT_SYMBOL:
1247 case MRB_TT_FIXNUM:
1248 #ifndef MRB_WITHOUT_FLOAT
1249 case MRB_TT_FLOAT:
1250 #endif
1251 mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
1252 return mrb_nil_value(); /* not reached */
1253 default:
1254 break;
1255 }
1256 obj = mrb_basic_ptr(v);
1257 prepare_singleton_class(mrb, obj);
1258 return mrb_obj_value(obj->c);
1259 }
1260
1261 MRB_API void
mrb_define_singleton_method(mrb_state * mrb,struct RObject * o,const char * name,mrb_func_t func,mrb_aspec aspec)1262 mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
1263 {
1264 prepare_singleton_class(mrb, (struct RBasic*)o);
1265 mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec);
1266 }
1267
1268 MRB_API void
mrb_define_class_method(mrb_state * mrb,struct RClass * c,const char * name,mrb_func_t func,mrb_aspec aspec)1269 mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1270 {
1271 mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec);
1272 }
1273
1274 MRB_API void
mrb_define_module_function(mrb_state * mrb,struct RClass * c,const char * name,mrb_func_t func,mrb_aspec aspec)1275 mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1276 {
1277 mrb_define_class_method(mrb, c, name, func, aspec);
1278 mrb_define_method(mrb, c, name, func, aspec);
1279 }
1280
1281 #ifdef MRB_METHOD_CACHE
1282 static void
mc_clear_all(mrb_state * mrb)1283 mc_clear_all(mrb_state *mrb)
1284 {
1285 struct mrb_cache_entry *mc = mrb->cache;
1286 int i;
1287
1288 for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
1289 mc[i].c = 0;
1290 }
1291 }
1292
1293 static void
mc_clear_by_class(mrb_state * mrb,struct RClass * c)1294 mc_clear_by_class(mrb_state *mrb, struct RClass *c)
1295 {
1296 struct mrb_cache_entry *mc = mrb->cache;
1297 int i;
1298
1299 if (c->flags & MRB_FL_CLASS_IS_INHERITED) {
1300 mc_clear_all(mrb);
1301 c->flags &= ~MRB_FL_CLASS_IS_INHERITED;
1302 return;
1303 }
1304 for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
1305 if (mc[i].c == c) mc[i].c = 0;
1306 }
1307 }
1308
1309 static void
mc_clear_by_id(mrb_state * mrb,struct RClass * c,mrb_sym mid)1310 mc_clear_by_id(mrb_state *mrb, struct RClass *c, mrb_sym mid)
1311 {
1312 struct mrb_cache_entry *mc = mrb->cache;
1313 int i;
1314
1315 if (c->flags & MRB_FL_CLASS_IS_INHERITED) {
1316 mc_clear_all(mrb);
1317 c->flags &= ~MRB_FL_CLASS_IS_INHERITED;
1318 return;
1319 }
1320 for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
1321 if (mc[i].c == c || mc[i].mid == mid)
1322 mc[i].c = 0;
1323 }
1324 }
1325 #endif
1326
1327 MRB_API mrb_method_t
mrb_method_search_vm(mrb_state * mrb,struct RClass ** cp,mrb_sym mid)1328 mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
1329 {
1330 khiter_t k;
1331 mrb_method_t m;
1332 struct RClass *c = *cp;
1333 #ifdef MRB_METHOD_CACHE
1334 struct RClass *oc = c;
1335 int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
1336 struct mrb_cache_entry *mc = &mrb->cache[h];
1337
1338 if (mc->c == c && mc->mid == mid) {
1339 *cp = mc->c0;
1340 return mc->m;
1341 }
1342 #endif
1343
1344 while (c) {
1345 khash_t(mt) *h = c->mt;
1346
1347 if (h) {
1348 k = kh_get(mt, mrb, h, mid);
1349 if (k != kh_end(h)) {
1350 m = kh_value(h, k);
1351 if (MRB_METHOD_UNDEF_P(m)) break;
1352 *cp = c;
1353 #ifdef MRB_METHOD_CACHE
1354 mc->c = oc;
1355 mc->c0 = c;
1356 mc->mid = mid;
1357 mc->m = m;
1358 #endif
1359 return m;
1360 }
1361 }
1362 c = c->super;
1363 }
1364 MRB_METHOD_FROM_PROC(m, NULL);
1365 return m; /* no method */
1366 }
1367
1368 MRB_API mrb_method_t
mrb_method_search(mrb_state * mrb,struct RClass * c,mrb_sym mid)1369 mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
1370 {
1371 mrb_method_t m;
1372
1373 m = mrb_method_search_vm(mrb, &c, mid);
1374 if (MRB_METHOD_UNDEF_P(m)) {
1375 mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0);
1376 if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) {
1377 inspect = mrb_any_to_s(mrb, mrb_obj_value(c));
1378 }
1379 mrb_name_error(mrb, mid, "undefined method '%S' for class %S",
1380 mrb_sym2str(mrb, mid), inspect);
1381 }
1382 return m;
1383 }
1384
1385 static mrb_value
attr_reader(mrb_state * mrb,mrb_value obj)1386 attr_reader(mrb_state *mrb, mrb_value obj)
1387 {
1388 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
1389 return mrb_iv_get(mrb, obj, to_sym(mrb, name));
1390 }
1391
1392 static mrb_value
mrb_mod_attr_reader(mrb_state * mrb,mrb_value mod)1393 mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
1394 {
1395 struct RClass *c = mrb_class_ptr(mod);
1396 mrb_value *argv;
1397 mrb_int argc, i;
1398 int ai;
1399
1400 mrb_get_args(mrb, "*", &argv, &argc);
1401 ai = mrb_gc_arena_save(mrb);
1402 for (i=0; i<argc; i++) {
1403 mrb_value name, str;
1404 mrb_sym method, sym;
1405 struct RProc *p;
1406 mrb_method_t m;
1407
1408 method = to_sym(mrb, argv[i]);
1409 name = mrb_sym2str(mrb, method);
1410 str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1);
1411 mrb_str_cat_lit(mrb, str, "@");
1412 mrb_str_cat_str(mrb, str, name);
1413 sym = mrb_intern_str(mrb, str);
1414 mrb_iv_name_sym_check(mrb, sym);
1415 name = mrb_symbol_value(sym);
1416 p = mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name);
1417 MRB_METHOD_FROM_PROC(m, p);
1418 mrb_define_method_raw(mrb, c, method, m);
1419 mrb_gc_arena_restore(mrb, ai);
1420 }
1421 return mrb_nil_value();
1422 }
1423
1424 static mrb_value
attr_writer(mrb_state * mrb,mrb_value obj)1425 attr_writer(mrb_state *mrb, mrb_value obj)
1426 {
1427 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
1428 mrb_value val;
1429
1430 mrb_get_args(mrb, "o", &val);
1431 mrb_iv_set(mrb, obj, to_sym(mrb, name), val);
1432 return val;
1433 }
1434
1435 static mrb_value
mrb_mod_attr_writer(mrb_state * mrb,mrb_value mod)1436 mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
1437 {
1438 struct RClass *c = mrb_class_ptr(mod);
1439 mrb_value *argv;
1440 mrb_int argc, i;
1441 int ai;
1442
1443 mrb_get_args(mrb, "*", &argv, &argc);
1444 ai = mrb_gc_arena_save(mrb);
1445 for (i=0; i<argc; i++) {
1446 mrb_value name, str, attr;
1447 mrb_sym method, sym;
1448 struct RProc *p;
1449 mrb_method_t m;
1450
1451 method = to_sym(mrb, argv[i]);
1452
1453 /* prepare iv name (@name) */
1454 name = mrb_sym2str(mrb, method);
1455 str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1);
1456 mrb_str_cat_lit(mrb, str, "@");
1457 mrb_str_cat_str(mrb, str, name);
1458 sym = mrb_intern_str(mrb, str);
1459 mrb_iv_name_sym_check(mrb, sym);
1460 attr = mrb_symbol_value(sym);
1461
1462 /* prepare method name (name=) */
1463 str = mrb_str_new_capa(mrb, RSTRING_LEN(str));
1464 mrb_str_cat_str(mrb, str, name);
1465 mrb_str_cat_lit(mrb, str, "=");
1466 method = mrb_intern_str(mrb, str);
1467
1468 p = mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr);
1469 MRB_METHOD_FROM_PROC(m, p);
1470 mrb_define_method_raw(mrb, c, method, m);
1471 mrb_gc_arena_restore(mrb, ai);
1472 }
1473 return mrb_nil_value();
1474 }
1475
1476 static mrb_value
mrb_instance_alloc(mrb_state * mrb,mrb_value cv)1477 mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
1478 {
1479 struct RClass *c = mrb_class_ptr(cv);
1480 struct RObject *o;
1481 enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
1482
1483 if (c->tt == MRB_TT_SCLASS)
1484 mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");
1485
1486 if (ttype == 0) ttype = MRB_TT_OBJECT;
1487 if (ttype <= MRB_TT_CPTR) {
1488 mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv);
1489 }
1490 o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
1491 return mrb_obj_value(o);
1492 }
1493
1494 /*
1495 * call-seq:
1496 * class.new(args, ...) -> obj
1497 *
1498 * Creates a new object of <i>class</i>'s class, then
1499 * invokes that object's <code>initialize</code> method,
1500 * passing it <i>args</i>. This is the method that ends
1501 * up getting called whenever an object is constructed using
1502 * `.new`.
1503 *
1504 */
1505
1506 MRB_API mrb_value
mrb_instance_new(mrb_state * mrb,mrb_value cv)1507 mrb_instance_new(mrb_state *mrb, mrb_value cv)
1508 {
1509 mrb_value obj, blk;
1510 mrb_value *argv;
1511 mrb_int argc;
1512 mrb_sym init;
1513 mrb_method_t m;
1514
1515 mrb_get_args(mrb, "*&", &argv, &argc, &blk);
1516 obj = mrb_instance_alloc(mrb, cv);
1517 init = mrb_intern_lit(mrb, "initialize");
1518 m = mrb_method_search(mrb, mrb_class(mrb, obj), init);
1519 if (MRB_METHOD_CFUNC_P(m)) {
1520 mrb_func_t f = MRB_METHOD_CFUNC(m);
1521 if (f != mrb_bob_init) {
1522 f(mrb, obj);
1523 }
1524 }
1525 else {
1526 mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
1527 }
1528
1529 return obj;
1530 }
1531
1532 MRB_API mrb_value
mrb_obj_new(mrb_state * mrb,struct RClass * c,mrb_int argc,const mrb_value * argv)1533 mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv)
1534 {
1535 mrb_value obj;
1536 mrb_sym mid;
1537
1538 obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
1539 mid = mrb_intern_lit(mrb, "initialize");
1540 if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) {
1541 mrb_funcall_argv(mrb, obj, mid, argc, argv);
1542 }
1543 return obj;
1544 }
1545
1546 static mrb_value
mrb_class_initialize(mrb_state * mrb,mrb_value c)1547 mrb_class_initialize(mrb_state *mrb, mrb_value c)
1548 {
1549 mrb_value a, b;
1550
1551 mrb_get_args(mrb, "|C&", &a, &b);
1552 if (!mrb_nil_p(b)) {
1553 mrb_yield_with_class(mrb, b, 1, &c, c, mrb_class_ptr(c));
1554 }
1555 return c;
1556 }
1557
1558 static mrb_value
mrb_class_new_class(mrb_state * mrb,mrb_value cv)1559 mrb_class_new_class(mrb_state *mrb, mrb_value cv)
1560 {
1561 mrb_int n;
1562 mrb_value super, blk;
1563 mrb_value new_class;
1564 mrb_sym mid;
1565
1566 n = mrb_get_args(mrb, "|C&", &super, &blk);
1567 if (n == 0) {
1568 super = mrb_obj_value(mrb->object_class);
1569 }
1570 new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
1571 mid = mrb_intern_lit(mrb, "initialize");
1572 if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) {
1573 mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
1574 }
1575 mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
1576 return new_class;
1577 }
1578
1579 static mrb_value
mrb_class_superclass(mrb_state * mrb,mrb_value klass)1580 mrb_class_superclass(mrb_state *mrb, mrb_value klass)
1581 {
1582 struct RClass *c;
1583
1584 c = mrb_class_ptr(klass);
1585 c = find_origin(c)->super;
1586 while (c && c->tt == MRB_TT_ICLASS) {
1587 c = find_origin(c)->super;
1588 }
1589 if (!c) return mrb_nil_value();
1590 return mrb_obj_value(c);
1591 }
1592
1593 static mrb_value
mrb_bob_init(mrb_state * mrb,mrb_value cv)1594 mrb_bob_init(mrb_state *mrb, mrb_value cv)
1595 {
1596 return mrb_nil_value();
1597 }
1598
1599 static mrb_value
mrb_bob_not(mrb_state * mrb,mrb_value cv)1600 mrb_bob_not(mrb_state *mrb, mrb_value cv)
1601 {
1602 return mrb_bool_value(!mrb_test(cv));
1603 }
1604
1605 /* 15.3.1.3.1 */
1606 /* 15.3.1.3.10 */
1607 /* 15.3.1.3.11 */
1608 /*
1609 * call-seq:
1610 * obj == other -> true or false
1611 * obj.equal?(other) -> true or false
1612 * obj.eql?(other) -> true or false
1613 *
1614 * Equality---At the <code>Object</code> level, <code>==</code> returns
1615 * <code>true</code> only if <i>obj</i> and <i>other</i> are the
1616 * same object. Typically, this method is overridden in descendant
1617 * classes to provide class-specific meaning.
1618 *
1619 * Unlike <code>==</code>, the <code>equal?</code> method should never be
1620 * overridden by subclasses: it is used to determine object identity
1621 * (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
1622 * object as <code>b</code>).
1623 *
1624 * The <code>eql?</code> method returns <code>true</code> if
1625 * <i>obj</i> and <i>anObject</i> have the same value. Used by
1626 * <code>Hash</code> to test members for equality. For objects of
1627 * class <code>Object</code>, <code>eql?</code> is synonymous with
1628 * <code>==</code>. Subclasses normally continue this tradition, but
1629 * there are exceptions. <code>Numeric</code> types, for example,
1630 * perform type conversion across <code>==</code>, but not across
1631 * <code>eql?</code>, so:
1632 *
1633 * 1 == 1.0 #=> true
1634 * 1.eql? 1.0 #=> false
1635 */
1636 mrb_value
mrb_obj_equal_m(mrb_state * mrb,mrb_value self)1637 mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
1638 {
1639 mrb_value arg;
1640
1641 mrb_get_args(mrb, "o", &arg);
1642 return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
1643 }
1644
1645 static mrb_value
mrb_obj_not_equal_m(mrb_state * mrb,mrb_value self)1646 mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
1647 {
1648 mrb_value arg;
1649
1650 mrb_get_args(mrb, "o", &arg);
1651 return mrb_bool_value(!mrb_equal(mrb, self, arg));
1652 }
1653
1654 MRB_API mrb_bool
mrb_obj_respond_to(mrb_state * mrb,struct RClass * c,mrb_sym mid)1655 mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid)
1656 {
1657 mrb_method_t m;
1658
1659 m = mrb_method_search_vm(mrb, &c, mid);
1660 if (MRB_METHOD_UNDEF_P(m)) {
1661 return FALSE;
1662 }
1663 return TRUE;
1664 }
1665
1666 MRB_API mrb_bool
mrb_respond_to(mrb_state * mrb,mrb_value obj,mrb_sym mid)1667 mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid)
1668 {
1669 return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid);
1670 }
1671
1672 MRB_API mrb_value
mrb_class_path(mrb_state * mrb,struct RClass * c)1673 mrb_class_path(mrb_state *mrb, struct RClass *c)
1674 {
1675 mrb_value path;
1676 mrb_sym nsym = mrb_intern_lit(mrb, "__classname__");
1677
1678 path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym);
1679 if (mrb_nil_p(path)) {
1680 /* no name (yet) */
1681 return mrb_class_find_path(mrb, c);
1682 }
1683 else if (mrb_symbol_p(path)) {
1684 /* toplevel class/module */
1685 return mrb_sym2str(mrb, mrb_symbol(path));
1686 }
1687 return mrb_str_dup(mrb, path);
1688 }
1689
1690 MRB_API struct RClass*
mrb_class_real(struct RClass * cl)1691 mrb_class_real(struct RClass* cl)
1692 {
1693 if (cl == 0) return NULL;
1694 while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) {
1695 cl = cl->super;
1696 if (cl == 0) return NULL;
1697 }
1698 return cl;
1699 }
1700
1701 MRB_API const char*
mrb_class_name(mrb_state * mrb,struct RClass * c)1702 mrb_class_name(mrb_state *mrb, struct RClass* c)
1703 {
1704 mrb_value name = class_name_str(mrb, c);
1705 return RSTRING_PTR(name);
1706 }
1707
1708 MRB_API const char*
mrb_obj_classname(mrb_state * mrb,mrb_value obj)1709 mrb_obj_classname(mrb_state *mrb, mrb_value obj)
1710 {
1711 return mrb_class_name(mrb, mrb_obj_class(mrb, obj));
1712 }
1713
1714 /*!
1715 * Ensures a class can be derived from super.
1716 *
1717 * \param super a reference to an object.
1718 * \exception TypeError if \a super is not a Class or \a super is a singleton class.
1719 */
1720 static void
mrb_check_inheritable(mrb_state * mrb,struct RClass * super)1721 mrb_check_inheritable(mrb_state *mrb, struct RClass *super)
1722 {
1723 if (super->tt != MRB_TT_CLASS) {
1724 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super));
1725 }
1726 if (super->tt == MRB_TT_SCLASS) {
1727 mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class");
1728 }
1729 if (super == mrb->class_class) {
1730 mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class");
1731 }
1732 }
1733
1734 /*!
1735 * Creates a new class.
1736 * \param super a class from which the new class derives.
1737 * \exception TypeError \a super is not inheritable.
1738 * \exception TypeError \a super is the Class class.
1739 */
1740 MRB_API struct RClass*
mrb_class_new(mrb_state * mrb,struct RClass * super)1741 mrb_class_new(mrb_state *mrb, struct RClass *super)
1742 {
1743 struct RClass *c;
1744
1745 if (super) {
1746 mrb_check_inheritable(mrb, super);
1747 }
1748 c = boot_defclass(mrb, super);
1749 if (super) {
1750 MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
1751 }
1752 make_metaclass(mrb, c);
1753
1754 return c;
1755 }
1756
1757 /*!
1758 * Creates a new module.
1759 */
1760 MRB_API struct RClass*
mrb_module_new(mrb_state * mrb)1761 mrb_module_new(mrb_state *mrb)
1762 {
1763 struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class);
1764 boot_initmod(mrb, m);
1765 return m;
1766 }
1767
1768 /*
1769 * call-seq:
1770 * obj.class => class
1771 *
1772 * Returns the class of <i>obj</i>, now preferred over
1773 * <code>Object#type</code>, as an object's type in Ruby is only
1774 * loosely tied to that object's class. This method must always be
1775 * called with an explicit receiver, as <code>class</code> is also a
1776 * reserved word in Ruby.
1777 *
1778 * 1.class #=> Fixnum
1779 * self.class #=> Object
1780 */
1781
1782 MRB_API struct RClass*
mrb_obj_class(mrb_state * mrb,mrb_value obj)1783 mrb_obj_class(mrb_state *mrb, mrb_value obj)
1784 {
1785 return mrb_class_real(mrb_class(mrb, obj));
1786 }
1787
1788 MRB_API void
mrb_alias_method(mrb_state * mrb,struct RClass * c,mrb_sym a,mrb_sym b)1789 mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
1790 {
1791 mrb_method_t m = mrb_method_search(mrb, c, b);
1792
1793 mrb_define_method_raw(mrb, c, a, m);
1794 }
1795
1796 /*!
1797 * Defines an alias of a method.
1798 * \param klass the class which the original method belongs to
1799 * \param name1 a new name for the method
1800 * \param name2 the original name of the method
1801 */
1802 MRB_API void
mrb_define_alias(mrb_state * mrb,struct RClass * klass,const char * name1,const char * name2)1803 mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
1804 {
1805 mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
1806 }
1807
1808 /*
1809 * call-seq:
1810 * mod.to_s -> string
1811 *
1812 * Return a string representing this module or class. For basic
1813 * classes and modules, this is the name. For singletons, we
1814 * show information on the thing we're attached to as well.
1815 */
1816
1817 mrb_value
mrb_mod_to_s(mrb_state * mrb,mrb_value klass)1818 mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
1819 {
1820
1821 if (mrb_type(klass) == MRB_TT_SCLASS) {
1822 mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__"));
1823 mrb_value str = mrb_str_new_lit(mrb, "#<Class:");
1824
1825 if (class_ptr_p(v)) {
1826 mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v));
1827 }
1828 else {
1829 mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v));
1830 }
1831 return mrb_str_cat_lit(mrb, str, ">");
1832 }
1833 else {
1834 return class_name_str(mrb, mrb_class_ptr(klass));
1835 }
1836 }
1837
1838 static mrb_value
mrb_mod_alias(mrb_state * mrb,mrb_value mod)1839 mrb_mod_alias(mrb_state *mrb, mrb_value mod)
1840 {
1841 struct RClass *c = mrb_class_ptr(mod);
1842 mrb_sym new_name, old_name;
1843
1844 mrb_get_args(mrb, "nn", &new_name, &old_name);
1845 mrb_alias_method(mrb, c, new_name, old_name);
1846 return mrb_nil_value();
1847 }
1848
1849 void
mrb_undef_method_id(mrb_state * mrb,struct RClass * c,mrb_sym a)1850 mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a)
1851 {
1852 if (!mrb_obj_respond_to(mrb, c, a)) {
1853 mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c));
1854 }
1855 else {
1856 mrb_method_t m;
1857
1858 MRB_METHOD_FROM_PROC(m, NULL);
1859 mrb_define_method_raw(mrb, c, a, m);
1860 }
1861 }
1862
1863 MRB_API void
mrb_undef_method(mrb_state * mrb,struct RClass * c,const char * name)1864 mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
1865 {
1866 mrb_undef_method_id(mrb, c, mrb_intern_cstr(mrb, name));
1867 }
1868
1869 MRB_API void
mrb_undef_class_method(mrb_state * mrb,struct RClass * c,const char * name)1870 mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name)
1871 {
1872 mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
1873 }
1874
1875 static mrb_value
mrb_mod_undef(mrb_state * mrb,mrb_value mod)1876 mrb_mod_undef(mrb_state *mrb, mrb_value mod)
1877 {
1878 struct RClass *c = mrb_class_ptr(mod);
1879 mrb_int argc;
1880 mrb_value *argv;
1881
1882 mrb_get_args(mrb, "*", &argv, &argc);
1883 while (argc--) {
1884 mrb_undef_method_id(mrb, c, to_sym(mrb, *argv));
1885 argv++;
1886 }
1887 return mrb_nil_value();
1888 }
1889
1890 static mrb_bool
const_name_p(mrb_state * mrb,const char * name,mrb_int len)1891 const_name_p(mrb_state *mrb, const char *name, mrb_int len)
1892 {
1893 return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
1894 }
1895
1896 static void
check_const_name_sym(mrb_state * mrb,mrb_sym id)1897 check_const_name_sym(mrb_state *mrb, mrb_sym id)
1898 {
1899 mrb_int len;
1900 const char *name = mrb_sym2name_len(mrb, id, &len);
1901 if (!const_name_p(mrb, name, len)) {
1902 mrb_name_error(mrb, id, "wrong constant name %S", mrb_sym2str(mrb, id));
1903 }
1904 }
1905
1906 static mrb_value
mrb_mod_const_defined(mrb_state * mrb,mrb_value mod)1907 mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
1908 {
1909 mrb_sym id;
1910 mrb_bool inherit = TRUE;
1911
1912 mrb_get_args(mrb, "n|b", &id, &inherit);
1913 check_const_name_sym(mrb, id);
1914 if (inherit) {
1915 return mrb_bool_value(mrb_const_defined(mrb, mod, id));
1916 }
1917 return mrb_bool_value(mrb_const_defined_at(mrb, mod, id));
1918 }
1919
1920 static mrb_value
mrb_const_get_sym(mrb_state * mrb,mrb_value mod,mrb_sym id)1921 mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id)
1922 {
1923 check_const_name_sym(mrb, id);
1924 return mrb_const_get(mrb, mod, id);
1925 }
1926
1927 static mrb_value
mrb_mod_const_get(mrb_state * mrb,mrb_value mod)1928 mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
1929 {
1930 mrb_value path;
1931 mrb_sym id;
1932 char *ptr;
1933 mrb_int off, end, len;
1934
1935 mrb_get_args(mrb, "o", &path);
1936
1937 if (mrb_symbol_p(path)) {
1938 /* const get with symbol */
1939 id = mrb_symbol(path);
1940 return mrb_const_get_sym(mrb, mod, id);
1941 }
1942
1943 /* const get with class path string */
1944 path = mrb_ensure_string_type(mrb, path);
1945 ptr = RSTRING_PTR(path);
1946 len = RSTRING_LEN(path);
1947 off = 0;
1948
1949 while (off < len) {
1950 end = mrb_str_index_lit(mrb, path, "::", off);
1951 end = (end == -1) ? len : end;
1952 id = mrb_intern(mrb, ptr+off, end-off);
1953 mod = mrb_const_get_sym(mrb, mod, id);
1954 if (end == len)
1955 off = end;
1956 else {
1957 off = end + 2;
1958 if (off == len) { /* trailing "::" */
1959 mrb_name_error(mrb, id, "wrong constant name '%S'", path);
1960 }
1961 }
1962 }
1963
1964 return mod;
1965 }
1966
1967 static mrb_value
mrb_mod_const_set(mrb_state * mrb,mrb_value mod)1968 mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
1969 {
1970 mrb_sym id;
1971 mrb_value value;
1972
1973 mrb_get_args(mrb, "no", &id, &value);
1974 check_const_name_sym(mrb, id);
1975 mrb_const_set(mrb, mod, id, value);
1976 return value;
1977 }
1978
1979 static mrb_value
mrb_mod_remove_const(mrb_state * mrb,mrb_value mod)1980 mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
1981 {
1982 mrb_sym id;
1983 mrb_value val;
1984
1985 mrb_get_args(mrb, "n", &id);
1986 check_const_name_sym(mrb, id);
1987 val = mrb_iv_remove(mrb, mod, id);
1988 if (mrb_undef_p(val)) {
1989 mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id));
1990 }
1991 return val;
1992 }
1993
1994 static mrb_value
mrb_mod_const_missing(mrb_state * mrb,mrb_value mod)1995 mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
1996 {
1997 mrb_sym sym;
1998
1999 mrb_get_args(mrb, "n", &sym);
2000
2001 if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
2002 mrb_name_error(mrb, sym, "uninitialized constant %S::%S",
2003 mod,
2004 mrb_sym2str(mrb, sym));
2005 }
2006 else {
2007 mrb_name_error(mrb, sym, "uninitialized constant %S",
2008 mrb_sym2str(mrb, sym));
2009 }
2010 /* not reached */
2011 return mrb_nil_value();
2012 }
2013
2014 /* 15.2.2.4.34 */
2015 /*
2016 * call-seq:
2017 * mod.method_defined?(symbol) -> true or false
2018 *
2019 * Returns +true+ if the named method is defined by
2020 * _mod_ (or its included modules and, if _mod_ is a class,
2021 * its ancestors). Public and protected methods are matched.
2022 *
2023 * module A
2024 * def method1() end
2025 * end
2026 * class B
2027 * def method2() end
2028 * end
2029 * class C < B
2030 * include A
2031 * def method3() end
2032 * end
2033 *
2034 * A.method_defined? :method1 #=> true
2035 * C.method_defined? "method1" #=> true
2036 * C.method_defined? "method2" #=> true
2037 * C.method_defined? "method3" #=> true
2038 * C.method_defined? "method4" #=> false
2039 */
2040
2041 static mrb_value
mrb_mod_method_defined(mrb_state * mrb,mrb_value mod)2042 mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
2043 {
2044 mrb_sym id;
2045
2046 mrb_get_args(mrb, "n", &id);
2047 return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id));
2048 }
2049
2050 static mrb_value
mod_define_method(mrb_state * mrb,mrb_value self)2051 mod_define_method(mrb_state *mrb, mrb_value self)
2052 {
2053 struct RClass *c = mrb_class_ptr(self);
2054 struct RProc *p;
2055 mrb_method_t m;
2056 mrb_sym mid;
2057 mrb_value proc = mrb_undef_value();
2058 mrb_value blk;
2059
2060 mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
2061 switch (mrb_type(proc)) {
2062 case MRB_TT_PROC:
2063 blk = proc;
2064 break;
2065 case MRB_TT_UNDEF:
2066 /* ignored */
2067 break;
2068 default:
2069 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc)));
2070 break;
2071 }
2072 if (mrb_nil_p(blk)) {
2073 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
2074 }
2075 p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
2076 mrb_proc_copy(p, mrb_proc_ptr(blk));
2077 p->flags |= MRB_PROC_STRICT;
2078 MRB_METHOD_FROM_PROC(m, p);
2079 mrb_define_method_raw(mrb, c, mid, m);
2080 return mrb_symbol_value(mid);
2081 }
2082
2083 static mrb_value
top_define_method(mrb_state * mrb,mrb_value self)2084 top_define_method(mrb_state *mrb, mrb_value self)
2085 {
2086 return mod_define_method(mrb, mrb_obj_value(mrb->object_class));
2087 }
2088
2089 static mrb_value
mrb_mod_eqq(mrb_state * mrb,mrb_value mod)2090 mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
2091 {
2092 mrb_value obj;
2093 mrb_bool eqq;
2094
2095 mrb_get_args(mrb, "o", &obj);
2096 eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod));
2097
2098 return mrb_bool_value(eqq);
2099 }
2100
2101 static mrb_value
mrb_mod_module_function(mrb_state * mrb,mrb_value mod)2102 mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
2103 {
2104 mrb_value *argv;
2105 mrb_int argc, i;
2106 mrb_sym mid;
2107 mrb_method_t m;
2108 struct RClass *rclass;
2109 int ai;
2110
2111 mrb_check_type(mrb, mod, MRB_TT_MODULE);
2112
2113 mrb_get_args(mrb, "*", &argv, &argc);
2114 if (argc == 0) {
2115 /* set MODFUNC SCOPE if implemented */
2116 return mod;
2117 }
2118
2119 /* set PRIVATE method visibility if implemented */
2120 /* mrb_mod_dummy_visibility(mrb, mod); */
2121
2122 for (i=0; i<argc; i++) {
2123 mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
2124
2125 mid = mrb_symbol(argv[i]);
2126 rclass = mrb_class_ptr(mod);
2127 m = mrb_method_search(mrb, rclass, mid);
2128
2129 prepare_singleton_class(mrb, (struct RBasic*)rclass);
2130 ai = mrb_gc_arena_save(mrb);
2131 mrb_define_method_raw(mrb, rclass->c, mid, m);
2132 mrb_gc_arena_restore(mrb, ai);
2133 }
2134
2135 return mod;
2136 }
2137
2138 /* implementation of __id__ */
2139 mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self);
2140 /* implementation of instance_eval */
2141 mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value);
2142
2143 static mrb_value
inspect_main(mrb_state * mrb,mrb_value mod)2144 inspect_main(mrb_state *mrb, mrb_value mod)
2145 {
2146 return mrb_str_new_lit(mrb, "main");
2147 }
2148
2149 void
mrb_init_class(mrb_state * mrb)2150 mrb_init_class(mrb_state *mrb)
2151 {
2152 struct RClass *bob; /* BasicObject */
2153 struct RClass *obj; /* Object */
2154 struct RClass *mod; /* Module */
2155 struct RClass *cls; /* Class */
2156
2157 /* boot class hierarchy */
2158 bob = boot_defclass(mrb, 0);
2159 obj = boot_defclass(mrb, bob); mrb->object_class = obj;
2160 mod = boot_defclass(mrb, obj); mrb->module_class = mod;/* obj -> mod */
2161 cls = boot_defclass(mrb, mod); mrb->class_class = cls; /* obj -> cls */
2162 /* fix-up loose ends */
2163 bob->c = obj->c = mod->c = cls->c = cls;
2164 make_metaclass(mrb, bob);
2165 make_metaclass(mrb, obj);
2166 make_metaclass(mrb, mod);
2167 make_metaclass(mrb, cls);
2168
2169 /* name basic classes */
2170 mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob));
2171 mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob));
2172 mrb_define_const(mrb, obj, "Object", mrb_obj_value(obj));
2173 mrb_define_const(mrb, obj, "Module", mrb_obj_value(mod));
2174 mrb_define_const(mrb, obj, "Class", mrb_obj_value(cls));
2175
2176 /* name each classes */
2177 mrb_class_name_class(mrb, NULL, bob, mrb_intern_lit(mrb, "BasicObject"));
2178 mrb_class_name_class(mrb, NULL, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */
2179 mrb_class_name_class(mrb, NULL, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */
2180 mrb_class_name_class(mrb, NULL, cls, mrb_intern_lit(mrb, "Class")); /* 15.2.3 */
2181
2182 mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); /* 15.2.17 */
2183 MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC);
2184
2185 MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
2186 mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE());
2187 mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE());
2188 mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */
2189 mrb_define_method(mrb, bob, "!=", mrb_obj_not_equal_m, MRB_ARGS_REQ(1));
2190 mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.4 */
2191 mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.5 */
2192 mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_ANY()); /* 15.3.1.3.18 */
2193
2194 mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1));
2195 mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */
2196 mrb_define_method(mrb, cls, "new", mrb_instance_new, MRB_ARGS_ANY()); /* 15.2.3.3.3 */
2197 mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
2198 mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1));
2199
2200 MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
2201 mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
2202 mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
2203 mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1));
2204 mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1));
2205 mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
2206 mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */
2207 mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */
2208 mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
2209 mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */
2210 mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
2211 mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY());
2212 mrb_define_method(mrb, mod, "private", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
2213 mrb_define_method(mrb, mod, "protected", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
2214 mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
2215 mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */
2216 mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */
2217 mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE());
2218 mrb_define_method(mrb, mod, "inspect", mrb_mod_to_s, MRB_ARGS_NONE());
2219 mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */
2220 mrb_define_method(mrb, mod, "ancestors", mrb_mod_ancestors, MRB_ARGS_NONE()); /* 15.2.2.4.9 */
2221 mrb_define_method(mrb, mod, "undef_method", mrb_mod_undef, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
2222 mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, MRB_ARGS_ARG(1,1)); /* 15.2.2.4.20 */
2223 mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */
2224 mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */
2225 mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */
2226 mrb_define_method(mrb, mod, "const_missing", mrb_mod_const_missing, MRB_ARGS_REQ(1));
2227 mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
2228 mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1));
2229 mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1));
2230
2231 mrb_undef_method(mrb, cls, "append_features");
2232 mrb_undef_method(mrb, cls, "extend_object");
2233
2234 mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
2235 mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
2236 mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
2237 mrb_define_singleton_method(mrb, mrb->top_self, "define_method", top_define_method, MRB_ARGS_ARG(1,1));
2238 }
2239