gpt4 book ai didi

c - 如何在尾调用中保留 Lua 函数闭包?

转载 作者:太空宇宙 更新时间:2023-11-03 23:43:28 25 4
gpt4 key购买 nike

在 Lua 中,一个 C closure使用函数指针和附加值 (upvalues) 创建,这些值在调用闭包时可用。

在我的应用程序中,我使用此功能将 getter 方法表传递给 __index 元方法。如果键作为方法存在,则将调用它,并传递其原始参数。如果我直接调用该函数,那么上值仍可用于被调用者并因此在同一个函数闭包中执行。

是否可以保留函数闭包或以某种方式删除上值?目标是在不引入显着开销的情况下减少不必要的上值暴露。

这是一个 MWE(42 行),它通过突出显示该问题的 TODO 演示了该问题。它目前打印 upvalue: 42 两次。预期结果是一个 upvalue: 42 和另一个 upvalue: 0(对于无效值)。

#include <stdlib.h>
#include <stdio.h>
#include <lua.h>

static void *allocfn(void *ud, void *ptr, size_t osize, size_t nsize) {
if (nsize == 0) {
free(ptr);
return NULL;
} else {
return realloc(ptr, nsize);
}
}

static int myfunc(lua_State *L) {
lua_CFunction cfunc = lua_tocfunction(L, 1);
printf("myfunc called with %p\n", cfunc);
printf("upvalue: %d\n", (int)lua_tointeger(L, lua_upvalueindex(1)));
// TODO how to drop upvalue (tail call, leaving the closure)?
return cfunc(L);
}

static int otherfunc(lua_State *L) {
printf("otherfunc called with %p\n", lua_tocfunction(L, 1));
printf("upvalue: %d\n", (int)lua_tointeger(L, lua_upvalueindex(1)));
return 0;
}

int main() {
lua_State *L = lua_newstate(allocfn, NULL);

/* Create closure for myfunc with upvalue 42. */
lua_pushinteger(L, 42);
lua_pushcclosure(L, myfunc, 1);

/* Argument 1 for myfunc. */
lua_pushcclosure(L, otherfunc, 0);

/* Invoke myfunc(otherfunc) with "42" in its closure. */
lua_call(L, 1, 0);

lua_close(L);
}

最佳答案

通过Lua调用函数,而不是直接调用C函数:

static int myfunc(lua_State *L) {
// cfunc still used for printing here
lua_CFunction cfunc = lua_tocfunction(L, 1);
printf("myfunc called with %p\n", cfunc);
printf("upvalue: %d\n", (int)lua_tointeger(L, lua_upvalueindex(1)));

// call the C function as if it was a Lua function
int stackSizeBefore = lua_gettop(L);
lua_call(L, 0, LUA_MULTRET);
return lua_gettop(L) - stackSizeBefore;
}

(注意:未经测试的代码)

关于c - 如何在尾调用中保留 Lua 函数闭包?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39821462/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com