On Sun, Mar 30, 2008 at 7:17 PM, Dominique Pelle
<[EMAIL PROTECTED]> wrote:
>
> On Sun, Mar 30, 2008 at 2:17 PM, Bram Moolenaar <[EMAIL PROTECTED]> wrote:
>
>  >  Andy Wokula wrote:
>  >
>  >  > Strange bug and crash with :echo and lists,
>  >  > observed on gVim 7.1.283 (also gVim 7.0):
>  >  >
>  >  >
>  >  > let list = []
>  >  > call add(list, "abc")
>  >  > call add(list, "def")
>  >  > echo list[0]
>  >  > " ^ important
>  >  > let list = reverse(list)
>  >  > call add(list, "ghi")
>  >  > let left = list[: 1]
>  >  > let right = []
>  >  >
>  >  > " echo list[0] list[1] list[2]
>  >  > " " ^ crash, when uncommented!
>  >  >
>  >  > echo left list[2] right
>  >  > " ['abc', 'ghi'] ghi []           wrong
>  >  >
>  >  > let left = list[: 1]
>  >  >
>  >  > echo left list[2] right
>  >  > " ['def', 'abc'] ghi []           ok
>  >
>  >  I can reproduce it.  Also when it's shorter:
>  >
>  >  let list = []
>  >  call add(list, "abc")
>  >  call add(list, "def")
>  >  echo list[0]
>  >  let list = reverse(list)
>  >  call add(list, "ghi")
>  >  echo list[0] list[1] list[2]
>  >
>  >  I suspect the reference counter is wrong somewhere, possibly for the
>  >  first "echo" line.
>
>
>  I found the root cause of that bug.  The list contains a
>  cache (index in list + value) and that cache should be
>  invalidated when doing some operations on the list
>  such as:
>  - sorting the list
>  - inserting element in list
>  - removing element from list.
>
>  Also, when reversing the list, the cache index needed
>  to be updated.
>
>  Appending to the list does not need to invalidate cache.
>
>  Attached patch fixes all this.
>
>  Possible improvement: inserting or deleting element from
>  the list could get away with not invalidating the cache when
>  cached entry is before inserted/deleted element.  But it's
>  simpler and less risky to invalidate cache unconditionally
>  I think.
>
>  Cheers
>  -- Dominique


Ooop. There were 2 places where my patch invalidated the
cache and it was not needed.  Also, my cache index update
in f_reverse() was incorrect.

So I attach my patch again with updates.

-- Dominique

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Index: eval.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/eval.c,v
retrieving revision 1.248
diff -c -r1.248 eval.c
*** eval.c	20 Mar 2008 12:23:49 -0000	1.248
--- eval.c	30 Mar 2008 17:56:14 -0000
***************
*** 13955,13960 ****
--- 13955,13961 ----
  	rettv->v_type = VAR_LIST;
  	++l->lv_refcount;
      }
+     l->lv_idx = l->lv_len - l->lv_idx - 1;
  }
  
  #define SP_NOMOVE	0x01	    /* don't move cursor */
***************
*** 15202,15208 ****
  	    if (!item_compare_func_err)
  	    {
  		/* Clear the List and append the items in the sorted order. */
! 		l->lv_first = l->lv_last = NULL;
  		l->lv_len = 0;
  		for (i = 0; i < len; ++i)
  		    list_append(l, ptrs[i]);
--- 15203,15209 ----
  	    if (!item_compare_func_err)
  	    {
  		/* Clear the List and append the items in the sorted order. */
! 		l->lv_first = l->lv_last = l->lv_idx_item = NULL;
  		l->lv_len = 0;
  		for (i = 0; i < len; ++i)
  		    list_append(l, ptrs[i]);

Raspunde prin e-mail lui