タグ (続

昨晩、ヒープオブジェクトの項で道に迷いました。
ソースを冷静に眺めると

#define SCM_HOBJP(obj)  (SCM_HPTRP(obj)&&(SCM_HTAG(obj)==7))

heap allocated object は

  • SCM_HPTRP(obj) が真
  • (SCM_HTAG(obj)==7) が真

の場合。この方法って 0.8 系でも同様
# 使ってる bit の数が違いますが
なんですが、それぞれのマクロを掘ってみると SCM_HPTRP マクロは

/* Check if the ScmObj is a pointer to either a pair or a heap
   (That is, we can safely take SCM_OBJ(obj)->tag) */
#define SCM_HPTRP(obj)   (SCM_TAG2(obj) == 0)

となってて、ケツ 2 bit が 00 なら真。で、SCM_HTAG マクロが

/* This macro further takes the lower three bits of the word pointed
   by OBJ, to distinguish whether it's a pair or a heap object. */
#define SCM_HTAG(obj)    (SCM_WORD(SCM_OBJ(obj)->tag)&7)

との事で tag 属性のケツ 3 bit が立ってたら真。ちなみに SCM_HPTRP マクロが真を戻す場合、pair 又は heap ってコメントがあるんですが、SCM_PAIRP マクロの定義が以下。

#define SCM_PAIRP(obj)          (SCM_HPTRP(obj)&&SCM_HTAG(obj)!=7)

ここは微妙にツッコミどころ (SCM_HTAG(obj)!=7 なあたり) があったりするんですが、現時点ではスルー。

ちなみに

tag なナニで grep してみたのが以下。

$ find|xargs grep '\->tag'
./gauche.h:   (That is, we can safely take SCM_OBJ(obj)->tag) */
./gauche.h:#define SCM_HTAG(obj)    (SCM_WORD(SCM_OBJ(obj)->tag)&7)
./gauche.h:# define SCM_CLASS_OF(obj)      SCM_CLASS((SCM_OBJ(obj)->tag - 7))
./gauche.h:# define SCM_SET_CLASS(obj, k)  (SCM_OBJ(obj)->tag = (ScmByte*)(k) + 7)
./gauche.h:    (SCM_HPTRP(obj)&&(SCM_OBJ(obj)->tag == SCM_CLASS2TAG(klass)))
./gauche.h:# define SCM_CLASS_OF(obj)      (*(ScmClass**)((SCM_OBJ(obj)->tag - 7)))
./gauche.h:# define SCM_SET_CLASS(obj, k)  (SCM_OBJ(obj)->tag = (ScmByte*)((k)->classPtr) + 7)

しかしこれって、

struct ScmPairRec {
    ScmObj car;                 /* should be accessed via macros */
    ScmObj cdr;                 /* ditto */
};

な定義の pair なオブジェクトのコメントが以下で

/* Ordinary pair uses two words.  It can be distinguished from
 * other heap allocated objects by checking the first word doesn't
 * have "11" in the lower bits.
 */

見分ける事が保証されてるのかなぁ。このあたりは別途色々掘じくる事にしてとりあえず_タグについて_の項を仕上げます。
# てか lower bits は "111" なのか
# あるいは上記の通りで良いのかがナニ