在群里第二次遇到了关于某个问题的讨论,前一次有了结果,不过隔了很久(7月份)就记不清楚了,翻了历史记录才看明白,那次之后还想着要记住呢,看来真得找个烂笔头才行。
说问题吧,两次虽然表现不一样,实质原因是相同的,
结论么,就是基于Lua标准C库自制虚拟机,要先调用call系列的API,再导入其标准库,
原因么,是这样的,比如luaopen_io导入io库,这个用到了lua_replace函数,而后者需要虚拟机的调用栈非空,所以,最简单的虚拟机就是创建虚拟机、导入标准库、解释脚本,这样就出错了——导入标准库时调用栈是空的;
因为调用栈的压栈操作是在call系列API中处理的,所以在lua_replace被直接或间接调用前,一定要call一下,当然也可自己填充调用栈,呵呵;
以前还老困惑官方实现的虚拟机为啥那么麻烦呢,用pcall或cpcall保护了那么多层,遇到这个问题,才知道,除了要在可控的安全环境中解释脚本之外,还有这个作用呀。
补充,luaL_openlibs中调用了lua_call来打开所有的标准库,用这个还是比较安全的,而且为啥不直接调用那些open函数呢,原因不言自明吧。
阅读(1590) | 评论(0) | 转发(0) |