beam (zigler v0.7.3) View Source
This struct contains adapters designed to facilitate interfacing the BEAM's c-style helpers for NIFs with a more idiomatic Zig-style of programming, for example, the use of slices instead of null-terminated arrays as strings.
This struct derives from zig/beam/beam.zig
, and you may import it into
your module's zig code by calling:
const beam = @import("beam.zig")
This is done automatically for you inside your ~Z
forms, so do NOT
use this import statement with inline Zig.
Features
The BEAM Allocator
Wraps e.enif_alloc
and e.enif_free
functions into a compliant Zig
allocator struct. You should thus be able to supply Zig standard library
functions which require an allocator a struct that is compliant with its
requirements.
This is, in particular, useful for slice generation.
Example (slice generation)
beam = @import("beam.zig");
fn make_a_slice_of_floats() ![]f32 {
return beam.allocator.alloc(f32, 100);
}
Beacuse Zig features composable allocators, you can very easily implement custom allocators on top of the existing BEAM allocator.
Getters
Erlang's NIF interface provides a comprehensive set of methods to retrieve data out of BEAM terms. However, this set of methods presents an error handling scheme that is designed for C and inconsistent with the idiomatic scheme used for Zig best practices.
A series of get functions is provided, implementing these methods in
accordance to best practices. These include get/3
, which is the generic
method for getting scalar values, get_X
, which are typed methods for
retrieving scalar values, and get_slice_of/3
, which is the generic method
for retrieving a Zig slice from a BEAM list.
Naturally, for all of these functions, you will have to provide the BEAM environment value.
Examples
const beam = @import("beam.zig");
fn double_value(env: beam.env, value: beam.term) !f64 {
return (try beam.get_f64(env, value)) * 2;
}
fn sum_float_list(env: beam.env, list: beam.term) !f64 {
zig_list: []f64 = try beam.get_slice_of(f64, env, list);
defer beam.allocator.free(zig_list); // don't forget to clean up!
result: f64 = 0;
for (list) |item| { result += item; }
return result;
}
Makers
A series of "make" functions is provided which allow for easy export of Zig values back to the BEAM. Typically, these functions are used in the automatic type marshalling performed by Zigler, however, you may want to be able to use them yourself to assemble BEAM datatypes not directly supported by Zig. For example, a custom tuple value.
Example
const beam = @import("beam.zig");
const ok_slice="ok"[0..];
fn to_ok_tuple(env: beam.env, value: i64) !beam.term {
var tuple_slice: []term = try beam.allocator.alloc(beam.term, 2);
defer beam.allocator.free(tuple_slice);
tuple_slice[0] = beam.make_atom(env, ok_slice);
tuple_slice[1] = beam.make_i64(env, value);
return beam.make_tuple(env, tuple_slice);
}
Link to this section Summary
Functions
A helper for marshalling values from the BEAM runtime into Zig. Use this function if you need support for Zig generics.
Takes a BEAM int term and returns a c_int
value. Should only be used for
C interop with Zig functions.
Takes a BEAM int term and returns a c_uint
value. Should only be used for
C interop with Zig functions.
Takes a BEAM int term and returns a c_long
value. Should only be used
for C interop with Zig functions.
Takes a BEAM int term and returns a c_ulong
value. Should only be used
for C interop with Zig functions.
Takes a BEAM int term and returns a isize
value. Should only be used
for C interop.
Takes a BEAM int term and returns a usize
value. Zig idiomatically uses
usize
for its size values, so typically you should be using this function.
Takes a BEAM int term and returns a u8
value.
Takes a BEAM int term and returns a u16
value.
Takes a BEAM int term and returns a u32
value.
Takes a BEAM int term and returns a u64
value.
Takes a BEAM int term and returns an i32
value.
Takes a BEAM int term and returns an i64
value.
Takes a BEAM float term and returns an f16
value.
Takes a BEAM float term and returns an f32
value.
Takes a BEAM float term and returns an f64
value.
Takes a BEAM atom term and retrieves it as a slice []u8
value.
it's the caller's responsibility to make sure that the value is freed.
Takes a BEAM atom term and retrieves it as a slice []u8
value, with
any allocator.
Takes an BEAM binary/0
term and retrieves a pointer to the
binary data as a Zig c-string ([*c]u8
). No memory is allocated for
this operation.
Takes an BEAM binary/0
term and retrieves it as a Zig character slice
([]u8
) No memory is allocated for this operation.
Takes an BEAM binary/0
term and returns the corresponding
binary
struct.
Takes an BEAM pid/0
term and returns the corresponding pid
struct.
shortcut for e.enif_self
, marshalling into zig error style.
shortcut for e.enif_self
shortcut for e.enif_self
Takes an Beam tuple/0
term and returns it as a slice of term
structs.
Does not allocate memory for this operation.
Takes a BEAM list/0
term and returns its length.
Iterates over a BEAM list/0
.
A generic function which lets you convert a BEAM list/0
of
homogeous type into a Zig slice.
Converts an BEAM list/0
of homogenous type into a Zig slice, but
using any allocator you wish.
Converts an BEAM boolean/0
into a Zig bool
.
A helper for marshalling values from Zig back into the runtime. Use this function if you need support for Zig generics.
converts a char (u8
) value into a BEAM integer/0
.
converts a unsigned (u16
) value into a BEAM integer/0
.
converts a unsigned (u32
) value into a BEAM integer/0
.
converts a unsigned (u64
) value into a BEAM integer/0
.
converts a c_int
value into a BEAM integer/0
.
converts a c_uint
value into a BEAM integer/0
.
converts a c_long
value into a BEAM integer/0
.
converts a c_ulong
value into a BEAM integer/0
.
converts an isize
value into a BEAM integer/0
.
converts a usize
value into a BEAM integer/0
.
converts an i32
value into a BEAM integer/0
.
converts an i64
value into a BEAM integer/0
.
converts an f16
value into a BEAM float/0
.
converts an f32
value into a BEAM float/0
.
converts an f64
value into a BEAM float/0
.
converts a Zig char slice ([]u8
) into a BEAM atom/0
.
converts a Zig char slice ([]u8
) into a BEAM binary/0
.
converts an c string ([*c]u8
) into a BEAM binary/0
. Mostly used for
c interop.
converts a slice of term
s into a BEAM tuple/0
.
converts a slice of term
s into a BEAM list/0
.
converts a Zig char slice ([]u8
) into a BEAM charlist/0
.
converts a c string ([*c]u8
) into a BEAM charlist/0
.
A helper to make BEAM lists out of slices of term
. Use this function if
you need a generic listbuilding function.
A helper to make a BEAM t:Kernel.list
out of term
s, with any allocator.
Use this function if you need a generic listbuilding function.
converts a c_int slice ([]c_int
) into a BEAM list of integer/0
.
converts a c_long slice ([]c_long
) into a BEAM list of integer/0
.
converts an i32 slice ([]i32
) into a BEAM list of integer/0
.
converts an i64 slice ([]i64
) into a BEAM list of integer/0
.
converts an f16 slice ([]f16
) into a BEAM list of float/0
.
converts an f32 slice ([]f32
) into a BEAM list of float/0
.
converts an f64 slice ([]f64
) into a BEAM list of float/0
.
converts a bool
value into a boolean/0
value.
creates a beam nil
value.
creates a beam ok
value.
creates a beam error
value.
A helper to make {:ok, term}
terms from arbitrarily-typed values.
A helper to make {:ok, binary}
terms from slices
A helper to make {:ok, atom}
terms from slices
A helper to make {:ok, term}
terms in general
A helper to make {:error, term}
terms from arbitrarily-typed values.
A helper to make {:error, atom}
terms from slices
A helper to make {:error, binary}
terms from slices
A helper to make {:error, term}
terms in general
Encapsulates e.enif_make_ref
and allows it to return a
FunctionClauseError.
this function is going to be dropped inside the suspend statement.
This function is used to communicate :enomem
back to the BEAM as an
exception.
This function is used to communicate :function_clause
back to the BEAM as an
exception.
This function is used to communicate :resource_error
back to the BEAM as an
exception.
This function is used to communicate :assertion_error
back to the BEAM as an
exception.
A function used to return assertion errors to a zigtest.
Link to this section Functions
get(comptime T: type, environment: env, value: term) !T
View Source (comptime)A helper for marshalling values from the BEAM runtime into Zig. Use this function if you need support for Zig generics.
Used internally to typcheck values coming into Zig slice.
supported types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
Takes a BEAM int term and returns a c_int
value. Should only be used for
C interop with Zig functions.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a c_uint
value. Should only be used for
C interop with Zig functions.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a c_long
value. Should only be used
for C interop with Zig functions.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a c_ulong
value. Should only be used
for C interop with Zig functions.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a isize
value. Should only be used
for C interop.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a usize
value. Zig idiomatically uses
usize
for its size values, so typically you should be using this function.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a u8
value.
Note that this conversion function checks to make sure it's in range
(0..255
).
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a u16
value.
Note that this conversion function checks to make sure it's in range
(0..65535
).
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a u32
value.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns a u64
value.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns an i32
value.
Note that this conversion function does not currently do range checking.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM int term and returns an i64
value.
Note that this conversion function does not currently do range checking.
Raises beam.Error.FunctionClauseError
if the term is not integer/0
Takes a BEAM float term and returns an f16
value.
Note that this conversion function does not currently do range checking.
Raises beam.Error.FunctionClauseError
if the term is not float/0
Takes a BEAM float term and returns an f32
value.
Note that this conversion function does not currently do range checking.
Raises beam.Error.FunctionClauseError
if the term is not float/0
Takes a BEAM float term and returns an f64
value.
Raises beam.Error.FunctionClauseError
if the term is not float/0
Takes a BEAM atom term and retrieves it as a slice []u8
value.
it's the caller's responsibility to make sure that the value is freed.
Uses the standard beam.allocator
allocator. If you require a custom
allocator, use get_atom_slice_alloc/3
Raises beam.Error.FunctionClauseError
if the term is not atom/0
get_atom_slice_alloc(a: *Allocator, environment: env, src_term: atom) ![]u8
View SourceTakes a BEAM atom term and retrieves it as a slice []u8
value, with
any allocator.
Raises beam.Error.FunctionClauseError
if the term is not atom/0
Takes an BEAM binary/0
term and retrieves a pointer to the
binary data as a Zig c-string ([*c]u8
). No memory is allocated for
this operation.
Should only be used for c interop functions.
Note: this function could have unexpected results if your BEAM binary
contains any zero byte values. Always use get_char_slice/2
when
C-interop is not necessary.
Raises beam.Error.FunctionClauseError
if the term is not binary/0
Takes an BEAM binary/0
term and retrieves it as a Zig character slice
([]u8
) No memory is allocated for this operation.
Raises beam.Error.FunctionClauseError
if the term is not binary/0
Takes an BEAM binary/0
term and returns the corresponding
binary
struct.
Raises beam.Error.FunctionClauseError
if the term is not binary/0
Takes an BEAM pid/0
term and returns the corresponding pid
struct.
Note that this is a fairly opaque struct and you're on your
own as to what you can do with this (for now), except as a argument
for the e.enif_send
function.
Raises beam.Error.FunctionClauseError
if the term is not pid/0
shortcut for e.enif_self
, marshalling into zig error style.
returns the pid value if it's env is a process-bound environment, otherwise
returns beam.Error.FunctionClauseError
.
shortcut for e.enif_self
returns true if the send is successful, false otherwise.
NOTE this function assumes a valid BEAM environment. If you have spawned
an OS thread without a BEAM environment, you must use send_advanced/4
send_advanced(c_env: env, to_pid: pid, m_env: env, msg: term) bool
View Sourceshortcut for e.enif_self
returns true if the send is successful, false otherwise.
if you are sending from a thread that does not have a BEAM environment, you
should put null
in both environment variables.
Takes an Beam tuple/0
term and returns it as a slice of term
structs.
Does not allocate memory for this operation.
Raises beam.Error.FunctionClauseError
if the term is not tuple/0
Takes a BEAM list/0
term and returns its length.
Raises beam.Error.FunctionClauseError
if the term is not list/0
Iterates over a BEAM list/0
.
In this function, the list
value will be modified to the tl
of the
BEAM list, and the return value will be the BEAM term.
Raises beam.Error.FunctionClauseError
if the term is not list/0
get_slice_of(comptime T: type, environment: env, list: term) ![]T
View Source (comptime)A generic function which lets you convert a BEAM list/0
of
homogeous type into a Zig slice.
The resulting slice will be allocated using the beam allocator, with
ownership passed to the caller. If you need to use a different allocator,
use get_slice_of_alloc/4
Raises beam.Error.FunctionClauseError
if the term is not list/0
.
Also raises beam.Error.FunctionClauseError
if any of the terms is
incompatible with the internal type
supported internal types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
get_slice_of_alloc(comptime T: type, a: *Allocator, environment: env, list: term) ![]T
View Source (comptime)Converts an BEAM list/0
of homogenous type into a Zig slice, but
using any allocator you wish.
ownership is passed to the caller.
Raises beam.Error.FunctionClauseError
if the term is not list/0
.
Also raises beam.Error.FunctionClauseError
if any of the terms is
incompatible with the internal type.
supported internal types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
Converts an BEAM boolean/0
into a Zig bool
.
Raises beam.Error.FunctionClauseError
if the term is not boolean/0
.
May potentially raise an out of memory error, as it must make an allocation
to perform its conversion.
A helper for marshalling values from Zig back into the runtime. Use this function if you need support for Zig generics.
supported types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
converts a char (u8
) value into a BEAM integer/0
.
converts a unsigned (u16
) value into a BEAM integer/0
.
converts a unsigned (u32
) value into a BEAM integer/0
.
converts a unsigned (u64
) value into a BEAM integer/0
.
converts a c_int
value into a BEAM integer/0
.
converts a c_uint
value into a BEAM integer/0
.
converts a c_long
value into a BEAM integer/0
.
converts a c_ulong
value into a BEAM integer/0
.
converts an isize
value into a BEAM integer/0
.
converts a usize
value into a BEAM integer/0
.
converts an i32
value into a BEAM integer/0
.
converts an i64
value into a BEAM integer/0
.
converts an f16
value into a BEAM float/0
.
converts an f32
value into a BEAM float/0
.
converts an f64
value into a BEAM float/0
.
converts a Zig char slice ([]u8
) into a BEAM atom/0
.
converts a Zig char slice ([]u8
) into a BEAM binary/0
.
no memory allocation inside of Zig is performed and the BEAM environment is responsible for the resulting binary. You are responsible for managing the allocation of the slice.
converts an c string ([*c]u8
) into a BEAM binary/0
. Mostly used for
c interop.
no memory allocation inside of Zig is performed and the BEAM environment is responsible for the resulting binary. You are responsible for managing the allocation of the slice.
converts a slice of term
s into a BEAM tuple/0
.
converts a slice of term
s into a BEAM list/0
.
converts a Zig char slice ([]u8
) into a BEAM charlist/0
.
converts a c string ([*c]u8
) into a BEAM charlist/0
.
make_list(comptime T: type, environment: env, val: []T) !term
View Source (comptime)A helper to make BEAM lists out of slices of term
. Use this function if
you need a generic listbuilding function.
uses the BEAM allocator internally. If you would like to use a custom
allocator, (for example an arena allocator, if you have very long lists),
use make_list_alloc/4
supported internal types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
make_list_alloc(comptime T: type, a: *Allocator, environment: env, val: []T) !term
View Source (comptime)A helper to make a BEAM t:Kernel.list
out of term
s, with any allocator.
Use this function if you need a generic listbuilding function.
supported internal types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
converts a c_int slice ([]c_int
) into a BEAM list of integer/0
.
converts a c_long slice ([]c_long
) into a BEAM list of integer/0
.
converts an i32 slice ([]i32
) into a BEAM list of integer/0
.
converts an i64 slice ([]i64
) into a BEAM list of integer/0
.
converts an f16 slice ([]f16
) into a BEAM list of float/0
.
converts an f32 slice ([]f32
) into a BEAM list of float/0
.
converts an f64 slice ([]f64
) into a BEAM list of float/0
.
converts a bool
value into a boolean/0
value.
creates a beam nil
value.
creates a beam ok
value.
creates a beam error
value.
make_ok_tuple(comptime T: type, environment: env, val: T) term
View Source (comptime)A helper to make {:ok, term}
terms from arbitrarily-typed values.
supported types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
Use make_ok_term/2
to make ok tuples from generic terms.
Use make_ok_atom/2
to make ok tuples with atom terms from slices.
A helper to make {:ok, binary}
terms from slices
A helper to make {:ok, atom}
terms from slices
A helper to make {:ok, term}
terms in general
make_error_tuple(comptime T: type, environment: env, val: T) term
View Source (comptime)A helper to make {:error, term}
terms from arbitrarily-typed values.
supported types:
c_int
c_long
isize
usize
u8
i32
i64
f16
f32
f64
Use make_error_term/2
to make error tuples from generic terms.
Use make_error_atom/2
to make atom errors from slices.
A helper to make {:error, atom}
terms from slices
A helper to make {:error, binary}
terms from slices
A helper to make {:error, term}
terms in general
Encapsulates e.enif_make_ref
and allows it to return a
FunctionClauseError.
this function is going to be dropped inside the suspend statement.
This function is used to communicate :enomem
back to the BEAM as an
exception.
The BEAM is potentially OOM-safe, and Zig lets you leverage that.
OOM errors from beam.allocator
can be converted to a generic erlang term
that represents an exception. Returning this from your NIF results in
a BEAM throw event.
This function is used to communicate :function_clause
back to the BEAM as an
exception.
By default Zigler will do argument input checking on value ingress from the dynamic BEAM runtime to the static Zig runtime. You can also use this function to communicate a similar error by returning the resulting term from your NIF.
This function is used to communicate :resource_error
back to the BEAM as an
exception.
This function is used to communicate :assertion_error
back to the BEAM as an
exception.
Used when running Zigtests, when trapping beam.AssertionError.AssertionError
.
A function used to return assertion errors to a zigtest.
Zig's std.assert() will panic the Zig runtime and therefore the entire
BEAM VM, making it incompatible with Elixir's Unit tests. As the VM is
required for certain functionality (like e.enif_alloc
), a BEAM-compatible
assert is necessary.
When building zigtests, assert(...)
calls get lexically converted to
try beam.assert(...)
calls.