« 我们需要 photoshop 之外的选择 | 返回首页 | 支持一下《致招商银行的公开信》的活动 »

lua 近期的一个 bug

在 lua 的 maillist 上最近报告了一个 bug

看起来问题比较严重,因为稍具规模的 lua 程序都可能因此而出现问题。最近两周,我和我的同事都比较关注这个问题,并对 lua 的源代码做了相关的分析。

Roberto 作为 lua 委员会三巨头之一,在 mail 中已经表示追踪到 bug 的起因,但暂时还找不到合适的解决方案。直觉告诉我,这不会是一个简单的问题。如果容易修正的话,patch 早就有了,而不会只是发一个 bug report 而已。所以我们也并未尝试自己去修补这个 bug ,可以做的可能只有等待。

近期的一些讨论表明,这个问题出至于 lua 的 parser 在处理常数时做的一些简单优化。类似 1+2 这样的代码在编译器有可能被编译成常量 3 。

算法本身没有错,错在 lua 的一些优化处理上。

当一个 chunk 中常量少于 256 个时,lua 在生成 VM 指令时,会将常量编号直接生成在指令内;而超过 256 个常量,就必须依赖堆栈。lua 的 parser 是一次扫描的递归下降算法。在做这种常量合并(编译期运算)时,每一个常量都不能立刻生成代码,而要看它是否可以和下一个常量合并。一次扫描导致了在 256 这个临界点时不太好处理两种生成算法的区别。

我自己去年也写过简单的编译器,同样是一次扫描的递归下降算法。对于这样的 bug 的出现深有感触。

我想,这也是一种提前优化的体现吧。越是复杂的程序,执行效率越是来之不易。


3月26日补:

Lua 5.1.2 中修补了这个 Bug

Comments

烦死哦 最近遇到个问题 181-195作为脚本参数传入调用c api,断住一看变成2050了 要么变成0,0-180 或者更大的数都没事
关注中! 这可是一个大BUG。 目前在我们的项目中还没有遇到,不过可能很快就遇到了。 谢谢提醒!
是呀,好象你在写编译器。呵呵,我现在也在学。手工写词法分析器和语法分析器有点复杂,
风云的编译器怎么样了?能试用么? 最近有在自己写的微型嵌入式GUI 加入虚拟执行机的想法,当然编译器也要自己写了。我非常喜欢 C 语言,打算去掉其中的一些语法,减少工作量,毕竟还是我一个人做 嘛。 lua 的"寄存器"思想还是很不错的。如果局部变量太多,可能会是个问题。我现在在想如何更好的实现 C 语言中 的域变量,就是 {int a; ... {int b; ... {int c; ... }}} 虚拟执行机部分,我想如果能尽可能减少 虚拟指令产生的数量,就是一个虚拟指令表示近可能多的 stack 指令,就可以显著提高执行速度。

Post a comment

非这个主题相关的留言请到:留言本