はじめに
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