Edited at

vim8.0 Paritial機能のバグ修正を追ってみた

More than 1 year has passed since last update.


はじめに

vim8.0でPartial機能が追加されたことは、みなさんご存知でしょうか?http://vim-jp.org/blog/2016/09/13/vim8.0-features.html

Partial機能実装時のバグにより、いくつかのpluginに不具合が出ることになりました。今回は、バグ修正のパッチをコードリーディングしながら、バグ修正の過程を追ってみたいと思います。

これは、Vim (その2) Advent Calendar 2016のための記事です。vimのような老舗プロジェクトでもこんなことがあるんだなーと思ってネタを選びました。


何が問題だったのか

let dict = {'value': 'foo'}

function! dict.func()
return self.value
endfunction

Partialの実装後、dict.funcはdictを束縛したPartialとなりました。Partialの実装にバグがあり、dict.funcを扱っているコードの後方互換性が失われました。


修正パッチを追ってみる


patch 7.4.1580

https://github.com/vim/vim/commit/7a5c46a9df7ef01a4f6a620861c35400d5ad28d9

変更は1行だけで、pt_refcountを1で初期化しています。pt_refcountをincrement/decrementして、ゼロになったときにPartialの束縛を解放する仕組みのようですね。


patch 7.4.1581

https://github.com/vim/vim/commit/65639032bb7b17996cd255d1508a1df4ad528a1f

functionがPartialのとき、dict.funcがうまく動かないバグを修正しています。下のテストを見ると、修正の意味がわかりやすいです。

+  let dict = {"tr": function('tr', ['hello', 'h', 'H'])}

+ call assert_equal("Hello", dict.tr())


patch 7.4.1582

https://github.com/vim/vim/commit/6f2e4b36c9d9908e1cace2b1b96e2c154a837bc2

上記の問題は、まさにこの箇所で修正されました。Partialがdictを束縛していたとき、dictの引数を無視してしまったためにバグが起きた、ということのようです。

+       /* When the function has a partial with a dict and there is a dict

+ * argument, use the dict argument. That is backwards compatible.
+ */
+ if (selfdict_in == NULL)
+ selfdict = partial->pt_dict;


感想

vimのパッチを見るのは初めてで、良い経験でした。

結局3パッチしか追えず、尻切れトンボ感すみません。。。


参考

こちらの記事を参考にしています。

http://vim-jp.org/blog/2016/03/23/take-care-of-patch-1577.html