Skip to content

Commit 2735340

Browse files
matzclaude
andcommitted
kernel.c: remove mrb_inspect_recursive_p(); #5531
And use mrb_recursive_method_p() and its helper methods. Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5ca2d44 commit 2735340

7 files changed

Lines changed: 5 additions & 70 deletions

File tree

include/mruby/internal.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ void mrb_ary_decref(mrb_state*, mrb_shared_array*);
1212
mrb_value mrb_ary_subseq(mrb_state *mrb, mrb_value ary, mrb_int beg, mrb_int len);
1313
#endif
1414

15-
mrb_bool mrb_inspect_recursive_p(mrb_state *mrb, mrb_value self);
16-
1715
#ifdef MRUBY_CLASS_H
1816
struct RClass *mrb_vm_define_class(mrb_state*, mrb_value, mrb_value, mrb_sym);
1917
struct RClass *mrb_vm_define_module(mrb_state*, mrb_value, mrb_sym);

mrbgems/mruby-set/src/set.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,7 @@ set_inspect(mrb_state *mrb, mrb_value self)
13801380
}
13811381

13821382
/* Handle recursive inspection */
1383-
if (mrb_inspect_recursive_p(mrb, self)) {
1383+
if (MRB_RECURSIVE_UNARY_P(mrb, MRB_SYM(inspect), self)) {
13841384
return mrb_format(mrb, "%s[...]", classname);
13851385
}
13861386

mrbgems/mruby-struct/src/struct.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -647,7 +647,7 @@ mrb_struct_to_s(mrb_state *mrb, mrb_value self)
647647
mrb_str_cat_str(mrb, ret, cname);
648648
mrb_str_cat_lit(mrb, ret, " ");
649649
}
650-
if (mrb_inspect_recursive_p(mrb, self)) {
650+
if (MRB_RECURSIVE_UNARY_P(mrb, MRB_SYM(inspect), self)) {
651651
mrb_str_cat_lit(mrb, ret, "...>");
652652
return ret;
653653
}

src/array.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1626,7 +1626,7 @@ mrb_ary_to_s(mrb_state *mrb, mrb_value self)
16261626
mrb->c->ci->mid = MRB_SYM(inspect);
16271627
mrb_value ret = mrb_str_new_lit(mrb, "[");
16281628
int ai = mrb_gc_arena_save(mrb);
1629-
if (mrb_inspect_recursive_p(mrb, self)) {
1629+
if (MRB_RECURSIVE_UNARY_P(mrb, MRB_SYM(inspect), self)) {
16301630
mrb_str_cat_lit(mrb, ret, "...]");
16311631
return ret;
16321632
}

src/hash.c

Lines changed: 1 addition & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,7 +2032,7 @@ mrb_hash_to_s(mrb_state *mrb, mrb_value self)
20322032
mrb->c->ci->mid = MRB_SYM(inspect);
20332033
mrb_value ret = mrb_str_new_lit(mrb, "{");
20342034
int ai = mrb_gc_arena_save(mrb);
2035-
if (mrb_inspect_recursive_p(mrb, self)) {
2035+
if (MRB_RECURSIVE_UNARY_P(mrb, MRB_SYM(inspect), self)) {
20362036
mrb_str_cat_lit(mrb, ret, "...}");
20372037
return ret;
20382038
}
@@ -2125,62 +2125,6 @@ mrb_hash_rassoc(mrb_state *mrb, mrb_value hash)
21252125
return mrb_nil_value();
21262126
}
21272127

2128-
/*
2129-
* Hash recursion detection for equality comparison
2130-
*
2131-
* This implements a memory-efficient recursion detection mechanism for Hash#== and Hash#eql?
2132-
* to prevent SystemStackError when comparing mutually recursive hash structures.
2133-
*
2134-
* Background:
2135-
* - Issue: Hash#eql? caused infinite recursion and stack overflow with recursive hashes
2136-
* - Example: a = {}; b = {}; a[:self] = a; a[:other] = b; b[:self] = b; b[:other] = a; a.eql?(b)
2137-
*
2138-
* Solution:
2139-
* - Uses call stack inspection (similar to inspect_recursive_p) to detect recursion
2140-
* - Minimal memory overhead - examines existing call frames without additional storage
2141-
* - Returns FALSE when recursion detected (conservative approach for mruby's constraints)
2142-
* - Preserves all normal equality behavior for non-recursive cases
2143-
*
2144-
* Design considerations:
2145-
* - Memory > Performance > Readability (mruby design priority)
2146-
* - Compatible with mruby's embedded/memory-constrained environment
2147-
* - Uses established pattern from kernel.c inspect_recursive_p implementation
2148-
*/
2149-
2150-
static mrb_bool
2151-
hash_eql_recursive_p(mrb_state *mrb, mrb_value obj)
2152-
{
2153-
/* Look for recursive eql? calls on the same object in the call stack
2154-
* Start from ci[-2] to skip current call frame (ci[-1] is __eql_recursive_p?, ci[0] is eql?)
2155-
*/
2156-
for (mrb_callinfo *ci=&mrb->c->ci[-2]; ci>=mrb->c->cibase; ci--) {
2157-
if (ci->mid == MRB_SYM_Q(eql) &&
2158-
mrb_obj_eq(mrb, obj, ci->stack[0])) {
2159-
return TRUE;
2160-
}
2161-
}
2162-
return FALSE;
2163-
}
2164-
2165-
static mrb_bool
2166-
hash_equal_recursive_p(mrb_state *mrb, mrb_value obj)
2167-
{
2168-
/* Look for recursive == calls on the same object in the call stack */
2169-
for (mrb_callinfo *ci=&mrb->c->ci[-2]; ci>=mrb->c->cibase; ci--) {
2170-
if (ci->mid == MRB_OPSYM(eq) &&
2171-
mrb_obj_eq(mrb, obj, ci->stack[0])) {
2172-
return TRUE;
2173-
}
2174-
}
2175-
return FALSE;
2176-
}
2177-
2178-
static mrb_value
2179-
mrb_hash_eql_recursive_p(mrb_state *mrb, mrb_value self)
2180-
{
2181-
return mrb_bool_value(hash_eql_recursive_p(mrb, self));
2182-
}
2183-
21842128
/* 15.2.13.4.1 */
21852129
static mrb_value
21862130
mrb_hash_equal(mrb_state *mrb, mrb_value hash)
@@ -2313,5 +2257,4 @@ mrb_init_hash(mrb_state *mrb)
23132257
mrb_define_method_id(mrb, h, MRB_SYM(rassoc), mrb_hash_rassoc, MRB_ARGS_REQ(1));
23142258
mrb_define_method_id(mrb, h, MRB_SYM(__merge), mrb_hash_merge_m, MRB_ARGS_REQ(1));
23152259
mrb_define_method_id(mrb, h, MRB_SYM(__compact), mrb_hash_compact, MRB_ARGS_NONE()); /* implementation of Hash#compact! */
2316-
mrb_define_private_method_id(mrb, h, MRB_SYM_Q(__eql_recursive_p), mrb_hash_eql_recursive_p, MRB_ARGS_NONE()); /* recursion detection for Hash#eql? */
23172260
}

src/kernel.c

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,6 @@ mrb_recursive_method_p(mrb_state *mrb, mrb_sym mid, mrb_value obj1, mrb_value ob
126126
#define MRB_RECURSIVE_BINARY_P(mrb, mid, obj1, obj2) \
127127
mrb_recursive_method_p(mrb, mid, obj1, obj2)
128128

129-
mrb_bool
130-
mrb_inspect_recursive_p(mrb_state *mrb, mrb_value obj)
131-
{
132-
return MRB_RECURSIVE_UNARY_P(mrb, MRB_SYM(inspect), obj);
133-
}
134-
135129
static mrb_value
136130
mrb_obj_method_recursive_p(mrb_state *mrb, mrb_value obj)
137131
{

src/variable.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj)
636636
mrb_str_cat_lit(mrb, str, ":");
637637
mrb_str_cat_str(mrb, str, mrb_ptr_to_str(mrb, obj));
638638

639-
if (mrb_inspect_recursive_p(mrb, mrb_obj_value(obj))) {
639+
if (MRB_RECURSIVE_UNARY_P(mrb, MRB_SYM(inspect), mrb_obj_value(obj))) {
640640
mrb_str_cat_lit(mrb, str, " ...>");
641641
return str;
642642
}

0 commit comments

Comments
 (0)