fix: prevent stack overflow on recursive toString for List and Map

Add `String.safeToString_` static method that tracks objects currently being
converted to string per fiber, returning "..." when recursion is detected.
Wrap List.toString and Map.toString with this guard to handle self-referential
and mutually recursive structures without crashing.
This commit is contained in:
Bob Nystrom
2015-05-03 18:13:05 +00:00
parent cd1cc07c6f
commit 898ac53f4f
4 changed files with 137 additions and 20 deletions
+25 -1
View File
@@ -24,4 +24,28 @@ IO.print(s == "{1: 2, 3: 4, 5: 6}" ||
s == "{5: 6, 1: 2, 3: 4}" ||
s == "{5: 6, 3: 4, 1: 2}") // expect: true
// TODO: Handle maps that contain themselves.
// Map that directly contains itself.
var map = {}
map["key"] = map
IO.print(map) // expect: {key: ...}
// Map that indirectly contains itself.
map = {}
map["a"] = {"b": {"c": map}}
IO.print(map) // expect: {a: {b: {c: ...}}}
// Map containing an object that calls toString on a recursive map.
class Box {
new(field) { _field = field }
toString { "box " + _field.toString }
}
map = {}
map["box"] = new Box(map)
IO.print(map) // expect: {box: box ...}
// Map containing a list containing the map.
map = {}
map["list"] = [1, map, 2]
IO.print(map) // expect: {list: [1, ..., 2]}