mbed I/F binding for mruby

Dependents:   mruby_mbed_web mirb_mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers kernel.c Source File

kernel.c

00001 /*
00002 ** kernel.c - Kernel module
00003 **
00004 ** See Copyright Notice in mruby.h
00005 */
00006 
00007 #include "mruby.h"
00008 #include "mruby/array.h"
00009 #include "mruby/class.h"
00010 #include "mruby/proc.h"
00011 #include "mruby/string.h"
00012 #include "mruby/variable.h"
00013 #include "mruby/error.h"
00014 
00015 typedef enum {
00016   NOEX_PUBLIC    = 0x00,
00017   NOEX_NOSUPER   = 0x01,
00018   NOEX_PRIVATE   = 0x02,
00019   NOEX_PROTECTED = 0x04,
00020   NOEX_MASK      = 0x06,
00021   NOEX_BASIC     = 0x08,
00022   NOEX_UNDEF     = NOEX_NOSUPER,
00023   NOEX_MODFUNC   = 0x12,
00024   NOEX_SUPER     = 0x20,
00025   NOEX_VCALL     = 0x40,
00026   NOEX_RESPONDS  = 0x80
00027 } mrb_method_flag_t;
00028 
00029 static mrb_bool
00030 mrb_obj_basic_to_s_p(mrb_state *mrb, mrb_value obj)
00031 {
00032   struct RProc *me = mrb_method_search(mrb, mrb_class(mrb, obj), mrb_intern_lit(mrb, "to_s"));
00033   if (MRB_PROC_CFUNC_P(me) && (me->body.func == mrb_any_to_s))
00034     return TRUE;
00035   return FALSE;
00036 }
00037 
00038 /* 15.3.1.3.17 */
00039 /*
00040  *  call-seq:
00041  *     obj.inspect   -> string
00042  *
00043  *  Returns a string containing a human-readable representation of
00044  *  <i>obj</i>. If not overridden and no instance variables, uses the
00045  *  <code>to_s</code> method to generate the string.
00046  *  <i>obj</i>.  If not overridden, uses the <code>to_s</code> method to
00047  *  generate the string.
00048  *
00049  *     [ 1, 2, 3..4, 'five' ].inspect   #=> "[1, 2, 3..4, \"five\"]"
00050  *     Time.new.inspect                 #=> "2008-03-08 19:43:39 +0900"
00051  */
00052 MRB_API mrb_value
00053 mrb_obj_inspect(mrb_state *mrb, mrb_value obj)
00054 {
00055   if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) {
00056     return mrb_obj_iv_inspect(mrb, mrb_obj_ptr(obj));
00057   }
00058   return mrb_any_to_s(mrb, obj);
00059 }
00060 
00061 /* 15.3.1.3.1  */
00062 /* 15.3.1.3.10 */
00063 /* 15.3.1.3.11 */
00064 /*
00065  *  call-seq:
00066  *     obj == other        -> true or false
00067  *     obj.equal?(other)   -> true or false
00068  *     obj.eql?(other)     -> true or false
00069  *
00070  *  Equality---At the <code>Object</code> level, <code>==</code> returns
00071  *  <code>true</code> only if <i>obj</i> and <i>other</i> are the
00072  *  same object. Typically, this method is overridden in descendant
00073  *  classes to provide class-specific meaning.
00074  *
00075  *  Unlike <code>==</code>, the <code>equal?</code> method should never be
00076  *  overridden by subclasses: it is used to determine object identity
00077  *  (that is, <code>a.equal?(b)</code> iff <code>a</code> is the same
00078  *  object as <code>b</code>).
00079  *
00080  *  The <code>eql?</code> method returns <code>true</code> if
00081  *  <i>obj</i> and <i>anObject</i> have the same value. Used by
00082  *  <code>Hash</code> to test members for equality.  For objects of
00083  *  class <code>Object</code>, <code>eql?</code> is synonymous with
00084  *  <code>==</code>. Subclasses normally continue this tradition, but
00085  *  there are exceptions. <code>Numeric</code> types, for example,
00086  *  perform type conversion across <code>==</code>, but not across
00087  *  <code>eql?</code>, so:
00088  *
00089  *     1 == 1.0     #=> true
00090  *     1.eql? 1.0   #=> false
00091  */
00092 static mrb_value
00093 mrb_obj_equal_m(mrb_state *mrb, mrb_value self)
00094 {
00095   mrb_value arg;
00096 
00097   mrb_get_args(mrb, "o", &arg);
00098   return mrb_bool_value(mrb_obj_equal(mrb, self, arg));
00099 }
00100 
00101 static mrb_value
00102 mrb_obj_not_equal_m(mrb_state *mrb, mrb_value self)
00103 {
00104   mrb_value arg;
00105 
00106   mrb_get_args(mrb, "o", &arg);
00107   return mrb_bool_value(!mrb_equal(mrb, self, arg));
00108 }
00109 
00110 /* 15.3.1.3.2  */
00111 /*
00112  *  call-seq:
00113  *     obj === other   -> true or false
00114  *
00115  *  Case Equality---For class <code>Object</code>, effectively the same
00116  *  as calling  <code>#==</code>, but typically overridden by descendants
00117  *  to provide meaningful semantics in <code>case</code> statements.
00118  */
00119 static mrb_value
00120 mrb_equal_m(mrb_state *mrb, mrb_value self)
00121 {
00122   mrb_value arg;
00123 
00124   mrb_get_args(mrb, "o", &arg);
00125   return mrb_bool_value(mrb_equal(mrb, self, arg));
00126 }
00127 
00128 /* 15.3.1.3.3  */
00129 /* 15.3.1.3.33 */
00130 /*
00131  *  Document-method: __id__
00132  *  Document-method: object_id
00133  *
00134  *  call-seq:
00135  *     obj.__id__       -> fixnum
00136  *     obj.object_id    -> fixnum
00137  *
00138  *  Returns an integer identifier for <i>obj</i>. The same number will
00139  *  be returned on all calls to <code>id</code> for a given object, and
00140  *  no two active objects will share an id.
00141  *  <code>Object#object_id</code> is a different concept from the
00142  *  <code>:name</code> notation, which returns the symbol id of
00143  *  <code>name</code>. Replaces the deprecated <code>Object#id</code>.
00144  */
00145 static mrb_value
00146 mrb_obj_id_m(mrb_state *mrb, mrb_value self)
00147 {
00148   return mrb_fixnum_value(mrb_obj_id(self));
00149 }
00150 
00151 /* 15.3.1.2.2  */
00152 /* 15.3.1.2.5  */
00153 /* 15.3.1.3.6  */
00154 /* 15.3.1.3.25 */
00155 /*
00156  *  call-seq:
00157  *     block_given?   -> true or false
00158  *     iterator?      -> true or false
00159  *
00160  *  Returns <code>true</code> if <code>yield</code> would execute a
00161  *  block in the current context. The <code>iterator?</code> form
00162  *  is mildly deprecated.
00163  *
00164  *     def try
00165  *       if block_given?
00166  *         yield
00167  *       else
00168  *         "no block"
00169  *       end
00170  *     end
00171  *     try                  #=> "no block"
00172  *     try { "hello" }      #=> "hello"
00173  *     try do "hello" end   #=> "hello"
00174  */
00175 static mrb_value
00176 mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
00177 {
00178   mrb_callinfo *ci = mrb->c->ci;
00179   mrb_value *bp;
00180   mrb_bool given_p;
00181 
00182   bp = ci->stackent + 1;
00183   ci--;
00184   if (ci <= mrb->c->cibase) {
00185     given_p = FALSE;
00186   }
00187   else {
00188     /* block_given? called within block; check upper scope */
00189     if (ci->proc->env && ci->proc->env->stack) {
00190       given_p = !(ci->proc->env->stack == mrb->c->stbase ||
00191                   mrb_nil_p(ci->proc->env->stack[1]));
00192     }
00193     else {
00194       if (ci->argc > 0) {
00195         bp += ci->argc;
00196       }
00197       given_p = !mrb_nil_p(*bp);
00198     }
00199   }
00200 
00201   return mrb_bool_value(given_p);
00202 }
00203 
00204 /* 15.3.1.3.7  */
00205 /*
00206  *  call-seq:
00207  *     obj.class    -> class
00208  *
00209  *  Returns the class of <i>obj</i>. This method must always be
00210  *  called with an explicit receiver, as <code>class</code> is also a
00211  *  reserved word in Ruby.
00212  *
00213  *     1.class      #=> Fixnum
00214  *     self.class   #=> Object
00215  */
00216 static mrb_value
00217 mrb_obj_class_m(mrb_state *mrb, mrb_value self)
00218 {
00219   return mrb_obj_value(mrb_obj_class(mrb, self));
00220 }
00221 
00222 static struct RClass*
00223 mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
00224 {
00225   struct RClass *klass = mrb_basic_ptr(obj)->c;
00226 
00227   if (klass->tt != MRB_TT_SCLASS)
00228     return klass;
00229   else {
00230     /* copy singleton(unnamed) class */
00231     struct RClass *clone = (struct RClass*)mrb_obj_alloc(mrb, klass->tt, mrb->class_class);
00232 
00233     if ((mrb_type(obj) == MRB_TT_CLASS) ||
00234       (mrb_type(obj) == MRB_TT_SCLASS)) { /* BUILTIN_TYPE(obj) == T_CLASS */
00235       clone->c = clone;
00236     }
00237     else {
00238       clone->c = mrb_singleton_class_clone(mrb, mrb_obj_value(klass));
00239     }
00240 
00241     clone->super = klass->super;
00242     if (klass->iv) {
00243       mrb_iv_copy(mrb, mrb_obj_value(clone), mrb_obj_value(klass));
00244       mrb_obj_iv_set(mrb, (struct RObject*)clone, mrb_intern_lit(mrb, "__attached__"), obj);
00245     }
00246     if (klass->mt) {
00247       clone->mt = kh_copy(mt, mrb, klass->mt);
00248     }
00249     else {
00250       clone->mt = kh_init(mt, mrb);
00251     }
00252     clone->tt = MRB_TT_SCLASS;
00253     return clone;
00254   }
00255 }
00256 
00257 static void
00258 copy_class(mrb_state *mrb, mrb_value dst, mrb_value src)
00259 {
00260   struct RClass *dc = mrb_class_ptr(dst);
00261   struct RClass *sc = mrb_class_ptr(src);
00262   dc->mt = kh_copy(mt, mrb, sc->mt);
00263   dc->super = sc->super;
00264 }
00265 
00266 static void
00267 init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
00268 {
00269   switch (mrb_type(obj)) {
00270     case MRB_TT_CLASS:
00271     case MRB_TT_MODULE:
00272       copy_class(mrb, dest, obj);
00273       /* fall through */
00274     case MRB_TT_OBJECT:
00275     case MRB_TT_SCLASS:
00276     case MRB_TT_HASH:
00277     case MRB_TT_DATA:
00278     case MRB_TT_EXCEPTION:
00279       mrb_iv_copy(mrb, dest, obj);
00280       break;
00281 
00282     default:
00283       break;
00284   }
00285   mrb_funcall(mrb, dest, "initialize_copy", 1, obj);
00286 }
00287 
00288 /* 15.3.1.3.8  */
00289 /*
00290  *  call-seq:
00291  *     obj.clone -> an_object
00292  *
00293  *  Produces a shallow copy of <i>obj</i>---the instance variables of
00294  *  <i>obj</i> are copied, but not the objects they reference. Copies
00295  *  the frozen state of <i>obj</i>. See also the discussion
00296  *  under <code>Object#dup</code>.
00297  *
00298  *     class Klass
00299  *        attr_accessor :str
00300  *     end
00301  *     s1 = Klass.new      #=> #<Klass:0x401b3a38>
00302  *     s1.str = "Hello"    #=> "Hello"
00303  *     s2 = s1.clone       #=> #<Klass:0x401b3998 @str="Hello">
00304  *     s2.str[1,4] = "i"   #=> "i"
00305  *     s1.inspect          #=> "#<Klass:0x401b3a38 @str=\"Hi\">"
00306  *     s2.inspect          #=> "#<Klass:0x401b3998 @str=\"Hi\">"
00307  *
00308  *  This method may have class-specific behavior.  If so, that
00309  *  behavior will be documented under the #+initialize_copy+ method of
00310  *  the class.
00311  *
00312  *  Some Class(True False Nil Symbol Fixnum Float) Object  cannot clone.
00313  */
00314 MRB_API mrb_value
00315 mrb_obj_clone(mrb_state *mrb, mrb_value self)
00316 {
00317   struct RObject *p;
00318   mrb_value clone;
00319 
00320   if (mrb_immediate_p(self)) {
00321     mrb_raisef(mrb, E_TYPE_ERROR, "can't clone %S", self);
00322   }
00323   p = (struct RObject*)mrb_obj_alloc(mrb, mrb_type(self), mrb_obj_class(mrb, self));
00324   p->c = mrb_singleton_class_clone(mrb, self);
00325   clone = mrb_obj_value(p);
00326   init_copy(mrb, clone, self);
00327 
00328   return clone;
00329 }
00330 
00331 /* 15.3.1.3.9  */
00332 /*
00333  *  call-seq:
00334  *     obj.dup -> an_object
00335  *
00336  *  Produces a shallow copy of <i>obj</i>---the instance variables of
00337  *  <i>obj</i> are copied, but not the objects they reference.
00338  *  <code>dup</code> copies the frozen state of <i>obj</i>. See also
00339  *  the discussion under <code>Object#clone</code>. In general,
00340  *  <code>clone</code> and <code>dup</code> may have different semantics
00341  *  in descendant classes. While <code>clone</code> is used to duplicate
00342  *  an object, including its internal state, <code>dup</code> typically
00343  *  uses the class of the descendant object to create the new instance.
00344  *
00345  *  This method may have class-specific behavior.  If so, that
00346  *  behavior will be documented under the #+initialize_copy+ method of
00347  *  the class.
00348  */
00349 
00350 MRB_API mrb_value
00351 mrb_obj_dup(mrb_state *mrb, mrb_value obj)
00352 {
00353   struct RBasic *p;
00354   mrb_value dup;
00355 
00356   if (mrb_immediate_p(obj)) {
00357     mrb_raisef(mrb, E_TYPE_ERROR, "can't dup %S", obj);
00358   }
00359   p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
00360   dup = mrb_obj_value(p);
00361   init_copy(mrb, dup, obj);
00362 
00363   return dup;
00364 }
00365 
00366 static mrb_value
00367 mrb_obj_extend(mrb_state *mrb, mrb_int argc, mrb_value *argv, mrb_value obj)
00368 {
00369   mrb_int i;
00370 
00371   if (argc == 0) {
00372     mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments (at least 1)");
00373   }
00374   for (i = 0; i < argc; i++) {
00375     mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
00376   }
00377   while (argc--) {
00378     mrb_funcall(mrb, argv[argc], "extend_object", 1, obj);
00379     mrb_funcall(mrb, argv[argc], "extended", 1, obj);
00380   }
00381   return obj;
00382 }
00383 
00384 /* 15.3.1.3.13 */
00385 /*
00386  *  call-seq:
00387  *     obj.extend(module, ...)    -> obj
00388  *
00389  *  Adds to _obj_ the instance methods from each module given as a
00390  *  parameter.
00391  *
00392  *     module Mod
00393  *       def hello
00394  *         "Hello from Mod.\n"
00395  *       end
00396  *     end
00397  *
00398  *     class Klass
00399  *       def hello
00400  *         "Hello from Klass.\n"
00401  *       end
00402  *     end
00403  *
00404  *     k = Klass.new
00405  *     k.hello         #=> "Hello from Klass.\n"
00406  *     k.extend(Mod)   #=> #<Klass:0x401b3bc8>
00407  *     k.hello         #=> "Hello from Mod.\n"
00408  */
00409 static mrb_value
00410 mrb_obj_extend_m(mrb_state *mrb, mrb_value self)
00411 {
00412   mrb_value *argv;
00413   mrb_int argc;
00414 
00415   mrb_get_args(mrb, "*", &argv, &argc);
00416   return mrb_obj_extend(mrb, argc, argv, self);
00417 }
00418 
00419 /* 15.3.1.3.15 */
00420 /*
00421  *  call-seq:
00422  *     obj.hash    -> fixnum
00423  *
00424  *  Generates a <code>Fixnum</code> hash value for this object. This
00425  *  function must have the property that <code>a.eql?(b)</code> implies
00426  *  <code>a.hash == b.hash</code>. The hash value is used by class
00427  *  <code>Hash</code>. Any hash value that exceeds the capacity of a
00428  *  <code>Fixnum</code> will be truncated before being used.
00429  */
00430 MRB_API mrb_value
00431 mrb_obj_hash(mrb_state *mrb, mrb_value self)
00432 {
00433   return mrb_fixnum_value(mrb_obj_id(self));
00434 }
00435 
00436 /* 15.3.1.3.16 */
00437 static mrb_value
00438 mrb_obj_init_copy(mrb_state *mrb, mrb_value self)
00439 {
00440   mrb_value orig;
00441 
00442   mrb_get_args(mrb, "o", &orig);
00443   if (mrb_obj_equal(mrb, self, orig)) return self;
00444   if ((mrb_type(self) != mrb_type(orig)) || (mrb_obj_class(mrb, self) != mrb_obj_class(mrb, orig))) {
00445       mrb_raise(mrb, E_TYPE_ERROR, "initialize_copy should take same class object");
00446   }
00447   return self;
00448 }
00449 
00450 
00451 /* implementation of instance_eval */
00452 mrb_value mrb_obj_instance_eval(mrb_state*, mrb_value);
00453 
00454 MRB_API mrb_bool
00455 mrb_obj_is_instance_of(mrb_state *mrb, mrb_value obj, struct RClass* c)
00456 {
00457   if (mrb_obj_class(mrb, obj) == c) return TRUE;
00458   return FALSE;
00459 }
00460 
00461 /* 15.3.1.3.19 */
00462 /*
00463  *  call-seq:
00464  *     obj.instance_of?(class)    -> true or false
00465  *
00466  *  Returns <code>true</code> if <i>obj</i> is an instance of the given
00467  *  class. See also <code>Object#kind_of?</code>.
00468  */
00469 static mrb_value
00470 obj_is_instance_of(mrb_state *mrb, mrb_value self)
00471 {
00472   mrb_value arg;
00473 
00474   mrb_get_args(mrb, "C", &arg);
00475 
00476   return mrb_bool_value(mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg)));
00477 }
00478 
00479 /* 15.3.1.3.20 */
00480 /*
00481  *  call-seq:
00482  *     obj.instance_variable_defined?(symbol)    -> true or false
00483  *
00484  *  Returns <code>true</code> if the given instance variable is
00485  *  defined in <i>obj</i>.
00486  *
00487  *     class Fred
00488  *       def initialize(p1, p2)
00489  *         @a, @b = p1, p2
00490  *       end
00491  *     end
00492  *     fred = Fred.new('cat', 99)
00493  *     fred.instance_variable_defined?(:@a)    #=> true
00494  *     fred.instance_variable_defined?("@b")   #=> true
00495  *     fred.instance_variable_defined?("@c")   #=> false
00496  */
00497 static mrb_value
00498 mrb_obj_ivar_defined(mrb_state *mrb, mrb_value self)
00499 {
00500   mrb_sym sym;
00501 
00502   mrb_get_args(mrb, "n", &sym);
00503   mrb_iv_check(mrb, sym);
00504   return mrb_bool_value(mrb_iv_defined(mrb, self, sym));
00505 }
00506 
00507 /* 15.3.1.3.21 */
00508 /*
00509  *  call-seq:
00510  *     obj.instance_variable_get(symbol)    -> obj
00511  *
00512  *  Returns the value of the given instance variable, or nil if the
00513  *  instance variable is not set. The <code>@</code> part of the
00514  *  variable name should be included for regular instance
00515  *  variables. Throws a <code>NameError</code> exception if the
00516  *  supplied symbol is not valid as an instance variable name.
00517  *
00518  *     class Fred
00519  *       def initialize(p1, p2)
00520  *         @a, @b = p1, p2
00521  *       end
00522  *     end
00523  *     fred = Fred.new('cat', 99)
00524  *     fred.instance_variable_get(:@a)    #=> "cat"
00525  *     fred.instance_variable_get("@b")   #=> 99
00526  */
00527 static mrb_value
00528 mrb_obj_ivar_get(mrb_state *mrb, mrb_value self)
00529 {
00530   mrb_sym iv_name;
00531 
00532   mrb_get_args(mrb, "n", &iv_name);
00533   mrb_iv_check(mrb, iv_name);
00534   return mrb_iv_get(mrb, self, iv_name);
00535 }
00536 
00537 /* 15.3.1.3.22 */
00538 /*
00539  *  call-seq:
00540  *     obj.instance_variable_set(symbol, obj)    -> obj
00541  *
00542  *  Sets the instance variable names by <i>symbol</i> to
00543  *  <i>object</i>, thereby frustrating the efforts of the class's
00544  *  author to attempt to provide proper encapsulation. The variable
00545  *  did not have to exist prior to this call.
00546  *
00547  *     class Fred
00548  *       def initialize(p1, p2)
00549  *         @a, @b = p1, p2
00550  *       end
00551  *     end
00552  *     fred = Fred.new('cat', 99)
00553  *     fred.instance_variable_set(:@a, 'dog')   #=> "dog"
00554  *     fred.instance_variable_set(:@c, 'cat')   #=> "cat"
00555  *     fred.inspect                             #=> "#<Fred:0x401b3da8 @a=\"dog\", @b=99, @c=\"cat\">"
00556  */
00557 static mrb_value
00558 mrb_obj_ivar_set(mrb_state *mrb, mrb_value self)
00559 {
00560   mrb_sym iv_name;
00561   mrb_value val;
00562 
00563   mrb_get_args(mrb, "no", &iv_name, &val);
00564   mrb_iv_check(mrb, iv_name);
00565   mrb_iv_set(mrb, self, iv_name, val);
00566   return val;
00567 }
00568 
00569 /* 15.3.1.3.24 */
00570 /* 15.3.1.3.26 */
00571 /*
00572  *  call-seq:
00573  *     obj.is_a?(class)       -> true or false
00574  *     obj.kind_of?(class)    -> true or false
00575  *
00576  *  Returns <code>true</code> if <i>class</i> is the class of
00577  *  <i>obj</i>, or if <i>class</i> is one of the superclasses of
00578  *  <i>obj</i> or modules included in <i>obj</i>.
00579  *
00580  *     module M;    end
00581  *     class A
00582  *       include M
00583  *     end
00584  *     class B < A; end
00585  *     class C < B; end
00586  *     b = B.new
00587  *     b.instance_of? A   #=> false
00588  *     b.instance_of? B   #=> true
00589  *     b.instance_of? C   #=> false
00590  *     b.instance_of? M   #=> false
00591  *     b.kind_of? A       #=> true
00592  *     b.kind_of? B       #=> true
00593  *     b.kind_of? C       #=> false
00594  *     b.kind_of? M       #=> true
00595  */
00596 static mrb_value
00597 mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self)
00598 {
00599   mrb_value arg;
00600 
00601   mrb_get_args(mrb, "C", &arg);
00602 
00603   return mrb_bool_value(mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg)));
00604 }
00605 
00606 KHASH_DECLARE(st, mrb_sym, char, FALSE)
00607 KHASH_DEFINE(st, mrb_sym, char, FALSE, kh_int_hash_func, kh_int_hash_equal)
00608 
00609 static void
00610 method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set)
00611 {
00612   khint_t i;
00613 
00614   khash_t(mt) *h = klass->mt;
00615   if (!h) return;
00616   for (i=0;i<kh_end(h);i++) {
00617     if (kh_exist(h, i) && kh_value(h, i)) {
00618       kh_put(st, mrb, set, kh_key(h, i));
00619     }
00620   }
00621 }
00622 
00623 mrb_value
00624 mrb_class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj)
00625 {
00626   khint_t i;
00627   mrb_value ary;
00628   struct RClass* oldklass;
00629   khash_t(st)* set = kh_init(st, mrb);
00630 
00631   oldklass = 0;
00632   while (klass && (klass != oldklass)) {
00633     method_entry_loop(mrb, klass, set);
00634     if ((klass->tt == MRB_TT_ICLASS) ||
00635         (klass->tt == MRB_TT_SCLASS)) {
00636     }
00637     else {
00638       if (!recur) break;
00639     }
00640     oldklass = klass;
00641     klass = klass->super;
00642   }
00643 
00644   ary = mrb_ary_new(mrb);
00645   for (i=0;i<kh_end(set);i++) {
00646     if (kh_exist(set, i)) {
00647       mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
00648     }
00649   }
00650   kh_destroy(st, mrb, set);
00651 
00652   return ary;
00653 }
00654 
00655 static mrb_value
00656 mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj)
00657 {
00658   khint_t i;
00659   mrb_value ary;
00660   struct RClass* klass;
00661   khash_t(st)* set = kh_init(st, mrb);
00662 
00663   klass = mrb_class(mrb, obj);
00664 
00665   if (klass && (klass->tt == MRB_TT_SCLASS)) {
00666       method_entry_loop(mrb, klass, set);
00667       klass = klass->super;
00668   }
00669   if (recur) {
00670       while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) {
00671         method_entry_loop(mrb, klass, set);
00672         klass = klass->super;
00673       }
00674   }
00675 
00676   ary = mrb_ary_new(mrb);
00677   for (i=0;i<kh_end(set);i++) {
00678     if (kh_exist(set, i)) {
00679       mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set, i)));
00680     }
00681   }
00682   kh_destroy(st, mrb, set);
00683 
00684   return ary;
00685 }
00686 
00687 static mrb_value
00688 mrb_obj_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj, mrb_method_flag_t flag)
00689 {
00690   if (recur)
00691     return mrb_class_instance_method_list(mrb, recur, mrb_class(mrb, obj), 0);
00692   return mrb_obj_singleton_methods(mrb, recur, obj);
00693 }
00694 /* 15.3.1.3.31 */
00695 /*
00696  *  call-seq:
00697  *     obj.methods    -> array
00698  *
00699  *  Returns a list of the names of methods publicly accessible in
00700  *  <i>obj</i>. This will include all the methods accessible in
00701  *  <i>obj</i>'s ancestors.
00702  *
00703  *     class Klass
00704  *       def kMethod()
00705  *       end
00706  *     end
00707  *     k = Klass.new
00708  *     k.methods[0..9]    #=> [:kMethod, :respond_to?, :nil?, :is_a?,
00709  *                        #    :class, :instance_variable_set,
00710  *                        #    :methods, :extend, :__send__, :instance_eval]
00711  *     k.methods.length   #=> 42
00712  */
00713 static mrb_value
00714 mrb_obj_methods_m(mrb_state *mrb, mrb_value self)
00715 {
00716   mrb_bool recur = TRUE;
00717   mrb_get_args(mrb, "|b", &recur);
00718   return mrb_obj_methods(mrb, recur, self, (mrb_method_flag_t)0); /* everything but private */
00719 }
00720 
00721 /* 15.3.1.3.32 */
00722 /*
00723  * call_seq:
00724  *   nil.nil?               -> true
00725  *   <anything_else>.nil?   -> false
00726  *
00727  * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
00728  */
00729 static mrb_value
00730 mrb_false(mrb_state *mrb, mrb_value self)
00731 {
00732   return mrb_false_value();
00733 }
00734 
00735 /* 15.3.1.3.36 */
00736 /*
00737  *  call-seq:
00738  *     obj.private_methods(all=true)   -> array
00739  *
00740  *  Returns the list of private methods accessible to <i>obj</i>. If
00741  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
00742  *  in the receiver will be listed.
00743  */
00744 static mrb_value
00745 mrb_obj_private_methods(mrb_state *mrb, mrb_value self)
00746 {
00747   mrb_bool recur = TRUE;
00748   mrb_get_args(mrb, "|b", &recur);
00749   return mrb_obj_methods(mrb, recur, self, NOEX_PRIVATE); /* private attribute not define */
00750 }
00751 
00752 /* 15.3.1.3.37 */
00753 /*
00754  *  call-seq:
00755  *     obj.protected_methods(all=true)   -> array
00756  *
00757  *  Returns the list of protected methods accessible to <i>obj</i>. If
00758  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
00759  *  in the receiver will be listed.
00760  */
00761 static mrb_value
00762 mrb_obj_protected_methods(mrb_state *mrb, mrb_value self)
00763 {
00764   mrb_bool recur = TRUE;
00765   mrb_get_args(mrb, "|b", &recur);
00766   return mrb_obj_methods(mrb, recur, self, NOEX_PROTECTED); /* protected attribute not define */
00767 }
00768 
00769 /* 15.3.1.3.38 */
00770 /*
00771  *  call-seq:
00772  *     obj.public_methods(all=true)   -> array
00773  *
00774  *  Returns the list of public methods accessible to <i>obj</i>. If
00775  *  the <i>all</i> parameter is set to <code>false</code>, only those methods
00776  *  in the receiver will be listed.
00777  */
00778 static mrb_value
00779 mrb_obj_public_methods(mrb_state *mrb, mrb_value self)
00780 {
00781   mrb_bool recur = TRUE;
00782   mrb_get_args(mrb, "|b", &recur);
00783   return mrb_obj_methods(mrb, recur, self, NOEX_PUBLIC); /* public attribute not define */
00784 }
00785 
00786 /* 15.3.1.2.12  */
00787 /* 15.3.1.3.40 */
00788 /*
00789  *  call-seq:
00790  *     raise
00791  *     raise(string)
00792  *     raise(exception [, string])
00793  *
00794  *  With no arguments, raises a <code>RuntimeError</code>
00795  *  With a single +String+ argument, raises a
00796  *  +RuntimeError+ with the string as a message. Otherwise,
00797  *  the first parameter should be the name of an +Exception+
00798  *  class (or an object that returns an +Exception+ object when sent
00799  *  an +exception+ message). The optional second parameter sets the
00800  *  message associated with the exception, and the third parameter is an
00801  *  array of callback information. Exceptions are caught by the
00802  *  +rescue+ clause of <code>begin...end</code> blocks.
00803  *
00804  *     raise "Failed to create socket"
00805  *     raise ArgumentError, "No parameters", caller
00806  */
00807 MRB_API mrb_value
00808 mrb_f_raise(mrb_state *mrb, mrb_value self)
00809 {
00810   mrb_value a[2], exc;
00811   int argc;
00812 
00813 
00814   argc = mrb_get_args(mrb, "|oo", &a[0], &a[1]);
00815   switch (argc) {
00816   case 0:
00817     mrb_raise(mrb, E_RUNTIME_ERROR, "");
00818     break;
00819   case 1:
00820     a[1] = mrb_check_string_type(mrb, a[0]);
00821     if (!mrb_nil_p(a[1])) {
00822       argc = 2;
00823       a[0] = mrb_obj_value(E_RUNTIME_ERROR);
00824     }
00825     /* fall through */
00826   default:
00827     exc = mrb_make_exception(mrb, argc, a);
00828     mrb_obj_iv_set(mrb, mrb_obj_ptr(exc), mrb_intern_lit(mrb, "lastpc"), mrb_cptr_value(mrb, mrb->c->ci->pc));
00829     mrb_exc_raise(mrb, exc);
00830     break;
00831   }
00832   return mrb_nil_value();            /* not reached */
00833 }
00834 
00835 /* 15.3.1.3.41 */
00836 /*
00837  *  call-seq:
00838  *     obj.remove_instance_variable(symbol)    -> obj
00839  *
00840  *  Removes the named instance variable from <i>obj</i>, returning that
00841  *  variable's value.
00842  *
00843  *     class Dummy
00844  *       attr_reader :var
00845  *       def initialize
00846  *         @var = 99
00847  *       end
00848  *       def remove
00849  *         remove_instance_variable(:@var)
00850  *       end
00851  *     end
00852  *     d = Dummy.new
00853  *     d.var      #=> 99
00854  *     d.remove   #=> 99
00855  *     d.var      #=> nil
00856  */
00857 static mrb_value
00858 mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
00859 {
00860   mrb_sym sym;
00861   mrb_value val;
00862 
00863   mrb_get_args(mrb, "n", &sym);
00864   mrb_iv_check(mrb, sym);
00865   val = mrb_iv_remove(mrb, self, sym);
00866   if (mrb_undef_p(val)) {
00867     mrb_name_error(mrb, sym, "instance variable %S not defined", mrb_sym2str(mrb, sym));
00868   }
00869   return val;
00870 }
00871 
00872 static inline mrb_bool
00873 basic_obj_respond_to(mrb_state *mrb, mrb_value obj, mrb_sym id, int pub)
00874 {
00875   return mrb_respond_to(mrb, obj, id);
00876 }
00877 /* 15.3.1.3.43 */
00878 /*
00879  *  call-seq:
00880  *     obj.respond_to?(symbol, include_private=false) -> true or false
00881  *
00882  *  Returns +true+ if _obj_ responds to the given
00883  *  method. Private methods are included in the search only if the
00884  *  optional second parameter evaluates to +true+.
00885  *
00886  *  If the method is not implemented,
00887  *  as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
00888  *  false is returned.
00889  *
00890  *  If the method is not defined, <code>respond_to_missing?</code>
00891  *  method is called and the result is returned.
00892  */
00893 static mrb_value
00894 obj_respond_to(mrb_state *mrb, mrb_value self)
00895 {
00896   mrb_value mid;
00897   mrb_sym id, rtm_id;
00898   mrb_bool priv = FALSE, respond_to_p = TRUE;
00899 
00900   mrb_get_args(mrb, "o|b", &mid, &priv);
00901 
00902   if (mrb_symbol_p(mid)) {
00903     id = mrb_symbol(mid);
00904   }
00905   else {
00906     mrb_value tmp;
00907     if (!mrb_string_p(mid)) {
00908       tmp = mrb_check_string_type(mrb, mid);
00909       if (mrb_nil_p(tmp)) {
00910         tmp = mrb_inspect(mrb, mid);
00911         mrb_raisef(mrb, E_TYPE_ERROR, "%S is not a symbol", tmp);
00912       }
00913     }
00914     tmp = mrb_check_intern_str(mrb, mid);
00915     if (mrb_nil_p(tmp)) {
00916       respond_to_p = FALSE;
00917     }
00918     else {
00919       id = mrb_symbol(tmp);
00920     }
00921   }
00922 
00923   if (respond_to_p) {
00924     respond_to_p = basic_obj_respond_to(mrb, self, id, !priv);
00925   }
00926 
00927   if (!respond_to_p) {
00928     rtm_id = mrb_intern_lit(mrb, "respond_to_missing?");
00929     if (basic_obj_respond_to(mrb, self, rtm_id, !priv)) {
00930       mrb_value args[2];
00931       args[0] = mid;
00932       args[1] = mrb_bool_value(priv);
00933       return mrb_funcall_argv(mrb, self, rtm_id, 2, args);
00934     }
00935   }
00936   return mrb_bool_value(respond_to_p);
00937 }
00938 
00939 /* 15.3.1.3.45 */
00940 /*
00941  *  call-seq:
00942  *     obj.singleton_methods(all=true)    -> array
00943  *
00944  *  Returns an array of the names of singleton methods for <i>obj</i>.
00945  *  If the optional <i>all</i> parameter is true, the list will include
00946  *  methods in modules included in <i>obj</i>.
00947  *  Only public and protected singleton methods are returned.
00948  *
00949  *     module Other
00950  *       def three() end
00951  *     end
00952  *
00953  *     class Single
00954  *       def Single.four() end
00955  *     end
00956  *
00957  *     a = Single.new
00958  *
00959  *     def a.one()
00960  *     end
00961  *
00962  *     class << a
00963  *       include Other
00964  *       def two()
00965  *       end
00966  *     end
00967  *
00968  *     Single.singleton_methods    #=> [:four]
00969  *     a.singleton_methods(false)  #=> [:two, :one]
00970  *     a.singleton_methods         #=> [:two, :one, :three]
00971  */
00972 static mrb_value
00973 mrb_obj_singleton_methods_m(mrb_state *mrb, mrb_value self)
00974 {
00975   mrb_bool recur = TRUE;
00976   mrb_get_args(mrb, "|b", &recur);
00977   return mrb_obj_singleton_methods(mrb, recur, self);
00978 }
00979 
00980 static mrb_value
00981 mod_define_singleton_method(mrb_state *mrb, mrb_value self)
00982 {
00983   struct RProc *p;
00984   mrb_sym mid;
00985   mrb_value blk = mrb_nil_value();
00986 
00987   mrb_get_args(mrb, "n&", &mid, &blk);
00988   if (mrb_nil_p(blk)) {
00989     mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
00990   }
00991   p = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, mrb->proc_class);
00992   mrb_proc_copy(p, mrb_proc_ptr(blk));
00993   p->flags |= MRB_PROC_STRICT;
00994   mrb_define_method_raw(mrb, mrb_class_ptr(mrb_singleton_class(mrb, self)), mid, p);
00995   return mrb_symbol_value(mid);
00996 }
00997 
00998 static mrb_value
00999 mrb_obj_ceqq(mrb_state *mrb, mrb_value self)
01000 {
01001   mrb_value v;
01002   mrb_int i, len;
01003   mrb_sym eqq = mrb_intern_lit(mrb, "===");
01004   mrb_value ary = mrb_ary_splat(mrb, self);
01005 
01006   mrb_get_args(mrb, "o", &v);
01007   len = RARRAY_LEN(ary);
01008   for (i=0; i<len; i++) {
01009     mrb_value c = mrb_funcall_argv(mrb, mrb_ary_entry(ary, i), eqq, 1, &v);
01010     if (mrb_test(c)) return mrb_true_value();
01011   }
01012   return mrb_false_value();
01013 }
01014 
01015 static mrb_value
01016 mrb_local_variables(mrb_state *mrb, mrb_value self)
01017 {
01018   mrb_value ret;
01019   struct RProc *proc;
01020   struct mrb_irep *irep;
01021   size_t i;
01022 
01023   proc = mrb->c->ci[-1].proc;
01024 
01025   if (MRB_PROC_CFUNC_P(proc)) {
01026     return mrb_ary_new(mrb);
01027   }
01028 
01029   irep = proc->body.irep;
01030   if (!irep->lv) {
01031     return mrb_ary_new(mrb);
01032   }
01033   ret = mrb_ary_new_capa(mrb, irep->nlocals - 1);
01034   for (i = 0; i + 1 < irep->nlocals; ++i) {
01035     if (irep->lv[i].name) {
01036       mrb_ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));
01037     }
01038   }
01039   if (proc->env) {
01040     struct REnv *e = proc->env;
01041 
01042     while (e) {
01043       if (!MRB_PROC_CFUNC_P(mrb->c->cibase[e->cioff].proc)) {
01044         irep = mrb->c->cibase[e->cioff].proc->body.irep;
01045         if (irep->lv) {
01046           for (i = 0; i + 1 < irep->nlocals; ++i) {
01047             if (irep->lv[i].name) {
01048               mrb_ary_push(mrb, ret, mrb_symbol_value(irep->lv[i].name));
01049             }
01050           }
01051         }
01052       }
01053       e = (struct REnv*)e->c;
01054     }
01055   }
01056 
01057   return ret;
01058 }
01059 
01060 void
01061 mrb_init_kernel(mrb_state *mrb)
01062 {
01063   struct RClass *krn;
01064 
01065   krn = mrb->kernel_module = mrb_define_module(mrb, "Kernel");                                                    /* 15.3.1 */
01066   mrb_define_class_method(mrb, krn, "block_given?",         mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.2.2  */
01067   mrb_define_class_method(mrb, krn, "global_variables",     mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.2.4  */
01068   mrb_define_class_method(mrb, krn, "iterator?",            mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.2.5  */
01069   mrb_define_class_method(mrb, krn, "local_variables",      mrb_local_variables,             MRB_ARGS_NONE());    /* 15.3.1.2.7  */
01070 ;     /* 15.3.1.2.11 */
01071   mrb_define_class_method(mrb, krn, "raise",                mrb_f_raise,                     MRB_ARGS_OPT(2));    /* 15.3.1.2.12 */
01072 
01073   mrb_define_method(mrb, krn, "singleton_class",            mrb_singleton_class,             MRB_ARGS_NONE());
01074 
01075   mrb_define_method(mrb, krn, "==",                         mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.1  */
01076   mrb_define_method(mrb, krn, "!=",                         mrb_obj_not_equal_m,             MRB_ARGS_REQ(1));
01077   mrb_define_method(mrb, krn, "===",                        mrb_equal_m,                     MRB_ARGS_REQ(1));    /* 15.3.1.3.2  */
01078   mrb_define_method(mrb, krn, "__id__",                     mrb_obj_id_m,                    MRB_ARGS_NONE());    /* 15.3.1.3.3  */
01079   mrb_define_method(mrb, krn, "__send__",                   mrb_f_send,                      MRB_ARGS_ANY());     /* 15.3.1.3.4  */
01080   mrb_define_method(mrb, krn, "block_given?",               mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.3.6  */
01081   mrb_define_method(mrb, krn, "class",                      mrb_obj_class_m,                 MRB_ARGS_NONE());    /* 15.3.1.3.7  */
01082   mrb_define_method(mrb, krn, "clone",                      mrb_obj_clone,                   MRB_ARGS_NONE());    /* 15.3.1.3.8  */
01083   mrb_define_method(mrb, krn, "dup",                        mrb_obj_dup,                     MRB_ARGS_NONE());    /* 15.3.1.3.9  */
01084   mrb_define_method(mrb, krn, "eql?",                       mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.10 */
01085   mrb_define_method(mrb, krn, "equal?",                     mrb_obj_equal_m,                 MRB_ARGS_REQ(1));    /* 15.3.1.3.11 */
01086   mrb_define_method(mrb, krn, "extend",                     mrb_obj_extend_m,                MRB_ARGS_ANY());     /* 15.3.1.3.13 */
01087   mrb_define_method(mrb, krn, "global_variables",           mrb_f_global_variables,          MRB_ARGS_NONE());    /* 15.3.1.3.14 */
01088   mrb_define_method(mrb, krn, "hash",                       mrb_obj_hash,                    MRB_ARGS_NONE());    /* 15.3.1.3.15 */
01089   mrb_define_method(mrb, krn, "initialize_copy",            mrb_obj_init_copy,               MRB_ARGS_REQ(1));    /* 15.3.1.3.16 */
01090   mrb_define_method(mrb, krn, "inspect",                    mrb_obj_inspect,                 MRB_ARGS_NONE());    /* 15.3.1.3.17 */
01091   mrb_define_method(mrb, krn, "instance_eval",              mrb_obj_instance_eval,           MRB_ARGS_ANY());     /* 15.3.1.3.18 */
01092   mrb_define_method(mrb, krn, "instance_of?",               obj_is_instance_of,              MRB_ARGS_REQ(1));    /* 15.3.1.3.19 */
01093   mrb_define_method(mrb, krn, "instance_variable_defined?", mrb_obj_ivar_defined,            MRB_ARGS_REQ(1));    /* 15.3.1.3.20 */
01094   mrb_define_method(mrb, krn, "instance_variable_get",      mrb_obj_ivar_get,                MRB_ARGS_REQ(1));    /* 15.3.1.3.21 */
01095   mrb_define_method(mrb, krn, "instance_variable_set",      mrb_obj_ivar_set,                MRB_ARGS_REQ(2));    /* 15.3.1.3.22 */
01096   mrb_define_method(mrb, krn, "instance_variables",         mrb_obj_instance_variables,      MRB_ARGS_NONE());    /* 15.3.1.3.23 */
01097   mrb_define_method(mrb, krn, "is_a?",                      mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.24 */
01098   mrb_define_method(mrb, krn, "iterator?",                  mrb_f_block_given_p_m,           MRB_ARGS_NONE());    /* 15.3.1.3.25 */
01099   mrb_define_method(mrb, krn, "kind_of?",                   mrb_obj_is_kind_of_m,            MRB_ARGS_REQ(1));    /* 15.3.1.3.26 */
01100   mrb_define_method(mrb, krn, "local_variables",            mrb_local_variables,             MRB_ARGS_NONE());    /* 15.3.1.3.28 */
01101   mrb_define_method(mrb, krn, "methods",                    mrb_obj_methods_m,               MRB_ARGS_OPT(1));    /* 15.3.1.3.31 */
01102   mrb_define_method(mrb, krn, "nil?",                       mrb_false,                       MRB_ARGS_NONE());    /* 15.3.1.3.32 */
01103   mrb_define_method(mrb, krn, "object_id",                  mrb_obj_id_m,                    MRB_ARGS_NONE());    /* 15.3.1.3.33 */
01104   mrb_define_method(mrb, krn, "private_methods",            mrb_obj_private_methods,         MRB_ARGS_OPT(1));    /* 15.3.1.3.36 */
01105   mrb_define_method(mrb, krn, "protected_methods",          mrb_obj_protected_methods,       MRB_ARGS_OPT(1));    /* 15.3.1.3.37 */
01106   mrb_define_method(mrb, krn, "public_methods",             mrb_obj_public_methods,          MRB_ARGS_OPT(1));    /* 15.3.1.3.38 */
01107   mrb_define_method(mrb, krn, "raise",                      mrb_f_raise,                     MRB_ARGS_ANY());     /* 15.3.1.3.40 */
01108   mrb_define_method(mrb, krn, "remove_instance_variable",   mrb_obj_remove_instance_variable,MRB_ARGS_REQ(1));    /* 15.3.1.3.41 */
01109   mrb_define_method(mrb, krn, "respond_to?",                obj_respond_to,                  MRB_ARGS_ANY());     /* 15.3.1.3.43 */
01110   mrb_define_method(mrb, krn, "send",                       mrb_f_send,                      MRB_ARGS_ANY());     /* 15.3.1.3.44 */
01111   mrb_define_method(mrb, krn, "singleton_methods",          mrb_obj_singleton_methods_m,     MRB_ARGS_OPT(1));    /* 15.3.1.3.45 */
01112   mrb_define_method(mrb, krn, "define_singleton_method",    mod_define_singleton_method,     MRB_ARGS_ANY());
01113   mrb_define_method(mrb, krn, "to_s",                       mrb_any_to_s,                    MRB_ARGS_NONE());    /* 15.3.1.3.46 */
01114   mrb_define_method(mrb, krn, "__case_eqq",                 mrb_obj_ceqq,                    MRB_ARGS_REQ(1));    /* internal */
01115 
01116   mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
01117   mrb_alias_method(mrb, mrb->module_class, mrb_intern_lit(mrb, "dup"), mrb_intern_lit(mrb, "clone"));
01118 }
01119