mruby-random: Random#rand(nil) should raise TypeError
[mruby.git] / src / class.c
blob1031a53134d0a235f159134c62038ae7aa3d1ebb
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 const struct RProc *proc;
26 mrb_func_t func;
29 #define MT_KEY_SHIFT 4
30 #define MT_KEY_MASK ((1<<MT_KEY_SHIFT)-1)
31 #define MT_KEY_P(k) (((k)>>MT_KEY_SHIFT) != 0)
32 #define MT_FUNC MRB_METHOD_FUNC_FL
33 #define MT_NOARG MRB_METHOD_NOARG_FL
34 #define MT_PUBLIC MRB_METHOD_PUBLIC_FL
35 #define MT_PRIVATE MRB_METHOD_PRIVATE_FL
36 #define MT_PROTECTED MRB_METHOD_PROTECTED_FL
37 #define MT_VDEFAULT MRB_METHOD_VDEFAULT_FL
38 #define MT_VMASK MRB_METHOD_VISIBILITY_MASK
39 #define MT_EMPTY 0
40 #define MT_DELETED 1
42 #define MT_KEY(sym, flags) ((sym)<<MT_KEY_SHIFT|(flags))
43 #define MT_KEY_SYM(k) ((k)>>MT_KEY_SHIFT)
44 #define MT_KEY_FLG(k) ((k)&MT_KEY_MASK)
46 /* method table structure */
47 typedef struct mt_tbl {
48 int size;
49 int alloc;
50 union mt_ptr *ptr;
51 } mt_tbl;
53 #ifdef MRB_USE_INLINE_METHOD_CACHE
54 #define MT_INLINE_CACHE_SIZE 256
55 static uint8_t mt_cache[MT_INLINE_CACHE_SIZE];
56 #endif
58 /* Creates the method table. */
59 static mt_tbl*
60 mt_new(mrb_state *mrb)
62 mt_tbl *t;
64 t = (mt_tbl*)mrb_malloc(mrb, sizeof(mt_tbl));
65 t->size = 0;
66 t->alloc = 0;
67 t->ptr = NULL;
69 return t;
72 static void mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, mrb_sym flags, union mt_ptr ptr);
74 static void
75 mt_rehash(mrb_state *mrb, mt_tbl *t)
77 int old_alloc = t->alloc;
78 int new_alloc = old_alloc > 0 ? old_alloc << 1 : 8;
79 union mt_ptr *old_ptr = t->ptr;
81 t->ptr = (union mt_ptr*)mrb_calloc(mrb, sizeof(union mt_ptr)+sizeof(mrb_sym), new_alloc);
82 t->alloc = new_alloc;
83 t->size = 0;
84 if (old_alloc == 0) return;
86 mrb_sym *keys = (mrb_sym*)&old_ptr[old_alloc];
87 union mt_ptr *vals = old_ptr;
88 for (int i = 0; i < old_alloc; i++) {
89 mrb_sym key = keys[i];
90 if (MT_KEY_P(key)) {
91 mt_put(mrb, t, MT_KEY_SYM(key), MT_KEY_FLG(key), vals[i]);
94 mrb_free(mrb, old_ptr);
97 #define slot_empty_p(slot) ((slot)->key == 0 && (slot)->func_p == 0)
99 /* Set the value for the symbol in the method table. */
100 static void
101 mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, mrb_sym flags, union mt_ptr ptr)
103 int pos, start, dpos = -1;
105 if (t->alloc == 0) {
106 mt_rehash(mrb, t);
109 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
110 union mt_ptr *vals = t->ptr;
111 int hash = mrb_int_hash_func(mrb, sym);
112 start = pos = hash & (t->alloc-1);
113 for (;;) {
114 mrb_sym key = keys[pos];
115 if (MT_KEY_SYM(key) == sym) {
116 value_set:
117 keys[pos] = MT_KEY(sym, flags);
118 vals[pos] = ptr;
119 return;
121 else if (key == MT_EMPTY) {
122 t->size++;
123 goto value_set;
125 else if (key == MT_DELETED && dpos < 0) {
126 dpos = pos;
128 pos = (pos+1) & (t->alloc-1);
129 if (pos == start) { /* not found */
130 if (dpos > 0) {
131 t->size++;
132 pos = dpos;
133 goto value_set;
135 /* no room */
136 mt_rehash(mrb, t);
137 start = pos = hash & (t->alloc-1);
138 keys = (mrb_sym*)&t->ptr[t->alloc];
139 vals = t->ptr;
144 /* Get a value for a symbol from the method table. */
145 static mrb_sym
146 mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp)
148 int pos;
150 if (t == NULL) return 0;
151 if (t->alloc == 0) return 0;
152 if (t->size == 0) return 0;
154 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
155 union mt_ptr *vals = t->ptr;
156 int hash = mrb_int_hash_func(mrb, sym);
157 #ifdef MRB_USE_INLINE_METHOD_CACHE
158 int cpos = (hash^(uintptr_t)t) % MT_INLINE_CACHE_SIZE;
159 pos = mt_cache[cpos];
160 if (pos < t->alloc) {
161 mrb_sym key = keys[pos];
162 if (key) {
163 if (MT_KEY_SYM(key) == sym) {
164 *pp = vals[pos];
165 return key;
169 #endif
170 int start = pos = hash & (t->alloc-1);
171 for (;;) {
172 mrb_sym key = keys[pos];
173 if (MT_KEY_SYM(key) == sym) {
174 *pp = vals[pos];
175 #ifdef MRB_USE_INLINE_METHOD_CACHE
176 if (pos < 0x100) {
177 mt_cache[cpos] = pos;
179 #endif
180 return key;
182 else if (key == MT_EMPTY) {
183 return 0;
185 pos = (pos+1) & (t->alloc-1);
186 if (pos == start) { /* not found */
187 return 0;
192 /* Deletes the value for the symbol from the method table. */
193 static mrb_bool
194 mt_del(mrb_state *mrb, mt_tbl *t, mrb_sym sym)
196 int pos, start;
198 if (t == NULL) return FALSE;
199 if (t->alloc == 0) return FALSE;
200 if (t->size == 0) return FALSE;
202 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
203 int hash = mrb_int_hash_func(mrb, sym);
204 start = pos = hash & (t->alloc-1);
205 for (;;) {
206 mrb_sym key = keys[pos];
207 if (MT_KEY_SYM(key) == sym) {
208 t->size--;
209 keys[pos] = MT_DELETED;
210 return TRUE;
212 else if (key == MT_EMPTY) {
213 return FALSE;
215 pos = (pos+1) & (t->alloc-1);
216 if (pos == start) { /* not found */
217 return FALSE;
222 /* Copy the method table. */
223 static struct mt_tbl*
224 mt_copy(mrb_state *mrb, mt_tbl *t)
226 mt_tbl *t2;
228 if (t == NULL) return NULL;
229 if (t->alloc == 0) return NULL;
230 if (t->size == 0) return NULL;
232 t2 = mt_new(mrb);
233 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
234 union mt_ptr *vals = t->ptr;
235 for (int i=0; i<t->alloc; i++) {
236 if (MT_KEY_P(keys[i])) {
237 mt_put(mrb, t2, MT_KEY_SYM(keys[i]), MT_KEY_FLG(keys[i]), vals[i]);
240 return t2;
243 /* Free memory of the method table. */
244 static void
245 mt_free(mrb_state *mrb, mt_tbl *t)
247 mrb_free(mrb, t->ptr);
248 mrb_free(mrb, t);
251 static inline mrb_method_t
252 create_method_value(mrb_state *mrb, mrb_sym key, union mt_ptr val)
254 mrb_method_t m = { key, { val.proc } };
255 return m;
258 MRB_API void
259 mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p)
261 mt_tbl *t = c->mt;
263 if (t == NULL) return;
264 if (t->alloc == 0) return;
265 if (t->size == 0) return;
267 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
268 union mt_ptr *vals = t->ptr;
269 for (int i=0; i<t->alloc; i++) {
270 mrb_sym key = keys[i];
271 if (MT_KEY_SYM(key)) {
272 if (fn(mrb, MT_KEY_SYM(key), create_method_value(mrb, key, vals[i]), p) != 0)
273 return;
276 return;
279 size_t
280 mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c)
282 mt_tbl *t = c->mt;
284 if (t == NULL) return 0;
285 if (t->alloc == 0) return 0;
286 if (t->size == 0) return 0;
288 mrb_sym *keys = (mrb_sym*)&t->ptr[t->alloc];
289 union mt_ptr *vals = t->ptr;
290 for (int i=0; i<t->alloc; i++) {
291 if (MT_KEY_P(keys[i]) && (keys[i] & MT_FUNC) == 0) { /* Proc pointer */
292 const struct RProc *p = vals[i].proc;
293 mrb_gc_mark(mrb, (struct RBasic*)p);
296 if (!t) return 0;
297 return (size_t)t->size;
300 size_t
301 mrb_class_mt_memsize(mrb_state *mrb, struct RClass *c)
303 struct mt_tbl *h = c->mt;
305 if (!h) return 0;
306 return sizeof(struct mt_tbl) + (size_t)h->size * sizeof(mrb_method_t);
309 void
310 mrb_gc_free_mt(mrb_state *mrb, struct RClass *c)
312 if (c->mt) mt_free(mrb, c->mt);
315 void
316 mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
318 mrb_value name;
319 mrb_sym nsym = MRB_SYM(__classname__);
321 if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return;
322 if (outer == NULL || outer == mrb->object_class) {
323 name = mrb_symbol_value(id);
325 else {
326 name = mrb_class_path(mrb, outer);
327 if (mrb_nil_p(name)) { /* unnamed outer class */
328 if (outer != mrb->object_class && outer != c) {
329 mrb_obj_iv_set_force(mrb, (struct RObject*)c, MRB_SYM(__outer__),
330 mrb_obj_value(outer));
332 return;
334 else {
335 mrb_int len;
336 const char *n = mrb_sym_name_len(mrb, id, &len);
338 mrb_str_cat_lit(mrb, name, "::");
339 mrb_str_cat(mrb, name, n, len);
342 mrb_obj_iv_set_force(mrb, (struct RObject*)c, nsym, name);
345 mrb_bool
346 mrb_const_name_p(mrb_state *mrb, const char *name, mrb_int len)
348 return len > 0 && ISUPPER(name[0]) && mrb_ident_p(name+1, len-1);
351 static void
352 setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id)
354 mrb_const_set(mrb, mrb_obj_value(outer), id, mrb_obj_value(c));
357 #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
359 static void
360 prepare_singleton_class(mrb_state *mrb, struct RBasic *o)
362 struct RClass *c;
364 mrb_assert(o->c);
365 if (o->c->tt == MRB_TT_SCLASS) return;
366 struct RClass *sc = MRB_OBJ_ALLOC(mrb, MRB_TT_SCLASS, mrb->class_class);
367 sc->flags |= MRB_FL_CLASS_IS_INHERITED;
368 sc->mt = NULL;
369 sc->iv = NULL;
370 if (o->tt == MRB_TT_CLASS) {
371 c = (struct RClass*)o;
372 if (!c->super) {
373 sc->super = mrb->class_class;
375 else {
376 sc->super = c->super->c;
379 else if (o->tt == MRB_TT_SCLASS) {
380 c = (struct RClass*)o;
381 while (c->super->tt == MRB_TT_ICLASS)
382 c = c->super;
383 make_metaclass(mrb, c->super);
384 sc->super = c->super->c;
386 else {
387 sc->super = o->c;
388 prepare_singleton_class(mrb, (struct RBasic*)sc);
390 o->c = sc;
391 mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc);
392 mrb_obj_iv_set(mrb, (struct RObject*)sc, MRB_SYM(__attached__), mrb_obj_value(o));
393 sc->frozen = o->frozen;
396 static mrb_value
397 class_name_str(mrb_state *mrb, struct RClass* c)
399 mrb_value path = mrb_class_path(mrb, c);
400 if (mrb_nil_p(path)) {
401 path = c->tt == MRB_TT_MODULE ? mrb_str_new_lit(mrb, "#<Module:") :
402 mrb_str_new_lit(mrb, "#<Class:");
403 mrb_str_cat_str(mrb, path, mrb_ptr_to_str(mrb, c));
404 mrb_str_cat_lit(mrb, path, ">");
406 return path;
409 static struct RClass*
410 class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
412 mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
414 mrb_check_type(mrb, c, MRB_TT_CLASS);
415 return mrb_class_ptr(c);
418 static struct RClass*
419 module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id)
421 mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id);
423 mrb_check_type(mrb, c, MRB_TT_MODULE);
424 return mrb_class_ptr(c);
427 static mrb_bool
428 class_ptr_p(mrb_value obj)
430 switch (mrb_type(obj)) {
431 case MRB_TT_CLASS:
432 case MRB_TT_SCLASS:
433 case MRB_TT_MODULE:
434 return TRUE;
435 default:
436 return FALSE;
440 static void
441 check_if_class_or_module(mrb_state *mrb, mrb_value obj)
443 if (!class_ptr_p(obj)) {
444 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class/module", obj);
448 static struct RClass*
449 define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer)
451 if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
452 return module_from_sym(mrb, outer, name);
454 struct RClass *m = mrb_module_new(mrb);
455 setup_class(mrb, outer, m, name);
457 return m;
460 MRB_API struct RClass*
461 mrb_define_module_id(mrb_state *mrb, mrb_sym name)
463 return define_module(mrb, name, mrb->object_class);
466 MRB_API struct RClass*
467 mrb_define_module(mrb_state *mrb, const char *name)
469 return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class);
472 struct RClass*
473 mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id)
475 check_if_class_or_module(mrb, outer);
476 if (mrb_const_defined_at(mrb, outer, id)) {
477 mrb_value old = mrb_const_get(mrb, outer, id);
479 if (!mrb_module_p(old)) {
480 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a module", old);
482 return mrb_class_ptr(old);
484 return define_module(mrb, id, mrb_class_ptr(outer));
487 MRB_API struct RClass*
488 mrb_define_module_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
490 struct RClass * c = define_module(mrb, name, outer);
492 setup_class(mrb, outer, c, name);
493 return c;
496 MRB_API struct RClass*
497 mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name)
499 mrb_sym id = mrb_intern_cstr(mrb, name);
500 struct RClass * c = define_module(mrb, id, outer);
502 setup_class(mrb, outer, c, id);
503 return c;
506 static struct RClass*
507 find_origin(struct RClass *c)
509 MRB_CLASS_ORIGIN(c);
510 return c;
513 static struct RClass*
514 define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer)
516 struct RClass * c;
518 if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) {
519 c = class_from_sym(mrb, outer, name);
520 MRB_CLASS_ORIGIN(c);
521 if (super && mrb_class_real(c->super) != super) {
522 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %n (%C not %C)",
523 name, c->super, super);
525 return c;
528 c = mrb_class_new(mrb, super);
529 setup_class(mrb, outer, c, name);
531 return c;
534 MRB_API struct RClass*
535 mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super)
537 if (!super) {
538 mrb_warn(mrb, "no super class for '%n', Object assumed", name);
540 return define_class(mrb, name, super, mrb->object_class);
543 MRB_API struct RClass*
544 mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super)
546 return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super);
549 static mrb_value mrb_do_nothing(mrb_state *mrb, mrb_value);
550 #ifndef MRB_NO_METHOD_CACHE
551 static void mc_clear(mrb_state *mrb);
552 static void mc_clear_by_id(mrb_state *mrb, mrb_sym mid);
553 #else
554 #define mc_clear(mrb)
555 #define mc_clear_by_id(mrb,mid)
556 #endif
558 static void
559 mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass)
562 if (!super)
563 super = mrb->object_class;
564 super->flags |= MRB_FL_CLASS_IS_INHERITED;
566 mrb_value s = mrb_obj_value(super);
567 mrb_sym mid = MRB_SYM(inherited);
569 if (!mrb_func_basic_p(mrb, s, mid, mrb_do_nothing)) {
570 mrb_value c = mrb_obj_value(klass);
571 mrb_funcall_argv(mrb, s, mid, 1, &c);
575 struct RClass*
576 mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id)
578 struct RClass *s;
579 struct RClass *c;
581 if (!mrb_nil_p(super)) {
582 if (!mrb_class_p(super)) {
583 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%!v given)", super);
585 s = mrb_class_ptr(super);
587 else {
588 s = NULL;
590 check_if_class_or_module(mrb, outer);
591 if (mrb_const_defined_at(mrb, outer, id)) {
592 mrb_value old = mrb_const_get(mrb, outer, id);
594 if (!mrb_class_p(old)) {
595 mrb_raisef(mrb, E_TYPE_ERROR, "%!v is not a class", old);
597 c = mrb_class_ptr(old);
598 if (s) {
599 /* check super class */
600 if (mrb_class_real(c->super) != s) {
601 mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for %v", old);
604 return c;
606 c = define_class(mrb, id, s, mrb_class_ptr(outer));
607 mrb_class_inherited(mrb, mrb_class_real(c->super), c);
609 return c;
612 MRB_API mrb_bool
613 mrb_class_defined(mrb_state *mrb, const char *name)
615 mrb_sym sym = mrb_intern_check_cstr(mrb, name);
616 if (!sym) return FALSE;
617 return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), sym);
620 MRB_API mrb_bool
621 mrb_class_defined_id(mrb_state *mrb, mrb_sym name)
623 return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), name);
626 MRB_API mrb_bool
627 mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name)
629 mrb_sym sym = mrb_intern_check_cstr(mrb, name);
630 if (!sym) return FALSE;
631 return mrb_const_defined_at(mrb, mrb_obj_value(outer), sym);
634 MRB_API mrb_bool
635 mrb_class_defined_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
637 return mrb_const_defined_at(mrb, mrb_obj_value(outer), name);
640 MRB_API struct RClass*
641 mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
643 return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
646 MRB_API struct RClass*
647 mrb_class_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
649 return class_from_sym(mrb, outer, name);
652 MRB_API struct RClass*
653 mrb_class_get(mrb_state *mrb, const char *name)
655 return mrb_class_get_under(mrb, mrb->object_class, name);
658 MRB_API struct RClass*
659 mrb_class_get_id(mrb_state *mrb, mrb_sym name)
661 return mrb_class_get_under_id(mrb, mrb->object_class, name);
664 MRB_API struct RClass*
665 mrb_exc_get_id(mrb_state *mrb, mrb_sym name)
667 mrb_value c = mrb_exc_const_get(mrb, name);
669 if (!mrb_class_p(c)) {
670 mrb_raise(mrb, E_EXCEPTION, "exception corrupted");
673 struct RClass *exc = mrb_class_ptr(c);
674 for (struct RClass *e = exc; e; e = e->super) {
675 if (e == E_EXCEPTION)
676 return exc;
678 mrb_raise(mrb, E_EXCEPTION, "non-exception raised");
679 /* not reached */
680 return NULL;
683 MRB_API struct RClass*
684 mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name)
686 return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name));
689 MRB_API struct RClass*
690 mrb_module_get_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name)
692 return module_from_sym(mrb, outer, name);
695 MRB_API struct RClass*
696 mrb_module_get(mrb_state *mrb, const char *name)
698 return mrb_module_get_under(mrb, mrb->object_class, name);
701 MRB_API struct RClass*
702 mrb_module_get_id(mrb_state *mrb, mrb_sym name)
704 return mrb_module_get_under_id(mrb, mrb->object_class, name);
708 * Defines a class under the namespace of \a outer.
709 * \param outer a class which contains the new class.
710 * \param name name of the new class
711 * \param super a class from which the new class will derive.
712 * NULL means \c Object class.
713 * \return the created class
714 * \throw TypeError if the constant name \a name is already taken but
715 * the constant is not a \c Class.
716 * \throw NameError if the class is already defined but the class can not
717 * be reopened because its superclass is not \a super.
718 * \post top-level constant named \a name refers the returned class.
720 * \note if a class named \a name is already defined and its superclass is
721 * \a super, the function just returns the defined class.
723 MRB_API struct RClass*
724 mrb_define_class_under_id(mrb_state *mrb, struct RClass *outer, mrb_sym name, struct RClass *super)
726 struct RClass * c;
728 #if 0
729 if (!super) {
730 mrb_warn(mrb, "no super class for '%C::%n', Object assumed", outer, id);
732 #endif
733 c = define_class(mrb, name, super, outer);
734 setup_class(mrb, outer, c, name);
735 return c;
738 MRB_API struct RClass*
739 mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super)
741 return mrb_define_class_under_id(mrb, outer, mrb_intern_cstr(mrb, name), super);
744 static mrb_bool
745 check_visibility_break(const struct RProc *p, const struct RClass *c, mrb_callinfo *ci, struct REnv *env)
747 if (!p || p->upper == NULL || MRB_PROC_SCOPE_P(p) || p->e.env == NULL || !MRB_PROC_ENV_P(p)) {
748 return TRUE;
750 if (env) {
751 return p->e.env->c != c || MRB_ENV_VISIBILITY_BREAK_P(env);
753 return mrb_vm_ci_target_class(ci) != c || MRB_CI_VISIBILITY_BREAK_P(ci);
756 static void
757 find_visibility_scope(mrb_state *mrb, const struct RClass *c, int n, mrb_callinfo **cp, struct REnv **ep)
759 const struct mrb_context *ec = mrb->c;
760 mrb_callinfo *ci = ec->ci - n;
761 const struct RProc *p = ci->proc;
763 if (c == NULL) c = mrb_vm_ci_target_class(ci);
765 if (check_visibility_break(p, c, ci, NULL)) {
766 mrb_assert(ci->u.env);
767 *ep = NULL;
768 *cp = ci;
769 return;
772 for (;;) {
773 struct REnv *env = p->e.env;
774 p = p->upper;
775 if (check_visibility_break(p, c, ci, env)) {
776 *ep = env;
777 *cp = NULL;
778 return;
783 MRB_API void
784 mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_method_t m)
786 union mt_ptr ptr;
788 MRB_CLASS_ORIGIN(c);
790 mt_tbl *h = c->mt;
791 if (c->tt == MRB_TT_SCLASS && mrb_frozen_p(c)) {
792 mrb_value v = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__));
793 mrb_check_frozen_value(mrb, v);
795 else {
796 mrb_check_frozen(mrb, c);
798 if (!h) h = c->mt = mt_new(mrb);
799 if (MRB_METHOD_PROC_P(m)) {
800 struct RProc *p = (struct RProc*)MRB_METHOD_PROC(m);
802 ptr.proc = p;
803 if (p) {
804 if (p->gc_color != MRB_GC_RED) {
805 p->flags |= MRB_PROC_SCOPE;
806 p->c = NULL;
807 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)p);
808 if (!MRB_PROC_ENV_P(p)) {
809 MRB_PROC_SET_TARGET_CLASS(p, c);
812 else {
813 mrb_assert(mrb_frozen_p(p) && MRB_PROC_SCOPE_P(p));
814 mrb_assert(p->c == NULL && p->upper == NULL && p->e.target_class == NULL);
818 else {
819 ptr.func = MRB_METHOD_FUNC(m);
822 int flags = MT_KEY_FLG(m.flags);
823 if (mid == MRB_SYM(initialize)) {
824 MRB_SET_VISIBILITY_FLAGS(flags, MT_PRIVATE);
826 else if ((flags & MT_VMASK) == MT_VDEFAULT) {
827 mrb_callinfo *ci;
828 struct REnv *e;
829 find_visibility_scope(mrb, c, 0, &ci, &e);
830 mrb_assert(ci || e);
831 MRB_SET_VISIBILITY_FLAGS(flags, (e ? MRB_ENV_VISIBILITY(e) : MRB_CI_VISIBILITY(ci)));
833 mt_put(mrb, h, mid, flags, ptr);
834 mc_clear_by_id(mrb, mid);
837 static void
838 define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec, int vis)
840 mrb_method_t m;
841 int ai = mrb_gc_arena_save(mrb);
843 MRB_METHOD_FROM_FUNC(m, func);
844 if (aspec == MRB_ARGS_NONE()) {
845 MRB_METHOD_NOARG_SET(m);
847 MRB_METHOD_SET_VISIBILITY(m, vis);
848 mrb_define_method_raw(mrb, c, mid, m);
849 mrb_gc_arena_restore(mrb, ai);
852 MRB_API void
853 mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
855 define_method_id(mrb, c, mid, func, aspec, MT_PUBLIC);
858 MRB_API void
859 mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
861 mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
864 MRB_API void
865 mrb_define_private_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec)
867 define_method_id(mrb, c, mid, func, aspec, MT_PRIVATE);
870 MRB_API void
871 mrb_define_private_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
873 mrb_define_private_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
876 /* a function to raise NotImplementedError with current method name */
877 MRB_API void
878 mrb_notimplement(mrb_state *mrb)
880 mrb_callinfo *ci = mrb->c->ci;
882 if (ci->mid) {
883 mrb_raisef(mrb, E_NOTIMP_ERROR, "%n() function is unimplemented on this machine", ci->mid);
887 /* a function to be replacement of unimplemented method */
888 MRB_API mrb_value
889 mrb_notimplement_m(mrb_state *mrb, mrb_value self)
891 mrb_notimplement(mrb);
892 /* not reached */
893 return mrb_nil_value();
896 static void
897 ensure_class_type(mrb_state *mrb, mrb_value val)
899 if (!class_ptr_p(val)) {
900 mrb_raisef(mrb, E_TYPE_ERROR, "%v is not class/module", val);
904 #define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss)
906 MRB_API mrb_int
907 mrb_get_argc(mrb_state *mrb)
909 mrb_int argc = mrb->c->ci->n;
911 if (argc == 15) {
912 struct RArray *a = mrb_ary_ptr(mrb->c->ci->stack[1]);
914 a->c = NULL; /* hide from ObjectSpace.each_object */
915 argc = ARY_LEN(a);
917 return argc;
920 MRB_API const mrb_value*
921 mrb_get_argv(mrb_state *mrb)
923 mrb_int argc = mrb->c->ci->n;
924 mrb_value *array_argv = mrb->c->ci->stack + 1;
925 if (argc == 15) {
926 struct RArray *a = mrb_ary_ptr(*array_argv);
928 a->c = NULL; /* hide from ObjectSpace.each_object */
929 array_argv = ARY_PTR(a);
931 return array_argv;
934 MRB_API mrb_value
935 mrb_get_arg1(mrb_state *mrb)
937 mrb_callinfo *ci = mrb->c->ci;
938 mrb_int argc = ci->n;
939 mrb_value *array_argv = ci->stack + 1;
940 if (argc == 15) {
941 struct RArray *a = mrb_ary_ptr(*array_argv);
943 argc = ARY_LEN(a);
944 array_argv = ARY_PTR(a);
946 if (argc == 0 && ci->nk == 15) {
947 mrb_int n = ci->n;
948 if (n == 15) n = 1;
949 return ci->stack[n+1]; /* kwhash next to positional arguments */
951 if (argc != 1) {
952 mrb_argnum_error(mrb, argc, 1, 1);
954 return array_argv[0];
957 MRB_API mrb_bool
958 mrb_block_given_p(mrb_state *mrb)
960 mrb_callinfo *ci = mrb->c->ci;
961 mrb_value b = ci->stack[mrb_ci_bidx(ci)];
963 return !mrb_nil_p(b);
966 #define GET_ARG(_type) (ptr ? ((_type)(*ptr++)) : va_arg((*ap), _type))
968 static mrb_int
969 get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list *ap)
971 const char *fmt = format;
972 char c;
973 mrb_int i = 0;
974 mrb_callinfo *ci = mrb->c->ci;
975 mrb_int argc = ci->n;
976 const mrb_value *argv = ci->stack+1;
977 mrb_bool argv_on_stack;
978 mrb_bool opt = FALSE;
979 mrb_bool opt_skip = TRUE;
980 const mrb_value *pickarg = NULL; /* arguments currently being processed */
981 mrb_value kdict = mrb_nil_value();
982 mrb_bool reqkarg = FALSE;
983 int argc_min = 0, argc_max = 0;
985 while ((c = *fmt++)) {
986 switch (c) {
987 case '|':
988 opt = TRUE;
989 break;
990 case '*':
991 opt_skip = FALSE;
992 argc_max = -1;
993 if (!reqkarg) reqkarg = strchr(fmt, ':') ? TRUE : FALSE;
994 goto check_exit;
995 case '!':
996 case '+':
997 break;
998 case ':':
999 reqkarg = TRUE;
1000 /* fall through */
1001 case '&': case '?':
1002 if (opt) opt_skip = FALSE;
1003 break;
1004 default:
1005 if (!opt) argc_min++;
1006 argc_max++;
1007 break;
1011 check_exit:
1012 if (!reqkarg && ci->nk > 0) {
1013 mrb_assert(ci->nk == 15);
1014 kdict = ci->stack[mrb_ci_bidx(ci)-1];
1015 if (mrb_hash_p(kdict) && mrb_hash_size(mrb, kdict) > 0) {
1016 if (argc < 14) {
1017 ci->n++;
1018 argc++; /* include kdict in normal arguments */
1020 else {
1021 /* 14+1 == 15 so pack first */
1022 if (argc == 14) {
1023 /* pack arguments and kdict */
1024 ci->stack[1] = mrb_ary_new_from_values(mrb, argc+1, &ci->stack[1]);
1025 argc = ci->n = 15;
1027 else {
1028 /* push kdict to packed arguments */
1029 mrb_ary_push(mrb, ci->stack[1], kdict);
1031 ci->stack[2] = ci->stack[mrb_ci_bidx(ci)];
1033 ci->nk = 0;
1036 if (reqkarg && ci->nk > 0) {
1037 kdict = ci->stack[mrb_ci_bidx(ci)-1];
1038 mrb_assert(ci->nk == 15);
1039 mrb_assert(mrb_hash_p(kdict));
1042 argv_on_stack = argc < 15;
1043 if (!argv_on_stack) {
1044 struct RArray *a = mrb_ary_ptr(*argv);
1045 argv = ARY_PTR(a);
1046 argc = ARY_LEN(a);
1047 a->c = NULL; /* hide from ObjectSpace.each_object */
1050 opt = FALSE;
1051 i = 0;
1052 while ((c = *format++)) {
1053 mrb_bool altmode = FALSE;
1054 mrb_bool needmodify = FALSE;
1056 for (; *format; format++) {
1057 switch (*format) {
1058 case '!':
1059 if (altmode) goto modifier_exit; /* not accept for multiple '!' */
1060 altmode = TRUE;
1061 break;
1062 case '+':
1063 if (needmodify) goto modifier_exit; /* not accept for multiple '+' */
1064 needmodify = TRUE;
1065 break;
1066 default:
1067 goto modifier_exit;
1071 modifier_exit:
1072 switch (c) {
1073 case '|': case '*': case '&': case '?': case ':':
1074 if (needmodify) {
1075 bad_needmodify:
1076 mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong `%c+` modified specifier`", c);
1078 break;
1079 default:
1080 if (i < argc) {
1081 pickarg = &argv[i++];
1082 if (needmodify && !mrb_nil_p(*pickarg)) {
1083 mrb_check_frozen_value(mrb, *pickarg);
1086 else {
1087 if (opt) {
1088 pickarg = NULL;
1090 else {
1091 mrb_argnum_error(mrb, argc, argc_min, argc_max);
1094 break;
1097 switch (c) {
1098 case 'o':
1099 case 'C':
1100 case 'S':
1101 case 'A':
1102 case 'H':
1104 mrb_value *p;
1106 p = GET_ARG(mrb_value*);
1107 if (pickarg) {
1108 if (!(altmode && mrb_nil_p(*pickarg))) {
1109 switch (c) {
1110 case 'C': ensure_class_type(mrb, *pickarg); break;
1111 case 'S': mrb_ensure_string_type(mrb, *pickarg); break;
1112 case 'A': mrb_ensure_array_type(mrb, *pickarg); break;
1113 case 'H': mrb_ensure_hash_type(mrb, *pickarg); break;
1116 *p = *pickarg;
1119 break;
1120 case 'c':
1122 struct RClass **p;
1124 p = GET_ARG(struct RClass**);
1125 if (pickarg) {
1126 if (altmode && mrb_nil_p(*pickarg)) {
1127 *p = NULL;
1129 else {
1130 ensure_class_type(mrb, *pickarg);
1131 *p = mrb_class_ptr(*pickarg);
1135 break;
1136 case 's':
1138 const char **ps = NULL;
1139 mrb_int *pl = NULL;
1141 ps = GET_ARG(const char**);
1142 pl = GET_ARG(mrb_int*);
1143 if (needmodify) goto bad_needmodify;
1144 if (pickarg) {
1145 if (altmode && mrb_nil_p(*pickarg)) {
1146 *ps = NULL;
1147 *pl = 0;
1149 else {
1150 mrb_ensure_string_type(mrb, *pickarg);
1151 *ps = RSTRING_PTR(*pickarg);
1152 *pl = RSTRING_LEN(*pickarg);
1156 break;
1157 case 'z':
1159 const char **ps;
1161 ps = GET_ARG(const char**);
1162 if (needmodify) goto bad_needmodify;
1163 if (pickarg) {
1164 if (altmode && mrb_nil_p(*pickarg)) {
1165 *ps = NULL;
1167 else {
1168 mrb_ensure_string_type(mrb, *pickarg);
1169 *ps = RSTRING_CSTR(mrb, *pickarg);
1173 break;
1174 case 'a':
1176 struct RArray *a;
1177 const mrb_value **pb;
1178 mrb_int *pl;
1180 pb = GET_ARG(const mrb_value**);
1181 pl = GET_ARG(mrb_int*);
1182 if (needmodify) goto bad_needmodify;
1183 if (pickarg) {
1184 if (altmode && mrb_nil_p(*pickarg)) {
1185 *pb = NULL;
1186 *pl = 0;
1188 else {
1189 mrb_ensure_array_type(mrb, *pickarg);
1190 a = mrb_ary_ptr(*pickarg);
1191 *pb = ARY_PTR(a);
1192 *pl = ARY_LEN(a);
1196 break;
1197 #ifndef MRB_NO_FLOAT
1198 case 'f':
1200 mrb_float *p;
1202 p = GET_ARG(mrb_float*);
1203 if (pickarg) {
1204 *p = mrb_as_float(mrb, *pickarg);
1207 break;
1208 #endif
1209 case 'i':
1211 mrb_int *p;
1213 p = GET_ARG(mrb_int*);
1214 if (pickarg) {
1215 *p = mrb_as_int(mrb, *pickarg);
1218 break;
1219 case 'b':
1221 mrb_bool *boolp = GET_ARG(mrb_bool*);
1223 if (pickarg) {
1224 *boolp = mrb_test(*pickarg);
1227 break;
1228 case 'n':
1230 mrb_sym *symp;
1232 symp = GET_ARG(mrb_sym*);
1233 if (pickarg) {
1234 *symp = to_sym(mrb, *pickarg);
1237 break;
1238 case 'd':
1240 void** datap;
1241 struct mrb_data_type const* type;
1243 datap = GET_ARG(void**);
1244 type = GET_ARG(struct mrb_data_type const*);
1245 if (pickarg) {
1246 if (altmode && mrb_nil_p(*pickarg)) {
1247 *datap = NULL;
1249 else {
1250 *datap = mrb_data_get_ptr(mrb, *pickarg, type);
1254 break;
1256 case '&':
1258 mrb_value *p, *bp;
1260 p = GET_ARG(mrb_value*);
1261 bp = ci->stack + mrb_ci_bidx(ci);
1262 if (altmode && mrb_nil_p(*bp)) {
1263 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
1265 *p = *bp;
1267 break;
1268 case '|':
1269 if (opt_skip && i == argc) goto finish;
1270 opt = TRUE;
1271 break;
1272 case '?':
1274 mrb_bool *p;
1276 p = GET_ARG(mrb_bool*);
1277 *p = pickarg ? TRUE : FALSE;
1279 break;
1281 case '*':
1283 const mrb_value **var;
1284 mrb_int *pl;
1285 mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE;
1287 var = GET_ARG(const mrb_value**);
1288 pl = GET_ARG(mrb_int*);
1289 if (argc > i) {
1290 *pl = argc-i;
1291 if (*pl > 0) {
1292 if (nocopy) {
1293 *var = argv+i;
1295 else {
1296 mrb_value args = mrb_ary_new_from_values(mrb, *pl, argv+i);
1297 RARRAY(args)->c = NULL;
1298 *var = RARRAY_PTR(args);
1301 i = argc;
1303 else {
1304 *pl = 0;
1305 *var = NULL;
1308 break;
1310 case ':':
1312 mrb_value ksrc = mrb_hash_p(kdict) ? mrb_hash_dup(mrb, kdict) : mrb_hash_new(mrb);
1313 const mrb_kwargs *kwargs = GET_ARG(const mrb_kwargs*);
1314 mrb_value *rest;
1316 if (kwargs == NULL) {
1317 rest = NULL;
1319 else {
1320 mrb_int kwnum = kwargs->num;
1321 mrb_int required = kwargs->required;
1322 const mrb_sym *kname = kwargs->table;
1323 mrb_value *values = kwargs->values;
1324 mrb_int j;
1325 const mrb_int keyword_max = 40;
1327 mrb_assert(kwnum >= 0);
1328 mrb_assert(required >= 0);
1329 if (kwnum > keyword_max || required > kwnum) {
1330 mrb_raise(mrb, E_ARGUMENT_ERROR, "keyword number is too large");
1333 for (j = required; j > 0; j--, kname++, values++) {
1334 mrb_value k = mrb_symbol_value(*kname);
1335 if (!mrb_hash_key_p(mrb, ksrc, k)) {
1336 mrb_raisef(mrb, E_ARGUMENT_ERROR, "missing keyword: %n", *kname);
1338 *values = mrb_hash_delete_key(mrb, ksrc, k);
1339 mrb_gc_protect(mrb, *values);
1342 for (j = kwnum - required; j > 0; j--, kname++, values++) {
1343 mrb_value k = mrb_symbol_value(*kname);
1344 if (mrb_hash_key_p(mrb, ksrc, k)) {
1345 *values = mrb_hash_delete_key(mrb, ksrc, k);
1346 mrb_gc_protect(mrb, *values);
1348 else {
1349 *values = mrb_undef_value();
1353 rest = kwargs->rest;
1356 if (rest) {
1357 *rest = ksrc;
1359 else if (!mrb_hash_empty_p(mrb, ksrc)) {
1360 ksrc = mrb_hash_first_key(mrb, ksrc);
1361 mrb_raisef(mrb, E_ARGUMENT_ERROR, "unknown keyword: %v", ksrc);
1364 break;
1366 default:
1367 mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c);
1368 break;
1372 if (!c && argc > i) {
1373 mrb_argnum_error(mrb, argc, argc_min, argc_max);
1376 finish:
1377 return i;
1381 retrieve arguments from mrb_state.
1383 mrb_get_args(mrb, format, ...)
1385 returns number of arguments parsed.
1387 format specifiers:
1389 string mruby type C type note
1390 ----------------------------------------------------------------------------------------------
1391 o: Object [mrb_value]
1392 C: Class/Module [mrb_value] when ! follows, the value may be nil
1393 S: String [mrb_value] when ! follows, the value may be nil
1394 A: Array [mrb_value] when ! follows, the value may be nil
1395 H: Hash [mrb_value] when ! follows, the value may be nil
1396 s: String [const char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil
1397 z: String [const char*] NUL terminated string; z! gives NULL for nil
1398 a: Array [const mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil
1399 c: Class/Module [struct RClass*] c! gives NULL for nil
1400 f: Integer/Float [mrb_float]
1401 i: Integer/Float [mrb_int]
1402 b: boolean [mrb_bool]
1403 n: String/Symbol [mrb_sym]
1404 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
1405 &: block [mrb_value] &! raises exception if no block given
1406 *: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
1407 |: optional Following arguments are optional
1408 ?: optional given [mrb_bool] true if preceding argument (optional) is given
1409 ':': keyword args [mrb_kwargs const] Get keyword arguments
1411 format modifiers:
1413 string note
1414 ----------------------------------------------------------------------------------------------
1415 !: Switch to the alternate mode; The behaviour changes depending on the specifier
1416 +: Request a not frozen object; However, except nil value
1418 MRB_API mrb_int
1419 mrb_get_args(mrb_state *mrb, mrb_args_format format, ...)
1421 va_list ap;
1422 va_start(ap, format);
1423 mrb_int rc = get_args_v(mrb, format, NULL, &ap);
1424 va_end(ap);
1425 return rc;
1428 MRB_API mrb_int
1429 mrb_get_args_a(mrb_state *mrb, mrb_args_format format, void **args)
1431 return get_args_v(mrb, format, args, NULL);
1434 static struct RClass*
1435 boot_defclass(mrb_state *mrb, struct RClass *super)
1437 struct RClass *c = MRB_OBJ_ALLOC(mrb, MRB_TT_CLASS, mrb->class_class);
1439 if (super) {
1440 c->super = super;
1441 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super);
1442 c->flags |= MRB_FL_CLASS_IS_INHERITED;
1444 else {
1445 c->super = mrb->object_class;
1447 c->mt = mt_new(mrb);
1448 return c;
1451 static void
1452 boot_initmod(mrb_state *mrb, struct RClass *mod)
1454 if (!mod->mt) {
1455 mod->mt = mt_new(mrb);
1459 static struct RClass*
1460 include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super)
1462 struct RClass *ic = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, mrb->class_class);
1463 if (m->tt == MRB_TT_ICLASS) {
1464 m = m->c;
1466 MRB_CLASS_ORIGIN(m);
1467 ic->mt = m->mt;
1468 ic->super = super;
1469 if (m->tt == MRB_TT_ICLASS) {
1470 ic->c = m->c;
1472 else {
1473 ic->c = m;
1475 return ic;
1478 static int
1479 include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super)
1481 struct RClass *ic;
1482 void *klass_mt = find_origin(c)->mt;
1484 while (m) {
1485 struct RClass *p = c->super;
1486 int original_seen = FALSE;
1487 int superclass_seen = FALSE;
1489 if (c == ins_pos) original_seen = TRUE;
1490 if (m->flags & MRB_FL_CLASS_IS_PREPENDED)
1491 goto skip;
1492 if (klass_mt && klass_mt == m->mt)
1493 return -1;
1495 while (p) {
1496 if (c == p) original_seen = TRUE;
1497 if (p->tt == MRB_TT_ICLASS) {
1498 if (p->mt == m->mt) {
1499 if (!superclass_seen && original_seen) {
1500 ins_pos = p; /* move insert point */
1502 goto skip;
1505 else if (p->tt == MRB_TT_CLASS) {
1506 if (!search_super) break;
1507 superclass_seen = TRUE;
1509 p = p->super;
1512 ic = include_class_new(mrb, m, ins_pos->super);
1513 m->flags |= MRB_FL_CLASS_IS_INHERITED;
1514 ins_pos->super = ic;
1515 mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic);
1516 ins_pos = ic;
1517 skip:
1518 m = m->super;
1520 mc_clear(mrb);
1521 return 0;
1524 static int
1525 fix_include_module(mrb_state *mrb, struct RBasic *obj, void *data)
1527 struct RClass **m = (struct RClass**)data;
1529 if (obj->tt == MRB_TT_ICLASS && obj->c == m[0] && !MRB_FLAG_TEST(obj, MRB_FL_CLASS_IS_ORIGIN)) {
1530 struct RClass *ic = (struct RClass*)obj;
1531 include_module_at(mrb, ic, ic, m[1], 1);
1533 return MRB_EACH_OBJ_OK;
1536 MRB_API void
1537 mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
1539 mrb_check_frozen(mrb, c);
1540 if (include_module_at(mrb, c, find_origin(c), m, 1) < 0) {
1541 mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected");
1543 if (c->tt == MRB_TT_MODULE && (c->flags & MRB_FL_CLASS_IS_INHERITED)) {
1544 struct RClass *data[2];
1545 data[0] = c;
1546 data[1] = m;
1547 mrb_objspace_each_objects(mrb, fix_include_module, data);
1551 static int
1552 fix_prepend_module(mrb_state *mrb, struct RBasic *obj, void *data)
1554 struct RClass **m = (struct RClass**)data;
1555 struct RClass *c = (struct RClass*)obj;
1557 if (c->tt == MRB_TT_CLASS || c->tt == MRB_TT_MODULE) {
1558 struct RClass *p = c->super;
1559 struct RClass *ins_pos = c;
1560 while (p) {
1561 if (c == m[0]) break;
1562 if (p == m[0]->super->c) {
1563 ins_pos = c;
1565 if (p->tt == MRB_TT_CLASS) break;
1566 if (p->c == m[0]) {
1567 include_module_at(mrb, ins_pos, ins_pos, m[1], 0);
1568 break;
1570 c = p;
1571 p = p->super;
1574 return MRB_EACH_OBJ_OK;
1577 MRB_API void
1578 mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m)
1580 mrb_check_frozen(mrb, c);
1581 if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
1582 struct RClass *origin = MRB_OBJ_ALLOC(mrb, MRB_TT_ICLASS, c);
1583 origin->flags |= MRB_FL_CLASS_IS_ORIGIN | MRB_FL_CLASS_IS_INHERITED;
1584 origin->super = c->super;
1585 c->super = origin;
1586 origin->mt = c->mt;
1587 c->mt = NULL;
1588 mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin);
1589 c->flags |= MRB_FL_CLASS_IS_PREPENDED;
1591 if (include_module_at(mrb, c, c, m, 0) < 0) {
1592 mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected");
1594 if (c->tt == MRB_TT_MODULE &&
1595 (c->flags & (MRB_FL_CLASS_IS_INHERITED|MRB_FL_CLASS_IS_PREPENDED))) {
1596 struct RClass *data[2];
1597 data[0] = c;
1598 data[1] = m;
1599 mrb_objspace_each_objects(mrb, fix_prepend_module, data);
1603 static mrb_value
1604 mrb_mod_prepend(mrb_state *mrb, mrb_value mod)
1606 struct RClass *c = mrb_class_ptr(mod);
1607 mrb_int argc;
1608 mrb_value *argv;
1609 mrb_sym prepended = MRB_SYM(prepended);
1611 mrb_get_args(mrb, "*", &argv, &argc);
1612 while (argc--) {
1613 mrb_value m = argv[argc];
1614 mrb_check_type(mrb, m, MRB_TT_MODULE);
1615 mrb_prepend_module(mrb, c, mrb_class_ptr(m));
1616 if (!mrb_func_basic_p(mrb, m, prepended, mrb_do_nothing)) {
1617 mrb_funcall_argv(mrb, m, prepended, 1, &mod);
1620 return mod;
1623 static mrb_value
1624 mrb_mod_include(mrb_state *mrb, mrb_value mod)
1626 struct RClass *c = mrb_class_ptr(mod);
1627 mrb_int argc;
1628 mrb_value *argv;
1629 mrb_sym included = MRB_SYM(included);
1631 mrb_get_args(mrb, "*", &argv, &argc);
1632 while (argc--) {
1633 mrb_value m = argv[argc];
1634 mrb_check_type(mrb, m, MRB_TT_MODULE);
1635 mrb_include_module(mrb, c, mrb_class_ptr(m));
1636 if (!mrb_func_basic_p(mrb, m, included, mrb_do_nothing)) {
1637 mrb_funcall_argv(mrb, m, included, 1, &mod);
1640 return mod;
1643 /* 15.3.1.3.13 */
1645 * call-seq:
1646 * obj.extend(module, ...) -> obj
1648 * Adds to _obj_ the instance methods from each module given as a
1649 * parameter.
1651 * module Mod
1652 * def hello
1653 * "Hello from Mod.\n"
1654 * end
1655 * end
1657 * class Klass
1658 * def hello
1659 * "Hello from Klass.\n"
1660 * end
1661 * end
1663 * k = Klass.new
1664 * k.hello #=> "Hello from Klass.\n"
1665 * k.extend(Mod) #=> #<Klass:0x401b3bc8>
1666 * k.hello #=> "Hello from Mod.\n"
1669 mrb_value
1670 mrb_obj_extend(mrb_state *mrb, mrb_value obj)
1672 mrb_int argc;
1673 mrb_value *argv;
1674 mrb_sym extended = MRB_SYM(extended);
1676 mrb_get_args(mrb, "*", &argv, &argc);
1678 mrb_value cc = mrb_singleton_class(mrb, obj);
1679 while (argc--) {
1680 mrb_value mod = argv[argc];
1681 mrb_check_type(mrb, mod, MRB_TT_MODULE);
1682 mrb_include_module(mrb, mrb_class_ptr(cc), mrb_class_ptr(mod));
1683 if (!mrb_func_basic_p(mrb, cc, extended, mrb_do_nothing)) {
1684 mrb_funcall_argv(mrb, cc, extended, 1, &mod);
1687 return obj;
1690 /* 15.2.2.4.28 */
1692 * call-seq:
1693 * mod.include?(module) -> true or false
1695 * Returns <code>true</code> if <i>module</i> is included in
1696 * <i>mod</i> or one of <i>mod</i>'s ancestors.
1698 * module A
1699 * end
1700 * class B
1701 * include A
1702 * end
1703 * class C < B
1704 * end
1705 * B.include?(A) #=> true
1706 * C.include?(A) #=> true
1707 * A.include?(A) #=> false
1709 static mrb_value
1710 mrb_mod_include_p(mrb_state *mrb, mrb_value mod)
1712 mrb_value mod2;
1713 struct RClass *c = mrb_class_ptr(mod);
1715 mrb_get_args(mrb, "C", &mod2);
1716 mrb_check_type(mrb, mod2, MRB_TT_MODULE);
1718 while (c) {
1719 if (c->tt == MRB_TT_ICLASS) {
1720 if (c->c == mrb_class_ptr(mod2)) return mrb_true_value();
1722 c = c->super;
1724 return mrb_false_value();
1727 static mrb_value
1728 mrb_mod_ancestors(mrb_state *mrb, mrb_value self)
1730 struct RClass *c = mrb_class_ptr(self);
1731 mrb_value result = mrb_ary_new(mrb);
1733 while (c) {
1734 if (c->tt == MRB_TT_ICLASS) {
1735 mrb_ary_push(mrb, result, mrb_obj_value(c->c));
1737 else if (!(c->flags & MRB_FL_CLASS_IS_PREPENDED)) {
1738 mrb_ary_push(mrb, result, mrb_obj_value(c));
1740 c = c->super;
1743 return result;
1746 static mrb_value
1747 mrb_mod_initialize(mrb_state *mrb, mrb_value mod)
1749 mrb_value b;
1750 struct RClass *m = mrb_class_ptr(mod);
1751 boot_initmod(mrb, m); /* bootstrap a newly initialized module */
1752 mrb_get_args(mrb, "|&", &b);
1753 if (!mrb_nil_p(b)) {
1754 mrb_yield_with_class(mrb, b, 1, &mod, mod, m);
1756 return mod;
1759 static void
1760 mrb_mod_visibility(mrb_state *mrb, mrb_value mod, int vis)
1762 mrb_assert((vis&MT_VMASK)==vis);
1763 mrb_int argc;
1764 mrb_value *argv;
1765 struct RClass *c = mrb_class_ptr(mod);
1767 mrb_get_args(mrb, "*!", &argv, &argc);
1768 if (argc == 0) {
1769 mrb_callinfo *ci;
1770 struct REnv *e;
1771 find_visibility_scope(mrb, NULL, 1, &ci, &e);
1772 if (e) {
1773 MRB_ENV_SET_VISIBILITY(e, vis);
1775 else {
1776 MRB_CI_SET_VISIBILITY(ci, vis);
1779 else {
1780 mt_tbl *h = c->mt;
1781 for (int i=0; i<argc; i++) {
1782 mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
1783 mrb_sym mid = mrb_symbol(argv[i]);
1784 mrb_method_t m = mrb_method_search(mrb, c, mid);
1785 MRB_METHOD_SET_VISIBILITY(m, vis);
1786 union mt_ptr ptr;
1787 if (MRB_METHOD_PROC_P(m)) {
1788 ptr.proc = MRB_METHOD_PROC(m);
1790 else {
1791 ptr.func = MRB_METHOD_FUNC(m);
1793 mt_put(mrb, h, mid, MT_KEY_FLG(m.flags), ptr);
1794 mc_clear_by_id(mrb, mid);
1799 static mrb_value
1800 mrb_mod_public(mrb_state *mrb, mrb_value mod)
1802 mrb_mod_visibility(mrb, mod, MT_PUBLIC);
1803 return mod;
1806 static mrb_value
1807 mrb_mod_private(mrb_state *mrb, mrb_value mod)
1809 mrb_mod_visibility(mrb, mod, MT_PRIVATE);
1810 return mod;
1813 static mrb_value
1814 mrb_mod_protected(mrb_state *mrb, mrb_value mod)
1816 mrb_mod_visibility(mrb, mod, MT_PROTECTED);
1817 return mod;
1820 static mrb_value
1821 top_public(mrb_state *mrb, mrb_value self)
1823 self = mrb_obj_value(mrb->object_class);
1824 mrb_mod_visibility(mrb, self, MT_PUBLIC);
1825 return self;
1828 static mrb_value
1829 top_private(mrb_state *mrb, mrb_value self)
1831 self = mrb_obj_value(mrb->object_class);
1832 mrb_mod_visibility(mrb, self, MT_PRIVATE);
1833 return self;
1836 static mrb_value
1837 top_protected(mrb_state *mrb, mrb_value self)
1839 self = mrb_obj_value(mrb->object_class);
1840 mrb_mod_visibility(mrb, self, MT_PROTECTED);
1841 return self;
1844 MRB_API struct RClass*
1845 mrb_singleton_class_ptr(mrb_state *mrb, mrb_value v)
1847 struct RBasic *obj;
1849 switch (mrb_type(v)) {
1850 case MRB_TT_FALSE:
1851 if (mrb_nil_p(v))
1852 return mrb->nil_class;
1853 return mrb->false_class;
1854 case MRB_TT_TRUE:
1855 return mrb->true_class;
1856 case MRB_TT_CPTR:
1857 case MRB_TT_SYMBOL:
1858 case MRB_TT_INTEGER:
1859 #ifndef MRB_NO_FLOAT
1860 case MRB_TT_FLOAT:
1861 #endif
1862 return NULL;
1863 default:
1864 break;
1866 obj = mrb_basic_ptr(v);
1867 if (obj->c == NULL) return NULL;
1868 prepare_singleton_class(mrb, obj);
1869 return obj->c;
1872 MRB_API mrb_value
1873 mrb_singleton_class(mrb_state *mrb, mrb_value v)
1875 struct RClass *c = mrb_singleton_class_ptr(mrb, v);
1877 if (c == NULL) {
1878 mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton");
1880 return mrb_obj_value(c);
1883 MRB_API void
1884 mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec)
1886 prepare_singleton_class(mrb, (struct RBasic*)o);
1887 mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec);
1890 MRB_API void
1891 mrb_define_singleton_method_id(mrb_state *mrb, struct RObject *o, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
1893 prepare_singleton_class(mrb, (struct RBasic*)o);
1894 mrb_define_method_id(mrb, o->c, name, func, aspec);
1897 MRB_API void
1898 mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1900 mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec);
1903 MRB_API void
1904 mrb_define_class_method_id(mrb_state *mrb, struct RClass *c, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
1906 mrb_define_singleton_method_id(mrb, (struct RObject*)c, name, func, aspec);
1909 MRB_API void
1910 mrb_define_module_function_id(mrb_state *mrb, struct RClass *c, mrb_sym name, mrb_func_t func, mrb_aspec aspec)
1912 mrb_define_class_method_id(mrb, c, name, func, aspec);
1913 mrb_define_private_method_id(mrb, c, name, func, aspec);
1916 MRB_API void
1917 mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec)
1919 mrb_define_module_function_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec);
1922 #ifndef MRB_NO_METHOD_CACHE
1923 /* clear whole method cache table */
1924 static void
1925 mc_clear(mrb_state *mrb)
1927 static const struct mrb_cache_entry ce_zero ={0};
1929 for (int i=0; i<MRB_METHOD_CACHE_SIZE; i++) {
1930 mrb->cache[i] = ce_zero;
1934 /* clear method cache for a class */
1935 void
1936 mrb_mc_clear_by_class(mrb_state *mrb, struct RClass *c)
1938 struct mrb_cache_entry *mc = mrb->cache;
1940 for (int i=0; i<MRB_METHOD_CACHE_SIZE; mc++,i++) {
1941 if (mc->c == c || mc->c0 == c) mc->c = NULL;
1945 static void
1946 mc_clear_by_id(mrb_state *mrb, mrb_sym id)
1948 struct mrb_cache_entry *mc = mrb->cache;
1950 for (int i=0; i<MRB_METHOD_CACHE_SIZE; mc++,i++) {
1951 if (METHOD_MID(mc->m) == id) mc->c = NULL;
1954 #endif // MRB_NO_METHOD_CACHE
1956 mrb_method_t
1957 mrb_vm_find_method(mrb_state *mrb, struct RClass *c, struct RClass **cp, mrb_sym mid)
1959 mrb_method_t m;
1960 #ifndef MRB_NO_METHOD_CACHE
1961 struct RClass *oc = c;
1962 int h = mrb_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1);
1963 struct mrb_cache_entry *mc = &mrb->cache[h];
1965 if (mc->c == c && METHOD_MID(mc->m) == mid) {
1966 *cp = mc->c0;
1967 return mc->m;
1969 #endif
1971 while (c) {
1972 mt_tbl *h = c->mt;
1974 if (h) {
1975 union mt_ptr ptr;
1976 mrb_sym ret = mt_get(mrb, h, mid, &ptr);
1977 if (ret) {
1978 if (ptr.proc == 0) break;
1979 *cp = c;
1980 m = create_method_value(mrb, ret, ptr);
1981 #ifndef MRB_NO_METHOD_CACHE
1982 mc->c = oc;
1983 mc->c0 = c;
1984 mc->m = m;
1985 #endif
1986 return m;
1989 c = c->super;
1991 MRB_METHOD_FROM_PROC(m, NULL);
1992 return m; /* no method */
1995 MRB_API mrb_method_t
1996 mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid)
1998 return mrb_vm_find_method(mrb, *cp, cp, mid);
2001 MRB_API mrb_method_t
2002 mrb_method_search(mrb_state *mrb, struct RClass *c, mrb_sym mid)
2004 mrb_method_t m;
2006 m = mrb_method_search_vm(mrb, &c, mid);
2007 if (MRB_METHOD_UNDEF_P(m)) {
2008 mrb_name_error(mrb, mid, "undefined method '%n' for class %C", mid, c);
2010 return m;
2013 #define ONSTACK_ALLOC_MAX 32
2015 static mrb_sym
2016 prepare_name_common(mrb_state *mrb, mrb_sym sym, const char *prefix, const char *suffix)
2018 char onstack[ONSTACK_ALLOC_MAX];
2019 mrb_int sym_len;
2020 const char *sym_str = mrb_sym_name_len(mrb, sym, &sym_len);
2021 size_t prefix_len = prefix ? strlen(prefix) : 0;
2022 size_t suffix_len = suffix ? strlen(suffix) : 0;
2023 size_t name_len = sym_len + prefix_len + suffix_len;
2024 char *buf = name_len > sizeof(onstack) ? (char*)mrb_alloca(mrb, name_len) : onstack;
2025 char *p = buf;
2027 if (prefix_len > 0) {
2028 memcpy(p, prefix, prefix_len);
2029 p += prefix_len;
2032 memcpy(p, sym_str, sym_len);
2033 p += sym_len;
2035 if (suffix_len > 0) {
2036 memcpy(p, suffix, suffix_len);
2039 return mrb_intern(mrb, buf, name_len);
2042 static mrb_value
2043 prepare_ivar_name(mrb_state *mrb, mrb_sym sym)
2045 sym = prepare_name_common(mrb, sym, "@", NULL);
2046 mrb_iv_name_sym_check(mrb, sym);
2047 return mrb_symbol_value(sym);
2050 static mrb_sym
2051 prepare_writer_name(mrb_state *mrb, mrb_sym sym)
2053 return prepare_name_common(mrb, sym, NULL, "=");
2056 static mrb_value
2057 mod_attr_define(mrb_state *mrb, mrb_value mod, mrb_value (*accessor)(mrb_state*, mrb_value), mrb_sym (*access_name)(mrb_state*, mrb_sym))
2059 struct RClass *c = mrb_class_ptr(mod);
2060 const mrb_value *argv;
2061 mrb_int argc;
2063 mrb_get_args(mrb, "*", &argv, &argc);
2065 int ai = mrb_gc_arena_save(mrb);
2066 for (int i=0; i<argc; i++) {
2067 mrb_value name;
2068 mrb_sym method;
2069 struct RProc *p;
2070 mrb_method_t m;
2072 method = to_sym(mrb, argv[i]);
2073 name = prepare_ivar_name(mrb, method);
2074 if (access_name) {
2075 method = access_name(mrb, method);
2078 p = mrb_proc_new_cfunc_with_env(mrb, accessor, 1, &name);
2079 MRB_METHOD_FROM_PROC(m, p);
2080 mrb_define_method_raw(mrb, c, method, m);
2081 mrb_gc_arena_restore(mrb, ai);
2083 return mrb_nil_value();
2086 static mrb_value
2087 attr_reader(mrb_state *mrb, mrb_value obj)
2089 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
2090 return mrb_iv_get(mrb, obj, to_sym(mrb, name));
2093 static mrb_value
2094 mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod)
2096 return mod_attr_define(mrb, mod, attr_reader, NULL);
2099 static mrb_value
2100 attr_writer(mrb_state *mrb, mrb_value obj)
2102 mrb_value name = mrb_proc_cfunc_env_get(mrb, 0);
2103 mrb_value val = mrb_get_arg1(mrb);
2105 mrb_iv_set(mrb, obj, to_sym(mrb, name), val);
2106 return val;
2109 static mrb_value
2110 mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod)
2112 return mod_attr_define(mrb, mod, attr_writer, prepare_writer_name);
2115 static mrb_value
2116 mrb_mod_attr_accessor(mrb_state *mrb, mrb_value mod)
2118 mrb_mod_attr_reader(mrb, mod);
2119 return mrb_mod_attr_writer(mrb, mod);
2122 static mrb_value
2123 mrb_instance_alloc(mrb_state *mrb, mrb_value cv)
2125 struct RClass *c = mrb_class_ptr(cv);
2126 enum mrb_vtype ttype = MRB_INSTANCE_TT(c);
2128 if (c->tt == MRB_TT_SCLASS)
2129 mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class");
2131 if (c == mrb->nil_class || c == mrb->false_class) {
2132 mrb_assert(ttype == 0);
2134 else if (ttype == 0) {
2135 ttype = MRB_TT_OBJECT;
2137 if (MRB_UNDEF_ALLOCATOR_P(c)) {
2138 mrb_raisef(mrb, E_TYPE_ERROR, "allocator undefined for %v", cv);
2140 if (ttype <= MRB_TT_CPTR) {
2141 mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %v", cv);
2144 struct RObject *o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
2145 return mrb_obj_value(o);
2149 * call-seq:
2150 * class.new(args, ...) -> obj
2152 * Creates a new object of <i>class</i>'s class, then
2153 * invokes that object's <code>initialize</code> method,
2154 * passing it <i>args</i>. This is the method that ends
2155 * up getting called whenever an object is constructed using
2156 * `.new`.
2160 mrb_value
2161 mrb_instance_new(mrb_state *mrb, mrb_value cv)
2163 const mrb_value *argv;
2164 mrb_int argc;
2165 mrb_value blk;
2166 mrb_sym init;
2168 mrb_get_args(mrb, "*!&", &argv, &argc, &blk);
2169 mrb_value obj = mrb_instance_alloc(mrb, cv);
2170 init = MRB_SYM(initialize);
2171 if (!mrb_func_basic_p(mrb, obj, init, mrb_do_nothing)) {
2172 mrb_funcall_with_block(mrb, obj, init, argc, argv, blk);
2174 return obj;
2177 MRB_API mrb_value
2178 mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv)
2180 mrb_value obj = mrb_instance_alloc(mrb, mrb_obj_value(c));
2181 mrb_sym mid = MRB_SYM(initialize);
2183 if (!mrb_func_basic_p(mrb, obj, mid, mrb_do_nothing)) {
2184 mrb_funcall_argv(mrb, obj, mid, argc, argv);
2186 return obj;
2189 static mrb_value
2190 mrb_class_initialize(mrb_state *mrb, mrb_value obj)
2192 struct RClass *c = mrb_class_ptr(obj);
2194 if (c->iv) {
2195 mrb_raise(mrb, E_TYPE_ERROR, "already initialized class");
2198 mrb_value a, b;
2199 mrb_get_args(mrb, "|C&", &a, &b);
2200 if (!mrb_nil_p(b)) {
2201 mrb_yield_with_class(mrb, b, 1, &obj, obj, c);
2203 return obj;
2206 static mrb_value
2207 mrb_class_new_class(mrb_state *mrb, mrb_value cv)
2209 mrb_value super, blk;
2210 mrb_int n = mrb_get_args(mrb, "|C&", &super, &blk);
2212 if (n == 0) {
2213 super = mrb_obj_value(mrb->object_class);
2215 mrb_value new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super)));
2216 mrb_sym mid = MRB_SYM(initialize);
2217 if (mrb_func_basic_p(mrb, new_class, mid, mrb_class_initialize)) {
2218 mrb_class_initialize(mrb, new_class);
2220 else {
2221 mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk);
2223 mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class));
2224 return new_class;
2227 static mrb_value
2228 mrb_class_superclass(mrb_state *mrb, mrb_value klass)
2230 struct RClass *c = mrb_class_ptr(klass);
2232 c = find_origin(c)->super;
2233 while (c && c->tt == MRB_TT_ICLASS) {
2234 c = find_origin(c)->super;
2236 if (!c) return mrb_nil_value();
2237 return mrb_obj_value(c);
2240 static mrb_value
2241 mrb_do_nothing(mrb_state *mrb, mrb_value cv)
2243 return mrb_nil_value();
2246 static mrb_value
2247 mrb_bob_not(mrb_state *mrb, mrb_value cv)
2249 return mrb_bool_value(!mrb_test(cv));
2252 /* 15.3.1.3.1 */
2253 /* 15.3.1.3.10 */
2254 /* 15.3.1.3.11 */
2256 * call-seq:
2257 * obj == other -> true or false
2258 * obj.equal?(other) -> true or false
2259 * obj.eql?(other) -> true or false
2261 * Equality---At the <code>Object</code> level, <code>==</code> returns
2262 * <code>true</code> only if <i>obj</i> and <i>other</i> are the
2263 * same object. Typically, this method is overridden in descendant
2264 * classes to provide class-specific meaning.
2266 * Unlike <code>==</code>, the <code>equal?</code> method should never be
2267 * overridden by subclasses: it is used to determine object identity
2268 * (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
2269 * object as <code>b</code>).
2271 * The <code>eql?</code> method returns <code>true</code> if
2272 * <i>obj</i> and <i>anObject</i> have the same value. Used by
2273 * <code>Hash</code> to test members for equality. For objects of
2274 * class <code>Object</code>, <code>eql?</code> is synonymous with
2275 * <code>==</code>. Subclasses normally continue this tradition, but
2276 * there are exceptions. <code>Numeric</code> types, for example,
2277 * perform type conversion across <code>==</code>, but not across
2278 * <code>eql?</code>, so:
2280 * 1 == 1.0 #=> true
2281 * 1.eql? 1.0 #=> false
2283 mrb_value
2284 mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
2286 mrb_value arg = mrb_get_arg1(mrb);
2288 return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
2291 MRB_API mrb_bool
2292 mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid)
2294 mrb_method_t m = mrb_method_search_vm(mrb, &c, mid);
2296 if (MRB_METHOD_UNDEF_P(m)) {
2297 return FALSE;
2299 return TRUE;
2302 MRB_API mrb_bool
2303 mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid)
2305 return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid);
2308 MRB_API mrb_value
2309 mrb_class_path(mrb_state *mrb, struct RClass *c)
2311 mrb_sym nsym = MRB_SYM(__classname__);
2312 mrb_value path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym);
2314 if (mrb_nil_p(path)) {
2315 /* no name (yet) */
2316 return mrb_class_find_path(mrb, c);
2318 else if (mrb_symbol_p(path)) {
2319 /* toplevel class/module */
2320 return mrb_sym_str(mrb, mrb_symbol(path));
2322 return mrb_str_dup(mrb, path);
2325 MRB_API struct RClass*
2326 mrb_class_real(struct RClass* cl)
2328 if (cl == 0) return NULL;
2329 while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) {
2330 cl = cl->super;
2331 if (cl == 0) return NULL;
2333 return cl;
2336 MRB_API const char*
2337 mrb_class_name(mrb_state *mrb, struct RClass* c)
2339 if (c == NULL) return NULL;
2341 mrb_value name = class_name_str(mrb, c);
2342 return RSTRING_PTR(name);
2345 MRB_API const char*
2346 mrb_obj_classname(mrb_state *mrb, mrb_value obj)
2348 return mrb_class_name(mrb, mrb_obj_class(mrb, obj));
2352 * Ensures a class can be derived from super.
2354 * \param super a reference to an object.
2355 * \exception TypeError if \a super is not a Class or \a super is a singleton class.
2357 static void
2358 mrb_check_inheritable(mrb_state *mrb, struct RClass *super)
2360 if (super->tt != MRB_TT_CLASS) {
2361 mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%C given)", super);
2363 if (super->tt == MRB_TT_SCLASS) {
2364 mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class");
2366 if (super == mrb->class_class) {
2367 mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class");
2372 * Creates a new class.
2373 * \param super a class from which the new class derives.
2374 * \exception TypeError \a super is not inheritable.
2375 * \exception TypeError \a super is the Class class.
2377 MRB_API struct RClass*
2378 mrb_class_new(mrb_state *mrb, struct RClass *super)
2380 if (super) {
2381 mrb_check_inheritable(mrb, super);
2384 struct RClass *c = boot_defclass(mrb, super);
2385 if (super) {
2386 MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super));
2387 c->flags |= super->flags & MRB_FL_UNDEF_ALLOCATE;
2389 make_metaclass(mrb, c);
2391 return c;
2395 * Creates a new module.
2397 MRB_API struct RClass*
2398 mrb_module_new(mrb_state *mrb)
2400 struct RClass *m = MRB_OBJ_ALLOC(mrb, MRB_TT_MODULE, mrb->module_class);
2401 boot_initmod(mrb, m);
2402 return m;
2406 * call-seq:
2407 * obj.class => class
2409 * Returns the class of <i>obj</i>, now preferred over
2410 * <code>Object#type</code>, as an object's type in Ruby is only
2411 * loosely tied to that object's class. This method must always be
2412 * called with an explicit receiver, as <code>class</code> is also a
2413 * reserved word in Ruby.
2415 * 1.class #=> Integer
2416 * self.class #=> Object
2419 MRB_API struct RClass*
2420 mrb_obj_class(mrb_state *mrb, mrb_value obj)
2422 return mrb_class_real(mrb_class(mrb, obj));
2425 MRB_API void
2426 mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b)
2428 if (a == b) return;
2429 mrb_method_t m = mrb_method_search(mrb, c, b);
2431 if (!MRB_METHOD_CFUNC_P(m)) {
2432 const struct RProc *p = MRB_METHOD_PROC(m);
2433 if (!MRB_PROC_CFUNC_P(p) && !MRB_PROC_ALIAS_P(p)) {
2434 struct RProc *pnew = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class);
2435 int vis = MRB_METHOD_VISIBILITY(m);
2437 pnew->body.mid = b;
2438 pnew->upper = p;
2439 pnew->e.env = NULL;
2440 pnew->flags |= MRB_PROC_ALIAS;
2441 MRB_METHOD_FROM_PROC(m, pnew);
2442 MRB_METHOD_SET_VISIBILITY(m, vis);
2445 mrb_define_method_raw(mrb, c, a, m);
2449 * Defines an alias of a method.
2450 * \param mrb the mruby state
2451 * \param klass the class which the original method belongs to
2452 * \param name1 a new name for the method
2453 * \param name2 the original name of the method
2455 MRB_API void
2456 mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2)
2458 mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2));
2461 MRB_API void
2462 mrb_define_alias_id(mrb_state *mrb, struct RClass *klass, mrb_sym a, mrb_sym b)
2464 mrb_alias_method(mrb, klass, a, b);
2468 * call-seq:
2469 * mod.to_s -> string
2471 * Return a string representing this module or class. For basic
2472 * classes and modules, this is the name. For singletons, we
2473 * show information on the thing we're attached to as well.
2476 mrb_value
2477 mrb_mod_to_s(mrb_state *mrb, mrb_value klass)
2479 if (mrb_sclass_p(klass)) {
2480 mrb_value v = mrb_iv_get(mrb, klass, MRB_SYM(__attached__));
2481 mrb_value str = mrb_str_new_lit(mrb, "#<Class:");
2483 if (class_ptr_p(v)) {
2484 mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v));
2486 else {
2487 mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v));
2489 return mrb_str_cat_lit(mrb, str, ">");
2491 else {
2492 return class_name_str(mrb, mrb_class_ptr(klass));
2496 static mrb_value
2497 mrb_mod_alias(mrb_state *mrb, mrb_value mod)
2499 struct RClass *c = mrb_class_ptr(mod);
2500 mrb_sym new_name, old_name;
2502 mrb_get_args(mrb, "nn", &new_name, &old_name);
2503 mrb_alias_method(mrb, c, new_name, old_name);
2504 mrb_method_added(mrb, c, new_name);
2505 return mod;
2508 static void
2509 undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a)
2511 mrb_method_t m;
2512 mrb_sym undefined;
2513 mrb_value recv;
2515 MRB_METHOD_FROM_PROC(m, NULL);
2516 mrb_define_method_raw(mrb, c, a, m);
2517 if (c->tt == MRB_TT_SCLASS) {
2518 undefined = MRB_SYM(singleton_method_undefined);
2519 recv = mrb_iv_get(mrb, mrb_obj_value(c), MRB_SYM(__attached__));
2521 else {
2522 undefined = MRB_SYM(method_undefined);
2523 recv = mrb_obj_value(c);
2525 if (!mrb_func_basic_p(mrb, recv, undefined, mrb_do_nothing)) {
2526 mrb_value sym = mrb_symbol_value(a);
2527 mrb_funcall_argv(mrb, recv, undefined, 1, &sym);
2531 MRB_API void
2532 mrb_undef_method_id(mrb_state *mrb, struct RClass *c, mrb_sym a)
2534 if (!mrb_obj_respond_to(mrb, c, a)) {
2535 mrb_name_error(mrb, a, "undefined method '%n' for class '%C'", a, c);
2537 undef_method(mrb, c, a);
2540 MRB_API void
2541 mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name)
2543 undef_method(mrb, c, mrb_intern_cstr(mrb, name));
2546 MRB_API void
2547 mrb_undef_class_method_id(mrb_state *mrb, struct RClass *c, mrb_sym name)
2549 mrb_undef_method_id(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
2552 MRB_API void
2553 mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name)
2555 mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name);
2558 MRB_API void
2559 mrb_remove_method(mrb_state *mrb, struct RClass *c0, mrb_sym mid)
2561 struct RClass *c = c0;
2562 MRB_CLASS_ORIGIN(c);
2563 mt_tbl *h = c->mt;
2565 if (h && mt_del(mrb, h, mid)) {
2566 mrb_sym removed;
2567 mrb_value recv;
2569 mc_clear_by_id(mrb, mid);
2570 if (c0->tt == MRB_TT_SCLASS) {
2571 removed = MRB_SYM(singleton_method_removed);
2572 recv = mrb_iv_get(mrb, mrb_obj_value(c0), MRB_SYM(__attached__));
2574 else {
2575 removed = MRB_SYM(method_removed);
2576 recv = mrb_obj_value(c0);
2578 if (!mrb_func_basic_p(mrb, recv, removed, mrb_do_nothing)) {
2579 mrb_value sym = mrb_symbol_value(mid);
2580 mrb_funcall_argv(mrb, recv, removed, 1, &sym);
2582 return;
2584 mrb_name_error(mrb, mid, "method '%n' not defined in %C", mid, c);
2587 static mrb_value
2588 mrb_mod_undef(mrb_state *mrb, mrb_value mod)
2590 struct RClass *c = mrb_class_ptr(mod);
2591 mrb_int argc;
2592 const mrb_value *argv;
2594 mrb_get_args(mrb, "*", &argv, &argc);
2595 while (argc--) {
2596 mrb_undef_method_id(mrb, c, to_sym(mrb, *argv));
2597 argv++;
2599 return mrb_nil_value();
2602 static void
2603 check_const_name_sym(mrb_state *mrb, mrb_sym id)
2605 mrb_int len;
2606 const char *name = mrb_sym_name_len(mrb, id, &len);
2607 if (!mrb_const_name_p(mrb, name, len)) {
2608 mrb_name_error(mrb, id, "wrong constant name %n", id);
2612 static mrb_value
2613 mrb_mod_const_defined(mrb_state *mrb, mrb_value mod)
2615 mrb_sym id;
2616 mrb_bool inherit = TRUE;
2618 mrb_get_args(mrb, "n|b", &id, &inherit);
2619 check_const_name_sym(mrb, id);
2620 if (inherit) {
2621 return mrb_bool_value(mrb_const_defined(mrb, mod, id));
2623 return mrb_bool_value(mrb_const_defined_at(mrb, mod, id));
2626 static mrb_value
2627 mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id)
2629 check_const_name_sym(mrb, id);
2630 return mrb_const_get(mrb, mod, id);
2633 static mrb_value
2634 mrb_mod_const_get(mrb_state *mrb, mrb_value mod)
2636 mrb_value path = mrb_get_arg1(mrb);
2638 if (mrb_symbol_p(path)) {
2639 /* const get with symbol */
2640 return mrb_const_get_sym(mrb, mod, mrb_symbol(path));
2643 /* const get with class path string */
2644 mrb_ensure_string_type(mrb, path);
2646 char *ptr = RSTRING_PTR(path);
2647 mrb_int len = RSTRING_LEN(path);
2648 mrb_int off = 0;
2650 while (off < len) {
2651 mrb_int end = mrb_str_index_lit(mrb, path, "::", off);
2652 if (end == -1) end = len;
2653 mrb_sym id = mrb_intern(mrb, ptr+off, end-off);
2654 mod = mrb_const_get_sym(mrb, mod, id);
2655 if (end == len)
2656 off = end;
2657 else {
2658 off = end + 2;
2659 if (off == len) { /* trailing "::" */
2660 mrb_name_error(mrb, id, "wrong constant name '%v'", path);
2665 return mod;
2668 static mrb_value
2669 mrb_mod_const_set(mrb_state *mrb, mrb_value mod)
2671 mrb_sym id;
2672 mrb_value value;
2674 mrb_get_args(mrb, "no", &id, &value);
2675 check_const_name_sym(mrb, id);
2676 mrb_const_set(mrb, mod, id, value);
2677 return value;
2680 static mrb_value
2681 mrb_mod_remove_const(mrb_state *mrb, mrb_value mod)
2683 mrb_sym id;
2685 mrb_get_args(mrb, "n", &id);
2686 check_const_name_sym(mrb, id);
2688 mrb_value val = mrb_iv_remove(mrb, mod, id);
2689 if (mrb_undef_p(val)) {
2690 mrb_name_error(mrb, id, "constant %n not defined", id);
2692 return val;
2695 mrb_value
2696 mrb_const_missing(mrb_state *mrb, mrb_value mod, mrb_sym sym)
2698 if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) {
2699 mrb_name_error(mrb, sym, "uninitialized constant %v::%n", mod, sym);
2701 else {
2702 mrb_name_error(mrb, sym, "uninitialized constant %n", sym);
2704 /* not reached */
2705 return mrb_nil_value();
2708 mrb_value
2709 mrb_mod_const_missing(mrb_state *mrb, mrb_value mod)
2711 mrb_sym sym;
2713 mrb_get_args(mrb, "n", &sym);
2714 mrb->c->ci->mid = 0;
2715 return mrb_const_missing(mrb, mod, sym);
2718 /* 15.2.2.4.34 */
2720 * call-seq:
2721 * mod.method_defined?(symbol) -> true or false
2723 * Returns +true+ if the named method is defined by
2724 * _mod_ (or its included modules and, if _mod_ is a class,
2725 * its ancestors). Public and protected methods are matched.
2727 * module A
2728 * def method1() end
2729 * end
2730 * class B
2731 * def method2() end
2732 * end
2733 * class C < B
2734 * include A
2735 * def method3() end
2736 * end
2738 * A.method_defined? :method1 #=> true
2739 * C.method_defined? "method1" #=> true
2740 * C.method_defined? "method2" #=> true
2741 * C.method_defined? "method3" #=> true
2742 * C.method_defined? "method4" #=> false
2745 static mrb_value
2746 mrb_mod_method_defined(mrb_state *mrb, mrb_value mod)
2748 mrb_sym id;
2750 mrb_get_args(mrb, "n", &id);
2751 return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id));
2754 void
2755 mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid)
2757 mrb_sym added;
2758 mrb_value recv = mrb_obj_value(c);
2760 if (c->tt == MRB_TT_SCLASS) {
2761 added = MRB_SYM(singleton_method_added);
2762 recv = mrb_iv_get(mrb, recv, MRB_SYM(__attached__));
2764 else {
2765 added = MRB_SYM(method_added);
2767 if (!mrb_func_basic_p(mrb, recv, added, mrb_do_nothing)) {
2768 mrb_value sym = mrb_symbol_value(mid);
2769 mrb_funcall_argv(mrb, recv, added, 1, &sym);
2773 mrb_value
2774 define_method_m(mrb_state *mrb, struct RClass *c, int vis)
2776 mrb_sym mid;
2777 mrb_value proc = mrb_undef_value();
2778 mrb_value blk;
2780 mrb_get_args(mrb, "n|o&", &mid, &proc, &blk);
2781 switch (mrb_type(proc)) {
2782 case MRB_TT_PROC:
2783 blk = proc;
2784 break;
2785 case MRB_TT_UNDEF:
2786 /* ignored */
2787 break;
2788 default:
2789 mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %T (expected Proc)", proc);
2790 break;
2792 if (mrb_nil_p(blk)) {
2793 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
2795 struct RProc *p = MRB_OBJ_ALLOC(mrb, MRB_TT_PROC, mrb->proc_class);
2796 mrb_proc_copy(mrb, p, mrb_proc_ptr(blk));
2797 p->flags |= MRB_PROC_STRICT;
2799 mrb_method_t m;
2800 MRB_METHOD_FROM_PROC(m, p);
2801 MRB_METHOD_SET_VISIBILITY(m, vis);
2802 mrb_define_method_raw(mrb, c, mid, m);
2803 mrb_method_added(mrb, c, mid);
2804 return mrb_symbol_value(mid);
2807 mrb_value
2808 mrb_mod_define_method_m(mrb_state *mrb, struct RClass *c)
2810 return define_method_m(mrb, c, MT_PUBLIC);
2813 static mrb_value
2814 mod_define_method(mrb_state *mrb, mrb_value self)
2816 return mrb_mod_define_method_m(mrb, mrb_class_ptr(self));
2819 static mrb_value
2820 top_define_method(mrb_state *mrb, mrb_value self)
2822 return define_method_m(mrb, mrb->object_class, MT_PRIVATE);
2825 static mrb_value
2826 mrb_mod_eqq(mrb_state *mrb, mrb_value mod)
2828 mrb_value obj = mrb_get_arg1(mrb);
2829 mrb_bool eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod));
2831 return mrb_bool_value(eqq);
2834 static mrb_value
2835 mrb_mod_dup(mrb_state *mrb, mrb_value self)
2837 mrb_value mod = mrb_obj_clone(mrb, self);
2838 mrb_obj_ptr(mod)->frozen = 0;
2839 return mod;
2842 static mrb_value
2843 mrb_mod_module_function(mrb_state *mrb, mrb_value mod)
2845 const mrb_value *argv;
2846 mrb_int argc;
2848 mrb_check_type(mrb, mod, MRB_TT_MODULE);
2850 mrb_get_args(mrb, "*", &argv, &argc);
2851 if (argc == 0) {
2852 /* set MODFUNC SCOPE if implemented */
2853 return mod;
2856 /* set PRIVATE method visibility if implemented */
2857 /* mrb_mod_dummy_visibility(mrb, mod); */
2859 struct RClass *rclass = mrb_class_ptr(mod);
2860 int ai = mrb_gc_arena_save(mrb);
2861 for (int i=0; i<argc; i++) {
2862 mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL);
2864 mrb_sym mid = mrb_symbol(argv[i]);
2865 mrb_method_t m = mrb_method_search(mrb, rclass, mid);
2867 prepare_singleton_class(mrb, (struct RBasic*)rclass);
2868 MRB_METHOD_SET_VISIBILITY(m, MT_PUBLIC);
2869 mrb_define_method_raw(mrb, rclass->c, mid, m);
2870 mrb_gc_arena_restore(mrb, ai);
2873 return mod;
2876 static struct RClass*
2877 mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
2879 struct RClass *klass = mrb_basic_ptr(obj)->c;
2881 if (klass->tt != MRB_TT_SCLASS)
2882 return klass;
2883 else {
2884 /* copy singleton(unnamed) class */
2885 struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
2887 switch (mrb_type(obj)) {
2888 case MRB_TT_CLASS:
2889 case MRB_TT_SCLASS:
2890 break;
2891 default:
2892 clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
2893 break;
2895 clone->super = klass->super;
2896 if (klass->iv) {
2897 mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass));
2898 mrb_obj_iv_set(mrb, (struct RObject*)clone, MRB_SYM(__attached__), obj);
2900 if (klass->mt) {
2901 clone->mt = mt_copy(mrb, klass->mt);
2903 else {
2904 clone->mt = mt_new(mrb);
2906 clone->tt = MRB_TT_SCLASS;
2907 return clone;
2911 static void
2912 copy_class(mrb_state *mrb, mrb_value dst, mrb_value src)
2914 struct RClass *dc = mrb_class_ptr(dst);
2915 struct RClass *sc = mrb_class_ptr(src);
2916 /* if the origin is not the same as the class, then the origin and
2917 the current class need to be copied */
2918 if (sc->flags & MRB_FL_CLASS_IS_PREPENDED) {
2919 struct RClass *c0 = sc->super;
2920 struct RClass *c1 = dc;
2922 /* copy prepended iclasses */
2923 while (!(c0->flags & MRB_FL_CLASS_IS_ORIGIN)) {
2924 c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
2925 c1 = c1->super;
2926 c0 = c0->super;
2928 c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0)));
2929 c1->super->flags |= MRB_FL_CLASS_IS_ORIGIN;
2931 if (sc->mt) {
2932 if (sc->tt == MRB_TT_ICLASS && !(sc->flags & MRB_FL_CLASS_IS_ORIGIN)) {
2933 dc->mt = sc->mt;
2935 else {
2936 dc->mt = mt_copy(mrb, sc->mt);
2939 dc->super = sc->super;
2940 dc->flags = sc->flags;
2941 dc->frozen = 0;
2944 /* 15.3.1.3.16 */
2945 mrb_value mrb_obj_init_copy(mrb_state *mrb, mrb_value self);
2947 static void
2948 init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
2950 mrb_assert((mrb_type(dest) == mrb_type(obj)));
2951 switch (mrb_unboxed_type(obj)) {
2952 case MRB_TT_ICLASS:
2953 copy_class(mrb, dest, obj);
2954 return;
2955 case MRB_TT_CLASS:
2956 case MRB_TT_MODULE:
2957 copy_class(mrb, dest, obj);
2958 mrb_iv_copy(mrb, dest, obj);
2959 mrb_iv_remove(mrb, dest, MRB_SYM(__classname__));
2960 break;
2961 case MRB_TT_OBJECT:
2962 case MRB_TT_SCLASS:
2963 case MRB_TT_HASH:
2964 case MRB_TT_CDATA:
2965 case MRB_TT_EXCEPTION:
2966 mrb_iv_copy(mrb, dest, obj);
2967 break;
2968 case MRB_TT_ISTRUCT:
2969 mrb_istruct_copy(dest, obj);
2970 break;
2971 #if !defined(MRB_NO_FLOAT) && defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE)
2972 case MRB_TT_FLOAT:
2974 struct RFloat *f = (struct RFloat*)mrb_obj_ptr(dest);
2975 f->f = mrb_float(obj);
2977 break;
2978 #endif
2979 #ifdef MRB_USE_BIGINT
2980 case MRB_TT_BIGINT:
2981 mrb_bint_copy(mrb, dest, obj);
2982 break;
2983 #endif
2984 #ifdef MRB_USE_RATIONAL
2985 case MRB_TT_RATIONAL:
2986 mrb_rational_copy(mrb, dest, obj);
2987 break;
2988 #endif
2989 #ifdef MRB_USE_COMPLEX
2990 case MRB_TT_COMPLEX:
2991 mrb_complex_copy(mrb, dest, obj);
2992 break;
2993 #endif
2995 default:
2996 break;
2998 if (!mrb_func_basic_p(mrb, dest, MRB_SYM(initialize_copy), mrb_obj_init_copy)) {
2999 mrb_funcall_argv(mrb, dest, MRB_SYM(initialize_copy), 1, &obj);
3003 /* 15.3.1.3.8 */
3005 * call-seq:
3006 * obj.clone -> an_object
3008 * Produces a shallow copy of <i>obj</i>---the instance variables of
3009 * <i>obj</i> are copied, but not the objects they reference. Copies
3010 * the frozen state of <i>obj</i>. See also the discussion
3011 * under <code>Object#dup</code>.
3013 * class Klass
3014 * attr_accessor :str
3015 * end
3016 * s1 = Klass.new #=> #<Klass:0x401b3a38>
3017 * s1.str = "Hello" #=> "Hello"
3018 * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello">
3019 * s2.str[1,4] = "i" #=> "i"
3020 * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
3021 * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">"
3023 * This method may have class-specific behavior. If so, that
3024 * behavior will be documented under the #+initialize_copy+ method of
3025 * the class.
3027 * Some Class(True False Nil Symbol Integer Float) Object cannot clone.
3029 MRB_API mrb_value
3030 mrb_obj_clone(mrb_state *mrb, mrb_value self)
3032 if (mrb_immediate_p(self)) {
3033 return self;
3035 if (mrb_sclass_p(self)) {
3036 mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class");
3038 struct RObject *p = (struct RObject*)mrb_obj_alloc(mrb, mrb_unboxed_type(self), mrb_obj_class(mrb, self));
3039 p->c = mrb_singleton_class_clone(mrb, self);
3040 mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c);
3042 mrb_value clone = mrb_obj_value(p);
3043 init_copy(mrb, clone, self);
3044 p->frozen = mrb_obj_ptr(self)->frozen;
3046 return clone;
3049 /* 15.3.1.3.9 */
3051 * call-seq:
3052 * obj.dup -> an_object
3054 * Produces a shallow copy of <i>obj</i>---the instance variables of
3055 * <i>obj</i> are copied, but not the objects they reference.
3056 * <code>dup</code> copies the frozen state of <i>obj</i>. See also
3057 * the discussion under <code>Object#clone</code>. In general,
3058 * <code>clone</code> and <code>dup</code> may have different semantics
3059 * in descendant classes. While <code>clone</code> is used to duplicate
3060 * an object, including its internal state, <code>dup</code> typically
3061 * uses the class of the descendant object to create the new instance.
3063 * This method may have class-specific behavior. If so, that
3064 * behavior will be documented under the #+initialize_copy+ method of
3065 * the class.
3068 MRB_API mrb_value
3069 mrb_obj_dup(mrb_state *mrb, mrb_value obj)
3071 if (mrb_immediate_p(obj)) {
3072 return obj;
3074 if (mrb_sclass_p(obj)) {
3075 mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class");
3078 struct RBasic *p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
3079 mrb_value dup = mrb_obj_value(p);
3080 init_copy(mrb, dup, obj);
3082 return dup;
3085 /* implementation of __id__ */
3086 mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self);
3088 mrb_noreturn void
3089 mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args)
3091 mrb_no_method_error(mrb, name, args, "undefined method '%n' for %T", name, self);
3094 /* 15.3.1.3.30 */
3096 * call-seq:
3097 * obj.method_missing(symbol [, *args] ) -> result
3099 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
3100 * <i>symbol</i> is the symbol for the method called, and <i>args</i>
3101 * are any arguments that were passed to it. By default, the interpreter
3102 * raises an error when this method is called. However, it is possible
3103 * to override the method to provide more dynamic behavior.
3104 * If it is decided that a particular method should not be handled, then
3105 * <i>super</i> should be called, so that ancestors can pick up the
3106 * missing method.
3107 * The example below creates
3108 * a class <code>Roman</code>, which responds to methods with names
3109 * consisting of roman numerals, returning the corresponding integer
3110 * values.
3112 * class Roman
3113 * def romanToInt(str)
3114 * # ...
3115 * end
3116 * def method_missing(sym)
3117 * str = sym.to_s
3118 * romanToInt(str)
3119 * end
3120 * end
3122 * r = Roman.new
3123 * r.iv #=> 4
3124 * r.xxiii #=> 23
3125 * r.mm #=> 2000
3127 mrb_value
3128 mrb_obj_missing(mrb_state *mrb, mrb_value mod)
3130 mrb_sym name;
3131 const mrb_value *a;
3132 mrb_int alen;
3134 mrb->c->ci->mid = 0;
3135 mrb_get_args(mrb, "n*!", &name, &a, &alen);
3136 mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a));
3137 /* not reached */
3138 return mrb_nil_value();
3141 static mrb_value
3142 inspect_main(mrb_state *mrb, mrb_value mod)
3144 return mrb_str_new_lit(mrb, "main");
3147 static const mrb_code new_iseq[] = {
3148 OP_ENTER, 0x0, 0x10, 0x3, // OP_ENTER 0:0:1:0:0:1:1
3149 OP_SSEND, 4, 0, 0, // OP_SSEND R4 :allocate n=0
3150 OP_MOVE, 0, 4, // OP_MOVE R0 R4
3151 OP_MOVE, 4, 3, // OP_MOVE R4 R3 (&)
3152 OP_MOVE, 3, 2, // OP_MOVE R3 R2 (**)
3153 OP_MOVE, 2, 1, // OP_MOVE R2 R1 (*)
3154 OP_SSENDB, 1, 1, 255, // OP_SSENDB R1 :initialize n=*|nk=*
3155 OP_RETURN, 0 // OP_RETURN R0
3158 MRB_PRESYM_DEFINE_VAR_AND_INITER(new_syms, 2, MRB_SYM(allocate), MRB_SYM(initialize))
3160 static const mrb_irep new_irep = {
3161 4, 6, 0, MRB_IREP_STATIC,
3162 new_iseq, NULL, new_syms, NULL, NULL, NULL,
3163 sizeof(new_iseq), 0, 2, 0, 0,
3166 mrb_alignas(8)
3167 static const struct RProc new_proc = {
3168 NULL, NULL, MRB_TT_PROC, MRB_GC_RED, MRB_OBJ_IS_FROZEN, MRB_PROC_SCOPE | MRB_PROC_STRICT,
3169 { &new_irep }, NULL, { NULL }
3172 static void
3173 init_class_new(mrb_state *mrb, struct RClass *cls)
3175 mrb_method_t m;
3177 MRB_PRESYM_INIT_SYMBOLS(mrb, new_syms);
3178 MRB_METHOD_FROM_PROC(m, &new_proc);
3179 mrb_define_method_raw(mrb, cls, MRB_SYM(new), m);
3182 static const mrb_code neq_iseq[] = {
3183 OP_ENTER, 0x4, 0, 0, // OP_ENTER 1:0:0:0:0:0:0
3184 OP_EQ, 0, // OP_EQ R0 (R1)
3185 OP_JMPNOT, 0, 0, 5, // OP_JMPNOT R3 016
3186 OP_LOADF, 0, // OP_LOADF R0 (true)
3187 OP_JMP, 0, 2, // OP_JMP R1 018
3188 OP_LOADT, 0, // OP_LOADT R3 (true)
3189 OP_RETURN, 0 // OP_RETURN R0
3192 static const mrb_irep neq_irep = {
3193 4, 6, 0, MRB_IREP_STATIC,
3194 neq_iseq, NULL, NULL, NULL, NULL, NULL,
3195 sizeof(neq_iseq), 0, 2, 0, 0,
3198 mrb_alignas(8)
3199 static const struct RProc neq_proc = {
3200 NULL, NULL, MRB_TT_PROC, MRB_GC_RED, MRB_OBJ_IS_FROZEN, MRB_PROC_SCOPE | MRB_PROC_STRICT,
3201 { &neq_irep }, NULL, { NULL }
3204 void
3205 mrb_init_class(mrb_state *mrb)
3207 struct RClass *bob; /* BasicObject */
3208 struct RClass *obj; /* Object */
3209 struct RClass *mod; /* Module */
3210 struct RClass *cls; /* Class */
3212 /* boot class hierarchy */
3213 bob = boot_defclass(mrb, 0);
3214 obj = boot_defclass(mrb, bob); mrb->object_class = obj;
3215 mod = boot_defclass(mrb, obj); mrb->module_class = mod;/* obj -> mod */
3216 cls = boot_defclass(mrb, mod); mrb->class_class = cls; /* obj -> cls */
3217 /* fix-up loose ends */
3218 bob->c = obj->c = mod->c = cls->c = cls;
3219 make_metaclass(mrb, bob);
3220 make_metaclass(mrb, obj);
3221 make_metaclass(mrb, mod);
3222 make_metaclass(mrb, cls);
3224 /* name basic classes */
3225 mrb_define_const_id(mrb, bob, MRB_SYM(BasicObject), mrb_obj_value(bob));
3226 mrb_define_const_id(mrb, obj, MRB_SYM(Object), mrb_obj_value(obj));
3227 mrb_define_const_id(mrb, obj, MRB_SYM(Module), mrb_obj_value(mod));
3228 mrb_define_const_id(mrb, obj, MRB_SYM(Class), mrb_obj_value(cls));
3230 /* name each classes */
3231 mrb_class_name_class(mrb, NULL, bob, MRB_SYM(BasicObject));
3232 mrb_class_name_class(mrb, NULL, obj, MRB_SYM(Object)); /* 15.2.1 */
3233 mrb_class_name_class(mrb, NULL, mod, MRB_SYM(Module)); /* 15.2.2 */
3234 mrb_class_name_class(mrb, NULL, cls, MRB_SYM(Class)); /* 15.2.3 */
3236 MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS);
3237 mrb_define_method_id(mrb, bob, MRB_SYM(initialize), mrb_do_nothing, MRB_ARGS_NONE());
3238 mrb_define_method_id(mrb, bob, MRB_OPSYM(not), mrb_bob_not, MRB_ARGS_NONE());
3239 mrb_define_method_id(mrb, bob, MRB_OPSYM(eq), mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */
3240 mrb_define_method_id(mrb, bob, MRB_SYM(__id__), mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.4 */
3241 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 */
3242 mrb_define_method_id(mrb, bob, MRB_SYM_Q(equal), mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */
3243 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 */
3244 mrb_define_private_method_id(mrb, bob, MRB_SYM(singleton_method_added), mrb_do_nothing, MRB_ARGS_REQ(1));
3245 mrb_define_private_method_id(mrb, bob, MRB_SYM(singleton_method_removed),mrb_do_nothing, MRB_ARGS_REQ(1));
3246 mrb_define_private_method_id(mrb, bob, MRB_SYM(singleton_method_undefined),mrb_do_nothing, MRB_ARGS_REQ(1));
3247 mrb_define_private_method_id(mrb, bob, MRB_SYM(method_missing), mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */
3249 mrb_method_t m;
3250 MRB_METHOD_FROM_PROC(m, &neq_proc);
3251 mrb_define_method_raw(mrb, bob, MRB_OPSYM(neq), m);
3253 mrb_define_class_method_id(mrb, cls, MRB_SYM(new), mrb_class_new_class, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());
3254 mrb_define_method_id(mrb, cls, MRB_SYM(allocate), mrb_instance_alloc, MRB_ARGS_NONE());
3255 mrb_define_method_id(mrb, cls, MRB_SYM(superclass), mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */
3256 mrb_define_method_id(mrb, cls, MRB_SYM(initialize), mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
3257 mrb_define_private_method_id(mrb, cls, MRB_SYM(inherited), mrb_do_nothing, MRB_ARGS_REQ(1));
3259 init_class_new(mrb, cls);
3261 MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE);
3262 mrb_define_private_method_id(mrb, mod, MRB_SYM(extended), mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
3263 mrb_define_private_method_id(mrb, mod, MRB_SYM(prepended), mrb_do_nothing, MRB_ARGS_REQ(1));
3264 mrb_define_method_id(mrb, mod, MRB_SYM_Q(include), mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
3266 mrb_define_method_id(mrb, mod, MRB_SYM(include), mrb_mod_include, MRB_ARGS_REQ(1)); /* 15.2.2.4.27 */
3267 mrb_define_method_id(mrb, mod, MRB_SYM(prepend), mrb_mod_prepend, MRB_ARGS_REQ(1));
3268 mrb_define_method_id(mrb, mod, MRB_SYM(class_eval), mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */
3269 mrb_define_private_method_id(mrb, mod, MRB_SYM(included), mrb_do_nothing, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
3270 mrb_define_method_id(mrb, mod, MRB_SYM(initialize), mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */
3271 mrb_define_method_id(mrb, mod, MRB_SYM(module_eval), mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
3272 mrb_define_private_method_id(mrb, mod, MRB_SYM(module_function), mrb_mod_module_function, MRB_ARGS_ANY());
3273 mrb_define_private_method_id(mrb, mod, MRB_SYM(private), mrb_mod_private, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
3274 mrb_define_private_method_id(mrb, mod, MRB_SYM(protected), mrb_mod_protected, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
3275 mrb_define_private_method_id(mrb, mod, MRB_SYM(public), mrb_mod_public, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
3276 mrb_define_method_id(mrb, mod, MRB_SYM(attr_accessor), mrb_mod_attr_accessor, MRB_ARGS_ANY()); /* 15.2.2.4.12 */
3277 mrb_define_method_id(mrb, mod, MRB_SYM(attr_reader), mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */
3278 mrb_define_method_id(mrb, mod, MRB_SYM(attr_writer), mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */
3279 mrb_define_alias_id(mrb, mod, MRB_SYM(attr), MRB_SYM(attr_reader)); /* 15.2.2.4.11 */
3280 mrb_define_method_id(mrb, mod, MRB_SYM(to_s), mrb_mod_to_s, MRB_ARGS_NONE());
3281 mrb_define_method_id(mrb, mod, MRB_SYM(inspect), mrb_mod_to_s, MRB_ARGS_NONE());
3282 mrb_define_method_id(mrb, mod, MRB_SYM(alias_method), mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */
3283 mrb_define_method_id(mrb, mod, MRB_SYM(ancestors), mrb_mod_ancestors, MRB_ARGS_NONE()); /* 15.2.2.4.9 */
3284 mrb_define_method_id(mrb, mod, MRB_SYM(undef_method), mrb_mod_undef, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
3285 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 */
3286 mrb_define_method_id(mrb, mod, MRB_SYM(const_get), mrb_mod_const_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */
3287 mrb_define_method_id(mrb, mod, MRB_SYM(const_set), mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */
3288 mrb_define_private_method_id(mrb, mod, MRB_SYM(remove_const), mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */
3289 mrb_define_method_id(mrb, mod, MRB_SYM(const_missing), mrb_mod_const_missing, MRB_ARGS_REQ(1));
3290 mrb_define_method_id(mrb, mod, MRB_SYM_Q(method_defined), mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
3291 mrb_define_method_id(mrb, mod, MRB_SYM(define_method), mod_define_method, MRB_ARGS_ARG(1,1));
3292 mrb_define_method_id(mrb, mod, MRB_OPSYM(eqq), mrb_mod_eqq, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */
3293 mrb_define_method_id(mrb, mod, MRB_SYM(dup), mrb_mod_dup, MRB_ARGS_NONE());
3294 mrb_define_private_method_id(mrb, mod, MRB_SYM(method_added), mrb_do_nothing, MRB_ARGS_REQ(1));
3295 mrb_define_private_method_id(mrb, mod, MRB_SYM(method_removed), mrb_do_nothing, MRB_ARGS_REQ(1));
3296 mrb_define_private_method_id(mrb, mod, MRB_SYM(method_undefined), mrb_do_nothing, MRB_ARGS_REQ(1));
3297 mrb_define_private_method_id(mrb, mod, MRB_SYM(const_added), mrb_do_nothing, MRB_ARGS_REQ(1));
3299 mrb_undef_method_id(mrb, cls, MRB_SYM(module_function));
3301 mrb->top_self = MRB_OBJ_ALLOC(mrb, MRB_TT_OBJECT, mrb->object_class);
3302 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(inspect), inspect_main, MRB_ARGS_NONE());
3303 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(to_s), inspect_main, MRB_ARGS_NONE());
3304 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(define_method), top_define_method, MRB_ARGS_ARG(1,1));
3305 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(public), top_public, MRB_ARGS_ANY());
3306 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(private), top_private, MRB_ARGS_ANY());
3307 mrb_define_singleton_method_id(mrb, mrb->top_self, MRB_SYM(protected), top_protected, MRB_ARGS_ANY());