Is there a way to access special tokens in perl from XS?

前端 未结 3 946
一个人的身影
一个人的身影 2021-01-04 10:25

In perl special tokens like __PACKAGE__, __SUB__, __FILE__, __LINE__ exists and available from script.

I may get

相关标签:
3条回答
  • 2021-01-04 11:09

    The C equivalent to __FILE__ is __FILE__.

    The C equivalent to __LINE__ is __LINE__.

    The C99 equivalent to __SUB__ is __func__. There wasn't anything standard before.

    There's no C equivalent to __PACKAGE__ because C doesn't have namespaces.

    That said, I don't think you want information about the current line of execution; I think you want information about the XS sub's caller. That means you're actually asking for the XS equivalent of caller.

    The XS equivalent of caller is caller_cx. Looking at Perl_cx_dump in scope.c should give an idea how to use the returned PERL_CONTEXT structure.

    0 讨论(0)
  • 2021-01-04 11:17

    You can look them up one by one in toke.c for the compile-time values:

    • __PACKAGE__ => HvNAME(PL_curstash) or PL_curstname
    • __FILE__ => CopFILE(PL_curcop) (at compile-time)
    • __LINE__ => CopLINE(PL_curcop) (at compile-time)
    • __SUB__ => PL_compcv

    If you need them at run-time look at the various data fields available in the context caller_cx and current sub (cv). There's no context struct as in parrot or perl6 passed around, rather a stack of active context blocks.

    0 讨论(0)
  • 2021-01-04 11:26

    Perl subroutines are represented in C with type CV. The CV for the XSUB is passed in the cv argument:

    #define XSPROTO(name) void name(pTHX_ CV* cv)
    

    You can get the name of the XSUB with GvNAME(CvGV(cv)). This is especially useful if you register an XSUB under multiple names, for example with the ALIAS or INTERFACE keywords, or in typemaps.

    To get the current stash (__PACKAGE__ equivalent), I'd suggest to use CvSTASH(cv).

    __FILE__ and __LINE__ are provided by the C compiler as macro.

    0 讨论(0)
提交回复
热议问题