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