2 ** class.c - Class class
4 ** See Copyright Notice in mruby.h
8 #include <mruby/array.h>
9 #include <mruby/hash.h>
10 #include <mruby/class.h>
11 #include <mruby/numeric.h>
12 #include <mruby/proc.h>
13 #include <mruby/string.h>
14 #include <mruby/variable.h>
15 #include <mruby/error.h>
16 #include <mruby/data.h>
17 #include <mruby/istruct.h>
18 #include <mruby/opcode.h>
19 #include <mruby/internal.h>
20 #include <mruby/presym.h>
22 #define METHOD_MID(m) MT_KEY_SYM((m).flags)
25 const struct RProc
*proc
;
29 #define MT_KEY_SHIFT 4
30 #define MT_KEY_MASK ((1<<MT_KEY_SHIFT)-1)
31 #define MT_KEY_P(k) (((k)>>MT_KEY_SHIFT) != 0)
32 #define MT_FUNC MRB_METHOD_FUNC_FL
33 #define MT_NOARG MRB_METHOD_NOARG_FL
34 #define MT_PUBLIC MRB_METHOD_PUBLIC_FL
35 #define MT_PRIVATE MRB_METHOD_PRIVATE_FL
36 #define MT_PROTECTED MRB_METHOD_PROTECTED_FL
37 #define MT_VDEFAULT MRB_METHOD_VDEFAULT_FL
38 #define MT_VMASK MRB_METHOD_VISIBILITY_MASK
42 #define MT_KEY(sym, flags) ((sym)<<MT_KEY_SHIFT|(flags))
43 #define MT_KEY_SYM(k) ((k)>>MT_KEY_SHIFT)
44 #define MT_KEY_FLG(k) ((k)&MT_KEY_MASK)
46 /* method table structure */
47 typedef struct mt_tbl
{
53 #ifdef MRB_USE_INLINE_METHOD_CACHE
54 #define MT_INLINE_CACHE_SIZE 256
55 static uint8_t mt_cache
[MT_INLINE_CACHE_SIZE
];
58 /* Creates the method table. */
60 mt_new(mrb_state
*mrb
)
64 t
= (mt_tbl
*)mrb_malloc(mrb
, sizeof(mt_tbl
));
72 static void mt_put(mrb_state
*mrb
, mt_tbl
*t
, mrb_sym sym
, mrb_sym flags
, union mt_ptr ptr
);
75 mt_rehash(mrb_state
*mrb
, mt_tbl
*t
)
77 int old_alloc
= t
->alloc
;
78 int new_alloc
= old_alloc
> 0 ? old_alloc
<< 1 : 8;
79 union mt_ptr
*old_ptr
= t
->ptr
;
81 t
->ptr
= (union mt_ptr
*)mrb_calloc(mrb
, sizeof(union mt_ptr
)+sizeof(mrb_sym
), new_alloc
);
84 if (old_alloc
== 0) return;
86 mrb_sym
*keys
= (mrb_sym
*)&old_ptr
[old_alloc
];
87 union mt_ptr
*vals
= old_ptr
;
88 for (int i
= 0; i
< old_alloc
; i
++) {
89 mrb_sym key
= keys
[i
];
91 mt_put(mrb
, t
, MT_KEY_SYM(key
), MT_KEY_FLG(key
), vals
[i
]);
94 mrb_free(mrb
, old_ptr
);
97 #define slot_empty_p(slot) ((slot)->key == 0 && (slot)->func_p == 0)
99 /* Set the value for the symbol in the method table. */
101 mt_put(mrb_state
*mrb
, mt_tbl
*t
, mrb_sym sym
, mrb_sym flags
, union mt_ptr ptr
)
103 int pos
, start
, dpos
= -1;
109 mrb_sym
*keys
= (mrb_sym
*)&t
->ptr
[t
->alloc
];
110 union mt_ptr
*vals
= t
->ptr
;
111 int hash
= mrb_int_hash_func(mrb
, sym
);
112 start
= pos
= hash
& (t
->alloc
-1);
114 mrb_sym key
= keys
[pos
];
115 if (MT_KEY_SYM(key
) == sym
) {
117 keys
[pos
] = MT_KEY(sym
, flags
);
121 else if (key
== MT_EMPTY
) {
125 else if (key
== MT_DELETED
&& dpos
< 0) {
128 pos
= (pos
+1) & (t
->alloc
-1);
129 if (pos
== start
) { /* not found */
137 start
= pos
= hash
& (t
->alloc
-1);
138 keys
= (mrb_sym
*)&t
->ptr
[t
->alloc
];
144 /* Get a value for a symbol from the method table. */
146 mt_get(mrb_state
*mrb
, mt_tbl
*t
, mrb_sym sym
, union mt_ptr
*pp
)
150 if (t
== NULL
) return 0;
151 if (t
->alloc
== 0) return 0;
152 if (t
->size
== 0) return 0;
154 mrb_sym
*keys
= (mrb_sym
*)&t
->ptr
[t
->alloc
];
155 union mt_ptr
*vals
= t
->ptr
;
156 int hash
= mrb_int_hash_func(mrb
, sym
);
157 #ifdef MRB_USE_INLINE_METHOD_CACHE
158 int cpos
= (hash
^(uintptr_t)t
) % MT_INLINE_CACHE_SIZE
;
159 pos
= mt_cache
[cpos
];
160 if (pos
< t
->alloc
) {
161 mrb_sym key
= keys
[pos
];
163 if (MT_KEY_SYM(key
) == sym
) {
170 int start
= pos
= hash
& (t
->alloc
-1);
172 mrb_sym key
= keys
[pos
];
173 if (MT_KEY_SYM(key
) == sym
) {
175 #ifdef MRB_USE_INLINE_METHOD_CACHE
177 mt_cache
[cpos
] = pos
;
182 else if (key
== MT_EMPTY
) {
185 pos
= (pos
+1) & (t
->alloc
-1);
186 if (pos
== start
) { /* not found */
192 /* Deletes the value for the symbol from the method table. */
194 mt_del(mrb_state
*mrb
, mt_tbl
*t
, mrb_sym sym
)
198 if (t
== NULL
) return FALSE
;
199 if (t
->alloc
== 0) return FALSE
;
200 if (t
->size
== 0) return FALSE
;
202 mrb_sym
*keys
= (mrb_sym
*)&t
->ptr
[t
->alloc
];
203 int hash
= mrb_int_hash_func(mrb
, sym
);
204 start
= pos
= hash
& (t
->alloc
-1);
206 mrb_sym key
= keys
[pos
];
207 if (MT_KEY_SYM(key
) == sym
) {
209 keys
[pos
] = MT_DELETED
;
212 else if (key
== MT_EMPTY
) {
215 pos
= (pos
+1) & (t
->alloc
-1);
216 if (pos
== start
) { /* not found */
222 /* Copy the method table. */
223 static struct mt_tbl
*
224 mt_copy(mrb_state
*mrb
, mt_tbl
*t
)
228 if (t
== NULL
) return NULL
;
229 if (t
->alloc
== 0) return NULL
;
230 if (t
->size
== 0) return NULL
;
233 mrb_sym
*keys
= (mrb_sym
*)&t
->ptr
[t
->alloc
];
234 union mt_ptr
*vals
= t
->ptr
;
235 for (int i
=0; i
<t
->alloc
; i
++) {
236 if (MT_KEY_P(keys
[i
])) {
237 mt_put(mrb
, t2
, MT_KEY_SYM(keys
[i
]), MT_KEY_FLG(keys
[i
]), vals
[i
]);
243 /* Free memory of the method table. */
245 mt_free(mrb_state
*mrb
, mt_tbl
*t
)
247 mrb_free(mrb
, t
->ptr
);
251 static inline mrb_method_t
252 create_method_value(mrb_state
*mrb
, mrb_sym key
, union mt_ptr val
)
254 mrb_method_t m
= { key
, { val
.proc
} };
259 mrb_mt_foreach(mrb_state
*mrb
, struct RClass
*c
, mrb_mt_foreach_func
*fn
, void *p
)
263 if (t
== NULL
) return;
264 if (t
->alloc
== 0) return;
265 if (t
->size
== 0) return;
267 mrb_sym
*keys
= (mrb_sym
*)&t
->ptr
[t
->alloc
];
268 union mt_ptr
*vals
= t
->ptr
;
269 for (int i
=0; i
<t
->alloc
; i
++) {
270 mrb_sym key
= keys
[i
];
271 if (MT_KEY_SYM(key
)) {
272 if (fn(mrb
, MT_KEY_SYM(key
), create_method_value(mrb
, key
, vals
[i
]), p
) != 0)
280 mrb_gc_mark_mt(mrb_state
*mrb
, struct RClass
*c
)
284 if (t
== NULL
) return 0;
285 if (t
->alloc
== 0) return 0;
286 if (t
->size
== 0) return 0;
288 mrb_sym
*keys
= (mrb_sym
*)&t
->ptr
[t
->alloc
];
289 union mt_ptr
*vals
= t
->ptr
;
290 for (int i
=0; i
<t
->alloc
; i
++) {
291 if (MT_KEY_P(keys
[i
]) && (keys
[i
] & MT_FUNC
) == 0) { /* Proc pointer */
292 const struct RProc
*p
= vals
[i
].proc
;
293 mrb_gc_mark(mrb
, (struct RBasic
*)p
);
297 return (size_t)t
->size
;
301 mrb_class_mt_memsize(mrb_state
*mrb
, struct RClass
*c
)
303 struct mt_tbl
*h
= c
->mt
;
306 return sizeof(struct mt_tbl
) + (size_t)h
->size
* sizeof(mrb_method_t
);
310 mrb_gc_free_mt(mrb_state
*mrb
, struct RClass
*c
)
312 if (c
->mt
) mt_free(mrb
, c
->mt
);
316 mrb_class_name_class(mrb_state
*mrb
, struct RClass
*outer
, struct RClass
*c
, mrb_sym id
)
319 mrb_sym nsym
= MRB_SYM(__classname__
);
321 if (mrb_obj_iv_defined(mrb
, (struct RObject
*)c
, nsym
)) return;
322 if (outer
== NULL
|| outer
== mrb
->object_class
) {
323 name
= mrb_symbol_value(id
);
326 name
= mrb_class_path(mrb
, outer
);
327 if (mrb_nil_p(name
)) { /* unnamed outer class */
328 if (outer
!= mrb
->object_class
&& outer
!= c
) {
329 mrb_obj_iv_set_force(mrb
, (struct RObject
*)c
, MRB_SYM(__outer__
),
330 mrb_obj_value(outer
));
336 const char *n
= mrb_sym_name_len(mrb
, id
, &len
);
338 mrb_str_cat_lit(mrb
, name
, "::");
339 mrb_str_cat(mrb
, name
, n
, len
);
342 mrb_obj_iv_set_force(mrb
, (struct RObject
*)c
, nsym
, name
);
346 mrb_const_name_p(mrb_state
*mrb
, const char *name
, mrb_int len
)
348 return len
> 0 && ISUPPER(name
[0]) && mrb_ident_p(name
+1, len
-1);
352 setup_class(mrb_state
*mrb
, struct RClass
*outer
, struct RClass
*c
, mrb_sym id
)
354 mrb_const_set(mrb
, mrb_obj_value(outer
), id
, mrb_obj_value(c
));
357 #define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c))
360 prepare_singleton_class(mrb_state
*mrb
, struct RBasic
*o
)
365 if (o
->c
->tt
== MRB_TT_SCLASS
) return;
366 struct RClass
*sc
= MRB_OBJ_ALLOC(mrb
, MRB_TT_SCLASS
, mrb
->class_class
);
367 sc
->flags
|= MRB_FL_CLASS_IS_INHERITED
;
370 if (o
->tt
== MRB_TT_CLASS
) {
371 c
= (struct RClass
*)o
;
373 sc
->super
= mrb
->class_class
;
376 sc
->super
= c
->super
->c
;
379 else if (o
->tt
== MRB_TT_SCLASS
) {
380 c
= (struct RClass
*)o
;
381 while (c
->super
->tt
== MRB_TT_ICLASS
)
383 make_metaclass(mrb
, c
->super
);
384 sc
->super
= c
->super
->c
;
388 prepare_singleton_class(mrb
, (struct RBasic
*)sc
);
391 mrb_field_write_barrier(mrb
, (struct RBasic
*)o
, (struct RBasic
*)sc
);
392 mrb_obj_iv_set(mrb
, (struct RObject
*)sc
, MRB_SYM(__attached__
), mrb_obj_value(o
));
393 sc
->frozen
= o
->frozen
;
397 class_name_str(mrb_state
*mrb
, struct RClass
* c
)
399 mrb_value path
= mrb_class_path(mrb
, c
);
400 if (mrb_nil_p(path
)) {
401 path
= c
->tt
== MRB_TT_MODULE
? mrb_str_new_lit(mrb
, "#<Module:") :
402 mrb_str_new_lit(mrb
, "#<Class:");
403 mrb_str_cat_str(mrb
, path
, mrb_ptr_to_str(mrb
, c
));
404 mrb_str_cat_lit(mrb
, path
, ">");
409 static struct RClass
*
410 class_from_sym(mrb_state
*mrb
, struct RClass
*klass
, mrb_sym id
)
412 mrb_value c
= mrb_const_get(mrb
, mrb_obj_value(klass
), id
);
414 mrb_check_type(mrb
, c
, MRB_TT_CLASS
);
415 return mrb_class_ptr(c
);
418 static struct RClass
*
419 module_from_sym(mrb_state
*mrb
, struct RClass
*klass
, mrb_sym id
)
421 mrb_value c
= mrb_const_get(mrb
, mrb_obj_value(klass
), id
);
423 mrb_check_type(mrb
, c
, MRB_TT_MODULE
);
424 return mrb_class_ptr(c
);
428 class_ptr_p(mrb_value obj
)
430 switch (mrb_type(obj
)) {
441 check_if_class_or_module(mrb_state
*mrb
, mrb_value obj
)
443 if (!class_ptr_p(obj
)) {
444 mrb_raisef(mrb
, E_TYPE_ERROR
, "%!v is not a class/module", obj
);
448 static struct RClass
*
449 define_module(mrb_state
*mrb
, mrb_sym name
, struct RClass
*outer
)
451 if (mrb_const_defined_at(mrb
, mrb_obj_value(outer
), name
)) {
452 return module_from_sym(mrb
, outer
, name
);
454 struct RClass
*m
= mrb_module_new(mrb
);
455 setup_class(mrb
, outer
, m
, name
);
460 MRB_API
struct RClass
*
461 mrb_define_module_id(mrb_state
*mrb
, mrb_sym name
)
463 return define_module(mrb
, name
, mrb
->object_class
);
466 MRB_API
struct RClass
*
467 mrb_define_module(mrb_state
*mrb
, const char *name
)
469 return define_module(mrb
, mrb_intern_cstr(mrb
, name
), mrb
->object_class
);
473 mrb_vm_define_module(mrb_state
*mrb
, mrb_value outer
, mrb_sym id
)
475 check_if_class_or_module(mrb
, outer
);
476 if (mrb_const_defined_at(mrb
, outer
, id
)) {
477 mrb_value old
= mrb_const_get(mrb
, outer
, id
);
479 if (!mrb_module_p(old
)) {
480 mrb_raisef(mrb
, E_TYPE_ERROR
, "%!v is not a module", old
);
482 return mrb_class_ptr(old
);
484 return define_module(mrb
, id
, mrb_class_ptr(outer
));
487 MRB_API
struct RClass
*
488 mrb_define_module_under_id(mrb_state
*mrb
, struct RClass
*outer
, mrb_sym name
)
490 struct RClass
* c
= define_module(mrb
, name
, outer
);
492 setup_class(mrb
, outer
, c
, name
);
496 MRB_API
struct RClass
*
497 mrb_define_module_under(mrb_state
*mrb
, struct RClass
*outer
, const char *name
)
499 mrb_sym id
= mrb_intern_cstr(mrb
, name
);
500 struct RClass
* c
= define_module(mrb
, id
, outer
);
502 setup_class(mrb
, outer
, c
, id
);
506 static struct RClass
*
507 find_origin(struct RClass
*c
)
513 static struct RClass
*
514 define_class(mrb_state
*mrb
, mrb_sym name
, struct RClass
*super
, struct RClass
*outer
)
518 if (mrb_const_defined_at(mrb
, mrb_obj_value(outer
), name
)) {
519 c
= class_from_sym(mrb
, outer
, name
);
521 if (super
&& mrb_class_real(c
->super
) != super
) {
522 mrb_raisef(mrb
, E_TYPE_ERROR
, "superclass mismatch for Class %n (%C not %C)",
523 name
, c
->super
, super
);
528 c
= mrb_class_new(mrb
, super
);
529 setup_class(mrb
, outer
, c
, name
);
534 MRB_API
struct RClass
*
535 mrb_define_class_id(mrb_state
*mrb
, mrb_sym name
, struct RClass
*super
)
538 mrb_warn(mrb
, "no super class for '%n', Object assumed", name
);
540 return define_class(mrb
, name
, super
, mrb
->object_class
);
543 MRB_API
struct RClass
*
544 mrb_define_class(mrb_state
*mrb
, const char *name
, struct RClass
*super
)
546 return mrb_define_class_id(mrb
, mrb_intern_cstr(mrb
, name
), super
);
549 static mrb_value
mrb_do_nothing(mrb_state
*mrb
, mrb_value
);
550 #ifndef MRB_NO_METHOD_CACHE
551 static void mc_clear(mrb_state
*mrb
);
552 static void mc_clear_by_id(mrb_state
*mrb
, mrb_sym mid
);
554 #define mc_clear(mrb)
555 #define mc_clear_by_id(mrb,mid)
559 mrb_class_inherited(mrb_state
*mrb
, struct RClass
*super
, struct RClass
*klass
)
563 super
= mrb
->object_class
;
564 super
->flags
|= MRB_FL_CLASS_IS_INHERITED
;
566 mrb_value s
= mrb_obj_value(super
);
567 mrb_sym mid
= MRB_SYM(inherited
);
569 if (!mrb_func_basic_p(mrb
, s
, mid
, mrb_do_nothing
)) {
570 mrb_value c
= mrb_obj_value(klass
);
571 mrb_funcall_argv(mrb
, s
, mid
, 1, &c
);
576 mrb_vm_define_class(mrb_state
*mrb
, mrb_value outer
, mrb_value super
, mrb_sym id
)
581 if (!mrb_nil_p(super
)) {
582 if (!mrb_class_p(super
)) {
583 mrb_raisef(mrb
, E_TYPE_ERROR
, "superclass must be a Class (%!v given)", super
);
585 s
= mrb_class_ptr(super
);
590 check_if_class_or_module(mrb
, outer
);
591 if (mrb_const_defined_at(mrb
, outer
, id
)) {
592 mrb_value old
= mrb_const_get(mrb
, outer
, id
);
594 if (!mrb_class_p(old
)) {
595 mrb_raisef(mrb
, E_TYPE_ERROR
, "%!v is not a class", old
);
597 c
= mrb_class_ptr(old
);
599 /* check super class */
600 if (mrb_class_real(c
->super
) != s
) {
601 mrb_raisef(mrb
, E_TYPE_ERROR
, "superclass mismatch for %v", old
);
606 c
= define_class(mrb
, id
, s
, mrb_class_ptr(outer
));
607 mrb_class_inherited(mrb
, mrb_class_real(c
->super
), c
);
613 mrb_class_defined(mrb_state
*mrb
, const char *name
)
615 mrb_sym sym
= mrb_intern_check_cstr(mrb
, name
);
616 if (!sym
) return FALSE
;
617 return mrb_const_defined(mrb
, mrb_obj_value(mrb
->object_class
), sym
);
621 mrb_class_defined_id(mrb_state
*mrb
, mrb_sym name
)
623 return mrb_const_defined(mrb
, mrb_obj_value(mrb
->object_class
), name
);
627 mrb_class_defined_under(mrb_state
*mrb
, struct RClass
*outer
, const char *name
)
629 mrb_sym sym
= mrb_intern_check_cstr(mrb
, name
);
630 if (!sym
) return FALSE
;
631 return mrb_const_defined_at(mrb
, mrb_obj_value(outer
), sym
);
635 mrb_class_defined_under_id(mrb_state
*mrb
, struct RClass
*outer
, mrb_sym name
)
637 return mrb_const_defined_at(mrb
, mrb_obj_value(outer
), name
);
640 MRB_API
struct RClass
*
641 mrb_class_get_under(mrb_state
*mrb
, struct RClass
*outer
, const char *name
)
643 return class_from_sym(mrb
, outer
, mrb_intern_cstr(mrb
, name
));
646 MRB_API
struct RClass
*
647 mrb_class_get_under_id(mrb_state
*mrb
, struct RClass
*outer
, mrb_sym name
)
649 return class_from_sym(mrb
, outer
, name
);
652 MRB_API
struct RClass
*
653 mrb_class_get(mrb_state
*mrb
, const char *name
)
655 return mrb_class_get_under(mrb
, mrb
->object_class
, name
);
658 MRB_API
struct RClass
*
659 mrb_class_get_id(mrb_state
*mrb
, mrb_sym name
)
661 return mrb_class_get_under_id(mrb
, mrb
->object_class
, name
);
664 MRB_API
struct RClass
*
665 mrb_exc_get_id(mrb_state
*mrb
, mrb_sym name
)
667 mrb_value c
= mrb_exc_const_get(mrb
, name
);
669 if (!mrb_class_p(c
)) {
670 mrb_raise(mrb
, E_EXCEPTION
, "exception corrupted");
673 struct RClass
*exc
= mrb_class_ptr(c
);
674 for (struct RClass
*e
= exc
; e
; e
= e
->super
) {
675 if (e
== E_EXCEPTION
)
678 mrb_raise(mrb
, E_EXCEPTION
, "non-exception raised");
683 MRB_API
struct RClass
*
684 mrb_module_get_under(mrb_state
*mrb
, struct RClass
*outer
, const char *name
)
686 return module_from_sym(mrb
, outer
, mrb_intern_cstr(mrb
, name
));
689 MRB_API
struct RClass
*
690 mrb_module_get_under_id(mrb_state
*mrb
, struct RClass
*outer
, mrb_sym name
)
692 return module_from_sym(mrb
, outer
, name
);
695 MRB_API
struct RClass
*
696 mrb_module_get(mrb_state
*mrb
, const char *name
)
698 return mrb_module_get_under(mrb
, mrb
->object_class
, name
);
701 MRB_API
struct RClass
*
702 mrb_module_get_id(mrb_state
*mrb
, mrb_sym name
)
704 return mrb_module_get_under_id(mrb
, mrb
->object_class
, name
);
708 * Defines a class under the namespace of \a outer.
709 * \param outer a class which contains the new class.
710 * \param name name of the new class
711 * \param super a class from which the new class will derive.
712 * NULL means \c Object class.
713 * \return the created class
714 * \throw TypeError if the constant name \a name is already taken but
715 * the constant is not a \c Class.
716 * \throw NameError if the class is already defined but the class can not
717 * be reopened because its superclass is not \a super.
718 * \post top-level constant named \a name refers the returned class.
720 * \note if a class named \a name is already defined and its superclass is
721 * \a super, the function just returns the defined class.
723 MRB_API
struct RClass
*
724 mrb_define_class_under_id(mrb_state
*mrb
, struct RClass
*outer
, mrb_sym name
, struct RClass
*super
)
730 mrb_warn(mrb
, "no super class for '%C::%n', Object assumed", outer
, id
);
733 c
= define_class(mrb
, name
, super
, outer
);
734 setup_class(mrb
, outer
, c
, name
);
738 MRB_API
struct RClass
*
739 mrb_define_class_under(mrb_state
*mrb
, struct RClass
*outer
, const char *name
, struct RClass
*super
)
741 return mrb_define_class_under_id(mrb
, outer
, mrb_intern_cstr(mrb
, name
), super
);
745 check_visibility_break(const struct RProc
*p
, const struct RClass
*c
, mrb_callinfo
*ci
, struct REnv
*env
)
747 if (!p
|| p
->upper
== NULL
|| MRB_PROC_SCOPE_P(p
) || p
->e
.env
== NULL
|| !MRB_PROC_ENV_P(p
)) {
751 return p
->e
.env
->c
!= c
|| MRB_ENV_VISIBILITY_BREAK_P(env
);
753 return mrb_vm_ci_target_class(ci
) != c
|| MRB_CI_VISIBILITY_BREAK_P(ci
);
757 find_visibility_scope(mrb_state
*mrb
, const struct RClass
*c
, int n
, mrb_callinfo
**cp
, struct REnv
**ep
)
759 const struct mrb_context
*ec
= mrb
->c
;
760 mrb_callinfo
*ci
= ec
->ci
- n
;
761 const struct RProc
*p
= ci
->proc
;
763 if (c
== NULL
) c
= mrb_vm_ci_target_class(ci
);
765 if (check_visibility_break(p
, c
, ci
, NULL
)) {
766 mrb_assert(ci
->u
.env
);
773 struct REnv
*env
= p
->e
.env
;
775 if (check_visibility_break(p
, c
, ci
, env
)) {
784 mrb_define_method_raw(mrb_state
*mrb
, struct RClass
*c
, mrb_sym mid
, mrb_method_t m
)
791 if (c
->tt
== MRB_TT_SCLASS
&& mrb_frozen_p(c
)) {
792 mrb_value v
= mrb_iv_get(mrb
, mrb_obj_value(c
), MRB_SYM(__attached__
));
793 mrb_check_frozen_value(mrb
, v
);
796 mrb_check_frozen(mrb
, c
);
798 if (!h
) h
= c
->mt
= mt_new(mrb
);
799 if (MRB_METHOD_PROC_P(m
)) {
800 struct RProc
*p
= (struct RProc
*)MRB_METHOD_PROC(m
);
804 if (p
->gc_color
!= MRB_GC_RED
) {
805 p
->flags
|= MRB_PROC_SCOPE
;
807 mrb_field_write_barrier(mrb
, (struct RBasic
*)c
, (struct RBasic
*)p
);
808 if (!MRB_PROC_ENV_P(p
)) {
809 MRB_PROC_SET_TARGET_CLASS(p
, c
);
813 mrb_assert(mrb_frozen_p(p
) && MRB_PROC_SCOPE_P(p
));
814 mrb_assert(p
->c
== NULL
&& p
->upper
== NULL
&& p
->e
.target_class
== NULL
);
819 ptr
.func
= MRB_METHOD_FUNC(m
);
822 int flags
= MT_KEY_FLG(m
.flags
);
823 if (mid
== MRB_SYM(initialize
)) {
824 MRB_SET_VISIBILITY_FLAGS(flags
, MT_PRIVATE
);
826 else if ((flags
& MT_VMASK
) == MT_VDEFAULT
) {
829 find_visibility_scope(mrb
, c
, 0, &ci
, &e
);
831 MRB_SET_VISIBILITY_FLAGS(flags
, (e
? MRB_ENV_VISIBILITY(e
) : MRB_CI_VISIBILITY(ci
)));
833 mt_put(mrb
, h
, mid
, flags
, ptr
);
834 mc_clear_by_id(mrb
, mid
);
838 define_method_id(mrb_state
*mrb
, struct RClass
*c
, mrb_sym mid
, mrb_func_t func
, mrb_aspec aspec
, int vis
)
841 int ai
= mrb_gc_arena_save(mrb
);
843 MRB_METHOD_FROM_FUNC(m
, func
);
844 if (aspec
== MRB_ARGS_NONE()) {
845 MRB_METHOD_NOARG_SET(m
);
847 MRB_METHOD_SET_VISIBILITY(m
, vis
);
848 mrb_define_method_raw(mrb
, c
, mid
, m
);
849 mrb_gc_arena_restore(mrb
, ai
);
853 mrb_define_method_id(mrb_state
*mrb
, struct RClass
*c
, mrb_sym mid
, mrb_func_t func
, mrb_aspec aspec
)
855 define_method_id(mrb
, c
, mid
, func
, aspec
, MT_PUBLIC
);
859 mrb_define_method(mrb_state
*mrb
, struct RClass
*c
, const char *name
, mrb_func_t func
, mrb_aspec aspec
)
861 mrb_define_method_id(mrb
, c
, mrb_intern_cstr(mrb
, name
), func
, aspec
);
865 mrb_define_private_method_id(mrb_state
*mrb
, struct RClass
*c
, mrb_sym mid
, mrb_func_t func
, mrb_aspec aspec
)
867 define_method_id(mrb
, c
, mid
, func
, aspec
, MT_PRIVATE
);
871 mrb_define_private_method(mrb_state
*mrb
, struct RClass
*c
, const char *name
, mrb_func_t func
, mrb_aspec aspec
)
873 mrb_define_private_method_id(mrb
, c
, mrb_intern_cstr(mrb
, name
), func
, aspec
);
876 /* a function to raise NotImplementedError with current method name */
878 mrb_notimplement(mrb_state
*mrb
)
880 mrb_callinfo
*ci
= mrb
->c
->ci
;
883 mrb_raisef(mrb
, E_NOTIMP_ERROR
, "%n() function is unimplemented on this machine", ci
->mid
);
887 /* a function to be replacement of unimplemented method */
889 mrb_notimplement_m(mrb_state
*mrb
, mrb_value self
)
891 mrb_notimplement(mrb
);
893 return mrb_nil_value();
897 ensure_class_type(mrb_state
*mrb
, mrb_value val
)
899 if (!class_ptr_p(val
)) {
900 mrb_raisef(mrb
, E_TYPE_ERROR
, "%v is not class/module", val
);
904 #define to_sym(mrb, ss) mrb_obj_to_sym(mrb, ss)
907 mrb_get_argc(mrb_state
*mrb
)
909 mrb_int argc
= mrb
->c
->ci
->n
;
912 struct RArray
*a
= mrb_ary_ptr(mrb
->c
->ci
->stack
[1]);
914 a
->c
= NULL
; /* hide from ObjectSpace.each_object */
920 MRB_API
const mrb_value
*
921 mrb_get_argv(mrb_state
*mrb
)
923 mrb_int argc
= mrb
->c
->ci
->n
;
924 mrb_value
*array_argv
= mrb
->c
->ci
->stack
+ 1;
926 struct RArray
*a
= mrb_ary_ptr(*array_argv
);
928 a
->c
= NULL
; /* hide from ObjectSpace.each_object */
929 array_argv
= ARY_PTR(a
);
935 mrb_get_arg1(mrb_state
*mrb
)
937 mrb_callinfo
*ci
= mrb
->c
->ci
;
938 mrb_int argc
= ci
->n
;
939 mrb_value
*array_argv
= ci
->stack
+ 1;
941 struct RArray
*a
= mrb_ary_ptr(*array_argv
);
944 array_argv
= ARY_PTR(a
);
946 if (argc
== 0 && ci
->nk
== 15) {
949 return ci
->stack
[n
+1]; /* kwhash next to positional arguments */
952 mrb_argnum_error(mrb
, argc
, 1, 1);
954 return array_argv
[0];
958 mrb_block_given_p(mrb_state
*mrb
)
960 mrb_callinfo
*ci
= mrb
->c
->ci
;
961 mrb_value b
= ci
->stack
[mrb_ci_bidx(ci
)];
963 return !mrb_nil_p(b
);
966 #define GET_ARG(_type) (ptr ? ((_type)(*ptr++)) : va_arg((*ap), _type))
969 get_args_v(mrb_state
*mrb
, mrb_args_format format
, void** ptr
, va_list *ap
)
971 const char *fmt
= format
;
974 mrb_callinfo
*ci
= mrb
->c
->ci
;
975 mrb_int argc
= ci
->n
;
976 const mrb_value
*argv
= ci
->stack
+1;
977 mrb_bool argv_on_stack
;
978 mrb_bool opt
= FALSE
;
979 mrb_bool opt_skip
= TRUE
;
980 const mrb_value
*pickarg
= NULL
; /* arguments currently being processed */
981 mrb_value kdict
= mrb_nil_value();
982 mrb_bool reqkarg
= FALSE
;
983 int argc_min
= 0, argc_max
= 0;
985 while ((c
= *fmt
++)) {
993 if (!reqkarg
) reqkarg
= strchr(fmt
, ':') ? TRUE
: FALSE
;
1002 if (opt
) opt_skip
= FALSE
;
1005 if (!opt
) argc_min
++;
1012 if (!reqkarg
&& ci
->nk
> 0) {
1013 mrb_assert(ci
->nk
== 15);
1014 kdict
= ci
->stack
[mrb_ci_bidx(ci
)-1];
1015 if (mrb_hash_p(kdict
) && mrb_hash_size(mrb
, kdict
) > 0) {
1018 argc
++; /* include kdict in normal arguments */
1021 /* 14+1 == 15 so pack first */
1023 /* pack arguments and kdict */
1024 ci
->stack
[1] = mrb_ary_new_from_values(mrb
, argc
+1, &ci
->stack
[1]);
1028 /* push kdict to packed arguments */
1029 mrb_ary_push(mrb
, ci
->stack
[1], kdict
);
1031 ci
->stack
[2] = ci
->stack
[mrb_ci_bidx(ci
)];
1036 if (reqkarg
&& ci
->nk
> 0) {
1037 kdict
= ci
->stack
[mrb_ci_bidx(ci
)-1];
1038 mrb_assert(ci
->nk
== 15);
1039 mrb_assert(mrb_hash_p(kdict
));
1042 argv_on_stack
= argc
< 15;
1043 if (!argv_on_stack
) {
1044 struct RArray
*a
= mrb_ary_ptr(*argv
);
1047 a
->c
= NULL
; /* hide from ObjectSpace.each_object */
1052 while ((c
= *format
++)) {
1053 mrb_bool altmode
= FALSE
;
1054 mrb_bool needmodify
= FALSE
;
1056 for (; *format
; format
++) {
1059 if (altmode
) goto modifier_exit
; /* not accept for multiple '!' */
1063 if (needmodify
) goto modifier_exit
; /* not accept for multiple '+' */
1073 case '|': case '*': case '&': case '?': case ':':
1076 mrb_raisef(mrb
, E_ARGUMENT_ERROR
, "wrong `%c+` modified specifier`", c
);
1081 pickarg
= &argv
[i
++];
1082 if (needmodify
&& !mrb_nil_p(*pickarg
)) {
1083 mrb_check_frozen_value(mrb
, *pickarg
);
1091 mrb_argnum_error(mrb
, argc
, argc_min
, argc_max
);
1106 p
= GET_ARG(mrb_value
*);
1108 if (!(altmode
&& mrb_nil_p(*pickarg
))) {
1110 case 'C': ensure_class_type(mrb
, *pickarg
); break;
1111 case 'S': mrb_ensure_string_type(mrb
, *pickarg
); break;
1112 case 'A': mrb_ensure_array_type(mrb
, *pickarg
); break;
1113 case 'H': mrb_ensure_hash_type(mrb
, *pickarg
); break;
1124 p
= GET_ARG(struct RClass
**);
1126 if (altmode
&& mrb_nil_p(*pickarg
)) {
1130 ensure_class_type(mrb
, *pickarg
);
1131 *p
= mrb_class_ptr(*pickarg
);
1138 const char **ps
= NULL
;
1141 ps
= GET_ARG(const char**);
1142 pl
= GET_ARG(mrb_int
*);
1143 if (needmodify
) goto bad_needmodify
;
1145 if (altmode
&& mrb_nil_p(*pickarg
)) {
1150 mrb_ensure_string_type(mrb
, *pickarg
);
1151 *ps
= RSTRING_PTR(*pickarg
);
1152 *pl
= RSTRING_LEN(*pickarg
);
1161 ps
= GET_ARG(const char**);
1162 if (needmodify
) goto bad_needmodify
;
1164 if (altmode
&& mrb_nil_p(*pickarg
)) {
1168 mrb_ensure_string_type(mrb
, *pickarg
);
1169 *ps
= RSTRING_CSTR(mrb
, *pickarg
);
1177 const mrb_value
**pb
;
1180 pb
= GET_ARG(const mrb_value
**);
1181 pl
= GET_ARG(mrb_int
*);
1182 if (needmodify
) goto bad_needmodify
;
1184 if (altmode
&& mrb_nil_p(*pickarg
)) {
1189 mrb_ensure_array_type(mrb
, *pickarg
);
1190 a
= mrb_ary_ptr(*pickarg
);
1197 #ifndef MRB_NO_FLOAT
1202 p
= GET_ARG(mrb_float
*);
1204 *p
= mrb_as_float(mrb
, *pickarg
);
1213 p
= GET_ARG(mrb_int
*);
1215 *p
= mrb_as_int(mrb
, *pickarg
);
1221 mrb_bool
*boolp
= GET_ARG(mrb_bool
*);
1224 *boolp
= mrb_test(*pickarg
);
1232 symp
= GET_ARG(mrb_sym
*);
1234 *symp
= to_sym(mrb
, *pickarg
);
1241 struct mrb_data_type
const* type
;
1243 datap
= GET_ARG(void**);
1244 type
= GET_ARG(struct mrb_data_type
const*);
1246 if (altmode
&& mrb_nil_p(*pickarg
)) {
1250 *datap
= mrb_data_get_ptr(mrb
, *pickarg
, type
);
1260 p
= GET_ARG(mrb_value
*);
1261 bp
= ci
->stack
+ mrb_ci_bidx(ci
);
1262 if (altmode
&& mrb_nil_p(*bp
)) {
1263 mrb_raise(mrb
, E_ARGUMENT_ERROR
, "no block given");
1269 if (opt_skip
&& i
== argc
) goto finish
;
1276 p
= GET_ARG(mrb_bool
*);
1277 *p
= pickarg
? TRUE
: FALSE
;
1283 const mrb_value
**var
;
1285 mrb_bool nocopy
= (altmode
|| !argv_on_stack
) ? TRUE
: FALSE
;
1287 var
= GET_ARG(const mrb_value
**);
1288 pl
= GET_ARG(mrb_int
*);
1296 mrb_value args
= mrb_ary_new_from_values(mrb
, *pl
, argv
+i
);
1297 RARRAY(args
)->c
= NULL
;
1298 *var
= RARRAY_PTR(args
);
1312 mrb_value ksrc
= mrb_hash_p(kdict
) ? mrb_hash_dup(mrb
, kdict
) : mrb_hash_new(mrb
);
1313 const mrb_kwargs
*kwargs
= GET_ARG(const mrb_kwargs
*);
1316 if (kwargs
== NULL
) {
1320 mrb_int kwnum
= kwargs
->num
;
1321 mrb_int required
= kwargs
->required
;
1322 const mrb_sym
*kname
= kwargs
->table
;
1323 mrb_value
*values
= kwargs
->values
;
1325 const mrb_int keyword_max
= 40;
1327 mrb_assert(kwnum
>= 0);
1328 mrb_assert(required
>= 0);
1329 if (kwnum
> keyword_max
|| required
> kwnum
) {
1330 mrb_raise(mrb
, E_ARGUMENT_ERROR
, "keyword number is too large");
1333 for (j
= required
; j
> 0; j
--, kname
++, values
++) {
1334 mrb_value k
= mrb_symbol_value(*kname
);
1335 if (!mrb_hash_key_p(mrb
, ksrc
, k
)) {
1336 mrb_raisef(mrb
, E_ARGUMENT_ERROR
, "missing keyword: %n", *kname
);
1338 *values
= mrb_hash_delete_key(mrb
, ksrc
, k
);
1339 mrb_gc_protect(mrb
, *values
);
1342 for (j
= kwnum
- required
; j
> 0; j
--, kname
++, values
++) {
1343 mrb_value k
= mrb_symbol_value(*kname
);
1344 if (mrb_hash_key_p(mrb
, ksrc
, k
)) {
1345 *values
= mrb_hash_delete_key(mrb
, ksrc
, k
);
1346 mrb_gc_protect(mrb
, *values
);
1349 *values
= mrb_undef_value();
1353 rest
= kwargs
->rest
;
1359 else if (!mrb_hash_empty_p(mrb
, ksrc
)) {
1360 ksrc
= mrb_hash_first_key(mrb
, ksrc
);
1361 mrb_raisef(mrb
, E_ARGUMENT_ERROR
, "unknown keyword: %v", ksrc
);
1367 mrb_raisef(mrb
, E_ARGUMENT_ERROR
, "invalid argument specifier %c", c
);
1372 if (!c
&& argc
> i
) {
1373 mrb_argnum_error(mrb
, argc
, argc_min
, argc_max
);
1381 retrieve arguments from mrb_state.
1383 mrb_get_args(mrb, format, ...)
1385 returns number of arguments parsed.
1389 string mruby type C type note
1390 ----------------------------------------------------------------------------------------------
1391 o: Object [mrb_value]
1392 C: Class/Module [mrb_value] when ! follows, the value may be nil
1393 S: String [mrb_value] when ! follows, the value may be nil
1394 A: Array [mrb_value] when ! follows, the value may be nil
1395 H: Hash [mrb_value] when ! follows, the value may be nil
1396 s: String [const char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil
1397 z: String [const char*] NUL terminated string; z! gives NULL for nil
1398 a: Array [const mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil
1399 c: Class/Module [struct RClass*] c! gives NULL for nil
1400 f: Integer/Float [mrb_float]
1401 i: Integer/Float [mrb_int]
1402 b: boolean [mrb_bool]
1403 n: String/Symbol [mrb_sym]
1404 d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil
1405 &: block [mrb_value] &! raises exception if no block given
1406 *: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack
1407 |: optional Following arguments are optional
1408 ?: optional given [mrb_bool] true if preceding argument (optional) is given
1409 ':': keyword args [mrb_kwargs const] Get keyword arguments
1414 ----------------------------------------------------------------------------------------------
1415 !: Switch to the alternate mode; The behaviour changes depending on the specifier
1416 +: Request a not frozen object; However, except nil value
1419 mrb_get_args(mrb_state
*mrb
, mrb_args_format format
, ...)
1422 va_start(ap
, format
);
1423 mrb_int rc
= get_args_v(mrb
, format
, NULL
, &ap
);
1429 mrb_get_args_a(mrb_state
*mrb
, mrb_args_format format
, void **args
)
1431 return get_args_v(mrb
, format
, args
, NULL
);
1434 static struct RClass
*
1435 boot_defclass(mrb_state
*mrb
, struct RClass
*super
)
1437 struct RClass
*c
= MRB_OBJ_ALLOC(mrb
, MRB_TT_CLASS
, mrb
->class_class
);
1441 mrb_field_write_barrier(mrb
, (struct RBasic
*)c
, (struct RBasic
*)super
);
1442 c
->flags
|= MRB_FL_CLASS_IS_INHERITED
;
1445 c
->super
= mrb
->object_class
;
1447 c
->mt
= mt_new(mrb
);
1452 boot_initmod(mrb_state
*mrb
, struct RClass
*mod
)
1455 mod
->mt
= mt_new(mrb
);
1459 static struct RClass
*
1460 include_class_new(mrb_state
*mrb
, struct RClass
*m
, struct RClass
*super
)
1462 struct RClass
*ic
= MRB_OBJ_ALLOC(mrb
, MRB_TT_ICLASS
, mrb
->class_class
);
1463 if (m
->tt
== MRB_TT_ICLASS
) {
1466 MRB_CLASS_ORIGIN(m
);
1469 if (m
->tt
== MRB_TT_ICLASS
) {
1479 include_module_at(mrb_state
*mrb
, struct RClass
*c
, struct RClass
*ins_pos
, struct RClass
*m
, int search_super
)
1482 void *klass_mt
= find_origin(c
)->mt
;
1485 struct RClass
*p
= c
->super
;
1486 int original_seen
= FALSE
;
1487 int superclass_seen
= FALSE
;
1489 if (c
== ins_pos
) original_seen
= TRUE
;
1490 if (m
->flags
& MRB_FL_CLASS_IS_PREPENDED
)
1492 if (klass_mt
&& klass_mt
== m
->mt
)
1496 if (c
== p
) original_seen
= TRUE
;
1497 if (p
->tt
== MRB_TT_ICLASS
) {
1498 if (p
->mt
== m
->mt
) {
1499 if (!superclass_seen
&& original_seen
) {
1500 ins_pos
= p
; /* move insert point */
1505 else if (p
->tt
== MRB_TT_CLASS
) {
1506 if (!search_super
) break;
1507 superclass_seen
= TRUE
;
1512 ic
= include_class_new(mrb
, m
, ins_pos
->super
);
1513 m
->flags
|= MRB_FL_CLASS_IS_INHERITED
;
1514 ins_pos
->super
= ic
;
1515 mrb_field_write_barrier(mrb
, (struct RBasic
*)ins_pos
, (struct RBasic
*)ic
);
1525 fix_include_module(mrb_state
*mrb
, struct RBasic
*obj
, void *data
)
1527 struct RClass
**m
= (struct RClass
**)data
;
1529 if (obj
->tt
== MRB_TT_ICLASS
&& obj
->c
== m
[0] && !MRB_FLAG_TEST(obj
, MRB_FL_CLASS_IS_ORIGIN
)) {
1530 struct RClass
*ic
= (struct RClass
*)obj
;
1531 include_module_at(mrb
, ic
, ic
, m
[1], 1);
1533 return MRB_EACH_OBJ_OK
;
1537 mrb_include_module(mrb_state
*mrb
, struct RClass
*c
, struct RClass
*m
)
1539 mrb_check_frozen(mrb
, c
);
1540 if (include_module_at(mrb
, c
, find_origin(c
), m
, 1) < 0) {
1541 mrb_raise(mrb
, E_ARGUMENT_ERROR
, "cyclic include detected");
1543 if (c
->tt
== MRB_TT_MODULE
&& (c
->flags
& MRB_FL_CLASS_IS_INHERITED
)) {
1544 struct RClass
*data
[2];
1547 mrb_objspace_each_objects(mrb
, fix_include_module
, data
);
1552 fix_prepend_module(mrb_state
*mrb
, struct RBasic
*obj
, void *data
)
1554 struct RClass
**m
= (struct RClass
**)data
;
1555 struct RClass
*c
= (struct RClass
*)obj
;
1557 if (c
->tt
== MRB_TT_CLASS
|| c
->tt
== MRB_TT_MODULE
) {
1558 struct RClass
*p
= c
->super
;
1559 struct RClass
*ins_pos
= c
;
1561 if (c
== m
[0]) break;
1562 if (p
== m
[0]->super
->c
) {
1565 if (p
->tt
== MRB_TT_CLASS
) break;
1567 include_module_at(mrb
, ins_pos
, ins_pos
, m
[1], 0);
1574 return MRB_EACH_OBJ_OK
;
1578 mrb_prepend_module(mrb_state
*mrb
, struct RClass
*c
, struct RClass
*m
)
1580 mrb_check_frozen(mrb
, c
);
1581 if (!(c
->flags
& MRB_FL_CLASS_IS_PREPENDED
)) {
1582 struct RClass
*origin
= MRB_OBJ_ALLOC(mrb
, MRB_TT_ICLASS
, c
);
1583 origin
->flags
|= MRB_FL_CLASS_IS_ORIGIN
| MRB_FL_CLASS_IS_INHERITED
;
1584 origin
->super
= c
->super
;
1588 mrb_field_write_barrier(mrb
, (struct RBasic
*)c
, (struct RBasic
*)origin
);
1589 c
->flags
|= MRB_FL_CLASS_IS_PREPENDED
;
1591 if (include_module_at(mrb
, c
, c
, m
, 0) < 0) {
1592 mrb_raise(mrb
, E_ARGUMENT_ERROR
, "cyclic prepend detected");
1594 if (c
->tt
== MRB_TT_MODULE
&&
1595 (c
->flags
& (MRB_FL_CLASS_IS_INHERITED
|MRB_FL_CLASS_IS_PREPENDED
))) {
1596 struct RClass
*data
[2];
1599 mrb_objspace_each_objects(mrb
, fix_prepend_module
, data
);
1604 mrb_mod_prepend(mrb_state
*mrb
, mrb_value mod
)
1606 struct RClass
*c
= mrb_class_ptr(mod
);
1609 mrb_sym prepended
= MRB_SYM(prepended
);
1611 mrb_get_args(mrb
, "*", &argv
, &argc
);
1613 mrb_value m
= argv
[argc
];
1614 mrb_check_type(mrb
, m
, MRB_TT_MODULE
);
1615 mrb_prepend_module(mrb
, c
, mrb_class_ptr(m
));
1616 if (!mrb_func_basic_p(mrb
, m
, prepended
, mrb_do_nothing
)) {
1617 mrb_funcall_argv(mrb
, m
, prepended
, 1, &mod
);
1624 mrb_mod_include(mrb_state
*mrb
, mrb_value mod
)
1626 struct RClass
*c
= mrb_class_ptr(mod
);
1629 mrb_sym included
= MRB_SYM(included
);
1631 mrb_get_args(mrb
, "*", &argv
, &argc
);
1633 mrb_value m
= argv
[argc
];
1634 mrb_check_type(mrb
, m
, MRB_TT_MODULE
);
1635 mrb_include_module(mrb
, c
, mrb_class_ptr(m
));
1636 if (!mrb_func_basic_p(mrb
, m
, included
, mrb_do_nothing
)) {
1637 mrb_funcall_argv(mrb
, m
, included
, 1, &mod
);
1646 * obj.extend(module, ...) -> obj
1648 * Adds to _obj_ the instance methods from each module given as a
1653 * "Hello from Mod.\n"
1659 * "Hello from Klass.\n"
1664 * k.hello #=> "Hello from Klass.\n"
1665 * k.extend(Mod) #=> #<Klass:0x401b3bc8>
1666 * k.hello #=> "Hello from Mod.\n"
1670 mrb_obj_extend(mrb_state
*mrb
, mrb_value obj
)
1674 mrb_sym extended
= MRB_SYM(extended
);
1676 mrb_get_args(mrb
, "*", &argv
, &argc
);
1678 mrb_value cc
= mrb_singleton_class(mrb
, obj
);
1680 mrb_value mod
= argv
[argc
];
1681 mrb_check_type(mrb
, mod
, MRB_TT_MODULE
);
1682 mrb_include_module(mrb
, mrb_class_ptr(cc
), mrb_class_ptr(mod
));
1683 if (!mrb_func_basic_p(mrb
, cc
, extended
, mrb_do_nothing
)) {
1684 mrb_funcall_argv(mrb
, cc
, extended
, 1, &mod
);
1693 * mod.include?(module) -> true or false
1695 * Returns <code>true</code> if <i>module</i> is included in
1696 * <i>mod</i> or one of <i>mod</i>'s ancestors.
1705 * B.include?(A) #=> true
1706 * C.include?(A) #=> true
1707 * A.include?(A) #=> false
1710 mrb_mod_include_p(mrb_state
*mrb
, mrb_value mod
)
1713 struct RClass
*c
= mrb_class_ptr(mod
);
1715 mrb_get_args(mrb
, "C", &mod2
);
1716 mrb_check_type(mrb
, mod2
, MRB_TT_MODULE
);
1719 if (c
->tt
== MRB_TT_ICLASS
) {
1720 if (c
->c
== mrb_class_ptr(mod2
)) return mrb_true_value();
1724 return mrb_false_value();
1728 mrb_mod_ancestors(mrb_state
*mrb
, mrb_value self
)
1730 struct RClass
*c
= mrb_class_ptr(self
);
1731 mrb_value result
= mrb_ary_new(mrb
);
1734 if (c
->tt
== MRB_TT_ICLASS
) {
1735 mrb_ary_push(mrb
, result
, mrb_obj_value(c
->c
));
1737 else if (!(c
->flags
& MRB_FL_CLASS_IS_PREPENDED
)) {
1738 mrb_ary_push(mrb
, result
, mrb_obj_value(c
));
1747 mrb_mod_initialize(mrb_state
*mrb
, mrb_value mod
)
1750 struct RClass
*m
= mrb_class_ptr(mod
);
1751 boot_initmod(mrb
, m
); /* bootstrap a newly initialized module */
1752 mrb_get_args(mrb
, "|&", &b
);
1753 if (!mrb_nil_p(b
)) {
1754 mrb_yield_with_class(mrb
, b
, 1, &mod
, mod
, m
);
1760 mrb_mod_visibility(mrb_state
*mrb
, mrb_value mod
, int vis
)
1762 mrb_assert((vis
&MT_VMASK
)==vis
);
1765 struct RClass
*c
= mrb_class_ptr(mod
);
1767 mrb_get_args(mrb
, "*!", &argv
, &argc
);
1771 find_visibility_scope(mrb
, NULL
, 1, &ci
, &e
);
1773 MRB_ENV_SET_VISIBILITY(e
, vis
);
1776 MRB_CI_SET_VISIBILITY(ci
, vis
);
1781 for (int i
=0; i
<argc
; i
++) {
1782 mrb_check_type(mrb
, argv
[i
], MRB_TT_SYMBOL
);
1783 mrb_sym mid
= mrb_symbol(argv
[i
]);
1784 mrb_method_t m
= mrb_method_search(mrb
, c
, mid
);
1785 MRB_METHOD_SET_VISIBILITY(m
, vis
);
1787 if (MRB_METHOD_PROC_P(m
)) {
1788 ptr
.proc
= MRB_METHOD_PROC(m
);
1791 ptr
.func
= MRB_METHOD_FUNC(m
);
1793 mt_put(mrb
, h
, mid
, MT_KEY_FLG(m
.flags
), ptr
);
1794 mc_clear_by_id(mrb
, mid
);
1800 mrb_mod_public(mrb_state
*mrb
, mrb_value mod
)
1802 mrb_mod_visibility(mrb
, mod
, MT_PUBLIC
);
1807 mrb_mod_private(mrb_state
*mrb
, mrb_value mod
)
1809 mrb_mod_visibility(mrb
, mod
, MT_PRIVATE
);
1814 mrb_mod_protected(mrb_state
*mrb
, mrb_value mod
)
1816 mrb_mod_visibility(mrb
, mod
, MT_PROTECTED
);
1821 top_public(mrb_state
*mrb
, mrb_value self
)
1823 self
= mrb_obj_value(mrb
->object_class
);
1824 mrb_mod_visibility(mrb
, self
, MT_PUBLIC
);
1829 top_private(mrb_state
*mrb
, mrb_value self
)
1831 self
= mrb_obj_value(mrb
->object_class
);
1832 mrb_mod_visibility(mrb
, self
, MT_PRIVATE
);
1837 top_protected(mrb_state
*mrb
, mrb_value self
)
1839 self
= mrb_obj_value(mrb
->object_class
);
1840 mrb_mod_visibility(mrb
, self
, MT_PROTECTED
);
1844 MRB_API
struct RClass
*
1845 mrb_singleton_class_ptr(mrb_state
*mrb
, mrb_value v
)
1849 switch (mrb_type(v
)) {
1852 return mrb
->nil_class
;
1853 return mrb
->false_class
;
1855 return mrb
->true_class
;
1858 case MRB_TT_INTEGER
:
1859 #ifndef MRB_NO_FLOAT
1866 obj
= mrb_basic_ptr(v
);
1867 if (obj
->c
== NULL
) return NULL
;
1868 prepare_singleton_class(mrb
, obj
);
1873 mrb_singleton_class(mrb_state
*mrb
, mrb_value v
)
1875 struct RClass
*c
= mrb_singleton_class_ptr(mrb
, v
);
1878 mrb_raise(mrb
, E_TYPE_ERROR
, "can't define singleton");
1880 return mrb_obj_value(c
);
1884 mrb_define_singleton_method(mrb_state
*mrb
, struct RObject
*o
, const char *name
, mrb_func_t func
, mrb_aspec aspec
)
1886 prepare_singleton_class(mrb
, (struct RBasic
*)o
);
1887 mrb_define_method_id(mrb
, o
->c
, mrb_intern_cstr(mrb
, name
), func
, aspec
);
1891 mrb_define_singleton_method_id(mrb_state
*mrb
, struct RObject
*o
, mrb_sym name
, mrb_func_t func
, mrb_aspec aspec
)
1893 prepare_singleton_class(mrb
, (struct RBasic
*)o
);
1894 mrb_define_method_id(mrb
, o
->c
, name
, func
, aspec
);
1898 mrb_define_class_method(mrb_state
*mrb
, struct RClass
*c
, const char *name
, mrb_func_t func
, mrb_aspec aspec
)
1900 mrb_define_singleton_method(mrb
, (struct RObject
*)c
, name
, func
, aspec
);
1904 mrb_define_class_method_id(mrb_state
*mrb
, struct RClass
*c
, mrb_sym name
, mrb_func_t func
, mrb_aspec aspec
)
1906 mrb_define_singleton_method_id(mrb
, (struct RObject
*)c
, name
, func
, aspec
);
1910 mrb_define_module_function_id(mrb_state
*mrb
, struct RClass
*c
, mrb_sym name
, mrb_func_t func
, mrb_aspec aspec
)
1912 mrb_define_class_method_id(mrb
, c
, name
, func
, aspec
);
1913 mrb_define_private_method_id(mrb
, c
, name
, func
, aspec
);
1917 mrb_define_module_function(mrb_state
*mrb
, struct RClass
*c
, const char *name
, mrb_func_t func
, mrb_aspec aspec
)
1919 mrb_define_module_function_id(mrb
, c
, mrb_intern_cstr(mrb
, name
), func
, aspec
);
1922 #ifndef MRB_NO_METHOD_CACHE
1923 /* clear whole method cache table */
1925 mc_clear(mrb_state
*mrb
)
1927 static const struct mrb_cache_entry ce_zero
={0};
1929 for (int i
=0; i
<MRB_METHOD_CACHE_SIZE
; i
++) {
1930 mrb
->cache
[i
] = ce_zero
;
1934 /* clear method cache for a class */
1936 mrb_mc_clear_by_class(mrb_state
*mrb
, struct RClass
*c
)
1938 struct mrb_cache_entry
*mc
= mrb
->cache
;
1940 for (int i
=0; i
<MRB_METHOD_CACHE_SIZE
; mc
++,i
++) {
1941 if (mc
->c
== c
|| mc
->c0
== c
) mc
->c
= NULL
;
1946 mc_clear_by_id(mrb_state
*mrb
, mrb_sym id
)
1948 struct mrb_cache_entry
*mc
= mrb
->cache
;
1950 for (int i
=0; i
<MRB_METHOD_CACHE_SIZE
; mc
++,i
++) {
1951 if (METHOD_MID(mc
->m
) == id
) mc
->c
= NULL
;
1954 #endif // MRB_NO_METHOD_CACHE
1957 mrb_vm_find_method(mrb_state
*mrb
, struct RClass
*c
, struct RClass
**cp
, mrb_sym mid
)
1960 #ifndef MRB_NO_METHOD_CACHE
1961 struct RClass
*oc
= c
;
1962 int h
= mrb_int_hash_func(mrb
, ((intptr_t)oc
) ^ mid
) & (MRB_METHOD_CACHE_SIZE
-1);
1963 struct mrb_cache_entry
*mc
= &mrb
->cache
[h
];
1965 if (mc
->c
== c
&& METHOD_MID(mc
->m
) == mid
) {
1976 mrb_sym ret
= mt_get(mrb
, h
, mid
, &ptr
);
1978 if (ptr
.proc
== 0) break;
1980 m
= create_method_value(mrb
, ret
, ptr
);
1981 #ifndef MRB_NO_METHOD_CACHE
1991 MRB_METHOD_FROM_PROC(m
, NULL
);
1992 return m
; /* no method */
1995 MRB_API mrb_method_t
1996 mrb_method_search_vm(mrb_state
*mrb
, struct RClass
**cp
, mrb_sym mid
)
1998 return mrb_vm_find_method(mrb
, *cp
, cp
, mid
);
2001 MRB_API mrb_method_t
2002 mrb_method_search(mrb_state
*mrb
, struct RClass
*c
, mrb_sym mid
)
2006 m
= mrb_method_search_vm(mrb
, &c
, mid
);
2007 if (MRB_METHOD_UNDEF_P(m
)) {
2008 mrb_name_error(mrb
, mid
, "undefined method '%n' for class %C", mid
, c
);
2013 #define ONSTACK_ALLOC_MAX 32
2016 prepare_name_common(mrb_state
*mrb
, mrb_sym sym
, const char *prefix
, const char *suffix
)
2018 char onstack
[ONSTACK_ALLOC_MAX
];
2020 const char *sym_str
= mrb_sym_name_len(mrb
, sym
, &sym_len
);
2021 size_t prefix_len
= prefix
? strlen(prefix
) : 0;
2022 size_t suffix_len
= suffix
? strlen(suffix
) : 0;
2023 size_t name_len
= sym_len
+ prefix_len
+ suffix_len
;
2024 char *buf
= name_len
> sizeof(onstack
) ? (char*)mrb_alloca(mrb
, name_len
) : onstack
;
2027 if (prefix_len
> 0) {
2028 memcpy(p
, prefix
, prefix_len
);
2032 memcpy(p
, sym_str
, sym_len
);
2035 if (suffix_len
> 0) {
2036 memcpy(p
, suffix
, suffix_len
);
2039 return mrb_intern(mrb
, buf
, name_len
);
2043 prepare_ivar_name(mrb_state
*mrb
, mrb_sym sym
)
2045 sym
= prepare_name_common(mrb
, sym
, "@", NULL
);
2046 mrb_iv_name_sym_check(mrb
, sym
);
2047 return mrb_symbol_value(sym
);
2051 prepare_writer_name(mrb_state
*mrb
, mrb_sym sym
)
2053 return prepare_name_common(mrb
, sym
, NULL
, "=");
2057 mod_attr_define(mrb_state
*mrb
, mrb_value mod
, mrb_value (*accessor
)(mrb_state
*, mrb_value
), mrb_sym (*access_name
)(mrb_state
*, mrb_sym
))
2059 struct RClass
*c
= mrb_class_ptr(mod
);
2060 const mrb_value
*argv
;
2063 mrb_get_args(mrb
, "*", &argv
, &argc
);
2065 int ai
= mrb_gc_arena_save(mrb
);
2066 for (int i
=0; i
<argc
; i
++) {
2072 method
= to_sym(mrb
, argv
[i
]);
2073 name
= prepare_ivar_name(mrb
, method
);
2075 method
= access_name(mrb
, method
);
2078 p
= mrb_proc_new_cfunc_with_env(mrb
, accessor
, 1, &name
);
2079 MRB_METHOD_FROM_PROC(m
, p
);
2080 mrb_define_method_raw(mrb
, c
, method
, m
);
2081 mrb_gc_arena_restore(mrb
, ai
);
2083 return mrb_nil_value();
2087 attr_reader(mrb_state
*mrb
, mrb_value obj
)
2089 mrb_value name
= mrb_proc_cfunc_env_get(mrb
, 0);
2090 return mrb_iv_get(mrb
, obj
, to_sym(mrb
, name
));
2094 mrb_mod_attr_reader(mrb_state
*mrb
, mrb_value mod
)
2096 return mod_attr_define(mrb
, mod
, attr_reader
, NULL
);
2100 attr_writer(mrb_state
*mrb
, mrb_value obj
)
2102 mrb_value name
= mrb_proc_cfunc_env_get(mrb
, 0);
2103 mrb_value val
= mrb_get_arg1(mrb
);
2105 mrb_iv_set(mrb
, obj
, to_sym(mrb
, name
), val
);
2110 mrb_mod_attr_writer(mrb_state
*mrb
, mrb_value mod
)
2112 return mod_attr_define(mrb
, mod
, attr_writer
, prepare_writer_name
);
2116 mrb_mod_attr_accessor(mrb_state
*mrb
, mrb_value mod
)
2118 mrb_mod_attr_reader(mrb
, mod
);
2119 return mrb_mod_attr_writer(mrb
, mod
);
2123 mrb_instance_alloc(mrb_state
*mrb
, mrb_value cv
)
2125 struct RClass
*c
= mrb_class_ptr(cv
);
2126 enum mrb_vtype ttype
= MRB_INSTANCE_TT(c
);
2128 if (c
->tt
== MRB_TT_SCLASS
)
2129 mrb_raise(mrb
, E_TYPE_ERROR
, "can't create instance of singleton class");
2131 if (c
== mrb
->nil_class
|| c
== mrb
->false_class
) {
2132 mrb_assert(ttype
== 0);
2134 else if (ttype
== 0) {
2135 ttype
= MRB_TT_OBJECT
;
2137 if (MRB_UNDEF_ALLOCATOR_P(c
)) {
2138 mrb_raisef(mrb
, E_TYPE_ERROR
, "allocator undefined for %v", cv
);
2140 if (ttype
<= MRB_TT_CPTR
) {
2141 mrb_raisef(mrb
, E_TYPE_ERROR
, "can't create instance of %v", cv
);
2144 struct RObject
*o
= (struct RObject
*)mrb_obj_alloc(mrb
, ttype
, c
);
2145 return mrb_obj_value(o
);
2150 * class.new(args, ...) -> obj
2152 * Creates a new object of <i>class</i>'s class, then
2153 * invokes that object's <code>initialize</code> method,
2154 * passing it <i>args</i>. This is the method that ends
2155 * up getting called whenever an object is constructed using
2161 mrb_instance_new(mrb_state
*mrb
, mrb_value cv
)
2163 const mrb_value
*argv
;
2168 mrb_get_args(mrb
, "*!&", &argv
, &argc
, &blk
);
2169 mrb_value obj
= mrb_instance_alloc(mrb
, cv
);
2170 init
= MRB_SYM(initialize
);
2171 if (!mrb_func_basic_p(mrb
, obj
, init
, mrb_do_nothing
)) {
2172 mrb_funcall_with_block(mrb
, obj
, init
, argc
, argv
, blk
);
2178 mrb_obj_new(mrb_state
*mrb
, struct RClass
*c
, mrb_int argc
, const mrb_value
*argv
)
2180 mrb_value obj
= mrb_instance_alloc(mrb
, mrb_obj_value(c
));
2181 mrb_sym mid
= MRB_SYM(initialize
);
2183 if (!mrb_func_basic_p(mrb
, obj
, mid
, mrb_do_nothing
)) {
2184 mrb_funcall_argv(mrb
, obj
, mid
, argc
, argv
);
2190 mrb_class_initialize(mrb_state
*mrb
, mrb_value obj
)
2192 struct RClass
*c
= mrb_class_ptr(obj
);
2195 mrb_raise(mrb
, E_TYPE_ERROR
, "already initialized class");
2199 mrb_get_args(mrb
, "|C&", &a
, &b
);
2200 if (!mrb_nil_p(b
)) {
2201 mrb_yield_with_class(mrb
, b
, 1, &obj
, obj
, c
);
2207 mrb_class_new_class(mrb_state
*mrb
, mrb_value cv
)
2209 mrb_value super
, blk
;
2210 mrb_int n
= mrb_get_args(mrb
, "|C&", &super
, &blk
);
2213 super
= mrb_obj_value(mrb
->object_class
);
2215 mrb_value new_class
= mrb_obj_value(mrb_class_new(mrb
, mrb_class_ptr(super
)));
2216 mrb_sym mid
= MRB_SYM(initialize
);
2217 if (mrb_func_basic_p(mrb
, new_class
, mid
, mrb_class_initialize
)) {
2218 mrb_class_initialize(mrb
, new_class
);
2221 mrb_funcall_with_block(mrb
, new_class
, mid
, n
, &super
, blk
);
2223 mrb_class_inherited(mrb
, mrb_class_ptr(super
), mrb_class_ptr(new_class
));
2228 mrb_class_superclass(mrb_state
*mrb
, mrb_value klass
)
2230 struct RClass
*c
= mrb_class_ptr(klass
);
2232 c
= find_origin(c
)->super
;
2233 while (c
&& c
->tt
== MRB_TT_ICLASS
) {
2234 c
= find_origin(c
)->super
;
2236 if (!c
) return mrb_nil_value();
2237 return mrb_obj_value(c
);
2241 mrb_do_nothing(mrb_state
*mrb
, mrb_value cv
)
2243 return mrb_nil_value();
2247 mrb_bob_not(mrb_state
*mrb
, mrb_value cv
)
2249 return mrb_bool_value(!mrb_test(cv
));
2257 * obj == other -> true or false
2258 * obj.equal?(other) -> true or false
2259 * obj.eql?(other) -> true or false
2261 * Equality---At the <code>Object</code> level, <code>==</code> returns
2262 * <code>true</code> only if <i>obj</i> and <i>other</i> are the
2263 * same object. Typically, this method is overridden in descendant
2264 * classes to provide class-specific meaning.
2266 * Unlike <code>==</code>, the <code>equal?</code> method should never be
2267 * overridden by subclasses: it is used to determine object identity
2268 * (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
2269 * object as <code>b</code>).
2271 * The <code>eql?</code> method returns <code>true</code> if
2272 * <i>obj</i> and <i>anObject</i> have the same value. Used by
2273 * <code>Hash</code> to test members for equality. For objects of
2274 * class <code>Object</code>, <code>eql?</code> is synonymous with
2275 * <code>==</code>. Subclasses normally continue this tradition, but
2276 * there are exceptions. <code>Numeric</code> types, for example,
2277 * perform type conversion across <code>==</code>, but not across
2278 * <code>eql?</code>, so:
2281 * 1.eql? 1.0 #=> false
2284 mrb_obj_equal_m(mrb_state
*mrb
, mrb_value self
)
2286 mrb_value arg
= mrb_get_arg1(mrb
);
2288 return mrb_bool_value(mrb_obj_equal(mrb
, self
, arg
));
2292 mrb_obj_respond_to(mrb_state
*mrb
, struct RClass
* c
, mrb_sym mid
)
2294 mrb_method_t m
= mrb_method_search_vm(mrb
, &c
, mid
);
2296 if (MRB_METHOD_UNDEF_P(m
)) {
2303 mrb_respond_to(mrb_state
*mrb
, mrb_value obj
, mrb_sym mid
)
2305 return mrb_obj_respond_to(mrb
, mrb_class(mrb
, obj
), mid
);
2309 mrb_class_path(mrb_state
*mrb
, struct RClass
*c
)
2311 mrb_sym nsym
= MRB_SYM(__classname__
);
2312 mrb_value path
= mrb_obj_iv_get(mrb
, (struct RObject
*)c
, nsym
);
2314 if (mrb_nil_p(path
)) {
2316 return mrb_class_find_path(mrb
, c
);
2318 else if (mrb_symbol_p(path
)) {
2319 /* toplevel class/module */
2320 return mrb_sym_str(mrb
, mrb_symbol(path
));
2322 return mrb_str_dup(mrb
, path
);
2325 MRB_API
struct RClass
*
2326 mrb_class_real(struct RClass
* cl
)
2328 if (cl
== 0) return NULL
;
2329 while ((cl
->tt
== MRB_TT_SCLASS
) || (cl
->tt
== MRB_TT_ICLASS
)) {
2331 if (cl
== 0) return NULL
;
2337 mrb_class_name(mrb_state
*mrb
, struct RClass
* c
)
2339 if (c
== NULL
) return NULL
;
2341 mrb_value name
= class_name_str(mrb
, c
);
2342 return RSTRING_PTR(name
);
2346 mrb_obj_classname(mrb_state
*mrb
, mrb_value obj
)
2348 return mrb_class_name(mrb
, mrb_obj_class(mrb
, obj
));
2352 * Ensures a class can be derived from super.
2354 * \param super a reference to an object.
2355 * \exception TypeError if \a super is not a Class or \a super is a singleton class.
2358 mrb_check_inheritable(mrb_state
*mrb
, struct RClass
*super
)
2360 if (super
->tt
!= MRB_TT_CLASS
) {
2361 mrb_raisef(mrb
, E_TYPE_ERROR
, "superclass must be a Class (%C given)", super
);
2363 if (super
->tt
== MRB_TT_SCLASS
) {
2364 mrb_raise(mrb
, E_TYPE_ERROR
, "can't make subclass of singleton class");
2366 if (super
== mrb
->class_class
) {
2367 mrb_raise(mrb
, E_TYPE_ERROR
, "can't make subclass of Class");
2372 * Creates a new class.
2373 * \param super a class from which the new class derives.
2374 * \exception TypeError \a super is not inheritable.
2375 * \exception TypeError \a super is the Class class.
2377 MRB_API
struct RClass
*
2378 mrb_class_new(mrb_state
*mrb
, struct RClass
*super
)
2381 mrb_check_inheritable(mrb
, super
);
2384 struct RClass
*c
= boot_defclass(mrb
, super
);
2386 MRB_SET_INSTANCE_TT(c
, MRB_INSTANCE_TT(super
));
2387 c
->flags
|= super
->flags
& MRB_FL_UNDEF_ALLOCATE
;
2389 make_metaclass(mrb
, c
);
2395 * Creates a new module.
2397 MRB_API
struct RClass
*
2398 mrb_module_new(mrb_state
*mrb
)
2400 struct RClass
*m
= MRB_OBJ_ALLOC(mrb
, MRB_TT_MODULE
, mrb
->module_class
);
2401 boot_initmod(mrb
, m
);
2407 * obj.class => class
2409 * Returns the class of <i>obj</i>, now preferred over
2410 * <code>Object#type</code>, as an object's type in Ruby is only
2411 * loosely tied to that object's class. This method must always be
2412 * called with an explicit receiver, as <code>class</code> is also a
2413 * reserved word in Ruby.
2415 * 1.class #=> Integer
2416 * self.class #=> Object
2419 MRB_API
struct RClass
*
2420 mrb_obj_class(mrb_state
*mrb
, mrb_value obj
)
2422 return mrb_class_real(mrb_class(mrb
, obj
));
2426 mrb_alias_method(mrb_state
*mrb
, struct RClass
*c
, mrb_sym a
, mrb_sym b
)
2429 mrb_method_t m
= mrb_method_search(mrb
, c
, b
);
2431 if (!MRB_METHOD_CFUNC_P(m
)) {
2432 const struct RProc
*p
= MRB_METHOD_PROC(m
);
2433 if (!MRB_PROC_CFUNC_P(p
) && !MRB_PROC_ALIAS_P(p
)) {
2434 struct RProc
*pnew
= MRB_OBJ_ALLOC(mrb
, MRB_TT_PROC
, mrb
->proc_class
);
2435 int vis
= MRB_METHOD_VISIBILITY(m
);
2440 pnew
->flags
|= MRB_PROC_ALIAS
;
2441 MRB_METHOD_FROM_PROC(m
, pnew
);
2442 MRB_METHOD_SET_VISIBILITY(m
, vis
);
2445 mrb_define_method_raw(mrb
, c
, a
, m
);
2449 * Defines an alias of a method.
2450 * \param mrb the mruby state
2451 * \param klass the class which the original method belongs to
2452 * \param name1 a new name for the method
2453 * \param name2 the original name of the method
2456 mrb_define_alias(mrb_state
*mrb
, struct RClass
*klass
, const char *name1
, const char *name2
)
2458 mrb_alias_method(mrb
, klass
, mrb_intern_cstr(mrb
, name1
), mrb_intern_cstr(mrb
, name2
));
2462 mrb_define_alias_id(mrb_state
*mrb
, struct RClass
*klass
, mrb_sym a
, mrb_sym b
)
2464 mrb_alias_method(mrb
, klass
, a
, b
);
2469 * mod.to_s -> string
2471 * Return a string representing this module or class. For basic
2472 * classes and modules, this is the name. For singletons, we
2473 * show information on the thing we're attached to as well.
2477 mrb_mod_to_s(mrb_state
*mrb
, mrb_value klass
)
2479 if (mrb_sclass_p(klass
)) {
2480 mrb_value v
= mrb_iv_get(mrb
, klass
, MRB_SYM(__attached__
));
2481 mrb_value str
= mrb_str_new_lit(mrb
, "#<Class:");
2483 if (class_ptr_p(v
)) {
2484 mrb_str_cat_str(mrb
, str
, mrb_inspect(mrb
, v
));
2487 mrb_str_cat_str(mrb
, str
, mrb_any_to_s(mrb
, v
));
2489 return mrb_str_cat_lit(mrb
, str
, ">");
2492 return class_name_str(mrb
, mrb_class_ptr(klass
));
2497 mrb_mod_alias(mrb_state
*mrb
, mrb_value mod
)
2499 struct RClass
*c
= mrb_class_ptr(mod
);
2500 mrb_sym new_name
, old_name
;
2502 mrb_get_args(mrb
, "nn", &new_name
, &old_name
);
2503 mrb_alias_method(mrb
, c
, new_name
, old_name
);
2504 mrb_method_added(mrb
, c
, new_name
);
2509 undef_method(mrb_state
*mrb
, struct RClass
*c
, mrb_sym a
)
2515 MRB_METHOD_FROM_PROC(m
, NULL
);
2516 mrb_define_method_raw(mrb
, c
, a
, m
);
2517 if (c
->tt
== MRB_TT_SCLASS
) {
2518 undefined
= MRB_SYM(singleton_method_undefined
);
2519 recv
= mrb_iv_get(mrb
, mrb_obj_value(c
), MRB_SYM(__attached__
));
2522 undefined
= MRB_SYM(method_undefined
);
2523 recv
= mrb_obj_value(c
);
2525 if (!mrb_func_basic_p(mrb
, recv
, undefined
, mrb_do_nothing
)) {
2526 mrb_value sym
= mrb_symbol_value(a
);
2527 mrb_funcall_argv(mrb
, recv
, undefined
, 1, &sym
);
2532 mrb_undef_method_id(mrb_state
*mrb
, struct RClass
*c
, mrb_sym a
)
2534 if (!mrb_obj_respond_to(mrb
, c
, a
)) {
2535 mrb_name_error(mrb
, a
, "undefined method '%n' for class '%C'", a
, c
);
2537 undef_method(mrb
, c
, a
);
2541 mrb_undef_method(mrb_state
*mrb
, struct RClass
*c
, const char *name
)
2543 undef_method(mrb
, c
, mrb_intern_cstr(mrb
, name
));
2547 mrb_undef_class_method_id(mrb_state
*mrb
, struct RClass
*c
, mrb_sym name
)
2549 mrb_undef_method_id(mrb
, mrb_class_ptr(mrb_singleton_class(mrb
, mrb_obj_value(c
))), name
);
2553 mrb_undef_class_method(mrb_state
*mrb
, struct RClass
*c
, const char *name
)
2555 mrb_undef_method(mrb
, mrb_class_ptr(mrb_singleton_class(mrb
, mrb_obj_value(c
))), name
);
2559 mrb_remove_method(mrb_state
*mrb
, struct RClass
*c0
, mrb_sym mid
)
2561 struct RClass
*c
= c0
;
2562 MRB_CLASS_ORIGIN(c
);
2565 if (h
&& mt_del(mrb
, h
, mid
)) {
2569 mc_clear_by_id(mrb
, mid
);
2570 if (c0
->tt
== MRB_TT_SCLASS
) {
2571 removed
= MRB_SYM(singleton_method_removed
);
2572 recv
= mrb_iv_get(mrb
, mrb_obj_value(c0
), MRB_SYM(__attached__
));
2575 removed
= MRB_SYM(method_removed
);
2576 recv
= mrb_obj_value(c0
);
2578 if (!mrb_func_basic_p(mrb
, recv
, removed
, mrb_do_nothing
)) {
2579 mrb_value sym
= mrb_symbol_value(mid
);
2580 mrb_funcall_argv(mrb
, recv
, removed
, 1, &sym
);
2584 mrb_name_error(mrb
, mid
, "method '%n' not defined in %C", mid
, c
);
2588 mrb_mod_undef(mrb_state
*mrb
, mrb_value mod
)
2590 struct RClass
*c
= mrb_class_ptr(mod
);
2592 const mrb_value
*argv
;
2594 mrb_get_args(mrb
, "*", &argv
, &argc
);
2596 mrb_undef_method_id(mrb
, c
, to_sym(mrb
, *argv
));
2599 return mrb_nil_value();
2603 check_const_name_sym(mrb_state
*mrb
, mrb_sym id
)
2606 const char *name
= mrb_sym_name_len(mrb
, id
, &len
);
2607 if (!mrb_const_name_p(mrb
, name
, len
)) {
2608 mrb_name_error(mrb
, id
, "wrong constant name %n", id
);
2613 mrb_mod_const_defined(mrb_state
*mrb
, mrb_value mod
)
2616 mrb_bool inherit
= TRUE
;
2618 mrb_get_args(mrb
, "n|b", &id
, &inherit
);
2619 check_const_name_sym(mrb
, id
);
2621 return mrb_bool_value(mrb_const_defined(mrb
, mod
, id
));
2623 return mrb_bool_value(mrb_const_defined_at(mrb
, mod
, id
));
2627 mrb_const_get_sym(mrb_state
*mrb
, mrb_value mod
, mrb_sym id
)
2629 check_const_name_sym(mrb
, id
);
2630 return mrb_const_get(mrb
, mod
, id
);
2634 mrb_mod_const_get(mrb_state
*mrb
, mrb_value mod
)
2636 mrb_value path
= mrb_get_arg1(mrb
);
2638 if (mrb_symbol_p(path
)) {
2639 /* const get with symbol */
2640 return mrb_const_get_sym(mrb
, mod
, mrb_symbol(path
));
2643 /* const get with class path string */
2644 mrb_ensure_string_type(mrb
, path
);
2646 char *ptr
= RSTRING_PTR(path
);
2647 mrb_int len
= RSTRING_LEN(path
);
2651 mrb_int end
= mrb_str_index_lit(mrb
, path
, "::", off
);
2652 if (end
== -1) end
= len
;
2653 mrb_sym id
= mrb_intern(mrb
, ptr
+off
, end
-off
);
2654 mod
= mrb_const_get_sym(mrb
, mod
, id
);
2659 if (off
== len
) { /* trailing "::" */
2660 mrb_name_error(mrb
, id
, "wrong constant name '%v'", path
);
2669 mrb_mod_const_set(mrb_state
*mrb
, mrb_value mod
)
2674 mrb_get_args(mrb
, "no", &id
, &value
);
2675 check_const_name_sym(mrb
, id
);
2676 mrb_const_set(mrb
, mod
, id
, value
);
2681 mrb_mod_remove_const(mrb_state
*mrb
, mrb_value mod
)
2685 mrb_get_args(mrb
, "n", &id
);
2686 check_const_name_sym(mrb
, id
);
2688 mrb_value val
= mrb_iv_remove(mrb
, mod
, id
);
2689 if (mrb_undef_p(val
)) {
2690 mrb_name_error(mrb
, id
, "constant %n not defined", id
);
2696 mrb_const_missing(mrb_state
*mrb
, mrb_value mod
, mrb_sym sym
)
2698 if (mrb_class_real(mrb_class_ptr(mod
)) != mrb
->object_class
) {
2699 mrb_name_error(mrb
, sym
, "uninitialized constant %v::%n", mod
, sym
);
2702 mrb_name_error(mrb
, sym
, "uninitialized constant %n", sym
);
2705 return mrb_nil_value();
2709 mrb_mod_const_missing(mrb_state
*mrb
, mrb_value mod
)
2713 mrb_get_args(mrb
, "n", &sym
);
2714 mrb
->c
->ci
->mid
= 0;
2715 return mrb_const_missing(mrb
, mod
, sym
);
2721 * mod.method_defined?(symbol) -> true or false
2723 * Returns +true+ if the named method is defined by
2724 * _mod_ (or its included modules and, if _mod_ is a class,
2725 * its ancestors). Public and protected methods are matched.
2738 * A.method_defined? :method1 #=> true
2739 * C.method_defined? "method1" #=> true
2740 * C.method_defined? "method2" #=> true
2741 * C.method_defined? "method3" #=> true
2742 * C.method_defined? "method4" #=> false
2746 mrb_mod_method_defined(mrb_state
*mrb
, mrb_value mod
)
2750 mrb_get_args(mrb
, "n", &id
);
2751 return mrb_bool_value(mrb_obj_respond_to(mrb
, mrb_class_ptr(mod
), id
));
2755 mrb_method_added(mrb_state
*mrb
, struct RClass
*c
, mrb_sym mid
)
2758 mrb_value recv
= mrb_obj_value(c
);
2760 if (c
->tt
== MRB_TT_SCLASS
) {
2761 added
= MRB_SYM(singleton_method_added
);
2762 recv
= mrb_iv_get(mrb
, recv
, MRB_SYM(__attached__
));
2765 added
= MRB_SYM(method_added
);
2767 if (!mrb_func_basic_p(mrb
, recv
, added
, mrb_do_nothing
)) {
2768 mrb_value sym
= mrb_symbol_value(mid
);
2769 mrb_funcall_argv(mrb
, recv
, added
, 1, &sym
);
2774 define_method_m(mrb_state
*mrb
, struct RClass
*c
, int vis
)
2777 mrb_value proc
= mrb_undef_value();
2780 mrb_get_args(mrb
, "n|o&", &mid
, &proc
, &blk
);
2781 switch (mrb_type(proc
)) {
2789 mrb_raisef(mrb
, E_TYPE_ERROR
, "wrong argument type %T (expected Proc)", proc
);
2792 if (mrb_nil_p(blk
)) {
2793 mrb_raise(mrb
, E_ARGUMENT_ERROR
, "no block given");
2795 struct RProc
*p
= MRB_OBJ_ALLOC(mrb
, MRB_TT_PROC
, mrb
->proc_class
);
2796 mrb_proc_copy(mrb
, p
, mrb_proc_ptr(blk
));
2797 p
->flags
|= MRB_PROC_STRICT
;
2800 MRB_METHOD_FROM_PROC(m
, p
);
2801 MRB_METHOD_SET_VISIBILITY(m
, vis
);
2802 mrb_define_method_raw(mrb
, c
, mid
, m
);
2803 mrb_method_added(mrb
, c
, mid
);
2804 return mrb_symbol_value(mid
);
2808 mrb_mod_define_method_m(mrb_state
*mrb
, struct RClass
*c
)
2810 return define_method_m(mrb
, c
, MT_PUBLIC
);
2814 mod_define_method(mrb_state
*mrb
, mrb_value self
)
2816 return mrb_mod_define_method_m(mrb
, mrb_class_ptr(self
));
2820 top_define_method(mrb_state
*mrb
, mrb_value self
)
2822 return define_method_m(mrb
, mrb
->object_class
, MT_PRIVATE
);
2826 mrb_mod_eqq(mrb_state
*mrb
, mrb_value mod
)
2828 mrb_value obj
= mrb_get_arg1(mrb
);
2829 mrb_bool eqq
= mrb_obj_is_kind_of(mrb
, obj
, mrb_class_ptr(mod
));
2831 return mrb_bool_value(eqq
);
2835 mrb_mod_dup(mrb_state
*mrb
, mrb_value self
)
2837 mrb_value mod
= mrb_obj_clone(mrb
, self
);
2838 mrb_obj_ptr(mod
)->frozen
= 0;
2843 mrb_mod_module_function(mrb_state
*mrb
, mrb_value mod
)
2845 const mrb_value
*argv
;
2848 mrb_check_type(mrb
, mod
, MRB_TT_MODULE
);
2850 mrb_get_args(mrb
, "*", &argv
, &argc
);
2852 /* set MODFUNC SCOPE if implemented */
2856 /* set PRIVATE method visibility if implemented */
2857 /* mrb_mod_dummy_visibility(mrb, mod); */
2859 struct RClass
*rclass
= mrb_class_ptr(mod
);
2860 int ai
= mrb_gc_arena_save(mrb
);
2861 for (int i
=0; i
<argc
; i
++) {
2862 mrb_check_type(mrb
, argv
[i
], MRB_TT_SYMBOL
);
2864 mrb_sym mid
= mrb_symbol(argv
[i
]);
2865 mrb_method_t m
= mrb_method_search(mrb
, rclass
, mid
);
2867 prepare_singleton_class(mrb
, (struct RBasic
*)rclass
);
2868 MRB_METHOD_SET_VISIBILITY(m
, MT_PUBLIC
);
2869 mrb_define_method_raw(mrb
, rclass
->c
, mid
, m
);
2870 mrb_gc_arena_restore(mrb
, ai
);
2876 static struct RClass
*
2877 mrb_singleton_class_clone(mrb_state
*mrb
, mrb_value obj
)
2879 struct RClass
*klass
= mrb_basic_ptr(obj
)->c
;
2881 if (klass
->tt
!= MRB_TT_SCLASS
)
2884 /* copy singleton(unnamed) class */
2885 struct RClass
*clone
= (struct RClass
*)mrb_obj_alloc(mrb
, klass
->tt
, mrb
->class_class
);
2887 switch (mrb_type(obj
)) {
2892 clone
->c
= mrb_singleton_class_clone(mrb
, mrb_obj_value(klass
));
2895 clone
->super
= klass
->super
;
2897 mrb_iv_copy(mrb
, mrb_obj_value(clone
), mrb_obj_value(klass
));
2898 mrb_obj_iv_set(mrb
, (struct RObject
*)clone
, MRB_SYM(__attached__
), obj
);
2901 clone
->mt
= mt_copy(mrb
, klass
->mt
);
2904 clone
->mt
= mt_new(mrb
);
2906 clone
->tt
= MRB_TT_SCLASS
;
2912 copy_class(mrb_state
*mrb
, mrb_value dst
, mrb_value src
)
2914 struct RClass
*dc
= mrb_class_ptr(dst
);
2915 struct RClass
*sc
= mrb_class_ptr(src
);
2916 /* if the origin is not the same as the class, then the origin and
2917 the current class need to be copied */
2918 if (sc
->flags
& MRB_FL_CLASS_IS_PREPENDED
) {
2919 struct RClass
*c0
= sc
->super
;
2920 struct RClass
*c1
= dc
;
2922 /* copy prepended iclasses */
2923 while (!(c0
->flags
& MRB_FL_CLASS_IS_ORIGIN
)) {
2924 c1
->super
= mrb_class_ptr(mrb_obj_dup(mrb
, mrb_obj_value(c0
)));
2928 c1
->super
= mrb_class_ptr(mrb_obj_dup(mrb
, mrb_obj_value(c0
)));
2929 c1
->super
->flags
|= MRB_FL_CLASS_IS_ORIGIN
;
2932 if (sc
->tt
== MRB_TT_ICLASS
&& !(sc
->flags
& MRB_FL_CLASS_IS_ORIGIN
)) {
2936 dc
->mt
= mt_copy(mrb
, sc
->mt
);
2939 dc
->super
= sc
->super
;
2940 dc
->flags
= sc
->flags
;
2945 mrb_value
mrb_obj_init_copy(mrb_state
*mrb
, mrb_value self
);
2948 init_copy(mrb_state
*mrb
, mrb_value dest
, mrb_value obj
)
2950 mrb_assert((mrb_type(dest
) == mrb_type(obj
)));
2951 switch (mrb_unboxed_type(obj
)) {
2953 copy_class(mrb
, dest
, obj
);
2957 copy_class(mrb
, dest
, obj
);
2958 mrb_iv_copy(mrb
, dest
, obj
);
2959 mrb_iv_remove(mrb
, dest
, MRB_SYM(__classname__
));
2965 case MRB_TT_EXCEPTION
:
2966 mrb_iv_copy(mrb
, dest
, obj
);
2968 case MRB_TT_ISTRUCT
:
2969 mrb_istruct_copy(dest
, obj
);
2971 #if !defined(MRB_NO_FLOAT) && defined(MRB_WORDBOX_NO_FLOAT_TRUNCATE)
2974 struct RFloat
*f
= (struct RFloat
*)mrb_obj_ptr(dest
);
2975 f
->f
= mrb_float(obj
);
2979 #ifdef MRB_USE_BIGINT
2981 mrb_bint_copy(mrb
, dest
, obj
);
2984 #ifdef MRB_USE_RATIONAL
2985 case MRB_TT_RATIONAL
:
2986 mrb_rational_copy(mrb
, dest
, obj
);
2989 #ifdef MRB_USE_COMPLEX
2990 case MRB_TT_COMPLEX
:
2991 mrb_complex_copy(mrb
, dest
, obj
);
2998 if (!mrb_func_basic_p(mrb
, dest
, MRB_SYM(initialize_copy
), mrb_obj_init_copy
)) {
2999 mrb_funcall_argv(mrb
, dest
, MRB_SYM(initialize_copy
), 1, &obj
);
3006 * obj.clone -> an_object
3008 * Produces a shallow copy of <i>obj</i>---the instance variables of
3009 * <i>obj</i> are copied, but not the objects they reference. Copies
3010 * the frozen state of <i>obj</i>. See also the discussion
3011 * under <code>Object#dup</code>.
3014 * attr_accessor :str
3016 * s1 = Klass.new #=> #<Klass:0x401b3a38>
3017 * s1.str = "Hello" #=> "Hello"
3018 * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello">
3019 * s2.str[1,4] = "i" #=> "i"
3020 * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
3021 * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">"
3023 * This method may have class-specific behavior. If so, that
3024 * behavior will be documented under the #+initialize_copy+ method of
3027 * Some Class(True False Nil Symbol Integer Float) Object cannot clone.
3030 mrb_obj_clone(mrb_state
*mrb
, mrb_value self
)
3032 if (mrb_immediate_p(self
)) {
3035 if (mrb_sclass_p(self
)) {
3036 mrb_raise(mrb
, E_TYPE_ERROR
, "can't clone singleton class");
3038 struct RObject
*p
= (struct RObject
*)mrb_obj_alloc(mrb
, mrb_unboxed_type(self
), mrb_obj_class(mrb
, self
));
3039 p
->c
= mrb_singleton_class_clone(mrb
, self
);
3040 mrb_field_write_barrier(mrb
, (struct RBasic
*)p
, (struct RBasic
*)p
->c
);
3042 mrb_value clone
= mrb_obj_value(p
);
3043 init_copy(mrb
, clone
, self
);
3044 p
->frozen
= mrb_obj_ptr(self
)->frozen
;
3052 * obj.dup -> an_object
3054 * Produces a shallow copy of <i>obj</i>---the instance variables of
3055 * <i>obj</i> are copied, but not the objects they reference.
3056 * <code>dup</code> copies the frozen state of <i>obj</i>. See also
3057 * the discussion under <code>Object#clone</code>. In general,
3058 * <code>clone</code> and <code>dup</code> may have different semantics
3059 * in descendant classes. While <code>clone</code> is used to duplicate
3060 * an object, including its internal state, <code>dup</code> typically
3061 * uses the class of the descendant object to create the new instance.
3063 * This method may have class-specific behavior. If so, that
3064 * behavior will be documented under the #+initialize_copy+ method of
3069 mrb_obj_dup(mrb_state
*mrb
, mrb_value obj
)
3071 if (mrb_immediate_p(obj
)) {
3074 if (mrb_sclass_p(obj
)) {
3075 mrb_raise(mrb
, E_TYPE_ERROR
, "can't dup singleton class");
3078 struct RBasic
*p
= mrb_obj_alloc(mrb
, mrb_type(obj
), mrb_obj_class(mrb
, obj
));
3079 mrb_value dup
= mrb_obj_value(p
);
3080 init_copy(mrb
, dup
, obj
);
3085 /* implementation of __id__ */
3086 mrb_value
mrb_obj_id_m(mrb_state
*mrb
, mrb_value self
);
3089 mrb_method_missing(mrb_state
*mrb
, mrb_sym name
, mrb_value self
, mrb_value args
)
3091 mrb_no_method_error(mrb
, name
, args
, "undefined method '%n' for %T", name
, self
);
3097 * obj.method_missing(symbol [, *args] ) -> result
3099 * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle.
3100 * <i>symbol</i> is the symbol for the method called, and <i>args</i>
3101 * are any arguments that were passed to it. By default, the interpreter
3102 * raises an error when this method is called. However, it is possible
3103 * to override the method to provide more dynamic behavior.
3104 * If it is decided that a particular method should not be handled, then
3105 * <i>super</i> should be called, so that ancestors can pick up the
3107 * The example below creates
3108 * a class <code>Roman</code>, which responds to methods with names
3109 * consisting of roman numerals, returning the corresponding integer
3113 * def romanToInt(str)
3116 * def method_missing(sym)
3128 mrb_obj_missing(mrb_state
*mrb
, mrb_value mod
)
3134 mrb
->c
->ci
->mid
= 0;
3135 mrb_get_args(mrb
, "n*!", &name
, &a
, &alen
);
3136 mrb_method_missing(mrb
, name
, mod
, mrb_ary_new_from_values(mrb
, alen
, a
));
3138 return mrb_nil_value();
3142 inspect_main(mrb_state
*mrb
, mrb_value mod
)
3144 return mrb_str_new_lit(mrb
, "main");
3147 static const mrb_code new_iseq
[] = {
3148 OP_ENTER
, 0x0, 0x10, 0x3, // OP_ENTER 0:0:1:0:0:1:1
3149 OP_SSEND
, 4, 0, 0, // OP_SSEND R4 :allocate n=0
3150 OP_MOVE
, 0, 4, // OP_MOVE R0 R4
3151 OP_MOVE
, 4, 3, // OP_MOVE R4 R3 (&)
3152 OP_MOVE
, 3, 2, // OP_MOVE R3 R2 (**)
3153 OP_MOVE
, 2, 1, // OP_MOVE R2 R1 (*)
3154 OP_SSENDB
, 1, 1, 255, // OP_SSENDB R1 :initialize n=*|nk=*
3155 OP_RETURN
, 0 // OP_RETURN R0
3158 MRB_PRESYM_DEFINE_VAR_AND_INITER(new_syms
, 2, MRB_SYM(allocate
), MRB_SYM(initialize
))
3160 static const mrb_irep new_irep
= {
3161 4, 6, 0, MRB_IREP_STATIC
,
3162 new_iseq
, NULL
, new_syms
, NULL
, NULL
, NULL
,
3163 sizeof(new_iseq
), 0, 2, 0, 0,
3167 static const struct RProc new_proc
= {
3168 NULL
, NULL
, MRB_TT_PROC
, MRB_GC_RED
, MRB_OBJ_IS_FROZEN
, MRB_PROC_SCOPE
| MRB_PROC_STRICT
,
3169 { &new_irep
}, NULL
, { NULL
}
3173 init_class_new(mrb_state
*mrb
, struct RClass
*cls
)
3177 MRB_PRESYM_INIT_SYMBOLS(mrb
, new_syms
);
3178 MRB_METHOD_FROM_PROC(m
, &new_proc
);
3179 mrb_define_method_raw(mrb
, cls
, MRB_SYM(new), m
);
3182 static const mrb_code neq_iseq
[] = {
3183 OP_ENTER
, 0x4, 0, 0, // OP_ENTER 1:0:0:0:0:0:0
3184 OP_EQ
, 0, // OP_EQ R0 (R1)
3185 OP_JMPNOT
, 0, 0, 5, // OP_JMPNOT R3 016
3186 OP_LOADF
, 0, // OP_LOADF R0 (true)
3187 OP_JMP
, 0, 2, // OP_JMP R1 018
3188 OP_LOADT
, 0, // OP_LOADT R3 (true)
3189 OP_RETURN
, 0 // OP_RETURN R0
3192 static const mrb_irep neq_irep
= {
3193 4, 6, 0, MRB_IREP_STATIC
,
3194 neq_iseq
, NULL
, NULL
, NULL
, NULL
, NULL
,
3195 sizeof(neq_iseq
), 0, 2, 0, 0,
3199 static const struct RProc neq_proc
= {
3200 NULL
, NULL
, MRB_TT_PROC
, MRB_GC_RED
, MRB_OBJ_IS_FROZEN
, MRB_PROC_SCOPE
| MRB_PROC_STRICT
,
3201 { &neq_irep
}, NULL
, { NULL
}
3205 mrb_init_class(mrb_state
*mrb
)
3207 struct RClass
*bob
; /* BasicObject */
3208 struct RClass
*obj
; /* Object */
3209 struct RClass
*mod
; /* Module */
3210 struct RClass
*cls
; /* Class */
3212 /* boot class hierarchy */
3213 bob
= boot_defclass(mrb
, 0);
3214 obj
= boot_defclass(mrb
, bob
); mrb
->object_class
= obj
;
3215 mod
= boot_defclass(mrb
, obj
); mrb
->module_class
= mod
;/* obj -> mod */
3216 cls
= boot_defclass(mrb
, mod
); mrb
->class_class
= cls
; /* obj -> cls */
3217 /* fix-up loose ends */
3218 bob
->c
= obj
->c
= mod
->c
= cls
->c
= cls
;
3219 make_metaclass(mrb
, bob
);
3220 make_metaclass(mrb
, obj
);
3221 make_metaclass(mrb
, mod
);
3222 make_metaclass(mrb
, cls
);
3224 /* name basic classes */
3225 mrb_define_const_id(mrb
, bob
, MRB_SYM(BasicObject
), mrb_obj_value(bob
));
3226 mrb_define_const_id(mrb
, obj
, MRB_SYM(Object
), mrb_obj_value(obj
));
3227 mrb_define_const_id(mrb
, obj
, MRB_SYM(Module
), mrb_obj_value(mod
));
3228 mrb_define_const_id(mrb
, obj
, MRB_SYM(Class
), mrb_obj_value(cls
));
3230 /* name each classes */
3231 mrb_class_name_class(mrb
, NULL
, bob
, MRB_SYM(BasicObject
));
3232 mrb_class_name_class(mrb
, NULL
, obj
, MRB_SYM(Object
)); /* 15.2.1 */
3233 mrb_class_name_class(mrb
, NULL
, mod
, MRB_SYM(Module
)); /* 15.2.2 */
3234 mrb_class_name_class(mrb
, NULL
, cls
, MRB_SYM(Class
)); /* 15.2.3 */
3236 MRB_SET_INSTANCE_TT(cls
, MRB_TT_CLASS
);
3237 mrb_define_method_id(mrb
, bob
, MRB_SYM(initialize
), mrb_do_nothing
, MRB_ARGS_NONE());
3238 mrb_define_method_id(mrb
, bob
, MRB_OPSYM(not), mrb_bob_not
, MRB_ARGS_NONE());
3239 mrb_define_method_id(mrb
, bob
, MRB_OPSYM(eq
), mrb_obj_equal_m
, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */
3240 mrb_define_method_id(mrb
, bob
, MRB_SYM(__id__
), mrb_obj_id_m
, MRB_ARGS_NONE()); /* 15.3.1.3.4 */
3241 mrb_define_method_id(mrb
, bob
, MRB_SYM(__send__
), mrb_f_send
, MRB_ARGS_REQ(1)|MRB_ARGS_REST()|MRB_ARGS_BLOCK()); /* 15.3.1.3.5 */
3242 mrb_define_method_id(mrb
, bob
, MRB_SYM_Q(equal
), mrb_obj_equal_m
, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */
3243 mrb_define_method_id(mrb
, bob
, MRB_SYM(instance_eval
), mrb_obj_instance_eval
, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK()); /* 15.3.1.3.18 */
3244 mrb_define_private_method_id(mrb
, bob
, MRB_SYM(singleton_method_added
), mrb_do_nothing
, MRB_ARGS_REQ(1));
3245 mrb_define_private_method_id(mrb
, bob
, MRB_SYM(singleton_method_removed
),mrb_do_nothing
, MRB_ARGS_REQ(1));
3246 mrb_define_private_method_id(mrb
, bob
, MRB_SYM(singleton_method_undefined
),mrb_do_nothing
, MRB_ARGS_REQ(1));
3247 mrb_define_private_method_id(mrb
, bob
, MRB_SYM(method_missing
), mrb_obj_missing
, MRB_ARGS_ANY()); /* 15.3.1.3.30 */
3250 MRB_METHOD_FROM_PROC(m
, &neq_proc
);
3251 mrb_define_method_raw(mrb
, bob
, MRB_OPSYM(neq
), m
);
3253 mrb_define_class_method_id(mrb
, cls
, MRB_SYM(new), mrb_class_new_class
, MRB_ARGS_OPT(1)|MRB_ARGS_BLOCK());
3254 mrb_define_method_id(mrb
, cls
, MRB_SYM(allocate
), mrb_instance_alloc
, MRB_ARGS_NONE());
3255 mrb_define_method_id(mrb
, cls
, MRB_SYM(superclass
), mrb_class_superclass
, MRB_ARGS_NONE()); /* 15.2.3.3.4 */
3256 mrb_define_method_id(mrb
, cls
, MRB_SYM(initialize
), mrb_class_initialize
, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */
3257 mrb_define_private_method_id(mrb
, cls
, MRB_SYM(inherited
), mrb_do_nothing
, MRB_ARGS_REQ(1));
3259 init_class_new(mrb
, cls
);
3261 MRB_SET_INSTANCE_TT(mod
, MRB_TT_MODULE
);
3262 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(extended
), mrb_do_nothing
, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */
3263 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(prepended
), mrb_do_nothing
, MRB_ARGS_REQ(1));
3264 mrb_define_method_id(mrb
, mod
, MRB_SYM_Q(include
), mrb_mod_include_p
, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */
3266 mrb_define_method_id(mrb
, mod
, MRB_SYM(include
), mrb_mod_include
, MRB_ARGS_REQ(1)); /* 15.2.2.4.27 */
3267 mrb_define_method_id(mrb
, mod
, MRB_SYM(prepend
), mrb_mod_prepend
, MRB_ARGS_REQ(1));
3268 mrb_define_method_id(mrb
, mod
, MRB_SYM(class_eval
), mrb_mod_module_eval
, MRB_ARGS_ANY()); /* 15.2.2.4.15 */
3269 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(included
), mrb_do_nothing
, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */
3270 mrb_define_method_id(mrb
, mod
, MRB_SYM(initialize
), mrb_mod_initialize
, MRB_ARGS_NONE()); /* 15.2.2.4.31 */
3271 mrb_define_method_id(mrb
, mod
, MRB_SYM(module_eval
), mrb_mod_module_eval
, MRB_ARGS_ANY()); /* 15.2.2.4.35 */
3272 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(module_function
), mrb_mod_module_function
, MRB_ARGS_ANY());
3273 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(private), mrb_mod_private
, MRB_ARGS_ANY()); /* 15.2.2.4.36 */
3274 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(protected), mrb_mod_protected
, MRB_ARGS_ANY()); /* 15.2.2.4.37 */
3275 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(public), mrb_mod_public
, MRB_ARGS_ANY()); /* 15.2.2.4.38 */
3276 mrb_define_method_id(mrb
, mod
, MRB_SYM(attr_accessor
), mrb_mod_attr_accessor
, MRB_ARGS_ANY()); /* 15.2.2.4.12 */
3277 mrb_define_method_id(mrb
, mod
, MRB_SYM(attr_reader
), mrb_mod_attr_reader
, MRB_ARGS_ANY()); /* 15.2.2.4.13 */
3278 mrb_define_method_id(mrb
, mod
, MRB_SYM(attr_writer
), mrb_mod_attr_writer
, MRB_ARGS_ANY()); /* 15.2.2.4.14 */
3279 mrb_define_alias_id(mrb
, mod
, MRB_SYM(attr
), MRB_SYM(attr_reader
)); /* 15.2.2.4.11 */
3280 mrb_define_method_id(mrb
, mod
, MRB_SYM(to_s
), mrb_mod_to_s
, MRB_ARGS_NONE());
3281 mrb_define_method_id(mrb
, mod
, MRB_SYM(inspect
), mrb_mod_to_s
, MRB_ARGS_NONE());
3282 mrb_define_method_id(mrb
, mod
, MRB_SYM(alias_method
), mrb_mod_alias
, MRB_ARGS_ANY()); /* 15.2.2.4.8 */
3283 mrb_define_method_id(mrb
, mod
, MRB_SYM(ancestors
), mrb_mod_ancestors
, MRB_ARGS_NONE()); /* 15.2.2.4.9 */
3284 mrb_define_method_id(mrb
, mod
, MRB_SYM(undef_method
), mrb_mod_undef
, MRB_ARGS_ANY()); /* 15.2.2.4.41 */
3285 mrb_define_method_id(mrb
, mod
, MRB_SYM_Q(const_defined
), mrb_mod_const_defined
, MRB_ARGS_ARG(1,1)); /* 15.2.2.4.20 */
3286 mrb_define_method_id(mrb
, mod
, MRB_SYM(const_get
), mrb_mod_const_get
, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */
3287 mrb_define_method_id(mrb
, mod
, MRB_SYM(const_set
), mrb_mod_const_set
, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */
3288 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(remove_const
), mrb_mod_remove_const
, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */
3289 mrb_define_method_id(mrb
, mod
, MRB_SYM(const_missing
), mrb_mod_const_missing
, MRB_ARGS_REQ(1));
3290 mrb_define_method_id(mrb
, mod
, MRB_SYM_Q(method_defined
), mrb_mod_method_defined
, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */
3291 mrb_define_method_id(mrb
, mod
, MRB_SYM(define_method
), mod_define_method
, MRB_ARGS_ARG(1,1));
3292 mrb_define_method_id(mrb
, mod
, MRB_OPSYM(eqq
), mrb_mod_eqq
, MRB_ARGS_REQ(1)); /* 15.2.2.4.7 */
3293 mrb_define_method_id(mrb
, mod
, MRB_SYM(dup
), mrb_mod_dup
, MRB_ARGS_NONE());
3294 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(method_added
), mrb_do_nothing
, MRB_ARGS_REQ(1));
3295 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(method_removed
), mrb_do_nothing
, MRB_ARGS_REQ(1));
3296 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(method_undefined
), mrb_do_nothing
, MRB_ARGS_REQ(1));
3297 mrb_define_private_method_id(mrb
, mod
, MRB_SYM(const_added
), mrb_do_nothing
, MRB_ARGS_REQ(1));
3299 mrb_undef_method_id(mrb
, cls
, MRB_SYM(module_function
));
3301 mrb
->top_self
= MRB_OBJ_ALLOC(mrb
, MRB_TT_OBJECT
, mrb
->object_class
);
3302 mrb_define_singleton_method_id(mrb
, mrb
->top_self
, MRB_SYM(inspect
), inspect_main
, MRB_ARGS_NONE());
3303 mrb_define_singleton_method_id(mrb
, mrb
->top_self
, MRB_SYM(to_s
), inspect_main
, MRB_ARGS_NONE());
3304 mrb_define_singleton_method_id(mrb
, mrb
->top_self
, MRB_SYM(define_method
), top_define_method
, MRB_ARGS_ARG(1,1));
3305 mrb_define_singleton_method_id(mrb
, mrb
->top_self
, MRB_SYM(public), top_public
, MRB_ARGS_ANY());
3306 mrb_define_singleton_method_id(mrb
, mrb
->top_self
, MRB_SYM(private), top_private
, MRB_ARGS_ANY());
3307 mrb_define_singleton_method_id(mrb
, mrb
->top_self
, MRB_SYM(protected), top_protected
, MRB_ARGS_ANY());