import socket import ../../core/ion/memory import ion_client proc console_write(p: pointer, len: csize_t) {.importc, cdecl.} proc membrane_init*() {.importc, cdecl.} proc pump_membrane_stack*() {.importc, cdecl.} # --- SYSCALL PRIMITIVE --- proc syscall*(nr: int, a0: int = 0, a1: int = 0, a2: int = 0): int {.inline.} = var res: int asm """ mv a7, %1 mv a0, %2 mv a1, %3 mv a2, %4 ecall mv %0, a0 : "=r"(`res`) : "r"(`nr`), "r"(`a0`), "r"(`a1`), "r"(`a2`) : "a0", "a7", "memory" """ return res # --- POSIX SOCKET API SHIMS --- type SockAddrIn = object sin_family: uint16 sin_port: uint16 sin_addr: uint32 sin_zero: array[8, char] proc socket*(domain, sock_type, protocol: int): int {.exportc, cdecl.} = return new_socket() proc connect*(fd: int, sock_addr: pointer, len: int): int {.exportc, cdecl.} = if sock_addr == nil: return -1 let sin = cast[ptr SockAddrIn](sock_addr) return connect_flow(fd, sin.sin_addr, sin.sin_port) proc send*(fd: cint, buf: pointer, count: csize_t, flags: cint): int {.exportc, cdecl.} = return send_flow(int(fd), buf, int(count)) proc recv*(fd: cint, buf: pointer, count: csize_t, flags: cint): int {.exportc, cdecl.} = return recv_flow(int(fd), buf, int(count)) # --- LIBC IO SHIMS --- proc write*(fd: cint, buf: pointer, count: csize_t): int {.exportc, cdecl.} = if fd == 1 or fd == 2: when defined(is_kernel): return -1 else: console_write(buf, count) return int(count) let sys = cast[ptr SysTable](SYS_TABLE_ADDR) if sys.fn_vfs_write != nil: let f = cast[proc(fd: int32, buf: pointer, count: uint64): int64 {.cdecl.}]( sys.fn_vfs_write) return int(f(int32(fd), buf, uint64(count))) if fd >= 100: return send_flow(int(fd), buf, int(count)) # File Write (Syscall 0x204) return syscall(0x204, int(fd), cast[int](buf), int(count)) # Stdin buffer for input packets var stdin_buf: array[128, byte] var stdin_len: int = 0 var stdin_pos: int = 0 proc read*(fd: cint, buf: pointer, count: csize_t): int {.exportc, cdecl.} = if fd == 0: if stdin_pos < stdin_len: let remaining = stdin_len - stdin_pos let to_copy = if remaining > int(count): int(count) else: remaining copyMem(buf, addr stdin_buf[stdin_pos], to_copy) stdin_pos += to_copy if stdin_pos >= stdin_len: stdin_len = 0 stdin_pos = 0 return to_copy # Poll input ring var pkt: IonPacket if ion_user_input(addr pkt): let len = min(int(pkt.len), 128) copyMem(addr stdin_buf[0], pkt.data, len) stdin_len = len stdin_pos = 0 ion_user_return(pkt.id) let to_copy = if stdin_len > int(count): int(count) else: stdin_len copyMem(buf, addr stdin_buf[0], to_copy) stdin_pos += to_copy return to_copy return 0 if fd >= 100: return recv(fd, buf, count, 0) # Try SysTable first let sys = cast[ptr SysTable](SYS_TABLE_ADDR) if sys.fn_vfs_read != nil: let f = cast[proc(fd: int32, buf: pointer, count: uint64): int64 {.cdecl.}]( sys.fn_vfs_read) return int(f(int32(fd), buf, uint64(count))) return syscall(0x203, int(fd), cast[int](buf), int(count)) proc exit*(status: cint) {.exportc, cdecl.} = discard syscall(0, 0) while true: discard proc open*(pathname: cstring, flags: cint): cint {.exportc, cdecl.} = let sys = cast[ptr SysTable](SYS_TABLE_ADDR) if sys.fn_vfs_open != nil: return cint(sys.fn_vfs_open(pathname, int32(flags))) return cint(syscall(0x200, cast[int](pathname), int(flags))) proc close*(fd: cint): cint {.exportc, cdecl.} = if fd >= 100: return 0 # Try SysTable first let sys = cast[ptr SysTable](SYS_TABLE_ADDR) if sys.fn_vfs_close != nil: let f = cast[proc(fd: int32): int32 {.cdecl.}](sys.fn_vfs_close) return cint(f(int32(fd))) return cint(syscall(0x201, int(fd))) proc nexus_list*(buf: pointer, len: int): int {.exportc, cdecl.} = let sys = cast[ptr SysTable](SYS_TABLE_ADDR) if sys.fn_vfs_list != nil: let f = cast[proc(buf: pointer, max_len: uint64): int64 {.cdecl.}]( sys.fn_vfs_list) return int(f(buf, uint64(len))) return syscall(0x202, cast[int](buf), len) # moved to top proc sleep*(seconds: uint32) {.exportc, cdecl.} = var i: int = 0 let limit = int(seconds) * 50_000_000 while i < limit: i += 1 # --- PHASE 29: WORKER MODEL (THE HIVE) --- proc spawn*(entry: proc(arg: uint64) {.cdecl.}, arg: uint64 = 0): int {.exportc, cdecl.} = ## Spawn a new worker fiber ## Returns: Fiber ID on success, -1 on failure return syscall(0x500, cast[int](entry), int(arg)) proc join*(fid: int): int {.exportc, cdecl.} = ## Wait for worker fiber to complete ## Returns: 0 on success, -1 on failure return syscall(0x501, fid) # --- PHASE 28: PLEDGE --- proc pledge*(promises: uint64): int {.exportc, cdecl.} = ## Reduce capabilities (one-way ratchet) ## Returns: 0 on success, -1 on failure let sys = cast[ptr SysTable](SYS_TABLE_ADDR) if sys.fn_pledge != nil: return int(sys.fn_pledge(promises)) return -1 # --- HIGH LEVEL HELPERS --- import strutils, sequtils proc get_vfs_listing*(): seq[string] = var buf = newString(4096) let n = nexus_list(addr buf[0], 4096) if n > 0: buf.setLen(n) return buf.splitLines().filterIt(it.strip().len > 0) return @[]