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:
Yukihiro "Matz" Matsumoto
2023-06-20 07:01:55 +09:00
parent 75c8ffddf5
commit e2bbf75d58
2 changed files with 27 additions and 0 deletions
+2
View File
@@ -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);
+25
View File
@@ -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);
}