1

注意:这是关于 Perl 内部,C 代码本身的问题。

我想将 Perl 堆栈(即 SP)的内容作为数组传递给 Perl 函数。

  1. 是否有将堆栈复制到 AV 的现有方法?
  2. 如果没有,如何实现它?该数组可以是只读的。
  3. 如何将 AV 变成参考?
4

1 回答 1

4

在 pp.c 的 pp_anonlist 中找到了我要找的婴儿床

dVAR; dSP; dMARK;
const I32 items = SP - MARK;
SV * const args = MUTABLE_SV(av_make(items, MARK+1));
SPAGAIN;

mXPUSHs(newRV_noinc(args));

在我最终解决这个问题之前,我花了很多次尝试:

#define NUMARGS         (SP - (PL_stack_base + TOPMARK))

AV *
Perl_get_args(pTHX) {
    dSP;
    AV * args;

    args = av_make(NUMARGS, SP - NUMARGS + 1);

    return args;
}

这类似于 pp_anonlist,但不完全一样。dMARK 扩展为SV **mark = PL_stack_base + (*PL_markstack_ptr--). MARK 被广泛使用,但在文档中定义不明确。因为 dMARK 修改了堆栈的状态,所以它在我的函数中不可用,应该没有副作用。TOPMARK 只是 *PL_markstack_ptr,没有递减。NUMARGS 实际上SP - MARK没有副作用。

SP 指向堆栈的顶部,但 av_make() 适用于列表。所以有必要传入SP - NUMARGS以确保 av_make() 可以从堆栈中读取两个项目。为什么有必要添加一个,我不确定。

于 2014-11-13T21:53:22.647 回答