编译可以防止什么?

时间:2018-07-29 14:43:36

标签: ruby bytecode

RubyVM可以将Ruby代码编译为字节代码,然后直接执行它。例如,

COMPILE.rb

File.write(ARGV[1],RubyVM::InstructionSequence.compile_file(ARGV[0]).to_binary)

EXECUTE.rb

RubyVM::InstructionSequence.load_from_binary(File.read(ARGV[0]).force_encoding(Encoding::ISO_8859_1)).eval

Test.bat

ruby COMPILE.rb test.rb test.rbx
ruby EXECUTE.rb test.rbx

test.rb本身的红宝石代码实际执行。这里有什么明显的不利之处吗?一位朋友建议可能要小心,因为它可能最终无法在其他操作系统上运行。但是我希望它可以在所有操作系统上运行,例如例如Java字节码,它可以在由JVM执行的所有操作系统上运行。

将Ruby编译为字节码是否有明显的弊端(当然可读性除外)?

1 个答案:

答案 0 :(得分:6)

Ruby没有标准化的字节码格式。因此,无论那里有什么,它都是 not “ Ruby字节码”,它是Ruby的 one 实现的 one 版本的字节码。

在您的特定情况下,它是YARV的字节码。它不适用于MRuby,JRuby,Rubinius,Opal,MagLev,IronRuby,Topaz,MRI或任何其他Ruby实现。

此外,YARV不保证其字节码的向前或向后兼容性,因此不能保证它将在YARV的较新或较旧版本上运行。 The documentation says

  

随着Ruby的改变,指令序列的结果几乎肯定会改变

同样,YARV不保证字节码可移植性,因此不能保证它即使在使用相同版本的YARV上也可以在不同的操作系统,不同的CPU或不同的平台上运行。

最后,YARV的字节码是不安全,并且没有验证程序。 YARV会很乐意执行任何不安全的字节代码而不进行检查,您可以构造使VM处于不安全状态的字节代码。因此,您应该永远不要使用尚未创建的字节码执行此操作,而这完全在您的控制之下。 The documentation says

  

此加载程序没有验证程序,因此加载损坏的/修改的二进制文件会导致严重问题。

     

您不应加载他人提供的二进制数据。您应该使用自己翻译的二进制数据。

请注意,关于您的特定问题:

  

将Ruby编译为字节码是否有明显的弊端(当然可读性除外)?

您似乎有一种错误的印象,即您需要积极地做一些特殊的事情才能将Ruby编译为字节码。不一定是真的。

如果您使用YARV,Rubinius,MRuby,MagLev或Topaz,则您的Ruby代码总是 编译为字节代码,而无需执行任何操作。使用IronRuby和JRuby,可能会或可能不会将其编译为字节码,具体取决于代码是否足够“热”。

另外,使用MagLev,如果字节码足够“热”,则您的字节码将被编译为本机代码;对于Rubinius和YARV,根据版本,可能 被编译为本机代码,并且使用IronRuby和JRuby,根据CLI VES / JVM的实现,CIL / JVM字节码可能会编译为本机代码。