source: EcnlProtoTool/trunk/mruby-1.2.0/src/class.c@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

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