Gauche-0.9 のタグに関するメモ
重箱のスミをツツく。
intptr_t
gauche.h 見てていきなり以下の定義で躓く。
/* * A word large enough to hold a pointer */ typedef intptr_t ScmWord;
intptr_t って何だ。無論 M-t では出てこない。grep で探してみる。
$ find /usr/include gauche |xargs grep intptr_t|grep typedef /usr/include/SDL/SDL_thread.h:typedef uintptr_t (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, /usr/include/unistd.h:typedef __intptr_t intptr_t; /usr/include/stdint.h:typedef long int intptr_t; /usr/include/stdint.h:typedef unsigned long int uintptr_t; /usr/include/stdint.h:typedef int intptr_t; /usr/include/stdint.h:typedef unsigned int uintptr_t; /usr/include/cucul_types.h:typedef long int _cucul_intptr_t; /usr/include/cucul_types.h:typedef unsigned long int _cucul_uintptr_t; gauche/hash.h:typedef u_long ScmHashProc(const ScmHashCore *hc, intptr_t key); gauche/hash.h:typedef int ScmHashCompareProc(const ScmHashCore *hc, intptr_t key, gauche/treemap.h:typedef int ScmTreeCoreCompareProc(ScmTreeCore*, intptr_t, intptr_t); $
どうやら stdint.h らしい。これを include してるのは gauche/int64.h なのを grep で探して、その int64.h は gauche.h で include されてるのを確認。
int64.h での定義が以下。
/* Types for `void *' pointers. */ #if __WORDSIZE == 64 # ifndef __intptr_t_defined typedef long int intptr_t; # define __intptr_t_defined # endif typedef unsigned long int uintptr_t; #else # ifndef __intptr_t_defined typedef int intptr_t; # define __intptr_t_defined # endif typedef unsigned int uintptr_t; #endif
BASIC TYPES
順に
/* * A word large enough to hold a pointer */ typedef intptr_t ScmWord;
ポインタをナニするのに十分でかい word
/* * A byte */ typedef unsigned char ScmByte; /* * A character. */ typedef long ScmChar;
byte とか character とか。以下は一番てっぺんの抽象オブジェクト
/* * An opaque pointer. All Scheme objects are represented by * this type. */ typedef struct ScmHeaderRec *ScmObj;
ScmHeaderRec 構造体の定義は同じ gauche.h にて以下。
/* A common header for heap-allocated objects */ typedef struct ScmHeaderRec { ScmByte *tag; /* private. should be accessed only via SCM_CLASS_OF and SCM_SET_CLASS macros. */ } ScmHeader; #define SCM_HEADER ScmHeader hdr /* for declaration */
heap-allocated なオブジェクトの共通なナニ。アクセサは以下との事。
/* Extract the class pointer from the tag. You can use these only if SCM_HOBJP(obj) != FALSE */ # define SCM_CLASS_OF(obj) SCM_CLASS((SCM_OBJ(obj)->tag - 7)) # define SCM_SET_CLASS(obj, k) (SCM_OBJ(obj)->tag = (ScmByte*)(k) + 7)
これって、reading Gauche で_クラスタグ_と呼んでるナニですな。0.8 系は以下な記述でした (0.8.7)
/* Extract the class pointer from the tag. You can use these only if SCM_HOBJP(obj) != FALSE */ #define SCM_CLASS_OF(obj) SCM_CLASS((SCM_OBJ(obj)->tag - 3)) #define SCM_SET_CLASS(obj, k) (SCM_OBJ(obj)->tag = (ScmByte*)(k) + 3)
2-bit から 3-bit になってるのが分かります。がしかし、ここはとりあえずこのあたりでスルー。
Gauche-0.9 でのタグなソレ
gauche.h での定義が以下。
/* * PRIMARY TAG IDENTIFICATION */ #define SCM_TAG1(obj) (SCM_WORD(obj) & 0x01) #define SCM_TAG2(obj) (SCM_WORD(obj) & 0x03) #define SCM_TAG3(obj) (SCM_WORD(obj) & 0x07) #define SCM_TAG8(obj) (SCM_WORD(obj) & 0xff)
1, 2, 3, 8 bit なマスクの定義。気になったのはコメントでは 0x01 なマスクに関する記述が無かった事だったりして。とは言え以下ですぐ出てきます。てかここでしか出てこないみたい。
/* Check if the ScmObj is a 'pointer'---either to a pair, a heap object, or a ScmFlonum. */ #define SCM_PTRP(obj) (SCM_TAG1(obj) == 0)
SCM_TAG1 マクロが出てくるのはここだけな模様。なんでケツ 0 が_pointer_なのか、なソレはコメント参照。
/* 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)
ケツ 00 は heap な ptr との事。
/* 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 属性を取り出して 7 と & とってるのは何故なのか、というあたりが微妙。