I’m exploring the idea of implementing JIT compilation for my language buzz.
I’m first trying to compile this minimal use case:
extern fun print(str value) > void;
fun main([str] args) > void {
print("hello world");
}
The extern
function is available in a dynamic library and is written in zig. It simply casts the pointer back to the buzz representation of a string (ObjString
) and prints its content:
const std = @import("std");
const api = @import("../../src/lib/buzz_api.zig");
export fn print(obj_string_addr: usize) void {
const obj_string = @intToPtr(*api.ObjString, obj_string_addr);
var len: usize = undefined;
const string = obj_string.bz_objStringToString(&len);
const slice = if (string) |ustring| ustring[0..len] else "";
std.io.getStdOut().writer().print("{s}\n", .{slice}) catch unreachable;
}
Now here’s what IR i have so far:
; ModuleID = 'tests/llvm/basic.buzz'
source_filename = "tests/llvm/basic.buzz"
@print = external global ptr
define void @"tests/llvm/basic.buzz"() {
"tests/llvm/basic.buzz.block":
; 4398868384 is the value of the ptr to the `print` function
store ptr inttoptr (i64 4398868384 to ptr), ptr @print, align 8
%0 = call i64 @main(ptr inttoptr (i64 4396651264 to ptr))
ret void
}
define void @main(ptr %0) {
main.block:
%1 = load ptr, ptr @print, align 8
; 4395893696 is the value of the ptr to the buzz representation of the string "hello world"
call void %1(ptr inttoptr (i64 4395893696 to ptr))
ret void
}
As you can see I’m passing any buzz value that is not number/boolean/null or void as a pointer so I can use the same data from LLVM IR and from buzz’s VM.
Seems ok to me but i’m getting a bus error. I’m guessing it occurs when trying to call @print
since the error is Bus error at address 0x1063167a0
and 1063167a0 == 4398868384
which the print function pointer value.
What am I missing?