@shd101wyy/yo 0.1.28 → 0.1.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/skills/yo-async-effects/SKILL.md +15 -15
- package/.github/skills/yo-async-effects/async-effects-recipes.md +118 -121
- package/.github/skills/yo-core-patterns/core-patterns-cheatsheet.md +33 -13
- package/.github/skills/yo-project-workflow/workflow-cheatsheet.md +1 -1
- package/.github/skills/yo-syntax/SKILL.md +2 -2
- package/.github/skills/yo-syntax/syntax-cheatsheet.md +108 -96
- package/README.md +6 -3
- package/out/cjs/index.cjs +812 -706
- package/out/cjs/yo-cli.cjs +1023 -907
- package/out/cjs/yo-lsp.cjs +836 -730
- package/out/esm/index.mjs +757 -651
- package/out/types/src/codegen/exprs/async.d.ts +2 -0
- package/out/types/src/codegen/exprs/await.d.ts +1 -0
- package/out/types/src/codegen/exprs/closures.d.ts +4 -0
- package/out/types/src/codegen/functions/context.d.ts +6 -0
- package/out/types/src/codegen/functions/declarations.d.ts +1 -1
- package/out/types/src/doc/model.d.ts +0 -1
- package/out/types/src/env.d.ts +2 -2
- package/out/types/src/evaluator/builtins/pragma.d.ts +9 -0
- package/out/types/src/evaluator/builtins/unsafe.d.ts +8 -0
- package/out/types/src/evaluator/context.d.ts +3 -1
- package/out/types/src/evaluator/exprs/{escape.d.ts → unwind.d.ts} +1 -1
- package/out/types/src/evaluator/index.d.ts +1 -1
- package/out/types/src/evaluator/memory-safety.d.ts +14 -0
- package/out/types/src/evaluator/types/flowability.d.ts +6 -0
- package/out/types/src/evaluator/types/function.d.ts +1 -2
- package/out/types/src/evaluator/utils.d.ts +0 -1
- package/out/types/src/expr-traversal.d.ts +1 -0
- package/out/types/src/expr.d.ts +9 -7
- package/out/types/src/public-safe-report.d.ts +19 -0
- package/out/types/src/tests/comptime-ref-gate.test.d.ts +1 -0
- package/out/types/src/tests/pragma-validation.test.d.ts +1 -0
- package/out/types/src/tests/public-safe-report.test.d.ts +1 -0
- package/out/types/src/tests/type-representation-pointer.test.d.ts +1 -0
- package/out/types/src/tests/unsafe-gate.test.d.ts +1 -0
- package/out/types/src/tests/unsafe-report-classify.test.d.ts +1 -0
- package/out/types/src/types/creators.d.ts +4 -6
- package/out/types/src/types/definitions.d.ts +9 -16
- package/out/types/src/types/guards.d.ts +1 -2
- package/out/types/src/types/tags.d.ts +0 -1
- package/out/types/src/types/utils.d.ts +5 -0
- package/out/types/src/unsafe-report.d.ts +29 -0
- package/out/types/src/value.d.ts +1 -0
- package/out/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/add-pragma-for-pointer-decls.ts +134 -0
- package/scripts/add-pragma.ts +58 -0
- package/scripts/migrate-amp-method-calls.ts +186 -0
- package/scripts/migrate-clone-calls.ts +93 -0
- package/scripts/migrate-get-unwrap.ts +166 -0
- package/scripts/migrate-index-patterns.ts +210 -0
- package/scripts/migrate-index-trait.ts +142 -0
- package/scripts/migrate-iterator.ts +150 -0
- package/scripts/migrate-self-ptr.ts +220 -0
- package/scripts/migrate-skip-pragmas.ts +109 -0
- package/scripts/migrate-tostring.ts +134 -0
- package/scripts/trim-pragma.ts +130 -0
- package/scripts/wrap-extern-calls.ts +161 -0
- package/std/alg/hash.yo +3 -2
- package/std/allocator.yo +6 -5
- package/std/async.yo +2 -2
- package/std/collections/array_list.yo +59 -40
- package/std/collections/btree_map.yo +19 -18
- package/std/collections/deque.yo +9 -8
- package/std/collections/hash_map.yo +101 -13
- package/std/collections/hash_set.yo +5 -4
- package/std/collections/linked_list.yo +39 -4
- package/std/collections/ordered_map.yo +3 -3
- package/std/collections/priority_queue.yo +14 -13
- package/std/crypto/md5.yo +2 -1
- package/std/crypto/random.yo +21 -20
- package/std/crypto/sha256.yo +2 -1
- package/std/encoding/base64.yo +18 -18
- package/std/encoding/hex.yo +5 -5
- package/std/encoding/json.yo +62 -13
- package/std/encoding/punycode.yo +24 -23
- package/std/encoding/toml.yo +4 -3
- package/std/encoding/utf16.yo +3 -3
- package/std/env.yo +43 -28
- package/std/error.yo +15 -3
- package/std/fmt/display.yo +2 -2
- package/std/fmt/index.yo +6 -5
- package/std/fmt/to_string.yo +39 -38
- package/std/fmt/writer.yo +9 -8
- package/std/fs/dir.yo +61 -66
- package/std/fs/file.yo +121 -126
- package/std/fs/metadata.yo +13 -18
- package/std/fs/temp.yo +35 -30
- package/std/fs/walker.yo +14 -19
- package/std/gc.yo +1 -0
- package/std/glob.yo +7 -7
- package/std/http/client.yo +33 -36
- package/std/http/http.yo +6 -6
- package/std/http/index.yo +4 -4
- package/std/imm/list.yo +33 -0
- package/std/imm/map.yo +2 -1
- package/std/imm/set.yo +1 -0
- package/std/imm/sorted_map.yo +1 -0
- package/std/imm/sorted_set.yo +1 -0
- package/std/imm/string.yo +27 -23
- package/std/imm/vec.yo +18 -2
- package/std/io/reader.yo +2 -1
- package/std/io/writer.yo +3 -2
- package/std/libc/assert.yo +1 -0
- package/std/libc/ctype.yo +1 -0
- package/std/libc/dirent.yo +1 -0
- package/std/libc/errno.yo +1 -0
- package/std/libc/fcntl.yo +1 -0
- package/std/libc/float.yo +1 -0
- package/std/libc/limits.yo +1 -0
- package/std/libc/math.yo +1 -0
- package/std/libc/signal.yo +1 -0
- package/std/libc/stdatomic.yo +1 -0
- package/std/libc/stdint.yo +1 -0
- package/std/libc/stdio.yo +1 -0
- package/std/libc/stdlib.yo +1 -0
- package/std/libc/string.yo +1 -0
- package/std/libc/sys/stat.yo +1 -0
- package/std/libc/time.yo +1 -0
- package/std/libc/unistd.yo +1 -0
- package/std/libc/wctype.yo +1 -0
- package/std/libc/windows.yo +2 -0
- package/std/log.yo +7 -6
- package/std/net/addr.yo +6 -5
- package/std/net/dns.yo +13 -16
- package/std/net/errors.yo +9 -9
- package/std/net/tcp.yo +71 -74
- package/std/net/udp.yo +40 -43
- package/std/os/signal.yo +5 -5
- package/std/path.yo +1 -0
- package/std/prelude.yo +377 -200
- package/std/process/command.yo +57 -46
- package/std/process/index.yo +2 -1
- package/std/regex/compiler.yo +10 -9
- package/std/regex/index.yo +41 -41
- package/std/regex/match.yo +2 -2
- package/std/regex/parser.yo +31 -31
- package/std/regex/vm.yo +42 -41
- package/std/string/string.yo +95 -40
- package/std/string/string_builder.yo +9 -9
- package/std/string/unicode.yo +50 -49
- package/std/sync/channel.yo +2 -1
- package/std/sync/cond.yo +5 -4
- package/std/sync/mutex.yo +4 -3
- package/std/sys/advise.yo +1 -0
- package/std/sys/bufio/buf_reader.yo +27 -26
- package/std/sys/bufio/buf_writer.yo +22 -21
- package/std/sys/clock.yo +1 -0
- package/std/sys/copy.yo +1 -0
- package/std/sys/dir.yo +10 -9
- package/std/sys/dns.yo +6 -5
- package/std/sys/errors.yo +12 -12
- package/std/sys/events.yo +1 -0
- package/std/sys/externs.yo +38 -37
- package/std/sys/file.yo +17 -16
- package/std/sys/future.yo +4 -3
- package/std/sys/iov.yo +1 -0
- package/std/sys/mmap.yo +1 -0
- package/std/sys/path.yo +1 -0
- package/std/sys/perm.yo +2 -1
- package/std/sys/pipe.yo +1 -0
- package/std/sys/process.yo +5 -4
- package/std/sys/signal.yo +1 -0
- package/std/sys/socketpair.yo +1 -0
- package/std/sys/sockinfo.yo +1 -0
- package/std/sys/statfs.yo +2 -1
- package/std/sys/statx.yo +1 -0
- package/std/sys/sysinfo.yo +1 -0
- package/std/sys/tcp.yo +15 -14
- package/std/sys/temp.yo +1 -0
- package/std/sys/time.yo +2 -1
- package/std/sys/timer.yo +6 -6
- package/std/sys/tty.yo +2 -1
- package/std/sys/udp.yo +13 -12
- package/std/sys/unix.yo +12 -11
- package/std/testing/bench.yo +4 -3
- package/std/thread.yo +7 -6
- package/std/time/datetime.yo +18 -15
- package/std/time/duration.yo +11 -10
- package/std/time/instant.yo +4 -4
- package/std/time/sleep.yo +1 -0
- package/std/url/index.yo +5 -5
- package/std/worker.yo +4 -3
package/std/net/tcp.yo
CHANGED
|
@@ -9,25 +9,22 @@
|
|
|
9
9
|
// { SocketAddr, IpAddr } :: import "std/net/addr";
|
|
10
10
|
// { Exception } :: import "std/error";
|
|
11
11
|
//
|
|
12
|
-
// main :: (fn(
|
|
13
|
-
// given(exn) := Exception(throw : ((err) -> {
|
|
14
|
-
// println(err.message());
|
|
15
|
-
// escape ();
|
|
16
|
-
// }));
|
|
12
|
+
// main :: (fn(io : Io, exn : Exception) -> unit)({
|
|
17
13
|
// addr := SocketAddr.new(IpAddr.any_v4(), u16(8080));
|
|
18
|
-
// listener := io.await(TcpListener.bind(addr));
|
|
19
|
-
// stream := io.await(listener.accept());
|
|
14
|
+
// listener := io.await(TcpListener.bind(addr, io), { io, exn });
|
|
15
|
+
// stream := io.await(listener.accept(io), { io, exn });
|
|
20
16
|
// // ...
|
|
21
17
|
// });
|
|
18
|
+
pragma(Pragma.AllowUnsafe);
|
|
22
19
|
{ GlobalAllocator } :: import("../allocator");
|
|
23
20
|
{ malloc, free } :: GlobalAllocator;
|
|
24
21
|
{ ArrayList } :: import("../collections/array_list");
|
|
25
22
|
open(import("../string"));
|
|
26
23
|
open(import("../fmt"));
|
|
27
24
|
{ NetError } :: import("./errors");
|
|
28
|
-
{
|
|
25
|
+
{ IoError } :: import("../sys/errors");
|
|
29
26
|
{ IpAddr, SocketAddr } :: import("./addr");
|
|
30
|
-
{ Error, AnyError, Exception } :: import("../error");
|
|
27
|
+
{ Error, AnyError, Exception, IoExn } :: import("../error");
|
|
31
28
|
IO_tcp :: import("../sys/tcp");
|
|
32
29
|
{ AF_INET, AF_INET6, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR, IPPROTO_TCP, TCP_NODELAY, SO_KEEPALIVE } :: import("../sys/socket");
|
|
33
30
|
// ============================================================================
|
|
@@ -41,7 +38,7 @@ _make_sockaddr :: (fn(addr : SocketAddr) -> IO_tcp.SockAddr)(
|
|
|
41
38
|
// Build the IP string "a.b.c.d"
|
|
42
39
|
{ snprintf } :: import("../libc/stdio");
|
|
43
40
|
buf := Array(u8, usize(16)).fill(u8(0));
|
|
44
|
-
snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
41
|
+
unsafe(snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d)));
|
|
45
42
|
IO_tcp.make_sockaddr_in(&(buf(usize(0))), addr.port)
|
|
46
43
|
},
|
|
47
44
|
.V6(_) =>
|
|
@@ -49,8 +46,8 @@ _make_sockaddr :: (fn(addr : SocketAddr) -> IO_tcp.SockAddr)(
|
|
|
49
46
|
IO_tcp.make_sockaddr_in6(*(u8)("::1"), addr.port)
|
|
50
47
|
)
|
|
51
48
|
);
|
|
52
|
-
_throw_io :: (fn(errno_val : i32,
|
|
53
|
-
exn.throw(dyn(NetError.from_io(
|
|
49
|
+
_throw_io :: (fn(errno_val : i32, exn : Exception) -> unit)(
|
|
50
|
+
exn.throw(dyn(NetError.from_io(IoError.from_errno(errno_val))))
|
|
54
51
|
);
|
|
55
52
|
// ============================================================================
|
|
56
53
|
// TcpStream (declared before TcpListener so accept can reference it)
|
|
@@ -73,36 +70,36 @@ TcpListener :: object(
|
|
|
73
70
|
impl(
|
|
74
71
|
TcpListener,
|
|
75
72
|
/// Bind to a socket address and start listening.
|
|
76
|
-
bind : (fn(addr : SocketAddr,
|
|
77
|
-
io.async((
|
|
73
|
+
bind : (fn(addr : SocketAddr, io : Io) -> Impl(Future(TcpListener, IoExn)))(
|
|
74
|
+
io.async((e) => {
|
|
78
75
|
domain := cond(
|
|
79
76
|
addr.ip.is_v4() => AF_INET,
|
|
80
77
|
true => AF_INET6
|
|
81
78
|
);
|
|
82
79
|
// Create socket
|
|
83
|
-
raw_fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
|
|
84
|
-
fd := NetError.check(raw_fd);
|
|
80
|
+
raw_fd := e.io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)), e.io);
|
|
81
|
+
fd := NetError.check(raw_fd, e.exn);
|
|
85
82
|
// Set SO_REUSEADDR
|
|
86
83
|
reuse_val := i32(1);
|
|
87
84
|
reuse_ptr := &(reuse_val);
|
|
88
|
-
io.await(IO_tcp.setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, *(u8)(reuse_ptr), u32(4)));
|
|
85
|
+
e.io.await(IO_tcp.setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, *(u8)(reuse_ptr), u32(4)), e.io);
|
|
89
86
|
// Bind
|
|
90
87
|
saddr := _make_sockaddr(addr);
|
|
91
|
-
bind_result := io.await(IO_tcp.bind(fd, saddr.buf, saddr.len));
|
|
88
|
+
bind_result := e.io.await(IO_tcp.bind(fd, saddr.buf, saddr.len), e.io);
|
|
92
89
|
IO_tcp.free_sockaddr(saddr);
|
|
93
90
|
cond(
|
|
94
91
|
(bind_result < i32(0)) => {
|
|
95
|
-
io.await(IO_tcp.close(fd));
|
|
96
|
-
_throw_io(i32(0) - bind_result);
|
|
92
|
+
e.io.await(IO_tcp.close(fd), e.io);
|
|
93
|
+
_throw_io(i32(0) - bind_result, e.exn);
|
|
97
94
|
},
|
|
98
95
|
true => ()
|
|
99
96
|
);
|
|
100
97
|
// Listen
|
|
101
|
-
listen_result := io.await(IO_tcp.listen(fd, i32(128)));
|
|
98
|
+
listen_result := e.io.await(IO_tcp.listen(fd, i32(128)), e.io);
|
|
102
99
|
cond(
|
|
103
100
|
(listen_result < i32(0)) => {
|
|
104
|
-
io.await(IO_tcp.close(fd));
|
|
105
|
-
_throw_io(i32(0) - listen_result);
|
|
101
|
+
e.io.await(IO_tcp.close(fd), e.io);
|
|
102
|
+
_throw_io(i32(0) - listen_result, e.exn);
|
|
106
103
|
},
|
|
107
104
|
true => ()
|
|
108
105
|
);
|
|
@@ -110,19 +107,19 @@ impl(
|
|
|
110
107
|
})
|
|
111
108
|
),
|
|
112
109
|
/// Accept an incoming connection, returning a new `TcpStream`.
|
|
113
|
-
accept : (fn(self : Self,
|
|
110
|
+
accept : (fn(self : Self, io : Io) -> Impl(Future(TcpStream, IoExn)))({
|
|
114
111
|
fd := self._fd;
|
|
115
|
-
io.async((
|
|
112
|
+
io.async((e) => {
|
|
116
113
|
// Allocate space for the peer address
|
|
117
114
|
addr_buf := *(u8)(malloc(usize(128)).unwrap());
|
|
118
115
|
addr_len := *(u32)(malloc(usize(4)).unwrap());
|
|
119
116
|
addr_len.* = u32(128);
|
|
120
|
-
client_fd := io.await(IO_tcp.accept(fd, addr_buf, addr_len));
|
|
117
|
+
client_fd := e.io.await(IO_tcp.accept(fd, addr_buf, addr_len), e.io);
|
|
121
118
|
cond(
|
|
122
119
|
(client_fd < i32(0)) => {
|
|
123
120
|
free(.Some(*(void)(addr_buf)));
|
|
124
121
|
free(.Some(*(void)(addr_len)));
|
|
125
|
-
_throw_io(i32(0) - client_fd);
|
|
122
|
+
_throw_io(i32(0) - client_fd, e.exn);
|
|
126
123
|
},
|
|
127
124
|
true => ()
|
|
128
125
|
);
|
|
@@ -145,17 +142,17 @@ impl(
|
|
|
145
142
|
self._local_addr
|
|
146
143
|
),
|
|
147
144
|
/// Close the listener socket.
|
|
148
|
-
close : (fn(self : Self,
|
|
145
|
+
close : (fn(self : Self, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
149
146
|
fd := self._fd;
|
|
150
|
-
io.async((
|
|
147
|
+
io.async((e) => {
|
|
151
148
|
cond(
|
|
152
149
|
self._is_closed => (),
|
|
153
150
|
true => {
|
|
154
|
-
r := io.await(IO_tcp.close(fd));
|
|
151
|
+
r := e.io.await(IO_tcp.close(fd), e.io);
|
|
155
152
|
self._is_closed = true;
|
|
156
153
|
cond(
|
|
157
154
|
(r < i32(0)) => {
|
|
158
|
-
_throw_io(i32(0) - r);
|
|
155
|
+
_throw_io(i32(0) - r, e.exn);
|
|
159
156
|
},
|
|
160
157
|
true => ()
|
|
161
158
|
);
|
|
@@ -190,21 +187,21 @@ export(TcpListener);
|
|
|
190
187
|
impl(
|
|
191
188
|
TcpStream,
|
|
192
189
|
/// Connect to a remote address, returning a new `TcpStream`.
|
|
193
|
-
connect : (fn(addr : SocketAddr,
|
|
194
|
-
io.async((
|
|
190
|
+
connect : (fn(addr : SocketAddr, io : Io) -> Impl(Future(TcpStream, IoExn)))(
|
|
191
|
+
io.async((e) => {
|
|
195
192
|
domain := cond(
|
|
196
193
|
addr.ip.is_v4() => AF_INET,
|
|
197
194
|
true => AF_INET6
|
|
198
195
|
);
|
|
199
|
-
raw_fd := io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)));
|
|
200
|
-
fd := NetError.check(raw_fd);
|
|
196
|
+
raw_fd := e.io.await(IO_tcp.socket(domain, SOCK_STREAM, i32(0)), e.io);
|
|
197
|
+
fd := NetError.check(raw_fd, e.exn);
|
|
201
198
|
saddr := _make_sockaddr(addr);
|
|
202
|
-
conn_result := io.await(IO_tcp.connect(fd, saddr.buf, saddr.len));
|
|
199
|
+
conn_result := e.io.await(IO_tcp.connect(fd, saddr.buf, saddr.len), e.io);
|
|
203
200
|
IO_tcp.free_sockaddr(saddr);
|
|
204
201
|
cond(
|
|
205
202
|
(conn_result < i32(0)) => {
|
|
206
|
-
io.await(IO_tcp.close(fd));
|
|
207
|
-
_throw_io(i32(0) - conn_result);
|
|
203
|
+
e.io.await(IO_tcp.close(fd), e.io);
|
|
204
|
+
_throw_io(i32(0) - conn_result, e.exn);
|
|
208
205
|
},
|
|
209
206
|
true => ()
|
|
210
207
|
);
|
|
@@ -219,58 +216,58 @@ impl(
|
|
|
219
216
|
),
|
|
220
217
|
/// Read bytes from the stream into `buf`.
|
|
221
218
|
/// Returns the number of bytes read, or 0 if the peer closed the connection.
|
|
222
|
-
read : (fn(self : Self, buf : *(u8), size : usize,
|
|
219
|
+
read : (fn(self : Self, buf : *(u8), size : usize, io : Io) -> Impl(Future(i32, IoExn)))({
|
|
223
220
|
fd := self._fd;
|
|
224
|
-
io.async((
|
|
225
|
-
r := io.await(IO_tcp.recv(fd, buf, size, i32(0)));
|
|
226
|
-
NetError.check(r)
|
|
221
|
+
io.async((e) => {
|
|
222
|
+
r := e.io.await(IO_tcp.recv(fd, buf, size, i32(0)), e.io);
|
|
223
|
+
NetError.check(r, e.exn)
|
|
227
224
|
})
|
|
228
225
|
}),
|
|
229
226
|
/// Write a `str` to the stream.
|
|
230
227
|
/// Returns the number of bytes written.
|
|
231
|
-
write_str : (fn(self : Self, data : str,
|
|
228
|
+
write_str : (fn(self : Self, data : str, io : Io) -> Impl(Future(i32, IoExn)))({
|
|
232
229
|
fd := self._fd;
|
|
233
230
|
s := String.from(data);
|
|
234
231
|
s_bytes := s.as_bytes();
|
|
235
|
-
io.async((
|
|
236
|
-
r := io.await(IO_tcp.send(fd, s_bytes.ptr().unwrap(), s_bytes.len(), i32(0)));
|
|
237
|
-
NetError.check(r)
|
|
232
|
+
io.async((e) => {
|
|
233
|
+
r := e.io.await(IO_tcp.send(fd, s_bytes.ptr().unwrap(), s_bytes.len(), i32(0)), e.io);
|
|
234
|
+
NetError.check(r, e.exn)
|
|
238
235
|
})
|
|
239
236
|
}),
|
|
240
237
|
/// Write a `String` to the stream.
|
|
241
238
|
/// Returns the number of bytes written.
|
|
242
|
-
write_string : (fn(self : Self, data : String,
|
|
239
|
+
write_string : (fn(self : Self, data : String, io : Io) -> Impl(Future(i32, IoExn)))({
|
|
243
240
|
fd := self._fd;
|
|
244
241
|
data_bytes := data.as_bytes();
|
|
245
|
-
io.async((
|
|
246
|
-
r := io.await(IO_tcp.send(fd, data_bytes.ptr().unwrap(), data_bytes.len(), i32(0)));
|
|
247
|
-
NetError.check(r)
|
|
242
|
+
io.async((e) => {
|
|
243
|
+
r := e.io.await(IO_tcp.send(fd, data_bytes.ptr().unwrap(), data_bytes.len(), i32(0)), e.io);
|
|
244
|
+
NetError.check(r, e.exn)
|
|
248
245
|
})
|
|
249
246
|
}),
|
|
250
247
|
/// Write raw bytes from an `ArrayList(u8)` to the stream.
|
|
251
248
|
/// Returns the number of bytes written.
|
|
252
|
-
write_bytes : (fn(self : Self, data : ArrayList(u8),
|
|
249
|
+
write_bytes : (fn(self : Self, data : ArrayList(u8), io : Io) -> Impl(Future(i32, IoExn)))({
|
|
253
250
|
fd := self._fd;
|
|
254
|
-
io.async((
|
|
255
|
-
r := io.await(IO_tcp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
|
|
256
|
-
NetError.check(r)
|
|
251
|
+
io.async((e) => {
|
|
252
|
+
r := e.io.await(IO_tcp.send(fd, data.ptr().unwrap(), data.len(), i32(0)), e.io);
|
|
253
|
+
NetError.check(r, e.exn)
|
|
257
254
|
})
|
|
258
255
|
}),
|
|
259
256
|
/// Read all available data from the stream into a byte list.
|
|
260
|
-
read_bytes : (fn(self : Self,
|
|
257
|
+
read_bytes : (fn(self : Self, io : Io) -> Impl(Future(ArrayList(u8), IoExn)))({
|
|
261
258
|
fd := self._fd;
|
|
262
|
-
io.async((
|
|
259
|
+
io.async((e) => {
|
|
263
260
|
buf_size := usize(4096);
|
|
264
261
|
buf := *(u8)(malloc(buf_size).unwrap());
|
|
265
262
|
acc := ArrayList(u8).new();
|
|
266
263
|
done := false;
|
|
267
264
|
while(runtime(!(done)), {
|
|
268
|
-
n := io.await(IO_tcp.recv(fd, buf, buf_size, i32(0)));
|
|
265
|
+
n := e.io.await(IO_tcp.recv(fd, buf, buf_size, i32(0)), e.io);
|
|
269
266
|
cond(
|
|
270
267
|
(n < i32(0)) => {
|
|
271
268
|
free(.Some(*(void)(buf)));
|
|
272
269
|
done = true;
|
|
273
|
-
_throw_io(i32(0) - n);
|
|
270
|
+
_throw_io(i32(0) - n, e.exn);
|
|
274
271
|
},
|
|
275
272
|
(n == i32(0)) => {
|
|
276
273
|
done = true;
|
|
@@ -290,30 +287,30 @@ impl(
|
|
|
290
287
|
}),
|
|
291
288
|
/// Shut down part or all of the connection.
|
|
292
289
|
/// `how`: 0 = read, 1 = write, 2 = both.
|
|
293
|
-
shutdown : (fn(self : Self, how : i32,
|
|
290
|
+
shutdown : (fn(self : Self, how : i32, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
294
291
|
fd := self._fd;
|
|
295
|
-
io.async((
|
|
296
|
-
r := io.await(IO_tcp.shutdown(fd, how));
|
|
292
|
+
io.async((e) => {
|
|
293
|
+
r := e.io.await(IO_tcp.shutdown(fd, how), e.io);
|
|
297
294
|
cond(
|
|
298
295
|
(r < i32(0)) => {
|
|
299
|
-
_throw_io(i32(0) - r);
|
|
296
|
+
_throw_io(i32(0) - r, e.exn);
|
|
300
297
|
},
|
|
301
298
|
true => ()
|
|
302
299
|
);
|
|
303
300
|
})
|
|
304
301
|
}),
|
|
305
302
|
/// Close the stream.
|
|
306
|
-
close : (fn(self : Self,
|
|
303
|
+
close : (fn(self : Self, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
307
304
|
fd := self._fd;
|
|
308
|
-
io.async((
|
|
305
|
+
io.async((e) => {
|
|
309
306
|
cond(
|
|
310
307
|
self._is_closed => (),
|
|
311
308
|
true => {
|
|
312
|
-
r := io.await(IO_tcp.close(fd));
|
|
309
|
+
r := e.io.await(IO_tcp.close(fd), e.io);
|
|
313
310
|
self._is_closed = true;
|
|
314
311
|
cond(
|
|
315
312
|
(r < i32(0)) => {
|
|
316
|
-
_throw_io(i32(0) - r);
|
|
313
|
+
_throw_io(i32(0) - r, e.exn);
|
|
317
314
|
},
|
|
318
315
|
true => ()
|
|
319
316
|
);
|
|
@@ -330,30 +327,30 @@ impl(
|
|
|
330
327
|
self._fd
|
|
331
328
|
),
|
|
332
329
|
/// Enable or disable TCP_NODELAY (disables Nagle's algorithm).
|
|
333
|
-
set_nodelay : (fn(self : Self, nodelay : bool,
|
|
330
|
+
set_nodelay : (fn(self : Self, nodelay : bool, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
334
331
|
sock_fd := self._fd;
|
|
335
|
-
io.async((
|
|
332
|
+
io.async((e) => {
|
|
336
333
|
val := cond(nodelay => i32(1), true => i32(0));
|
|
337
334
|
val_ptr := &(val);
|
|
338
|
-
r := io.await(IO_tcp.setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, *(u8)(val_ptr), u32(4)));
|
|
335
|
+
r := e.io.await(IO_tcp.setsockopt(sock_fd, IPPROTO_TCP, TCP_NODELAY, *(u8)(val_ptr), u32(4)), e.io);
|
|
339
336
|
cond(
|
|
340
337
|
(r < i32(0)) => {
|
|
341
|
-
_throw_io(i32(0) - r);
|
|
338
|
+
_throw_io(i32(0) - r, e.exn);
|
|
342
339
|
},
|
|
343
340
|
true => ()
|
|
344
341
|
);
|
|
345
342
|
})
|
|
346
343
|
}),
|
|
347
344
|
/// Enable or disable SO_KEEPALIVE on the socket.
|
|
348
|
-
set_keepalive : (fn(self : Self, enabled : bool,
|
|
345
|
+
set_keepalive : (fn(self : Self, enabled : bool, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
349
346
|
sock_fd := self._fd;
|
|
350
|
-
io.async((
|
|
347
|
+
io.async((e) => {
|
|
351
348
|
val := cond(enabled => i32(1), true => i32(0));
|
|
352
349
|
val_ptr := &(val);
|
|
353
|
-
r := io.await(IO_tcp.setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, *(u8)(val_ptr), u32(4)));
|
|
350
|
+
r := e.io.await(IO_tcp.setsockopt(sock_fd, SOL_SOCKET, SO_KEEPALIVE, *(u8)(val_ptr), u32(4)), e.io);
|
|
354
351
|
cond(
|
|
355
352
|
(r < i32(0)) => {
|
|
356
|
-
_throw_io(i32(0) - r);
|
|
353
|
+
_throw_io(i32(0) - r, e.exn);
|
|
357
354
|
},
|
|
358
355
|
true => ()
|
|
359
356
|
);
|
package/std/net/udp.yo
CHANGED
|
@@ -9,24 +9,21 @@
|
|
|
9
9
|
// { SocketAddr, IpAddr } :: import "std/net/addr";
|
|
10
10
|
// { Exception } :: import "std/error";
|
|
11
11
|
//
|
|
12
|
-
// main :: (fn(
|
|
13
|
-
// given(exn) := Exception(throw : ((err) -> {
|
|
14
|
-
// println(err.message());
|
|
15
|
-
// escape ();
|
|
16
|
-
// }));
|
|
12
|
+
// main :: (fn(io : Io, exn : Exception) -> unit)({
|
|
17
13
|
// addr := SocketAddr.new(IpAddr.loopback_v4(), u16(9999));
|
|
18
|
-
// sock := io.await(UdpSocket.bind(addr));
|
|
19
|
-
// io.await(sock.close());
|
|
14
|
+
// sock := io.await(UdpSocket.bind(addr, io), { io, exn });
|
|
15
|
+
// io.await(sock.close(io), { io, exn });
|
|
20
16
|
// });
|
|
17
|
+
pragma(Pragma.AllowUnsafe);
|
|
21
18
|
{ GlobalAllocator } :: import("../allocator");
|
|
22
19
|
{ malloc, free } :: GlobalAllocator;
|
|
23
20
|
{ ArrayList } :: import("../collections/array_list");
|
|
24
21
|
open(import("../string"));
|
|
25
22
|
open(import("../fmt"));
|
|
26
23
|
{ NetError } :: import("./errors");
|
|
27
|
-
{
|
|
24
|
+
{ IoError } :: import("../sys/errors");
|
|
28
25
|
{ IpAddr, SocketAddr } :: import("./addr");
|
|
29
|
-
{ Error, AnyError, Exception } :: import("../error");
|
|
26
|
+
{ Error, AnyError, Exception, IoExn } :: import("../error");
|
|
30
27
|
IO_udp :: import("../sys/udp");
|
|
31
28
|
IO_tcp :: import("../sys/tcp");
|
|
32
29
|
{ AF_INET, AF_INET6, SOCK_DGRAM, SOL_SOCKET, SO_BROADCAST } :: import("../sys/socket");
|
|
@@ -39,15 +36,15 @@ _make_sockaddr :: (fn(addr : SocketAddr) -> IO_tcp.SockAddr)(
|
|
|
39
36
|
addr.ip,
|
|
40
37
|
.V4(a, b, c, d) => {
|
|
41
38
|
buf := Array(u8, usize(16)).fill(u8(0));
|
|
42
|
-
snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d));
|
|
39
|
+
unsafe(snprintf(*(char)(&(buf(usize(0)))), usize(16), "%d.%d.%d.%d", i32(a), i32(b), i32(c), i32(d)));
|
|
43
40
|
IO_tcp.make_sockaddr_in(&(buf(usize(0))), addr.port)
|
|
44
41
|
},
|
|
45
42
|
.V6(_) =>
|
|
46
43
|
IO_tcp.make_sockaddr_in6(*(u8)("::1"), addr.port)
|
|
47
44
|
)
|
|
48
45
|
);
|
|
49
|
-
_throw_net_io :: (fn(errno_val : i32,
|
|
50
|
-
exn.throw(dyn(NetError.from_io(
|
|
46
|
+
_throw_net_io :: (fn(errno_val : i32, exn : Exception) -> unit)(
|
|
47
|
+
exn.throw(dyn(NetError.from_io(IoError.from_errno(errno_val))))
|
|
51
48
|
);
|
|
52
49
|
// ============================================================================
|
|
53
50
|
// UdpSocket
|
|
@@ -61,21 +58,21 @@ UdpSocket :: object(
|
|
|
61
58
|
impl(
|
|
62
59
|
UdpSocket,
|
|
63
60
|
/// Create and bind a UDP socket to the given address.
|
|
64
|
-
bind : (fn(addr : SocketAddr,
|
|
65
|
-
io.async((
|
|
61
|
+
bind : (fn(addr : SocketAddr, io : Io) -> Impl(Future(UdpSocket, IoExn)))(
|
|
62
|
+
io.async((e) => {
|
|
66
63
|
domain := cond(
|
|
67
64
|
addr.ip.is_v4() => AF_INET,
|
|
68
65
|
true => AF_INET6
|
|
69
66
|
);
|
|
70
|
-
raw_fd := io.await(IO_udp.socket(domain, i32(0)));
|
|
71
|
-
fd := NetError.check(raw_fd);
|
|
67
|
+
raw_fd := e.io.await(IO_udp.socket(domain, i32(0)), e.io);
|
|
68
|
+
fd := NetError.check(raw_fd, e.exn);
|
|
72
69
|
saddr := _make_sockaddr(addr);
|
|
73
|
-
bind_r := io.await(IO_udp.bind(fd, saddr.buf, saddr.len));
|
|
70
|
+
bind_r := e.io.await(IO_udp.bind(fd, saddr.buf, saddr.len), e.io);
|
|
74
71
|
IO_tcp.free_sockaddr(saddr);
|
|
75
72
|
cond(
|
|
76
73
|
(bind_r < i32(0)) => {
|
|
77
|
-
io.await(IO_udp.close(fd));
|
|
78
|
-
_throw_net_io(i32(0) - bind_r);
|
|
74
|
+
e.io.await(IO_udp.close(fd), e.io);
|
|
75
|
+
_throw_net_io(i32(0) - bind_r, e.exn);
|
|
79
76
|
},
|
|
80
77
|
true => ()
|
|
81
78
|
);
|
|
@@ -84,53 +81,53 @@ impl(
|
|
|
84
81
|
),
|
|
85
82
|
/// Send a datagram to a specific address.
|
|
86
83
|
/// Returns the number of bytes sent.
|
|
87
|
-
send_to : (fn(self : Self, data : ArrayList(u8), addr : SocketAddr,
|
|
84
|
+
send_to : (fn(self : Self, data : ArrayList(u8), addr : SocketAddr, io : Io) -> Impl(Future(i32, IoExn)))({
|
|
88
85
|
fd := self._fd;
|
|
89
|
-
io.async((
|
|
86
|
+
io.async((e) => {
|
|
90
87
|
saddr := _make_sockaddr(addr);
|
|
91
|
-
r := io.await(IO_udp.sendto(fd, data.ptr().unwrap(), data.len(), i32(0), saddr.buf, saddr.len));
|
|
88
|
+
r := e.io.await(IO_udp.sendto(fd, data.ptr().unwrap(), data.len(), i32(0), saddr.buf, saddr.len), e.io);
|
|
92
89
|
IO_tcp.free_sockaddr(saddr);
|
|
93
|
-
NetError.check(r)
|
|
90
|
+
NetError.check(r, e.exn)
|
|
94
91
|
})
|
|
95
92
|
}),
|
|
96
93
|
/// Receive a datagram into the provided buffer.
|
|
97
94
|
/// Returns the number of bytes received.
|
|
98
|
-
recv : (fn(self : Self, buf : *(u8), size : usize,
|
|
95
|
+
recv : (fn(self : Self, buf : *(u8), size : usize, io : Io) -> Impl(Future(i32, IoExn)))({
|
|
99
96
|
fd := self._fd;
|
|
100
|
-
io.async((
|
|
101
|
-
r := io.await(IO_udp.recv(fd, buf, size, i32(0)));
|
|
102
|
-
NetError.check(r)
|
|
97
|
+
io.async((e) => {
|
|
98
|
+
r := e.io.await(IO_udp.recv(fd, buf, size, i32(0)), e.io);
|
|
99
|
+
NetError.check(r, e.exn)
|
|
103
100
|
})
|
|
104
101
|
}),
|
|
105
102
|
/// Receive a datagram and retrieve the sender's address.
|
|
106
103
|
/// Returns the number of bytes received.
|
|
107
|
-
recv_from : (fn(self : Self, buf : *(u8), size : usize, src_addr : *(u8), src_addr_len : *(u32),
|
|
104
|
+
recv_from : (fn(self : Self, buf : *(u8), size : usize, src_addr : *(u8), src_addr_len : *(u32), io : Io) -> Impl(Future(i32, IoExn)))({
|
|
108
105
|
fd := self._fd;
|
|
109
|
-
io.async((
|
|
110
|
-
r := io.await(IO_udp.recvfrom(fd, buf, size, i32(0), src_addr, src_addr_len));
|
|
111
|
-
NetError.check(r)
|
|
106
|
+
io.async((e) => {
|
|
107
|
+
r := e.io.await(IO_udp.recvfrom(fd, buf, size, i32(0), src_addr, src_addr_len), e.io);
|
|
108
|
+
NetError.check(r, e.exn)
|
|
112
109
|
})
|
|
113
110
|
}),
|
|
114
111
|
/// Send data on a connected socket (requires prior connect).
|
|
115
|
-
send : (fn(self : Self, data : ArrayList(u8),
|
|
112
|
+
send : (fn(self : Self, data : ArrayList(u8), io : Io) -> Impl(Future(i32, IoExn)))({
|
|
116
113
|
fd := self._fd;
|
|
117
|
-
io.async((
|
|
118
|
-
r := io.await(IO_udp.send(fd, data.ptr().unwrap(), data.len(), i32(0)));
|
|
119
|
-
NetError.check(r)
|
|
114
|
+
io.async((e) => {
|
|
115
|
+
r := e.io.await(IO_udp.send(fd, data.ptr().unwrap(), data.len(), i32(0)), e.io);
|
|
116
|
+
NetError.check(r, e.exn)
|
|
120
117
|
})
|
|
121
118
|
}),
|
|
122
119
|
/// Close the socket.
|
|
123
|
-
close : (fn(self : Self,
|
|
120
|
+
close : (fn(self : Self, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
124
121
|
fd := self._fd;
|
|
125
|
-
io.async((
|
|
122
|
+
io.async((e) => {
|
|
126
123
|
cond(
|
|
127
124
|
self._is_closed => (),
|
|
128
125
|
true => {
|
|
129
|
-
r := io.await(IO_udp.close(fd));
|
|
126
|
+
r := e.io.await(IO_udp.close(fd), e.io);
|
|
130
127
|
self._is_closed = true;
|
|
131
128
|
cond(
|
|
132
129
|
(r < i32(0)) => {
|
|
133
|
-
_throw_net_io(i32(0) - r);
|
|
130
|
+
_throw_net_io(i32(0) - r, e.exn);
|
|
134
131
|
},
|
|
135
132
|
true => ()
|
|
136
133
|
);
|
|
@@ -139,15 +136,15 @@ impl(
|
|
|
139
136
|
})
|
|
140
137
|
}),
|
|
141
138
|
/// Enable or disable SO_BROADCAST on the socket.
|
|
142
|
-
set_broadcast : (fn(self : Self, enabled : bool,
|
|
139
|
+
set_broadcast : (fn(self : Self, enabled : bool, io : Io) -> Impl(Future(unit, IoExn)))({
|
|
143
140
|
fd := self._fd;
|
|
144
|
-
io.async((
|
|
141
|
+
io.async((e) => {
|
|
145
142
|
val := cond(enabled => i32(1), true => i32(0));
|
|
146
143
|
val_ptr := &(val);
|
|
147
|
-
r := io.await(IO_udp.setsockopt(fd, SOL_SOCKET, SO_BROADCAST, *(u8)(val_ptr), u32(4)));
|
|
144
|
+
r := e.io.await(IO_udp.setsockopt(fd, SOL_SOCKET, SO_BROADCAST, *(u8)(val_ptr), u32(4)), e.io);
|
|
148
145
|
cond(
|
|
149
146
|
(r < i32(0)) => {
|
|
150
|
-
_throw_net_io(i32(0) - r);
|
|
147
|
+
_throw_net_io(i32(0) - r, e.exn);
|
|
151
148
|
},
|
|
152
149
|
true => ()
|
|
153
150
|
);
|
package/std/os/signal.yo
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
//! handler :: (fn(data: *(u8)) -> unit)({ println("Caught SIGINT"); });
|
|
11
11
|
//! on_signal(.Interrupt, handler);
|
|
12
12
|
//! ```
|
|
13
|
-
{
|
|
13
|
+
{ IoError } :: import("../sys/errors");
|
|
14
14
|
{ on_signal : _on_signal, off_signal : _off_signal, SignalHandler } :: import("../sys/signal");
|
|
15
15
|
{ platform, Platform } :: import("../process");
|
|
16
16
|
{ Error, AnyError, Exception } :: import("../error");
|
|
@@ -78,23 +78,23 @@ _signal_num :: (fn(sig : Signal) -> i32)(
|
|
|
78
78
|
// on_signal / off_signal
|
|
79
79
|
// ============================================================================
|
|
80
80
|
/// Register a handler for the given signal.
|
|
81
|
-
on_signal :: (fn(sig : Signal, handler : SignalHandler,
|
|
81
|
+
on_signal :: (fn(sig : Signal, handler : SignalHandler, exn : Exception) -> unit)({
|
|
82
82
|
num := _signal_num(sig);
|
|
83
83
|
r := _on_signal(num, handler);
|
|
84
84
|
cond(
|
|
85
85
|
(r < i32(0)) => {
|
|
86
|
-
exn.throw(dyn(
|
|
86
|
+
exn.throw(dyn(IoError.from_errno(i32(0) - r)));
|
|
87
87
|
},
|
|
88
88
|
true => ()
|
|
89
89
|
);
|
|
90
90
|
});
|
|
91
91
|
/// Remove the handler for the given signal.
|
|
92
|
-
off_signal :: (fn(sig : Signal,
|
|
92
|
+
off_signal :: (fn(sig : Signal, exn : Exception) -> unit)({
|
|
93
93
|
num := _signal_num(sig);
|
|
94
94
|
r := _off_signal(num);
|
|
95
95
|
cond(
|
|
96
96
|
(r < i32(0)) => {
|
|
97
|
-
exn.throw(dyn(
|
|
97
|
+
exn.throw(dyn(IoError.from_errno(i32(0) - r)));
|
|
98
98
|
},
|
|
99
99
|
true => ()
|
|
100
100
|
);
|