mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
kernel.c: prepare for new recursive inspect check
Like previous recursive `<=>` check, scan call stack to detect recursive `inspect` calls. We no longer need incomplete `_inspect` hack to pass around a hash table to record objects currently inspecting.
This commit is contained in:
@@ -12,6 +12,8 @@ void mrb_ary_decref(mrb_state*, mrb_shared_array*);
|
||||
mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
|
||||
#endif
|
||||
|
||||
mrb_bool mrb_inspect_recursive_p(mrb_state *mrb, mrb_value self);
|
||||
|
||||
#ifdef MRUBY_CLASS_H
|
||||
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
|
||||
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);
|
||||
|
||||
@@ -98,6 +98,30 @@ mrb_cmp_m(mrb_state *mrb, mrb_value self)
|
||||
return mrb_nil_value();
|
||||
}
|
||||
|
||||
static mrb_bool
|
||||
inspect_recursive_p(mrb_state *mrb, mrb_value obj, int n)
|
||||
{
|
||||
for (mrb_callinfo *ci=&mrb->c->ci[-1-n]; ci>=mrb->c->cibase; ci--) {
|
||||
if (ci->mid == MRB_SYM(inspect) &&
|
||||
mrb_obj_eq(mrb, obj, ci->stack[0])) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
mrb_bool
|
||||
mrb_inspect_recursive_p(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return inspect_recursive_p(mrb, obj, 0);
|
||||
}
|
||||
|
||||
static mrb_value
|
||||
mrb_obj_inspect_recursive_p(mrb_state *mrb, mrb_value obj)
|
||||
{
|
||||
return mrb_bool_value(inspect_recursive_p(mrb, obj, 1));
|
||||
}
|
||||
|
||||
/* 15.3.1.3.3 */
|
||||
/* 15.3.1.3.33 */
|
||||
/*
|
||||
@@ -571,6 +595,7 @@ mrb_init_kernel(mrb_state *mrb)
|
||||
mrb_define_method(mrb, krn, "__to_int", mrb_ensure_int_type, MRB_ARGS_NONE()); /* internal */
|
||||
mrb_define_method(mrb, krn, "__ENCODING__", mrb_encoding, MRB_ARGS_NONE());
|
||||
mrb_define_method(mrb, krn, "respond_to_missing?", mrb_false, MRB_ARGS_ARG(1,1));
|
||||
mrb_define_method(mrb, krn, "__inspect_recursive?", mrb_obj_inspect_recursive_p, MRB_ARGS_NONE());
|
||||
|
||||
mrb_include_module(mrb, mrb->object_class, mrb->kernel_module);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user