perlvars.h
perlvars.hには、Perlのグローバル変数が定義されています。
/* perlvars.h */ /* global state */ #if defined(USE_ITHREADS) PERLVAR(G, op_mutex, perl_mutex) /* Mutex for op refcounting */ #endif PERLVARI(G, curinterp, PerlInterpreter *, NULL) /* currently running interpreter * (initial parent interpreter under * useithreads) */ #if defined(USE_ITHREADS) PERLVAR(G, thr_key, perl_key) /* key to retrieve per-thread struct */ #endif
Perlには、インタープリタごとに持つインタープリタ変数がありますが、それとは別にグローバル変数も存在します。たとえば、現在実行しているインタープリタ、スレッドの競合を制御するためのミューテックスなどは、グローバル変数として定義されています。
グローバル変数の宣言は、「PERLVAR」「PERLVARI」というマクロを使って記述されていま。これは「perl.h」で定義されています。
=====
/* perl.h */ /* Set up PERLVAR macros for populating structs */ # define PERLVAR(prefix,var,type) type prefix##var; /* 'var' is an array of length 'n' */ # define PERLVARA(prefix,var,n,type) type prefix##var[n]; /* initialize 'var' to init' */ # define PERLVARI(prefix,var,type,init) type prefix##var; /* like PERLVARI, but make 'var' a const */ # define PERLVARIC(prefix,var,type,init) type prefix##var;
たとえば「PERLVAR(G, op_mutex, perl_mutex)」は次のように展開されます。
perl_mutex Gop_mutex;
このグローバル変数は、ソース上で直接利用されず、「PL_op_mutex」のようにラッピングされた形でアクセスされます。
PL_op_mutex = ...;
このようにラッピングされているのは、コンパイルオプション「PERL_GLOBAL_STRUCT」によって、グローバル変数の格納方法が異なるからです。「PERL_GLOBAL_STRUCT」が定義されているが場合は、グローバル変数が構造体に格納されており、そうでない場合は、グローバル変数が直接記述されています。
この前提で「PL_op_mutex」がどのように展開されているかを見ましょう。まず「embedvar.h」より、
#if defined(PERL_GLOBAL_STRUCT) #define PL_op_mutex (my_vars->Gop_mutex) #endif
「my_vars」は、「perlmain.c」で定義されています。
/* perlmain.c */ struct perl_vars *my_vars = init_global_struct();
「perl_vars」という構造体の定義も見ておきましょう。「perlvars.h」の内容をメンバ変数として持つ構造体だということがわかります。
struct perl_vars { # include "perlvars.h" };