Affix
view release on metacpan or search on metacpan
- \[infix] Fixed `long double` handling on macOS Intel (Darwin). Verified that Apple adheres to the System V ABI for this type: it requires 16-byte stack alignment and returns values on the x87 FPU stack (`ST(0)`).
- \[infix] Fixed a generic System V ABI bug where 128-bit types (vectors, `__int128`) were not correctly aligned to 16 bytes on the stack relative to the return address, causing data corruption when mixed with odd numbers of 8-byte arguments.
- \[infix] Enforced natural alignment for stack arguments in the AAPCS64 implementation. Previously, arguments were packed to 8-byte boundaries, which violated alignment requirements for 128-bit types.
- \[infix] Fixed a critical deployment issue where the public `infix.h` header included an internal file (`common/compat_c23.h`). The header is now fully self-contained and defines `INFIX_NODISCARD` for attribute compatibility.
- \[infix] Fixed 128-bit vector truncation on System V x64 (Linux/macOS). Reverse trampolines previously used 64-bit moves (`MOVSD`) for all SSE arguments, corrupting the upper half of vector arguments. They now correctly use `MOVUPS`.
- \[infix] Fixed vector argument corruption on AArch64. The reverse trampoline generator now correctly identifies vector types and uses 128-bit stores (`STR Qn`) instead of falling back to 64-bit/32-bit stores or GPRs.
- \[infix] Fixed floating-point corruption on Windows on ARM64. Reverse trampolines now force full 128-bit register saves for all floating-point arguments to ensure robust handling of volatile register states.
- \[infix] Fixed a logic error in the System V reverse argument classifier where vectors were defaulting to `INTEGER` class, causing the trampoline to look in `RDI`/`RSI` instead of `XMM` registers.
- \[infix] Fixed potential cache coherency issues on Windows x64. The library now unconditionally calls `FlushInstructionCache` after JIT compilation.
- \[infix] Capped the maximum alignment in `infix_type_create_packed_struct` to 1MB to prevent integer wrap-around bugs in layout calculation.
- \[infix] Fixed a buffer overread on macOS ARM64 where small signed integers were loaded using 32-bit `LDRSW`. Implemented `LDRSH` and `LDRSB`.
- \[infix] Added native support for Apple's Hardened Runtime security policy.
- The JIT engine now utilizes `MAP_JIT` when the `com.apple.security.cs.allow-jit` entitlement is detected.
- Implemented thread-local permission toggling via `pthread_jit_write_protect_np` to maintain W^X compliance.
## [v1.0.5] - 2026-01-11
### Changed
- Affix::Wrap allows you to define your own types just in case the headers fail to parse completely.
## [v1.0.4] - 2026-01-10
This should just be a documentation cleanup cycle.
## [v1.0.3] - 2026-01-07
Based on infix v0.1.3
### Added
- Support for Variadic Functions (varargs):
- Implemented dynamic JIT compilation for C functions with variable arguments (e.g., `printf`).
- Added `variadic_cache` to cache trampolines for repeated calls, ensuring high performance.
- Implemented runtime type inference: Perl integers promote to `sint64`, floats to `double`, and strings to `*char`.
- Added `Affix::coerce($type, $value)` to explicitly hint types for variadic arguments. This allows passing structs by value or forcing specific integer widths where inference is insufficient.
- Cookbook: I'm putting together chapters on a wide range of topics at https://github.com/sanko/Affix.pm/discussions/categories/recipes
- `affix` and `wrap` functions now accept an address to bind to. This expects the library to be `undef` and jumps past the lib location and loading steps.
- Added `File` and `PerlIO` types.
- Allows passing Perl filehandles to C functions expecting standard C streams (`PerlIO*` => `Pointer[PerlIO]`).
- Allows receiving `FILE*` from C and using them as standard Perl filehandles (`FILE*` => `Pointer[File]`).
- A few new specialized pointer types:
- `StringList`: Automatically marshals an array ref of strings to a null-terminated `char**` array (and back). This is useful in instances where `argv` or a similar list is expected.
- `Buffer`: Allows passing a pre-allocated scalar as a mutable `char*` buffer to C (zero-copy write).
- `SockAddr`: Safe marshalling of Perl packed socket addresses to `struct sockaddr*`.
- Affix::Build: A polyglot shared library builder. Currently supports Ada, Assembly, C, C#, C++, Cobol, Crystal, Dlang, Eiffel, F#, Fortran, Futhark, Go, Haskell, Nim, OCaml, Odin, Pascal, Rust, Swift, Vlang, and Zig.
- Affix::Wrap: An experimental tool to introspect C header files and generate Affix bindings and documentation.
- Dual-Driver Architecture:
- `Affix::Wrap::Driver::Clang`: Uses the system `clang` executable to parse the AST for high-fidelity extraction of types, macros, and comments.
- `Affix::Wrap::Driver::Regex`: A zero-dependency fallback driver that parses headers using heuristics.
### Changed
- `Array[Char]` function arguments now accept Perl strings directly, copying the string data into the temporary C array.
- `Affix::errno()` now returns a dualvar containing both the numeric error code (`errno`/`GetLastError`) and the system error string (`strerror`/`FormatMessage`).
### Fixed
- Correctly implemented array decay for function arguments on ARM and Win64. `Array[...]` types are now marshalled into temporary C arrays and passed as pointers, matching standard C behavior. Previously, they were incorrectly passed by value, caus...
- Fixed binary safety for `Array[Char/UChar]`. Reading these arrays now respects the explicit length rather than stopping at the first null byte.
- The write-back mechanism no longer attempts to overwrite the read-only ArrayRef scalar with the pointer address.
- `Pointer[SV]` is now handled properly as args, return values, and in callbacks. Reference counting is automatic to prevent premature garbage collection of passed scalars.
- Shared libs written in Go spin up background threads (for GC and scheduling) that do not shut down cleanly when a shared library is unloaded. This often causes access violations on Windows during program exit. We attempt to work around this by de...
## [v1.0.2] - 2025-12-14
### Changed
- In an attempt to debug mystery failures in SDL3.pm, Affix.pm will warn and return `undef` instead of `croak`ing.
- Improved error reporting: if the internal error message is empty, the numeric error code is now included in the warning.
### Fixed
- [[infix]] Fixed a critical file descriptor leak on POSIX platforms (Linux/FreeBSD) where the file descriptor returned by `shm_open` was kept open for the lifetime of the trampoline, eventually hitting the process file descriptor limit (EMFILE). T...
- Fixed memory leaks that occurred when trampoline creation failed midway (cleaning up partial arenas, strings, and backend structures).
## [v1.0.1] - 2025-12-13
### Changed
- Improved Union marshalling: Union members are now exposed as pins within the hash. This allows clean syntax (like `$u->{member} = 5`) without needing to dereference a reference, while maintaining C-memory aliasing.
### Fixed
- Fixed `writeback_pointer_generic` to support writing back to scalar output parameters (pointers-to-pointers). This resolves issues where C functions returning handles via arguments would fail to populate the SV*/pin.
## [v1.0.0] - 2025-12-13
- Stable? Stable. Stable enough.
## [v0.12.0] - 2025-12-12
### Changed
- Affix is reborn! This is a complete rewrite
- Replaced dyncall with a JIT and introspection engine I've called [infix](https://github.com/sanko/infix.git)
## [0.11] - 2023-03-30
### Added
- Support for WChar
- Rough, basic support for mangled symbols:
- Itanium C++ ABI
- Rust (legacy)
- Expose dcNewCallVM( ... ) size variable
## [0.10] - 2023-03-11
### Changed
- Support for ArrayRef[] with dynamic size
- Support for empty Stuct[]
- Coerce Enum[] types with sv2ptr(...)
- Explicit undef values are turned into NULL in Pointer[], ArrayRef[], etc.
- Provide default values in Struct[]
- Ignore perl's PTRSIZE which might be different than the system's actual pointer size
- Cleanup VM on Affix::END()
- Simplify API around named subs
- Support for WStr (wchar_t *, PWSTR, etc.)
( run in 1.248 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )