Skip to content

Commit f95e6f2

Browse files
committed
FEAT: handle gracefully bind with recursive data
resolves: Oldes/Rebol-issues#2278
1 parent ddad4bb commit f95e6f2

File tree

2 files changed

+18
-4
lines changed

2 files changed

+18
-4
lines changed

src/core/c-frame.c

+11-3
Original file line numberDiff line numberDiff line change
@@ -814,8 +814,7 @@
814814
REBINT *binds = WORDS_HEAD(Bind_Table); // GC safe to do here
815815
REBCNT n;
816816
REBFLG selfish = !IS_SELFLESS(frame);
817-
818-
CHECK_STACK(&n);
817+
REBVAL *val;
819818

820819
for (; NOT_END(value); value++) {
821820
if (ANY_WORD(value)) {
@@ -840,11 +839,20 @@
840839
}
841840
}
842841
}
843-
else if ((ANY_BLOCK(value) || IS_MAP(value)) && (mode & BIND_DEEP))
842+
else if ((ANY_BLOCK(value) || IS_MAP(value)) && (mode & BIND_DEEP)) {
843+
// Recursion check: (variation of: Find_Same_Block(MOLD_LOOP, value))
844+
for (val = BLK_HEAD(MOLD_LOOP); NOT_END(val); val++) {
845+
if (VAL_SERIES(val) == VAL_SERIES(value)) return;
846+
}
847+
val = Append_Value(MOLD_LOOP);
848+
Set_Block(val, VAL_SERIES(value));
844849
Bind_Block_Words(frame, VAL_BLK_DATA(value), mode);
850+
Remove_Last(MOLD_LOOP);
851+
}
845852
else if ((IS_FUNCTION(value) || IS_CLOSURE(value)) && (mode & BIND_FUNC))
846853
Bind_Block_Words(frame, BLK_HEAD(VAL_FUNC_BODY(value)), mode);
847854
}
855+
848856
}
849857

850858

src/tests/units/crash-test.r3

+7-1
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,13 @@ foreach [n s] system/schemes [
237237
obj: make object! [x: 10]
238238
blk: copy [x]
239239
append/only blk blk
240-
--assert all [error? e: try [bind block obj] e/id = 'stack-overflow]
240+
--assert all [
241+
block? try [bind blk obj]
242+
same? blk/1 blk/2/1
243+
10 == get blk/1
244+
10 == get blk/2/1
245+
10 == get blk/2/2/1
246+
]
241247

242248
===end-group===
243249

0 commit comments

Comments
 (0)