- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
LuaJIT 手册 states :
Lua errors can be caught on the C++ side with catch(...). The corresponding Lua error message can be retrieved from the Lua stack.
这按预期工作 - 除了 std::uncaught_exception()
在这种情况下不返回 true。
以下是说明该问题的最小示例。 checker
的析构函数应该在堆栈展开期间执行,因此其中的 std::uncaught_exception()
应该返回 true,但它没有。
这怎么可能?是我误解了这个过程还是 LuaJIT 以粗略的方式执行异常引发?
struct checker {
~checker() {
if(std::uncaught_exception()) {
// condition should evaluate true, but doesn't
}
}
}
auto l = luaL_newstate();
try {
{
checker c;
luaL_checknumber(l, -1); // this line causes LuaJIT to raise an error
}
}
catch(...) {
// this will be executed, as intended
auto err = lua_tostring(state, -1); // read the LuaJIT error, works too
// ...
}
最佳答案
原始 Lua(不是 LuaJIT)使用不是 C++ 异常的 C 风格异常(长跳转)。grep
LUAI_THROW 的 Lua 来源并注意 C/C++ 异常处理之间的区别。
/*
@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
** CHANGE them if you prefer to use longjmp/setjmp even with C++
** or if want/don't to use _longjmp/_setjmp instead of regular
** longjmp/setjmp. By default, Lua handles errors with exceptions when
** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
** and with longjmp/setjmp otherwise.
*/
#if defined(__cplusplus)
/* C++ exceptions */
#define LUAI_THROW(L,c) throw(c)
#define LUAI_TRY(L,c,a) try { a } catch(...) \
{ if ((c)->status == 0) (c)->status = -1; }
#define luai_jmpbuf int /* dummy variable */
#elif defined(LUA_USE_ULONGJMP)
/* in Unix, try _longjmp/_setjmp (more efficient) */
#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#else
/* default handling with long jumps */
#define LUAI_THROW(L,c) longjmp((c)->b, 1)
#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
#define luai_jmpbuf jmp_buf
#endif
我不确定是否可行,但您可以尝试使用 C++ 编译 Lua,这将允许您捕获 Lua 异常。注意,编译为 C 代码的原始 Lua 不支持 C++ 栈帧展开!
至于 LuaJIT,它看起来像是自己实现了帧展开,有关详细信息,请参阅 lj_err.c。这就是为什么在此过程中可能不会设置某些 CRT 变量的原因。
/*
** LuaJIT can either use internal or external frame unwinding:
**
** - Internal frame unwinding (INT) is free-standing and doesn't require
** any OS or library support.
**
** - External frame unwinding (EXT) uses the system-provided unwind handler.
**
** Pros and Cons:
**
** - EXT requires unwind tables for *all* functions on the C stack between
** the pcall/catch and the error/throw. This is the default on x64,
** but needs to be manually enabled on x86/PPC for non-C++ code.
**
** - INT is faster when actually throwing errors (but this happens rarely).
** Setting up error handlers is zero-cost in any case.
**
** - EXT provides full interoperability with C++ exceptions. You can throw
** Lua errors or C++ exceptions through a mix of Lua frames and C++ frames.
** C++ destructors are called as needed. C++ exceptions caught by pcall
** are converted to the string "C++ exception". Lua errors can be caught
** with catch (...) in C++.
**
** - INT has only limited support for automatically catching C++ exceptions
** on POSIX systems using DWARF2 stack unwinding. Other systems may use
** the wrapper function feature. Lua errors thrown through C++ frames
** cannot be caught by C++ code and C++ destructors are not run.
**
** EXT is the default on x64 systems, INT is the default on all other systems.
**
** EXT can be manually enabled on POSIX systems using GCC and DWARF2 stack
** unwinding with -DLUAJIT_UNWIND_EXTERNAL. *All* C code must be compiled
** with -funwind-tables (or -fexceptions). This includes LuaJIT itself (set
** TARGET_CFLAGS), all of your C/Lua binding code, all loadable C modules
** and all C libraries that have callbacks which may be used to call back
** into Lua. C++ code must *not* be compiled with -fno-exceptions.
**
** EXT cannot be enabled on WIN32 since system exceptions use code-driven SEH.
** EXT is mandatory on WIN64 since the calling convention has an abundance
** of callee-saved registers (rbx, rbp, rsi, rdi, r12-r15, xmm6-xmm15).
** EXT is mandatory on POSIX/x64 since the interpreter doesn't save r12/r13.
*/
附言我想您已经了解安全 Lua 类型检查 (lua_is*
) 和安全函数,例如 lua_pcall
。
关于c++ - 为什么 std::uncaught_exception 在 LuaJIT 抛出时返回 false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38493718/
在 official guide 之后的一段时间里,我一直在尝试在 Windows 10 上安装 LuaJIT。 ,我实际上开始安装它。例如,如果我执行 luajit我进入提示。另外,luajit -
require "utils.lua" stdin:1: module 'utils.lua' not found: no field package.preload['utils.l
我正在尝试使用 setfenv 对一些函数进行沙盒处理,我收到以下输出: 123 nil 为什么调用sandboxTest()时testValue是nil,而在callSandboxedTest()中
只是来自“Lua 新手”的一个小问题......我一直在使用 LuaJIT,它很棒,没有问题是因为 LuaJIT 是 Lua 5.1 兼容的,这是否意味着我可以使用标准 Lua 在 LuaJIT 中使
教程部分中的示例:“为 C 类型定义元方法” 如下所示: local ffi = require("ffi") ffi.cdef[[ typedef struct { double x, y; } p
我想用 C 编写一些函数以在 Lua 中使用,我认为我能找到的最简单的方法是使用 LuaJIT 的 FFI。 我有一个 C 文件“add.c”: int add(int a, int b){ retu
我正在寻找有关如何为 LuaJIT 2 优化 Lua 代码的好指南.它应该关注 LJ2 的细节,比如如何检测哪些跟踪正在被编译,哪些不是,等等。 任何指针?收集到 Lua ML 帖子的链接可以作为答案
我正在尝试优化我的 LuaJIT 代码,我想知道是否有一个调试工具,或者我是否可以编写一个,来检查我的脚本访问全局变量/表/函数的次数? 最佳答案 您可以使用代理表来存储全局变量,并将对全局表的任何访
我有以下 qsort 示例来尝试 luajit 中的回调。但是它有内存泄漏(luajit:执行时内存不足),这对我来说并不明显。 有人可以给我一些关于如何创建正确的回调示例的提示吗? local ff
我在使用 ffi.metatype 定义的用户数据时遇到问题。当对象被垃圾收集时,我会遇到段错误。这是代码。 ffi = require("ffi") srate = 48000 ffi.cdef[[
关于 的 Luajit 手册-b 选项 说: The output file type is auto-detected from the extension of the output file n
我有一个小的 C 程序,它有一个字符串,它必须代表一个 Lua 模块,它看起来像这样: const char *lua_str = " local mymodule = {} \ functi
已关注 MSDN's GetOpenFileName example使用 LuaJIT 的 FFI。这两天我一直在努力让它工作,不仅对话框打不开,而且整个东西都崩溃了。 当使用 OllyDdb 进行调
我有这样的文件设置: main.lua (requires 'mydir.b' and then 'b') b.lua mydir/ b.so (LuaJIT C module) 从主要,
我认为 LuaJIT 很棒,现在我也看到了 eLua。 我很好奇嵌入式程序员什么时候会为嵌入式系统选择一个而不是另一个? 最佳答案 这取决于您所说的“嵌入式系统”是什么意思。您是指“移动应用程序”还是
lua -e "print(package.path)" ./?.lua;/usr/share/lua/5.1/?.lua;/usr/share/lua/5.1/?/init.lua;/usr/lib
编辑:不幸的是,LuaJIT 被排除在下面链接的比较之外。 这个comparison编程语言的多样性表明 LuaJIT 比普通 Lua 实现有十倍以上的改进。为什么变化这么大? Lua 是否有什么特殊
我目前正在尝试使用以下命令在我的 Arch linux 发行版上使用 luajit 支持编译 suricata ( http://suricata-ids.org/ ): ./configure --
LuaJIT 知道它定义的 C 类型以及数组的长度,但它不检查边界: ffi = require("ffi") ten_ints = ffi.typeof("int [10]") p1 = ten_i
我在 LuaJit 中不断收到内存不足错误。如何增加堆栈或堆大小? 谢谢 最佳答案 除了玩具示例,我自己没有使用过 LuaJIT。但是由于还没有其他人提供任何答案... 从浏览 documentati
我是一名优秀的程序员,十分优秀!