embedvar.h
embedvar.hは、インタープリタ変数、グローバル変数の抽象化のためのヘッダです。
インタープリタ変数の抽象化
インタープリタ変数の抽象化のロジックは以下のようになっています。
#if defined(MULTIPLICITY) /* cases 2 and 3 above */ # if defined(PERL_IMPLICIT_CONTEXT) # define vTHX aTHX # else # define vTHX PERL_GET_INTERP # endif #define PL_AboveLatin1 (vTHX->IAboveLatin1) #define PL_Argv (vTHX->IArgv) #define PL_Cmd (vTHX->ICmd) #define PL_DBcontrol (vTHX->IDBcontrol) #endif
まず「MULTIPLICITY」が定義されている場合というのは、複数のインタープリタが利用できる状態であるということです。そのような場合は、インタープリタごとの変数にアクセスする必要があります。
次に、「PERL_IMPLICIT_CONTEXT」とは、暗黙のコンテキストが想定するという意味で、「Perl_」で始まる関数の第一引数に、インタープリタが渡されるということを意味します。
一般的には「MULTIPLICITY」が定義されていれば「PERL_IMPLICIT_CONTEXT」が定義されていると考えてください。
「aTHX」は次のように定義されています。
/* perl.h */ #ifdef PERL_IMPLICIT_CONTEXT # define aTHX my_perl #end
my_perlは、グローバル変数であり、インタープリタを表しています。
/* perlmain.c */ static PerlInterpreter *my_perl;
次に「PERL_IMPLICIT_CONTEXT」が定義されていない場合ですが、「PERL_GET_INTERP」は、次のように定義されていて、現在のインタープリタです。これは、グローバル変数です。
/* perl.h */ # define PERL_GET_INTERP (PL_curinterp)
/* perlvar.h */ PERLVARI(G, curinterp, PerlInterpreter *, NULL) /* currently running interpreter * (initial parent interpreter under * useithreads) */
「PERL_IMPLICT_CONTEXT」が定義されている場合は「vTHX」は「my_perl」として展開され、そうでない場合は「Gcurinterp」として展開されます。。
そして、インタープリタ変数へのアクセスですが以下のように定義されています。
#define PL_AboveLatin1 (vTHX->IAboveLatin1)
グローバル変数の抽象化
次にグローバル変数の抽象化のコードが書かれています。「PERL_GLOBAL_STRUCT」が、定義されている場合は、グローバル変数全体が、ひとつの構造体として存在しています、定義されていない場合は、通常のグローバル変数として存在しています。その二つの場合のどちらでも「PL_appctx」によって、変数にアクセスすることができます。
#if defined(PERL_GLOBAL_STRUCT) #define PL_appctx (my_vars->Gappctx) #define PL_Gappctx (my_vars->Gappctx) #endif
/* perlmain.c */ struct perl_vars *my_vars = init_global_struct();