Affix
view release on metacpan or search on metacpan
# Changelog
All notable changes to Affix.pm will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.2.5] - 2026-08-17
### Fixed
- `SAVEVPTR`/`SAVEDESTRUCTOR_X` 'fix' broke thread safety. When a second thread or fiber entered the same Affix-generated XSUB, its `SAVEVPTR` captured the first fiber's temp arena as "old", so on scope exit the second fiber restored a dangling point...
## [v1.2.4] - 2026-08-15
Plugging leaks...
### Fixed
- Use `SAVEVPTR` and `SAVEDESTRUCTOR_X` to swap out arenas to fix leaky allocator in situations where tons of structs are passed in a list and need to be marshalled in only one direction
- Casting or binding an aggregate (`Affix::cast`, member pins) no longer leaks: member pins borrowed the freshly created parent hash/array as their lifeline, forming a strong reference cycle that Perl's refcounting cannot collect, so the whole pin tr...
- Passing a union to a wrapped call no longer segfaults: the argument sync read back *every* union member, and reading an inactive pointer/string member dereferenced the active member's float bytes as a C string pointer. Deep writes now skip members ...
- The library probe in `Affix::Platform::Unix` (`_findLib_gcc`) no longer prints linker errors (`undefined reference to WinMain`/`main`) while searching: it probes with `-shared`, which needs no entry point.
- Bitfields inside `Struct[...]` are no longer read or written out of bounds: `member->offset` now points at the storage unit base (with `bit_offset` relative to the unit) instead of the bitfield's own byte, so the unit-sized load/store in `push_stru...
- Reading and writing packed struct members (and pinned primitives) no longer uses unaligned native loads/stores: the dispatch vtables, bitfield vtables, pull handlers, and push handlers now round-trip through `memcpy`, which is safe on strict-alignm...
- Passing a wide string (`WString()`, i.e. `*wchar_t`) to a wrapped function now works on all platforms instead of croaking `Don't know how to handle this type of scalar as a pointer argument yet` on non-Windows systems, where the wide-string push op...
- Returning a `WString` no longer crashes: the wide-string pull handler called `SvGROW` on an uninitialized target SV, faulting before any buffer was allocated.
- [infix] Passing a 5-7 byte `Struct[...]` by value to a wrapped function no longer drops the trailing members on ARM64. The forward trampoline emitted a 32-bit register load unless the struct was exactly 8 bytes, so a `Struct[ arr => Array[2, UInt16...
## [v1.2.3] - 2026-08-08
### Fixed
- `Struct[...]` fields of type `WString` can now be assigned to (or as?) Perl strings (`SvPV`) rather than falling through and becoming null pointers
## [v1.2.2] - 2026-08-05
The headline is support for RISC-V!
### Fixed
- `malloc()`/`calloc()` pins no longer lose their `Affix::Memory` lifeline: the memory is kept alive for as long as any derived pin exists (fixes a use-after-free where the block could be handed out to a later allocation), and `free()` now works on p...
- `realloc()` no longer corrupts the `Affix::Memory` reference header when updating the stored address.
- [infix] Layout recalculation now descends into reverse trampolines, so a `Struct[...]` declared inline in a signature whose members referenced named types no longer has corrupted offsets.
### Added
- [infix] Support for RISC-V (rv64)
## [v1.2.1] - 2026-08-02
### Fixed
- Fixed `panic: free ... from wrong pool` crash at process exit on perls built with both debugging and threads enabled.
## [v1.2.0] - 2026-07-29
### Changed
- Affix::Build tests have been fenced off as author tests.
## [v1.1.0] - 2026-07-25
### Added
- V2 Pin System: Replaced the old `Affix_Pin` struct with `Affix_Pin_2_Point_Oh` backed by Perl Magic VTables, eliminating tied-variable overhead for all memory access.
- Reworked `Affix::Wrap` type parser to handle `const`, `restrict`, and `volatile` qualifiers, improved function pointer matching, and refactored the type map for cleaner code generation.
- Generated `Affix::Wrap` bindings now emit `Const[...]` for C `const`-qualified types, enabling compile-time safety in wrapper output.
- Added `Const[...]` type wrapper that prevents Perl-side mutation of C memory marked `const`. Replaces the old `Live` helper.
- Added struct bitfield array syntax so members can be declared as `[$name, $type, $width]`.
- Enum definitions now accept explicit integer values and arithmetic expressions (`FOO => BAR | 0x8`) in addition to sequential auto-increment.
- [infix] Added support for preserving character-specific primitive names (`wchar_t`, `char16_t`, `char32_t`, `char8_t`), enabling correct identification of string buffers via `infix_type_get_name()`.
### Changed
- WChar now maps to the platform-correct `wchar_t` type (uint16 on Windows, uint32 elsewhere) instead of hardcoded `uint16`.
- WString now platform-dependent (`*uint16` on Windows, `*uint32` elsewhere).
- StringList redefined as `Pointer[Pointer[Char]]` instead of the `@StringList` alias.
- Extended `_is_signature_string` to recognize `+`, `c[...]`, `v[...]`, and `e:` prefixed type strings.
- Do not rewind `args_arena` so pointers survive XSUB return (hopefully callee stored them).
### Fixed
- Fixed struct member callback assignment where `$pin->{fn} = sub { ... }` silently created a trampoline with 0 arguments, causing "Too few arguments" errors or crashes when C called through the function pointer. `Pointer[Callback[...]]` creates a do...
- `set_ptr` now croaks when a coderef is assigned to a non-callback pointer type instead of silently creating a broken 0-argument trampoline.
( run in 0.826 second using v1.01-cache-2.11-cpan-64ef6c95b5d )