Skip to content

Instantly share code, notes, and snippets.

@ishikawa
Created May 17, 2014 23:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ishikawa/8b3af97dec4ced222a01 to your computer and use it in GitHub Desktop.
Save ishikawa/8b3af97dec4ced222a01 to your computer and use it in GitHub Desktop.
Call Ruby method (FFI::Function) from LLVM
require 'ffi'
require 'llvm/core'
require 'llvm/analysis'
require 'llvm/execution_engine'
CALLBACK_TYPE = LLVM.Function([LLVM::Int], LLVM.Void)
mod = LLVM::Module.new("test.fprintf")
do_work = mod.functions.add("do_work", [CALLBACK_TYPE.pointer], LLVM.Void) do |fn, callback|
callback.name = "callback"
fn.basic_blocks.append.build do |builder|
builder.call(callback, LLVM::Int(rand 1000))
builder.ret_void
end
end
mod.verify!
mod.dump
# ; ModuleID = 'test.fprintf'
#
# define void @do_work(void (i32)* %callback) {
# call void %callback(i32 760)
# ret void
# }
# LLVM callback: 760
# --- JIT
LLVM.init_jit
engine = LLVM::JITCompiler.new(mod)
funptr = engine.pointer_to_global(do_work)
ffi_fun = FFI::Function.new(:void, [:pointer], funptr)
callback = FFI::Function.new(:void, [:int]) do |i|
puts "LLVM callback: #{i}"
end
ffi_fun.call(callback)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment