Llvmruby ( llvmruby 的 GitHub 代码库)是由 Tom Bagby 开发的项目。它提供 Ruby 对 LLVM 的绑定。Llvmruby 与 Ruby 可以良好的集成。例如,下面的代码可以添加一个 add 指令(codeblock 是指令构造器)。
codeblock.bin_op(Instruction::Add, 41.llvm, 1.llvm)
Llvmruby 重新打开了 Object 并将 llvm 添加进去,以便可以将其转换成 LLVM 可以处理的值。
在按照 README 的使用说明做完以后(包括获取和编译 LLVM 以及编译 llvmruby),就可以开始进行实验了,例如使用 irb。这有一个示例会话(其中一些示例代码是取自于 llvmruby 项目):
# Set up LLVM >> require 'llvm' => true >> include LLVM => Object >> m = LLVM::Module.new("test_module") => ; ModuleID = 'test_module' # Create a function type - the second argument is the method signature, # ie. the return type and the types of the arguments # In this case, there are no return values or arguments >> type = Type::function(MACHINE_WORD, []) => # >> f = m.get_or_insert_function("test", type) => declare i32 @test() # Create an LLVMBuilder object which allows to call methods and # generate instructions >> builder = f.create_block.builder => # # Create an Add instruction - note how it's possible to pass regular Ruby Fixnums >> ret = builder.bin_op(Instruction::Add, 41.llvm, 1.llvm) => # >> fcode = builder.return(ret) => # >> ExecutionEngine.get(m); => true # Finally: execute the generated code >> ExecutionEngine.run_autoconvert(f) => 42
关于 LLVM 的更多信息,请看 LLVM 关于如何为一门简洁的语言实现 JIT 的教程。
Miura Hidek 给出了两个更大一点儿的使用 llvmruby 的实例:
- regexpllvm :将正则表达式转换为 LLVM 代码。
- yarv2llvm :将 Ruby 1.9 的操作码(1.9 虚拟机在没有成为官方 1.9 虚拟机之前被称为 YARV)转换成 LLVM 代码。它跟随着相似项目前行的脚步,例如 _why 的 Unholy(将 Ruby 1.9 的操作码转换为 Python 虚拟机的操作码)或者 HotRuby(一个用于 Ruby 1.9 操作码的 Javascript 解析器)。和这些项目不同的是,llvmruby 和 Ruby 1.9 虚拟机紧密集成,可以做的事情更加有趣。Regexpllvm 展示了一种加速代码执行的可能,比如将 DSL 编译成 LLVM 操作码。其他系统使用过这种方法,比如 Java 的 XSLT 实现将 XSLT 样式表编译成 JVM 字节码。
另 一种可能:编译 Ruby 代码的热点。此事,如果某段 Ruby 代码遇到性能瓶颈,通常的解决方案是用 C 重写(最理想化的解决方案是等待 Ruby 虚拟机的性能 提升)。通过 llvmruby,有了另一个选择:将 Ruby 代码编译成 LLVM,例如使用 yarv2llvm 来加速。当然,能否可以提供必要的性能加速还 要取决于代码本身。
Llvmruby 可以让你不接触任何 C++ 就能够试用 LLVM,还允许你通过 irb 增量进行尝试。这是一项很有用的特性,比如 Rubinius(此项目正计划使用 LLVM)的贡献者就利用其构建原型系统,以原型化自己的某些主张。Rubinius 团队正忙于使用 C++ 重写虚拟机和清理一些内部问题。这个目前已经在 Rubinius 在 Git 的代码库的 CPP 分支中出现,而且还将 LLVM 作为外部的程序库。C++ 分支很快就会转入主干。根据最近在 Twitter 上发布的消息显示,Rubinius 已经在全新的 C++ 虚拟机上重新获得了运行大量 Ruby 代码的能力。 Eric Hodel 本周在 Twitter 上说道:
Rubinius 全新的虚拟机目前已经可以运行核心规格而不会挂掉
万岁!IRB 又能在新的 Rubinius C++ 虚拟机下面工作了!
你打算如何在 Ruby 中使用 LLVM 呢?
评论