implement our own readdir and strtol, syscall builtin
This commit is contained in:
@@ -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(())
|
||||
|
||||
105
src/std.zr
105
src/std.zr
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user