rumpk/libs/membrane/libc.nim

106 lines
3.6 KiB
Nim

# Markus Maiwald (Architect) | Voxis Forge (AI)
# libc.nim - Sovereign Libc for Nexus
# (C) 2026 Markus Maiwald
import ion_client
proc memcpy*(dest, src: pointer, n: uint64): pointer {.importc, cdecl.}
template copyMem*(dest, src: pointer, n: uint64) = discard memcpy(dest, src, n)
proc syscall*(nr: int, a0: uint64 = 0, a1: uint64 = 0, a2: uint64 = 0): int =
var res: int
let n = cast[uint64](nr)
let v0 = a0
let v1 = a1
let v2 = a2
{.emit: """
register unsigned long a7 __asm__("a7") = `n`;
register unsigned long a0_ __asm__("a0") = `v0`;
register unsigned long a1_ __asm__("a1") = `v1`;
register unsigned long a2_ __asm__("a2") = `v2`;
__asm__ volatile("ecall" : "+r"(a0_) : "r"(a7), "r"(a1_), "r"(a2_) : "memory");
`res` = (int)a0_;
""".}
return res
# --- LIBC IO SHIMS ---
proc write*(fd: int, buf: pointer, count: uint64): int {.exportc, cdecl.} =
# Always use syscall, even for stdout/stderr. Kernel handles it.
return int(syscall(0x204, uint64(fd), cast[uint64](buf), count))
proc read*(fd: int, buf: pointer, count: uint64): int {.exportc, cdecl.} =
return int(syscall(0x203, uint64(fd), cast[uint64](buf), count))
proc open*(path: cstring, flags: int = 0): int {.exportc, cdecl.} =
return int(syscall(0x200, cast[uint64](path), uint64(flags)))
proc close*(fd: int): int {.exportc, cdecl.} =
return int(syscall(0x201, uint64(fd)))
proc print*(s: string) =
if s.len > 0: discard write(1, unsafeAddr s[0], uint64(s.len))
proc readdir*(buf: pointer, max_len: uint64): int {.exportc, cdecl.} =
return int(syscall(0x202, cast[uint64](buf), max_len))
proc exit*(status: int) {.exportc, cdecl.} =
discard syscall(0x01, uint64(status))
while true: discard
proc yield_fiber*() {.exportc: "yield", cdecl.} =
discard syscall(0x100, 0)
proc pledge*(promises: uint64): int {.exportc, cdecl.} =
return int(syscall(0x101, promises))
proc spawn*(entry: pointer, arg: uint64): int {.exportc, cdecl.} =
return int(syscall(0x500, cast[uint64](entry), arg))
proc join*(fid: int): int {.exportc, cdecl.} =
return int(syscall(0x501, uint64(fid)))
proc upgrade*(id: int, path: cstring): int {.exportc, cdecl.} =
return -1 # Not implemented yet
proc get_vfs_listing*(): seq[string] =
var buf: array[4096, char]
let n = readdir(addr buf[0], 4096)
if n <= 0: return @[]
result = @[]
var current = ""
for i in 0..<n:
if buf[i] == '\n':
if current.len > 0:
result.add(current)
current = ""
else:
current.add(buf[i])
if current.len > 0: result.add(current)
# Surface API (Glyph)
proc sys_surface_create*(width, height: int): int {.exportc, cdecl.} =
return int(syscall(0x300, uint64(width), uint64(height)))
proc sys_surface_flip*(surf_id: int = 0) {.exportc, cdecl.} =
discard syscall(0x301, uint64(surf_id))
proc sys_surface_get_ptr*(surf_id: int): pointer {.exportc, cdecl.} =
return cast[pointer](syscall(0x302, uint64(surf_id)))
# Stubs for Glyph/NipBox compatibility
proc socket*(domain, sock_type, protocol: int): int {.exportc, cdecl.} = return -1
proc connect*(fd: int, addr_ptr: pointer, len: int): int {.exportc, cdecl.} = return -1
proc send*(fd: int, buf: pointer, count: uint64, flags: int): int {.exportc, cdecl.} = return 0
proc recv*(fd: int, buf: pointer, count: uint64, flags: int): int {.exportc, cdecl.} = return 0
proc lseek*(fd: int, offset: int, whence: int): int {.exportc, cdecl.} = return 0
proc fstat*(fd: int, buf: pointer): int {.exportc, cdecl.} = return 0
proc stat*(path: cstring, buf: pointer): int {.exportc, cdecl.} = return 0
proc membrane_init*() {.importc, cdecl.}
proc pump_membrane_stack*() {.importc, cdecl.}