Есть ли способ получить доступ к специальным токенам в perl от XS?
В perl используются специальные токены типа __PACKAGE__
, __SUB__
, __FILE__
, __LINE__
и доступны из script.
Я могу получить значение __PACKAGE__
от XS
как HvNAME( PL_currstash )
, я полагаю.
Но как получить доступ к другим?
Есть ли специальный интерфейс для доступа ко всем из них из XS
? Например: CTX->package
, CTX->sub
и т.д.
Ответы
Ответ 1
Вы можете искать их один за другим в toke.c
для значений времени компиляции:
-
__PACKAGE__
= > HvNAME(PL_curstash)
или PL_curstname
-
__FILE__
= > CopFILE(PL_curcop)
(во время компиляции)
-
__LINE__
= > CopLINE(PL_curcop)
(во время компиляции)
-
__SUB__
= > PL_compcv
Если вам понадобятся во время выполнения, просмотрите различные поля данных, доступные в контексте caller_cx
и текущем суб (cv
). Там не существует контекстной структуры, как в попугате или perl6, а скорее в стек активных блоков контекста.
Ответ 2
Подпрограммы Perl представлены в C с типом CV
. CV
для XSUB передается в аргументе CV
:
#define XSPROTO(name) void name(pTHX_ CV* cv)
Вы можете получить имя XSUB с помощью GvNAME(CvGV(cv))
. Это особенно полезно, если вы зарегистрируете XSUB под несколькими именами, например, с ключевыми словами ALIAS
или INTERFACE
или в typemaps.
Чтобы получить текущий тайник (эквивалент __PACKAGE__
), я бы предложил использовать CvSTASH(cv)
.
__FILE__
и __LINE__
предоставляются компилятором C в качестве макроса.
Ответ 3
C, эквивалентный __FILE__
, __FILE__
.
C, эквивалентный __LINE__
, __LINE__
.
Эквивалент C99 __SUB__
равен __func__
. Раньше не было ничего стандартного.
Нет C, эквивалентного __PACKAGE__
, потому что C не имеет пространств имен.
Тем не менее, я не думаю, что вам нужна информация о текущей строке исполнения; Я думаю, вам нужна информация о подзаголовке XS. Это означает, что вы действительно запрашиваете эквивалент XS caller
.
XS-эквивалент caller
caller_cx
. Глядя на Perl_cx_dump
в scope.c
, следует дать представление о том, как использовать возвращенную структуру PERL_CONTEXT
.