Files
sx/examples/ffi-04-fp-struct.sx
agra 3855f2351e ffi: move test-companion .c/.h next to their .sx (drop vendors/ namespace)
vendors/ is a third-party namespace (stb_image, kb_text_shape, etc.);
test fixtures don't belong there. The .c/.h companion files for the
Phase-0 FFI baselines now sit alongside the .sx that drives them in
examples/, with matching basenames:

  examples/ffi-01-primitives.{sx,c,h}    <- was vendors/ffi_primitives/
  examples/ffi-02-small-struct.{sx,c,h}  <- was vendors/ffi_structs/
  examples/ffi-03-large-struct.{sx,c,h}  <- was vendors/ffi_large_struct/
  examples/ffi-04-fp-struct.{sx,c,h}     <- was vendors/ffi_fp_struct/
  examples/ffi-05-string-args.{sx,c,h}   <- was vendors/ffi_strings/
  examples/ffi-06-callback.{sx,c,h}      <- was vendors/ffi_callback/
  examples/101-ffi-medium-struct.{sx,c}  <- was vendors/ffi_medium_struct/

`#source` / `#include` paths in the .sx files become bare filenames
(no prefix) since imports.zig's base_dir resolution finds them
relative to the importing .sx file's directory.

`library/vendors/sx_ffi_resolve_test/` stays put — that one's the
whole point: regression coverage for the stdlib-search branch of
the resolution chain, so it must live where ONLY that branch can
find it.

94/94 regression tests pass.
2026-05-19 11:54:36 +03:00

50 lines
2.1 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Phase 0 baseline (PLAN-FFI.md step 0.4): focused FP-aggregate (HFA)
// FFI test. All-float / all-double aggregates of ≤4 fields stay as
// struct values in LLVM and pass through the float register file
// (AAPCS64 v0..v3, SysV AMD64 xmm0..xmm7). Distinct from the int
// register-coercion paths (i64 / [2 x i64]).
//
// FQuad — 16 B, four f32 (same slot as ffi-02's Vec4f)
// DQuad — 32 B, four f64 (UIEdgeInsets-shape HFA — the
// f32-vs-f64 landmine from this session)
//
// Already nominally covered by ffi-02's Vec4f, but pinning it as a
// focused single-file test means a future ABI rule change that
// breaks the FP path fails *this* test directly without a noisy
// drag-in from the multi-shape baseline.
#import "modules/std.sx";
#import c {
#source "ffi-04-fp-struct.c";
};
FQuad :: struct { a: f32; b: f32; c: f32; d: f32; }
DQuad :: struct { a: f64; b: f64; c: f64; d: f64; }
ffi_fquad_make :: (a: f32, b: f32, c: f32, d: f32) -> FQuad #foreign;
ffi_fquad_reverse :: (v: FQuad) -> FQuad #foreign;
ffi_fquad_sum :: (v: FQuad) -> f32 #foreign;
ffi_dquad_make :: (a: f64, b: f64, c: f64, d: f64) -> DQuad #foreign;
ffi_dquad_reverse :: (v: DQuad) -> DQuad #foreign;
ffi_dquad_sum :: (v: DQuad) -> f64 #foreign;
main :: () -> s32 {
// ── FQuad (16 B, 4×f32 HFA) ────────────────────────────────────
f := ffi_fquad_make(1.0, 2.0, 3.0, 4.0);
print("fquad make = ({}, {}, {}, {})\n", f.a, f.b, f.c, f.d);
g := ffi_fquad_reverse(f);
print("fquad rev = ({}, {}, {}, {})\n", g.a, g.b, g.c, g.d);
print("fquad sum = {}\n", ffi_fquad_sum(f));
// ── DQuad (32 B, 4×f64 HFA — UIEdgeInsets-shape) ──────────────
d := ffi_dquad_make(1.5, 2.5, 3.5, 4.5);
print("dquad make = ({}, {}, {}, {})\n", d.a, d.b, d.c, d.d);
e := ffi_dquad_reverse(d);
print("dquad rev = ({}, {}, {}, {})\n", e.a, e.b, e.c, e.d);
print("dquad sum = {}\n", ffi_dquad_sum(d));
0;
}