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.

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.

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 terms into a BEAM tuple/0.

converts a slice of terms into a BEAM list/0.

converts a Zig char slice ([]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 terms, 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

Link to this function

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
Link to this function

get_c_int(environment: env, src_term: term) !c_int

View Source

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

Link to this function

get_c_uint(environment: env, src_term: term) !c_uint

View Source

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

Link to this function

get_c_long(environment: env, src_term: term) !c_long

View Source

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

Link to this function

get_c_ulong(environment: env, src_term: term) !c_ulong

View Source

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

Link to this function

get_isize(environment: env, src_term: term) !isize

View Source

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

Link to this function

get_usize(environment: env, src_term: term) !usize

View Source

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

Link to this function

get_u8(environment: env, src_term: term) !u8

View Source

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

Link to this function

get_u16(environment: env, src_term: term) !u16

View Source

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

Link to this function

get_u32(environment: env, src_term: term) !u32

View Source

Takes a BEAM int term and returns a u32 value.

Raises beam.Error.FunctionClauseError if the term is not integer/0

Link to this function

get_u64(environment: env, src_term: term) !u64

View Source

Takes a BEAM int term and returns a u64 value.

Raises beam.Error.FunctionClauseError if the term is not integer/0

Link to this function

get_i32(environment: env, src_term: term) !i32

View Source

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

Link to this function

get_i64(environment: env, src_term: term) !i64

View Source

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

Link to this function

get_f16(environment: env, src_term: term) !f16

View Source

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

Link to this function

get_f32(environment: env, src_term: term) !f32

View Source

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

Link to this function

get_f64(environment: env, src_term: term) !f64

View Source

Takes a BEAM float term and returns an f64 value.

Raises beam.Error.FunctionClauseError if the term is not float/0

Link to this function

get_atom_slice(environment: env, src_term: atom) ![]u8

View Source

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

Link to this function

get_atom_slice_alloc(a: *Allocator, environment: env, src_term: atom) ![]u8

View Source

Takes 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

Link to this function

get_c_string(environment: env, src_term: term) ![*c]u8

View Source

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

Link to this function

get_char_slice(environment: env, src_term: term) ![]u8

View Source

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

Link to this function

get_binary(environment: env, src_term: term) !binary

View Source

Takes an BEAM binary/0 term and returns the corresponding binary struct.

Raises beam.Error.FunctionClauseError if the term is not binary/0

Link to this function

get_pid(environment: env, src_term: term) !pid

View Source

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

Link to this function

self(environment: env) !pid

View Source

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.

Link to this function

send(c_env: env, to_pid: pid, msg: term) bool

View Source

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

Link to this function

send_advanced(c_env: env, to_pid: pid, m_env: env, msg: term) bool

View Source

shortcut 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.

Link to this function

get_tuple(environment: env, src_term: term) ![]term

View Source

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

Link to this function

get_list_length(environment: env, list: term) !usize

View Source

Takes a BEAM list/0 term and returns its length.

Raises beam.Error.FunctionClauseError if the term is not list/0

Link to this function

get_head_and_iter(environment: env, list: *term) !term

View Source

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

Link to this function

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
Link to this function

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
Link to this function

get_bool(environment: env, val: term) !bool

View Source

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.

Link to this function

make(comptime T: type, environment: env, val: T) term

View Source (comptime)

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
Link to this function

make_u8(environment: env, chr: u8) term

View Source

converts a char (u8) value into a BEAM integer/0.

Link to this function

make_u16(environment: env, val: u16) term

View Source

converts a unsigned (u16) value into a BEAM integer/0.

Link to this function

make_u32(environment: env, val: u32) term

View Source

converts a unsigned (u32) value into a BEAM integer/0.

Link to this function

make_u64(environment: env, val: u64) term

View Source

converts a unsigned (u64) value into a BEAM integer/0.

Link to this function

make_c_int(environment: env, val: c_int) term

View Source

converts a c_int value into a BEAM integer/0.

Link to this function

make_c_uint(environment: env, val: c_uint) term

View Source

converts a c_uint value into a BEAM integer/0.

Link to this function

make_c_long(environment: env, val: c_long) term

View Source

converts a c_long value into a BEAM integer/0.

Link to this function

make_c_ulong(environment: env, val: c_ulong) term

View Source

converts a c_ulong value into a BEAM integer/0.

Link to this function

make_isize(environment: env, val: isize) term

View Source

converts an isize value into a BEAM integer/0.

Link to this function

make_usize(environment: env, val: usize) term

View Source

converts a usize value into a BEAM integer/0.

Link to this function

make_i32(environment: env, val: i32) term

View Source

converts an i32 value into a BEAM integer/0.

Link to this function

make_i64(environment: env, val: i64) term

View Source

converts an i64 value into a BEAM integer/0.

Link to this function

make_f16(environment: env, val: f16) term

View Source

converts an f16 value into a BEAM float/0.

Link to this function

make_f32(environment: env, val: f32) term

View Source

converts an f32 value into a BEAM float/0.

Link to this function

make_f64(environment: env, val: f64) term

View Source

converts an f64 value into a BEAM float/0.

Link to this function

make_atom(environment: env, atom_str: []const u8) term

View Source

converts a Zig char slice ([]u8) into a BEAM atom/0.

Link to this function

make_slice(environment: env, val: []const u8) term

View Source

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.

Link to this function

make_c_string(environment: env, val: [*c] const u8) term

View Source

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.

Link to this function

make_tuple(environment: env, val: []term) term

View Source

converts a slice of terms into a BEAM tuple/0.

Link to this function

make_term_list(environment: env, val: []term) term

View Source

converts a slice of terms into a BEAM list/0.

Link to this function

make_charlist(environment: env, val: [] const u8) term

View Source

converts a Zig char slice ([]u8) into a BEAM charlist/0.

Link to this function

make_cstring_charlist(environment: env, val: [*c] const u8) term

View Source

converts a c string ([*c]u8) into a BEAM charlist/0.

Link to this function

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
Link to this function

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 terms, 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
Link to this function

make_c_int_list(environment: env, val: []c_int) !term

View Source

converts a c_int slice ([]c_int) into a BEAM list of integer/0.

Link to this function

make_c_long_list(environment: env, val: []c_long) !term

View Source

converts a c_long slice ([]c_long) into a BEAM list of integer/0.

Link to this function

make_i32_list(environment: env, val: []i32) !term

View Source

converts an i32 slice ([]i32) into a BEAM list of integer/0.

Link to this function

make_i64_list(environment: env, val: []i64) !term

View Source

converts an i64 slice ([]i64) into a BEAM list of integer/0.

Link to this function

make_f16_list(environment: env, val: []f16) !term

View Source

converts an f16 slice ([]f16) into a BEAM list of float/0.

Link to this function

make_f32_list(environment: env, val: []f32) !term

View Source

converts an f32 slice ([]f32) into a BEAM list of float/0.

Link to this function

make_f64_list(environment: env, val: []f64) !term

View Source

converts an f64 slice ([]f64) into a BEAM list of float/0.

Link to this function

make_bool(environment: env, val: bool) term

View Source

converts a bool value into a boolean/0 value.

Link to this function

make_nil(environment: env) term

View Source

creates a beam nil value.

Link to this function

make_ok(environment: env) term

View Source

creates a beam ok value.

Link to this function

make_error(environment: env) term

View Source

creates a beam error value.

Link to this function

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.

Link to this function

make_ok_binary(environment: env, val: [] const u8) term

View Source

A helper to make {:ok, binary} terms from slices

Link to this function

make_ok_atom(environment: env, val: [] const u8) term

View Source

A helper to make {:ok, atom} terms from slices

Link to this function

make_ok_term(environment: env, val: term) term

View Source

A helper to make {:ok, term} terms in general

Link to this function

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.

Link to this function

make_error_atom(environment: env, val: [] const u8) term

View Source

A helper to make {:error, atom} terms from slices

Link to this function

make_error_binary(environment: env, val: [] const u8) term

View Source

A helper to make {:error, binary} terms from slices

Link to this function

make_error_term(environment: env, val: term) term

View Source

A helper to make {:error, term} terms in general

Link to this function

make_ref(environment: env) term

View Source

Encapsulates e.enif_make_ref and allows it to return a FunctionClauseError.

this function is going to be dropped inside the suspend statement.

Link to this function

raise_enomem(environment: env) term

View Source

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.

Link to this function

raise_function_clause_error(environment: env) term

View Source

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.

Link to this function

raise_resource_error(environment: env) term

View Source

This function is used to communicate :resource_error back to the BEAM as an exception.

Link to this function

raise_assertion_error(environment: env) term

View Source

This function is used to communicate :assertion_error back to the BEAM as an exception.

Used when running Zigtests, when trapping beam.AssertionError.AssertionError.

Link to this function

assert(ok: bool, file: []const u8, line: i64) !void

View Source

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.