【问题标题】:Why does the Flash ActionScript3 compiler emit unnecessary code?为什么 Flash ActionScript3 编译器会发出不必要的代码?
【发布时间】:2012-02-09 02:50:33
【问题描述】:

我最近为 AVM2/AS3 制作了一个反编译器,我注意到 Flash 编译器往往会发出大量不必要的代码。例如,对于某个应用程序,我已经删除了大约 10% 的代码,而对功能没有任何损害。它只是一个没有被条件操作码或异常处理块引用的肯定死代码。

另外,看看这个sn-p:

    ...
    313     setproperty         y
    315     getlocal            12
    317     returnvalue         
    318     jump                L9

    L3: 
    322     getlocal            8
    324     returnvalue         

    L9: 
    325     jump                L10 ; L10 (opcode #331) does not ever exist.
                                    ; Technically, it is a jump beyond
                                    ; the end of function. This is invalid code!

    L2: 
    329     pushnull            
    330     returnvalue         

好吧,这当然是无效的代码,它也是死的,因此不会造成任何不利影响(除了代码库膨胀)。但是为什么它会发出那个代码呢?为什么验证者会接受呢?

【问题讨论】:

  • 它不是从异常表中引用的(因为不是很多其他的,更大的——10 条指令——死代码块),从规范来看,你可以转移通过跳转操作码或异常进行控制。也没有跳跃。
  • @wvxvw 顺便说一句,finally 块是在 AS3 中通过一种奇怪而狡猾的 hack 完成的,其中编译器故意生成无效的操作码来欺骗验证者和 VM,再次故意忽略它们。 Flash 只是一个巨大的 WTF。
  • @wvxvw,我理解正确吗?如果您执行特定的操作码序列,那么虚拟机允许正在运行的代码以某种方式检查其操作码流,大概是通过将它们推送到数据堆栈? +50 如果你能找到参考资料。
  • @wvxvw 我已经写了一个反汇编器和分析器;)(见github.com/whitequark/furnace-avm2),无论如何,这个错误似乎不允许从运行时读取。 Stacktrace 只写给用户,而不是 VM 内的代码。

标签: flash actionscript-3 avm2


【解决方案1】:

ASC 或 compc 不优化。这是不幸的,但理论上是 JIT 完成了所有的优化工作。你可以想出更糟糕的例子,比如添加两个常量。所以答案是:对不起,它只是没有优化。将来可能会有更好的编译器。现在,您必须依靠 AS3 JIT 在运行时进行优化工作(它做得不错!)或使用不同的编译器。

【讨论】:

  • 是的,我当然见过添加常量等,更不用说到处都是不必要的强制了。最糟糕的例子可能是lookupswitch 是如何被代码生成的。你有什么关于为什么这样设计的参考资料(比如LLVM 有)?常量折叠并不是那么难以实现,除非你完全脑残。
  • whitequark:理论是“编译器”只是一个美化的解析器,JIT 会处理其他所有事情。我个人不认为这是一个好的设计,但它就是这样。我也不知道有什么好的参考资料,抱歉。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-10-03
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-26
相关资源
最近更新 更多