2 ** kernel.c - Kernel module
4 ** See Copyright Notice in mruby.h
8 #include <mruby/array.h>
9 #include <mruby/hash.h>
10 #include <mruby/class.h>
11 #include <mruby/proc.h>
12 #include <mruby/string.h>
13 #include <mruby/variable.h>
14 #include <mruby/error.h>
15 #include <mruby/istruct.h>
16 #include <mruby/internal.h>
17 #include <mruby/presym.h>
20 mrb_func_basic_p(mrb_state
*mrb
, mrb_value obj
, mrb_sym mid
, mrb_func_t func
)
22 struct RClass
*c
= mrb_class(mrb
, obj
);
23 mrb_method_t m
= mrb_method_search_vm(mrb
, &c
, mid
);
24 const struct RProc
*p
;
26 if (MRB_METHOD_UNDEF_P(m
)) return FALSE
;
27 if (MRB_METHOD_FUNC_P(m
))
28 return MRB_METHOD_FUNC(m
) == func
;
29 p
= MRB_METHOD_PROC(m
);
30 if (MRB_PROC_CFUNC_P(p
) && (MRB_PROC_CFUNC(p
) == func
))
36 mrb_obj_basic_to_s_p(mrb_state
*mrb
, mrb_value obj
)
38 return mrb_func_basic_p(mrb
, obj
, MRB_SYM(to_s
), mrb_any_to_s
);
44 * obj.inspect -> string
46 * Returns a string containing a human-readable representation of
47 * <i>obj</i>. If not overridden and no instance variables, uses the
48 * <code>to_s</code> method to generate the string.
49 * <i>obj</i>. If not overridden, uses the <code>to_s</code> method to
50 * generate the string.
52 * [ 1, 2, 3..4, 'five' ].inspect #=> "[1, 2, 3..4, \"five\"]"
53 * Time.new.inspect #=> "2008-03-08 19:43:39 +0900"
56 mrb_obj_inspect(mrb_state
*mrb
, mrb_value obj
)
58 if (mrb_object_p(obj
) && mrb_obj_basic_to_s_p(mrb
, obj
)) {
59 return mrb_obj_iv_inspect(mrb
, mrb_obj_ptr(obj
));
61 return mrb_any_to_s(mrb
, obj
);
67 * obj === other -> true or false
69 * Case Equality---For class <code>Object</code>, effectively the same
70 * as calling <code>#==</code>, but typically overridden by descendants
71 * to provide meaningful semantics in <code>case</code> statements.
74 mrb_eqq_m(mrb_state
*mrb
, mrb_value self
)
76 mrb_value arg
= mrb_get_arg1(mrb
);
78 return mrb_bool_value(mrb_equal(mrb
, self
, arg
));
82 mrb_cmp_m(mrb_state
*mrb
, mrb_value self
)
84 mrb_value arg
= mrb_get_arg1(mrb
);
87 for (mrb_callinfo
*ci
=&mrb
->c
->ci
[-1]; ci
>=mrb
->c
->cibase
; ci
--) {
88 if (ci
->mid
== MRB_OPSYM(cmp
) &&
89 mrb_obj_eq(mrb
, self
, ci
->stack
[0]) &&
90 mrb_obj_eq(mrb
, arg
, ci
->stack
[1])) {
91 /* recursive <=> calling returns `nil` */
92 return mrb_nil_value();
96 if (mrb_equal(mrb
, self
, arg
))
97 return mrb_fixnum_value(0);
98 return mrb_nil_value();
102 inspect_recursive_p(mrb_state
*mrb
, mrb_value obj
, int n
)
104 for (mrb_callinfo
*ci
=&mrb
->c
->ci
[-1-n
]; ci
>=mrb
->c
->cibase
; ci
--) {
105 if (ci
->mid
== MRB_SYM(inspect
) &&
106 mrb_obj_eq(mrb
, obj
, ci
->stack
[0])) {
114 mrb_inspect_recursive_p(mrb_state
*mrb
, mrb_value obj
)
116 return inspect_recursive_p(mrb
, obj
, 0);
120 mrb_obj_inspect_recursive_p(mrb_state
*mrb
, mrb_value obj
)
122 return mrb_bool_value(inspect_recursive_p(mrb
, obj
, 1));
128 * Document-method: __id__
129 * Document-method: object_id
133 * obj.object_id -> int
135 * Returns an integer identifier for <i>obj</i>. The same number will
136 * be returned on all calls to <code>id</code> for a given object, and
137 * no two active objects will share an id.
138 * <code>Object#object_id</code> is a different concept from the
139 * <code>:name</code> notation, which returns the symbol id of
140 * <code>name</code>. Replaces the deprecated <code>Object#id</code>.
143 mrb_obj_id_m(mrb_state
*mrb
, mrb_value self
)
145 return mrb_fixnum_value(mrb_obj_id(self
));
149 env_bidx(struct REnv
*e
)
153 /* use saved block arg position */
154 bidx
= MRB_ENV_BIDX(e
);
155 /* bidx may be useless (e.g. define_method) */
156 if (bidx
>= MRB_ENV_LEN(e
)) return -1;
166 * block_given? -> true or false
167 * iterator? -> true or false
169 * Returns <code>true</code> if <code>yield</code> would execute a
170 * block in the current context. The <code>iterator?</code> form
171 * is mildly deprecated.
181 * try { "hello" } #=> "hello"
182 * try do "hello" end #=> "hello"
185 mrb_f_block_given_p_m(mrb_state
*mrb
, mrb_value self
)
187 mrb_callinfo
*ci
= &mrb
->c
->ci
[-1];
188 mrb_callinfo
*cibase
= mrb
->c
->cibase
;
191 struct REnv
*e
= NULL
;
192 const struct RProc
*p
;
195 /* toplevel does not have block */
196 return mrb_false_value();
199 /* search method/class/module proc */
201 if (MRB_PROC_SCOPE_P(p
)) break;
205 if (p
== NULL
) return mrb_false_value();
208 if (bidx
< 0) return mrb_false_value();
209 bp
= &e
->stack
[bidx
];
212 /* search ci corresponding to proc */
213 while (cibase
< ci
) {
214 if (ci
->proc
== p
) break;
218 /* proc is closure */
219 if (!MRB_PROC_ENV_P(p
)) return mrb_false_value();
222 if (bidx
< 0) return mrb_false_value();
223 bp
= &e
->stack
[bidx
];
225 else if ((e
= mrb_vm_ci_env(ci
)) != NULL
) {
226 /* top-level does not have block slot (always false) */
227 if (e
->stack
== mrb
->c
->stbase
) return mrb_false_value();
229 /* bidx may be useless (e.g. define_method) */
230 if (bidx
< 0) return mrb_false_value();
231 bp
= &e
->stack
[bidx
];
234 uint8_t n
= ci
->n
== 15 ? 1 : ci
->n
;
235 uint8_t k
= ci
->nk
== 15 ? 1 : ci
->nk
*2;
236 bidx
= n
+ k
+ 1; /* self + args + kargs => bidx */
237 bp
= &ci
->stack
[bidx
];
241 return mrb_false_value();
242 return mrb_true_value();
250 * Returns the class of <i>obj</i>. This method must always be
251 * called with an explicit receiver, as <code>class</code> is also a
252 * reserved word in Ruby.
254 * 1.class #=> Integer
255 * self.class #=> Object
258 mrb_obj_class_m(mrb_state
*mrb
, mrb_value self
)
260 return mrb_obj_value(mrb_obj_class(mrb
, self
));
264 mrb_obj_freeze(mrb_state
*mrb
, mrb_value self
)
266 if (!mrb_immediate_p(self
)) {
267 struct RBasic
*b
= mrb_basic_ptr(self
);
268 if (!mrb_frozen_p(b
)) {
269 MRB_SET_FROZEN_FLAG(b
);
270 if (b
->c
->tt
== MRB_TT_SCLASS
) MRB_SET_FROZEN_FLAG(b
->c
);
277 mrb_obj_frozen(mrb_state
*mrb
, mrb_value self
)
279 return mrb_bool_value(mrb_immediate_p(self
) || mrb_frozen_p(mrb_basic_ptr(self
)));
287 * Generates a <code>Integer</code> hash value for this object. This
288 * function must have the property that <code>a.eql?(b)</code> implies
289 * <code>a.hash == b.hash</code>. The hash value is used by class
290 * <code>Hash</code>. Any hash value that exceeds the capacity of a
291 * <code>Integer</code> will be truncated before being used.
294 mrb_obj_hash(mrb_state
*mrb
, mrb_value self
)
296 #ifdef MRB_USE_BIGINT
297 if (mrb_bigint_p(self
)) {
298 return mrb_bint_hash(mrb
, self
);
301 return mrb_int_value(mrb
, mrb_obj_id(self
));
306 mrb_obj_init_copy(mrb_state
*mrb
, mrb_value self
)
308 mrb_value orig
= mrb_get_arg1(mrb
);
310 if (mrb_obj_equal(mrb
, self
, orig
)) return self
;
311 if ((mrb_type(self
) != mrb_type(orig
)) || (mrb_obj_class(mrb
, self
) != mrb_obj_class(mrb
, orig
))) {
312 mrb_raise(mrb
, E_TYPE_ERROR
, "initialize_copy should take same class object");
318 mrb_obj_is_instance_of(mrb_state
*mrb
, mrb_value obj
, const struct RClass
* c
)
320 if (mrb_obj_class(mrb
, obj
) == c
) return TRUE
;
327 * obj.instance_of?(class) -> true or false
329 * Returns <code>true</code> if <i>obj</i> is an instance of the given
330 * class. See also <code>Object#kind_of?</code>.
333 obj_is_instance_of(mrb_state
*mrb
, mrb_value self
)
337 mrb_get_args(mrb
, "c", &c
);
339 return mrb_bool_value(mrb_obj_is_instance_of(mrb
, self
, c
));
346 * obj.is_a?(class) -> true or false
347 * obj.kind_of?(class) -> true or false
349 * Returns <code>true</code> if <i>class</i> is the class of
350 * <i>obj</i>, or if <i>class</i> is one of the superclasses of
351 * <i>obj</i> or modules included in <i>obj</i>.
360 * b.instance_of? A #=> false
361 * b.instance_of? B #=> true
362 * b.instance_of? C #=> false
363 * b.instance_of? M #=> false
364 * b.kind_of? A #=> true
365 * b.kind_of? B #=> true
366 * b.kind_of? C #=> false
367 * b.kind_of? M #=> true
370 mrb_obj_is_kind_of_m(mrb_state
*mrb
, mrb_value self
)
374 mrb_get_args(mrb
, "c", &c
);
376 return mrb_bool_value(mrb_obj_is_kind_of(mrb
, self
, c
));
383 * <anything_else>.nil? -> false
385 * Only the object <i>nil</i> responds <code>true</code> to <code>nil?</code>.
388 mrb_false(mrb_state
*mrb
, mrb_value self
)
390 return mrb_false_value();
399 * raise(exception [, string])
401 * With no arguments, raises a <code>RuntimeError</code>
402 * With a single +String+ argument, raises a
403 * +RuntimeError+ with the string as a message. Otherwise,
404 * the first parameter should be the name of an +Exception+
405 * class (or an object that returns an +Exception+ object when sent
406 * an +exception+ message). The optional second parameter sets the
407 * message associated with the exception, and the third parameter is an
408 * array of callback information. Exceptions are caught by the
409 * +rescue+ clause of <code>begin...end</code> blocks.
411 * raise "Failed to create socket"
412 * raise ArgumentError, "No parameters", caller
415 mrb_f_raise(mrb_state
*mrb
, mrb_value self
)
420 argc
= mrb_get_args(mrb
, "|oo", &exc
, &mesg
);
424 mrb_raise(mrb
, E_RUNTIME_ERROR
, "");
427 if (mrb_string_p(exc
)) {
429 exc
= mrb_obj_value(E_RUNTIME_ERROR
);
432 mesg
= mrb_nil_value();
436 exc
= mrb_make_exception(mrb
, exc
, mesg
);
437 mrb_exc_raise(mrb
, exc
);
440 return mrb_nil_value(); /* not reached */
446 * obj.remove_instance_variable(symbol) -> obj
448 * Removes the named instance variable from <i>obj</i>, returning that
457 * remove_instance_variable(:@var)
466 mrb_obj_remove_instance_variable(mrb_state
*mrb
, mrb_value self
)
471 mrb_get_args(mrb
, "n", &sym
);
472 mrb_iv_name_sym_check(mrb
, sym
);
473 val
= mrb_iv_remove(mrb
, self
, sym
);
474 if (mrb_undef_p(val
)) {
475 mrb_name_error(mrb
, sym
, "instance variable %n not defined", sym
);
483 * obj.respond_to?(symbol, include_private=false) -> true or false
485 * Returns +true+ if _obj_ responds to the given
486 * method. Private methods are included in the search only if the
487 * optional second parameter evaluates to +true+.
489 * If the method is not implemented,
490 * as Process.fork on Windows, File.lchmod on GNU/Linux, etc.,
493 * If the method is not defined, <code>respond_to_missing?</code>
494 * method is called and the result is returned.
497 obj_respond_to(mrb_state
*mrb
, mrb_value self
)
500 mrb_bool priv
= FALSE
, respond_to_p
;
502 mrb_get_args(mrb
, "n|b", &id
, &priv
);
503 respond_to_p
= mrb_respond_to(mrb
, self
, id
);
505 mrb_sym rtm_id
= MRB_SYM_Q(respond_to_missing
);
506 if (!mrb_func_basic_p(mrb
, self
, rtm_id
, mrb_false
)) {
508 v
= mrb_funcall_id(mrb
, self
, rtm_id
, 2, mrb_symbol_value(id
), mrb_bool_value(priv
));
509 return mrb_bool_value(mrb_bool(v
));
512 return mrb_bool_value(respond_to_p
);
516 mrb_obj_ceqq(mrb_state
*mrb
, mrb_value self
)
518 mrb_value v
= mrb_get_arg1(mrb
);
520 mrb_sym eqq
= MRB_OPSYM(eqq
);
524 if (mrb_array_p(self
)) {
527 else if (mrb_nil_p(self
)) {
528 return mrb_false_value();
530 else if (!mrb_respond_to(mrb
, self
, MRB_SYM(to_a
))) {
531 mrb_value c
= mrb_funcall_argv(mrb
, self
, eqq
, 1, &v
);
532 if (mrb_test(c
)) return mrb_true_value();
533 return mrb_false_value();
536 ary
= mrb_funcall_argv(mrb
, self
, MRB_SYM(to_a
), 0, NULL
);
537 if (mrb_nil_p(ary
)) {
538 return mrb_funcall_argv(mrb
, self
, eqq
, 1, &v
);
540 mrb_ensure_array_type(mrb
, ary
);
542 len
= RARRAY_LEN(ary
);
543 for (i
=0; i
<len
; i
++) {
544 mrb_value c
= mrb_funcall_argv(mrb
, RARRAY_PTR(ary
)[i
], eqq
, 1, &v
);
545 if (mrb_test(c
)) return mrb_true_value();
547 return mrb_false_value();
551 mrb_init_kernel(mrb_state
*mrb
)
555 mrb
->kernel_module
= krn
= mrb_define_module_id(mrb
, MRB_SYM(Kernel
)); /* 15.3.1 */
556 mrb_define_class_method_id(mrb
, krn
, MRB_SYM_Q(block_given
), mrb_f_block_given_p_m
, MRB_ARGS_NONE()); /* 15.3.1.2.2 */
557 mrb_define_class_method_id(mrb
, krn
, MRB_SYM_Q(iterator
), mrb_f_block_given_p_m
, MRB_ARGS_NONE()); /* 15.3.1.2.5 */
558 mrb_define_class_method_id(mrb
, krn
, MRB_SYM(raise
), mrb_f_raise
, MRB_ARGS_OPT(2)); /* 15.3.1.2.12 */
560 mrb_define_method_id(mrb
, krn
, MRB_OPSYM(eqq
), mrb_eqq_m
, MRB_ARGS_REQ(1)); /* 15.3.1.3.2 */
561 mrb_define_method_id(mrb
, krn
, MRB_OPSYM(cmp
), mrb_cmp_m
, MRB_ARGS_REQ(1));
562 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(block_given
), mrb_f_block_given_p_m
, MRB_ARGS_NONE()); /* 15.3.1.3.6 */
563 mrb_define_method_id(mrb
, krn
, MRB_SYM(class), mrb_obj_class_m
, MRB_ARGS_NONE()); /* 15.3.1.3.7 */
564 mrb_define_method_id(mrb
, krn
, MRB_SYM(clone
), mrb_obj_clone
, MRB_ARGS_NONE()); /* 15.3.1.3.8 */
565 mrb_define_method_id(mrb
, krn
, MRB_SYM(dup
), mrb_obj_dup
, MRB_ARGS_NONE()); /* 15.3.1.3.9 */
566 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(eql
), mrb_obj_equal_m
, MRB_ARGS_REQ(1)); /* 15.3.1.3.10 */
567 mrb_define_method_id(mrb
, krn
, MRB_SYM(freeze
), mrb_obj_freeze
, MRB_ARGS_NONE());
568 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(frozen
), mrb_obj_frozen
, MRB_ARGS_NONE());
569 mrb_define_method_id(mrb
, krn
, MRB_SYM(hash
), mrb_obj_hash
, MRB_ARGS_NONE()); /* 15.3.1.3.15 */
570 mrb_define_method_id(mrb
, krn
, MRB_SYM(initialize_copy
), mrb_obj_init_copy
, MRB_ARGS_REQ(1)); /* 15.3.1.3.16 */
571 mrb_define_method_id(mrb
, krn
, MRB_SYM(inspect
), mrb_obj_inspect
, MRB_ARGS_NONE()); /* 15.3.1.3.17 */
572 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(instance_of
), obj_is_instance_of
, MRB_ARGS_REQ(1)); /* 15.3.1.3.19 */
574 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(is_a
), mrb_obj_is_kind_of_m
, MRB_ARGS_REQ(1)); /* 15.3.1.3.24 */
575 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(iterator
), mrb_f_block_given_p_m
, MRB_ARGS_NONE()); /* 15.3.1.3.25 */
576 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(kind_of
), mrb_obj_is_kind_of_m
, MRB_ARGS_REQ(1)); /* 15.3.1.3.26 */
577 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(nil
), mrb_false
, MRB_ARGS_NONE()); /* 15.3.1.3.32 */
578 mrb_define_method_id(mrb
, krn
, MRB_SYM(object_id
), mrb_obj_id_m
, MRB_ARGS_NONE()); /* 15.3.1.3.33 */
579 mrb_define_method_id(mrb
, krn
, MRB_SYM(raise
), mrb_f_raise
, MRB_ARGS_ANY()); /* 15.3.1.3.40 */
580 mrb_define_method_id(mrb
, krn
, MRB_SYM(remove_instance_variable
), mrb_obj_remove_instance_variable
,MRB_ARGS_REQ(1)); /* 15.3.1.3.41 */
581 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(respond_to
), obj_respond_to
, MRB_ARGS_ARG(1,1)); /* 15.3.1.3.43 */
582 mrb_define_method_id(mrb
, krn
, MRB_SYM(to_s
), mrb_any_to_s
, MRB_ARGS_NONE()); /* 15.3.1.3.46 */
583 mrb_define_method_id(mrb
, krn
, MRB_SYM(__case_eqq
), mrb_obj_ceqq
, MRB_ARGS_REQ(1)); /* internal */
584 mrb_define_method_id(mrb
, krn
, MRB_SYM(__to_int
), mrb_ensure_int_type
, MRB_ARGS_NONE()); /* internal */
585 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(respond_to_missing
), mrb_false
, MRB_ARGS_ARG(1,1));
586 mrb_define_method_id(mrb
, krn
, MRB_SYM_Q(__inspect_recursive
), mrb_obj_inspect_recursive_p
, MRB_ARGS_NONE());
588 mrb_include_module(mrb
, mrb
->object_class
, mrb
->kernel_module
);