4.4 - C代码中的错误处理
在内部,Lua使用C方法longjump来处理错误。(如果你将Lua作为C++代码编译,那么将使用C++异常;相关细节请在源码中搜索LUAI_THROW。)当Lua面对错误时,例如内存分配错误或类型错误,它会抛出错误;即执行一次longjump。保护模式下的环境使用setjmp设置一个恢复点;任何错误都会跳转到最近的活跃恢复点。
在C函数内部你可以显式调用lua_error来抛出错误。
API中的大部分函数都可以抛出错误,例如内存分配错误。本文中对于每个函数都会说明是否可能抛出异常。
如果在保护模式环境的外部发生了错误,Lua会调用panic函数(see lua_atpanic)然后调用abort,以此来退出宿主程序。你的panic函数可以永不返回以避免程序退出(例如做一次Lua外部的long jump)。
panic函数,其顾名思义(panic有陷入恐慌的含义)就是最后的挽救机制,应该在程序中避免。在通用的规则下,当Lua在一个状态机中调用了一个C函数,这个函数对Lua状态机中做的任意操作都应该处于保护模式下。然而当C代码对其他的Lua状态机操作时(例如作为一个是参数传进函数的Lua状态机,另一个是在注册表中存储的Lua状态机,或者还有lua_newthread返回的结果),其应当使用那些不会抛出错误的API调用。
paninc函数运行方式类似于(错误)消息处理(参见2.3);尤其是错误对象会在栈顶上。然而这里的栈空间没有任何保证。所以panic函数中应当在把一些东西压栈前首先检查其中的可用空间(参见4.1.1)。