Merge pull request #6288 from dearblue/closing
[mruby.git] / src / class.c
blob4033ccbce56fd6839a813c3805c42db1cc2d1582
1 /*
2 ** class.c - Class class
3 **
4 ** See Copyright Notice in mruby.h
5 */
7 #include <mruby.h>
8 #include <mruby/array.h>
9 #include <mruby/hash.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 #include <mruby/opcode.h>
19 #include <mruby/internal.h>
20 #include <mruby/presym.h>
22 #define METHOD_MID(m) MT_KEY_SYM((m).flags)
24 union mt_ptr {
25 struct RProc *proc;
26 mrb_func_t func;
29 #define MT_KEY_P(k) (((k)>>2) != 0)
30 #define MT_FUNC_P 1
31 #define MT_NOARG_P 2
32 #define MT_EMPTY 0
33 #define MT_DELETED 1
35 #define MT_KEY(sym, flags) ((sym)<<2|(flags))
36 #define MT_FLAGS(func_p, noarg_p) ((func_p)?MT_FUNC_P:0)|((noarg_p)?MT_NOARG_P:0)
37 #define MT_KEY_SYM(k) ((k)>>2)
38 #define MT_KEY_FLG(k) ((k)&3)
40 /* method table structure */
41 typedef struct mt_tbl {
42 int size;
43 int alloc;
44 union mt_ptr *ptr;
45 } mt_tbl;
47 #ifdef MRB_USE_INLINE_METHOD_CACHE
48 #define MT_INLINE_CACHE_SIZE 256
49 static uint8_t mt_cache[MT_INLINE_CACHE_SIZE];
50 #endif
52 /* Creates the method table. */
53 static mt_tbl*
54 mt_new(mrb_state *mrb)
56 mt_tbl *t;
58 t = (mt_tbl*)mrb_malloc(mrb, sizeof(mt_tbl));
59 t->size = 0;
60 t->alloc = 0;
61 t->ptr = NULL;
63 return t;
66 static void mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, mrb_sym flags, union mt_ptr ptr);
68 static void
69 mt_rehash(mrb_state *mrb, mt_tbl *t)
71 int old_alloc = t->alloc;
72 int new_alloc = old_alloc > 0 ? old_alloc << 1 : 8;
73 union mt_ptr *old_ptr = t->ptr;
75 t->ptr = (union mt_ptr*)mrb_calloc(mrb, sizeof(union mt_ptr)+sizeof(mrb_sym), new_alloc);
76 t->alloc = new_alloc;
77 t->size = 0;
78 if (old_alloc == 0) return;
80 mrb_sym *keys = (mrb_sym*)&old_ptr[old_alloc];
81 union mt_ptr *vals = old_ptr;
82 for (int i = 0; i < old_alloc; i++) {
83 mrb_sym key = keys[i];
84 if (MT_KEY_P(key)) {
85 mt_put(mrb, t, MT_KEY_SYM(key), MT_KEY_FLG(key), vals[i]);
88 mrb_free(mrb, old_ptr);
91 #define slot_empty_p(slot) ((slot)->key == 0 && (slot)->func_p == 0)
93 /* Set the value for the symbol in the method table. */
94 static void
95 mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, mrb_sym flags, union mt_ptr ptr)
97 int hash, pos, start, dpos = -1;
99 if (t->alloc == 0) {
100 mt_rehash(mrb, t);
103 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
104 union mt_ptr *vals = t->ptr;
105 hash = mrb_int_hash_func(mrb, sym);
106 start = pos = hash & (t->alloc-1);
107 for (;;) {
108 mrb_sym key = keys[pos];
109 if (MT_KEY_SYM(key) == sym) {
110 value_set:
111 keys[pos] = MT_KEY(sym, flags);
112 vals[pos] = ptr;
113 return;
115 else if (key == MT_EMPTY) {
116 t->size++;
117 goto value_set;
119 else if (key == MT_DELETED && dpos < 0) {
120 dpos = pos;
122 pos = (pos+1) & (t->alloc-1);
123 if (pos == start) { /* not found */
124 if (dpos > 0) {
125 t->size++;
126 pos = dpos;
127 goto value_set;
129 /* no room */
130 mt_rehash(mrb, t);
131 start = pos = hash & (t->alloc-1);
132 keys = (mrb_sym*)&t->ptr[t->alloc];
133 vals = t->ptr;
138 /* Get a value for a symbol from the method table. */
139 static mrb_sym
140 mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp)
142 int hash, pos, start;
144 if (t == NULL) return 0;
145 if (t->alloc == 0) return 0;
146 if (t->size == 0) return 0;
148 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
149 union mt_ptr *vals = t->ptr;
150 hash = mrb_int_hash_func(mrb, sym);
151 #ifdef MRB_USE_INLINE_METHOD_CACHE
152 int cpos = (hash^(uintptr_t)t) % MT_INLINE_CACHE_SIZE;
153 pos = mt_cache[cpos];
154 if (pos < t->alloc) {
155 mrb_sym key = keys[pos];
156 if (key) {
157 if (MT_KEY_SYM(key) == sym) {
158 *pp = vals[pos];
159 return key;
163 #endif
164 start = pos = hash & (t->alloc-1);
165 for (;;) {
166 mrb_sym key = keys[pos];
167 if (MT_KEY_SYM(key) == sym) {
168 *pp = vals[pos];
169 #ifdef MRB_USE_INLINE_METHOD_CACHE
170 if (pos < 0x100) {
171 mt_cache[cpos] = pos;
173 #endif
174 return key;
176 else if (key == MT_EMPTY) {
177 return 0;
179 pos = (pos+1) & (t->alloc-1);
180 if (pos == start) { /* not found */
181 return 0;
186 /* Deletes the value for the symbol from the method table. */
187 static mrb_bool
188 mt_del(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
190 int hash, pos, start;
192 if (t == NULL) return FALSE;
193 if (t->alloc == 0) return FALSE;
194 if (t->size == 0) return FALSE;
196 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
197 hash = mrb_int_hash_func(mrb, sym);
198 start = pos = hash & (t->alloc-1);
199 for (;;) {
200 mrb_sym key = keys[pos];
201 if (MT_KEY_SYM(key) == sym) {
202 t->size--;
203 keys[pos] = MT_DELETED;
204 return TRUE;
206 else if (key == MT_EMPTY) {
207 return FALSE;
209 pos = (pos+1) & (t->alloc-1);
210 if (pos == start) { /* not found */
211 return FALSE;
216 /* Copy the method table. */
217 static struct mt_tbl*
218 mt_copy(mrb_state *mrb, mt_tbl *t)
220 mt_tbl *t2;
222 if (t == NULL) return NULL;
223 if (t->alloc == 0) return NULL;
224 if (t->size == 0) return NULL;
226 t2 = mt_new(mrb);
227 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
228 union mt_ptr *vals = t->ptr;
229 for (int i=0; i<t->alloc; i++) {
230 if (MT_KEY_P(keys[i])) {
231 mt_put(mrb, t2, MT_KEY_SYM(keys[i]), MT_KEY_FLG(keys[i]), vals[i]);
234 return t2;
237 /* Free memory of the method table. */
238 static void
239 mt_free(mrb_state *mrb, mt_tbl *t)
241 mrb_free(mrb, t->ptr);
242 mrb_free(mrb, t);
245 static inline mrb_method_t
246 create_method_value(mrb_state *mrb, mrb_sym key, union mt_ptr val)
248 mrb_method_t m = { key, { val.proc } };
249 return m;
252 MRB_API void
253 mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p)
255 mt_tbl *t = c->mt;
257 if (t == NULL) return;
258 if (t->alloc == 0) return;
259 if (t->size == 0) return;
261 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
262 union mt_ptr *vals = t->ptr;
263 for (int i=0; i<t->alloc; i++) {
264 mrb_sym key = keys[i];
265 if (MT_KEY_SYM(key)) {
266 if (fn(mrb, MT_KEY_SYM(key), create_method_value(mrb, key, vals[i]), p) != 0)
267 return;
270 return;
273 size_t
274 mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
276 mt_tbl *t = c->mt;
278 if (t == NULL) return 0;
279 if (t->alloc == 0) return 0;
280 if (t->size == 0) return 0;
282 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
283 union mt_ptr *vals = t->ptr;
284 for (int i=0; i<t->alloc; i++) {
285 if (MT_KEY_P(keys[i]) && (keys[i] & MT_FUNC_P) == 0) { /* Proc pointer */
286 struct RProc *p = vals[i].proc;
287 mrb_gc_mark(mrb, (struct RBasic*)p);
290 if (!t) return 0;
291 return (size_t)t->size;
294 size_t
295 mrb_class_mt_memsize(mrb_state *mrb, struct RClass *c)
297 struct mt_tbl *h = c->mt;
299 if (!h) return 0;
300 return sizeof(struct mt_tbl) + (size_t)h->size * sizeof(mrb_method_t);
303 void
304 mrb_gc_free_mt(mrb_state *mrb, struct RClass *c)
306 if (c->mt) mt_free(mrb, c->mt);
309 void
310 mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
312 mrb_value name;
313 mrb_sym nsym = MRB_SYM(__classname__);
315 if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return;
316 if (outer == NULL || outer == mrb->object_class) {
317 name = mrb_symbol_value(id);
319 else {
320 name = mrb_class_path(mrb, outer);
321 if (mrb_nil_p(name)) { /* unnamed outer class */
322 if (outer != mrb->object_class && outer != c) {
323 mrb_obj_iv_set_force(mrb, (struct RObject*)c, MRB_SYM(__outer__),
324 mrb_obj_value(outer));
326 return;
328 else {
329 mrb_int len;
330 const char *n = mrb_sym_name_len(mrb, id, &len);
332 mrb_str_cat_lit(mrb, name, "::");
333 mrb_str_cat(mrb, name, n, len);
336 mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name);
339 mrb_bool
340 mrb_const_name_p(mrb_state *mrb, const char *name, mrb_int len)
342 return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
345 static void
346 setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
348 mrb_class_name_class(mrb, outer, c, id);
349 mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c));
352 #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
354 static void
355 prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
357 struct RClass *sc, *c;
359 mrb_assert(o->c);
360 if (o->c->tt == MRB_TT_SCLASS) return;
361 sc = MRB_OBJ_ALLOC(mrb, MRB_TT_SCLASS, mrb->class_class);
362 sc->flags |= MRB_FL_CLASS_IS_INHERITED;
363 sc->mt = NULL;
364 sc->iv = NULL;
365 if (o->tt == MRB_TT_CLASS) {
366 c = (struct RClass*)o;
367 if (!c->super) {
368 sc->super = mrb->class_class;
370 else {
371 sc->super = c->super->c;
374 else if (o->tt == MRB_TT_SCLASS) {
375 c = (struct RClass*)o;
376 while (c->super->tt == MRB_TT_ICLASS)
377 c = c->super;
378 make_metaclass(mrb, c->super);
379 sc->super = c->super->c;
381 else {
382 sc->super = o->c;
383 prepare_singleton_class(mrb, (struct RBasic*)sc);
385 o->c = sc;
386 mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc);
387 mrb_obj_iv_set(mrb, (struct RObject*)sc, MRB_SYM(__attached__), mrb_obj_value(o));
388 sc->flags |= o->flags & MRB_FL_OBJ_IS_FROZEN;
391 static mrb_value
392 class_name_str(mrb_state *mrb, struct RClass* c)
394 mrb_value path = mrb_class_path(mrb, c);
395 if (mrb_nil_p(path)) {
396 path = c->tt == MRB_TT_MODULE ? mrb_str_new_lit(mrb, "#<Module:") :
397 mrb_str_new_lit(mrb, "#<Class:");
398 mrb_str_cat_str(mrb, path, mrb_ptr_to_str(mrb, c));
399 mrb_str_cat_lit(mrb, path, ">");
401 return path;
404 static struct RClass*
405 class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
407 mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
409 mrb_check_type(mrb, c, MRB_TT_CLASS);
410 return mrb_class_ptr(c);
413 static struct RClass*
414 module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
416 mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
418 mrb_check_type(mrb, c, MRB_TT_MODULE);
419 return mrb_class_ptr(c);
422 static mrb_bool
423 class_ptr_p(mrb_value obj)
425 switch (mrb_type(obj)) {
426 case MRB_TT_CLASS:
427 case MRB_TT_SCLASS:
428 case MRB_TT_MODULE:
429 return TRUE;
430 default:
431 return FALSE;
435 static void
436 check_if_class_or_module(mrb_state *mrb, mrb_value obj)
438 if (!class_ptr_p(obj)) {
439 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class/module", obj);
443 static struct RClass*
444 define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer)
446 struct RClass *m;
448 if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
449 return module_from_sym(mrb, outer, name);
451 m = mrb_module_new(mrb);
452 setup_class(mrb, outer, m, name);
454 return m;
457 MRB_API struct RClass*
458 mrb_define_module_id(mrb_state *mrb, mrb_sym name)
460 return define_module(mrb, name, mrb->object_class);
463 MRB_API struct RClass*
464 mrb_define_module(mrb_state *mrb, const char *name)
466 return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class);
469 struct RClass*
470 mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id)
472 check_if_class_or_module(mrb, outer);
473 if (mrb_const_defined_at(mrb, outer, id)) {
474 mrb_value old = mrb_const_get(mrb, outer, id);
476 if (!mrb_module_p(old)) {
477 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old);
479 return mrb_class_ptr(old);
481 return define_module(mrb, id, mrb_class_ptr(outer));
484 MRB_API struct RClass*
485 mrb_define_module_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
487 struct RClass * c = define_module(mrb, name, outer);
489 setup_class(mrb, outer, c, name);
490 return c;
493 MRB_API struct RClass*
494 mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
496 mrb_sym id = mrb_intern_cstr(mrb, name);
497 struct RClass * c = define_module(mrb, id, outer);
499 setup_class(mrb, outer, c, id);
500 return c;
503 static struct RClass*
504 find_origin(struct RClass *c)
506 MRB_CLASS_ORIGIN(c);
507 return c;
510 static struct RClass*
511 define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer)
513 struct RClass * c;
515 if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
516 c = class_from_sym(mrb, outer, name);
517 MRB_CLASS_ORIGIN(c);
518 if (super && mrb_class_real(c->super) != super) {
519 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %n (%C not %C)",
520 name, c->super, super);
522 return c;
525 c = mrb_class_new(mrb, super);
526 setup_class(mrb, outer, c, name);
528 return c;
531 MRB_API struct RClass*
532 mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
534 if (!super) {
535 mrb_warn(mrb, "no super class for '%n', Object assumed", name);
537 return define_class(mrb, name, super, mrb->object_class);
540 MRB_API struct RClass*
541 mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
543 return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
546 static mrb_value mrb_do_nothing(mrb_state *mrb, mrb_value);
547 #ifndef MRB_NO_METHOD_CACHE
548 static void mc_clear(mrb_state *mrb);
549 static void mc_clear_by_id(mrb_state *mrb, mrb_sym mid);
550 #else
551 #define mc_clear(mrb)
552 #define mc_clear_by_id(mrb,mid)
553 #endif
555 static void
556 mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
558 mrb_value s;
559 mrb_sym mid;
561 if (!super)
562 super = mrb->object_class;
563 super->flags |= MRB_FL_CLASS_IS_INHERITED;
564 s = mrb_obj_value(super);
565 mid = MRB_SYM(inherited);
566 if (!mrb_func_basic_p(mrb, s, mid, mrb_do_nothing)) {
567 mrb_value c = mrb_obj_value(klass);
568 mrb_funcall_argv(mrb, s, mid, 1, &c);
572 struct RClass*
573 mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
575 struct RClass *s;
576 struct RClass *c;
578 if (!mrb_nil_p(super)) {
579 if (!mrb_class_p(super)) {
580 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super);
582 s = mrb_class_ptr(super);
584 else {
585 s = NULL;
587 check_if_class_or_module(mrb, outer);
588 if (mrb_const_defined_at(mrb, outer, id)) {
589 mrb_value old = mrb_const_get(mrb, outer, id);
591 if (!mrb_class_p(old)) {
592 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old);
594 c = mrb_class_ptr(old);
595 if (s) {
596 /* check super class */
597 if (mrb_class_real(c->super) != s) {
598 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %v", old);
601 return c;
603 c = define_class(mrb, id, s, mrb_class_ptr(outer));
604 mrb_class_inherited(mrb, mrb_class_real(c->super), c);
606 return c;
609 MRB_API mrb_bool
610 mrb_class_defined(mrb_state *mrb, const char *name)
612 mrb_sym sym = mrb_intern_check_cstr(mrb, name);
613 if (!sym) return FALSE;
614 return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), sym);
617 MRB_API mrb_bool
618 mrb_class_defined_id(mrb_state *mrb, mrb_sym name)
620 return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), name);
623 MRB_API mrb_bool
624 mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name)
626 mrb_sym sym = mrb_intern_check_cstr(mrb, name);
627 if (!sym) return FALSE;
628 return mrb_const_defined_at(mrb, mrb_obj_value(outer), sym);
631 MRB_API mrb_bool
632 mrb_class_defined_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
634 return mrb_const_defined_at(mrb, mrb_obj_value(outer), name);
637 MRB_API struct RClass*
638 mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
640 return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
643 MRB_API struct RClass*
644 mrb_class_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
646 return class_from_sym(mrb, outer, name);
649 MRB_API struct RClass*
650 mrb_class_get(mrb_state *mrb, const char *name)
652 return mrb_class_get_under(mrb, mrb->object_class, name);
655 MRB_API struct RClass*
656 mrb_class_get_id(mrb_state *mrb, mrb_sym name)
658 return mrb_class_get_under_id(mrb, mrb->object_class, name);
661 MRB_API struct RClass*
662 mrb_exc_get_id(mrb_state *mrb, mrb_sym name)
664 struct RClass *exc, *e;
665 mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), name);
667 if (!mrb_class_p(c)) {
668 mrb_raise(mrb, E_EXCEPTION, "exception corrupted");
670 exc = e = mrb_class_ptr(c);
672 while (e) {
673 if (e == E_EXCEPTION)
674 return exc;
675 e = e->super;
677 return E_EXCEPTION;
680 MRB_API struct RClass*
681 mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
683 return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
686 MRB_API struct RClass*
687 mrb_module_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
689 return module_from_sym(mrb, outer, name);
692 MRB_API struct RClass*
693 mrb_module_get(mrb_state *mrb, const char *name)
695 return mrb_module_get_under(mrb, mrb->object_class, name);
698 MRB_API struct RClass*
699 mrb_module_get_id(mrb_state *mrb, mrb_sym name)
701 return mrb_module_get_under_id(mrb, mrb->object_class, name);
705 * Defines a class under the namespace of \a outer.
706 * \param outer a class which contains the new class.
707 * \param name name of the new class
708 * \param super a class from which the new class will derive.
709 * NULL means \c Object class.
710 * \return the created class
711 * \throw TypeError if the constant name \a name is already taken but
712 * the constant is not a \c Class.
713 * \throw NameError if the class is already defined but the class can not
714 * be reopened because its superclass is not \a super.
715 * \post top-level constant named \a name refers the returned class.
717 * \note if a class named \a name is already defined and its superclass is
718 * \a super, the function just returns the defined class.
720 MRB_API struct RClass*
721 mrb_define_class_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name, struct RClass *super)
723 struct RClass * c;
725 #if 0
726 if (!super) {
727 mrb_warn(mrb, "no super class for '%C::%n', Object assumed", outer, id);
729 #endif
730 c = define_class(mrb, name, super, outer);
731 setup_class(mrb, outer, c, name);
732 return c;
735 MRB_API struct RClass*
736 mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
738 return mrb_define_class_under_id(mrb, outer, mrb_intern_cstr(mrb, name), super);
741 MRB_API void
742 mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_t m)
744 mt_tbl *h;
745 union mt_ptr ptr;
747 MRB_CLASS_ORIGIN(c);
748 h = c->mt;
749 if (c->tt == MRB_TT_SCLASS && mrb_frozen_p(c)) {
750 mrb_value v = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__));
751 mrb_check_frozen_value(mrb, v);
753 else {
754 mrb_check_frozen(mrb, c);
756 if (!h) h = c->mt = mt_new(mrb);
757 if (MRB_METHOD_PROC_P(m)) {
758 struct RProc *p = MRB_METHOD_PROC(m);
760 ptr.proc = p;
761 if (p) {
762 if (p->color != MRB_GC_RED) {
763 p->flags |= MRB_PROC_SCOPE;
764 p->c = NULL;
765 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p);
766 if (!MRB_PROC_ENV_P(p)) {
767 MRB_PROC_SET_TARGET_CLASS(p, c);
770 else {
771 mrb_assert(MRB_FROZEN_P(p) && MRB_PROC_SCOPE_P(p));
772 mrb_assert(p->c == NULL && p->upper == NULL && p->e.target_class == NULL);
776 else {
777 ptr.func = MRB_METHOD_FUNC(m);
779 mt_put(mrb, h, mid, MT_FLAGS(MRB_METHOD_FUNC_P(m), MRB_METHOD_NOARG_P(m)), ptr);
780 mc_clear_by_id(mrb, mid);
783 MRB_API void
784 mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
786 mrb_method_t m;
787 int ai = mrb_gc_arena_save(mrb);
789 MRB_METHOD_FROM_FUNC(m, func);
790 if (aspec == MRB_ARGS_NONE()) {
791 MRB_METHOD_NOARG_SET(m);
793 mrb_define_method_raw(mrb, c, mid, m);
794 mrb_gc_arena_restore(mrb, ai);
797 MRB_API void
798 mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
800 mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
803 /* a function to raise NotImplementedError with current method name */
804 MRB_API void
805 mrb_notimplement(mrb_state *mrb)
807 mrb_callinfo *ci = mrb->c->ci;
809 if (ci->mid) {
810 mrb_raisef(mrb, E_NOTIMP_ERROR, "%n() function is unimplemented on this machine", ci->mid);
814 /* a function to be replacement of unimplemented method */
815 MRB_API mrb_value
816 mrb_notimplement_m(mrb_state *mrb, mrb_value self)
818 mrb_notimplement(mrb);
819 /* not reached */
820 return mrb_nil_value();
823 static void
824 ensure_class_type(mrb_state *mrb, mrb_value val)
826 if (!class_ptr_p(val)) {
827 mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", val);
831 #define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss)
833 MRB_API mrb_int
834 mrb_get_argc(mrb_state *mrb)
836 mrb_int argc = mrb->c->ci->n;
838 if (argc == 15) {
839 struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]);
841 argc = ARY_LEN(a);
843 return argc;
846 MRB_API const mrb_value*
847 mrb_get_argv(mrb_state *mrb)
849 mrb_int argc = mrb->c->ci->n;
850 mrb_value *array_argv = mrb->c->ci->stack + 1;
851 if (argc == 15) {
852 struct RArray *a = mrb_ary_ptr(*array_argv);
854 array_argv = ARY_PTR(a);
856 return array_argv;
859 MRB_API mrb_value
860 mrb_get_arg1(mrb_state *mrb)
862 mrb_callinfo *ci = mrb->c->ci;
863 mrb_int argc = ci->n;
864 mrb_value *array_argv = ci->stack + 1;
865 if (argc == 15) {
866 struct RArray *a = mrb_ary_ptr(*array_argv);
868 argc = ARY_LEN(a);
869 array_argv = ARY_PTR(a);
871 if (argc == 0 && ci->nk == 15) {
872 mrb_int n = ci->n;
873 if (n == 15) n = 1;
874 return ci->stack[n+1]; /* kwhash next to positional arguments */
876 if (argc != 1) {
877 mrb_argnum_error(mrb, argc, 1, 1);
879 return array_argv[0];
882 MRB_API mrb_bool
883 mrb_block_given_p(mrb_state *mrb)
885 mrb_callinfo *ci = mrb->c->ci;
886 mrb_value b = ci->stack[mrb_ci_bidx(ci)];
888 return !mrb_nil_p(b);
891 #define GET_ARG(_type) (ptr ? ((_type)(*ptr++)) : va_arg((*ap), _type))
893 static mrb_int
894 get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap)
896 const char *fmt = format;
897 char c;
898 mrb_int i = 0;
899 mrb_callinfo *ci = mrb->c->ci;
900 mrb_int argc = ci->n;
901 const mrb_value *argv = ci->stack+1;
902 mrb_bool argv_on_stack;
903 mrb_bool opt = FALSE;
904 mrb_bool opt_skip = TRUE;
905 const mrb_value *pickarg = NULL; /* arguments currently being processed */
906 mrb_value kdict = mrb_nil_value();
907 mrb_bool reqkarg = FALSE;
908 int argc_min = 0, argc_max = 0;
910 while ((c = *fmt++)) {
911 switch (c) {
912 case '|':
913 opt = TRUE;
914 break;
915 case '*':
916 opt_skip = FALSE;
917 argc_max = -1;
918 if (!reqkarg) reqkarg = strchr(fmt, ':') ? TRUE : FALSE;
919 goto check_exit;
920 case '!':
921 case '+':
922 break;
923 case ':':
924 reqkarg = TRUE;
925 /* fall through */
926 case '&': case '?':
927 if (opt) opt_skip = FALSE;
928 break;
929 default:
930 if (!opt) argc_min++;
931 argc_max++;
932 break;
936 check_exit:
937 if (!reqkarg && ci->nk > 0) {
938 mrb_assert(ci->nk == 15);
939 kdict = ci->stack[mrb_ci_bidx(ci)-1];
940 if (mrb_hash_p(kdict) && mrb_hash_size(mrb, kdict) > 0) {
941 if (argc < 14) {
942 ci->n++;
943 argc++; /* include kdict in normal arguments */
945 else {
946 /* 14+1 == 15 so pack first */
947 if (argc == 14) {
948 /* pack arguments and kdict */
949 ci->stack[1] = mrb_ary_new_from_values(mrb, argc+1, &ci->stack[1]);
950 argc = ci->n = 15;
952 else {
953 /* push kdict to packed arguments */
954 mrb_ary_push(mrb, ci->stack[1], kdict);
956 ci->stack[2] = ci->stack[mrb_ci_bidx(ci)];
958 ci->nk = 0;
961 if (reqkarg && ci->nk > 0) {
962 kdict = ci->stack[mrb_ci_bidx(ci)-1];
963 mrb_assert(ci->nk == 15);
964 mrb_assert(mrb_hash_p(kdict));
967 argv_on_stack = argc < 15;
968 if (!argv_on_stack) {
969 struct RArray *a = mrb_ary_ptr(*argv);
970 argv = ARY_PTR(a);
971 argc = ARY_LEN(a);
974 opt = FALSE;
975 i = 0;
976 while ((c = *format++)) {
977 mrb_bool altmode = FALSE;
978 mrb_bool needmodify = FALSE;
980 for (; *format; format++) {
981 switch (*format) {
982 case '!':
983 if (altmode) goto modifier_exit; /* not accept for multiple '!' */
984 altmode = TRUE;
985 break;
986 case '+':
987 if (needmodify) goto modifier_exit; /* not accept for multiple '+' */
988 needmodify = TRUE;
989 break;
990 default:
991 goto modifier_exit;
995 modifier_exit:
996 switch (c) {
997 case '|': case '*': case '&': case '?': case ':':
998 if (needmodify) {
999 bad_needmodify:
1000 mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong `%c+` modified specifier`", c);
1002 break;
1003 default:
1004 if (i < argc) {
1005 pickarg = &argv[i++];
1006 if (needmodify && !mrb_nil_p(*pickarg)) {
1007 mrb_check_frozen_value(mrb, *pickarg);
1010 else {
1011 if (opt) {
1012 pickarg = NULL;
1014 else {
1015 mrb_argnum_error(mrb, argc, argc_min, argc_max);
1018 break;
1021 switch (c) {
1022 case 'o':
1023 case 'C':
1024 case 'S':
1025 case 'A':
1026 case 'H':
1028 mrb_value *p;
1030 p = GET_ARG(mrb_value*);
1031 if (pickarg) {
1032 if (!(altmode && mrb_nil_p(*pickarg))) {
1033 switch (c) {
1034 case 'C': ensure_class_type(mrb, *pickarg); break;
1035 case 'S': mrb_ensure_string_type(mrb, *pickarg); break;
1036 case 'A': mrb_ensure_array_type(mrb, *pickarg); break;
1037 case 'H': mrb_ensure_hash_type(mrb, *pickarg); break;
1040 *p = *pickarg;
1043 break;
1044 case 'c':
1046 struct RClass **p;
1048 p = GET_ARG(struct RClass**);
1049 if (pickarg) {
1050 if (altmode && mrb_nil_p(*pickarg)) {
1051 *p = NULL;
1053 else {
1054 ensure_class_type(mrb, *pickarg);
1055 *p = mrb_class_ptr(*pickarg);
1059 break;
1060 case 's':
1062 const char **ps = NULL;
1063 mrb_int *pl = NULL;
1065 ps = GET_ARG(const char**);
1066 pl = GET_ARG(mrb_int*);
1067 if (needmodify) goto bad_needmodify;
1068 if (pickarg) {
1069 if (altmode && mrb_nil_p(*pickarg)) {
1070 *ps = NULL;
1071 *pl = 0;
1073 else {
1074 mrb_ensure_string_type(mrb, *pickarg);
1075 *ps = RSTRING_PTR(*pickarg);
1076 *pl = RSTRING_LEN(*pickarg);
1080 break;
1081 case 'z':
1083 const char **ps;
1085 ps = GET_ARG(const char**);
1086 if (needmodify) goto bad_needmodify;
1087 if (pickarg) {
1088 if (altmode && mrb_nil_p(*pickarg)) {
1089 *ps = NULL;
1091 else {
1092 mrb_ensure_string_type(mrb, *pickarg);
1093 *ps = RSTRING_CSTR(mrb, *pickarg);
1097 break;
1098 case 'a':
1100 struct RArray *a;
1101 const mrb_value **pb;
1102 mrb_int *pl;
1104 pb = GET_ARG(const mrb_value**);
1105 pl = GET_ARG(mrb_int*);
1106 if (needmodify) goto bad_needmodify;
1107 if (pickarg) {
1108 if (altmode && mrb_nil_p(*pickarg)) {
1109 *pb = NULL;
1110 *pl = 0;
1112 else {
1113 mrb_ensure_array_type(mrb, *pickarg);
1114 a = mrb_ary_ptr(*pickarg);
1115 *pb = ARY_PTR(a);
1116 *pl = ARY_LEN(a);
1120 break;
1121 #ifndef MRB_NO_FLOAT
1122 case 'f':
1124 mrb_float *p;
1126 p = GET_ARG(mrb_float*);
1127 if (pickarg) {
1128 *p = mrb_as_float(mrb, *pickarg);
1131 break;
1132 #endif
1133 case 'i':
1135 mrb_int *p;
1137 p = GET_ARG(mrb_int*);
1138 if (pickarg) {
1139 *p = mrb_as_int(mrb, *pickarg);
1142 break;
1143 case 'b':
1145 mrb_bool *boolp = GET_ARG(mrb_bool*);
1147 if (pickarg) {
1148 *boolp = mrb_test(*pickarg);
1151 break;
1152 case 'n':
1154 mrb_sym *symp;
1156 symp = GET_ARG(mrb_sym*);
1157 if (pickarg) {
1158 *symp = to_sym(mrb, *pickarg);
1161 break;
1162 case 'd':
1164 void** datap;
1165 struct mrb_data_type const* type;
1167 datap = GET_ARG(void**);
1168 type = GET_ARG(struct mrb_data_type const*);
1169 if (pickarg) {
1170 if (altmode && mrb_nil_p(*pickarg)) {
1171 *datap = NULL;
1173 else {
1174 *datap = mrb_data_get_ptr(mrb, *pickarg, type);
1178 break;
1180 case '&':
1182 mrb_value *p, *bp;
1184 p = GET_ARG(mrb_value*);
1185 bp = ci->stack + mrb_ci_bidx(ci);
1186 if (altmode && mrb_nil_p(*bp)) {
1187 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
1189 *p = *bp;
1191 break;
1192 case '|':
1193 if (opt_skip && i == argc) goto finish;
1194 opt = TRUE;
1195 break;
1196 case '?':
1198 mrb_bool *p;
1200 p = GET_ARG(mrb_bool*);
1201 *p = pickarg ? TRUE : FALSE;
1203 break;
1205 case '*':
1207 const mrb_value **var;
1208 mrb_int *pl;
1209 mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE;
1211 var = GET_ARG(const mrb_value**);
1212 pl = GET_ARG(mrb_int*);
1213 if (argc > i) {
1214 *pl = argc-i;
1215 if (*pl > 0) {
1216 if (nocopy) {
1217 *var = argv+i;
1219 else {
1220 mrb_value args = mrb_ary_new_from_values(mrb, *pl, argv+i);
1221 RARRAY(args)->c = NULL;
1222 *var = RARRAY_PTR(args);
1225 i = argc;
1227 else {
1228 *pl = 0;
1229 *var = NULL;
1232 break;
1234 case ':':
1236 mrb_value ksrc = mrb_hash_p(kdict) ? mrb_hash_dup(mrb, kdict) : mrb_hash_new(mrb);
1237 const mrb_kwargs *kwargs = GET_ARG(const mrb_kwargs*);
1238 mrb_value *rest;
1240 if (kwargs == NULL) {
1241 rest = NULL;
1243 else {
1244 mrb_int kwnum = kwargs->num;
1245 mrb_int required = kwargs->required;
1246 const mrb_sym *kname = kwargs->table;
1247 mrb_value *values = kwargs->values;
1248 mrb_int j;
1249 const mrb_int keyword_max = 40;
1251 mrb_assert(kwnum >= 0);
1252 mrb_assert(required >= 0);
1253 if (kwnum > keyword_max || required > kwnum) {
1254 mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large");
1257 for (j = required; j > 0; j--, kname++, values++) {
1258 mrb_value k = mrb_symbol_value(*kname);
1259 if (!mrb_hash_key_p(mrb, ksrc, k)) {
1260 mrb_raisef(mrb, E_ARGUMENT_ERROR, "missing keyword: %n", *kname);
1262 *values = mrb_hash_delete_key(mrb, ksrc, k);
1263 mrb_gc_protect(mrb, *values);
1266 for (j = kwnum - required; j > 0; j--, kname++, values++) {
1267 mrb_value k = mrb_symbol_value(*kname);
1268 if (mrb_hash_key_p(mrb, ksrc, k)) {
1269 *values = mrb_hash_delete_key(mrb, ksrc, k);
1270 mrb_gc_protect(mrb, *values);
1272 else {
1273 *values = mrb_undef_value();
1277 rest = kwargs->rest;
1280 if (rest) {
1281 *rest = ksrc;
1283 else if (!mrb_hash_empty_p(mrb, ksrc)) {
1284 ksrc = mrb_hash_keys(mrb, ksrc);
1285 ksrc = RARRAY_PTR(ksrc)[0];
1286 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown keyword: %v", ksrc);
1289 break;
1291 default:
1292 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c);
1293 break;
1297 if (!c && argc > i) {
1298 mrb_argnum_error(mrb, argc, argc_min, argc_max);
1301 finish:
1302 return i;
1306 retrieve arguments from mrb_state.
1308 mrb_get_args(mrb, format, ...)
1310 returns number of arguments parsed.
1312 format specifiers:
1314 string mruby type C type note
1315 ----------------------------------------------------------------------------------------------
1316 o: Object [mrb_value]
1317 C: Class/Module [mrb_value] when ! follows, the value may be nil
1318 S: String [mrb_value] when ! follows, the value may be nil
1319 A: Array [mrb_value] when ! follows, the value may be nil
1320 H: Hash [mrb_value] when ! follows, the value may be nil
1321 s: String [const char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil
1322 z: String [const char*] NUL terminated string; z! gives NULL for nil
1323 a: Array [const mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil
1324 c: Class/Module [struct RClass*] c! gives NULL for nil
1325 f: Integer/Float [mrb_float]
1326 i: Integer/Float [mrb_int]
1327 b: boolean [mrb_bool]
1328 n: String/Symbol [mrb_sym]
1329 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
1330 &: block [mrb_value] &! raises exception if no block given
1331 *: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
1332 |: optional Following arguments are optional
1333 ?: optional given [mrb_bool] true if preceding argument (optional) is given
1334 ':': keyword args [mrb_kwargs const] Get keyword arguments
1336 format modifiers:
1338 string note
1339 ----------------------------------------------------------------------------------------------
1340 !: Switch to the alternate mode; The behaviour changes depending on the specifier
1341 +: Request a not frozen object; However, except nil value
1343 MRB_API mrb_int
1344 mrb_get_args(mrb_state *mrb, mrb_args_format format, ...)
1346 va_list ap;
1347 va_start(ap, format);
1348 mrb_int rc = get_args_v(mrb, format, NULL, &ap);
1349 va_end(ap);
1350 return rc;
1353 MRB_API mrb_int
1354 mrb_get_args_a(mrb_state *mrb, mrb_args_format format, void **args)
1356 return get_args_v(mrb, format, args, NULL);
1359 static struct RClass*
1360 boot_defclass(mrb_state *mrb, struct RClass *super)
1362 struct RClass *c;
1364 c = MRB_OBJ_ALLOC(mrb, MRB_TT_CLASS, mrb->class_class);
1365 if (super) {
1366 c->super = super;
1367 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
1368 c->flags |= MRB_FL_CLASS_IS_INHERITED;
1370 else {
1371 c->super = mrb->object_class;
1373 c->mt = mt_new(mrb);
1374 return c;
1377 static void
1378 boot_initmod(mrb_state *mrb, struct RClass *mod)
1380 if (!mod->mt) {
1381 mod->mt = mt_new(mrb);
1385 static struct RClass*
1386 include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super)
1388 struct RClass *ic = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, mrb->class_class);
1389 if (m->tt == MRB_TT_ICLASS) {
1390 m = m->c;
1392 MRB_CLASS_ORIGIN(m);
1393 ic->mt = m->mt;
1394 ic->super = super;
1395 if (m->tt == MRB_TT_ICLASS) {
1396 ic->c = m->c;
1398 else {
1399 ic->c = m;
1401 return ic;
1404 static int
1405 include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super)
1407 struct RClass *p, *ic;
1408 void *klass_mt = find_origin(c)->mt;
1410 while (m) {
1411 int original_seen = FALSE;
1412 int superclass_seen = FALSE;
1414 if (c == ins_pos) original_seen = TRUE;
1415 if (m->flags & MRB_FL_CLASS_IS_PREPENDED)
1416 goto skip;
1418 if (klass_mt && klass_mt == m->mt)
1419 return -1;
1421 p = c->super;
1422 while (p) {
1423 if (c == p) original_seen = TRUE;
1424 if (p->tt == MRB_TT_ICLASS) {
1425 if (p->mt == m->mt) {
1426 if (!superclass_seen && original_seen) {
1427 ins_pos = p; /* move insert point */
1429 goto skip;
1432 else if (p->tt == MRB_TT_CLASS) {
1433 if (!search_super) break;
1434 superclass_seen = TRUE;
1436 p = p->super;
1439 ic = include_class_new(mrb, m, ins_pos->super);
1440 m->flags |= MRB_FL_CLASS_IS_INHERITED;
1441 ins_pos->super = ic;
1442 mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
1443 ins_pos = ic;
1444 skip:
1445 m = m->super;
1447 mc_clear(mrb);
1448 return 0;
1451 static int
1452 fix_include_module(mrb_state *mrb, struct RBasic *obj, void *data)
1454 struct RClass **m = (struct RClass**)data;
1456 if (obj->tt == MRB_TT_ICLASS && obj->c == m[0] && !MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) {
1457 struct RClass *ic = (struct RClass*)obj;
1458 include_module_at(mrb, ic, ic, m[1], 1);
1460 return MRB_EACH_OBJ_OK;
1463 MRB_API void
1464 mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
1466 mrb_check_frozen(mrb, c);
1467 if (include_module_at(mrb, c, find_origin(c), m, 1) < 0) {
1468 mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
1470 if (c->tt == MRB_TT_MODULE && (c->flags & MRB_FL_CLASS_IS_INHERITED)) {
1471 struct RClass *data[2];
1472 data[0] = c;
1473 data[1] = m;
1474 mrb_objspace_each_objects(mrb, fix_include_module, data);
1478 static int
1479 fix_prepend_module(mrb_state *mrb, struct RBasic *obj, void *data)
1481 struct RClass **m = (struct RClass**)data;
1482 struct RClass *c = (struct RClass*)obj;
1484 if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) {
1485 struct RClass *p = c->super;
1486 struct RClass *ins_pos = c;
1487 while (p) {
1488 if (c == m[0]) break;
1489 if (p == m[0]->super->c) {
1490 ins_pos = c;
1492 if (p->tt == MRB_TT_CLASS) break;
1493 if (p->c == m[0]) {
1494 include_module_at(mrb, ins_pos, ins_pos, m[1], 0);
1495 break;
1497 c = p;
1498 p = p->super;
1501 return MRB_EACH_OBJ_OK;
1504 MRB_API void
1505 mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
1507 struct RClass *origin;
1509 mrb_check_frozen(mrb, c);
1510 if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
1511 origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c);
1512 origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED;
1513 origin->super = c->super;
1514 c->super = origin;
1515 origin->mt = c->mt;
1516 c->mt = NULL;
1517 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin);
1518 c->flags |= MRB_FL_CLASS_IS_PREPENDED;
1520 if (include_module_at(mrb, c, c, m, 0) < 0) {
1521 mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected");
1523 if (c->tt == MRB_TT_MODULE &&
1524 (c->flags & (MRB_FL_CLASS_IS_INHERITED|MRB_FL_CLASS_IS_PREPENDED))) {
1525 struct RClass *data[2];
1526 data[0] = c;
1527 data[1] = m;
1528 mrb_objspace_each_objects(mrb, fix_prepend_module, data);
1532 static mrb_value
1533 mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod)
1535 struct RClass *c;
1537 mrb_check_type(mrb, mod, MRB_TT_MODULE);
1538 mrb_get_args(mrb, "c", &c);
1539 mrb_prepend_module(mrb, c, mrb_class_ptr(mod));
1540 return mod;
1543 static mrb_value
1544 mrb_mod_append_features(mrb_state *mrb, mrb_value mod)
1546 struct RClass *c;
1548 mrb_check_type(mrb, mod, MRB_TT_MODULE);
1549 mrb_get_args(mrb, "c", &c);
1550 mrb_include_module(mrb, c, mrb_class_ptr(mod));
1551 return mod;
1554 /* 15.2.2.4.28 */
1556 * call-seq:
1557 * mod.include?(module) -> true or false
1559 * Returns <code>true</code> if <i>module</i> is included in
1560 * <i>mod</i> or one of <i>mod</i>'s ancestors.
1562 * module A
1563 * end
1564 * class B
1565 * include A
1566 * end
1567 * class C < B
1568 * end
1569 * B.include?(A) #=> true
1570 * C.include?(A) #=> true
1571 * A.include?(A) #=> false
1573 static mrb_value
1574 mrb_mod_include_p(mrb_state *mrb, mrb_value mod)
1576 mrb_value mod2;
1577 struct RClass *c = mrb_class_ptr(mod);
1579 mrb_get_args(mrb, "C", &mod2);
1580 mrb_check_type(mrb, mod2, MRB_TT_MODULE);
1582 while (c) {
1583 if (c->tt == MRB_TT_ICLASS) {
1584 if (c->c == mrb_class_ptr(mod2)) return mrb_true_value();
1586 c = c->super;
1588 return mrb_false_value();
1591 static mrb_value
1592 mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
1594 mrb_value result;
1595 struct RClass *c = mrb_class_ptr(self);
1596 result = mrb_ary_new(mrb);
1597 while (c) {
1598 if (c->tt == MRB_TT_ICLASS) {
1599 mrb_ary_push(mrb, result, mrb_obj_value(c->c));
1601 else if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
1602 mrb_ary_push(mrb, result, mrb_obj_value(c));
1604 c = c->super;
1607 return result;
1610 static mrb_value
1611 mrb_mod_extend_object(mrb_state *mrb, mrb_value mod)
1613 mrb_value obj = mrb_get_arg1(mrb);
1615 mrb_check_type(mrb, mod, MRB_TT_MODULE);
1616 mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod));
1617 return mod;
1620 static mrb_value
1621 mrb_mod_initialize(mrb_state *mrb, mrb_value mod)
1623 mrb_value b;
1624 struct RClass *m = mrb_class_ptr(mod);
1625 boot_initmod(mrb, m); /* bootstrap a newly initialized module */
1626 mrb_get_args(mrb, "|&", &b);
1627 if (!mrb_nil_p(b)) {
1628 mrb_yield_with_class(mrb, b, 1, &mod, mod, m);
1630 return mod;
1633 static mrb_value
1634 mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod)
1636 return mod;
1639 MRB_API struct RClass*
1640 mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v)
1642 struct RBasic *obj;
1644 switch (mrb_type(v)) {
1645 case MRB_TT_FALSE:
1646 if (mrb_nil_p(v))
1647 return mrb->nil_class;
1648 return mrb->false_class;
1649 case MRB_TT_TRUE:
1650 return mrb->true_class;
1651 case MRB_TT_CPTR:
1652 case MRB_TT_SYMBOL:
1653 case MRB_TT_INTEGER:
1654 #ifndef MRB_NO_FLOAT
1655 case MRB_TT_FLOAT:
1656 #endif
1657 return NULL;
1658 default:
1659 break;
1661 obj = mrb_basic_ptr(v);
1662 if (obj->c == NULL) return NULL;
1663 prepare_singleton_class(mrb, obj);
1664 return obj->c;
1667 MRB_API mrb_value
1668 mrb_singleton_class(mrb_state *mrb, mrb_value v)
1670 struct RClass *c = mrb_singleton_class_ptr(mrb, v);
1672 if (c == NULL) {
1673 mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
1675 return mrb_obj_value(c);
1678 MRB_API void
1679 mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
1681 prepare_singleton_class(mrb, (struct RBasic*)o);
1682 mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec);
1685 MRB_API void
1686 mrb_define_singleton_method_id(mrb_state *mrb, struct RObject *o, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
1688 prepare_singleton_class(mrb, (struct RBasic*)o);
1689 mrb_define_method_id(mrb, o->c, name, func, aspec);
1692 MRB_API void
1693 mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1695 mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec);
1698 MRB_API void
1699 mrb_define_class_method_id(mrb_state *mrb, struct RClass *c, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
1701 mrb_define_singleton_method_id(mrb, (struct RObject*)c, name, func, aspec);
1704 MRB_API void
1705 mrb_define_module_function_id(mrb_state *mrb, struct RClass *c, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
1707 mrb_define_class_method_id(mrb, c, name, func, aspec);
1708 mrb_define_method_id(mrb, c, name, func, aspec);
1711 MRB_API void
1712 mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1714 mrb_define_module_function_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
1717 #ifndef MRB_NO_METHOD_CACHE
1718 /* clear whole method cache table */
1719 static void
1720 mc_clear(mrb_state *mrb)
1722 static const struct mrb_cache_entry ce_zero ={0};
1724 for (int i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
1725 mrb->cache[i] = ce_zero;
1729 /* clear method cache for a class */
1730 void
1731 mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c)
1733 struct mrb_cache_entry *mc = mrb->cache;
1735 for (int i=0; i<MRB_METHOD_CACHE_SIZE; mc++,i++) {
1736 if (mc->c == c || mc->c0 == c) mc->c = NULL;
1740 static void
1741 mc_clear_by_id(mrb_state *mrb, mrb_sym id)
1743 struct mrb_cache_entry *mc = mrb->cache;
1745 for (int i=0; i<MRB_METHOD_CACHE_SIZE; mc++,i++) {
1746 if (METHOD_MID(mc->m) == id) mc->c = NULL;
1749 #endif // MRB_NO_METHOD_CACHE
1751 mrb_method_t
1752 mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid)
1754 mrb_method_t m;
1755 #ifndef MRB_NO_METHOD_CACHE
1756 struct RClass *oc = c;
1757 int h = mrb_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
1758 struct mrb_cache_entry *mc = &mrb->cache[h];
1760 if (mc->c == c && METHOD_MID(mc->m) == mid) {
1761 *cp = mc->c0;
1762 return mc->m;
1764 #endif
1766 while (c) {
1767 mt_tbl *h = c->mt;
1769 if (h) {
1770 union mt_ptr ptr;
1771 mrb_sym ret = mt_get(mrb, h, mid, &ptr);
1772 if (ret) {
1773 if (ptr.proc == 0) break;
1774 *cp = c;
1775 m = create_method_value(mrb, ret, ptr);
1776 #ifndef MRB_NO_METHOD_CACHE
1777 mc->c = oc;
1778 mc->c0 = c;
1779 mc->m = m;
1780 #endif
1781 return m;
1784 c = c->super;
1786 MRB_METHOD_FROM_PROC(m, NULL);
1787 return m; /* no method */
1790 MRB_API mrb_method_t
1791 mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
1793 return mrb_vm_find_method(mrb, *cp, cp, mid);
1796 MRB_API mrb_method_t
1797 mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
1799 mrb_method_t m;
1801 m = mrb_method_search_vm(mrb, &c, mid);
1802 if (MRB_METHOD_UNDEF_P(m)) {
1803 mrb_name_error(mrb, mid, "undefined method '%n' for class %C", mid, c);
1805 return m;
1808 #define ONSTACK_ALLOC_MAX 32
1810 static mrb_sym
1811 prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char *suffix)
1813 char onstack[ONSTACK_ALLOC_MAX];
1814 mrb_int sym_len;
1815 const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len);
1816 size_t prefix_len = prefix ? strlen(prefix) : 0;
1817 size_t suffix_len = suffix ? strlen(suffix) : 0;
1818 size_t name_len = sym_len + prefix_len + suffix_len;
1819 char *buf = name_len > sizeof(onstack) ? (char*)mrb_alloca(mrb, name_len) : onstack;
1820 char *p = buf;
1822 if (prefix_len > 0) {
1823 memcpy(p, prefix, prefix_len);
1824 p += prefix_len;
1827 memcpy(p, sym_str, sym_len);
1828 p += sym_len;
1830 if (suffix_len > 0) {
1831 memcpy(p, suffix, suffix_len);
1834 return mrb_intern(mrb, buf, name_len);
1837 static mrb_value
1838 prepare_ivar_name(mrb_state *mrb, mrb_sym sym)
1840 sym = prepare_name_common(mrb, sym, "@", NULL);
1841 mrb_iv_name_sym_check(mrb, sym);
1842 return mrb_symbol_value(sym);
1845 static mrb_sym
1846 prepare_writer_name(mrb_state *mrb, mrb_sym sym)
1848 return prepare_name_common(mrb, sym, NULL, "=");
1851 static mrb_value
1852 mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state *, mrb_value), mrb_sym (*access_name)(mrb_state *, mrb_sym))
1854 struct RClass *c = mrb_class_ptr(mod);
1855 const mrb_value *argv;
1856 mrb_int argc;
1857 int ai;
1859 mrb_get_args(mrb, "*", &argv, &argc);
1860 ai = mrb_gc_arena_save(mrb);
1861 for (int i=0; i<argc; i++) {
1862 mrb_value name;
1863 mrb_sym method;
1864 struct RProc *p;
1865 mrb_method_t m;
1867 method = to_sym(mrb, argv[i]);
1868 name = prepare_ivar_name(mrb, method);
1869 if (access_name) {
1870 method = access_name(mrb, method);
1873 p = mrb_proc_new_cfunc_with_env(mrb, accessor, 1, &name);
1874 MRB_METHOD_FROM_PROC(m, p);
1875 mrb_define_method_raw(mrb, c, method, m);
1876 mrb_gc_arena_restore(mrb, ai);
1878 return mrb_nil_value();
1881 static mrb_value
1882 attr_reader(mrb_state *mrb, mrb_value obj)
1884 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
1885 return mrb_iv_get(mrb, obj, to_sym(mrb, name));
1888 static mrb_value
1889 mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
1891 return mod_attr_define(mrb, mod, attr_reader, NULL);
1894 static mrb_value
1895 attr_writer(mrb_state *mrb, mrb_value obj)
1897 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
1898 mrb_value val = mrb_get_arg1(mrb);
1900 mrb_iv_set(mrb, obj, to_sym(mrb, name), val);
1901 return val;
1904 static mrb_value
1905 mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
1907 return mod_attr_define(mrb, mod, attr_writer, prepare_writer_name);
1910 static mrb_value
1911 mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
1913 struct RClass *c = mrb_class_ptr(cv);
1914 struct RObject *o;
1915 enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
1917 if (c->tt == MRB_TT_SCLASS)
1918 mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");
1920 if (c == mrb->nil_class || c == mrb->false_class) {
1921 mrb_assert(ttype == 0);
1923 else if (ttype == 0) {
1924 ttype = MRB_TT_OBJECT;
1926 if (MRB_UNDEF_ALLOCATOR_P(c)) {
1927 mrb_raisef(mrb, E_TYPE_ERROR, "allocator undefined for %v", cv);
1929 if (ttype <= MRB_TT_CPTR) {
1930 mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv);
1932 o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
1933 return mrb_obj_value(o);
1937 * call-seq:
1938 * class.new(args, ...) -> obj
1940 * Creates a new object of <i>class</i>'s class, then
1941 * invokes that object's <code>initialize</code> method,
1942 * passing it <i>args</i>. This is the method that ends
1943 * up getting called whenever an object is constructed using
1944 * `.new`.
1948 mrb_value
1949 mrb_instance_new(mrb_state *mrb, mrb_value cv)
1951 mrb_value obj, blk;
1952 const mrb_value *argv;
1953 mrb_int argc;
1954 mrb_sym init;
1956 mrb_get_args(mrb, "*!&", &argv, &argc, &blk);
1957 obj = mrb_instance_alloc(mrb, cv);
1958 init = MRB_SYM(initialize);
1959 if (!mrb_func_basic_p(mrb, obj, init, mrb_do_nothing)) {
1960 mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
1962 return obj;
1965 MRB_API mrb_value
1966 mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv)
1968 mrb_value obj;
1969 mrb_sym mid;
1971 obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
1972 mid = MRB_SYM(initialize);
1973 if (!mrb_func_basic_p(mrb, obj, mid, mrb_do_nothing)) {
1974 mrb_funcall_argv(mrb, obj, mid, argc, argv);
1976 return obj;
1979 static mrb_value
1980 mrb_class_initialize(mrb_state *mrb, mrb_value obj)
1982 mrb_value a, b;
1983 struct RClass *c = mrb_class_ptr(obj);
1985 if (c->iv) {
1986 mrb_raise(mrb, E_TYPE_ERROR, "already initialized class");
1988 mrb_get_args(mrb, "|C&", &a, &b);
1989 if (!mrb_nil_p(b)) {
1990 mrb_yield_with_class(mrb, b, 1, &obj, obj, c);
1992 return obj;
1995 static mrb_value
1996 mrb_class_new_class(mrb_state *mrb, mrb_value cv)
1998 mrb_int n;
1999 mrb_value super, blk;
2000 mrb_value new_class;
2001 mrb_sym mid;
2003 n = mrb_get_args(mrb, "|C&", &super, &blk);
2004 if (n == 0) {
2005 super = mrb_obj_value(mrb->object_class);
2007 new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
2008 mid = MRB_SYM(initialize);
2009 if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) {
2010 mrb_class_initialize(mrb, new_class);
2012 else {
2013 mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
2015 mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
2016 return new_class;
2019 static mrb_value
2020 mrb_class_superclass(mrb_state *mrb, mrb_value klass)
2022 struct RClass *c;
2024 c = mrb_class_ptr(klass);
2025 c = find_origin(c)->super;
2026 while (c && c->tt == MRB_TT_ICLASS) {
2027 c = find_origin(c)->super;
2029 if (!c) return mrb_nil_value();
2030 return mrb_obj_value(c);
2033 static mrb_value
2034 mrb_do_nothing(mrb_state *mrb, mrb_value cv)
2036 return mrb_nil_value();
2039 static mrb_value
2040 mrb_bob_not(mrb_state *mrb, mrb_value cv)
2042 return mrb_bool_value(!mrb_test(cv));
2045 /* 15.3.1.3.1 */
2046 /* 15.3.1.3.10 */
2047 /* 15.3.1.3.11 */
2049 * call-seq:
2050 * obj == other -> true or false
2051 * obj.equal?(other) -> true or false
2052 * obj.eql?(other) -> true or false
2054 * Equality---At the <code>Object</code> level, <code>==</code> returns
2055 * <code>true</code> only if <i>obj</i> and <i>other</i> are the
2056 * same object. Typically, this method is overridden in descendant
2057 * classes to provide class-specific meaning.
2059 * Unlike <code>==</code>, the <code>equal?</code> method should never be
2060 * overridden by subclasses: it is used to determine object identity
2061 * (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
2062 * object as <code>b</code>).
2064 * The <code>eql?</code> method returns <code>true</code> if
2065 * <i>obj</i> and <i>anObject</i> have the same value. Used by
2066 * <code>Hash</code> to test members for equality. For objects of
2067 * class <code>Object</code>, <code>eql?</code> is synonymous with
2068 * <code>==</code>. Subclasses normally continue this tradition, but
2069 * there are exceptions. <code>Numeric</code> types, for example,
2070 * perform type conversion across <code>==</code>, but not across
2071 * <code>eql?</code>, so:
2073 * 1 == 1.0 #=> true
2074 * 1.eql? 1.0 #=> false
2076 mrb_value
2077 mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
2079 mrb_value arg = mrb_get_arg1(mrb);
2081 return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
2084 MRB_API mrb_bool
2085 mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid)
2087 mrb_method_t m;
2089 m = mrb_method_search_vm(mrb, &c, mid);
2090 if (MRB_METHOD_UNDEF_P(m)) {
2091 return FALSE;
2093 return TRUE;
2096 MRB_API mrb_bool
2097 mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid)
2099 return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid);
2102 MRB_API mrb_value
2103 mrb_class_path(mrb_state *mrb, struct RClass *c)
2105 mrb_value path;
2106 mrb_sym nsym = MRB_SYM(__classname__);
2108 path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym);
2109 if (mrb_nil_p(path)) {
2110 /* no name (yet) */
2111 return mrb_class_find_path(mrb, c);
2113 else if (mrb_symbol_p(path)) {
2114 /* toplevel class/module */
2115 return mrb_sym_str(mrb, mrb_symbol(path));
2117 return mrb_str_dup(mrb, path);
2120 MRB_API struct RClass*
2121 mrb_class_real(struct RClass* cl)
2123 if (cl == 0) return NULL;
2124 while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) {
2125 cl = cl->super;
2126 if (cl == 0) return NULL;
2128 return cl;
2131 MRB_API const char*
2132 mrb_class_name(mrb_state *mrb, struct RClass* c)
2134 mrb_value name;
2136 if (c == NULL) return NULL;
2137 name = class_name_str(mrb, c);
2138 return RSTRING_PTR(name);
2141 MRB_API const char*
2142 mrb_obj_classname(mrb_state *mrb, mrb_value obj)
2144 return mrb_class_name(mrb, mrb_obj_class(mrb, obj));
2148 * Ensures a class can be derived from super.
2150 * \param super a reference to an object.
2151 * \exception TypeError if \a super is not a Class or \a super is a singleton class.
2153 static void
2154 mrb_check_inheritable(mrb_state *mrb, struct RClass *super)
2156 if (super->tt != MRB_TT_CLASS) {
2157 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%C given)", super);
2159 if (super->tt == MRB_TT_SCLASS) {
2160 mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class");
2162 if (super == mrb->class_class) {
2163 mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class");
2168 * Creates a new class.
2169 * \param super a class from which the new class derives.
2170 * \exception TypeError \a super is not inheritable.
2171 * \exception TypeError \a super is the Class class.
2173 MRB_API struct RClass*
2174 mrb_class_new(mrb_state *mrb, struct RClass *super)
2176 struct RClass *c;
2178 if (super) {
2179 mrb_check_inheritable(mrb, super);
2181 c = boot_defclass(mrb, super);
2182 if (super) {
2183 MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
2184 c->flags |= super->flags & MRB_FL_UNDEF_ALLOCATE;
2186 make_metaclass(mrb, c);
2188 return c;
2192 * Creates a new module.
2194 MRB_API struct RClass*
2195 mrb_module_new(mrb_state *mrb)
2197 struct RClass *m = MRB_OBJ_ALLOC(mrb, MRB_TT_MODULE, mrb->module_class);
2198 boot_initmod(mrb, m);
2199 return m;
2203 * call-seq:
2204 * obj.class => class
2206 * Returns the class of <i>obj</i>, now preferred over
2207 * <code>Object#type</code>, as an object's type in Ruby is only
2208 * loosely tied to that object's class. This method must always be
2209 * called with an explicit receiver, as <code>class</code> is also a
2210 * reserved word in Ruby.
2212 * 1.class #=> Integer
2213 * self.class #=> Object
2216 MRB_API struct RClass*
2217 mrb_obj_class(mrb_state *mrb, mrb_value obj)
2219 return mrb_class_real(mrb_class(mrb, obj));
2222 MRB_API void
2223 mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
2225 if (a == b) return;
2226 mrb_method_t m = mrb_method_search(mrb, c, b);
2228 if (!MRB_METHOD_CFUNC_P(m)) {
2229 struct RProc *p = MRB_METHOD_PROC(m);
2230 if (!MRB_PROC_CFUNC_P(p) && !MRB_PROC_ALIAS_P(p)) {
2231 struct RProc *pnew = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class);
2233 pnew->body.mid = b;
2234 pnew->upper = p;
2235 pnew->e.env = NULL;
2236 pnew->flags |= MRB_PROC_ALIAS;
2237 MRB_METHOD_FROM_PROC(m, pnew);
2240 mrb_define_method_raw(mrb, c, a, m);
2244 * Defines an alias of a method.
2245 * \param mrb the mruby state
2246 * \param klass the class which the original method belongs to
2247 * \param name1 a new name for the method
2248 * \param name2 the original name of the method
2250 MRB_API void
2251 mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
2253 mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
2256 MRB_API void
2257 mrb_define_alias_id(mrb_state *mrb, struct RClass *klass, mrb_sym a, mrb_sym b)
2259 mrb_alias_method(mrb, klass, a, b);
2263 * call-seq:
2264 * mod.to_s -> string
2266 * Return a string representing this module or class. For basic
2267 * classes and modules, this is the name. For singletons, we
2268 * show information on the thing we're attached to as well.
2271 mrb_value
2272 mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
2274 if (mrb_sclass_p(klass)) {
2275 mrb_value v = mrb_iv_get(mrb, klass, MRB_SYM(__attached__));
2276 mrb_value str = mrb_str_new_lit(mrb, "#<Class:");
2278 if (class_ptr_p(v)) {
2279 mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v));
2281 else {
2282 mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v));
2284 return mrb_str_cat_lit(mrb, str, ">");
2286 else {
2287 return class_name_str(mrb, mrb_class_ptr(klass));
2291 static mrb_value
2292 mrb_mod_alias(mrb_state *mrb, mrb_value mod)
2294 struct RClass *c = mrb_class_ptr(mod);
2295 mrb_sym new_name, old_name;
2297 mrb_get_args(mrb, "nn", &new_name, &old_name);
2298 mrb_alias_method(mrb, c, new_name, old_name);
2299 mrb_method_added(mrb, c, new_name);
2300 return mod;
2303 static void
2304 undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
2306 mrb_method_t m;
2308 MRB_METHOD_FROM_PROC(m, NULL);
2309 mrb_define_method_raw(mrb, c, a, m);
2312 MRB_API void
2313 mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a)
2315 if (!mrb_obj_respond_to(mrb, c, a)) {
2316 mrb_name_error(mrb, a, "undefined method '%n' for class '%C'", a, c);
2318 undef_method(mrb, c, a);
2321 MRB_API void
2322 mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
2324 undef_method(mrb, c, mrb_intern_cstr(mrb, name));
2327 MRB_API void
2328 mrb_undef_class_method_id(mrb_state *mrb, struct RClass *c, mrb_sym name)
2330 mrb_undef_method_id(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
2333 MRB_API void
2334 mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name)
2336 mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
2339 MRB_API void
2340 mrb_remove_method(mrb_state *mrb, struct RClass *c, mrb_sym mid)
2342 mt_tbl *h;
2344 MRB_CLASS_ORIGIN(c);
2345 h = c->mt;
2347 if (h && mt_del(mrb, h, mid)) {
2348 mc_clear_by_id(mrb, mid);
2349 return;
2351 mrb_name_error(mrb, mid, "method '%n' not defined in %C", mid, c);
2354 static mrb_value
2355 mrb_mod_undef(mrb_state *mrb, mrb_value mod)
2357 struct RClass *c = mrb_class_ptr(mod);
2358 mrb_int argc;
2359 const mrb_value *argv;
2361 mrb_get_args(mrb, "*", &argv, &argc);
2362 while (argc--) {
2363 mrb_undef_method_id(mrb, c, to_sym(mrb, *argv));
2364 argv++;
2366 return mrb_nil_value();
2369 static void
2370 check_const_name_sym(mrb_state *mrb, mrb_sym id)
2372 mrb_int len;
2373 const char *name = mrb_sym_name_len(mrb, id, &len);
2374 if (!mrb_const_name_p(mrb, name, len)) {
2375 mrb_name_error(mrb, id, "wrong constant name %n", id);
2379 static mrb_value
2380 mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
2382 mrb_sym id;
2383 mrb_bool inherit = TRUE;
2385 mrb_get_args(mrb, "n|b", &id, &inherit);
2386 check_const_name_sym(mrb, id);
2387 if (inherit) {
2388 return mrb_bool_value(mrb_const_defined(mrb, mod, id));
2390 return mrb_bool_value(mrb_const_defined_at(mrb, mod, id));
2393 static mrb_value
2394 mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id)
2396 check_const_name_sym(mrb, id);
2397 return mrb_const_get(mrb, mod, id);
2400 static mrb_value
2401 mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
2403 mrb_value path = mrb_get_arg1(mrb);
2404 mrb_sym id;
2405 char *ptr;
2406 mrb_int off, end, len;
2408 if (mrb_symbol_p(path)) {
2409 /* const get with symbol */
2410 id = mrb_symbol(path);
2411 return mrb_const_get_sym(mrb, mod, id);
2414 /* const get with class path string */
2415 mrb_ensure_string_type(mrb, path);
2416 ptr = RSTRING_PTR(path);
2417 len = RSTRING_LEN(path);
2418 off = 0;
2420 while (off < len) {
2421 end = mrb_str_index_lit(mrb, path, "::", off);
2422 end = (end == -1) ? len : end;
2423 id = mrb_intern(mrb, ptr+off, end-off);
2424 mod = mrb_const_get_sym(mrb, mod, id);
2425 if (end == len)
2426 off = end;
2427 else {
2428 off = end + 2;
2429 if (off == len) { /* trailing "::" */
2430 mrb_name_error(mrb, id, "wrong constant name '%v'", path);
2435 return mod;
2438 static mrb_value
2439 mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
2441 mrb_sym id;
2442 mrb_value value;
2444 mrb_get_args(mrb, "no", &id, &value);
2445 check_const_name_sym(mrb, id);
2446 mrb_const_set(mrb, mod, id, value);
2447 return value;
2450 static mrb_value
2451 mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
2453 mrb_sym id;
2454 mrb_value val;
2456 mrb_get_args(mrb, "n", &id);
2457 check_const_name_sym(mrb, id);
2458 val = mrb_iv_remove(mrb, mod, id);
2459 if (mrb_undef_p(val)) {
2460 mrb_name_error(mrb, id, "constant %n not defined", id);
2462 return val;
2465 mrb_value
2466 mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym)
2468 if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
2469 mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym);
2471 else {
2472 mrb_name_error(mrb, sym, "uninitialized constant %n", sym);
2474 /* not reached */
2475 return mrb_nil_value();
2478 mrb_value
2479 mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
2481 mrb_sym sym;
2483 mrb_get_args(mrb, "n", &sym);
2484 mrb->c->ci->mid = 0;
2485 return mrb_const_missing(mrb, mod, sym);
2488 /* 15.2.2.4.34 */
2490 * call-seq:
2491 * mod.method_defined?(symbol) -> true or false
2493 * Returns +true+ if the named method is defined by
2494 * _mod_ (or its included modules and, if _mod_ is a class,
2495 * its ancestors). Public and protected methods are matched.
2497 * module A
2498 * def method1() end
2499 * end
2500 * class B
2501 * def method2() end
2502 * end
2503 * class C < B
2504 * include A
2505 * def method3() end
2506 * end
2508 * A.method_defined? :method1 #=> true
2509 * C.method_defined? "method1" #=> true
2510 * C.method_defined? "method2" #=> true
2511 * C.method_defined? "method3" #=> true
2512 * C.method_defined? "method4" #=> false
2515 static mrb_value
2516 mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
2518 mrb_sym id;
2520 mrb_get_args(mrb, "n", &id);
2521 return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id));
2524 void
2525 mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid)
2527 mrb_sym added;
2528 mrb_value recv = mrb_obj_value(c);
2530 if (c->tt == MRB_TT_SCLASS) {
2531 added = MRB_SYM(singleton_method_added);
2532 recv = mrb_iv_get(mrb, recv, MRB_SYM(__attached__));
2534 else {
2535 added = MRB_SYM(method_added);
2537 if (!mrb_func_basic_p(mrb, recv, added, mrb_do_nothing)) {
2538 mrb_value sym = mrb_symbol_value(mid);
2539 mrb_funcall_argv(mrb, recv, added, 1, &sym);
2543 mrb_value
2544 mrb_mod_define_method_m(mrb_state *mrb, struct RClass *c)
2546 struct RProc *p;
2547 mrb_method_t m;
2548 mrb_sym mid;
2549 mrb_value proc = mrb_undef_value();
2550 mrb_value blk;
2552 mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
2553 switch (mrb_type(proc)) {
2554 case MRB_TT_PROC:
2555 blk = proc;
2556 break;
2557 case MRB_TT_UNDEF:
2558 /* ignored */
2559 break;
2560 default:
2561 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %T (expected Proc)", proc);
2562 break;
2564 if (mrb_nil_p(blk)) {
2565 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
2567 p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class);
2568 mrb_proc_copy(mrb, p, mrb_proc_ptr(blk));
2569 p->flags |= MRB_PROC_STRICT;
2570 MRB_METHOD_FROM_PROC(m, p);
2571 mrb_define_method_raw(mrb, c, mid, m);
2572 mrb_method_added(mrb, c, mid);
2573 return mrb_symbol_value(mid);
2576 static mrb_value
2577 mod_define_method(mrb_state *mrb, mrb_value self)
2579 return mrb_mod_define_method_m(mrb, mrb_class_ptr(self));
2582 static mrb_value
2583 top_define_method(mrb_state *mrb, mrb_value self)
2585 return mrb_mod_define_method_m(mrb, mrb->object_class);
2588 static mrb_value
2589 mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
2591 mrb_value obj = mrb_get_arg1(mrb);
2592 mrb_bool eqq;
2594 eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod));
2596 return mrb_bool_value(eqq);
2599 static mrb_value
2600 mrb_mod_dup(mrb_state *mrb, mrb_value self)
2602 mrb_value mod = mrb_obj_clone(mrb, self);
2603 MRB_UNSET_FROZEN_FLAG(mrb_obj_ptr(mod));
2604 return mod;
2607 static mrb_value
2608 mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
2610 const mrb_value *argv;
2611 mrb_int argc;
2612 mrb_sym mid;
2613 mrb_method_t m;
2616 mrb_check_type(mrb, mod, MRB_TT_MODULE);
2618 mrb_get_args(mrb, "*", &argv, &argc);
2619 if (argc == 0) {
2620 /* set MODFUNC SCOPE if implemented */
2621 return mod;
2624 /* set PRIVATE method visibility if implemented */
2625 /* mrb_mod_dummy_visibility(mrb, mod); */
2627 struct RClass *rclass = mrb_class_ptr(mod);
2628 int ai = mrb_gc_arena_save(mrb);
2629 for (int i=0; i<argc; i++) {
2630 mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
2631 mid = mrb_symbol(argv[i]);
2632 m = mrb_method_search(mrb, rclass, mid);
2634 prepare_singleton_class(mrb, (struct RBasic*)rclass);
2635 mrb_define_method_raw(mrb, rclass->c, mid, m);
2636 mrb_gc_arena_restore(mrb, ai);
2639 return mod;
2642 static struct RClass*
2643 mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
2645 struct RClass *klass = mrb_basic_ptr(obj)->c;
2647 if (klass->tt != MRB_TT_SCLASS)
2648 return klass;
2649 else {
2650 /* copy singleton(unnamed) class */
2651 struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
2653 switch (mrb_type(obj)) {
2654 case MRB_TT_CLASS:
2655 case MRB_TT_SCLASS:
2656 break;
2657 default:
2658 clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
2659 break;
2661 clone->super = klass->super;
2662 if (klass->iv) {
2663 mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass));
2664 mrb_obj_iv_set(mrb, (struct RObject*)clone, MRB_SYM(__attached__), obj);
2666 if (klass->mt) {
2667 clone->mt = mt_copy(mrb, klass->mt);
2669 else {
2670 clone->mt = mt_new(mrb);
2672 clone->tt = MRB_TT_SCLASS;
2673 return clone;
2677 static void
2678 copy_class(mrb_state *mrb, mrb_value dst, mrb_value src)
2680 struct RClass *dc = mrb_class_ptr(dst);
2681 struct RClass *sc = mrb_class_ptr(src);
2682 /* if the origin is not the same as the class, then the origin and
2683 the current class need to be copied */
2684 if (sc->flags & MRB_FL_CLASS_IS_PREPENDED) {
2685 struct RClass *c0 = sc->super;
2686 struct RClass *c1 = dc;
2688 /* copy prepended iclasses */
2689 while (!(c0->flags & MRB_FL_CLASS_IS_ORIGIN)) {
2690 c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
2691 c1 = c1->super;
2692 c0 = c0->super;
2694 c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
2695 c1->super->flags |= MRB_FL_CLASS_IS_ORIGIN;
2697 if (sc->mt) {
2698 if (sc->tt == MRB_TT_ICLASS && !(sc->flags & MRB_FL_CLASS_IS_ORIGIN)) {
2699 dc->mt = sc->mt;
2701 else {
2702 dc->mt = mt_copy(mrb, sc->mt);
2705 dc->super = sc->super;
2706 dc->flags = sc->flags;
2707 dc->flags &= ~MRB_FL_OBJ_IS_FROZEN;
2710 /* 15.3.1.3.16 */
2711 static mrb_value
2712 mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
2714 mrb_value orig = mrb_get_arg1(mrb);
2716 if (mrb_obj_equal(mrb, self, orig)) return self;
2717 if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) {
2718 mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object");
2720 return self;
2723 static void
2724 init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
2726 mrb_assert((mrb_type(dest) == mrb_type(obj)));
2727 switch (mrb_type(obj)) {
2728 case MRB_TT_ICLASS:
2729 copy_class(mrb, dest, obj);
2730 return;
2731 case MRB_TT_CLASS:
2732 case MRB_TT_MODULE:
2733 copy_class(mrb, dest, obj);
2734 mrb_iv_copy(mrb, dest, obj);
2735 mrb_iv_remove(mrb, dest, MRB_SYM(__classname__));
2736 break;
2737 case MRB_TT_OBJECT:
2738 case MRB_TT_SCLASS:
2739 case MRB_TT_HASH:
2740 case MRB_TT_CDATA:
2741 case MRB_TT_EXCEPTION:
2742 mrb_iv_copy(mrb, dest, obj);
2743 break;
2744 case MRB_TT_ISTRUCT:
2745 mrb_istruct_copy(dest, obj);
2746 break;
2747 #ifdef MRB_USE_BIGINT
2748 case MRB_TT_BIGINT:
2749 mrb_bint_copy(mrb, dest, obj);
2750 break;
2751 #endif
2752 #ifdef MRB_USE_RATIONAL
2753 case MRB_TT_RATIONAL:
2754 mrb_rational_copy(mrb, dest, obj);
2755 break;
2756 #endif
2757 #ifdef MRB_USE_COMPLEX
2758 case MRB_TT_COMPLEX:
2759 mrb_complex_copy(mrb, dest, obj);
2760 break;
2761 #endif
2763 default:
2764 break;
2766 if (!mrb_func_basic_p(mrb, dest, MRB_SYM(initialize_copy), mrb_obj_init_copy)) {
2767 mrb_funcall_argv(mrb, dest, MRB_SYM(initialize_copy), 1, &obj);
2771 /* 15.3.1.3.8 */
2773 * call-seq:
2774 * obj.clone -> an_object
2776 * Produces a shallow copy of <i>obj</i>---the instance variables of
2777 * <i>obj</i> are copied, but not the objects they reference. Copies
2778 * the frozen state of <i>obj</i>. See also the discussion
2779 * under <code>Object#dup</code>.
2781 * class Klass
2782 * attr_accessor :str
2783 * end
2784 * s1 = Klass.new #=> #<Klass:0x401b3a38>
2785 * s1.str = "Hello" #=> "Hello"
2786 * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello">
2787 * s2.str[1,4] = "i" #=> "i"
2788 * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
2789 * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">"
2791 * This method may have class-specific behavior. If so, that
2792 * behavior will be documented under the #+initialize_copy+ method of
2793 * the class.
2795 * Some Class(True False Nil Symbol Integer Float) Object cannot clone.
2797 MRB_API mrb_value
2798 mrb_obj_clone(mrb_state *mrb, mrb_value self)
2800 struct RObject *p;
2801 mrb_value clone;
2803 if (mrb_immediate_p(self)) {
2804 return self;
2806 if (mrb_sclass_p(self)) {
2807 mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
2809 p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
2810 p->c = mrb_singleton_class_clone(mrb, self);
2811 mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c);
2812 clone = mrb_obj_value(p);
2813 init_copy(mrb, clone, self);
2814 p->flags |= mrb_obj_ptr(self)->flags & MRB_FL_OBJ_IS_FROZEN;
2816 return clone;
2819 /* 15.3.1.3.9 */
2821 * call-seq:
2822 * obj.dup -> an_object
2824 * Produces a shallow copy of <i>obj</i>---the instance variables of
2825 * <i>obj</i> are copied, but not the objects they reference.
2826 * <code>dup</code> copies the frozen state of <i>obj</i>. See also
2827 * the discussion under <code>Object#clone</code>. In general,
2828 * <code>clone</code> and <code>dup</code> may have different semantics
2829 * in descendant classes. While <code>clone</code> is used to duplicate
2830 * an object, including its internal state, <code>dup</code> typically
2831 * uses the class of the descendant object to create the new instance.
2833 * This method may have class-specific behavior. If so, that
2834 * behavior will be documented under the #+initialize_copy+ method of
2835 * the class.
2838 MRB_API mrb_value
2839 mrb_obj_dup(mrb_state *mrb, mrb_value obj)
2841 struct RBasic *p;
2842 mrb_value dup;
2844 if (mrb_immediate_p(obj)) {
2845 return obj;
2847 if (mrb_sclass_p(obj)) {
2848 mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
2850 p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
2851 dup = mrb_obj_value(p);
2852 init_copy(mrb, dup, obj);
2854 return dup;
2857 /* implementation of __id__ */
2858 mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self);
2860 mrb_noreturn void
2861 mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
2863 mrb_no_method_error(mrb, name, args, "undefined method '%n'", name);
2866 /* 15.3.1.3.30 */
2868 * call-seq:
2869 * obj.method_missing(symbol [, *args] ) -> result
2871 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
2872 * <i>symbol</i> is the symbol for the method called, and <i>args</i>
2873 * are any arguments that were passed to it. By default, the interpreter
2874 * raises an error when this method is called. However, it is possible
2875 * to override the method to provide more dynamic behavior.
2876 * If it is decided that a particular method should not be handled, then
2877 * <i>super</i> should be called, so that ancestors can pick up the
2878 * missing method.
2879 * The example below creates
2880 * a class <code>Roman</code>, which responds to methods with names
2881 * consisting of roman numerals, returning the corresponding integer
2882 * values.
2884 * class Roman
2885 * def romanToInt(str)
2886 * # ...
2887 * end
2888 * def method_missing(sym)
2889 * str = sym.to_s
2890 * romanToInt(str)
2891 * end
2892 * end
2894 * r = Roman.new
2895 * r.iv #=> 4
2896 * r.xxiii #=> 23
2897 * r.mm #=> 2000
2899 mrb_value
2900 mrb_obj_missing(mrb_state *mrb, mrb_value mod)
2902 mrb_sym name;
2903 const mrb_value *a;
2904 mrb_int alen;
2906 mrb->c->ci->mid = 0;
2907 mrb_get_args(mrb, "n*!", &name, &a, &alen);
2908 mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
2909 /* not reached */
2910 return mrb_nil_value();
2913 static mrb_value
2914 inspect_main(mrb_state *mrb, mrb_value mod)
2916 return mrb_str_new_lit(mrb, "main");
2919 static const mrb_code new_iseq[] = {
2920 OP_ENTER, 0x0, 0x10, 0x3, // OP_ENTER 0:0:1:0:0:1:1
2921 OP_LOADSELF, 4, // OP_LOADSELF R4
2922 OP_SEND, 4, 0, 0, // OP_SEND R4 :allocate n=0
2923 OP_MOVE, 0, 4, // OP_MOVE R0 R4
2924 OP_MOVE, 4, 3, // OP_MOVE R4 R3 (&)
2925 OP_MOVE, 3, 2, // OP_MOVE R3 R2 (**)
2926 OP_MOVE, 2, 1, // OP_MOVE R2 R1 (*)
2927 OP_SSENDB, 1, 1, 255, // OP_SSENDB R1 :initialize n=*|nk=*
2928 OP_RETURN, 0 // OP_RETURN R0
2931 MRB_PRESYM_DEFINE_VAR_AND_INITER(new_syms, 2, MRB_SYM(allocate), MRB_SYM(initialize))
2933 static const mrb_irep new_irep = {
2934 4, 6, 0, MRB_IREP_STATIC,
2935 new_iseq, NULL, new_syms, NULL, NULL, NULL,
2936 sizeof(new_iseq), 0, 2, 0, 0,
2939 static const struct RProc new_proc = {
2940 NULL, NULL, MRB_TT_PROC, MRB_GC_RED, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT,
2941 { &new_irep }, NULL, { NULL }
2944 static void
2945 init_class_new(mrb_state *mrb, struct RClass *cls)
2947 mrb_method_t m;
2949 MRB_PRESYM_INIT_SYMBOLS(mrb, new_syms);
2950 MRB_METHOD_FROM_PROC(m, &new_proc);
2951 mrb_define_method_raw(mrb, cls, MRB_SYM(new), m);
2954 void
2955 mrb_init_class(mrb_state *mrb)
2957 struct RClass *bob; /* BasicObject */
2958 struct RClass *obj; /* Object */
2959 struct RClass *mod; /* Module */
2960 struct RClass *cls; /* Class */
2962 /* boot class hierarchy */
2963 bob = boot_defclass(mrb, 0);
2964 obj = boot_defclass(mrb, bob); mrb->object_class = obj;
2965 mod = boot_defclass(mrb, obj); mrb->module_class = mod;/* obj -> mod */
2966 cls = boot_defclass(mrb, mod); mrb->class_class = cls; /* obj -> cls */
2967 /* fix-up loose ends */
2968 bob->c = obj->c = mod->c = cls->c = cls;
2969 make_metaclass(mrb, bob);
2970 make_metaclass(mrb, obj);
2971 make_metaclass(mrb, mod);
2972 make_metaclass(mrb, cls);
2974 /* name basic classes */
2975 mrb_define_const_id(mrb, bob, MRB_SYM(BasicObject), mrb_obj_value(bob));
2976 mrb_define_const_id(mrb, obj, MRB_SYM(Object), mrb_obj_value(obj));
2977 mrb_define_const_id(mrb, obj, MRB_SYM(Module), mrb_obj_value(mod));
2978 mrb_define_const_id(mrb, obj, MRB_SYM(Class), mrb_obj_value(cls));
2980 /* name each classes */
2981 mrb_class_name_class(mrb, NULL, bob, MRB_SYM(BasicObject));
2982 mrb_class_name_class(mrb, NULL, obj, MRB_SYM(Object)); /* 15.2.1 */
2983 mrb_class_name_class(mrb, NULL, mod, MRB_SYM(Module)); /* 15.2.2 */
2984 mrb_class_name_class(mrb, NULL, cls, MRB_SYM(Class)); /* 15.2.3 */
2986 MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
2987 mrb_define_method_id(mrb, bob, MRB_SYM(initialize), mrb_do_nothing, MRB_ARGS_NONE());
2988 mrb_define_method_id(mrb, bob, MRB_OPSYM(not), mrb_bob_not, MRB_ARGS_NONE());
2989 mrb_define_method_id(mrb, bob, MRB_OPSYM(eq), mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */
2990 mrb_define_method_id(mrb, bob, MRB_SYM(__id__), mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.4 */
2991 mrb_define_method_id(mrb, bob, MRB_SYM(__send__), mrb_f_send, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.5 */
2992 mrb_define_method_id(mrb, bob, MRB_SYM_Q(equal), mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */
2993 mrb_define_method_id(mrb, bob, MRB_SYM(instance_eval), mrb_obj_instance_eval, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.3.1.3.18 */
2994 mrb_define_method_id(mrb, bob, MRB_SYM(singleton_method_added), mrb_do_nothing, MRB_ARGS_REQ(1));
2995 mrb_define_method_id(mrb, bob, MRB_SYM(method_missing), mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */
2997 mrb_define_class_method_id(mrb, cls, MRB_SYM(new), mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());
2998 mrb_define_method_id(mrb, cls, MRB_SYM(allocate), mrb_instance_alloc, MRB_ARGS_NONE());
2999 mrb_define_method_id(mrb, cls, MRB_SYM(superclass), mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */
3000 mrb_define_method_id(mrb, cls, MRB_SYM(initialize), mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
3001 mrb_define_method_id(mrb, cls, MRB_SYM(inherited), mrb_do_nothing, MRB_ARGS_REQ(1));
3003 init_class_new(mrb, cls);
3005 MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
3006 mrb_define_method_id(mrb, mod, MRB_SYM(extend_object), mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */
3007 mrb_define_method_id(mrb, mod, MRB_SYM(extended), mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
3008 mrb_define_method_id(mrb, mod, MRB_SYM(prepended), mrb_do_nothing, MRB_ARGS_REQ(1));
3009 mrb_define_method_id(mrb, mod, MRB_SYM(prepend_features), mrb_mod_prepend_features, MRB_ARGS_REQ(1));
3010 mrb_define_method_id(mrb, mod, MRB_SYM_Q(include), mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
3011 mrb_define_method_id(mrb, mod, MRB_SYM(append_features), mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */
3012 mrb_define_method_id(mrb, mod, MRB_SYM(class_eval), mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */
3013 mrb_define_method_id(mrb, mod, MRB_SYM(included), mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
3014 mrb_define_method_id(mrb, mod, MRB_SYM(initialize), mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */
3015 mrb_define_method_id(mrb, mod, MRB_SYM(module_eval), mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
3016 mrb_define_method_id(mrb, mod, MRB_SYM(module_function), mrb_mod_module_function, MRB_ARGS_ANY());
3017 mrb_define_method_id(mrb, mod, MRB_SYM(private), mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
3018 mrb_define_method_id(mrb, mod, MRB_SYM(protected), mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
3019 mrb_define_method_id(mrb, mod, MRB_SYM(public), mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
3020 mrb_define_method_id(mrb, mod, MRB_SYM(attr_reader), mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */
3021 mrb_define_method_id(mrb, mod, MRB_SYM(attr_writer), mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */
3022 mrb_define_method_id(mrb, mod, MRB_SYM(to_s), mrb_mod_to_s, MRB_ARGS_NONE());
3023 mrb_define_method_id(mrb, mod, MRB_SYM(inspect), mrb_mod_to_s, MRB_ARGS_NONE());
3024 mrb_define_method_id(mrb, mod, MRB_SYM(alias_method), mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */
3025 mrb_define_method_id(mrb, mod, MRB_SYM(ancestors), mrb_mod_ancestors, MRB_ARGS_NONE()); /* 15.2.2.4.9 */
3026 mrb_define_method_id(mrb, mod, MRB_SYM(undef_method), mrb_mod_undef, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
3027 mrb_define_method_id(mrb, mod, MRB_SYM_Q(const_defined), mrb_mod_const_defined, MRB_ARGS_ARG(1,1)); /* 15.2.2.4.20 */
3028 mrb_define_method_id(mrb, mod, MRB_SYM(const_get), mrb_mod_const_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */
3029 mrb_define_method_id(mrb, mod, MRB_SYM(const_set), mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */
3030 mrb_define_method_id(mrb, mod, MRB_SYM(remove_const), mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */
3031 mrb_define_method_id(mrb, mod, MRB_SYM(const_missing), mrb_mod_const_missing, MRB_ARGS_REQ(1));
3032 mrb_define_method_id(mrb, mod, MRB_SYM_Q(method_defined), mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
3033 mrb_define_method_id(mrb, mod, MRB_SYM(define_method), mod_define_method, MRB_ARGS_ARG(1,1));
3034 mrb_define_method_id(mrb, mod, MRB_OPSYM(eqq), mrb_mod_eqq, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */
3035 mrb_define_method_id(mrb, mod, MRB_SYM(dup), mrb_mod_dup, MRB_ARGS_NONE());
3036 mrb_define_method_id(mrb, mod, MRB_SYM(method_added), mrb_do_nothing, MRB_ARGS_REQ(1));
3038 mrb_undef_method_id(mrb, cls, MRB_SYM(append_features));
3039 mrb_undef_method_id(mrb, cls, MRB_SYM(prepend_features));
3040 mrb_undef_method_id(mrb, cls, MRB_SYM(extend_object));
3041 mrb_undef_method_id(mrb, cls, MRB_SYM(module_function));
3043 mrb->top_self = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb->object_class);
3044 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(inspect), inspect_main, MRB_ARGS_NONE());
3045 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(to_s), inspect_main, MRB_ARGS_NONE());
3046 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(define_method), top_define_method, MRB_ARGS_ARG(1,1));