PHP の zval を読む #3
今回の記事でも GitHub における php/php-src の commit c5d10ddda394b573dfaea1380285e1dd5f3c0d50 を前提としている.
前回までで大体以下のようなことがわかってきた.
- PHP 中の値はソースコード中では zval という構造体として扱われている
- zval には値, 型, そして GC のためのリファレンスカウントなどが含まれている (ようである)
- zval での型チェックには Z_TYPE_P マクロに zval のポインタを渡して行う
- Z_TYPE_P でのマクロの返り値を IS_NULL や IS_LONG といった定数と比較して, データ型による分岐ができる
ここまで zval の型について調べてきたので, ここからは値, すなわち value メンバについて調べる.
なお, GC まわりの話は面倒だと思うので一旦避ける予定である.
今回も ./ext/standard/array.c の php_count_recursive 関数を読む.
PHP の count 関数は本来, 第二引数が COUNT_RECURSIVE なら配列を再帰的に処理するが, こんかいの説明をする上では本質的ではないので, 省略している.
PHP で count に渡された第一引数は, ここでは zval *array となっている.
例外処理と思われる部分を除けば, 本質的なのはほぼ以下の 1 行だと思われる.
この Z_ARRVAL_P を追ってみよう.
以下は ./Zend/zend_operators.h から.
zval_p (元は array) が指す値を Z_ARRVAL に渡し,
Z_ARRVAL では zval の value メンバ, さらにその中の ht というメンバを読み出している.
value メンバにはどんな値が入っていたのだろうか.
改めて zval 構造体の定義を ./Zend/zend.h で確認しよう.
value メンバの型は zvalue_value となっている.
そしてこの zvalue_value は同じく ./Zend/zend.h で定義されている.
zvalue_value は共用体なので, zval の value メンバには, これらのいずれかが格納されていることになる.
先の Z_ARRVAL では, zval は配列なので, ht メンバから HashTable という型のポインタを取り出していることになる.
次回は一旦 zval についての簡単なまとめとしようと思う.