I am writing code to generate LLVM bytecode from VM user bytecode using LLVM Go bindings ; the code is then JITed and executed in the process.
The VM user bytecode has several operations that cannot be implemented directly in LLVM, since they require an external state change; the functionality for these opcodes is implemented as Go functions.
great start-up guides when creating LLVM bytecode from Go, but not a single issue is related to callbacks or exported functions. Can LLVM statements be generated to return to Go functions? If so, how?
I tried the method described below, @arrowd, and it does not seem to work. Source code adapted from a Felix Angell post:
package main
import (
"C"
"fmt"
"llvm.org/llvm/final/bindings/go/llvm"
)
func AddInts(arg1, arg2 int) int {
return arg1 + arg2;
}
func main() {
builder := llvm.NewBuilder()
mod := llvm.NewModule("my_module")
main := llvm.FunctionType(llvm.Int32Type(), []llvm.Type{}, false)
llvm.AddFunction(mod, "main", main)
block := llvm.AddBasicBlock(mod.NamedFunction("main"), "entry")
builder.SetInsertPoint(block, block.FirstInstruction())
a := builder.CreateAlloca(llvm.Int32Type(), "a")
builder.CreateStore(llvm.ConstInt(llvm.Int32Type(), 32, false), a)
b := builder.CreateAlloca(llvm.Int32Type(), "b")
builder.CreateStore(llvm.ConstInt(llvm.Int32Type(), 16, false), b)
bVal := builder.CreateLoad(b, "b_val")
aVal := builder.CreateLoad(a, "a_val")
addIntsType := llvm.FunctionType(llvm.Int32Type(), []llvm.Type{llvm.Int32Type(), llvm.Int32Type()}, false)
addInts := llvm.AddFunction(mod, "AddInts", addIntsType)
call := builder.CreateCall(addInts, []llvm.Value{aVal, bVal}, "AddInts")
builder.CreateRet(call)
if ok := llvm.VerifyModule(mod, llvm.ReturnStatusAction); ok != nil {
fmt.Println(ok.Error())
}
mod.Dump()
engine, err := llvm.NewExecutionEngine(mod)
if err != nil {
fmt.Println(err.Error())
}
funcResult := engine.RunFunction(mod.NamedFunction("main"), []llvm.GenericValue{})
fmt.Printf("%d\n", funcResult.Int(false))
}
Return:
; ModuleID = 'my_module'
define i32 @main() {
entry:
%a = alloca i32
store i32 32, i32* %a
%b = alloca i32
store i32 16, i32* %b
%b_val = load i32* %b
%a_val = load i32* %a
%AddInts = call i32 @AddInts(i32 %a_val, i32 %b_val)
ret i32 %AddInts
}
declare i32 @AddInts(i32, i32)
LLVM ERROR: Tried to execute an unknown external function: AddInts
exit status 1