vnmakarov / mir

A lightweight JIT compiler based on MIR (Medium Internal Representation) and C11 JIT compiler and interpreter based on MIR

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow MIR text to be mixed in with C API

iacore opened this issue · comments

Currently, MIR_scan_string and MIR_read can only read complete modules, not a function or standalone MIR instructions.

Since MIR has both text and in-memory representation, I thought the C API should allow me to do this:

(sorry about the code being Zig)

const std = @import("std");
const m = @import("mir.zig");

const use_text = true;

pub fn main() !void {
    const ctx = m.MIR_init() orelse return error.MIRError;

    const mod = m.MIR_new_module(ctx, "name");

    var f: m.MIR_item_t = undefined;
    if (use_text) {
        m.MIR_scan_string(ctx,
            \\hello:  
            \\  func i64, i64:a, i64:b
            \\  local      i64:$ret
            \\  add        $ret, a, b
            \\  ret        $ret
            \\  endfunc
        );
        f = m.MIR_get_global_item(ctx, "hello");
    } else {
        var f_vars = [_]m.MIR_var_t{
            .{ .type = m.MIR_T_I64, .name = "a" },
            .{ .type = m.MIR_T_I64, .name = "b" },
        };
        f = ctx.new_func("add", 1, &.{m.MIR_T_I64}, 2, &f_vars);
        const fid = m.MIR_get_item_func(f);

        const ret = ctx.new_func_reg(fid, m.MIR_T_I64, "ret");
        const a = ctx.reg(f_vars[0].name, fid);
        const b = ctx.reg(f_vars[1].name, fid);

        ctx.append(f, ctx.insn(m.MIR_ADD, 3, &.{ ctx.op_reg(ret), ctx.op_reg(a), ctx.op_reg(b) }));

        ctx.append(f, ctx.insn(m.MIR_RET, 1, &.{ctx.op_reg(ret)}));
        m.MIR_finish_func(ctx);
    }

    m.MIR_finish_module(ctx);

    m.MIR_load_module(ctx, mod);

    m.MIR_output(ctx, m.stderr);

    m.MIR_gen_init(ctx, 1);
    m.MIR_link(ctx, m.MIR_set_gen_interface, null);
    const f_call = @as(*fn (i64, i64) callconv(.C) i64, @ptrCast(m.MIR_gen(ctx, 0, f)));
    m.MIR_gen_finish(ctx);

    const ans = f_call(2, 3);
    std.log.info("{}", .{ans});
}