diff options
author | Bram Moolenaar <Bram@vim.org> | 2006-09-05 10:59:47 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2006-09-05 10:59:47 +0000 |
commit | 9fecb460fea33e190904e70274345e42fb44ed52 (patch) | |
tree | ce0f4442c1bc1a78c5fe1285615e3b38341f399c | |
parent | 203335e4a9a4fb4c2d034fe950bdb12043b93f6e (diff) | |
download | vim-git-9fecb460fea33e190904e70274345e42fb44ed52.tar.gz |
updated for version 7.0-084v7.0.084
-rw-r--r-- | src/eval.c | 8 | ||||
-rw-r--r-- | src/getchar.c | 34 | ||||
-rw-r--r-- | src/globals.h | 13 | ||||
-rw-r--r-- | src/main.c | 10 | ||||
-rw-r--r-- | src/version.c | 2 |
5 files changed, 56 insertions, 11 deletions
diff --git a/src/eval.c b/src/eval.c index 162cdf4c7..5b5bfbc75 100644 --- a/src/eval.c +++ b/src/eval.c @@ -6074,6 +6074,10 @@ garbage_collect() tabpage_T *tp; #endif + /* Only do this once. */ + want_garbage_collect = FALSE; + may_garbage_collect = FALSE; + /* * 1. Go through all accessible variables and mark all lists and dicts * with copyID. @@ -9636,7 +9640,9 @@ f_garbagecollect(argvars, rettv) typval_T *argvars; typval_T *rettv; { - garbage_collect(); + /* This is postponed until we are back at the toplevel, because we may be + * using Lists and Dicts internally. E.g.: ":echo [garbagecollect()]". */ + want_garbage_collect = TRUE; } /* diff --git a/src/getchar.c b/src/getchar.c index 7d2cfd786..f840e0bd4 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -1451,7 +1451,8 @@ before_blocking() { updatescript(0); #ifdef FEAT_EVAL - garbage_collect(); + if (may_garbage_collect) + garbage_collect(); #endif } @@ -1502,6 +1503,13 @@ vgetc() int i; #endif +#ifdef FEAT_EVAL + /* Do garbage collection when garbagecollect() was called previously and + * we are now at the toplevel. */ + if (may_garbage_collect && want_garbage_collect) + garbage_collect(); +#endif + /* * If a character was put back with vungetc, it was already processed. * Return it directly. @@ -1511,13 +1519,13 @@ vgetc() c = old_char; old_char = -1; mod_mask = old_mod_mask; - return c; } - - mod_mask = 0x0; - last_recorded_len = 0; - for (;;) /* this is done twice if there are modifiers */ + else { + mod_mask = 0x0; + last_recorded_len = 0; + for (;;) /* this is done twice if there are modifiers */ + { if (mod_mask) /* no mapping after modifier has been read */ { ++no_mapping; @@ -1695,8 +1703,20 @@ vgetc() } #endif - return c; + break; + } } + +#ifdef FEAT_EVAL + /* + * In the main loop "may_garbage_collect" can be set to do garbage + * collection in the first next vgetc(). It's disabled after that to + * avoid internally used Lists and Dicts to be freed. + */ + may_garbage_collect = FALSE; +#endif + + return c; } /* diff --git a/src/globals.h b/src/globals.h index 4106742a9..b768127fd 100644 --- a/src/globals.h +++ b/src/globals.h @@ -300,9 +300,16 @@ EXTERN except_T *caught_stack INIT(= NULL); #endif #ifdef FEAT_EVAL -EXTERN scid_T current_SID INIT(= 0); /* ID of script being sourced or - was sourced to define the - current function. */ +/* Garbage collection can only take place when we are sure there are no Lists + * or Dictionaries being used internally. This is flagged with + * "may_garbage_collect" when we are at the toplevel. + * "want_garbage_collect" is set by the garbagecollect() function, which means + * we do garbage collection before waiting for a char at the toplevel. */ +EXTERN int may_garbage_collect INIT(= FALSE); +EXTERN int want_garbage_collect INIT(= FALSE); + +/* ID of script being sourced or was sourced to define the current function. */ +EXTERN scid_T current_SID INIT(= 0); #endif #if defined(FEAT_EVAL) || defined(FEAT_SYN_HL) diff --git a/src/main.c b/src/main.c index 5051adbf9..f903d06e2 100644 --- a/src/main.c +++ b/src/main.c @@ -1130,6 +1130,16 @@ main_loop(cmdwin, noexmode) */ update_curswant(); +#ifdef FEAT_EVAL + /* + * May perform garbage collection when waiting for a character, but + * only at the very toplevel. Otherwise we may be using a List or + * Dict internally somewhere. + * "may_garbage_collect" is reset in vgetc() which is invoked through + * do_exmode() and normal_cmd(). + */ + may_garbage_collect = (!cmdwin && !noexmode); +#endif /* * If we're invoked as ex, do a round of ex commands. * Otherwise, get and execute a normal mode command. diff --git a/src/version.c b/src/version.c index aeab51e4e..cac03679e 100644 --- a/src/version.c +++ b/src/version.c @@ -667,6 +667,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 84, +/**/ 83, /**/ 82, |