Mercurial > vim
changeset 958:e88950f0d4f6 v7.0.084
updated for version 7.0-084
author | vimboss |
---|---|
date | Tue, 05 Sep 2006 10:59:47 +0000 |
parents | 3dc6072e0a25 |
children | ea15087a42cd |
files | src/eval.c src/getchar.c src/globals.h src/main.c src/version.c |
diffstat | 5 files changed, 56 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- 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; } /*
--- 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; } /*
--- a/src/globals.h +++ b/src/globals.h @@ -300,9 +300,16 @@ EXTERN except_T *caught_stack INIT(= NUL #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)
--- 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.