diff options
author | Bram Moolenaar <Bram@vim.org> | 2015-02-03 12:55:18 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2015-02-03 12:55:18 +0100 |
commit | 2459a5ecaa43c8549ea53e9364253ff891676da5 (patch) | |
tree | b503323856e11d0e1e47e6c81875d32b1541ee04 /src/if_py_both.h | |
parent | 4ac163ae5f137af236931e778660cf7878d70c25 (diff) | |
download | vim-git-2459a5ecaa43c8549ea53e9364253ff891676da5.tar.gz |
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.h | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/src/if_py_both.h b/src/if_py_both.h index 206d2987a..a46b42add 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 |