feat(udp): Udp.* - polled IPv4 datagrams on macOS and Windows
Udp.open/port/send/recv/from_ip/from_port/close/resolve/local_ip/ip/ip_text, native BSD sockets (udp.ll) and Winsock (udp_win.ll, -lws2_32), linked only when a program uses Udp.*; example, docs and tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
6a7f1dd393
commit
ebb1a00352
24 changed files with 68630 additions and 66360 deletions
|
|
@ -48,7 +48,7 @@ function compile_app(src: pointer, out: pointer, mode: int, save: bool) -> bool
|
|||
|
||||
if mode == 2 {
|
||||
if not shq(`{ludicc()} --headless {src} --emit-llvm -o {ll}`) { return false }
|
||||
if not shq(`{cc()} -O2 {ll}{gl_link_flags(ll)}{vk_link_flags(ll)}{http_link_flags(ll)}{threads_link_flags(ll)}{pbf} -o {out}`) { return false }
|
||||
if not shq(`{cc()} -O2 {ll}{gl_link_flags(ll)}{vk_link_flags(ll)}{http_link_flags(ll)}{udp_link_flags(ll)}{threads_link_flags(ll)}{pbf} -o {out}`) { return false }
|
||||
if not save { shell(`rm -f {ll}`) }
|
||||
return true
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ function compile_app(src: pointer, out: pointer, mode: int, save: bool) -> bool
|
|||
# canonical `ludicc -o` path links it only when Audio.* is used.
|
||||
let cocoa = `{home}runtime/native/cocoa.ll`
|
||||
let audio = `{home}runtime/native/audio.ll`
|
||||
if not shq(`{cc()} -O2 {ll} {cocoa} {audio} -framework Cocoa -Wl,-needed_framework,GameController -Wl,-needed_framework,AVFoundation -Wl,-rpath,@loader_path{gl_link_flags(ll)}{vk_link_flags(ll)}{http_link_flags(ll)}{threads_link_flags(ll)}{pbf} -o {out}`) { return false }
|
||||
if not shq(`{cc()} -O2 {ll} {cocoa} {audio} -framework Cocoa -Wl,-needed_framework,GameController -Wl,-needed_framework,AVFoundation -Wl,-rpath,@loader_path{gl_link_flags(ll)}{vk_link_flags(ll)}{http_link_flags(ll)}{udp_link_flags(ll)}{threads_link_flags(ll)}{pbf} -o {out}`) { return false }
|
||||
if not save { shell(`rm -f {ll}`) }
|
||||
return true
|
||||
}
|
||||
|
|
@ -91,6 +91,13 @@ function http_link_flags(ll: pointer) -> pointer {
|
|||
return ` {ludic_home()}runtime/native/http.ll -Wl,-needed_framework,Foundation`
|
||||
}
|
||||
|
||||
# A program that uses Udp.* calls the lu_udp_* socket layer; link udp.ll only then, as
|
||||
# `ludicc -o` does (Windows links through ludicc, with udp_win.ll and ws2_32).
|
||||
function udp_link_flags(ll: pointer) -> pointer {
|
||||
if not shq(`grep -q "call .*@lu_udp_" {ll}`) { return "" }
|
||||
return ` {ludic_home()}runtime/native/udp.ll`
|
||||
}
|
||||
|
||||
# A program that uses Job.* / Promise.* / Sync.* calls the thr_* OS-thread runtime; link
|
||||
# threads.ll only then, as `ludicc -o` does.
|
||||
function threads_link_flags(ll: pointer) -> pointer {
|
||||
|
|
|
|||
|
|
@ -731,6 +731,20 @@ function cmd_dev_test() -> int {
|
|||
else { bad2("http.ludic via ludic build", `got [{got2}]`) }
|
||||
} else { bad2("ludic build of an Http.* program", capture_line(`tail -1 {tmp_dir()}/http_lb.out`)) }
|
||||
}
|
||||
# Udp.*: two sockets on the loopback, a datagram each way, through ludicc and ludic build
|
||||
if is_darwin() {
|
||||
let udp_want = "2 2 104 105 1 2 127.0.0.1 1 0 1"
|
||||
if shq(`LUDIC_HOME=. bin/ludicc examples/library/udp.ludic -o {tmp_dir()}/udp_demo > {tmp_dir()}/udp.out 2>&1`) {
|
||||
let got = capture_line(`{tmp_dir()}/udp_demo < /dev/null`)
|
||||
if (got == udp_want) { ok("udp.ludic (Udp.open/send/recv/from/ip - datagrams over the loopback)") }
|
||||
else { bad2("udp.ludic", `got [{got}]`) }
|
||||
} else { bad2("udp.ludic build", capture_line(`tail -1 {tmp_dir()}/udp.out`)) }
|
||||
if shq(`LUDIC_HOME=. bin/ludic build examples/library/udp.ludic --headless -o {tmp_dir()}/udp_lb > {tmp_dir()}/udp_lb.out 2>&1`) {
|
||||
let got2 = capture_line(`{tmp_dir()}/udp_lb < /dev/null`)
|
||||
if (got2 == udp_want) { ok("ludic build links udp.ll for a program that uses Udp.*") }
|
||||
else { bad2("udp.ludic via ludic build", `got [{got2}]`) }
|
||||
} else { bad2("ludic build of a Udp.* program", capture_line(`tail -1 {tmp_dir()}/udp_lb.out`)) }
|
||||
}
|
||||
|
||||
feat_case("events/recurse", "", "16", "recurse.ludic (EV6: re-entrant emit is depth-bounded, no runaway cycle)")
|
||||
net_case("events/scoped", "2")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue