Modules load their .so from priv/native in @on_load. A missing file is a load_nif error from OTP, not a silent Elixir fallback that pretends the function ran.
Mojoler.POC
add/2 :: integer, integer -> integer. Values that do not fit in signed 64 bits, non-integers, and overflowing sums raise ArgumentError.
Mojoler.Twice
double/1 :: integer -> integer. Same badarg policy. Implemented with the generated ABI. The source does not declare the NIF structs.
Mojoler.Term
Domain errors are {:error, atom}. Type errors are ArgumentError.
echo_i64/1,echo_u64/1,echo_i32/1,echo_u32/1add_i64/2->{:ok, n}|{:error, :overflow}echo_f64/1— no integer coercionecho_atom/1—:ok,:error,:nil,true,false, otherwise{:error, :unknown_atom}copy_binary/1->{:ok, binary, nbytes}|{:error, :not_binary | :too_large | :alloc}. The size cap is 1_048_576 bytes.borrow_stable/1->{:ok, size, 1 | 0}|{:error, :not_binary}fill_output/1->{:ok, binary}filled with the byte 7, or{:error, :bad_size}text_len/1->{:ok, byte_size}|{:error, :invalid_utf8 | :not_binary}tuple_sum/1— arity 2. Errors::not_tuple,:bad_arity,:bad_element,:overflowlist_sum/1— proper list, at most 64 integers. Errors::not_list,:improper_list,:too_long,:bad_element,:overflowmap_n/1— keyn. Extra keys are dropped. Errors::missing,:bad_element,:map
Mojoler.Own
open_counter/0returns a reference.counter_add/2->{:ok, n}|{:error, :closed}.counter_close/1->:ok, including a second close. A foreign handle raisesArgumentError. Collection sends:counter_destroyedonce.open_blob/1-> reference |{:error, :not_binary}blob_borrow/1->{:ok, size}|{:error, :not_mutable}blob_release/1andblob_close/1->:okblob_freeze/1->{:ok, binary}|{:error, :borrowed | :frozen}blob_token/1->{:ok, integer}blob_poke/3->:ok|{:error, :not_mutable | :bounds}. A byte outside0..255raisesArgumentError.blob_pin/1returns a reference.blob_dtors/0returns how many blob destructors have run.retain_binary/1returns a reference.read_retained/1returns the copied term.
The resource binary from a successful freeze stays valid after blob_close/1.
Mojoler.Sched
burn/1 and hold/2 run on a dirty CPU scheduler. io_ping/0 runs on a dirty I/O scheduler. Task.yield/2 does not cancel them.
Mojoler.Dsl
Generated from tools/dsl/decls.json.
Mojoler.Dsl.Arith.add/2->{:ok, n}|{:error, :overflow}Mojoler.Dsl.Bytes.shift/1->{:ok, binary, nbytes}Mojoler.Dsl.Bytes.borrow_len/1->{:ok, size}|{:error, :not_binary}Mojoler.Dsl.Box.open/0,bump/2
Mix tasks
mix compile— includescompile.mojolermix mojoler.doctormix mojoler.abimix mojoler.inspect— optional path, defaultpriv/native/libpoc.so
Not in this API
Raw pointers, a promise that add/2 is faster than Elixir, GPU as a default dependency, and cancellation of a running NIF. Ownership rules are ownership.md.