implement our own readdir and strtol, syscall builtin

This commit is contained in:
2025-11-22 18:04:25 +01:00
parent 7cffd73406
commit ce54d1b560
2 changed files with 86 additions and 39 deletions

View File

@@ -106,7 +106,7 @@ section .text
);
// take that rustfmt
for name in "syscall,malloc,realloc,free,snprintf,strtol,system,opendir,readdir,closedir,gettimeofday,send,write,read,close,getchar,gethostbyname".split(",")
for name in "malloc,realloc,free,snprintf,system,gettimeofday,send,write,read,close,getchar,gethostbyname".split(",")
{
emit!(&mut self.output, "extern {}", name);
emit!(&mut self.output, "c.{} equ {}", name, name);
@@ -121,6 +121,12 @@ _builtin_read8:
mov al, byte [rdi]
ret
section .text._builtin_read16
_builtin_read16:
xor rax, rax
mov ax, word [rdi]
ret
section .text._builtin_read32
_builtin_read32:
mov eax, dword [rdi]
@@ -140,6 +146,18 @@ section .text._builtin_set64
_builtin_set64:
mov [rdi], rsi
ret
section .text._builtin_syscall
_builtin_syscall:
mov rax, rdi
mov rdi, rsi
mov rsi, rdx
mov rdx, rcx
mov r10, r8
mov r8, r9
mov r9, [rsp+8]
syscall
ret
"
);
Ok(())

View File

