mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
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
Generated on Tue Jul 12 2022 18:00:34 by 1.7.2