GH-293: Protect copy() against reference cycles.

Reference cycles shouldn't occur but there's nothing really preventing
people from creating them, so may just as well be safe and deal with
them when cloning values. While the code is a bit more cumbersome this
way, it could actually be bit faster as well as it no longer caches
non-mutable values. (I measured it with the test suite: That's about
the same in execution time, maybe tiny little bit faster now;
definitly not slower).
This commit is contained in:
Robin Sommer 2019-06-03 15:20:30 +00:00
parent 1e488d7ebe
commit 0767598771
6 changed files with 52 additions and 12 deletions

View file

@ -424,7 +424,16 @@ protected:
// For internal use by the Val::Clone() methods.
struct CloneState {
std::unordered_map<const Val*, Val*> clones;
// Caches a cloned value for later reuse during the same
// cloning operation. For recursive types, call this *before*
// descending down.
Val* NewClone(Val *src, Val* dst)
{
clones.insert(std::make_pair(src, dst));
return dst;
}
std::unordered_map<Val*, Val*> clones;
};
Val* Clone(CloneState* state);