| 35 | |
| 36 | 最後に抑えておきたいポイントは同一モジュールローカル領域における実体オブジェクトの存在の問題。例えば、下記のようなコードで解放しなければならないオブジェクト、おおよそ想像がつくだろうか。 |
| 37 | |
| 38 | {{{ |
| 39 | Sub Foo() |
| 40 | Dim a As Object |
| 41 | Throw "messages" |
| 42 | Dim b As Object |
| 43 | End Sub |
| 44 | }}} |
| 45 | |
| 46 | Throwされたタイミングではまだbは未確保な状態であり、それに対してデストラクタを呼ぶのは正しい処理とはいえない。しかし、aもbもFoo関数のローカル領域内にあるオブジェクトであり、Foo関数の開始時に動的型情報として専用ストレージへと蓄積される。となると、それとは別途に「これは既に確保されたオブジェクト」「こちらはまだ確保されていないオブジェクト」という具合に状況を把握しておかなければならない。これはコンストラクタ及びデストラクタ呼び出しのタイミングで拡張ストレージ情報として書き込んでいかなければならない。しかし、これをやってしまうと関数呼び出しの前後と同時に、オブジェクト生成のタイミングでもオーバーヘッドが生じてしまう。 |
| 47 | |
| 48 | ABはネイティブコンパイラであり、高速処理を謳っている数少ないBasic言語なので、このようなオーバーヘッドを生じさせてしまう実装はなるべく避けたいところ。そこで、既存のデータとして存在し、尚且つ実体オブジェクトの存在を確認できる情報はないかと考えてみる。 |
| 49 | |
| 50 | その答えは、以外な場所にある。Objectクラスだ。Objectは、AB5から実装されるクラスであり、ToStringやEquals、GetHashCodeなどの幾つかの仮想メソッドを持ち合わせる。ここで重要視したいのは、生成されるオブジェクトすべてがvtblポインタを先頭に持つこと。vtblポインタにはコンストラクタで適切なデータがセットされる。関数実行時にローカル領域をすべてクリアできると過程すれば、コンストラクタが呼び出されるまで、そのオブジェクトのvtblは0であることが保障される。それでは、解放された後の状態を知るにはどうすれば良いものか…。答えは至って単純。Objectのデストラクタにvtblに0をセットするようなコードを仕込むだけである。これで、同一モジュール内におけるオブジェクトの存在確認はクリアできる。 |