Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to call bang func only to make return #38

Merged
merged 2 commits into from
Dec 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions src/kinda.zig
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,17 @@ pub fn BangFunc(comptime Kinds: anytype, c: anytype, comptime name: anytype) typ
else => @compileError("too many args"),
};
}
pub fn wrap_ret_call(env: beam.env, args: anytype) !beam.term {
const rt = FTI.return_type.?;
const RetKind = getKind(rt);
var tuple_slice: []beam.term = beam.allocator.alloc(beam.term, 3) catch return beam.Error.@"Fail to allocate memory for tuple slice";
defer beam.allocator.free(tuple_slice);
tuple_slice[0] = beam.make_atom(env, "kind");
tuple_slice[1] = beam.make_atom(env, RetKind.module_name);
const ret = RetKind.resource.make(env, @call(.auto, variadic_call, .{args})) catch return beam.Error.@"Fail to make resource for return type";
tuple_slice[2] = ret;
return beam.make_tuple(env, tuple_slice);
}
pub fn nif(env: beam.env, _: c_int, args: [*c]const beam.term) !beam.term {
var c_args: VariadicArgs() = undefined;
inline for (FTI.params, args, 0..) |p, arg, i| {
Expand All @@ -302,20 +313,13 @@ pub fn BangFunc(comptime Kinds: anytype, c: anytype, comptime name: anytype) typ
variadic_call(c_args);
return beam.make_ok(env);
} else {
const RetKind = getKind(rt);
var tuple_slice: []beam.term = beam.allocator.alloc(beam.term, 3) catch return beam.Error.@"Fail to allocate memory for tuple slice";
defer beam.allocator.free(tuple_slice);
tuple_slice[0] = beam.make_atom(env, "kind");
tuple_slice[1] = beam.make_atom(env, RetKind.module_name);
const ret = RetKind.resource.make(env, variadic_call(c_args)) catch return beam.Error.@"Fail to make resource for return type";
tuple_slice[2] = ret;
return beam.make_tuple(env, tuple_slice);
return wrap_ret_call(env, c_args);
}
}
});
}

pub fn NIFFunc(comptime Kinds: anytype, c: anytype, comptime name: anytype, attrs: NIFFuncAttrs) e.ErlNifFunc {
pub fn NIFFunc(comptime Kinds: anytype, c: anytype, comptime name: anytype, comptime attrs: NIFFuncAttrs) e.ErlNifFunc {
const bang = BangFunc(Kinds, c, name);
return result.nif_with_flags(attrs.nif_name orelse name, bang.arity, bang.nif, attrs.flags).entry;
}
Loading