amf_sys.rs mirrors five AMF COM vtables by hand and amf.rs dispatches through
them BY SLOT POSITION — 18 distinct slots across the five tables. The mirrors
carried 118 `Slot` placeholders whose only job is to hold the following slots at
their C offsets, and not one layout assertion of any kind. A slot inserted,
removed or reordered in an AMF header bump calls an arbitrary function pointer
through a mismatched signature: no compile error, no runtime signal.
`AMF_MIN_VERSION` does not defend against this. It checks a version NUMBER, not
a layout, and it is a floor with no ceiling.
The three POD checks that did exist (`AmfVariant`, `AmfGuid`, `AmfHdrMetadata`)
lived in amf.rs's `#[cfg(test)]` module, so they were verified only when someone
ran pf-encode's tests, on Windows, with AMF enabled — and NEVER in a release
build, which is exactly where a mis-mirrored `AMFVariantStruct` does its damage:
it crosses the FFI BY VALUE on every SetProperty. This is the same hole
`a8dd348b` closed for the cuda.h mirrors and missed here.
Adds ~40 `const _: () = assert!(...)` guards next to the mirrors: size of each
of the five vtables, the byte offset of every slot amf.rs actually calls, the
three POD layouts promoted out of the test module, and the AMFData/AMFBuffer
shared-prefix agreement that `create_surface_from_dx11_native`'s
AMFSurface-through-AMFData reinterpretation silently depends on.
Verified by compiling amf_sys.rs standalone (it needs only `c_void`, and a
repr(C) struct of code pointers has the same layout on any 64-bit target, so a
macOS const-eval proves the Windows arithmetic), and by deliberately breaking one
offset to confirm the guard actually fires rather than silently passing.
That check earned its keep immediately: `alloc_buffer` sits at slot 43, not 42.
Counting AMFInterface(3) + AMFPropertyStorage(10) + the AMFContext block by hand
is exactly the error these assertions exist to catch.
Zero runtime behaviour change. The `AMF_MIN_VERSION` ceiling is deliberately NOT
part of this commit: a ceiling would make the next AMF driver release refuse
encode on every AMD box, so it needs a warn-and-continue policy plus an env
override and a real AMF session to gate it.