#getting function pointers at comptime gives TODO (LLVM) error

1 messages · Page 1 of 1 (latest)

tough plinth
#

My project uses the signatures of user defined functions to automatically generate arguments for them. It gets passed fn pointers during comptime and generates a type to hold each of the pointers. Currently this causes the compiler to give this error:

src\ecs.zig:195:13: error: TODO (LLVM): implement const of pointer type '[TODO fix internal compiler bug regarding dump]' (value.Value.Tag.function)
        pub fn init(alloc: Allocator) !Self {
        ~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Is there any way around this? Currently I have to implement two passes, where I gather the Component types and Fn signatures first and then during runtime get their pointers. This might require the user to repeat themselves which isn't very ideal.
I'm also thinking of trying to finish this TODO myself but I'm not exactly well versed in the compiler internals or LLVM, so that will probably go horribly lol.

Recreating the bug:
cd into the base directory.
run zig build test

Any pull requests or ideas are greatly appreciated:
https://github.com/freakmangd/zentig_ecs

GitHub

Zig ECS library. Contribute to freakmangd/zentig_ecs development by creating an account on GitHub.

tough plinth
#

My current solution is to just have a separate runtime function for adding systems, unfortunately this gets rid of the ability to use custom function signatures :,( maybe it's for the best lol

tough plinth
#

ok, actually figured it out. if you instead use comptime fn fields and use a decl instead of a field to hold all of your fns, it works

#

working implementation in the github of course ;) under ecs.zig and WorldBuilder.addSystemsToStage, also take a look at World(...).__systems

tribal hawk
#

I think you may pass the function to your own function the wrong way. This should work:

pub fn FnToTuple(comptime my_fn: anytype) type {
    const Type = @TypeOf(my_fn);
    return std.meta.ArgsTuple(Type);
}

fn some_function(x: i32, y: f32) void {
    std.debug.print("{}@{}", .{ x, y });
}

test "stuff" {
    const Tuple = FnToTuple(some_function);
    inline for (std.meta.fields(Tuple)) |field| {
        std.debug.print("\n {s}\n", .{field.name});
    }
}
tough plinth
#

heres a cut down example of what i'm talking about, if you run zig run file.zig on this it will give you the error:

const std = @import("std");

const Gathered = blk: {
    var pg = PtrGather.new();
    pg.addFn(func1);
    pg.addFn(func2);
    break :blk pg.Build();
};

pub fn main() !void {
    var s = State{ .value = 10 };

    inline for (State.g) |f| {
        try f(s);
    }
}

const State = struct {
    const g: Gathered = .{};
    value: i32,
};

const PtrGather = struct {
    const Self = @This();

    inner: []const std.builtin.Type.StructField,

    pub fn new() Self {
        return .{
            .inner = &.{},
        };
    }

    pub fn addFn(comptime self: *Self, f: anytype) void {
        self.inner = self.inner ++ .{.{
            .name = std.fmt.comptimePrint("{}", .{self.inner.len}),
            .type = *const @TypeOf(f),
            .default_value = &f,
            .alignment = 0,
            .is_comptime = false,
        }};
    }

    pub fn Build(comptime self: Self) type {
        return @Type(.{ .Struct = .{
            .fields = self.inner,
            .decls = &.{},
            .layout = .Auto,
            .is_tuple = true,
        } });
    }
};

fn func1(s: State) !void {
    std.debug.print("{}\n", .{s.value});
}
fn func2(s: State) !void {
    _ = s;
}