LuaC-体面的LuaJIT兼容方式,将错误抛出到正在恢复的协同程序中

LuaC-体面的LuaJIT兼容方式,将错误抛出到正在恢复的协同程序中,lua,coroutine,Lua,Coroutine,简言之,虽然代码似乎工作得很好,但我很好奇是否存在比我目前提出的方法更少的黑客方法 假设您创建了一个协程via,然后将其从via挂起。你的程序绕着非Lua代码转了一圈,现在是时候通过恢复协程了,但是-假设Lua代码提供的参数是非常非法的,我们应该给它一个错误来表明这一点 您可能知道,除非状态当前正在运行,否则无法调用(或)。因此,状态必须恢复,但立即被错误击中 在5.3中,您将使用,提供一个延续函数,并在其中调用lua_error或luaL_error。等等 但是,唉,LuaJIT没有实现lua

简言之,虽然代码似乎工作得很好,但我很好奇是否存在比我目前提出的方法更少的黑客方法

假设您创建了一个协程via,然后将其从via挂起。你的程序绕着非Lua代码转了一圈,现在是时候通过恢复协程了,但是-假设Lua代码提供的参数是非常非法的,我们应该给它一个错误来表明这一点

您可能知道,除非状态当前正在运行,否则无法调用(或)。因此,状态必须恢复,但立即被错误击中

在5.3中,您将使用,提供一个延续函数,并在其中调用lua_error或luaL_error。等等

但是,唉,LuaJIT没有实现lua_yieldk,那么我们还有什么选择呢

  • 一次性挂钩

    假设错误消息存储在
    字符错误\u文本[256]
    中。然后我们可以在恢复之前立即绑定每个指令挂钩

    lua_sethook(L,抛出错误,lua_MASKCOUNT,1);
    int result=lua_resume(L,NULL,ret_计数);
    
    然后解开钩子,在那里抛出一个错误

    void-throw\u错误(lua\u状态*L,lua\u调试*ar){
    lua_sethook(L,抛出错误,0,0);
    if(error_text==nullptr)return;//不要相信任何人,尤其是你自己
    luaL_错误(L,“%s”,错误文本);
    }
    
    如果需要清理字符串,您当然更愿意在调用
    \u error
    之前将
    error\u text
    连接到
    luaL\u where(L,1)
    中,因为
    lua\u error
    luaL\u error
    都做了一个跳远,因此将是您的函数做的最后一件事

  • 侧边包装纸

    假设您决定在这上面拉一个类似node.js的代码,并让您的C代码恢复一个
    错误,结果
    对,这样您就可以有这样一个包装器函数

    函数部分(arg)
    局部e,r=一些本地(arg)
    如果(e)那么
    错误(e)
    其他的
    返回r
    结束
    结束
    
    或者完全重构API,以便使用相同的模式处理错误,但这是另一天的故事

  • 两个选项中,选项1似乎不那么老套

    选项2似乎不太可能引起任何麻烦


    我忍不住觉得有一种更好的方法可以做到这一点,但我忽略了(毕竟,
    lua_yieldk
    是一个相对较新的添加)。

    好的返回
    nil
    +错误消息方法如何?为了清楚起见,这是否适用于像选项2这样的包装器lua函数?如果以这种方式抛出错误,我将无法在C端/恢复之前执行此操作,因为这是一个不受保护的区域,Lua将抛出“恐慌”,而不是将状态设置为错误模式;也许你可以发布一个简单的例子来说明你想让你的代码做什么?我在开头的段落中解释过-Lua代码调用一个C闭包,它挂起Lua状态,然后恢复它。问题是在状态恢复时将错误抛出(请参阅:问题的其余部分)。