source: EcnlProtoTool/trunk/mruby-2.1.1/src/class.c@ 439

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

mrubyを2.1.1に更新

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