如何将Perl堆栈转换为AV?

时间:2014-11-13 21:33:25

标签: c perl xs

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

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

  1. 是否有将堆栈复制到AV的现有方法?
  2. 如果没有,怎么会实现呢?该阵列可以是只读的。
  3. 如何将AV转换为参考?

1 个答案:

答案 0 :(得分:4)

在pp.cananlist中找到我正在寻找的婴儿床

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()可以读取堆栈中的两个项目是必要的。为什么有必要添加一个,我不确定。