Changelog
View Source[0.4.0] - 2026-06-14
Elixir 1.20 and Erlang/OTP 29 support, plus safer atom creation.
Breaking
- Minimum Elixir version is now 1.20 (was 1.18).
- Safe UTF-8 is now the default atom-creation path.
term::make_atomandterm::make_atom_lennow useenif_make_new_atom*(UTF-8, returning a fallibleTerm?withATOM_TABLE_FULL) instead of the oldenif_make_atom*(Latin1, infallible, aborts the VM when the atom table is full). The previous behavior is available unchanged asmake_atom_latin1/make_atom_latin1_len.make_atom_utf8/make_atom_utf8_lenremain as@deprecatedaliases of the new defaults.
Added
- Erlang/OTP 29 support. The NIF ABI is unchanged: c3nif still declares
ERL_NIF 2.17, which loads on OTP 26 through 29 (OTP 29's 2.18 is
major-compatible). New ERL_NIF 2.18 bindings are available for OTP-29-only
use —
enif_term_size,enif_get_atom_cache_index,enif_max_atom_cache_index— but the declared minor version is intentionally kept at 17 so NIFs remain loadable on OTP 26+; calling a 2.18 function on an older runtime fails NIF load. - CI on Erlang/OTP 29 + Elixir 1.20, building the library and running the
integration suite (which compiles and
load_nifs every fixture) as a build-and-load smoke test.
Fixed
- Elixir 1.20 deprecations and warnings:
File.stream!/3argument order inC3nif.Precompiled.file_checksum/1, a now-unused module-levelrequire LoggerinC3nif.Compiler, and unreachablecaseclauses in the integration tests flagged by the 1.20 type checker. Added:test_ignore_filtersso the test-support module no longer trips the newmix testfile-pattern warning.
[0.3.0] - 2026-06-06
Migration to C3 0.8.
Breaking
- Minimum C3 compiler version is now 0.8.0 (was 0.7.11). The codebase
was updated for 0.8 language changes:
@extern("name")bindings replaced with@cname("name")(the old attribute was removed).- Type-size access changed from
Type.sizeoftoType::size. - The
Allocatorinterface now takes signedszsizes/alignments, and implicit signed↔unsigned conversions were removed, soBeamAllocatorgained explicit casts. - Macro method dispatch via
value.#param(...)was removed; the@require_typemacro now usesvalue.$eval($stringify(#param))(...).
[0.2.0] - 2026-04-11
Modernization release: C3 0.7.11 + ERL_NIF 2.17 (OTP 26+), with a new precompiled NIF distribution pipeline.
Breaking
- Minimum C3 compiler version is now 0.7.11 (was 0.6.0). Updates all
source to the current C3 syntax:
enum Foo : const CIntdeclarations were converted toconstdef X : inline CInt, and fault-creation sites usereturn X~;instead of the deprecatedreturn X?;. - Minimum OTP version is now 26 (was effectively OTP 21). Required
for ERL_NIF 2.17 APIs such as
enif_make_new_atom,enif_set_option, and UTF-8 atom encoding. - Resource registry API hard break. The O(n) string-keyed lookup has
been removed.
resource::register_typenow returns anErlNifResourceType*handle that callers must cache at load time, and bothresource::allocandresource::gettake that handle instead of a string name. The 32-type cap (MAX_RESOURCE_TYPES) and the internal registry arrays are gone.get_resourcemacro andc3nif.c3aliases were updated to match. Seeguides/resources.mdfor the new pattern.
Added
- ERL_NIF 2.17 API surface. Bound
enif_make_new_atom,enif_make_new_atom_len,enif_get_string_length, and the threeenif_set_optionvariants (DELAY_HALT,ON_HALT,ON_UNLOAD_THREAD). Added theErlNifCharEncoding.UTF8variant andErlNifOption,OnHaltFn,OnUnloadThreadFntypes. - UTF-8 atom helpers in
term.c3:make_atom_utf8,make_atom_utf8_len,make_existing_atom_utf8. Unlike the oldermake_atompath, these return anATOM_TABLE_FULLfault instead of aborting the VM when the atom table is exhausted. - Halt-safety wrappers in
scheduler.c3:delay_halt,set_on_halt,set_on_unload_thread. Use from a NIF's load callback to keep long-running dirty NIFs from being killed mid-operation duringinit:stop/0,1. - Precompiled NIF distribution. New
C3nif.Precompiledmodule andmix c3nif.precompiletask for building, archiving, and SHA-256 verifying prebuilt shared libraries per target triple. Consumers opt in viause C3nif, precompiled: [base_url: ..., version: ..., checksums_path: ...]and get automatic source-build fallback when a precompiled artifact isn't available. Mirrors therustler_precompiledworkflow. Seeguides/precompilation.md.
Changed
C3nif.Compiler.compile/1now accepts an optional:targetkey that is forwarded toc3c build --target <triple>. The c3c invocation was refactored into a sharedrun_c3c/2helper used by both the regular compile path and the precompile task.- Removed the unused
jasondependency; C3nif uses the stdlibJSONmodule (Elixir 1.18+).
Fixed
test/integration/binary_test.exscopy-binary assertion no longer depends on OTP 25 internal allocation-size reporting.
[0.1.2] - 2026-01-15
Fixed
- Fix
c3nif_src_pathto work with path dependencies using__DIR__
[0.1.1] - 2026-01-15
Fixed
- Fix
Application.app_dir/2errors during initial compilation of projects using c3nif
[0.1.0]
Added
- Initial release
- C3 NIF runtime library with type-safe term handling
- Resource management with destructors and process monitoring
- Dirty scheduler support (CPU and IO bound)
- BEAM-tracked memory allocator
- Mix compiler integration
~nsigil for inline C3 code- Automatic NIF entry point generation via
<* nif: *>annotations