diff options
Diffstat (limited to 'web/server/h2o/libh2o/deps/mruby/src/kernel.c')
-rw-r--r-- | web/server/h2o/libh2o/deps/mruby/src/kernel.c | 1238 |
1 files changed, 0 insertions, 1238 deletions
diff --git a/web/server/h2o/libh2o/deps/mruby/src/kernel.c b/web/server/h2o/libh2o/deps/mruby/src/kernel.c deleted file mode 100644 index 4e95ab24b..000000000 --- a/web/server/h2o/libh2o/deps/mruby/src/kernel.c +++ /dev/null @@ -1,1238 +0,0 @@ -/* -** kernel.c - Kernel module -** -** See Copyright Notice in mruby.h -*/ - -#include <mruby.h> -#include <mruby/array.h> -#include <mruby/hash.h> -#include <mruby/class.h> -#include <mruby/proc.h> -#include <mruby/string.h> -#include <mruby/variable.h> -#include <mruby/error.h> -#include <mruby/istruct.h> - -typedef enum { - NOEX_PUBLIC = 0x00, - NOEX_NOSUPER = 0x01, - NOEX_PRIVATE = 0x02, - NOEX_PROTECTED = 0x04, - NOEX_MASK = 0x06, - NOEX_BASIC = 0x08, - NOEX_UNDEF = NOEX_NOSUPER, - NOEX_MODFUNC = 0x12, - NOEX_SUPER = 0x20, - NOEX_VCALL = 0x40, - NOEX_RESPONDS = 0x80 -} mrb_method_flag_t; - -MRB_API mrb_bool -mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func) -{ - struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mid); - if (MRB_PROC_CFUNC_P(me) && (me->body.func == func)) - return TRUE; - return FALSE; -} - -static mrb_bool -mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj) -{ - return mrb_func_basic_p(mrb, obj, mrb_intern_lit(mrb, "to_s"), mrb_any_to_s); -} - -/* 15.3.1.3.17 */ -/* - * call-seq: - * obj.inspect -> string - * - * Returns a string containing a human-readable representation of - * <i>obj</i>. If not overridden and no instance variables, uses the - * <code>to_s</code> method to generate the string. - * <i>obj</i>. If not overridden, uses the <code>to_s</code> method to - * generate the string. - * - * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]" - * Time.new.inspect #=> "2008-03-08 19:43:39 +0900" - */ -MRB_API mrb_value -mrb_obj_inspect(mrb_state *mrb, mrb_value obj) -{ - if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) { - return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj)); - } - return mrb_any_to_s(mrb, obj); -} - -/* 15.3.1.3.2 */ -/* - * call-seq: - * obj === other -> true or false - * - * Case Equality---For class <code>Object</code>, effectively the same - * as calling <code>#==</code>, but typically overridden by descendants - * to provide meaningful semantics in <code>case</code> statements. - */ -static mrb_value -mrb_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)); -} - -/* 15.3.1.3.3 */ -/* 15.3.1.3.33 */ -/* - * Document-method: __id__ - * Document-method: object_id - * - * call-seq: - * obj.__id__ -> fixnum - * obj.object_id -> fixnum - * - * Returns an integer identifier for <i>obj</i>. The same number will - * be returned on all calls to <code>id</code> for a given object, and - * no two active objects will share an id. - * <code>Object#object_id</code> is a different concept from the - * <code>:name</code> notation, which returns the symbol id of - * <code>name</code>. Replaces the deprecated <code>Object#id</code>. - */ -mrb_value -mrb_obj_id_m(mrb_state *mrb, mrb_value self) -{ - return mrb_fixnum_value(mrb_obj_id(self)); -} - -/* 15.3.1.2.2 */ -/* 15.3.1.2.5 */ -/* 15.3.1.3.6 */ -/* 15.3.1.3.25 */ -/* - * call-seq: - * block_given? -> true or false - * iterator? -> true or false - * - * Returns <code>true</code> if <code>yield</code> would execute a - * block in the current context. The <code>iterator?</code> form - * is mildly deprecated. - * - * def try - * if block_given? - * yield - * else - * "no block" - * end - * end - * try #=> "no block" - * try { "hello" } #=> "hello" - * try do "hello" end #=> "hello" - */ -static mrb_value -mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self) -{ - mrb_callinfo *ci = mrb->c->ci; - mrb_value *bp; - - bp = ci->stackent + 1; - ci--; - if (ci <= mrb->c->cibase) { - return mrb_false_value(); - } - /* block_given? called within block; check upper scope */ - if (ci->proc->env) { - struct REnv *e = ci->proc->env; - - while (e->c) { - e = (struct REnv*)e->c; - } - /* top-level does not have block slot (always false) */ - if (e->stack == mrb->c->stbase) - return mrb_false_value(); - if (e->stack && e->cioff < 0) { - /* use saved block arg position */ - bp = &e->stack[-e->cioff]; - ci = 0; /* no callinfo available */ - } - else { - ci = e->cxt.c->cibase + e->cioff; - bp = ci[1].stackent + 1; - } - } - if (ci && ci->argc > 0) { - bp += ci->argc; - } - if (mrb_nil_p(*bp)) - return mrb_false_value(); - return mrb_true_value(); -} - -/* 15.3.1.3.7 */ -/* - * call-seq: - * obj.class -> class - * - * Returns the class of <i>obj</i>. 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 - */ -static mrb_value -mrb_obj_class_m(mrb_state *mrb, mrb_value self) -{ - return mrb_obj_value(mrb_obj_class(mrb, self)); -} - -static struct RClass* -mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj) -{ - struct RClass *klass = mrb_basic_ptr(obj)->c; - - if (klass->tt != MRB_TT_SCLASS) - return klass; - else { - /* copy singleton(unnamed) class */ - struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class); - - switch (mrb_type(obj)) { - case MRB_TT_CLASS: - case MRB_TT_SCLASS: - break; - default: - clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass)); - break; - } - clone->super = klass->super; - if (klass->iv) { - mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass)); - mrb_obj_iv_set(mrb, (struct RObject*)clone, mrb_intern_lit(mrb, "__attached__"), obj); - } - if (klass->mt) { - clone->mt = kh_copy(mt, mrb, klass->mt); - } - else { - clone->mt = kh_init(mt, mrb); - } - clone->tt = MRB_TT_SCLASS; - return clone; - } -} - -static void -copy_class(mrb_state *mrb, mrb_value dst, mrb_value src) -{ - struct RClass *dc = mrb_class_ptr(dst); - struct RClass *sc = mrb_class_ptr(src); - /* if the origin is not the same as the class, then the origin and - the current class need to be copied */ - if (sc->flags & MRB_FLAG_IS_PREPENDED) { - struct RClass *c0 = sc->super; - struct RClass *c1 = dc; - - /* copy prepended iclasses */ - while (!(c0->flags & MRB_FLAG_IS_ORIGIN)) { - c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); - c1 = c1->super; - c0 = c0->super; - } - c1->super = mrb_class_ptr(mrb_obj_dup(mrb, mrb_obj_value(c0))); - c1->super->flags |= MRB_FLAG_IS_ORIGIN; - } - if (sc->mt) { - dc->mt = kh_copy(mt, mrb, sc->mt); - } - else { - dc->mt = kh_init(mt, mrb); - } - dc->super = sc->super; - MRB_SET_INSTANCE_TT(dc, MRB_INSTANCE_TT(sc)); -} - -static void -init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) -{ - switch (mrb_type(obj)) { - case MRB_TT_CLASS: - case MRB_TT_MODULE: - copy_class(mrb, dest, obj); - /* fall through */ - case MRB_TT_OBJECT: - case MRB_TT_SCLASS: - case MRB_TT_HASH: - case MRB_TT_DATA: - case MRB_TT_EXCEPTION: - mrb_iv_copy(mrb, dest, obj); - break; - case MRB_TT_ISTRUCT: - mrb_istruct_copy(dest, obj); - break; - - default: - break; - } - mrb_funcall(mrb, dest, "initialize_copy", 1, obj); -} - -/* 15.3.1.3.8 */ -/* - * call-seq: - * obj.clone -> an_object - * - * Produces a shallow copy of <i>obj</i>---the instance variables of - * <i>obj</i> are copied, but not the objects they reference. Copies - * the frozen state of <i>obj</i>. See also the discussion - * under <code>Object#dup</code>. - * - * class Klass - * attr_accessor :str - * end - * s1 = Klass.new #=> #<Klass:0x401b3a38> - * s1.str = "Hello" #=> "Hello" - * s2 = s1.clone #=> #<Klass:0x401b3998 @str="Hello"> - * s2.str[1,4] = "i" #=> "i" - * s1.inspect #=> "#<Klass:0x401b3a38 @str=\"Hi\">" - * s2.inspect #=> "#<Klass:0x401b3998 @str=\"Hi\">" - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - * - * Some Class(True False Nil Symbol Fixnum Float) Object cannot clone. - */ -MRB_API mrb_value -mrb_obj_clone(mrb_state *mrb, mrb_value self) -{ - struct RObject *p; - mrb_value clone; - - if (mrb_immediate_p(self)) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self); - } - if (mrb_type(self) == MRB_TT_SCLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "can't clone singleton class"); - } - p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self)); - p->c = mrb_singleton_class_clone(mrb, self); - mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)p->c); - clone = mrb_obj_value(p); - init_copy(mrb, clone, self); - - return clone; -} - -/* 15.3.1.3.9 */ -/* - * call-seq: - * obj.dup -> an_object - * - * Produces a shallow copy of <i>obj</i>---the instance variables of - * <i>obj</i> are copied, but not the objects they reference. - * <code>dup</code> copies the frozen state of <i>obj</i>. See also - * the discussion under <code>Object#clone</code>. In general, - * <code>clone</code> and <code>dup</code> may have different semantics - * in descendant classes. While <code>clone</code> is used to duplicate - * an object, including its internal state, <code>dup</code> typically - * uses the class of the descendant object to create the new instance. - * - * This method may have class-specific behavior. If so, that - * behavior will be documented under the #+initialize_copy+ method of - * the class. - */ - -MRB_API mrb_value -mrb_obj_dup(mrb_state *mrb, mrb_value obj) -{ - struct RBasic *p; - mrb_value dup; - - if (mrb_immediate_p(obj)) { - mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj); - } - if (mrb_type(obj) == MRB_TT_SCLASS) { - mrb_raise(mrb, E_TYPE_ERROR, "can't dup singleton class"); - } - p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj)); - dup = mrb_obj_value(p); - init_copy(mrb, dup, obj); - - return dup; -} - -static mrb_value -mrb_obj_extend(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value obj) -{ - mrb_int i; - - if (argc == 0) { - mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)"); - } - for (i = 0; i < argc; i++) { - mrb_check_type(mrb, argv[i], MRB_TT_MODULE); - } - while (argc--) { - mrb_funcall(mrb, argv[argc], "extend_object", 1, obj); - mrb_funcall(mrb, argv[argc], "extended", 1, obj); - } - return obj; -} - -/* 15.3.1.3.13 */ -/* - * call-seq: - * obj.extend(module, ...) -> obj - * - * Adds to _obj_ the instance methods from each module given as a - * parameter. - * - * module Mod - * def hello - * "Hello from Mod.\n" - * end - * end - * - * class Klass - * def hello - * "Hello from Klass.\n" - * end - * end - * - * k = Klass.new - * k.hello #=> "Hello from Klass.\n" - * k.extend(Mod) #=> #<Klass:0x401b3bc8> - * k.hello #=> "Hello from Mod.\n" - */ -static mrb_value -mrb_obj_extend_m(mrb_state *mrb, mrb_value self) -{ - mrb_value *argv; - mrb_int argc; - - mrb_get_args(mrb, "*", &argv, &argc); - return mrb_obj_extend(mrb, argc, argv, self); -} - -static mrb_value -mrb_obj_freeze(mrb_state *mrb, mrb_value self) -{ - struct RBasic *b; - - switch (mrb_type(self)) { - case MRB_TT_FALSE: - case MRB_TT_TRUE: - case MRB_TT_FIXNUM: - case MRB_TT_SYMBOL: - case MRB_TT_FLOAT: - return self; - default: - break; - } - - b = mrb_basic_ptr(self); - if (!MRB_FROZEN_P(b)) { - MRB_SET_FROZEN_FLAG(b); - } - return self; -} - -static mrb_value -mrb_obj_frozen(mrb_state *mrb, mrb_value self) -{ - struct RBasic *b; - - switch (mrb_type(self)) { - case MRB_TT_FALSE: - case MRB_TT_TRUE: - case MRB_TT_FIXNUM: - case MRB_TT_SYMBOL: - case MRB_TT_FLOAT: - return mrb_true_value(); - default: - break; - } - - b = mrb_basic_ptr(self); - if (!MRB_FROZEN_P(b)) { - return mrb_false_value(); - } - return mrb_true_value(); -} - -/* 15.3.1.3.15 */ -/* - * call-seq: - * obj.hash -> fixnum - * - * Generates a <code>Fixnum</code> hash value for this object. This - * function must have the property that <code>a.eql?(b)</code> implies - * <code>a.hash == b.hash</code>. The hash value is used by class - * <code>Hash</code>. Any hash value that exceeds the capacity of a - * <code>Fixnum</code> will be truncated before being used. - */ -MRB_API mrb_value -mrb_obj_hash(mrb_state *mrb, mrb_value self) -{ - return mrb_fixnum_value(mrb_obj_id(self)); -} - -/* 15.3.1.3.16 */ -static mrb_value -mrb_obj_init_copy(mrb_state *mrb, mrb_value self) -{ - mrb_value orig; - - mrb_get_args(mrb, "o", &orig); - if (mrb_obj_equal(mrb, self, orig)) return self; - if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) { - mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object"); - } - return self; -} - - -MRB_API mrb_bool -mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c) -{ - if (mrb_obj_class(mrb, obj) == c) return TRUE; - return FALSE; -} - -/* 15.3.1.3.19 */ -/* - * call-seq: - * obj.instance_of?(class) -> true or false - * - * Returns <code>true</code> if <i>obj</i> is an instance of the given - * class. See also <code>Object#kind_of?</code>. - */ -static mrb_value -obj_is_instance_of(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "C", &arg); - - return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg))); -} - -/* 15.3.1.3.20 */ -/* - * call-seq: - * obj.instance_variable_defined?(symbol) -> true or false - * - * Returns <code>true</code> if the given instance variable is - * defined in <i>obj</i>. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_defined?(:@a) #=> true - * fred.instance_variable_defined?("@b") #=> true - * fred.instance_variable_defined?("@c") #=> false - */ -static mrb_value -mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self) -{ - mrb_sym sym; - - mrb_get_args(mrb, "n", &sym); - mrb_iv_check(mrb, sym); - return mrb_bool_value(mrb_iv_defined(mrb, self, sym)); -} - -/* 15.3.1.3.21 */ -/* - * call-seq: - * obj.instance_variable_get(symbol) -> obj - * - * Returns the value of the given instance variable, or nil if the - * instance variable is not set. The <code>@</code> part of the - * variable name should be included for regular instance - * variables. Throws a <code>NameError</code> exception if the - * supplied symbol is not valid as an instance variable name. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_get(:@a) #=> "cat" - * fred.instance_variable_get("@b") #=> 99 - */ -static mrb_value -mrb_obj_ivar_get(mrb_state *mrb, mrb_value self) -{ - mrb_sym iv_name; - - mrb_get_args(mrb, "n", &iv_name); - mrb_iv_check(mrb, iv_name); - return mrb_iv_get(mrb, self, iv_name); -} - -/* 15.3.1.3.22 */ -/* - * call-seq: - * obj.instance_variable_set(symbol, obj) -> obj - * - * Sets the instance variable names by <i>symbol</i> to - * <i>object</i>, thereby frustrating the efforts of the class's - * author to attempt to provide proper encapsulation. The variable - * did not have to exist prior to this call. - * - * class Fred - * def initialize(p1, p2) - * @a, @b = p1, p2 - * end - * end - * fred = Fred.new('cat', 99) - * fred.instance_variable_set(:@a, 'dog') #=> "dog" - * fred.instance_variable_set(:@c, 'cat') #=> "cat" - * fred.inspect #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">" - */ -static mrb_value -mrb_obj_ivar_set(mrb_state *mrb, mrb_value self) -{ - mrb_sym iv_name; - mrb_value val; - - mrb_get_args(mrb, "no", &iv_name, &val); - mrb_iv_check(mrb, iv_name); - mrb_iv_set(mrb, self, iv_name, val); - return val; -} - -/* 15.3.1.3.24 */ -/* 15.3.1.3.26 */ -/* - * call-seq: - * obj.is_a?(class) -> true or false - * obj.kind_of?(class) -> true or false - * - * Returns <code>true</code> if <i>class</i> is the class of - * <i>obj</i>, or if <i>class</i> is one of the superclasses of - * <i>obj</i> or modules included in <i>obj</i>. - * - * module M; end - * class A - * include M - * end - * class B < A; end - * class C < B; end - * b = B.new - * b.instance_of? A #=> false - * b.instance_of? B #=> true - * b.instance_of? C #=> false - * b.instance_of? M #=> false - * b.kind_of? A #=> true - * b.kind_of? B #=> true - * b.kind_of? C #=> false - * b.kind_of? M #=> true - */ -static mrb_value -mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) -{ - mrb_value arg; - - mrb_get_args(mrb, "C", &arg); - - return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg))); -} - -KHASH_DECLARE(st, mrb_sym, char, FALSE) -KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal) - -static void -method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) -{ - khint_t i; - - khash_t(mt) *h = klass->mt; - if (!h) return; - for (i=0;i<kh_end(h);i++) { - if (kh_exist(h, i) && kh_value(h, i)) { - kh_put(st, mrb, set, kh_key(h, i)); - } - } -} - -mrb_value -mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj) -{ - khint_t i; - mrb_value ary; - mrb_bool prepended = FALSE; - struct RClass* oldklass; - khash_t(st)* set = kh_init(st, mrb); - - if (!recur && (klass->flags & MRB_FLAG_IS_PREPENDED)) { - MRB_CLASS_ORIGIN(klass); - prepended = TRUE; - } - - oldklass = 0; - while (klass && (klass != oldklass)) { - method_entry_loop(mrb, klass, set); - if ((klass->tt == MRB_TT_ICLASS && !prepended) || - (klass->tt == MRB_TT_SCLASS)) { - } - else { - if (!recur) break; - } - oldklass = klass; - klass = klass->super; - } - - ary = mrb_ary_new(mrb); - for (i=0;i<kh_end(set);i++) { - if (kh_exist(set, i)) { - mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i))); - } - } - kh_destroy(st, mrb, set); - - return ary; -} - -static mrb_value -mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) -{ - khint_t i; - mrb_value ary; - struct RClass* klass; - khash_t(st)* set = kh_init(st, mrb); - - klass = mrb_class(mrb, obj); - - if (klass && (klass->tt == MRB_TT_SCLASS)) { - method_entry_loop(mrb, klass, set); - klass = klass->super; - } - if (recur) { - while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) { - method_entry_loop(mrb, klass, set); - klass = klass->super; - } - } - - ary = mrb_ary_new(mrb); - for (i=0;i<kh_end(set);i++) { - if (kh_exist(set, i)) { - mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i))); - } - } - kh_destroy(st, mrb, set); - - return ary; -} - -static mrb_value -mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag) -{ - return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0); -} -/* 15.3.1.3.31 */ -/* - * call-seq: - * obj.methods -> array - * - * Returns a list of the names of methods publicly accessible in - * <i>obj</i>. This will include all the methods accessible in - * <i>obj</i>'s ancestors. - * - * class Klass - * def kMethod() - * end - * end - * k = Klass.new - * k.methods[0..9] #=> [:kMethod, :respond_to?, :nil?, :is_a?, - * # :class, :instance_variable_set, - * # :methods, :extend, :__send__, :instance_eval] - * k.methods.length #=> 42 - */ -static mrb_value -mrb_obj_methods_m(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, (mrb_method_flag_t)0); /* everything but private */ -} - -/* 15.3.1.3.32 */ -/* - * call_seq: - * nil.nil? -> true - * <anything_else>.nil? -> false - * - * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>. - */ -static mrb_value -mrb_false(mrb_state *mrb, mrb_value self) -{ - return mrb_false_value(); -} - -/* 15.3.1.3.36 */ -/* - * call-seq: - * obj.private_methods(all=true) -> array - * - * Returns the list of private methods accessible to <i>obj</i>. If - * the <i>all</i> parameter is set to <code>false</code>, only those methods - * in the receiver will be listed. - */ -static mrb_value -mrb_obj_private_methods(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, NOEX_PRIVATE); /* private attribute not define */ -} - -/* 15.3.1.3.37 */ -/* - * call-seq: - * obj.protected_methods(all=true) -> array - * - * Returns the list of protected methods accessible to <i>obj</i>. If - * the <i>all</i> parameter is set to <code>false</code>, only those methods - * in the receiver will be listed. - */ -static mrb_value -mrb_obj_protected_methods(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, NOEX_PROTECTED); /* protected attribute not define */ -} - -/* 15.3.1.3.38 */ -/* - * call-seq: - * obj.public_methods(all=true) -> array - * - * Returns the list of public methods accessible to <i>obj</i>. If - * the <i>all</i> parameter is set to <code>false</code>, only those methods - * in the receiver will be listed. - */ -static mrb_value -mrb_obj_public_methods(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_methods(mrb, recur, self, NOEX_PUBLIC); /* public attribute not define */ -} - -/* 15.3.1.2.12 */ -/* 15.3.1.3.40 */ -/* - * call-seq: - * raise - * raise(string) - * raise(exception [, string]) - * - * With no arguments, raises a <code>RuntimeError</code> - * With a single +String+ argument, raises a - * +RuntimeError+ with the string as a message. Otherwise, - * the first parameter should be the name of an +Exception+ - * class (or an object that returns an +Exception+ object when sent - * an +exception+ message). The optional second parameter sets the - * message associated with the exception, and the third parameter is an - * array of callback information. Exceptions are caught by the - * +rescue+ clause of <code>begin...end</code> blocks. - * - * raise "Failed to create socket" - * raise ArgumentError, "No parameters", caller - */ -MRB_API mrb_value -mrb_f_raise(mrb_state *mrb, mrb_value self) -{ - mrb_value a[2], exc; - int argc; - - - argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]); - switch (argc) { - case 0: - mrb_raise(mrb, E_RUNTIME_ERROR, ""); - break; - case 1: - if (mrb_string_p(a[0])) { - a[1] = a[0]; - argc = 2; - a[0] = mrb_obj_value(E_RUNTIME_ERROR); - } - /* fall through */ - default: - exc = mrb_make_exception(mrb, argc, a); - mrb_exc_raise(mrb, exc); - break; - } - return mrb_nil_value(); /* not reached */ -} - -/* 15.3.1.3.41 */ -/* - * call-seq: - * obj.remove_instance_variable(symbol) -> obj - * - * Removes the named instance variable from <i>obj</i>, returning that - * variable's value. - * - * class Dummy - * attr_reader :var - * def initialize - * @var = 99 - * end - * def remove - * remove_instance_variable(:@var) - * end - * end - * d = Dummy.new - * d.var #=> 99 - * d.remove #=> 99 - * d.var #=> nil - */ -static mrb_value -mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self) -{ - mrb_sym sym; - mrb_value val; - - mrb_get_args(mrb, "n", &sym); - mrb_iv_check(mrb, sym); - val = mrb_iv_remove(mrb, self, sym); - if (mrb_undef_p(val)) { - mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym)); - } - return val; -} - -void -mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args) -{ - mrb_sym inspect; - mrb_value repr; - - inspect = mrb_intern_lit(mrb, "inspect"); - if (mrb->c->ci > mrb->c->cibase && mrb->c->ci[-1].mid == inspect) { - /* method missing in inspect; avoid recursion */ - repr = mrb_any_to_s(mrb, self); - } - else if (mrb_respond_to(mrb, self, inspect) && mrb->c->ci - mrb->c->cibase < 16) { - repr = mrb_funcall_argv(mrb, self, inspect, 0, 0); - if (mrb_string_p(repr) && RSTRING_LEN(repr) > 64) { - repr = mrb_any_to_s(mrb, self); - } - } - else { - repr = mrb_any_to_s(mrb, self); - } - - mrb_no_method_error(mrb, name, args, "undefined method '%S' for %S", - mrb_sym2str(mrb, name), repr); -} - -/* 15.3.1.3.30 */ -/* - * call-seq: - * obj.method_missing(symbol [, *args] ) -> result - * - * Invoked by Ruby when <i>obj</i> is sent a message it cannot handle. - * <i>symbol</i> is the symbol for the method called, and <i>args</i> - * are any arguments that were passed to it. By default, the interpreter - * raises an error when this method is called. However, it is possible - * to override the method to provide more dynamic behavior. - * If it is decided that a particular method should not be handled, then - * <i>super</i> should be called, so that ancestors can pick up the - * missing method. - * The example below creates - * a class <code>Roman</code>, which responds to methods with names - * consisting of roman numerals, returning the corresponding integer - * values. - * - * class Roman - * def romanToInt(str) - * # ... - * end - * def method_missing(methId) - * str = methId.id2name - * romanToInt(str) - * end - * end - * - * r = Roman.new - * r.iv #=> 4 - * r.xxiii #=> 23 - * r.mm #=> 2000 - */ -#ifdef MRB_DEFAULT_METHOD_MISSING -static mrb_value -mrb_obj_missing(mrb_state *mrb, mrb_value mod) -{ - mrb_sym name; - mrb_value *a; - mrb_int alen; - - mrb_get_args(mrb, "n*!", &name, &a, &alen); - mrb_method_missing(mrb, name, mod, mrb_ary_new_from_values(mrb, alen, a)); - /* not reached */ - return mrb_nil_value(); -} -#endif - -static inline mrb_bool -basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub) -{ - return mrb_respond_to(mrb, obj, id); -} -/* 15.3.1.3.43 */ -/* - * call-seq: - * obj.respond_to?(symbol, include_private=false) -> true or false - * - * Returns +true+ if _obj_ responds to the given - * method. Private methods are included in the search only if the - * optional second parameter evaluates to +true+. - * - * If the method is not implemented, - * as Process.fork on Windows, File.lchmod on GNU/Linux, etc., - * false is returned. - * - * If the method is not defined, <code>respond_to_missing?</code> - * method is called and the result is returned. - */ -static mrb_value -obj_respond_to(mrb_state *mrb, mrb_value self) -{ - mrb_value mid; - mrb_sym id, rtm_id; - mrb_bool priv = FALSE, respond_to_p = TRUE; - - mrb_get_args(mrb, "o|b", &mid, &priv); - - if (mrb_symbol_p(mid)) { - id = mrb_symbol(mid); - } - else { - mrb_value tmp; - if (mrb_string_p(mid)) { - tmp = mrb_check_intern_str(mrb, mid); - } - else { - tmp = mrb_check_string_type(mrb, mid); - if (mrb_nil_p(tmp)) { - tmp = mrb_inspect(mrb, mid); - mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp); - } - tmp = mrb_check_intern_str(mrb, tmp); - } - if (mrb_nil_p(tmp)) { - respond_to_p = FALSE; - } - else { - id = mrb_symbol(tmp); - } - } - - if (respond_to_p) { - respond_to_p = basic_obj_respond_to(mrb, self, id, !priv); - } - - if (!respond_to_p) { - rtm_id = mrb_intern_lit(mrb, "respond_to_missing?"); - if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) { - mrb_value args[2], v; - args[0] = mid; - args[1] = mrb_bool_value(priv); - v = mrb_funcall_argv(mrb, self, rtm_id, 2, args); - return mrb_bool_value(mrb_bool(v)); - } - } - return mrb_bool_value(respond_to_p); -} - -/* 15.3.1.3.45 */ -/* - * call-seq: - * obj.singleton_methods(all=true) -> array - * - * Returns an array of the names of singleton methods for <i>obj</i>. - * If the optional <i>all</i> parameter is true, the list will include - * methods in modules included in <i>obj</i>. - * Only public and protected singleton methods are returned. - * - * module Other - * def three() end - * end - * - * class Single - * def Single.four() end - * end - * - * a = Single.new - * - * def a.one() - * end - * - * class << a - * include Other - * def two() - * end - * end - * - * Single.singleton_methods #=> [:four] - * a.singleton_methods(false) #=> [:two, :one] - * a.singleton_methods #=> [:two, :one, :three] - */ -static mrb_value -mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self) -{ - mrb_bool recur = TRUE; - mrb_get_args(mrb, "|b", &recur); - return mrb_obj_singleton_methods(mrb, recur, self); -} - -static mrb_value -mod_define_singleton_method(mrb_state *mrb, mrb_value self) -{ - struct RProc *p; - mrb_sym mid; - mrb_value blk = mrb_nil_value(); - - mrb_get_args(mrb, "n&", &mid, &blk); - 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, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p); - return mrb_symbol_value(mid); -} - -static mrb_value -mrb_obj_ceqq(mrb_state *mrb, mrb_value self) -{ - mrb_value v; - mrb_int i, len; - mrb_sym eqq = mrb_intern_lit(mrb, "==="); - mrb_value ary = mrb_ary_splat(mrb, self); - - mrb_get_args(mrb, "o", &v); - len = RARRAY_LEN(ary); - for (i=0; i<len; i++) { - mrb_value c = mrb_funcall_argv(mrb, mrb_ary_entry(ary, i), eqq, 1, &v); - if (mrb_test(c)) return mrb_true_value(); - } - return mrb_false_value(); -} - -/* 15.3.1.2.7 */ -/* - * call-seq: - * local_variables -> array - * - * Returns the names of local variables in the current scope. - * - * [mruby limitation] - * If variable symbol information was stripped out from - * compiled binary files using `mruby-strip -l`, this - * method always returns an empty array. - */ -static mrb_value -mrb_local_variables(mrb_state *mrb, mrb_value self) -{ - struct RProc *proc; - mrb_irep *irep; - mrb_value vars; - size_t i; - - proc = mrb->c->ci[-1].proc; - - if (MRB_PROC_CFUNC_P(proc)) { - return mrb_ary_new(mrb); - } - vars = mrb_hash_new(mrb); - irep = proc->body.irep; - while (irep) { - if (!irep->lv) break; - for (i = 0; i + 1 < irep->nlocals; ++i) { - if (irep->lv[i].name) { - mrb_hash_set(mrb, vars, mrb_symbol_value(irep->lv[i].name), mrb_true_value()); - } - } - if (!proc->env) break; - irep = irep->outer; - } - - return mrb_hash_keys(mrb, vars); -} - -mrb_value mrb_obj_equal_m(mrb_state *mrb, mrb_value); -void -mrb_init_kernel(mrb_state *mrb) -{ - struct RClass *krn; - - mrb->kernel_module = krn = mrb_define_module(mrb, "Kernel"); /* 15.3.1 */ - mrb_define_class_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.2 */ - mrb_define_class_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.2.4 */ - mrb_define_class_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.2.5 */ - mrb_define_class_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.2.7 */ -; /* 15.3.1.2.11 */ - mrb_define_class_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_OPT(2)); /* 15.3.1.2.12 */ - - mrb_define_method(mrb, krn, "singleton_class", mrb_singleton_class, MRB_ARGS_NONE()); - - mrb_define_method(mrb, krn, "===", mrb_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */ - mrb_define_method(mrb, krn, "block_given?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.6 */ - mrb_define_method(mrb, krn, "class", mrb_obj_class_m, MRB_ARGS_NONE()); /* 15.3.1.3.7 */ - mrb_define_method(mrb, krn, "clone", mrb_obj_clone, MRB_ARGS_NONE()); /* 15.3.1.3.8 */ - mrb_define_method(mrb, krn, "dup", mrb_obj_dup, MRB_ARGS_NONE()); /* 15.3.1.3.9 */ - mrb_define_method(mrb, krn, "eql?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */ - mrb_define_method(mrb, krn, "equal?", mrb_obj_equal_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.11 */ - mrb_define_method(mrb, krn, "extend", mrb_obj_extend_m, MRB_ARGS_ANY()); /* 15.3.1.3.13 */ - mrb_define_method(mrb, krn, "freeze", mrb_obj_freeze, MRB_ARGS_NONE()); - mrb_define_method(mrb, krn, "frozen?", mrb_obj_frozen, MRB_ARGS_NONE()); - mrb_define_method(mrb, krn, "global_variables", mrb_f_global_variables, MRB_ARGS_NONE()); /* 15.3.1.3.14 */ - mrb_define_method(mrb, krn, "hash", mrb_obj_hash, MRB_ARGS_NONE()); /* 15.3.1.3.15 */ - mrb_define_method(mrb, krn, "initialize_copy", mrb_obj_init_copy, MRB_ARGS_REQ(1)); /* 15.3.1.3.16 */ - mrb_define_method(mrb, krn, "inspect", mrb_obj_inspect, MRB_ARGS_NONE()); /* 15.3.1.3.17 */ - mrb_define_method(mrb, krn, "instance_of?", obj_is_instance_of, MRB_ARGS_REQ(1)); /* 15.3.1.3.19 */ - mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined, MRB_ARGS_REQ(1)); /* 15.3.1.3.20 */ - mrb_define_method(mrb, krn, "instance_variable_get", mrb_obj_ivar_get, MRB_ARGS_REQ(1)); /* 15.3.1.3.21 */ - mrb_define_method(mrb, krn, "instance_variable_set", mrb_obj_ivar_set, MRB_ARGS_REQ(2)); /* 15.3.1.3.22 */ - mrb_define_method(mrb, krn, "instance_variables", mrb_obj_instance_variables, MRB_ARGS_NONE()); /* 15.3.1.3.23 */ - mrb_define_method(mrb, krn, "is_a?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.24 */ - mrb_define_method(mrb, krn, "iterator?", mrb_f_block_given_p_m, MRB_ARGS_NONE()); /* 15.3.1.3.25 */ - mrb_define_method(mrb, krn, "kind_of?", mrb_obj_is_kind_of_m, MRB_ARGS_REQ(1)); /* 15.3.1.3.26 */ - mrb_define_method(mrb, krn, "local_variables", mrb_local_variables, MRB_ARGS_NONE()); /* 15.3.1.3.28 */ -#ifdef MRB_DEFAULT_METHOD_MISSING - mrb_define_method(mrb, krn, "method_missing", mrb_obj_missing, MRB_ARGS_ANY()); /* 15.3.1.3.30 */ -#endif - mrb_define_method(mrb, krn, "methods", mrb_obj_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.31 */ - mrb_define_method(mrb, krn, "nil?", mrb_false, MRB_ARGS_NONE()); /* 15.3.1.3.32 */ - mrb_define_method(mrb, krn, "object_id", mrb_obj_id_m, MRB_ARGS_NONE()); /* 15.3.1.3.33 */ - mrb_define_method(mrb, krn, "private_methods", mrb_obj_private_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.36 */ - mrb_define_method(mrb, krn, "protected_methods", mrb_obj_protected_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.37 */ - mrb_define_method(mrb, krn, "public_methods", mrb_obj_public_methods, MRB_ARGS_OPT(1)); /* 15.3.1.3.38 */ - mrb_define_method(mrb, krn, "raise", mrb_f_raise, MRB_ARGS_ANY()); /* 15.3.1.3.40 */ - mrb_define_method(mrb, krn, "remove_instance_variable", mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1)); /* 15.3.1.3.41 */ - mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ANY()); /* 15.3.1.3.43 */ - mrb_define_method(mrb, krn, "send", mrb_f_send, MRB_ARGS_ANY()); /* 15.3.1.3.44 */ - mrb_define_method(mrb, krn, "singleton_methods", mrb_obj_singleton_methods_m, MRB_ARGS_OPT(1)); /* 15.3.1.3.45 */ - mrb_define_method(mrb, krn, "define_singleton_method", mod_define_singleton_method, MRB_ARGS_ANY()); - mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ - mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ - - mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); - mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone")); -} |