メインコンテンツまでスキップ

ついに GC の除去に成功した

地道な作業により GC を除去することができた。

w3m の GC の用途は主に、文字列と動的配列やリンクリストなどのコレクションに に使われている。

コレクションの方は量が多くないのでがんばればできる。 適宜 std::vector, std::unordered_map, std::list, std::shared_ptr などに置き換えていく。

文字列の方は、量が多いので大変。 文字列の寿命管理と長い文字列の連結用途の2つがある。 連結用途の方は、 Strcat_XXX という関数が頻出するのでわかる。 こっちは std::stringstream に置き換えて、 Strcat_XXX<< オエレーターに置き換えらえることが多い。

さらに減量

> cloc --exclude-dir=docusaurus "--match-f=\.(c|h|cpp)$" src
140 text files.
140 unique files.
0 files ignored.

github.com/AlDanial/cloc v 1.90 T=0.08 s (1664.0 files/s, 411521.6 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
C++ 65 2174 3058 23014
C/C++ Header 75 642 199 5536
-------------------------------------------------------------------------------
SUM: 140 2816 3257 28550
-------------------------------------------------------------------------------

流れで削ったので細かく覚えていないが、 前回の cloc が 36000 くらいだったのでだいぶ削った。

  • regex => std::regex
  • hash => std::unordered_map
  • GC関連 => std::shared_ptr
  • Str => std::string

機能回復が必要

動くが使える状態ではないです。 コード整理は山場を越えたので、機能回復に注力していく。 あと #if _MSC_VER 分岐をなおす。 libuv のシステムアクセス関数で置き換えることができる目論見。 当初予定していた pttylubuv 化する計画は、 ftxui で代替された。 libuv はネットワークとファイルシステムアクセスの抽象化と非同期化に対して やりなおし。

module 分け

GC と global 変数への依存があって、 機能毎に分割しづらかったのだけど、 GC の除去と global 把握ができたので分けたい。

  • (common/core) string / url / utf-8 / logger / input interface
  • (use libuv) filesystem / tcp / http / https
  • (html) parser / renderer
  • (screen) tab / buffer / follow link / history / scroll / cursor
  • (tui) global option / keyinput / keymap / command

あと、部品間の相互参照を片方向参照に改める。 app => parser => app->width のような参照を、 app => parser(app->width) のように 事前に引数化するなどして防ぐ。 header の #include を絞る。

全体のデザイン

ひとつ問題があって cookie の処理中に 受け入れますか? という モーダルダイアログに相当するものを出したい。 ネットワークサブシステムが UI にアクセスする、 しかも keyinput をジャックするという問題がある。

オリジナルでは、その場で gets するとか、新しい入力ループを開始していた。 ftxui の netsted loop で対応できるかもしれない。

この方法では、ダイアログを放置して別のタブに切り替えることができない。 なので keyinput をスタックに積んでオーバーライドするデザインを検討。

auto answer = co_await modal_input("accept cookie?(y/n)");

core ライブラリにある程度の機能を持たせる必要がある。