source: EcnlProtoTool/trunk/mruby-1.3.0/src/class.c@ 331

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

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

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