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.
--- 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,