@@ -16,6 +16,9 @@ func mem.zero[x: I64, size: I64] : Void
func mem.read8[x: Ptr] : U8
return _builtin_read8(x)
func mem.read16[x: Ptr] : I64
return _builtin_read16(x)
func mem.read32[x: Ptr] : I64
return _builtin_read32(x)
@@ -29,7 +32,7 @@ func mem.write64[x: Ptr, d: I64] : Void
_builtin_set64(x, d)
func io.print[x: String] : Void
c.syscall(1, 1, x, str.len(x))
_builtin_syscall(1, 1, x, str.len(x))
func io.println[x: String] : Void
io.print(x)
@@ -38,7 +41,7 @@ func io.println[x: String] : Void
func io.print_char[x: U8] : Void
let s: String = mem.alloc(1)
str.set(s, 0, x)
c.syscall(1, 1, s, 1)
_builtin_syscall(1, 1, s, 1)
mem.free(s)
func io.print_i64[x: I64] : Void
@@ -53,33 +56,33 @@ func io.println_i64[x: I64] : Void
func io.read_stdin[]: String
let buffer: String = mem.alloc(1025)
let n: I64 = c.syscall(0, 0, buffer, 1024)
let n: I64 = _builtin_syscall(0, 0, buffer, 1024)
if n < 0
return ""
str.set(buffer, n, 0)
return buffer
func io.read_file[path: String]: String
let fd: I64 = c.syscall(2, path, 0, 0) // open
let fd: I64 = _builtin_syscall(2, path, 0, 0) // open
if fd <= 0
dbg.panic("failed to open file")
let size: I64 = c.syscall(8, fd, 0, 2) // lseek to the end
c.syscall(8, fd, 0, 0) // lseek back to start
let size: I64 = _builtin_syscall(8, fd, 0, 2) // lseek to the end
_builtin_syscall(8, fd, 0, 0) // lseek back to start
let buffer: String = mem.alloc(size + 1)
let n: I64 = c.syscall(0, fd, buffer, size) // read
let n: I64 = _builtin_syscall(0, fd, buffer, size) // read
str.set(buffer, n, 0)
c.syscall(3, fd) // close
_builtin_syscall(3, fd) // close
return buffer
func io.write_file[path: String, content: String] : Void
let fd: Ptr = c.syscall(2, path, 0x241, 0o644) // open
let fd: Ptr = _builtin_syscall(2, path, 0x241, 0o644) // open
if fd < 0
dbg.panic("failed to open file")
c.syscall(1, fd, content, str.len(content)) // write
c.syscall(3, fd) // close
_builtin_syscall(1, fd, content, str.len(content)) // write
_builtin_syscall(3, fd) // close
func str.len[s: String] : I64
let i: I64 = 0
@@ -195,7 +198,22 @@ func str.from_i64[n: I64] : String
return x
func str.parse_i64[s: String] : I64
return c.strtol(s, 0, 0)
let len: I64 = str.len(s)
let i: I64 = 0
let sign: I64 = 1
if i < len & s[i] == '-'
sign = -1
i = i + 1
let num: I64 = 0
while i < len
let d: U8 = s[i]
if d < '0' | d > '9'
break
num = num * 10 + (d - '0')
i = i + 1
return num * sign
func str.hex_encode[s: String] : String
let hex_chars: String = "0123456789abcdef"
@@ -297,9 +315,9 @@ func math.is_prime[n: I64]: Bool
func math.urandom[]: I64
let buffer: Ptr = mem.alloc(8)
let fd: I64 = c.syscall(2, "/dev/urandom", 0, 0) // open
c.syscall(0, fd, buffer, 8) // read
c.syscall(3, fd) // close
let fd: I64 = _builtin_syscall(2, "/dev/urandom", 0, 0) // open
_builtin_syscall(0, fd, buffer, 8) // read
_builtin_syscall(3, fd) // close
let n: I64 = mem.read64(buffer)
mem.free(buffer)
return n
@@ -370,7 +388,7 @@ func alg._partition[arr: Array, low: I64, high: I64] : I64
return i + 1
func os.exit[code: I64] : Void
c.syscall(60, code)
_builtin_syscall(60, code)
func os.time[] : I64
let tv: Ptr = mem.alloc(16)
@@ -381,29 +399,40 @@ func os.time[] : I64
return seconds * 1000 + microseconds / 1000
func os.listdir[path: String] : Array
let dir: Ptr = c.opendir(path)
let files: Array = []
let fd: I64 = _builtin_syscall(2, path, 0, 0) // open
if fd < 0
return []
let files: Array = []
let buf: Ptr = mem.alloc(1024)
while true
let entry: Ptr = c.readdir(dir)
if entry == 0
let n: I64 = _builtin_syscall(217, fd, buf, 1024) // getdents64
if n <= 0
break
let skip: Bool = false
if entry[19] == '.'
if entry[20] == 0
skip = true
else if entry[20] == '.'
if entry[21] == 0
skip = true
let pos: I64 = 0
while pos < n
let len: I64 = mem.read16(buf + pos + 16)
let name: String = buf + pos + 19
if name[0]
let skip: Bool = false
// skip if name is exactly '.' or '..'
if name[0] == '.'
if name[1] == 0
skip = true
else if name[1] == '.'
if name[2] == 0
skip = true
if !skip
array.push(files, str.copy(name))
pos = pos + len
if !skip
array.push(files, str.copy(entry + 19))
c.closedir(dir)
mem.free(buf)
_builtin_syscall(3, fd) // close
return files
func net.listen[port: I64] : I64
let s: I64 = c.syscall(41, 2, 1, 0) // socket
let s: I64 = _builtin_syscall(41, 2, 1, 0) // socket
if s < 0
return -1
@@ -414,13 +443,13 @@ func net.listen[port: I64] : I64
mem.write8(sa + 2, (port >> 8) & 255)
mem.write8(sa + 3, port & 255)
if c.syscall(49, s, sa, 16) < 0 // bind
c.syscall(3, s) // close
if _builtin_syscall(49, s, sa, 16) < 0 // bind
_builtin_syscall(3, s) // close
return -1
mem.free(sa)
if c.syscall(50, s, 1) < 0 // listen
c.syscall(3, s) // close
if _builtin_syscall(50, s, 1) < 0 // listen
_builtin_syscall(3, s) // close
return -1
return s
@@ -432,7 +461,7 @@ func net.connect[host: String, port: I64] : I64
let ip_ptr: Ptr = mem.read64(mem.read64(he + 24))
let s: I64 = c.syscall(41, 2, 1, 0) // socket
let s: I64 = _builtin_syscall(41, 2, 1, 0) // socket
if s < 0
return -1
@@ -446,9 +475,9 @@ func net.connect[host: String, port: I64] : I64
mem.write8(sa + 6, ip_ptr[2])
mem.write8(sa + 7, ip_ptr[3])
if c.syscall(42, s, sa, 16) < 0 // connect
if _builtin_syscall(42, s, sa, 16) < 0 // connect
mem.free(sa)
c.syscall(3, s) // close
_builtin_syscall(3, s) // close
return -1
mem.free(sa)