ID (3)

さて、IDの種類を見るには、symbol.h に定義してある id_type(ID) 関数を使う。

static inline int
id_type(ID id)
{
    if (is_notop_id(id)) {
    return (int)(id&ID_SCOPE_MASK);
    }
    else {
    return -1;
    }
}

is_notop_id() の詳細はおいといて、とりあえずこれが大抵選ばれる。id&ID_SCOPE_MASK が本体。

enum ruby_id_types {
    RUBY_ID_STATIC_SYM  = 0x01,
    RUBY_ID_LOCAL       = 0x00,
    RUBY_ID_INSTANCE    = (0x01<<1),
    RUBY_ID_GLOBAL      = (0x03<<1),
    RUBY_ID_ATTRSET     = (0x04<<1),
    RUBY_ID_CONST       = (0x05<<1),
    RUBY_ID_CLASS       = (0x06<<1),
    RUBY_ID_JUNK        = (0x07<<1),
    RUBY_ID_INTERNAL    = RUBY_ID_JUNK,
    RUBY_ID_SCOPE_SHIFT = 4,
    RUBY_ID_SCOPE_MASK  = (~(~0U<<(RUBY_ID_SCOPE_SHIFT-1))<<1)
};

template/id.h.tmpl という不思議なファイルに、この定義が書いてある。RUBY_ID_SCOPE_SHIFT - 1 は 3 で、(~0U<<(RUBY_ID_SCOPE_SHIFT-1))0b1...1_1000。これの not なので 0b0...0_0111にして、1 bit ずらして 0b0...01110 が mask。あれ、type は 3bit のようだけど(id_type() で返す)、shift してるのは 4 bit だぞ?