{"atom":"regression/nativecall-features","family":"regression","slug":"nativecall-features","header":{"atom":"regression/nativecall-features","kind":"whole-program — a minimal repro, not yet reduced to an atom","source":"curated"},"axes":null,"cols":null,"engines":["rakudo-2026.07","rakupp-3.14.0"],"kinds":["ref","pp"],"defFrom":"rakupp:t/regression/nativecall-features.raku","counts":{"a":0,"f":0,"d":0,"c":0,"r":1,"n":0},"files":["atoms/regression/nativecall-features.grid"],"records":[["0001","","# Regression: NativeCall features 1-6, all against system libc/libm (present on\n# every arch, so portable):\n#   1. is rw / native-reference out-params (T* with copy-back)\n#   2. mixed int + float arguments (both orderings)\n#   3. nativecast\n#   4. cglobal\n#   5. Pointer.new / .deref / .defined / Pointer[T]\n#   6. CArray element read — byte-backed and live (native memory)\n# Contract: exit 0 + last line PASS.\nmy @fail;\n\n# 1. is rw write-back: time(time_t*) fills the out-param and returns the same value\nsub c_time(int64 $t is rw) returns int64 is native is symbol('time') {*}\nmy int64 $t = 0;\nmy $now = c_time($t);\n@fail.push(\"is-rw ($t vs $now)\") unless $t != 0 && $t == $now;\n\n# 2. mixed int/float args, both orderings. libm's symbols live in the default\n# namespace on macOS (libSystem) but not always on Linux — guard resolution, so a\n# wrong result still fails while an unresolved symbol just skips.\nsub ldexp(num64, int32) returns num64 is native {*}   # float, int\nmy $ld = try { ldexp(1.5e0, 3) };\nwith $ld { @fail.push(\"mixed-float-int ($ld)\") unless $_ == 12e0 }\nelse     { note '# ldexp (libm) not resolvable here — skipping mixed float,int' }\nsub jn(int32, num64) returns num64 is native {*}        # int, float\nmy $j0 = try { jn(0, 0e0) };                            # J0(0) = 1\nwith $j0 { @fail.push(\"mixed-int-float ($j0)\") unless $_ == 1e0 }\nelse     { note '# jn (libm) not resolvable here — skipping mixed int,float' }\n\n# 3. nativecast: int address <-> Pointer\nmy $p = nativecast(Pointer, 4242);\n@fail.push('nativecast-ptr') unless $p.Int == 4242;\n\n# 4. cglobal: read a libc global. sys_nerr is a small int on BSD/macOS libc but was\n# removed from modern glibc — guard so Linux skips rather than crashing.\nmy $ne = try { cglobal('c', 'sys_nerr', int32) };\nwith $ne { @fail.push(\"cglobal ($ne)\") unless $ne ~~ Int && $ne >= 0 }\nelse     { note '# cglobal sys_nerr not present here (glibc dropped it) — skipping' }\n\n# 5. Pointer API\n@fail.push('pointer-null')    unless !Pointer.new.defined;\n@fail.push('pointer-addr')    unless Pointer.new(999).Int == 999;\n\n# 6. CArray element read — byte-backed\nmy $c = CArray[uint8].new(65, 66, 67);\n@fail.push('carray-bytes') unless $c[0] == 65 && $c[1] == 66 && $c[2] == 67;\n# 6b. live CArray over native memory: getenv returns char*, read its first bytes\nsub c_getenv(Str) returns Pointer is native is symbol('getenv') {*}\nmy $hp = c_getenv('PATH');\nif $hp.defined && $hp.Int != 0 {\n    my $arr = nativecast(CArray[uint8], $hp);\n    @fail.push('carray-live') unless $arr[0] > 0;   # PATH is non-empty\n}\n\nif @fail { note \"FAILED: @fail[]\"; say 'FAIL' } else { say 'PASS' }","output PASS","r",["exit 1","PASS"],{"v":"disputed","w":"the reference implementation does not satisfy the program's own contract here (exit 0 with a last line of PASS) — it needs modules that are not installed, or exercises something only one engine implements; there is no reference observation to rule against","d":"2026-08-14 against rakudo-2026.07"},[["budget","20s"]]]]}