implement our own readdir and strtol, syscall builtin
This commit is contained in:
@@ -106,7 +106,7 @@ section .text
|
|||||||
);
|
);
|
||||||
|
|
||||||
// take that rustfmt
|
// 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, "extern {}", name);
|
||||||
emit!(&mut self.output, "c.{} equ {}", name, name);
|
emit!(&mut self.output, "c.{} equ {}", name, name);
|
||||||
@@ -121,6 +121,12 @@ _builtin_read8:
|
|||||||
mov al, byte [rdi]
|
mov al, byte [rdi]
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
section .text._builtin_read16
|
||||||
|
_builtin_read16:
|
||||||
|
xor rax, rax
|
||||||
|
mov ax, word [rdi]
|
||||||
|
ret
|
||||||
|
|
||||||
section .text._builtin_read32
|
section .text._builtin_read32
|
||||||
_builtin_read32:
|
_builtin_read32:
|
||||||
mov eax, dword [rdi]
|
mov eax, dword [rdi]
|
||||||
@@ -140,6 +146,18 @@ section .text._builtin_set64
|
|||||||
_builtin_set64:
|
_builtin_set64:
|
||||||
mov [rdi], rsi
|
mov [rdi], rsi
|
||||||
ret
|
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(())
|
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
|
func mem.read8[x: Ptr] : U8
|
||||||
return _builtin_read8(x)
|
return _builtin_read8(x)
|
||||||
|
|
||||||
|
func mem.read16[x: Ptr] : I64
|
||||||
|
return _builtin_read16(x)
|
||||||
|
|
||||||
func mem.read32[x: Ptr] : I64
|
func mem.read32[x: Ptr] : I64
|
||||||
return _builtin_read32(x)
|
return _builtin_read32(x)
|
||||||
|
|
||||||
@@ -29,7 +32,7 @@ func mem.write64[x: Ptr, d: I64] : Void
|
|||||||
_builtin_set64(x, d)
|
_builtin_set64(x, d)
|
||||||
|
|
||||||
func io.print[x: String] : Void
|
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
|
func io.println[x: String] : Void
|
||||||
io.print(x)
|
io.print(x)
|
||||||
@@ -38,7 +41,7 @@ func io.println[x: String] : Void
|
|||||||
func io.print_char[x: U8] : Void
|
func io.print_char[x: U8] : Void
|
||||||
let s: String = mem.alloc(1)
|
let s: String = mem.alloc(1)
|
||||||
str.set(s, 0, x)
|
str.set(s, 0, x)
|
||||||
c.syscall(1, 1, s, 1)
|
_builtin_syscall(1, 1, s, 1)
|
||||||
mem.free(s)
|
mem.free(s)
|
||||||
|
|
||||||
func io.print_i64[x: I64] : Void
|
func io.print_i64[x: I64] : Void
|
||||||
@@ -53,33 +56,33 @@ func io.println_i64[x: I64] : Void
|
|||||||
|
|
||||||
func io.read_stdin[]: String
|
func io.read_stdin[]: String
|
||||||
let buffer: String = mem.alloc(1025)
|
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
|
if n < 0
|
||||||
return ""
|
return ""
|
||||||
str.set(buffer, n, 0)
|
str.set(buffer, n, 0)
|
||||||
return buffer
|
return buffer
|
||||||
|
|
||||||
func io.read_file[path: String]: String
|
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
|
if fd <= 0
|
||||||
dbg.panic("failed to open file")
|
dbg.panic("failed to open file")
|
||||||
|
|
||||||
let size: I64 = c.syscall(8, fd, 0, 2) // lseek to the end
|
let size: I64 = _builtin_syscall(8, fd, 0, 2) // lseek to the end
|
||||||
c.syscall(8, fd, 0, 0) // lseek back to start
|
_builtin_syscall(8, fd, 0, 0) // lseek back to start
|
||||||
|
|
||||||
let buffer: String = mem.alloc(size + 1)
|
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)
|
str.set(buffer, n, 0)
|
||||||
c.syscall(3, fd) // close
|
_builtin_syscall(3, fd) // close
|
||||||
return buffer
|
return buffer
|
||||||
|
|
||||||
func io.write_file[path: String, content: String] : Void
|
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
|
if fd < 0
|
||||||
dbg.panic("failed to open file")
|
dbg.panic("failed to open file")
|
||||||
|
|
||||||
c.syscall(1, fd, content, str.len(content)) // write
|
_builtin_syscall(1, fd, content, str.len(content)) // write
|
||||||
c.syscall(3, fd) // close
|
_builtin_syscall(3, fd) // close
|
||||||
|
|
||||||
func str.len[s: String] : I64
|
func str.len[s: String] : I64
|
||||||
let i: I64 = 0
|
let i: I64 = 0
|
||||||
@@ -195,7 +198,22 @@ func str.from_i64[n: I64] : String
|
|||||||
return x
|
return x
|
||||||
|
|
||||||
func str.parse_i64[s: String] : I64
|
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
|
func str.hex_encode[s: String] : String
|
||||||
let hex_chars: String = "0123456789abcdef"
|
let hex_chars: String = "0123456789abcdef"
|
||||||
@@ -297,9 +315,9 @@ func math.is_prime[n: I64]: Bool
|
|||||||
|
|
||||||
func math.urandom[]: I64
|
func math.urandom[]: I64
|
||||||
let buffer: Ptr = mem.alloc(8)
|
let buffer: Ptr = mem.alloc(8)
|
||||||
let fd: I64 = c.syscall(2, "/dev/urandom", 0, 0) // open
|
let fd: I64 = _builtin_syscall(2, "/dev/urandom", 0, 0) // open
|
||||||
c.syscall(0, fd, buffer, 8) // read
|
_builtin_syscall(0, fd, buffer, 8) // read
|
||||||
c.syscall(3, fd) // close
|
_builtin_syscall(3, fd) // close
|
||||||
let n: I64 = mem.read64(buffer)
|
let n: I64 = mem.read64(buffer)
|
||||||
mem.free(buffer)
|
mem.free(buffer)
|
||||||
return n
|
return n
|
||||||
@@ -370,7 +388,7 @@ func alg._partition[arr: Array, low: I64, high: I64] : I64
|
|||||||
return i + 1
|
return i + 1
|
||||||
|
|
||||||
func os.exit[code: I64] : Void
|
func os.exit[code: I64] : Void
|
||||||
c.syscall(60, code)
|
_builtin_syscall(60, code)
|
||||||
|
|
||||||
func os.time[] : I64
|
func os.time[] : I64
|
||||||
let tv: Ptr = mem.alloc(16)
|
let tv: Ptr = mem.alloc(16)
|
||||||
@@ -381,29 +399,40 @@ func os.time[] : I64
|
|||||||
return seconds * 1000 + microseconds / 1000
|
return seconds * 1000 + microseconds / 1000
|
||||||
|
|
||||||
func os.listdir[path: String] : Array
|
func os.listdir[path: String] : Array
|
||||||
let dir: Ptr = c.opendir(path)
|
let fd: I64 = _builtin_syscall(2, path, 0, 0) // open
|
||||||
let files: Array = []
|
if fd < 0
|
||||||
|
return []
|
||||||
|
|
||||||
|
let files: Array = []
|
||||||
|
let buf: Ptr = mem.alloc(1024)
|
||||||
while true
|
while true
|
||||||
let entry: Ptr = c.readdir(dir)
|
let n: I64 = _builtin_syscall(217, fd, buf, 1024) // getdents64
|
||||||
if entry == 0
|
if n <= 0
|
||||||
break
|
break
|
||||||
|
|
||||||
let skip: Bool = false
|
let pos: I64 = 0
|
||||||
if entry[19] == '.'
|
while pos < n
|
||||||
if entry[20] == 0
|
let len: I64 = mem.read16(buf + pos + 16)
|
||||||
skip = true
|
let name: String = buf + pos + 19
|
||||||
else if entry[20] == '.'
|
if name[0]
|
||||||
if entry[21] == 0
|
let skip: Bool = false
|
||||||
skip = true
|
// 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
|
mem.free(buf)
|
||||||
array.push(files, str.copy(entry + 19))
|
_builtin_syscall(3, fd) // close
|
||||||
c.closedir(dir)
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
func net.listen[port: I64] : I64
|
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
|
if s < 0
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
@@ -414,13 +443,13 @@ func net.listen[port: I64] : I64
|
|||||||
mem.write8(sa + 2, (port >> 8) & 255)
|
mem.write8(sa + 2, (port >> 8) & 255)
|
||||||
mem.write8(sa + 3, port & 255)
|
mem.write8(sa + 3, port & 255)
|
||||||
|
|
||||||
if c.syscall(49, s, sa, 16) < 0 // bind
|
if _builtin_syscall(49, s, sa, 16) < 0 // bind
|
||||||
c.syscall(3, s) // close
|
_builtin_syscall(3, s) // close
|
||||||
return -1
|
return -1
|
||||||
mem.free(sa)
|
mem.free(sa)
|
||||||
|
|
||||||
if c.syscall(50, s, 1) < 0 // listen
|
if _builtin_syscall(50, s, 1) < 0 // listen
|
||||||
c.syscall(3, s) // close
|
_builtin_syscall(3, s) // close
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
return s
|
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 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
|
if s < 0
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
@@ -446,9 +475,9 @@ func net.connect[host: String, port: I64] : I64
|
|||||||
mem.write8(sa + 6, ip_ptr[2])
|
mem.write8(sa + 6, ip_ptr[2])
|
||||||
mem.write8(sa + 7, ip_ptr[3])
|
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)
|
mem.free(sa)
|
||||||
c.syscall(3, s) // close
|
_builtin_syscall(3, s) // close
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
mem.free(sa)
|
mem.free(sa)
|
||||||
|
|||||||
Reference in New Issue
Block a user