Current section
Files
Jump to
Current section
Files
lib/zig/templates/basic.zig.eex
<% needs_make? = Enum.any?(@type.params, &Type.needs_make?/1) %>
fn <%= @type.name %>(env: beam.env, argc: c_int, args: [*c] const e.ErlNifTerm) callconv(.C) e.ErlNifTerm {
beam.context = .<%= context(@concurrency) %>;
<%= if needs_make? do %>
var error_info = beam.make_empty_list(env);
<% end %>
<%# TODO: set up a proper allocator variable. %>
<%= if @leak_check do %>
var gpa = beam.make_general_purpose_allocator_instance();
// set the threadlocal beam.allocator
beam.allocator = gpa.allocator();
<% else %>
beam.allocator = beam.raw_allocator;
<% end %>
const outer_result = get_result: {
<%= for {param_type, index} <- Nif.indexed_parameters(@type.params), Type.missing_size?(param_type) do %>
var size<%= index %>:usize = undefined;
<% end %>
const payload_opts = .{
<%= for {param_type, index} <- Nif.indexed_parameters(@type.params) do %>
.{
<%= if needs_make? do %>.error_info = &error_info,<% end %>
<%= if Type.missing_size?(param_type) do%>.size = &size<%= index %>,<% end %>
<%= if match?(%Zig.Type.Resource{}, param_type) do%>.root = @This() <% end %>
},
<% end %>
};
var error_index: u8 = undefined;
const payload = beam.payload.build(nif.<%= @type.name %>, env, argc, args, &error_index, payload_opts) catch |err| {
<%= if needs_make? do %>
return e.enif_raise_exception(env, beam.make(env, .{err, error_index, error_info}, .{}).v);
<% else %>
return e.enif_raise_exception(env, beam.make(env, .{err, error_index, beam.make_empty_list(env)}, .{}).v);
<% end %>
};
const cleanup_opts = .{
<%= for {param_type, index} <- Nif.indexed_parameters(@type.params), do: cleanup_for(@args, param_type, index) %>
};
defer beam.payload.cleanup(payload, cleanup_opts);
const result = @call(.auto, nif.<%= @type.name %>, payload) <%= Nif.maybe_catch(@type.return) %>;
<%= Type.get_result(@type.return, @return) %>
};
<%= if @leak_check do %>
switch (gpa.deinit()) {
.ok =>
return outer_result,
.leak =>
return beam.raise_elixir_exception(env, "RuntimeError", .{.message = "memory leak detected in function `<%= @type.name %>/<%= @type.arity %>`"}).v
}
<% else %>
return outer_result;
<% end %>
}