string hosts in net.*
This commit is contained in:
@@ -49,7 +49,7 @@ func CHIP8.free[c: CHIP8] : void
|
|||||||
c->keyboard->free()
|
c->keyboard->free()
|
||||||
c->display->free()
|
c->display->free()
|
||||||
c->keyboard_map->free()
|
c->keyboard_map->free()
|
||||||
(c as ptr)->free()
|
mem.free(c)
|
||||||
|
|
||||||
func CHIP8.disassemble[c: CHIP8, ins_count: i64] : void
|
func CHIP8.disassemble[c: CHIP8, ins_count: i64] : void
|
||||||
for i in 0..ins_count
|
for i in 0..ins_count
|
||||||
|
|||||||
@@ -26,11 +26,7 @@ func main[argc: i64, argv: ptr] : i64
|
|||||||
if i < url_len
|
if i < url_len
|
||||||
path = url->substr(i, url_len - i)
|
path = url->substr(i, url_len - i)
|
||||||
|
|
||||||
~addr, ok := net.resolve(host)
|
~s, ok := net.connect(host, 80)
|
||||||
if !ok
|
|
||||||
panic("failed to resolve host")
|
|
||||||
|
|
||||||
~s, ok := net.connect(addr, 80)
|
|
||||||
if !ok
|
if !ok
|
||||||
panic("failed to connect")
|
panic("failed to connect")
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ func main[] : i64
|
|||||||
|
|
||||||
for i in 0..lines->size
|
for i in 0..lines->size
|
||||||
line : str = lines->nth(i)
|
line : str = lines->nth(i)
|
||||||
|
|
||||||
parts := line->split(" ")
|
parts := line->split(" ")
|
||||||
|
|
||||||
l1->push((parts->nth(0) as str)->parse_i64())
|
l1->push((parts->nth(0) as str)->parse_i64())
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
func main[] : i64
|
func main[] : i64
|
||||||
~s, ok := net.listen(net.pack_addr(127, 0, 0, 1), 8000)
|
~s, ok := net.listen("127.0.0.1", 8000)
|
||||||
if !ok
|
if !ok
|
||||||
panic("failed to listen")
|
panic("failed to listen")
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
func main[] : i64
|
func main[] : i64
|
||||||
~s, ok := net.create_udp_server(net.pack_addr(127, 0, 0, 1), 8000)
|
~s, ok := net.create_udp_server("127.0.0.1", 8000)
|
||||||
if !ok
|
if !ok
|
||||||
panic("net.create_udp_server failed")
|
panic("net.create_udp_server failed")
|
||||||
|
|
||||||
|
|||||||
@@ -670,7 +670,11 @@ _builtin_environ:
|
|||||||
self.emit_call_setup(arg_count);
|
self.emit_call_setup(arg_count);
|
||||||
|
|
||||||
if let ExprKind::Variable(callee_name) = &callee.kind {
|
if let ExprKind::Variable(callee_name) = &callee.kind {
|
||||||
if self.symbol_table.functions.contains_key(&callee_name.lexeme) {
|
if self
|
||||||
|
.symbol_table
|
||||||
|
.functions
|
||||||
|
.contains_key(&callee_name.lexeme)
|
||||||
|
{
|
||||||
// its a function (defined/builtin/extern)
|
// its a function (defined/builtin/extern)
|
||||||
emit!(&mut self.output, " call {}", callee_name.lexeme);
|
emit!(&mut self.output, " call {}", callee_name.lexeme);
|
||||||
} else {
|
} else {
|
||||||
@@ -852,28 +856,28 @@ _builtin_environ:
|
|||||||
|
|
||||||
fn emit_var_arg(&mut self, env: &mut Env, index_expr: &Expr) -> Result<(), ZernError> {
|
fn emit_var_arg(&mut self, env: &mut Env, index_expr: &Expr) -> Result<(), ZernError> {
|
||||||
self.compile_expr(env, index_expr)?;
|
self.compile_expr(env, index_expr)?;
|
||||||
emit!(&mut self.output, " mov r10, rax");
|
emit!(&mut self.output, " mov r10, rax");
|
||||||
|
|
||||||
let stack_label = self.label();
|
let stack_label = self.label();
|
||||||
let done_label = self.label();
|
let done_label = self.label();
|
||||||
|
|
||||||
emit!(&mut self.output, " cmp r10, 6");
|
emit!(&mut self.output, " cmp r10, 6");
|
||||||
emit!(&mut self.output, " jge {}", stack_label);
|
emit!(&mut self.output, " jge {}", stack_label);
|
||||||
|
|
||||||
// < 6
|
// < 6
|
||||||
emit!(&mut self.output, " mov rax, r10");
|
emit!(&mut self.output, " mov rax, r10");
|
||||||
emit!(&mut self.output, " inc rax");
|
emit!(&mut self.output, " inc rax");
|
||||||
emit!(&mut self.output, " shl rax, 3");
|
emit!(&mut self.output, " shl rax, 3");
|
||||||
emit!(&mut self.output, " neg rax");
|
emit!(&mut self.output, " neg rax");
|
||||||
emit!(&mut self.output, " mov rax, [rbp + rax]");
|
emit!(&mut self.output, " mov rax, [rbp + rax]");
|
||||||
emit!(&mut self.output, " jmp {}", done_label);
|
emit!(&mut self.output, " jmp {}", done_label);
|
||||||
|
|
||||||
// >= 6
|
// >= 6
|
||||||
emit!(&mut self.output, "{}:", stack_label);
|
emit!(&mut self.output, "{}:", stack_label);
|
||||||
emit!(&mut self.output, " mov rax, r10");
|
emit!(&mut self.output, " mov rax, r10");
|
||||||
emit!(&mut self.output, " sub rax, 6");
|
emit!(&mut self.output, " sub rax, 6");
|
||||||
emit!(&mut self.output, " shl rax, 3");
|
emit!(&mut self.output, " shl rax, 3");
|
||||||
emit!(&mut self.output, " mov rax, [rbp + 16 + rax]");
|
emit!(&mut self.output, " mov rax, [rbp + 16 + rax]");
|
||||||
|
|
||||||
emit!(&mut self.output, "{}:", done_label);
|
emit!(&mut self.output, "{}:", done_label);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
112
src/std/net.zr
112
src/std/net.zr
@@ -10,7 +10,7 @@ const DNS_TYPE_A = 1
|
|||||||
const DNS_CLASS_IN = 1
|
const DNS_CLASS_IN = 1
|
||||||
const DNS_RECURSION_DESIRED = 256
|
const DNS_RECURSION_DESIRED = 256
|
||||||
|
|
||||||
func net.listen[packed_host: i64, port: i64] : i64, bool
|
func net.listen[host: str, port: i64] : i64, bool
|
||||||
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
|
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
|
||||||
if s < 0
|
if s < 0
|
||||||
return -1, false
|
return -1, false
|
||||||
@@ -20,6 +20,10 @@ func net.listen[packed_host: i64, port: i64] : i64, bool
|
|||||||
_builtin_syscall(SYS_close, s)
|
_builtin_syscall(SYS_close, s)
|
||||||
return -1, false
|
return -1, false
|
||||||
|
|
||||||
|
~packed_host, ok := net.resolve(host)
|
||||||
|
if !ok
|
||||||
|
return -1, false
|
||||||
|
|
||||||
sa := _stackalloc(16)
|
sa := _stackalloc(16)
|
||||||
net._build_sa(sa, packed_host, port)
|
net._build_sa(sa, packed_host, port)
|
||||||
|
|
||||||
@@ -33,11 +37,15 @@ func net.listen[packed_host: i64, port: i64] : i64, bool
|
|||||||
|
|
||||||
return s, true
|
return s, true
|
||||||
|
|
||||||
func net.connect[packed_host: i64, port: i64] : i64, bool
|
func net.connect[host: str, port: i64] : i64, bool
|
||||||
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
|
s := _builtin_syscall(SYS_socket, AF_INET, SOCK_STREAM, 0)
|
||||||
if s < 0
|
if s < 0
|
||||||
return -1, false
|
return -1, false
|
||||||
|
|
||||||
|
~packed_host, ok := net.resolve(host)
|
||||||
|
if !ok
|
||||||
|
return -1, false
|
||||||
|
|
||||||
sa := _stackalloc(16)
|
sa := _stackalloc(16)
|
||||||
net._build_sa(sa, packed_host, port)
|
net._build_sa(sa, packed_host, port)
|
||||||
|
|
||||||
@@ -91,22 +99,26 @@ func net.UDPSocket.receive[s: net.UDPSocket, size: i64] : net.UDPPacket
|
|||||||
func net.UDPSocket.close_and_free[s: net.UDPSocket] : void
|
func net.UDPSocket.close_and_free[s: net.UDPSocket] : void
|
||||||
_builtin_syscall(SYS_close, s->fd)
|
_builtin_syscall(SYS_close, s->fd)
|
||||||
s->addr->free()
|
s->addr->free()
|
||||||
(s as ptr)->free()
|
mem.free(s)
|
||||||
|
|
||||||
func net.create_udp_client[packed_host: i64, port: i64] : net.UDPSocket, bool
|
func net.create_udp_client[host: str, port: i64] : net.UDPSocket, bool
|
||||||
s := new* net.UDPSocket
|
s := new* net.UDPSocket
|
||||||
|
|
||||||
|
~packed_host, ok := net.resolve(host)
|
||||||
|
if !ok
|
||||||
|
return 0 as net.UDPSocket, false
|
||||||
|
|
||||||
s->fd = _builtin_syscall(SYS_socket, AF_INET, SOCK_DGRAM, 0)
|
s->fd = _builtin_syscall(SYS_socket, AF_INET, SOCK_DGRAM, 0)
|
||||||
if s->fd < 0
|
if s->fd < 0
|
||||||
s->close_and_free()
|
mem.free(s)
|
||||||
return 0 as net.UDPSocket, false
|
return 0 as net.UDPSocket, false
|
||||||
|
|
||||||
s->addr = mem.alloc(16)
|
s->addr = mem.alloc(16)
|
||||||
net._build_sa(s->addr, packed_host, port)
|
net._build_sa(s->addr, packed_host, port)
|
||||||
return s, true
|
return s, true
|
||||||
|
|
||||||
func net.create_udp_server[packed_host: i64, port: i64] : net.UDPSocket, bool
|
func net.create_udp_server[host: str, port: i64] : net.UDPSocket, bool
|
||||||
~s, ok := net.create_udp_client(packed_host, port)
|
~s, ok := net.create_udp_client(host, port)
|
||||||
if !ok
|
if !ok
|
||||||
return 0 as net.UDPSocket, false
|
return 0 as net.UDPSocket, false
|
||||||
|
|
||||||
@@ -127,7 +139,61 @@ struct net.UDPPacket
|
|||||||
func net.UDPPacket.free[pkt: net.UDPPacket] : void
|
func net.UDPPacket.free[pkt: net.UDPPacket] : void
|
||||||
pkt->data->free()
|
pkt->data->free()
|
||||||
pkt->source_addr->free()
|
pkt->source_addr->free()
|
||||||
(pkt as ptr)->free()
|
mem.free(pkt)
|
||||||
|
|
||||||
|
func net.resolve[domain: str] : i64, bool
|
||||||
|
// if domain is already an ip, skip dns resolution
|
||||||
|
parts := domain->split(".")
|
||||||
|
if parts->size == 4
|
||||||
|
valid := true
|
||||||
|
for i in 0..4
|
||||||
|
p := parts->nth(i) as str
|
||||||
|
if p->len() < 1 || p->len() > 3
|
||||||
|
valid = false
|
||||||
|
break
|
||||||
|
for j in 0..p->len()
|
||||||
|
if !p[j]->is_digit()
|
||||||
|
valid = false
|
||||||
|
break
|
||||||
|
if !valid
|
||||||
|
break
|
||||||
|
if valid
|
||||||
|
a := (parts->nth(0) as str)->parse_i64()
|
||||||
|
b := (parts->nth(1) as str)->parse_i64()
|
||||||
|
c := (parts->nth(2) as str)->parse_i64()
|
||||||
|
d := (parts->nth(3) as str)->parse_i64()
|
||||||
|
if a >= 0 && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0 && d <= 255
|
||||||
|
parts->free_with_items()
|
||||||
|
return net.pack_addr(a, b, c, d), true
|
||||||
|
parts->free_with_items()
|
||||||
|
|
||||||
|
query := net.build_dns_query(domain, DNS_TYPE_A)
|
||||||
|
|
||||||
|
// TODO: this probably shouldnt be hardcoded
|
||||||
|
~s, ok := net.create_udp_client("1.1.1.1", 53)
|
||||||
|
if !ok
|
||||||
|
query->free()
|
||||||
|
return -1, false
|
||||||
|
|
||||||
|
s->send_to(s->addr, query->data, query->size)
|
||||||
|
query->free()
|
||||||
|
pkt := s->receive(1024)
|
||||||
|
s->close_and_free()
|
||||||
|
|
||||||
|
// TODO: do actual parsing
|
||||||
|
|
||||||
|
pos := 12 // skip header (12 bytes)
|
||||||
|
|
||||||
|
while pkt->data[pos] != 0
|
||||||
|
pos += pkt->data[pos] + 1 // skip question
|
||||||
|
|
||||||
|
pos += 5 // skip null byte, type(2), class(2)
|
||||||
|
|
||||||
|
pos += 12 // skip name(2), type(2), class(2), ttl(4), rdlength(2)
|
||||||
|
|
||||||
|
out := net.pack_addr(pkt->data[pos] as i64, pkt->data[pos+1] as i64, pkt->data[pos+2] as i64, pkt->data[pos+3] as i64)
|
||||||
|
pkt->free()
|
||||||
|
return out, true
|
||||||
|
|
||||||
func net.encode_dns_name[domain: str] : Blob
|
func net.encode_dns_name[domain: str] : Blob
|
||||||
domain_len := domain->len()
|
domain_len := domain->len()
|
||||||
@@ -168,33 +234,3 @@ func net.build_dns_query[domain_name: str, record_type: i64] : Blob
|
|||||||
|
|
||||||
name->free()
|
name->free()
|
||||||
return out
|
return out
|
||||||
|
|
||||||
// TODO: dont resolve if its already an IP
|
|
||||||
func net.resolve[domain: str] : i64, bool
|
|
||||||
query := net.build_dns_query(domain, DNS_TYPE_A)
|
|
||||||
|
|
||||||
// TODO: this probably shouldnt be hardcoded
|
|
||||||
~s, ok := net.create_udp_client(net.pack_addr(1, 1, 1, 1), 53)
|
|
||||||
if !ok
|
|
||||||
query->free()
|
|
||||||
return -1, false
|
|
||||||
|
|
||||||
s->send_to(s->addr, query->data, query->size)
|
|
||||||
query->free()
|
|
||||||
pkt := s->receive(1024)
|
|
||||||
s->close_and_free()
|
|
||||||
|
|
||||||
// TODO: do actual parsing
|
|
||||||
|
|
||||||
pos := 12 // skip header (12 bytes)
|
|
||||||
|
|
||||||
while pkt->data[pos] != 0
|
|
||||||
pos += pkt->data[pos] + 1 // skip question
|
|
||||||
|
|
||||||
pos += 5 // skip null byte, type(2), class(2)
|
|
||||||
|
|
||||||
pos += 12 // skip name(2), type(2), class(2), ttl(4), rdlength(2)
|
|
||||||
|
|
||||||
out := net.pack_addr(pkt->data[pos] as i64, pkt->data[pos+1] as i64, pkt->data[pos+2] as i64, pkt->data[pos+3] as i64)
|
|
||||||
pkt->free()
|
|
||||||
return out, true
|
|
||||||
|
|||||||
@@ -76,6 +76,9 @@ func mem.alloc[size: i64] : ptr
|
|||||||
|
|
||||||
return blk as ptr + MEM_BLOCK_SIZE
|
return blk as ptr + MEM_BLOCK_SIZE
|
||||||
|
|
||||||
|
func mem.free[x: any] : void
|
||||||
|
ptr.free(x as ptr)
|
||||||
|
|
||||||
func ptr.free[x: ptr] : void
|
func ptr.free[x: ptr] : void
|
||||||
if x == 0
|
if x == 0
|
||||||
return 0
|
return 0
|
||||||
@@ -372,7 +375,7 @@ func io.write_binary_file[path: str, content: ptr, size: i64] : bool
|
|||||||
return true
|
return true
|
||||||
|
|
||||||
func str.free[s: str] : void
|
func str.free[s: str] : void
|
||||||
(s as ptr)->free()
|
mem.free(s)
|
||||||
|
|
||||||
func str.len[s: str] : i64
|
func str.len[s: str] : i64
|
||||||
i := 0
|
i := 0
|
||||||
@@ -572,7 +575,7 @@ func str.parse_i64[s: str] : i64
|
|||||||
num := 0
|
num := 0
|
||||||
while i < len
|
while i < len
|
||||||
d := s[i]
|
d := s[i]
|
||||||
if d < '0' || d > '9'
|
if !d->is_digit()
|
||||||
break
|
break
|
||||||
num = num * 10 + (d - '0')
|
num = num * 10 + (d - '0')
|
||||||
i += 1
|
i += 1
|
||||||
@@ -591,7 +594,7 @@ func str.hex_encode[s: str, s_len: i64] : str
|
|||||||
return out
|
return out
|
||||||
|
|
||||||
func str._hex_digit_to_int[d: u8] : u8
|
func str._hex_digit_to_int[d: u8] : u8
|
||||||
if d >= '0' && d <= '9'
|
if d->is_digit()
|
||||||
return d - '0'
|
return d - '0'
|
||||||
lower : u8 = d | 32
|
lower : u8 = d | 32
|
||||||
if lower >= 'a' && lower <= 'f'
|
if lower >= 'a' && lower <= 'f'
|
||||||
@@ -831,7 +834,7 @@ func Blob.alloc[size: i64] : Blob
|
|||||||
|
|
||||||
func Blob.free[buf: Blob] : void
|
func Blob.free[buf: Blob] : void
|
||||||
buf->data->free()
|
buf->data->free()
|
||||||
(buf as ptr)->free()
|
mem.free(buf)
|
||||||
|
|
||||||
struct Array
|
struct Array
|
||||||
data: ptr
|
data: ptr
|
||||||
@@ -871,14 +874,14 @@ func Array.push[xs: Array, x: any] : void
|
|||||||
func Array.free[xs: Array] : void
|
func Array.free[xs: Array] : void
|
||||||
if xs->data != 0
|
if xs->data != 0
|
||||||
xs->data->free()
|
xs->data->free()
|
||||||
(xs as ptr)->free()
|
mem.free(xs)
|
||||||
|
|
||||||
func Array.free_with_items[xs: Array] : void
|
func Array.free_with_items[xs: Array] : void
|
||||||
if xs->data != 0
|
if xs->data != 0
|
||||||
for i in 0..xs->size
|
for i in 0..xs->size
|
||||||
(xs->nth(i) as ptr)->free()
|
mem.free(xs->nth(i))
|
||||||
xs->data->free()
|
xs->data->free()
|
||||||
(xs as ptr)->free()
|
mem.free(xs)
|
||||||
|
|
||||||
func Array.pop[xs: Array] : any
|
func Array.pop[xs: Array] : any
|
||||||
if xs->size == 0
|
if xs->size == 0
|
||||||
@@ -1004,7 +1007,7 @@ func HashMap.delete[map: HashMap, key: str] : void
|
|||||||
map->table->set(index, current->next)
|
map->table->set(index, current->next)
|
||||||
|
|
||||||
current->key->free()
|
current->key->free()
|
||||||
(current as ptr)->free()
|
mem.free(current)
|
||||||
return 0
|
return 0
|
||||||
|
|
||||||
prev = current
|
prev = current
|
||||||
@@ -1024,10 +1027,10 @@ func HashMap.free[map: HashMap] : void
|
|||||||
tmp := current
|
tmp := current
|
||||||
current = current->next
|
current = current->next
|
||||||
tmp->key->free()
|
tmp->key->free()
|
||||||
(tmp as ptr)->free()
|
mem.free(tmp)
|
||||||
|
|
||||||
map->table->free()
|
map->table->free()
|
||||||
(map as ptr)->free()
|
mem.free(map)
|
||||||
|
|
||||||
func os.exit[code: i64] : void
|
func os.exit[code: i64] : void
|
||||||
_builtin_syscall(SYS_exit, code)
|
_builtin_syscall(SYS_exit, code)
|
||||||
|
|||||||
Reference in New Issue
Block a user