summaryrefslogtreecommitdiffstats
path: root/src/if_py_both.h
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2015-02-03 12:55:18 +0100
committerBram Moolenaar <Bram@vim.org>2015-02-03 12:55:18 +0100
commit2459a5ecaa43c8549ea53e9364253ff891676da5 (patch)
treeb503323856e11d0e1e47e6c81875d32b1541ee04 /src/if_py_both.h
parent4ac163ae5f137af236931e778660cf7878d70c25 (diff)
updated for version 7.4.609v7.4.609
Problem: For complicated list and dict use the garbage collector can run out of stack space. Solution: Use a stack of dicts and lists to be marked, thus making it iterative instead of recursive. (Ben Fritz)
Diffstat (limited to 'src/if_py_both.h')
-rw-r--r--src/if_py_both.h17
1 files changed, 12 insertions, 5 deletions
diff --git a/src/if_py_both.h b/src/if_py_both.h
index 206d2987a5..a46b42adda 100644
--- a/src/if_py_both.h
+++ b/src/if_py_both.h
@@ -5502,34 +5502,41 @@ run_eval(const char *cmd, typval_T *rettv
PyErr_Clear();
}
- static void
+ static int
set_ref_in_py(const int copyID)
{
pylinkedlist_T *cur;
dict_T *dd;
list_T *ll;
+ int abort = FALSE;
if (lastdict != NULL)
- for(cur = lastdict ; cur != NULL ; cur = cur->pll_prev)
+ {
+ for(cur = lastdict ; !abort && cur != NULL ; cur = cur->pll_prev)
{
dd = ((DictionaryObject *) (cur->pll_obj))->dict;
if (dd->dv_copyID != copyID)
{
dd->dv_copyID = copyID;
- set_ref_in_ht(&dd->dv_hashtab, copyID);
+ abort = abort || set_ref_in_ht(&dd->dv_hashtab, copyID, NULL);
}
}
+ }
if (lastlist != NULL)
- for(cur = lastlist ; cur != NULL ; cur = cur->pll_prev)
+ {
+ for(cur = lastlist ; !abort && cur != NULL ; cur = cur->pll_prev)
{
ll = ((ListObject *) (cur->pll_obj))->list;
if (ll->lv_copyID != copyID)
{
ll->lv_copyID = copyID;
- set_ref_in_list(ll, copyID);
+ abort = abort || set_ref_in_list(ll, copyID, NULL);
}
}
+ }
+
+ return abort;
}
static int