Perl日記

日々の知ったことのメモなどです。Perlは最近やってないです。

XSのlooks_like_number()

前回の続き。
XSちょっとかじった程度の僕がXSのlooks_like_number()を追ってみたメモ。

ListUtil.xs

初めの方。

MODULE=List::Util    PACKAGE=Scalar::Util
/* 略 */

int                     /* 戻り値型 */
looks_like_number(sv)   /* 関数名 */
	SV *sv         /* 引数型 */
PROTOTYPE: $            /* Perlのプロトタイプ */
CODE:                   /* コード開始 */
  SV *tempsv;           /* 変数宣言 */

次の、

  if (SvAMAGIC(sv) && (tempsv = AMG_CALLun(sv, numer))) {
    sv = tempsv;
  }

が分からない。SvAMAGIC()ってマクロだよね?
Perl自体をmake(&&install)したディレクトリへcd。
grepしてみる。

$ grep -I SvAMAGIC ./*
...
./sv.h:#define SvAMAGIC(sv)    (SvROK(sv) && (SvFLAGS(SvRV(sv)) & SVf_AMAGIC))

defineだしこれっぽいかな?
ってまた分からないマクロが。
以下のサイトを発見。ありがとうございます。
perlxstut (6) - Hackadelic Memo - ミンナニハナイショダヨ

  • SvROK : リファレンスかどうか
  • SvRV() は常に SV* を返すので SvTYPE で型を調べて適切な型にキャストする

perlxstut (6) - Hackadelic Memo - ミンナニハナイショダヨ

SVf_AMAGIC()はgrep

$ grep -I SVf_AMAGIC ./*
...
./sv.h:#define SVf_AMAGIC       0x10000000  /* has magical overloaded methods */

「魔法のオーバーロードメソッド」ビット?
オーバーロードしてるか確かめる的な何か?


うーん、まとめると、

SvAMAGIC(sv)

は、「リファレンスとかオーバーロードされてる何かを持ってたら真」って感じなの?
でも「オーバーロード」が良く分からん。
演算子だけじゃないの?、オーバーロードって。


これが真のときにもうひとつの条件が評価される。

(tempsv = AMG_CALLun(sv, numer))

さっぱりなのでgrep

$ grep -I AMG_CALLun ./*
...
./pp.h:#define AMG_CALLun(sv,meth) AMG_CALLun_var(sv,CAT2(meth,_amg))

pp.h

#define AMG_CALLun_var(sv,meth_enum) amagic_call(sv,&PL_sv_undef,  \
                                        meth_enum,AMGf_noright | AMGf_unary)
$ grep -nI amagic_call ./*
...
./embed.h:46:#define amagic_call                Perl_amagic_call
./embed.h:2456:#define amagic_call(a,b,c,d)     Perl_amagic_call(aTHX_ a,b,c,d)
$ grep -nI Perl_amagic_call ./*
...
./global.sym:34:Perl_amagic_call
./gv.c:1817:Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)

以下のサイトを発見。ありがとうございます。
はてなブログ

pTHX_ は perl.h で定義されているマクロです。インタープリタのコンテキストがどういう風になっているかを隠蔽します。
はてなブログ

gv.cということはグロブ?、かな(Perl_amagic_callの中見てもあまり分からなかった)。


あれ?

(tempsv = AMG_CALLun(sv, numer))

numerって何だ? grepしても出てこない。
わからねえ。
リファレンス関連→グロブ関連→値代入なら、デリファレンスというか、元の値を戻している動き?
それを、

    sv = tempsv;

入れなおしている、みたいな?
次の、

  else if (SvMAGICAL(sv)) {
      SvGETMAGIC(sv);
  }

では、

$ grep -nI 'define SvMAGICAL' ./*
...
./sv.h:848:#define SvMAGICAL(sv)  (SvFLAGS(sv) & (SVs_GMG|SVs_SMG|SVs_RMG))
$ grep -nI 'define SvFLAGS' ./*
./sv.h:222:#define SvFLAGS(sv)  (sv)->sv_flags

SvGETMAGICは以下のサイトを見つけた。ありがとうございます。
perlapi - perl public API の自動生成ドキュメント - perldoc.jp

SV が 'get' magic を有している場合には mg_get を起動します。
perlapi - perl public API の自動生成ドキュメント - perldoc.jp

おお、何のことだか。
とにかく「sv_flagがたってたらmg_getを起動する」、って感じなの?
「utf8フラグを落とす」みたいな意味だろうか。


こんだけなのにすごい疲れた。。



今日すごく「?」使ってるなー。


他参考:
はてなブログanney's room - ぷめも - UTF-16BE MalformedNOT_FOUND 404NOT_FOUND 404