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