我如何在Perl源代码中找到一些函数的实现?(How i can find realization of some function in Perl source?)

例如,我想查找'print'或'foreach'操作符的源代码。 我已经下载了Perl源代码,希望看到这个运算符的“真实”代码。

For example, i want to find source code for 'print' or 'foreach' operators. I have downloaded Perl source and want to see 'real' code for this operators.

最满意答案

Perl将源代码编译为名为Opcode Tree的图形。 同时,这个数据结构代表了程序的语法和控制流程。 要理解操作码,您可能需要从Illustrated Perl Guts(illguts)开始

要了解您的程序编译的Ops,您可以这样称呼它:

perl -MO=Concise script.pl - 在操作语法树中获取操作码 perl -MO=Concise,-exec script.pl选项改为按照其执行顺序排列ops。 有时,这不那么令人困惑。 perl -MO=Concise,foo script.pl - 转储foo子例程的操作。

典型的操作码看起来像:

4 <$> const[PV "007B"] s/FOLD ->5 ^ ^ ^ ^ ^ | | | | The next op in execution order | | | Flags for this op, documented e.g. in illguts. "s" is | | | scalar context. After the slash, op-specific stuff | | The actual name of the op, may list further arguments | The optype ($: unop, 2: binop, @:listop) – not really useful The op number

Ops被声明为PP(pp_const) 。 要搜索该声明,请使用ack工具 ,这是一个智能的,用Perl正则表达式递归的grep 。 要在源代码的顶级目录中搜索所有C文件和头文件,我们需要:

$ ack 'pp_const' *.c *.h

输出(这里没有颜色):

op.c 29: * points to the pp_const() function and to an SV containing the constant 30: * value. When pp_const() is executed, its job is to push that SV onto the pp_hot.c 40:PP(pp_const) opcode.h 944: Perl_pp_const, pp_proto.h 43:PERL_CALLCONV OP *Perl_pp_const(pTHX);

所以它在pp_hot.c第40行中声明。我倾向于使用vim pp_hot.c +40去那里。 然后我们看到定义:

PP(pp_const) { dVAR; dSP; XPUSHs(cSVOP_sv); RETURN; }

要理解这一点,你应该对Perl API有一个最基本的了解,也许会写一些XS。

Perl compiles the source code to a graph called the Opcode Tree. At the same time, this data structure represents the syntax and control flow of your program. To understand opcodes, you may want to start with the Illustrated Perl Guts (illguts).

To find out to what Ops your program was compiled, you call it like so:

perl -MO=Concise script.pl – to get the opcodes in their syntax tree perl -MO=Concise,-exec script.pl – the -exec option orders the ops in their execution order instead. Sometimes, this is less confusing. perl -MO=Concise,foo script.pl – dump the ops of the foo subroutine.

A typical opcode looks like:

4 <$> const[PV "007B"] s/FOLD ->5 ^ ^ ^ ^ ^ | | | | The next op in execution order | | | Flags for this op, documented e.g. in illguts. "s" is | | | scalar context. After the slash, op-specific stuff | | The actual name of the op, may list further arguments | The optype ($: unop, 2: binop, @:listop) – not really useful The op number

Ops are declared like PP(pp_const). To search for that declaration, use the ack tool, which is an intelligent, recursive grep with Perl regexes. To search all C files and headers in the top direcory of the source, we do:

$ ack 'pp_const' *.c *.h

Output (here without color):

op.c 29: * points to the pp_const() function and to an SV containing the constant 30: * value. When pp_const() is executed, its job is to push that SV onto the pp_hot.c 40:PP(pp_const) opcode.h 944: Perl_pp_const, pp_proto.h 43:PERL_CALLCONV OP *Perl_pp_const(pTHX);

So it's declared in pp_hot.c, line 40. I tend to do vim pp_hot.c +40 to go there. Then we see the definition:

PP(pp_const) { dVAR; dSP; XPUSHs(cSVOP_sv); RETURN; }

To understand this, you should get a minimal knowledge of the Perl API, and maybe write a bit of XS.

更多推荐