diff options
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby/src/class.c')
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby/src/class.c | 2474 |
1 files changed, 0 insertions, 2474 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/src/class.c b/web/server/h2o/libh2o/deps/mruby/src/class.c deleted file mode 100644 index e3888001b..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/class.c +++ /dev/null @@ -1,2474 +0,0 @@ -/* -** class.c - Class class -** -** See Copyright Notice in mruby.h -*/ - -#include <stdarg.h> -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/class.h> -#include <mruby/numeric.h> -#include <mruby/proc.h> -#include <mruby/string.h> -#include <mruby/variable.h> -#include <mruby/error.h> -#include <mruby/data.h> -#include <mruby/istruct.h> - -KHASH_DEFINE(mt, mrb_sym, struct RProc*, TRUE, kh_int_hash_func, kh_int_hash_equal) - -void -mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) -{ - khiter_t k; - khash_t(mt) *h = c->mt; - - if (!h) return; - for (k = kh_begin(h); k != kh_end(h); k++) { - if (kh_exist(h, k)) { - struct RProc *m = kh_value(h, k); - if (m) { - mrb_gc_mark(mrb, (struct RBasic*)m); - } - } - } -} - -size_t -mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c) -{ - khash_t(mt) *h = c->mt; - - if (!h) return 0; - return kh_size(h); -} - -void -mrb_gc_free_mt(mrb_state *mrb, struct RClass *c) -{ - kh_destroy(mt, mrb, c->mt); -} - -void -mrb_class_name_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) -{ - mrb_value name; - mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); - - if (mrb_obj_iv_defined(mrb, (struct RObject*)c, nsym)) return; - if (outer == NULL || outer == mrb->object_class) { - name = mrb_symbol_value(id); - } - else { - name = mrb_class_path(mrb, outer); - if (mrb_nil_p(name)) { /* unnamed outer class */ - if (outer != mrb->object_class) { - mrb_obj_iv_set(mrb, (struct RObject*)c, mrb_intern_lit(mrb, "__outer__"), - mrb_obj_value(outer)); - } - return; - } - mrb_str_cat_cstr(mrb, name, "::"); - mrb_str_cat_cstr(mrb, name, mrb_sym2name(mrb, id)); - } - mrb_obj_iv_set(mrb, (struct RObject*)c, nsym, name); -} - -static void -setup_class(mrb_state *mrb, struct RClass *outer, struct RClass *c, mrb_sym id) -{ - mrb_class_name_class(mrb, outer, c, id); - mrb_obj_iv_set(mrb, (struct RObject*)outer, id, mrb_obj_value(c)); -} - -#define make_metaclass(mrb, c) prepare_singleton_class((mrb), (struct RBasic*)(c)) - -static void -prepare_singleton_class(mrb_state *mrb, struct RBasic *o) -{ - struct RClass *sc, *c; - - if (o->c->tt == MRB_TT_SCLASS) return; - sc = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_SCLASS, mrb->class_class); - sc->flags |= MRB_FLAG_IS_INHERITED; - sc->mt = kh_init(mt, mrb); - sc->iv = 0; - if (o->tt == MRB_TT_CLASS) { - c = (struct RClass*)o; - if (!c->super) { - sc->super = mrb->class_class; - } - else { - sc->super = c->super->c; - } - } - else if (o->tt == MRB_TT_SCLASS) { - c = (struct RClass*)o; - while (c->super->tt == MRB_TT_ICLASS) - c = c->super; - make_metaclass(mrb, c->super); - sc->super = c->super->c; - } - else { - sc->super = o->c; - prepare_singleton_class(mrb, (struct RBasic*)sc); - } - o->c = sc; - mrb_field_write_barrier(mrb, (struct RBasic*)o, (struct RBasic*)sc); - mrb_field_write_barrier(mrb, (struct RBasic*)sc, (struct RBasic*)o); - mrb_obj_iv_set(mrb, (struct RObject*)sc, mrb_intern_lit(mrb, "__attached__"), mrb_obj_value(o)); -} - -static struct RClass* -class_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) -{ - mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id); - - mrb_check_type(mrb, c, MRB_TT_CLASS); - return mrb_class_ptr(c); -} - -static struct RClass* -module_from_sym(mrb_state *mrb, struct RClass *klass, mrb_sym id) -{ - mrb_value c = mrb_const_get(mrb, mrb_obj_value(klass), id); - - mrb_check_type(mrb, c, MRB_TT_MODULE); - return mrb_class_ptr(c); -} - -static mrb_bool -class_ptr_p(mrb_value obj) -{ - switch (mrb_type(obj)) { - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - case MRB_TT_MODULE: - return TRUE; - default: - return FALSE; - } -} - -static void -check_if_class_or_module(mrb_state *mrb, mrb_value obj) -{ - if (!class_ptr_p(obj)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class/module", mrb_inspect(mrb, obj)); - } -} - -static struct RClass* -define_module(mrb_state *mrb, mrb_sym name, struct RClass *outer) -{ - struct RClass *m; - - if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { - return module_from_sym(mrb, outer, name); - } - m = mrb_module_new(mrb); - setup_class(mrb, outer, m, name); - - return m; -} - -MRB_API struct RClass* -mrb_define_module_id(mrb_state *mrb, mrb_sym name) -{ - return define_module(mrb, name, mrb->object_class); -} - -MRB_API struct RClass* -mrb_define_module(mrb_state *mrb, const char *name) -{ - return define_module(mrb, mrb_intern_cstr(mrb, name), mrb->object_class); -} - -MRB_API struct RClass* -mrb_vm_define_module(mrb_state *mrb, mrb_value outer, mrb_sym id) -{ - check_if_class_or_module(mrb, outer); - if (mrb_const_defined_at(mrb, outer, id)) { - mrb_value old = mrb_const_get(mrb, outer, id); - - if (mrb_type(old) != MRB_TT_MODULE) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a module", mrb_inspect(mrb, old)); - } - return mrb_class_ptr(old); - } - return define_module(mrb, id, mrb_class_ptr(outer)); -} - -MRB_API struct RClass* -mrb_define_module_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - mrb_sym id = mrb_intern_cstr(mrb, name); - struct RClass * c = define_module(mrb, id, outer); - - setup_class(mrb, outer, c, id); - return c; -} - -static struct RClass* -find_origin(struct RClass *c) -{ - MRB_CLASS_ORIGIN(c); - return c; -} - -static struct RClass* -define_class(mrb_state *mrb, mrb_sym name, struct RClass *super, struct RClass *outer) -{ - struct RClass * c; - - if (mrb_const_defined_at(mrb, mrb_obj_value(outer), name)) { - c = class_from_sym(mrb, outer, name); - MRB_CLASS_ORIGIN(c); - if (super && mrb_class_real(c->super) != super) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for Class %S (%S not %S)", - mrb_sym2str(mrb, name), - mrb_obj_value(c->super), mrb_obj_value(super)); - } - return c; - } - - c = mrb_class_new(mrb, super); - setup_class(mrb, outer, c, name); - - return c; -} - -MRB_API struct RClass* -mrb_define_class_id(mrb_state *mrb, mrb_sym name, struct RClass *super) -{ - if (!super) { - mrb_warn(mrb, "no super class for '%S', Object assumed", mrb_sym2str(mrb, name)); - } - return define_class(mrb, name, super, mrb->object_class); -} - -MRB_API struct RClass* -mrb_define_class(mrb_state *mrb, const char *name, struct RClass *super) -{ - return mrb_define_class_id(mrb, mrb_intern_cstr(mrb, name), super); -} - -static mrb_value mrb_bob_init(mrb_state *mrb, mrb_value); -#ifdef MRB_METHOD_CACHE -static void mc_clear_all(mrb_state *mrb); -static void mc_clear_by_class(mrb_state *mrb, struct RClass*); -static void mc_clear_by_id(mrb_state *mrb, struct RClass*, mrb_sym); -#else -#define mc_clear_all(mrb) -#define mc_clear_by_class(mrb,c) -#define mc_clear_by_id(mrb,c,s) -#endif - -static void -mrb_class_inherited(mrb_state *mrb, struct RClass *super, struct RClass *klass) -{ - mrb_value s; - mrb_sym mid; - - if (!super) - super = mrb->object_class; - super->flags |= MRB_FLAG_IS_INHERITED; - s = mrb_obj_value(super); - mc_clear_by_class(mrb, klass); - mid = mrb_intern_lit(mrb, "inherited"); - if (!mrb_func_basic_p(mrb, s, mid, mrb_bob_init)) { - mrb_value c = mrb_obj_value(klass); - mrb_funcall_argv(mrb, s, mid, 1, &c); - } -} - -MRB_API struct RClass* -mrb_vm_define_class(mrb_state *mrb, mrb_value outer, mrb_value super, mrb_sym id) -{ - struct RClass *s; - struct RClass *c; - - if (!mrb_nil_p(super)) { - if (mrb_type(super) != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", - mrb_inspect(mrb, super)); - } - s = mrb_class_ptr(super); - } - else { - s = 0; - } - check_if_class_or_module(mrb, outer); - if (mrb_const_defined_at(mrb, outer, id)) { - mrb_value old = mrb_const_get(mrb, outer, id); - - if (mrb_type(old) != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a class", mrb_inspect(mrb, old)); - } - c = mrb_class_ptr(old); - if (s) { - /* check super class */ - if (mrb_class_real(c->super) != s) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass mismatch for class %S", old); - } - } - return c; - } - c = define_class(mrb, id, s, mrb_class_ptr(outer)); - mrb_class_inherited(mrb, mrb_class_real(c->super), c); - - return c; -} - -MRB_API mrb_bool -mrb_class_defined(mrb_state *mrb, const char *name) -{ - mrb_value sym = mrb_check_intern_cstr(mrb, name); - if (mrb_nil_p(sym)) { - return FALSE; - } - return mrb_const_defined(mrb, mrb_obj_value(mrb->object_class), mrb_symbol(sym)); -} - -MRB_API mrb_bool -mrb_class_defined_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - mrb_value sym = mrb_check_intern_cstr(mrb, name); - if (mrb_nil_p(sym)) { - return FALSE; - } - return mrb_const_defined_at(mrb, mrb_obj_value(outer), mrb_symbol(sym)); -} - -MRB_API struct RClass* -mrb_class_get_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - return class_from_sym(mrb, outer, mrb_intern_cstr(mrb, name)); -} - -MRB_API struct RClass* -mrb_class_get(mrb_state *mrb, const char *name) -{ - return mrb_class_get_under(mrb, mrb->object_class, name); -} - -MRB_API struct RClass* -mrb_exc_get(mrb_state *mrb, const char *name) -{ - struct RClass *exc, *e; - mrb_value c = mrb_const_get(mrb, mrb_obj_value(mrb->object_class), - mrb_intern_cstr(mrb, name)); - - if (mrb_type(c) != MRB_TT_CLASS) { - mrb_raise(mrb, mrb->eException_class, "exception corrupted"); - } - exc = e = mrb_class_ptr(c); - - while (e) { - if (e == mrb->eException_class) - return exc; - e = e->super; - } - return mrb->eException_class; -} - -MRB_API struct RClass* -mrb_module_get_under(mrb_state *mrb, struct RClass *outer, const char *name) -{ - return module_from_sym(mrb, outer, mrb_intern_cstr(mrb, name)); -} - -MRB_API struct RClass* -mrb_module_get(mrb_state *mrb, const char *name) -{ - return mrb_module_get_under(mrb, mrb->object_class, name); -} - -/*! - * Defines a class under the namespace of \a outer. - * \param outer a class which contains the new class. - * \param id name of the new class - * \param super a class from which the new class will derive. - * NULL means \c Object class. - * \return the created class - * \throw TypeError if the constant name \a name is already taken but - * the constant is not a \c Class. - * \throw NameError if the class is already defined but the class can not - * be reopened because its superclass is not \a super. - * \post top-level constant named \a name refers the returned class. - * - * \note if a class named \a name is already defined and its superclass is - * \a super, the function just returns the defined class. - */ -MRB_API struct RClass* -mrb_define_class_under(mrb_state *mrb, struct RClass *outer, const char *name, struct RClass *super) -{ - mrb_sym id = mrb_intern_cstr(mrb, name); - struct RClass * c; - -#if 0 - if (!super) { - mrb_warn(mrb, "no super class for '%S::%S', Object assumed", - mrb_obj_value(outer), mrb_sym2str(mrb, id)); - } -#endif - c = define_class(mrb, id, super, outer); - setup_class(mrb, outer, c, id); - return c; -} - -MRB_API void -mrb_define_method_raw(mrb_state *mrb, struct RClass *c, mrb_sym mid, struct RProc *p) -{ - khash_t(mt) *h; - khiter_t k; - MRB_CLASS_ORIGIN(c); - h = c->mt; - - if (MRB_FROZEN_P(c)) { - if (c->tt == MRB_TT_MODULE) - mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen module"); - else - mrb_raise(mrb, E_RUNTIME_ERROR, "can't modify frozen class"); - } - if (!h) h = c->mt = kh_init(mt, mrb); - k = kh_put(mt, mrb, h, mid); - kh_value(h, k) = p; - if (p) { - p->c = NULL; - mrb_field_write_barrier(mrb, (struct RBasic *)c, (struct RBasic *)p); - } - mc_clear_by_id(mrb, c, mid); -} - -MRB_API void -mrb_define_method_id(mrb_state *mrb, struct RClass *c, mrb_sym mid, mrb_func_t func, mrb_aspec aspec) -{ - struct RProc *p; - int ai = mrb_gc_arena_save(mrb); - - p = mrb_proc_new_cfunc(mrb, func); - p->target_class = c; - mrb_define_method_raw(mrb, c, mid, p); - mrb_gc_arena_restore(mrb, ai); -} - -MRB_API void -mrb_define_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - mrb_define_method_id(mrb, c, mrb_intern_cstr(mrb, name), func, aspec); -} - -/* a function to raise NotImplementedError with current method name */ -MRB_API void -mrb_notimplement(mrb_state *mrb) -{ - const char *str; - mrb_int len; - mrb_callinfo *ci = mrb->c->ci; - - if (ci->mid) { - str = mrb_sym2name_len(mrb, ci->mid, &len); - mrb_raisef(mrb, E_NOTIMP_ERROR, - "%S() function is unimplemented on this machine", - mrb_str_new_static(mrb, str, (size_t)len)); - } -} - -/* a function to be replacement of unimplemented method */ -MRB_API mrb_value -mrb_notimplement_m(mrb_state *mrb, mrb_value self) -{ - mrb_notimplement(mrb); - /* not reached */ - return mrb_nil_value(); -} - -static mrb_value -check_type(mrb_state *mrb, mrb_value val, enum mrb_vtype t, const char *c, const char *m) -{ - mrb_value tmp; - - tmp = mrb_check_convert_type(mrb, val, t, c, m); - if (mrb_nil_p(tmp)) { - mrb_raisef(mrb, E_TYPE_ERROR, "expected %S", mrb_str_new_cstr(mrb, c)); - } - return tmp; -} - -static mrb_value -to_str(mrb_state *mrb, mrb_value val) -{ - return check_type(mrb, val, MRB_TT_STRING, "String", "to_str"); -} - -static mrb_value -to_ary(mrb_state *mrb, mrb_value val) -{ - return check_type(mrb, val, MRB_TT_ARRAY, "Array", "to_ary"); -} - -static mrb_value -to_hash(mrb_state *mrb, mrb_value val) -{ - return check_type(mrb, val, MRB_TT_HASH, "Hash", "to_hash"); -} - -static mrb_sym -to_sym(mrb_state *mrb, mrb_value ss) -{ - if (mrb_type(ss) == MRB_TT_SYMBOL) { - return mrb_symbol(ss); - } - else if (mrb_string_p(ss)) { - return mrb_intern_str(mrb, to_str(mrb, ss)); - } - else { - mrb_value obj = mrb_funcall(mrb, ss, "inspect", 0); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", obj); - /* not reached */ - return 0; - } -} - -/* - retrieve arguments from mrb_state. - - mrb_get_args(mrb, format, ...) - - returns number of arguments parsed. - - format specifiers: - - string mruby type C type note - ---------------------------------------------------------------------------------------------- - o: Object [mrb_value] - C: class/module [mrb_value] - S: String [mrb_value] when ! follows, the value may be nil - A: Array [mrb_value] when ! follows, the value may be nil - H: Hash [mrb_value] when ! follows, the value may be nil - s: String [char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil - z: String [char*] NUL terminated string; z! gives NULL for nil - a: Array [mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil - f: Float [mrb_float] - i: Integer [mrb_int] - b: Boolean [mrb_bool] - n: Symbol [mrb_sym] - d: Data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified - I: Inline struct [void*] - &: Block [mrb_value] - *: rest argument [mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack - |: optional Following arguments are optional - ?: optional given [mrb_bool] true if preceding argument (optional) is given - */ -MRB_API mrb_int -mrb_get_args(mrb_state *mrb, const char *format, ...) -{ - const char *fmt = format; - char c; - int i = 0; - va_list ap; - int argc = mrb->c->ci->argc; - int arg_i = 0; - mrb_value *array_argv; - mrb_bool opt = FALSE; - mrb_bool opt_skip = TRUE; - mrb_bool given = TRUE; - - va_start(ap, format); - if (argc < 0) { - struct RArray *a = mrb_ary_ptr(mrb->c->stack[1]); - - argc = ARY_LEN(a); - array_argv = ARY_PTR(a); - } - else { - array_argv = NULL; - } - -#define ARGV \ - (array_argv ? array_argv : (mrb->c->stack + 1)) - - while ((c = *fmt++)) { - switch (c) { - case '|': - opt = TRUE; - break; - case '*': - opt_skip = FALSE; - goto check_exit; - case '!': - break; - case '&': case '?': - if (opt) opt_skip = FALSE; - break; - default: - break; - } - } - - check_exit: - opt = FALSE; - i = 0; - while ((c = *format++)) { - switch (c) { - case '|': case '*': case '&': case '?': - break; - default: - if (argc <= i) { - if (opt) { - given = FALSE; - } - else { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); - } - } - break; - } - - switch (c) { - case 'o': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - *p = ARGV[arg_i++]; - i++; - } - } - break; - case 'C': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (i < argc) { - mrb_value ss; - - ss = ARGV[arg_i++]; - if (!class_ptr_p(ss)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss); - } - *p = ss; - i++; - } - } - break; - case 'S': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *p = ARGV[arg_i++]; - i++; - break; - } - } - if (i < argc) { - *p = to_str(mrb, ARGV[arg_i++]); - i++; - } - } - break; - case 'A': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *p = ARGV[arg_i++]; - i++; - break; - } - } - if (i < argc) { - *p = to_ary(mrb, ARGV[arg_i++]); - i++; - } - } - break; - case 'H': - { - mrb_value *p; - - p = va_arg(ap, mrb_value*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *p = ARGV[arg_i++]; - i++; - break; - } - } - if (i < argc) { - *p = to_hash(mrb, ARGV[arg_i++]); - i++; - } - } - break; - case 's': - { - mrb_value ss; - char **ps = 0; - mrb_int *pl = 0; - - ps = va_arg(ap, char**); - pl = va_arg(ap, mrb_int*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *ps = NULL; - *pl = 0; - i++; arg_i++; - break; - } - } - if (i < argc) { - ss = to_str(mrb, ARGV[arg_i++]); - *ps = RSTRING_PTR(ss); - *pl = RSTRING_LEN(ss); - i++; - } - } - break; - case 'z': - { - mrb_value ss; - const char **ps; - - ps = va_arg(ap, const char**); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *ps = NULL; - i++; arg_i++; - break; - } - } - if (i < argc) { - ss = to_str(mrb, ARGV[arg_i++]); - *ps = mrb_string_value_cstr(mrb, &ss); - i++; - } - } - break; - case 'a': - { - mrb_value aa; - struct RArray *a; - mrb_value **pb; - mrb_int *pl; - - pb = va_arg(ap, mrb_value**); - pl = va_arg(ap, mrb_int*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *pb = 0; - *pl = 0; - i++; arg_i++; - break; - } - } - if (i < argc) { - aa = to_ary(mrb, ARGV[arg_i++]); - a = mrb_ary_ptr(aa); - *pb = ARY_PTR(a); - *pl = ARY_LEN(a); - i++; - } - } - break; - case 'I': - { - void* *p; - mrb_value ss; - - p = va_arg(ap, void**); - if (i < argc) { - ss = ARGV[arg_i]; - if (mrb_type(ss) != MRB_TT_ISTRUCT) - { - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not inline struct", ss); - } - *p = mrb_istruct_ptr(ss); - arg_i++; - i++; - } - } - break; - case 'f': - { - mrb_float *p; - - p = va_arg(ap, mrb_float*); - if (i < argc) { - *p = mrb_to_flo(mrb, ARGV[arg_i]); - arg_i++; - i++; - } - } - break; - case 'i': - { - mrb_int *p; - - p = va_arg(ap, mrb_int*); - if (i < argc) { - switch (mrb_type(ARGV[arg_i])) { - case MRB_TT_FIXNUM: - *p = mrb_fixnum(ARGV[arg_i]); - break; - case MRB_TT_FLOAT: - { - mrb_float f = mrb_float(ARGV[arg_i]); - - if (!FIXABLE_FLOAT(f)) { - mrb_raise(mrb, E_RANGE_ERROR, "float too big for int"); - } - *p = (mrb_int)f; - } - break; - case MRB_TT_STRING: - mrb_raise(mrb, E_TYPE_ERROR, "no implicit conversion of String into Integer"); - break; - default: - *p = mrb_fixnum(mrb_Integer(mrb, ARGV[arg_i])); - break; - } - arg_i++; - i++; - } - } - break; - case 'b': - { - mrb_bool *boolp = va_arg(ap, mrb_bool*); - - if (i < argc) { - mrb_value b = ARGV[arg_i++]; - *boolp = mrb_test(b); - i++; - } - } - break; - case 'n': - { - mrb_sym *symp; - - symp = va_arg(ap, mrb_sym*); - if (i < argc) { - mrb_value ss; - - ss = ARGV[arg_i++]; - *symp = to_sym(mrb, ss); - i++; - } - } - break; - case 'd': - { - void** datap; - struct mrb_data_type const* type; - - datap = va_arg(ap, void**); - type = va_arg(ap, struct mrb_data_type const*); - if (*format == '!') { - format++; - if (i < argc && mrb_nil_p(ARGV[arg_i])) { - *datap = 0; - i++; arg_i++; - break; - } - } - if (i < argc) { - *datap = mrb_data_get_ptr(mrb, ARGV[arg_i++], type); - ++i; - } - } - break; - - case '&': - { - mrb_value *p, *bp; - - p = va_arg(ap, mrb_value*); - if (mrb->c->ci->argc < 0) { - bp = mrb->c->stack + 2; - } - else { - bp = mrb->c->stack + mrb->c->ci->argc + 1; - } - *p = *bp; - } - break; - case '|': - if (opt_skip && i == argc) return argc; - opt = TRUE; - break; - case '?': - { - mrb_bool *p; - - p = va_arg(ap, mrb_bool*); - *p = given; - } - break; - - case '*': - { - mrb_value **var; - mrb_int *pl; - mrb_bool nocopy = array_argv ? TRUE : FALSE; - - if (*format == '!') { - format++; - nocopy = TRUE; - } - var = va_arg(ap, mrb_value**); - pl = va_arg(ap, mrb_int*); - if (argc > i) { - *pl = argc-i; - if (*pl > 0) { - if (nocopy) { - *var = ARGV+arg_i; - } - else { - mrb_value args = mrb_ary_new_from_values(mrb, *pl, ARGV+arg_i); - RARRAY(args)->c = NULL; - *var = RARRAY_PTR(args); - } - } - i = argc; - arg_i += *pl; - } - else { - *pl = 0; - *var = NULL; - } - } - break; - default: - mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %S", mrb_str_new(mrb, &c, 1)); - break; - } - } - -#undef ARGV - - if (!c && argc > i) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments"); - } - va_end(ap); - return i; -} - -static struct RClass* -boot_defclass(mrb_state *mrb, struct RClass *super) -{ - struct RClass *c; - - c = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_CLASS, mrb->class_class); - if (super) { - c->super = super; - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)super); - } - else { - c->super = mrb->object_class; - } - c->mt = kh_init(mt, mrb); - return c; -} - -static void -boot_initmod(mrb_state *mrb, struct RClass *mod) -{ - if (!mod->mt) { - mod->mt = kh_init(mt, mrb); - } -} - -static struct RClass* -include_class_new(mrb_state *mrb, struct RClass *m, struct RClass *super) -{ - struct RClass *ic = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, mrb->class_class); - if (m->tt == MRB_TT_ICLASS) { - m = m->c; - } - MRB_CLASS_ORIGIN(m); - ic->iv = m->iv; - ic->mt = m->mt; - ic->super = super; - if (m->tt == MRB_TT_ICLASS) { - ic->c = m->c; - } - else { - ic->c = m; - } - return ic; -} - -static int -include_module_at(mrb_state *mrb, struct RClass *c, struct RClass *ins_pos, struct RClass *m, int search_super) -{ - struct RClass *p, *ic; - void *klass_mt = find_origin(c)->mt; - - while (m) { - int superclass_seen = 0; - - if (m->flags & MRB_FLAG_IS_PREPENDED) - goto skip; - - if (klass_mt && klass_mt == m->mt) - return -1; - - p = c->super; - while (p) { - if (p->tt == MRB_TT_ICLASS) { - if (p->mt == m->mt) { - if (!superclass_seen) { - ins_pos = p; /* move insert point */ - } - goto skip; - } - } else if (p->tt == MRB_TT_CLASS) { - if (!search_super) break; - superclass_seen = 1; - } - p = p->super; - } - - ic = include_class_new(mrb, m, ins_pos->super); - m->flags |= MRB_FLAG_IS_INHERITED; - ins_pos->super = ic; - mrb_field_write_barrier(mrb, (struct RBasic*)ins_pos, (struct RBasic*)ic); - mc_clear_by_class(mrb, ins_pos); - ins_pos = ic; - skip: - m = m->super; - } - mc_clear_all(mrb); - return 0; -} - -MRB_API void -mrb_include_module(mrb_state *mrb, struct RClass *c, struct RClass *m) -{ - int changed = include_module_at(mrb, c, find_origin(c), m, 1); - if (changed < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic include detected"); - } -} - -MRB_API void -mrb_prepend_module(mrb_state *mrb, struct RClass *c, struct RClass *m) -{ - struct RClass *origin; - int changed = 0; - - if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { - origin = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_ICLASS, c); - origin->flags |= MRB_FLAG_IS_ORIGIN | MRB_FLAG_IS_INHERITED; - origin->super = c->super; - c->super = origin; - origin->mt = c->mt; - c->mt = kh_init(mt, mrb); - mrb_field_write_barrier(mrb, (struct RBasic*)c, (struct RBasic*)origin); - c->flags |= MRB_FLAG_IS_PREPENDED; - } - changed = include_module_at(mrb, c, c, m, 0); - if (changed < 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "cyclic prepend detected"); - } -} - -static mrb_value -mrb_mod_prepend_features(mrb_state *mrb, mrb_value mod) -{ - mrb_value klass; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "C", &klass); - mrb_prepend_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); - return mod; -} - -static mrb_value -mrb_mod_append_features(mrb_state *mrb, mrb_value mod) -{ - mrb_value klass; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "C", &klass); - mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); - return mod; -} - -/* 15.2.2.4.28 */ -/* - * call-seq: - * mod.include?(module) -> true or false - * - * Returns <code>true</code> if <i>module</i> is included in - * <i>mod</i> or one of <i>mod</i>'s ancestors. - * - * module A - * end - * class B - * include A - * end - * class C < B - * end - * B.include?(A) #=> true - * C.include?(A) #=> true - * A.include?(A) #=> false - */ -static mrb_value -mrb_mod_include_p(mrb_state *mrb, mrb_value mod) -{ - mrb_value mod2; - struct RClass *c = mrb_class_ptr(mod); - - mrb_get_args(mrb, "C", &mod2); - mrb_check_type(mrb, mod2, MRB_TT_MODULE); - - while (c) { - if (c->tt == MRB_TT_ICLASS) { - if (c->c == mrb_class_ptr(mod2)) return mrb_true_value(); - } - c = c->super; - } - return mrb_false_value(); -} - -static mrb_value -mrb_mod_ancestors(mrb_state *mrb, mrb_value self) -{ - mrb_value result; - struct RClass *c = mrb_class_ptr(self); - result = mrb_ary_new(mrb); - while (c) { - if (c->tt == MRB_TT_ICLASS) { - mrb_ary_push(mrb, result, mrb_obj_value(c->c)); - } - else if (!(c->flags & MRB_FLAG_IS_PREPENDED)) { - mrb_ary_push(mrb, result, mrb_obj_value(c)); - } - c = c->super; - } - - return result; -} - -static mrb_value -mrb_mod_extend_object(mrb_state *mrb, mrb_value mod) -{ - mrb_value obj; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "o", &obj); - mrb_include_module(mrb, mrb_class_ptr(mrb_singleton_class(mrb, obj)), mrb_class_ptr(mod)); - return mod; -} - -static mrb_value -mrb_mod_included_modules(mrb_state *mrb, mrb_value self) -{ - mrb_value result; - struct RClass *c = mrb_class_ptr(self); - struct RClass *origin = c; - - MRB_CLASS_ORIGIN(origin); - result = mrb_ary_new(mrb); - while (c) { - if (c != origin && c->tt == MRB_TT_ICLASS) { - if (c->c->tt == MRB_TT_MODULE) { - mrb_ary_push(mrb, result, mrb_obj_value(c->c)); - } - } - c = c->super; - } - - return result; -} - -static mrb_value -mrb_mod_initialize(mrb_state *mrb, mrb_value mod) -{ - mrb_value b; - struct RClass *m = mrb_class_ptr(mod); - boot_initmod(mrb, m); /* bootstrap a newly initialized module */ - mrb_get_args(mrb, "|&", &b); - if (!mrb_nil_p(b)) { - mrb_yield_with_class(mrb, b, 1, &mod, mod, m); - } - return mod; -} - -mrb_value mrb_class_instance_method_list(mrb_state*, mrb_bool, struct RClass*, int); - -/* 15.2.2.4.33 */ -/* - * call-seq: - * mod.instance_methods(include_super=true) -> array - * - * Returns an array containing the names of the public and protected instance - * methods in the receiver. For a module, these are the public and protected methods; - * for a class, they are the instance (not singleton) methods. With no - * argument, or with an argument that is <code>false</code>, the - * instance methods in <i>mod</i> are returned, otherwise the methods - * in <i>mod</i> and <i>mod</i>'s superclasses are returned. - * - * module A - * def method1() end - * end - * class B - * def method2() end - * end - * class C < B - * def method3() end - * end - * - * A.instance_methods #=> [:method1] - * B.instance_methods(false) #=> [:method2] - * C.instance_methods(false) #=> [:method3] - * C.instance_methods(true).length #=> 43 - */ - -static mrb_value -mrb_mod_instance_methods(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_class_instance_method_list(mrb, recur, c, 0); -} - -/* implementation of module_eval/class_eval */ -mrb_value mrb_mod_module_eval(mrb_state*, mrb_value); - -static mrb_value -mrb_mod_dummy_visibility(mrb_state *mrb, mrb_value mod) -{ - return mod; -} - -MRB_API mrb_value -mrb_singleton_class(mrb_state *mrb, mrb_value v) -{ - struct RBasic *obj; - - switch (mrb_type(v)) { - case MRB_TT_FALSE: - if (mrb_nil_p(v)) - return mrb_obj_value(mrb->nil_class); - return mrb_obj_value(mrb->false_class); - case MRB_TT_TRUE: - return mrb_obj_value(mrb->true_class); - case MRB_TT_CPTR: - return mrb_obj_value(mrb->object_class); - case MRB_TT_SYMBOL: - case MRB_TT_FIXNUM: - case MRB_TT_FLOAT: - mrb_raise(mrb, E_TYPE_ERROR, "can't define singleton"); - return mrb_nil_value(); /* not reached */ - default: - break; - } - obj = mrb_basic_ptr(v); - prepare_singleton_class(mrb, obj); - return mrb_obj_value(obj->c); -} - -MRB_API void -mrb_define_singleton_method(mrb_state *mrb, struct RObject *o, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - prepare_singleton_class(mrb, (struct RBasic*)o); - mrb_define_method_id(mrb, o->c, mrb_intern_cstr(mrb, name), func, aspec); -} - -MRB_API void -mrb_define_class_method(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - mrb_define_singleton_method(mrb, (struct RObject*)c, name, func, aspec); -} - -MRB_API void -mrb_define_module_function(mrb_state *mrb, struct RClass *c, const char *name, mrb_func_t func, mrb_aspec aspec) -{ - mrb_define_class_method(mrb, c, name, func, aspec); - mrb_define_method(mrb, c, name, func, aspec); -} - -#ifdef MRB_METHOD_CACHE -static void -mc_clear_all(mrb_state *mrb) -{ - struct mrb_cache_entry *mc = mrb->cache; - int i; - - for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { - mc[i].c = 0; - } -} - -static void -mc_clear_by_class(mrb_state *mrb, struct RClass *c) -{ - struct mrb_cache_entry *mc = mrb->cache; - int i; - - if (c->flags & MRB_FLAG_IS_INHERITED) { - mc_clear_all(mrb); - c->flags &= ~MRB_FLAG_IS_INHERITED; - return; - } - for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { - if (mc[i].c == c) mc[i].c = 0; - } -} - -static void -mc_clear_by_id(mrb_state *mrb, struct RClass *c, mrb_sym mid) -{ - struct mrb_cache_entry *mc = mrb->cache; - int i; - - if (c->flags & MRB_FLAG_IS_INHERITED) { - mc_clear_all(mrb); - c->flags &= ~MRB_FLAG_IS_INHERITED; - return; - } - for (i=0; i<MRB_METHOD_CACHE_SIZE; i++) { - if (mc[i].c == c || mc[i].mid == mid) - mc[i].c = 0; - } -} -#endif - -MRB_API struct RProc* -mrb_method_search_vm(mrb_state *mrb, struct RClass **cp, mrb_sym mid) -{ - khiter_t k; - struct RProc *m; - struct RClass *c = *cp; -#ifdef MRB_METHOD_CACHE - struct RClass *oc = c; - int h = kh_int_hash_func(mrb, ((intptr_t)oc) ^ mid) & (MRB_METHOD_CACHE_SIZE-1); - struct mrb_cache_entry *mc = &mrb->cache[h]; - - if (mc->c == c && mc->mid == mid) { - return mc->m; - } -#endif - - while (c) { - khash_t(mt) *h = c->mt; - - if (h) { - k = kh_get(mt, mrb, h, mid); - if (k != kh_end(h)) { - m = kh_value(h, k); - if (!m) break; - *cp = c; -#ifdef MRB_METHOD_CACHE - mc->c = oc; - mc->mid = mid; - mc->m = m; -#endif - return m; - } - } - c = c->super; - } - return NULL; /* no method */ -} - -MRB_API struct RProc* -mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid) -{ - struct RProc *m; - - m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { - mrb_value inspect = mrb_funcall(mrb, mrb_obj_value(c), "inspect", 0); - if (mrb_string_p(inspect) && RSTRING_LEN(inspect) > 64) { - inspect = mrb_any_to_s(mrb, mrb_obj_value(c)); - } - mrb_name_error(mrb, mid, "undefined method '%S' for class %S", - mrb_sym2str(mrb, mid), inspect); - } - return m; -} - -static mrb_value -attr_reader(mrb_state *mrb, mrb_value obj) -{ - mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); - return mrb_iv_get(mrb, obj, to_sym(mrb, name)); -} - -static mrb_value -mrb_mod_attr_reader(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_value *argv; - mrb_int argc, i; - int ai; - - mrb_get_args(mrb, "*", &argv, &argc); - ai = mrb_gc_arena_save(mrb); - for (i=0; i<argc; i++) { - mrb_value name, str; - mrb_sym method, sym; - - method = to_sym(mrb, argv[i]); - name = mrb_sym2str(mrb, method); - str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1); - mrb_str_cat_lit(mrb, str, "@"); - mrb_str_cat_str(mrb, str, name); - sym = mrb_intern_str(mrb, str); - mrb_iv_check(mrb, sym); - name = mrb_symbol_value(sym); - mrb_define_method_raw(mrb, c, method, - mrb_proc_new_cfunc_with_env(mrb, attr_reader, 1, &name)); - mrb_gc_arena_restore(mrb, ai); - } - return mrb_nil_value(); -} - -static mrb_value -attr_writer(mrb_state *mrb, mrb_value obj) -{ - mrb_value name = mrb_proc_cfunc_env_get(mrb, 0); - mrb_value val; - - mrb_get_args(mrb, "o", &val); - mrb_iv_set(mrb, obj, to_sym(mrb, name), val); - return val; -} - -static mrb_value -mrb_mod_attr_writer(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_value *argv; - mrb_int argc, i; - int ai; - - mrb_get_args(mrb, "*", &argv, &argc); - ai = mrb_gc_arena_save(mrb); - for (i=0; i<argc; i++) { - mrb_value name, str, attr; - mrb_sym method, sym; - - method = to_sym(mrb, argv[i]); - - /* prepare iv name (@name) */ - name = mrb_sym2str(mrb, method); - str = mrb_str_new_capa(mrb, RSTRING_LEN(name)+1); - mrb_str_cat_lit(mrb, str, "@"); - mrb_str_cat_str(mrb, str, name); - sym = mrb_intern_str(mrb, str); - mrb_iv_check(mrb, sym); - attr = mrb_symbol_value(sym); - - /* prepare method name (name=) */ - str = mrb_str_new_capa(mrb, RSTRING_LEN(str)); - mrb_str_cat_str(mrb, str, name); - mrb_str_cat_lit(mrb, str, "="); - method = mrb_intern_str(mrb, str); - - mrb_define_method_raw(mrb, c, method, - mrb_proc_new_cfunc_with_env(mrb, attr_writer, 1, &attr)); - mrb_gc_arena_restore(mrb, ai); - } - return mrb_nil_value(); -} - -static mrb_value -mrb_instance_alloc(mrb_state *mrb, mrb_value cv) -{ - struct RClass *c = mrb_class_ptr(cv); - struct RObject *o; - enum mrb_vtype ttype = MRB_INSTANCE_TT(c); - - if (c->tt == MRB_TT_SCLASS) - mrb_raise(mrb, E_TYPE_ERROR, "can't create instance of singleton class"); - - if (ttype == 0) ttype = MRB_TT_OBJECT; - if (ttype <= MRB_TT_CPTR) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't create instance of %S", cv); - } - o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c); - return mrb_obj_value(o); -} - -/* - * call-seq: - * class.new(args, ...) -> obj - * - * Creates a new object of <i>class</i>'s class, then - * invokes that object's <code>initialize</code> method, - * passing it <i>args</i>. This is the method that ends - * up getting called whenever an object is constructed using - * `.new`. - * - */ - -MRB_API mrb_value -mrb_instance_new(mrb_state *mrb, mrb_value cv) -{ - mrb_value obj, blk; - mrb_value *argv; - mrb_int argc; - mrb_sym init; - - mrb_get_args(mrb, "*&", &argv, &argc, &blk); - obj = mrb_instance_alloc(mrb, cv); - init = mrb_intern_lit(mrb, "initialize"); - if (!mrb_func_basic_p(mrb, obj, init, mrb_bob_init)) { - mrb_funcall_with_block(mrb, obj, init, argc, argv, blk); - } - - return obj; -} - -MRB_API mrb_value -mrb_obj_new(mrb_state *mrb, struct RClass *c, mrb_int argc, const mrb_value *argv) -{ - mrb_value obj; - mrb_sym mid; - - obj = mrb_instance_alloc(mrb, mrb_obj_value(c)); - mid = mrb_intern_lit(mrb, "initialize"); - if (!mrb_func_basic_p(mrb, obj, mid, mrb_bob_init)) { - mrb_funcall_argv(mrb, obj, mid, argc, argv); - } - return obj; -} - -static mrb_value -mrb_class_initialize(mrb_state *mrb, mrb_value c) -{ - mrb_value a, b; - - mrb_get_args(mrb, "|C&", &a, &b); - if (!mrb_nil_p(b)) { - mrb_yield_with_class(mrb, b, 1, &c, c, mrb_class_ptr(c)); - } - return c; -} - -static mrb_value -mrb_class_new_class(mrb_state *mrb, mrb_value cv) -{ - mrb_int n; - mrb_value super, blk; - mrb_value new_class; - mrb_sym mid; - - n = mrb_get_args(mrb, "|C&", &super, &blk); - if (n == 0) { - super = mrb_obj_value(mrb->object_class); - } - new_class = mrb_obj_value(mrb_class_new(mrb, mrb_class_ptr(super))); - mid = mrb_intern_lit(mrb, "initialize"); - if (!mrb_func_basic_p(mrb, new_class, mid, mrb_bob_init)) { - mrb_funcall_with_block(mrb, new_class, mid, n, &super, blk); - } - mrb_class_inherited(mrb, mrb_class_ptr(super), mrb_class_ptr(new_class)); - return new_class; -} - -static mrb_value -mrb_class_superclass(mrb_state *mrb, mrb_value klass) -{ - struct RClass *c; - - c = mrb_class_ptr(klass); - c = find_origin(c)->super; - while (c && c->tt == MRB_TT_ICLASS) { - c = find_origin(c)->super; - } - if (!c) return mrb_nil_value(); - return mrb_obj_value(c); -} - -static mrb_value -mrb_bob_init(mrb_state *mrb, mrb_value cv) -{ - return mrb_nil_value(); -} - -static mrb_value -mrb_bob_not(mrb_state *mrb, mrb_value cv) -{ - return mrb_bool_value(!mrb_test(cv)); -} - -/* 15.3.1.3.1 */ -/* 15.3.1.3.10 */ -/* 15.3.1.3.11 */ -/* - * call-seq: - * obj == other -> true or false - * obj.equal?(other) -> true or false - * obj.eql?(other) -> true or false - * - * Equality---At the <code>Object</code> level, <code>==</code> returns - * <code>true</code> only if <i>obj</i> and <i>other</i> are the - * same object. Typically, this method is overridden in descendant - * classes to provide class-specific meaning. - * - * Unlike <code>==</code>, the <code>equal?</code> method should never be - * overridden by subclasses: it is used to determine object identity - * (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same - * object as <code>b</code>). - * - * The <code>eql?</code> method returns <code>true</code> if - * <i>obj</i> and <i>anObject</i> have the same value. Used by - * <code>Hash</code> to test members for equality. For objects of - * class <code>Object</code>, <code>eql?</code> is synonymous with - * <code>==</code>. Subclasses normally continue this tradition, but - * there are exceptions. <code>Numeric</code> types, for example, - * perform type conversion across <code>==</code>, but not across - * <code>eql?</code>, so: - * - * 1 == 1.0 #=> true - * 1.eql? 1.0 #=> false - */ -mrb_value -mrb_obj_equal_m(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "o", &arg); - return mrb_bool_value(mrb_obj_equal(mrb, self, arg)); -} - -static mrb_value -mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "o", &arg); - return mrb_bool_value(!mrb_equal(mrb, self, arg)); -} - -MRB_API mrb_bool -mrb_obj_respond_to(mrb_state *mrb, struct RClass* c, mrb_sym mid) -{ - struct RProc *m; - - m = mrb_method_search_vm(mrb, &c, mid); - if (!m) { - return FALSE; - } - return TRUE; -} - -MRB_API mrb_bool -mrb_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym mid) -{ - return mrb_obj_respond_to(mrb, mrb_class(mrb, obj), mid); -} - -MRB_API mrb_value -mrb_class_path(mrb_state *mrb, struct RClass *c) -{ - mrb_value path; - mrb_sym nsym = mrb_intern_lit(mrb, "__classname__"); - - path = mrb_obj_iv_get(mrb, (struct RObject*)c, nsym); - if (mrb_nil_p(path)) { - /* no name (yet) */ - return mrb_class_find_path(mrb, c); - } - else if (mrb_symbol_p(path)) { - /* topleve class/module */ - const char *str; - mrb_int len; - - str = mrb_sym2name_len(mrb, mrb_symbol(path), &len); - return mrb_str_new(mrb, str, len); - } - return mrb_str_dup(mrb, path); -} - -MRB_API struct RClass* -mrb_class_real(struct RClass* cl) -{ - if (cl == 0) - return NULL; - while ((cl->tt == MRB_TT_SCLASS) || (cl->tt == MRB_TT_ICLASS)) { - cl = cl->super; - } - return cl; -} - -MRB_API const char* -mrb_class_name(mrb_state *mrb, struct RClass* c) -{ - mrb_value path = mrb_class_path(mrb, c); - if (mrb_nil_p(path)) { - path = mrb_str_new_lit(mrb, "#<Class:"); - mrb_str_concat(mrb, path, mrb_ptr_to_str(mrb, c)); - mrb_str_cat_lit(mrb, path, ">"); - } - return RSTRING_PTR(path); -} - -MRB_API const char* -mrb_obj_classname(mrb_state *mrb, mrb_value obj) -{ - return mrb_class_name(mrb, mrb_obj_class(mrb, obj)); -} - -/*! - * Ensures a class can be derived from super. - * - * \param super a reference to an object. - * \exception TypeError if \a super is not a Class or \a super is a singleton class. - */ -static void -mrb_check_inheritable(mrb_state *mrb, struct RClass *super) -{ - if (super->tt != MRB_TT_CLASS) { - mrb_raisef(mrb, E_TYPE_ERROR, "superclass must be a Class (%S given)", mrb_obj_value(super)); - } - if (super->tt == MRB_TT_SCLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of singleton class"); - } - if (super == mrb->class_class) { - mrb_raise(mrb, E_TYPE_ERROR, "can't make subclass of Class"); - } -} - -/*! - * Creates a new class. - * \param super a class from which the new class derives. - * \exception TypeError \a super is not inheritable. - * \exception TypeError \a super is the Class class. - */ -MRB_API struct RClass* -mrb_class_new(mrb_state *mrb, struct RClass *super) -{ - struct RClass *c; - - if (super) { - mrb_check_inheritable(mrb, super); - } - c = boot_defclass(mrb, super); - if (super) { - MRB_SET_INSTANCE_TT(c, MRB_INSTANCE_TT(super)); - } - make_metaclass(mrb, c); - - return c; -} - -/*! - * Creates a new module. - */ -MRB_API struct RClass* -mrb_module_new(mrb_state *mrb) -{ - struct RClass *m = (struct RClass*)mrb_obj_alloc(mrb, MRB_TT_MODULE, mrb->module_class); - boot_initmod(mrb, m); - return m; -} - -/* - * call-seq: - * obj.class => class - * - * Returns the class of <i>obj</i>, now preferred over - * <code>Object#type</code>, as an object's type in Ruby is only - * loosely tied to that object's class. This method must always be - * called with an explicit receiver, as <code>class</code> is also a - * reserved word in Ruby. - * - * 1.class #=> Fixnum - * self.class #=> Object - */ - -MRB_API struct RClass* -mrb_obj_class(mrb_state *mrb, mrb_value obj) -{ - return mrb_class_real(mrb_class(mrb, obj)); -} - -MRB_API void -mrb_alias_method(mrb_state *mrb, struct RClass *c, mrb_sym a, mrb_sym b) -{ - struct RProc *m = mrb_method_search(mrb, c, b); - - mrb_define_method_raw(mrb, c, a, m); -} - -/*! - * Defines an alias of a method. - * \param klass the class which the original method belongs to - * \param name1 a new name for the method - * \param name2 the original name of the method - */ -MRB_API void -mrb_define_alias(mrb_state *mrb, struct RClass *klass, const char *name1, const char *name2) -{ - mrb_alias_method(mrb, klass, mrb_intern_cstr(mrb, name1), mrb_intern_cstr(mrb, name2)); -} - -/* - * call-seq: - * mod.to_s -> string - * - * Return a string representing this module or class. For basic - * classes and modules, this is the name. For singletons, we - * show information on the thing we're attached to as well. - */ - -static mrb_value -mrb_mod_to_s(mrb_state *mrb, mrb_value klass) -{ - mrb_value str; - - if (mrb_type(klass) == MRB_TT_SCLASS) { - mrb_value v = mrb_iv_get(mrb, klass, mrb_intern_lit(mrb, "__attached__")); - - str = mrb_str_new_lit(mrb, "#<Class:"); - - if (class_ptr_p(v)) { - mrb_str_cat_str(mrb, str, mrb_inspect(mrb, v)); - } - else { - mrb_str_cat_str(mrb, str, mrb_any_to_s(mrb, v)); - } - return mrb_str_cat_lit(mrb, str, ">"); - } - else { - struct RClass *c; - mrb_value path; - - str = mrb_str_new_capa(mrb, 32); - c = mrb_class_ptr(klass); - path = mrb_class_path(mrb, c); - - if (mrb_nil_p(path)) { - switch (mrb_type(klass)) { - case MRB_TT_CLASS: - mrb_str_cat_lit(mrb, str, "#<Class:"); - break; - - case MRB_TT_MODULE: - mrb_str_cat_lit(mrb, str, "#<Module:"); - break; - - default: - /* Shouldn't be happened? */ - mrb_str_cat_lit(mrb, str, "#<??????:"); - break; - } - mrb_str_concat(mrb, str, mrb_ptr_to_str(mrb, c)); - return mrb_str_cat_lit(mrb, str, ">"); - } - else { - return path; - } - } -} - -static mrb_value -mrb_mod_alias(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_sym new_name, old_name; - - mrb_get_args(mrb, "nn", &new_name, &old_name); - mrb_alias_method(mrb, c, new_name, old_name); - return mrb_nil_value(); -} - -static void -undef_method(mrb_state *mrb, struct RClass *c, mrb_sym a) -{ - if (!mrb_obj_respond_to(mrb, c, a)) { - mrb_name_error(mrb, a, "undefined method '%S' for class '%S'", mrb_sym2str(mrb, a), mrb_obj_value(c)); - } - else { - mrb_define_method_raw(mrb, c, a, NULL); - } -} - -MRB_API void -mrb_undef_method(mrb_state *mrb, struct RClass *c, const char *name) -{ - undef_method(mrb, c, mrb_intern_cstr(mrb, name)); -} - -MRB_API void -mrb_undef_class_method(mrb_state *mrb, struct RClass *c, const char *name) -{ - mrb_undef_method(mrb, mrb_class_ptr(mrb_singleton_class(mrb, mrb_obj_value(c))), name); -} - -static mrb_value -mrb_mod_undef(mrb_state *mrb, mrb_value mod) -{ - struct RClass *c = mrb_class_ptr(mod); - mrb_int argc; - mrb_value *argv; - - mrb_get_args(mrb, "*", &argv, &argc); - while (argc--) { - undef_method(mrb, c, to_sym(mrb, *argv)); - argv++; - } - return mrb_nil_value(); -} - -static mrb_value -mod_define_method(mrb_state *mrb, mrb_value self) -{ - struct RClass *c = mrb_class_ptr(self); - struct RProc *p; - mrb_sym mid; - mrb_value proc = mrb_undef_value(); - mrb_value blk; - - mrb_get_args(mrb, "n|o&", &mid, &proc, &blk); - switch (mrb_type(proc)) { - case MRB_TT_PROC: - blk = proc; - break; - case MRB_TT_UNDEF: - /* ignored */ - break; - default: - mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected Proc)", mrb_obj_value(mrb_obj_class(mrb, proc))); - break; - } - if (mrb_nil_p(blk)) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); - } - p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class); - mrb_proc_copy(p, mrb_proc_ptr(blk)); - p->flags |= MRB_PROC_STRICT; - mrb_define_method_raw(mrb, c, mid, p); - return mrb_symbol_value(mid); -} - -static void -check_cv_name_str(mrb_state *mrb, mrb_value str) -{ - const char *s = RSTRING_PTR(str); - mrb_int len = RSTRING_LEN(str); - - if (len < 3 || !(s[0] == '@' && s[1] == '@')) { - mrb_name_error(mrb, mrb_intern_str(mrb, str), "'%S' is not allowed as a class variable name", str); - } -} - -static void -check_cv_name_sym(mrb_state *mrb, mrb_sym id) -{ - check_cv_name_str(mrb, mrb_sym2str(mrb, id)); -} - -/* 15.2.2.4.16 */ -/* - * call-seq: - * obj.class_variable_defined?(symbol) -> true or false - * - * Returns <code>true</code> if the given class variable is defined - * in <i>obj</i>. - * - * class Fred - * @@foo = 99 - * end - * Fred.class_variable_defined?(:@@foo) #=> true - * Fred.class_variable_defined?(:@@bar) #=> false - */ - -static mrb_value -mrb_mod_cvar_defined(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - check_cv_name_sym(mrb, id); - return mrb_bool_value(mrb_cv_defined(mrb, mod, id)); -} - -/* 15.2.2.4.17 */ -/* - * call-seq: - * mod.class_variable_get(symbol) -> obj - * - * Returns the value of the given class variable (or throws a - * <code>NameError</code> exception). The <code>@@</code> part of the - * variable name should be included for regular class variables - * - * class Fred - * @@foo = 99 - * end - * Fred.class_variable_get(:@@foo) #=> 99 - */ - -static mrb_value -mrb_mod_cvar_get(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - check_cv_name_sym(mrb, id); - return mrb_cv_get(mrb, mod, id); -} - -/* 15.2.2.4.18 */ -/* - * call-seq: - * obj.class_variable_set(symbol, obj) -> obj - * - * Sets the class variable names by <i>symbol</i> to - * <i>object</i>. - * - * class Fred - * @@foo = 99 - * def foo - * @@foo - * end - * end - * Fred.class_variable_set(:@@foo, 101) #=> 101 - * Fred.new.foo #=> 101 - */ - -static mrb_value -mrb_mod_cvar_set(mrb_state *mrb, mrb_value mod) -{ - mrb_value value; - mrb_sym id; - - mrb_get_args(mrb, "no", &id, &value); - check_cv_name_sym(mrb, id); - mrb_cv_set(mrb, mod, id, value); - return value; -} - -/* 15.2.2.4.39 */ -/* - * call-seq: - * remove_class_variable(sym) -> obj - * - * Removes the definition of the <i>sym</i>, returning that - * constant's value. - * - * class Dummy - * @@var = 99 - * puts @@var - * p class_variables - * remove_class_variable(:@@var) - * p class_variables - * end - * - * <em>produces:</em> - * - * 99 - * [:@@var] - * [] - */ - -static mrb_value -mrb_mod_remove_cvar(mrb_state *mrb, mrb_value mod) -{ - mrb_value val; - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - check_cv_name_sym(mrb, id); - - val = mrb_iv_remove(mrb, mod, id); - if (!mrb_undef_p(val)) return val; - - if (mrb_cv_defined(mrb, mod, id)) { - mrb_name_error(mrb, id, "cannot remove %S for %S", - mrb_sym2str(mrb, id), mod); - } - - mrb_name_error(mrb, id, "class variable %S not defined for %S", - mrb_sym2str(mrb, id), mod); - - /* not reached */ - return mrb_nil_value(); -} - -/* 15.2.2.4.34 */ -/* - * call-seq: - * mod.method_defined?(symbol) -> true or false - * - * Returns +true+ if the named method is defined by - * _mod_ (or its included modules and, if _mod_ is a class, - * its ancestors). Public and protected methods are matched. - * - * module A - * def method1() end - * end - * class B - * def method2() end - * end - * class C < B - * include A - * def method3() end - * end - * - * A.method_defined? :method1 #=> true - * C.method_defined? "method1" #=> true - * C.method_defined? "method2" #=> true - * C.method_defined? "method3" #=> true - * C.method_defined? "method4" #=> false - */ - -static mrb_value -mrb_mod_method_defined(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - - mrb_get_args(mrb, "n", &id); - return mrb_bool_value(mrb_obj_respond_to(mrb, mrb_class_ptr(mod), id)); -} - -static void -remove_method(mrb_state *mrb, mrb_value mod, mrb_sym mid) -{ - struct RClass *c = mrb_class_ptr(mod); - khash_t(mt) *h = find_origin(c)->mt; - khiter_t k; - - if (h) { - k = kh_get(mt, mrb, h, mid); - if (k != kh_end(h)) { - kh_del(mt, mrb, h, k); - mrb_funcall(mrb, mod, "method_removed", 1, mrb_symbol_value(mid)); - return; - } - } - - mrb_name_error(mrb, mid, "method '%S' not defined in %S", - mrb_sym2str(mrb, mid), mod); -} - -/* 15.2.2.4.41 */ -/* - * call-seq: - * remove_method(symbol) -> self - * - * Removes the method identified by _symbol_ from the current - * class. For an example, see <code>Module.undef_method</code>. - */ - -static mrb_value -mrb_mod_remove_method(mrb_state *mrb, mrb_value mod) -{ - mrb_int argc; - mrb_value *argv; - - mrb_get_args(mrb, "*", &argv, &argc); - while (argc--) { - remove_method(mrb, mod, to_sym(mrb, *argv)); - argv++; - } - return mod; -} - - - -static void -check_const_name_str(mrb_state *mrb, mrb_value str) -{ - if (RSTRING_LEN(str) < 1 || !ISUPPER(*RSTRING_PTR(str))) { - mrb_name_error(mrb, mrb_intern_str(mrb, str), "wrong constant name %S", str); - } -} - -static void -check_const_name_sym(mrb_state *mrb, mrb_sym id) -{ - check_const_name_str(mrb, mrb_sym2str(mrb, id)); -} - -static mrb_value -const_defined(mrb_state *mrb, mrb_value mod, mrb_sym id, mrb_bool inherit) -{ - if (inherit) { - return mrb_bool_value(mrb_const_defined(mrb, mod, id)); - } - return mrb_bool_value(mrb_const_defined_at(mrb, mod, id)); -} - -static mrb_value -mrb_mod_const_defined(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - mrb_bool inherit = TRUE; - - mrb_get_args(mrb, "n|b", &id, &inherit); - check_const_name_sym(mrb, id); - return const_defined(mrb, mod, id, inherit); -} - -static mrb_value -mrb_const_get_sym(mrb_state *mrb, mrb_value mod, mrb_sym id) -{ - check_const_name_sym(mrb, id); - return mrb_const_get(mrb, mod, id); -} - -static mrb_value -mrb_mod_const_get(mrb_state *mrb, mrb_value mod) -{ - mrb_value path; - mrb_sym id; - char *ptr; - mrb_int off, end, len; - - mrb_get_args(mrb, "o", &path); - - if (mrb_symbol_p(path)) { - /* const get with symbol */ - id = mrb_symbol(path); - return mrb_const_get_sym(mrb, mod, id); - } - - /* const get with class path string */ - path = mrb_string_type(mrb, path); - ptr = RSTRING_PTR(path); - len = RSTRING_LEN(path); - off = 0; - - while (off < len) { - end = mrb_str_index_lit(mrb, path, "::", off); - end = (end == -1) ? len : end; - id = mrb_intern(mrb, ptr+off, end-off); - mod = mrb_const_get_sym(mrb, mod, id); - off = (end == len) ? end : end+2; - } - - return mod; -} - -static mrb_value -mrb_mod_const_set(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - mrb_value value; - - mrb_get_args(mrb, "no", &id, &value); - check_const_name_sym(mrb, id); - mrb_const_set(mrb, mod, id, value); - return value; -} - -static mrb_value -mrb_mod_remove_const(mrb_state *mrb, mrb_value mod) -{ - mrb_sym id; - mrb_value val; - - mrb_get_args(mrb, "n", &id); - check_const_name_sym(mrb, id); - val = mrb_iv_remove(mrb, mod, id); - if (mrb_undef_p(val)) { - mrb_name_error(mrb, id, "constant %S not defined", mrb_sym2str(mrb, id)); - } - return val; -} - -static mrb_value -mrb_mod_const_missing(mrb_state *mrb, mrb_value mod) -{ - mrb_sym sym; - - mrb_get_args(mrb, "n", &sym); - - if (mrb_class_real(mrb_class_ptr(mod)) != mrb->object_class) { - mrb_name_error(mrb, sym, "uninitialized constant %S::%S", - mod, - mrb_sym2str(mrb, sym)); - } - else { - mrb_name_error(mrb, sym, "uninitialized constant %S", - mrb_sym2str(mrb, sym)); - } - /* not reached */ - return mrb_nil_value(); -} - -static mrb_value -mrb_mod_s_constants(mrb_state *mrb, mrb_value mod) -{ - mrb_raise(mrb, E_NOTIMP_ERROR, "Module.constants not implemented"); - return mrb_nil_value(); /* not reached */ -} - -static mrb_value -mrb_mod_eqq(mrb_state *mrb, mrb_value mod) -{ - mrb_value obj; - mrb_bool eqq; - - mrb_get_args(mrb, "o", &obj); - eqq = mrb_obj_is_kind_of(mrb, obj, mrb_class_ptr(mod)); - - return mrb_bool_value(eqq); -} - -MRB_API mrb_value -mrb_mod_module_function(mrb_state *mrb, mrb_value mod) -{ - mrb_value *argv; - mrb_int argc, i; - mrb_sym mid; - struct RProc *method_rproc; - struct RClass *rclass; - int ai; - - mrb_check_type(mrb, mod, MRB_TT_MODULE); - - mrb_get_args(mrb, "*", &argv, &argc); - if (argc == 0) { - /* set MODFUNC SCOPE if implemented */ - return mod; - } - - /* set PRIVATE method visibility if implemented */ - /* mrb_mod_dummy_visibility(mrb, mod); */ - - for (i=0; i<argc; i++) { - mrb_check_type(mrb, argv[i], MRB_TT_SYMBOL); - - mid = mrb_symbol(argv[i]); - rclass = mrb_class_ptr(mod); - method_rproc = mrb_method_search(mrb, rclass, mid); - - prepare_singleton_class(mrb, (struct RBasic*)rclass); - ai = mrb_gc_arena_save(mrb); - mrb_define_method_raw(mrb, rclass->c, mid, method_rproc); - mrb_gc_arena_restore(mrb, ai); - } - - return mod; -} - -/* implementation of __id__ */ -mrb_value mrb_obj_id_m(mrb_state *mrb, mrb_value self); -/* implementation of instance_eval */ -mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value); -/* implementation of Module.nesting */ -mrb_value mrb_mod_s_nesting(mrb_state*, mrb_value); - -void -mrb_init_class(mrb_state *mrb) -{ - struct RClass *bob; /* BasicObject */ - struct RClass *obj; /* Object */ - struct RClass *mod; /* Module */ - struct RClass *cls; /* Class */ - - /* boot class hierarchy */ - bob = boot_defclass(mrb, 0); - obj = boot_defclass(mrb, bob); mrb->object_class = obj; - mod = boot_defclass(mrb, obj); mrb->module_class = mod;/* obj -> mod */ - cls = boot_defclass(mrb, mod); mrb->class_class = cls; /* obj -> cls */ - /* fix-up loose ends */ - bob->c = obj->c = mod->c = cls->c = cls; - make_metaclass(mrb, bob); - make_metaclass(mrb, obj); - make_metaclass(mrb, mod); - make_metaclass(mrb, cls); - - /* name basic classes */ - mrb_define_const(mrb, bob, "BasicObject", mrb_obj_value(bob)); - mrb_define_const(mrb, obj, "BasicObject", mrb_obj_value(bob)); - mrb_define_const(mrb, obj, "Object", mrb_obj_value(obj)); - mrb_define_const(mrb, obj, "Module", mrb_obj_value(mod)); - mrb_define_const(mrb, obj, "Class", mrb_obj_value(cls)); - - /* name each classes */ - mrb_class_name_class(mrb, NULL, bob, mrb_intern_lit(mrb, "BasicObject")); - mrb_class_name_class(mrb, NULL, obj, mrb_intern_lit(mrb, "Object")); /* 15.2.1 */ - mrb_class_name_class(mrb, NULL, mod, mrb_intern_lit(mrb, "Module")); /* 15.2.2 */ - mrb_class_name_class(mrb, NULL, cls, mrb_intern_lit(mrb, "Class")); /* 15.2.3 */ - - mrb->proc_class = mrb_define_class(mrb, "Proc", mrb->object_class); /* 15.2.17 */ - MRB_SET_INSTANCE_TT(mrb->proc_class, MRB_TT_PROC); - - MRB_SET_INSTANCE_TT(cls, MRB_TT_CLASS); - mrb_define_method(mrb, bob, "initialize", mrb_bob_init, MRB_ARGS_NONE()); - mrb_define_method(mrb, bob, "!", mrb_bob_not, MRB_ARGS_NONE()); - mrb_define_method(mrb, bob, "==", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.1 */ - mrb_define_method(mrb, bob, "!=", mrb_obj_not_equal_m, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, bob, "__id__", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.3 */ - mrb_define_method(mrb, bob, "__send__", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.4 */ - mrb_define_method(mrb, bob, "instance_eval", mrb_obj_instance_eval, MRB_ARGS_ANY()); /* 15.3.1.3.18 */ - - mrb_define_class_method(mrb, cls, "new", mrb_class_new_class, MRB_ARGS_OPT(1)); - mrb_define_method(mrb, cls, "superclass", mrb_class_superclass, MRB_ARGS_NONE()); /* 15.2.3.3.4 */ - mrb_define_method(mrb, cls, "new", mrb_instance_new, MRB_ARGS_ANY()); /* 15.2.3.3.3 */ - mrb_define_method(mrb, cls, "initialize", mrb_class_initialize, MRB_ARGS_OPT(1)); /* 15.2.3.3.1 */ - mrb_define_method(mrb, cls, "inherited", mrb_bob_init, MRB_ARGS_REQ(1)); - - MRB_SET_INSTANCE_TT(mod, MRB_TT_MODULE); - mrb_define_method(mrb, mod, "class_variable_defined?", mrb_mod_cvar_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.16 */ - mrb_define_method(mrb, mod, "class_variable_get", mrb_mod_cvar_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.17 */ - mrb_define_method(mrb, mod, "class_variable_set", mrb_mod_cvar_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.18 */ - mrb_define_method(mrb, mod, "extend_object", mrb_mod_extend_object, MRB_ARGS_REQ(1)); /* 15.2.2.4.25 */ - mrb_define_method(mrb, mod, "extended", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.26 */ - mrb_define_method(mrb, mod, "prepended", mrb_bob_init, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "prepend_features", mrb_mod_prepend_features, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "include?", mrb_mod_include_p, MRB_ARGS_REQ(1)); /* 15.2.2.4.28 */ - mrb_define_method(mrb, mod, "append_features", mrb_mod_append_features, MRB_ARGS_REQ(1)); /* 15.2.2.4.10 */ - mrb_define_method(mrb, mod, "class_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.15 */ - mrb_define_method(mrb, mod, "included", mrb_bob_init, MRB_ARGS_REQ(1)); /* 15.2.2.4.29 */ - mrb_define_method(mrb, mod, "included_modules", mrb_mod_included_modules, MRB_ARGS_NONE()); /* 15.2.2.4.30 */ - mrb_define_method(mrb, mod, "initialize", mrb_mod_initialize, MRB_ARGS_NONE()); /* 15.2.2.4.31 */ - mrb_define_method(mrb, mod, "instance_methods", mrb_mod_instance_methods, MRB_ARGS_ANY()); /* 15.2.2.4.33 */ - mrb_define_method(mrb, mod, "method_defined?", mrb_mod_method_defined, MRB_ARGS_REQ(1)); /* 15.2.2.4.34 */ - mrb_define_method(mrb, mod, "module_eval", mrb_mod_module_eval, MRB_ARGS_ANY()); /* 15.2.2.4.35 */ - mrb_define_method(mrb, mod, "module_function", mrb_mod_module_function, MRB_ARGS_ANY()); - mrb_define_method(mrb, mod, "private", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.36 */ - mrb_define_method(mrb, mod, "protected", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.37 */ - mrb_define_method(mrb, mod, "public", mrb_mod_dummy_visibility, MRB_ARGS_ANY()); /* 15.2.2.4.38 */ - mrb_define_method(mrb, mod, "remove_class_variable", mrb_mod_remove_cvar, MRB_ARGS_REQ(1)); /* 15.2.2.4.39 */ - mrb_define_method(mrb, mod, "remove_method", mrb_mod_remove_method, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ - mrb_define_method(mrb, mod, "method_removed", mrb_bob_init, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "attr_reader", mrb_mod_attr_reader, MRB_ARGS_ANY()); /* 15.2.2.4.13 */ - mrb_define_method(mrb, mod, "attr_writer", mrb_mod_attr_writer, MRB_ARGS_ANY()); /* 15.2.2.4.14 */ - mrb_define_method(mrb, mod, "to_s", mrb_mod_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, mod, "inspect", mrb_mod_to_s, MRB_ARGS_NONE()); - mrb_define_method(mrb, mod, "alias_method", mrb_mod_alias, MRB_ARGS_ANY()); /* 15.2.2.4.8 */ - mrb_define_method(mrb, mod, "ancestors", mrb_mod_ancestors, MRB_ARGS_NONE()); /* 15.2.2.4.9 */ - mrb_define_method(mrb, mod, "undef_method", mrb_mod_undef, MRB_ARGS_ANY()); /* 15.2.2.4.41 */ - mrb_define_method(mrb, mod, "const_defined?", mrb_mod_const_defined, MRB_ARGS_ARG(1,1)); /* 15.2.2.4.20 */ - mrb_define_method(mrb, mod, "const_get", mrb_mod_const_get, MRB_ARGS_REQ(1)); /* 15.2.2.4.21 */ - mrb_define_method(mrb, mod, "const_set", mrb_mod_const_set, MRB_ARGS_REQ(2)); /* 15.2.2.4.23 */ - mrb_define_method(mrb, mod, "constants", mrb_mod_constants, MRB_ARGS_OPT(1)); /* 15.2.2.4.24 */ - mrb_define_method(mrb, mod, "remove_const", mrb_mod_remove_const, MRB_ARGS_REQ(1)); /* 15.2.2.4.40 */ - mrb_define_method(mrb, mod, "const_missing", mrb_mod_const_missing, MRB_ARGS_REQ(1)); - mrb_define_method(mrb, mod, "define_method", mod_define_method, MRB_ARGS_ARG(1,1)); - mrb_define_method(mrb, mod, "class_variables", mrb_mod_class_variables, MRB_ARGS_NONE()); /* 15.2.2.4.19 */ - mrb_define_method(mrb, mod, "===", mrb_mod_eqq, MRB_ARGS_REQ(1)); - mrb_define_class_method(mrb, mod, "constants", mrb_mod_s_constants, MRB_ARGS_ANY()); /* 15.2.2.3.1 */ - mrb_define_class_method(mrb, mod, "nesting", mrb_mod_s_nesting, MRB_ARGS_REQ(0)); /* 15.2.2.3.2 */ - - mrb_undef_method(mrb, cls, "append_features"); - mrb_undef_method(mrb, cls, "extend_object"); -} |