Есть ли способ получить доступ к специальным токенам в 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.