cif := &types.CallInterface{}
ffi.PrepareCallInterface(cif, types.DefaultCall, retType, argTypes) // once
ffi.CallFunction(cif, fnPtr, &result, args) // many times, zero alloc
Type classification is pre-computed at prepare time, not at call time. The call path is: Go → runtime.cgocall → hand-written asm → C function. The asm loads GP/FP registers per ABI from a flat argument buffer — no interpretation at call time.