Committing for reference

This commit is contained in:
2025-01-12 02:02:01 +01:00
parent 52c8d1c95a
commit e0d246fe1f
17 changed files with 826 additions and 168 deletions

526
Cargo.lock generated
View File

@@ -87,12 +87,137 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "async-channel"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35"
dependencies = [
"concurrent-queue",
"event-listener 2.5.3",
"futures-core",
]
[[package]]
name = "async-channel"
version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a"
dependencies = [
"concurrent-queue",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-executor"
version = "1.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
"futures-lite",
"slab",
]
[[package]]
name = "async-global-executor"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c"
dependencies = [
"async-channel 2.3.1",
"async-executor",
"async-io",
"async-lock",
"blocking",
"futures-lite",
"once_cell",
]
[[package]]
name = "async-io"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059"
dependencies = [
"async-lock",
"cfg-if",
"concurrent-queue",
"futures-io",
"futures-lite",
"parking",
"polling",
"rustix",
"slab",
"tracing",
"windows-sys",
]
[[package]]
name = "async-lock"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18"
dependencies = [
"event-listener 5.4.0",
"event-listener-strategy",
"pin-project-lite",
]
[[package]]
name = "async-std"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615"
dependencies = [
"async-channel 1.9.0",
"async-global-executor",
"async-io",
"async-lock",
"crossbeam-utils",
"futures-channel",
"futures-core",
"futures-io",
"futures-lite",
"gloo-timers",
"kv-log-macro",
"log",
"memchr",
"once_cell",
"pin-project-lite",
"pin-utils",
"slab",
"wasm-bindgen-futures",
]
[[package]]
name = "async-task"
version = "4.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de"
[[package]]
name = "atomic-waker"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]] [[package]]
name = "autocfg" name = "autocfg"
version = "1.4.0" version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]] [[package]]
name = "bitvec" name = "bitvec"
version = "1.0.1" version = "1.0.1"
@@ -114,6 +239,19 @@ dependencies = [
"generic-array", "generic-array",
] ]
[[package]]
name = "blocking"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea"
dependencies = [
"async-channel 2.3.1",
"async-task",
"futures-io",
"futures-lite",
"piper",
]
[[package]] [[package]]
name = "borsh" name = "borsh"
version = "1.5.3" version = "1.5.3"
@@ -137,6 +275,12 @@ dependencies = [
"syn 2.0.95", "syn 2.0.95",
] ]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]] [[package]]
name = "bytecheck" name = "bytecheck"
version = "0.6.12" version = "0.6.12"
@@ -235,6 +379,15 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
[[package]] [[package]]
name = "const_panic" name = "const_panic"
version = "0.2.11" version = "0.2.11"
@@ -250,6 +403,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]] [[package]]
name = "crypto-common" name = "crypto-common"
version = "0.1.6" version = "0.1.6"
@@ -334,6 +493,49 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
dependencies = [
"libc",
"windows-sys",
]
[[package]]
name = "event-listener"
version = "2.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "event-listener"
version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2"
dependencies = [
"event-listener 5.4.0",
"pin-project-lite",
]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@@ -352,6 +554,108 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "futures"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
name = "futures-core"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
[[package]]
name = "futures-executor"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-lite"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cef40d21ae2c515b51041df9ed313ed21e572df340ea58a922a0aefe7e8891a1"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"parking",
"pin-project-lite",
]
[[package]]
name = "futures-macro"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
dependencies = [
"proc-macro2 1.0.92",
"quote 1.0.38",
"syn 2.0.95",
]
[[package]]
name = "futures-sink"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
[[package]]
name = "futures-task"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
[[package]]
name = "futures-util"
version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]] [[package]]
name = "generic-array" name = "generic-array"
version = "0.14.7" version = "0.14.7"
@@ -373,6 +677,18 @@ dependencies = [
"wasi", "wasi",
] ]
[[package]]
name = "gloo-timers"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994"
dependencies = [
"futures-channel",
"futures-core",
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.12.3" version = "0.12.3"
@@ -399,6 +715,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@@ -436,6 +758,16 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
[[package]]
name = "js-sys"
version = "0.3.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7"
dependencies = [
"once_cell",
"wasm-bindgen",
]
[[package]] [[package]]
name = "konst" name = "konst"
version = "0.3.16" version = "0.3.16"
@@ -463,6 +795,15 @@ version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "00af7901ba50898c9e545c24d5c580c96a982298134e8037d8978b6594782c07" checksum = "00af7901ba50898c9e545c24d5c580c96a982298134e8037d8978b6594782c07"
[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
dependencies = [
"log",
]
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
version = "1.5.0" version = "1.5.0"
@@ -475,6 +816,21 @@ version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "log"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
dependencies = [
"value-bag",
]
[[package]] [[package]]
name = "memchr" name = "memchr"
version = "2.7.4" version = "2.7.4"
@@ -536,6 +892,7 @@ dependencies = [
name = "orchid-base" name = "orchid-base"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-std",
"derive_destructure", "derive_destructure",
"dyn-clone", "dyn-clone",
"hashbrown 0.15.2", "hashbrown 0.15.2",
@@ -558,8 +915,10 @@ name = "orchid-extension"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"ahash 0.8.11", "ahash 0.8.11",
"async-std",
"derive_destructure", "derive_destructure",
"dyn-clone", "dyn-clone",
"futures",
"hashbrown 0.15.2", "hashbrown 0.15.2",
"itertools", "itertools",
"konst", "konst",
@@ -580,7 +939,9 @@ dependencies = [
name = "orchid-host" name = "orchid-host"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"async-std",
"derive_destructure", "derive_destructure",
"futures",
"hashbrown 0.15.2", "hashbrown 0.15.2",
"itertools", "itertools",
"lazy_static", "lazy_static",
@@ -630,12 +991,56 @@ dependencies = [
"num-traits", "num-traits",
] ]
[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]] [[package]]
name = "paste" name = "paste"
version = "1.0.15" version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "pin-project-lite"
version = "0.2.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
[[package]]
name = "pin-utils"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "piper"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066"
dependencies = [
"atomic-waker",
"fastrand",
"futures-io",
]
[[package]]
name = "polling"
version = "3.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f"
dependencies = [
"cfg-if",
"concurrent-queue",
"hermit-abi",
"pin-project-lite",
"rustix",
"tracing",
"windows-sys",
]
[[package]] [[package]]
name = "ppv-lite86" name = "ppv-lite86"
version = "0.2.20" version = "0.2.20"
@@ -834,6 +1239,19 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "rustix"
version = "0.38.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.18" version = "1.0.18"
@@ -904,6 +1322,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "stdio-perftest" name = "stdio-perftest"
version = "0.1.0" version = "0.1.0"
@@ -991,6 +1418,22 @@ dependencies = [
"winnow", "winnow",
] ]
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"pin-project-lite",
"tracing-core",
]
[[package]]
name = "tracing-core"
version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
[[package]] [[package]]
name = "trait-set" name = "trait-set"
version = "0.3.0" version = "0.3.0"
@@ -1047,6 +1490,12 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
[[package]]
name = "value-bag"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.5" version = "0.9.5"
@@ -1069,6 +1518,83 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasm-bindgen"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396"
dependencies = [
"cfg-if",
"once_cell",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79"
dependencies = [
"bumpalo",
"log",
"proc-macro2 1.0.92",
"quote 1.0.38",
"syn 2.0.95",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.49"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2"
dependencies = [
"cfg-if",
"js-sys",
"once_cell",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe"
dependencies = [
"quote 1.0.38",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2"
dependencies = [
"proc-macro2 1.0.92",
"quote 1.0.38",
"syn 2.0.95",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.99"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6"
[[package]]
name = "web-sys"
version = "0.3.76"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]] [[package]]
name = "winapi-util" name = "winapi-util"
version = "0.1.9" version = "0.1.9"

15
SWAP.md
View File

@@ -1,8 +1,3 @@
### Swapfile
A loose collection of ideas to quickly resume work
---
Must figure out how preprocessor can both be a System and referenced in the interpreter Must figure out how preprocessor can both be a System and referenced in the interpreter
Must actually write macro system as recorded in note Must actually write macro system as recorded in note
@@ -10,3 +5,13 @@ Must actually write macro system as recorded in note
At this point swappable preprocessors aren't a target because interaction with module system sounds complicated At this point swappable preprocessors aren't a target because interaction with module system sounds complicated
Check if any of this needs interpreter, if so, start with that Check if any of this needs interpreter, if so, start with that
## alternate extension mechanism
The Macro extension needs to be in the same compilation unit as the interpreter because the interpreter needs to proactively access its datastructures (in particular, it needs to generate MacTree from TokTree)
Ideally, it should reuse `orchid-extension` for message routing and decoding.
`orchid-host` accepts extensions as `impl ExtensionPort`

View File

@@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
async-std = "1.13.0"
derive_destructure = "1.0.0" derive_destructure = "1.0.0"
dyn-clone = "1.0.17" dyn-clone = "1.0.17"
hashbrown = "0.15.2" hashbrown = "0.15.2"

View File

@@ -0,0 +1,29 @@
use std::future::Future;
use std::ops::Deref;
use std::pin::Pin;
use crate::api;
/// The 3 primary contact points with an extension are
/// - send a message
/// - wait for a message to arrive
/// - wait for the extension to stop after exit (this is the implicit Drop)
///
/// There are no ordering guarantees about these
pub trait ExtPort {
fn send(&self, msg: &[u8]) -> Pin<Box<dyn Future<Output = ()>>>;
fn recv<'a>(&self, cb: Box<dyn FnOnce(&[u8]) + Send + 'a>) -> Pin<Box<dyn Future<Output = ()>>>;
}
pub struct ExtInit {
pub header: api::ExtensionHeader,
pub port: Box<dyn ExtPort>,
}
impl ExtInit {
pub async fn send(&self, msg: &[u8]) { self.port.send(msg).await }
pub async fn recv(&self, cb: impl FnOnce(&[u8]) + Send) { self.port.recv(Box::new(cb)).await }
}
impl Deref for ExtInit {
type Target = api::ExtensionHeader;
fn deref(&self) -> &Self::Target { &self.header }
}

View File

@@ -248,6 +248,7 @@ pub fn interner() -> impl DerefMut<Target = Interner> {
G(g) G(g)
} }
/// Initialize the interner in replica mode. No messages are sent at this point.
pub fn init_replica(req: impl DynRequester<Transfer = api::IntReq> + 'static) { pub fn init_replica(req: impl DynRequester<Transfer = api::IntReq> + 'static) {
let mut g = INTERNER.lock().unwrap(); let mut g = INTERNER.lock().unwrap();
assert!(g.is_none(), "Attempted to initialize replica interner after first use"); assert!(g.is_none(), "Attempted to initialize replica interner after first use");

View File

@@ -2,6 +2,7 @@ use orchid_api as api;
pub mod box_cow; pub mod box_cow;
pub mod boxed_iter; pub mod boxed_iter;
pub mod builtin;
pub mod char_filter; pub mod char_filter;
pub mod clone; pub mod clone;
pub mod combine; pub mod combine;

View File

@@ -1,16 +1,22 @@
use std::io; use std::io;
use std::pin::Pin;
use async_std::io::{Read, ReadExt, Write, WriteExt};
use orchid_api_traits::{Decode, Encode}; use orchid_api_traits::{Decode, Encode};
pub fn send_msg(write: &mut impl io::Write, msg: &[u8]) -> io::Result<()> { pub async fn send_msg(mut write: Pin<&mut impl Write>, msg: &[u8]) -> io::Result<()> {
u32::try_from(msg.len()).unwrap().encode(write); let mut len_buf = vec![];
write.write_all(msg)?; u32::try_from(msg.len()).unwrap().encode(&mut len_buf);
write.flush() write.write_all(&len_buf).await?;
write.write_all(msg).await?;
write.flush().await
} }
pub fn recv_msg(read: &mut impl io::Read) -> io::Result<Vec<u8>> { pub async fn recv_msg(mut read: Pin<&mut impl Read>) -> io::Result<Vec<u8>> {
let len = u32::decode(read); let mut len_buf = [0u8; (u32::BITS / 8) as usize];
read.read_exact(&mut len_buf).await?;
let len = u32::decode(&mut &len_buf[..]);
let mut msg = vec![0u8; len as usize]; let mut msg = vec![0u8; len as usize];
read.read_exact(&mut msg)?; read.read_exact(&mut msg).await?;
Ok(msg) Ok(msg)
} }

View File

@@ -1,32 +1,34 @@
use std::any::Any; use std::any::Any;
use std::cell::RefCell; use std::cell::RefCell;
use std::future::Future;
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::{BitAnd, Deref}; use std::ops::{BitAnd, Deref};
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{SyncSender, sync_channel}; use std::sync::mpsc::{SyncSender, sync_channel};
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::{mem, thread}; use std::{mem, thread};
use async_std::channel::{self, Sender};
use async_std::future;
use derive_destructure::destructure; use derive_destructure::destructure;
use dyn_clone::{DynClone, clone_box}; use dyn_clone::{DynClone, clone_box};
use hashbrown::HashMap; use hashbrown::HashMap;
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request}; use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request};
use trait_set::trait_set; use trait_set::trait_set;
pub struct Receipt; pub struct Receipt<'a>(PhantomData<&'a mut ()>);
impl Receipt {
pub fn off_thread(name: String, cb: impl FnOnce() -> Self + Send + 'static) -> Self {
thread::Builder::new().name(name).spawn(cb).unwrap();
Self
}
}
trait_set! { trait_set! {
pub trait SendFn<T: MsgSet> = for<'a> FnMut(&'a [u8], ReqNot<T>) + DynClone + Send + 'static; pub trait SendFn<T: MsgSet> =
for<'a> FnMut(&'a [u8], ReqNot<T>) -> Pin<Box<dyn Future<Output = ()> + 'a>>
+ DynClone + Send + 'static;
pub trait ReqFn<T: MsgSet> = pub trait ReqFn<T: MsgSet> =
FnMut(RequestHandle<T>, <T::In as Channel>::Req) -> Receipt + DynClone + Send + Sync + 'static; for<'a> FnMut(RequestHandle<T>, <T::In as Channel>::Req) -> Pin<Box<dyn Future<Output = Receipt>>>
+ DynClone + Send + Sync + 'static;
pub trait NotifFn<T: MsgSet> = pub trait NotifFn<T: MsgSet> =
for<'a> FnMut(<T::In as Channel>::Notif, ReqNot<T>) + DynClone + Send + Sync + 'static; for<'a> FnMut(<T::In as Channel>::Notif, ReqNot<T>) -> Pin<Box<dyn Future<Output = ()>>>
+ DynClone + Send + Sync + 'static;
} }
fn get_id(message: &[u8]) -> (u64, &[u8]) { fn get_id(message: &[u8]) -> (u64, &[u8]) {
@@ -38,35 +40,44 @@ pub trait ReqHandlish {
} }
#[derive(destructure)] #[derive(destructure)]
pub struct RequestHandle<MS: MsgSet> { pub struct RequestHandle<'a, MS: MsgSet> {
defer_drop: RefCell<Vec<Box<dyn Any>>>, defer_drop: RefCell<Vec<Box<dyn Any>>>,
fulfilled: AtomicBool, fulfilled: AtomicBool,
id: u64, id: u64,
_reqlt: PhantomData<&'a mut ()>,
parent: ReqNot<MS>, parent: ReqNot<MS>,
} }
impl<MS: MsgSet + 'static> RequestHandle<MS> { impl<'a, MS: MsgSet + 'static> RequestHandle<'a, MS> {
fn new(parent: ReqNot<MS>, id: u64) -> Self { fn new(parent: ReqNot<MS>, id: u64) -> Self {
Self { defer_drop: RefCell::default(), fulfilled: false.into(), parent, id } Self {
defer_drop: RefCell::default(),
fulfilled: false.into(),
_reqlt: PhantomData,
parent,
id,
}
} }
pub fn reqnot(&self) -> ReqNot<MS> { self.parent.clone() } pub fn reqnot(&self) -> ReqNot<MS> { self.parent.clone() }
pub fn handle<U: Request>(&self, _: &U, rep: &U::Response) -> Receipt { self.respond(rep) } pub async fn handle<U: Request>(&self, _: &U, rep: &U::Response) -> Receipt<'a> {
pub fn will_handle_as<U: Request>(&self, _: &U) -> ReqTypToken<U> { ReqTypToken(PhantomData) } self.respond(rep).await
pub fn handle_as<U: Request>(&self, _: ReqTypToken<U>, rep: &U::Response) -> Receipt {
self.respond(rep)
} }
pub fn respond(&self, response: &impl Encode) -> Receipt { pub fn will_handle_as<U: Request>(&self, _: &U) -> ReqTypToken<U> { ReqTypToken(PhantomData) }
pub async fn handle_as<U: Request>(&self, _: ReqTypToken<U>, rep: &U::Response) -> Receipt<'a> {
self.respond(rep).await
}
pub async fn respond(&self, response: &impl Encode) -> Receipt<'a> {
assert!(!self.fulfilled.swap(true, Ordering::Relaxed), "Already responded to {}", self.id); assert!(!self.fulfilled.swap(true, Ordering::Relaxed), "Already responded to {}", self.id);
let mut buf = (!self.id).to_be_bytes().to_vec(); let mut buf = (!self.id).to_be_bytes().to_vec();
response.encode(&mut buf); response.encode(&mut buf);
let mut send = clone_box(&*self.reqnot().0.lock().unwrap().send); let mut send = clone_box(&*self.reqnot().0.lock().unwrap().send);
(send)(&buf, self.parent.clone()); (send)(&buf, self.parent.clone()).await;
Receipt Receipt(PhantomData)
} }
} }
impl<MS: MsgSet> ReqHandlish for RequestHandle<MS> { impl<MS: MsgSet> ReqHandlish for RequestHandle<'_, MS> {
fn defer_drop(&self, val: impl Any) { self.defer_drop.borrow_mut().push(Box::new(val)) } fn defer_drop(&self, val: impl Any) { self.defer_drop.borrow_mut().push(Box::new(val)) }
} }
impl<MS: MsgSet> Drop for RequestHandle<MS> { impl<MS: MsgSet> Drop for RequestHandle<'_, MS> {
fn drop(&mut self) { fn drop(&mut self) {
let done = self.fulfilled.load(Ordering::Relaxed); let done = self.fulfilled.load(Ordering::Relaxed);
debug_assert!(done, "Request {} dropped without response", self.id) debug_assert!(done, "Request {} dropped without response", self.id)
@@ -80,7 +91,7 @@ pub struct ReqNotData<T: MsgSet> {
send: Box<dyn SendFn<T>>, send: Box<dyn SendFn<T>>,
notif: Box<dyn NotifFn<T>>, notif: Box<dyn NotifFn<T>>,
req: Box<dyn ReqFn<T>>, req: Box<dyn ReqFn<T>>,
responses: HashMap<u64, SyncSender<Vec<u8>>>, responses: HashMap<u64, channel::Sender<Vec<u8>>>,
} }
/// Wraps a raw message buffer to save on copying. /// Wraps a raw message buffer to save on copying.
@@ -105,44 +116,43 @@ impl<T: MsgSet> ReqNot<T> {
} }
/// Can be called from a polling thread or dispatched in any other way /// Can be called from a polling thread or dispatched in any other way
pub fn receive(&self, message: &[u8]) { pub async fn receive(&self, message: &[u8]) {
let mut g = self.0.lock().unwrap(); let mut g = self.0.lock().unwrap();
let (id, payload) = get_id(message); let (id, payload) = get_id(message);
if id == 0 { if id == 0 {
let mut notif = clone_box(&*g.notif); let mut notif = clone_box(&*g.notif);
mem::drop(g); mem::drop(g);
notif(<T::In as Channel>::Notif::decode(&mut &payload[..]), self.clone()) notif(<T::In as Channel>::Notif::decode(&mut &payload[..]), self.clone()).await
} else if 0 < id.bitand(1 << 63) { } else if 0 < id.bitand(1 << 63) {
let sender = g.responses.remove(&!id).expect("Received response for invalid message"); let sender = g.responses.remove(&!id).expect("Received response for invalid message");
sender.send(message.to_vec()).unwrap(); sender.send(message.to_vec()).await.unwrap();
} else { } else {
let message = <T::In as Channel>::Req::decode(&mut &payload[..]); let message = <T::In as Channel>::Req::decode(&mut &payload[..]);
let mut req = clone_box(&*g.req); let mut req = clone_box(&*g.req);
mem::drop(g); mem::drop(g);
let rn = self.clone(); let rn = self.clone();
thread::Builder::new() req(RequestHandle::new(rn, id), message).await;
.name(format!("request {id}"))
.spawn(move || req(RequestHandle::new(rn, id), message))
.unwrap();
} }
} }
pub fn notify<N: Coding + Into<<T::Out as Channel>::Notif>>(&self, notif: N) { pub async fn notify<N: Coding + Into<<T::Out as Channel>::Notif>>(&self, notif: N) {
let mut send = clone_box(&*self.0.lock().unwrap().send); let mut send = clone_box(&*self.0.lock().unwrap().send);
let mut buf = vec![0; 8]; let mut buf = vec![0; 8];
let msg: <T::Out as Channel>::Notif = notif.into(); let msg: <T::Out as Channel>::Notif = notif.into();
msg.encode(&mut buf); msg.encode(&mut buf);
send(&buf, self.clone()) send(&buf, self.clone()).await
} }
} }
pub trait DynRequester: Send + Sync { pub trait DynRequester: Send + Sync {
type Transfer; type Transfer;
/// Encode and send a request, then receive the response buffer. /// Encode and send a request, then receive the response buffer.
fn raw_request(&self, data: Self::Transfer) -> RawReply; fn raw_request(&self, data: Self::Transfer) -> Pin<Box<dyn Future<Output = RawReply>>>;
} }
pub struct MappedRequester<'a, T>(Box<dyn Fn(T) -> RawReply + Send + Sync + 'a>); pub struct MappedRequester<'a, T>(
Box<dyn Fn(T) -> Pin<Box<dyn Future<Output = RawReply>>> + Send + Sync + 'a>,
);
impl<'a, T> MappedRequester<'a, T> { impl<'a, T> MappedRequester<'a, T> {
fn new<U: DynRequester + 'a>(req: U) -> Self fn new<U: DynRequester + 'a>(req: U) -> Self
where T: Into<U::Transfer> { where T: Into<U::Transfer> {
@@ -152,38 +162,43 @@ impl<'a, T> MappedRequester<'a, T> {
impl<T> DynRequester for MappedRequester<'_, T> { impl<T> DynRequester for MappedRequester<'_, T> {
type Transfer = T; type Transfer = T;
fn raw_request(&self, data: Self::Transfer) -> RawReply { self.0(data) } fn raw_request(&self, data: Self::Transfer) -> Pin<Box<dyn Future<Output = RawReply>>> {
self.0(data)
}
} }
impl<T: MsgSet> DynRequester for ReqNot<T> { impl<T: MsgSet> DynRequester for ReqNot<T> {
type Transfer = <T::Out as Channel>::Req; type Transfer = <T::Out as Channel>::Req;
fn raw_request(&self, req: Self::Transfer) -> RawReply { fn raw_request(&self, req: Self::Transfer) -> Pin<Box<dyn Future<Output = RawReply>>> {
let mut g = self.0.lock().unwrap(); let mut g = self.0.lock().unwrap();
let id = g.id; let id = g.id;
g.id += 1; g.id += 1;
let mut buf = id.to_be_bytes().to_vec(); let mut buf = id.to_be_bytes().to_vec();
req.encode(&mut buf); req.encode(&mut buf);
let (send, recv) = sync_channel(1); let (send, recv) = channel::bounded(1);
g.responses.insert(id, send); g.responses.insert(id, send);
let mut send = clone_box(&*g.send); let mut send = clone_box(&*g.send);
mem::drop(g); mem::drop(g);
send(&buf, self.clone()); let rn = self.clone();
RawReply(recv.recv().unwrap()) Box::pin(async move {
send(&buf, rn).await;
RawReply(recv.recv().await.unwrap())
})
} }
} }
pub trait Requester: DynRequester { pub trait Requester: DynRequester {
#[must_use = "These types are subject to change with protocol versions. \ #[must_use = "These types are subject to change with protocol versions. \
If you don't want to use the return value, At a minimum, force the type."] If you don't want to use the return value, At a minimum, force the type."]
fn request<R: Request + Into<Self::Transfer>>(&self, data: R) -> R::Response; async fn request<R: Request + Into<Self::Transfer>>(&self, data: R) -> R::Response;
fn map<'a, U: Into<Self::Transfer>>(self) -> MappedRequester<'a, U> fn map<'a, U: Into<Self::Transfer>>(self) -> MappedRequester<'a, U>
where Self: Sized + 'a { where Self: Sized + 'a {
MappedRequester::new(self) MappedRequester::new(self)
} }
} }
impl<This: DynRequester + ?Sized> Requester for This { impl<This: DynRequester + ?Sized> Requester for This {
fn request<R: Request + Into<Self::Transfer>>(&self, data: R) -> R::Response { async fn request<R: Request + Into<Self::Transfer>>(&self, data: R) -> R::Response {
R::Response::decode(&mut &self.raw_request(data.into())[..]) R::Response::decode(&mut &self.raw_request(data.into()).await[..])
} }
} }
@@ -195,6 +210,7 @@ impl<T: MsgSet> Clone for ReqNot<T> {
mod test { mod test {
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use async_std::future;
use orchid_api_derive::Coding; use orchid_api_derive::Coding;
use orchid_api_traits::{Channel, Request}; use orchid_api_traits::{Channel, Request};
@@ -225,11 +241,16 @@ mod test {
let received = Arc::new(Mutex::new(None)); let received = Arc::new(Mutex::new(None));
let receiver = ReqNot::<TestMsgSet>::new( let receiver = ReqNot::<TestMsgSet>::new(
|_, _| panic!("Should not send anything"), |_, _| panic!("Should not send anything"),
clone!(received; move |notif, _| *received.lock().unwrap() = Some(notif)), clone!(received; move |notif, _| {
*received.lock().unwrap() = Some(notif);
Box::pin(future::ready(()))
}),
|_, _| panic!("Not receiving a request"), |_, _| panic!("Not receiving a request"),
); );
let sender = ReqNot::<TestMsgSet>::new( let sender = ReqNot::<TestMsgSet>::new(
clone!(receiver; move |d, _| receiver.receive(d)), clone!(receiver; move |d, _| Box::pin(async {
receiver.receive(d).await
})),
|_, _| panic!("Should not receive notif"), |_, _| panic!("Should not receive notif"),
|_, _| panic!("Should not receive request"), |_, _| panic!("Should not receive request"),
); );

View File

@@ -7,8 +7,10 @@ edition = "2021"
[dependencies] [dependencies]
ahash = "0.8.11" ahash = "0.8.11"
async-std = "1.13.0"
derive_destructure = "1.0.0" derive_destructure = "1.0.0"
dyn-clone = "1.0.17" dyn-clone = "1.0.17"
futures = "0.3.31"
hashbrown = "0.15.2" hashbrown = "0.15.2"
itertools = "0.14.0" itertools = "0.14.0"
konst = "0.3.16" konst = "0.3.16"

View File

@@ -81,6 +81,11 @@ pub fn extension_main(data: ExtensionData) {
} }
} }
pub struct ExtensionOwner {
rn: ReqNot<api::ExtMsgSet>,
onmessage: Mutex<OnMessage>,
}
fn extension_main_logic(data: ExtensionData) { fn extension_main_logic(data: ExtensionData) {
let api::HostHeader { log_strategy } = api::HostHeader::decode(&mut std::io::stdin().lock()); let api::HostHeader { log_strategy } = api::HostHeader::decode(&mut std::io::stdin().lock());
let mut buf = Vec::new(); let mut buf = Vec::new();

View File

@@ -1,6 +1,9 @@
use std::io; use std::pin::pin;
use async_std::io;
use orchid_base::msg::{recv_msg, send_msg}; use orchid_base::msg::{recv_msg, send_msg};
pub fn send_parent_msg(msg: &[u8]) -> io::Result<()> { send_msg(&mut io::stdout().lock(), msg) } pub async fn send_parent_msg(msg: &[u8]) -> io::Result<()> {
pub fn recv_parent_msg() -> io::Result<Vec<u8>> { recv_msg(&mut io::stdin().lock()) } send_msg(pin!(io::stdout()), msg).await
}
pub async fn recv_parent_msg() -> io::Result<Vec<u8>> { recv_msg(pin!(io::stdin())).await }

View File

@@ -6,7 +6,9 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
async-std = "1.13.0"
derive_destructure = "1.0.0" derive_destructure = "1.0.0"
futures = "0.3.31"
hashbrown = "0.15.2" hashbrown = "0.15.2"
itertools = "0.14.0" itertools = "0.14.0"
lazy_static = "1.5.0" lazy_static = "1.5.0"

View File

@@ -12,6 +12,7 @@ use hashbrown::hash_map::Entry;
use itertools::Itertools; use itertools::Itertools;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use orchid_api_traits::Request; use orchid_api_traits::Request;
use orchid_base::builtin::{ExtFactory, ExtPort};
use orchid_base::char_filter::char_filter_match; use orchid_base::char_filter::char_filter_match;
use orchid_base::clone; use orchid_base::clone;
use orchid_base::error::{OrcErrv, OrcRes}; use orchid_base::error::{OrcErrv, OrcRes};
@@ -106,27 +107,13 @@ impl fmt::Display for AtomHand {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.print()) } fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.write_str(&self.print()) }
} }
pub type OnMessage = Box<dyn FnMut(&[u8]) + Send>;
/// The 3 primary contact points with an extension are
/// - send a message
/// - wait for a message to arrive
/// - wait for the extension to stop after exit (this is the implicit Drop)
///
/// There are no ordering guarantees about these
pub trait ExtensionPort: Send + Sync {
fn set_onmessage(&self, callback: OnMessage);
fn send(&self, msg: &[u8]);
fn header(&self) -> &api::ExtensionHeader;
}
/// Data held about an Extension. This is refcounted within [Extension]. It's /// Data held about an Extension. This is refcounted within [Extension]. It's
/// important to only ever access parts of this struct through the [Arc] because /// important to only ever access parts of this struct through the [Arc] because
/// the components reference each other through [Weak]s of it, and will panic if /// the components reference each other through [Weak]s of it, and will panic if
/// upgrading fails. /// upgrading fails.
#[derive(destructure)] #[derive(destructure)]
pub struct ExtensionData { pub struct ExtensionData {
port: Arc<dyn ExtensionPort>, port: Mutex<Box<dyn ExtPort>>,
// child: Mutex<process::Child>, // child: Mutex<process::Child>,
// child_stdin: Mutex<ChildStdin>, // child_stdin: Mutex<ChildStdin>,
reqnot: ReqNot<api::HostMsgSet>, reqnot: ReqNot<api::HostMsgSet>,
@@ -153,84 +140,81 @@ fn rel_expr(sys: api::SysId, extk: api::ExprTicket) {
#[derive(Clone)] #[derive(Clone)]
pub struct Extension(Arc<ExtensionData>); pub struct Extension(Arc<ExtensionData>);
impl Extension { impl Extension {
pub fn new_process(port: Arc<dyn ExtensionPort>, logger: Logger) -> io::Result<Self> { pub fn new(fac: Box<dyn ExtFactory>, logger: Logger) -> io::Result<Self> {
let eh = port.header(); Ok(Self(Arc::new_cyclic(|weak: &Weak<ExtensionData>| {
let ret = Arc::new_cyclic(|weak: &Weak<ExtensionData>| ExtensionData { let (eh, port) = fac.run(Box::new(clone!(weak; move |msg| {
systems: (eh.systems.iter().cloned()) weak.upgrade().inspect(|xd| xd.reqnot.receive(msg));
.map(|decl| SystemCtor { decl, ext: weak.clone() }) })));
.collect(), ExtensionData {
logger, systems: (eh.systems.iter().cloned())
port: port.clone(), .map(|decl| SystemCtor { decl, ext: weak.clone() })
reqnot: ReqNot::new( .collect(),
clone!(weak; move |sfn, _| { logger,
let data = weak.upgrade().unwrap(); port: Mutex::new(port),
data.logger.log_buf("Downsending", sfn); reqnot: ReqNot::new(
data.port.send(sfn); clone!(weak; move |sfn, _| {
}), let data = weak.upgrade().unwrap();
clone!(weak; move |notif, _| match notif { data.logger.log_buf("Downsending", sfn);
api::ExtHostNotif::ExprNotif(api::ExprNotif::Acquire(acq)) => acq_expr(acq.0, acq.1), data.port.lock().unwrap().send(sfn);
api::ExtHostNotif::ExprNotif(api::ExprNotif::Release(rel)) => rel_expr(rel.0, rel.1), }),
api::ExtHostNotif::ExprNotif(api::ExprNotif::Move(mov)) => { clone!(weak; move |notif, _| match notif {
acq_expr(mov.inc, mov.expr); api::ExtHostNotif::ExprNotif(api::ExprNotif::Acquire(acq)) => acq_expr(acq.0, acq.1),
rel_expr(mov.dec, mov.expr); api::ExtHostNotif::ExprNotif(api::ExprNotif::Release(rel)) => rel_expr(rel.0, rel.1),
}, api::ExtHostNotif::ExprNotif(api::ExprNotif::Move(mov)) => {
api::ExtHostNotif::Log(api::Log(str)) => weak.upgrade().unwrap().logger.log(str), acq_expr(mov.inc, mov.expr);
}), rel_expr(mov.dec, mov.expr);
|hand, req| match req { },
api::ExtHostReq::Ping(ping) => hand.handle(&ping, &()), api::ExtHostNotif::Log(api::Log(str)) => weak.upgrade().unwrap().logger.log(str),
api::ExtHostReq::IntReq(intreq) => match intreq { }),
api::IntReq::InternStr(s) => hand.handle(&s, &intern(&**s.0).to_api()), |hand, req| match req {
api::IntReq::InternStrv(v) => hand.handle(&v, &intern(&*v.0).to_api()), api::ExtHostReq::Ping(ping) => hand.handle(&ping, &()),
api::IntReq::ExternStr(si) => hand.handle(&si, &Tok::<String>::from_api(si.0).arc()), api::ExtHostReq::IntReq(intreq) => match intreq {
api::IntReq::ExternStrv(vi) => hand.handle( api::IntReq::InternStr(s) => hand.handle(&s, &intern(&**s.0).to_api()),
&vi, api::IntReq::InternStrv(v) => hand.handle(&v, &intern(&*v.0).to_api()),
&Arc::new( api::IntReq::ExternStr(si) => hand.handle(&si, &Tok::<String>::from_api(si.0).arc()),
Tok::<Vec<Tok<String>>>::from_api(vi.0).iter().map(|t| t.to_api()).collect_vec(), api::IntReq::ExternStrv(vi) => hand.handle(
&vi,
&Arc::new(
Tok::<Vec<Tok<String>>>::from_api(vi.0).iter().map(|t| t.to_api()).collect_vec(),
),
),
},
api::ExtHostReq::Fwd(ref fw @ api::Fwd(ref atom, ref key, ref body)) => {
let sys = System::resolve(atom.owner).unwrap();
hand.handle(fw, &sys.reqnot().request(api::Fwded(fw.0.clone(), *key, body.clone())))
},
api::ExtHostReq::SysFwd(ref fw @ api::SysFwd(id, ref body)) => {
let sys = System::resolve(id).unwrap();
hand.handle(fw, &sys.request(body.clone()))
},
api::ExtHostReq::SubLex(sl) => {
let (rep_in, rep_out) = sync_channel(0);
let lex_g = LEX_RECUR.lock().unwrap();
let req_in = lex_g.get(&sl.id).expect("Sublex for nonexistent lexid");
req_in.send(ReqPair(sl.clone(), rep_in)).unwrap();
hand.handle(&sl, &rep_out.recv().unwrap())
},
api::ExtHostReq::ExprReq(api::ExprReq::Inspect(ins @ api::Inspect { target })) => {
let expr = Expr::resolve(target).expect("Invalid ticket");
hand.handle(&ins, &api::Inspected {
refcount: expr.strong_count() as u32,
location: expr.pos().to_api(),
kind: expr.to_api(),
})
},
api::ExtHostReq::RunMacros(ref rm @ api::RunMacros { ref run_id, ref query }) => hand
.handle(
rm,
&macro_recur(
*run_id,
mtreev_from_api(query, &mut |_| panic!("Recursion never contains atoms")),
)
.map(|x| macro_treev_to_api(*run_id, x)),
), ),
),
}, },
api::ExtHostReq::Fwd(ref fw @ api::Fwd(ref atom, ref key, ref body)) => { ),
let sys = System::resolve(atom.owner).unwrap();
hand.handle(fw, &sys.reqnot().request(api::Fwded(fw.0.clone(), *key, body.clone())))
},
api::ExtHostReq::SysFwd(ref fw @ api::SysFwd(id, ref body)) => {
let sys = System::resolve(id).unwrap();
hand.handle(fw, &sys.request(body.clone()))
},
api::ExtHostReq::SubLex(sl) => {
let (rep_in, rep_out) = sync_channel(0);
let lex_g = LEX_RECUR.lock().unwrap();
let req_in = lex_g.get(&sl.id).expect("Sublex for nonexistent lexid");
req_in.send(ReqPair(sl.clone(), rep_in)).unwrap();
hand.handle(&sl, &rep_out.recv().unwrap())
},
api::ExtHostReq::ExprReq(api::ExprReq::Inspect(ins @ api::Inspect { target })) => {
let expr = Expr::resolve(target).expect("Invalid ticket");
hand.handle(&ins, &api::Inspected {
refcount: expr.strong_count() as u32,
location: expr.pos().to_api(),
kind: expr.to_api(),
})
},
api::ExtHostReq::RunMacros(ref rm @ api::RunMacros { ref run_id, ref query }) => hand
.handle(
rm,
&macro_recur(
*run_id,
mtreev_from_api(query, &mut |_| panic!("Recursion never contains atoms")),
)
.map(|x| macro_treev_to_api(*run_id, x)),
),
},
),
});
let weak = Arc::downgrade(&ret);
port.set_onmessage(Box::new(move |msg| {
if let Some(xd) = weak.upgrade() {
xd.reqnot.receive(msg)
} }
})); })))
Ok(Self(ret))
} }
pub fn systems(&self) -> impl Iterator<Item = &SystemCtor> { self.0.systems.iter() } pub fn systems(&self) -> impl Iterator<Item = &SystemCtor> { self.0.systems.iter() }
} }
@@ -380,7 +364,7 @@ impl fmt::Debug for System {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let ctor = (self.0.ext.0.systems.iter().find(|c| c.decl.id == self.0.decl_id)) let ctor = (self.0.ext.0.systems.iter().find(|c| c.decl.id == self.0.decl_id))
.expect("System instance with no associated constructor"); .expect("System instance with no associated constructor");
write!(f, "System({} @ {} #{}, ", ctor.decl.name, ctor.decl.priority, self.0.id.0)?; write!(f, "System({} @ {} #{})", ctor.decl.name, ctor.decl.priority, self.0.id.0)?;
match self.0.exprs.read() { match self.0.exprs.read() {
Err(_) => write!(f, "expressions unavailable"), Err(_) => write!(f, "expressions unavailable"),
Ok(r) => { Ok(r) => {

View File

@@ -10,7 +10,7 @@ use trait_set::trait_set;
use crate::api; use crate::api;
use crate::extension::AtomHand; use crate::extension::AtomHand;
use crate::rule::matcher::{NamedMatcher, PriodMatcher}; use crate::rule::matcher::{NamedMatcher, PriodMatcher};
use crate::rule::state::{MatchState, OwnedState}; use crate::rule::state::MatchState;
use crate::tree::Code; use crate::tree::Code;
pub type MacTok = MTok<'static, AtomHand>; pub type MacTok = MTok<'static, AtomHand>;

View File

@@ -1,24 +1,20 @@
use std::io::{self, BufRead as _, Write}; use std::io::{self, BufRead as _, Write};
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::Mutex; use std::sync::mpsc::sync_channel;
use std::sync::mpsc::{SyncSender, sync_channel};
use std::{process, thread}; use std::{process, thread};
use async_std::sync::Mutex;
use orchid_api_traits::{Decode, Encode}; use orchid_api_traits::{Decode, Encode};
use orchid_base::builtin::{ExtInit, ExtPort};
use orchid_base::logging::Logger; use orchid_base::logging::Logger;
use orchid_base::msg::{recv_msg, send_msg}; use orchid_base::msg::{recv_msg, send_msg};
use crate::api; use crate::api;
use crate::extension::{ExtensionPort, OnMessage};
pub struct Subprocess { pub struct ExtensionCommand(pub process::Command, pub Logger);
child: Mutex<process::Child>, impl ExtFactory for ExtensionCommand {
stdin: Mutex<process::ChildStdin>, fn run(self: Box<Self>, onmessage: OnMessage) -> ExtInit {
set_onmessage: SyncSender<OnMessage>, let Self(mut cmd, logger) = *self;
header: api::ExtensionHeader,
}
impl Subprocess {
pub fn new(mut cmd: process::Command, logger: Logger) -> io::Result<Self> {
let prog_pbuf = PathBuf::from(cmd.get_program()); let prog_pbuf = PathBuf::from(cmd.get_program());
let prog = prog_pbuf.file_stem().unwrap_or(cmd.get_program()).to_string_lossy().to_string(); let prog = prog_pbuf.file_stem().unwrap_or(cmd.get_program()).to_string_lossy().to_string();
let mut child = cmd let mut child = cmd
@@ -54,19 +50,32 @@ impl Subprocess {
logger.log(buf); logger.log(buf);
} }
})?; })?;
Ok(Self { child: Mutex::new(child), stdin: Mutex::new(stdin), set_onmessage, header }) Ok(Subprocess { child: Mutex::new(child), stdin: Mutex::new(stdin), set_onmessage, header })
} }
} }
pub struct Subprocess {
child: Mutex<process::Child>,
stdin: Mutex<process::ChildStdin>,
stdout: Mutex<process::ChildStdout>,
header: api::ExtensionHeader,
}
impl Subprocess {
pub fn new(mut cmd: process::Command, logger: Logger) -> io::Result<Self> {}
}
impl Drop for Subprocess { impl Drop for Subprocess {
fn drop(&mut self) { self.child.lock().unwrap().wait().expect("Extension exited with error"); } fn drop(&mut self) { self.child.lock().unwrap().wait().expect("Extension exited with error"); }
} }
impl ExtensionPort for Subprocess { impl ExtPort for Subprocess {
fn set_onmessage(&self, callback: OnMessage) { self.set_onmessage.send(callback).unwrap(); }
fn header(&self) -> &orchid_api::ExtensionHeader { &self.header }
fn send(&self, msg: &[u8]) { fn send(&self, msg: &[u8]) {
if msg.starts_with(&[0, 0, 0, 0x1c]) { if msg.starts_with(&[0, 0, 0, 0x1c]) {
panic!("Received unnecessary prefix"); panic!("Received unnecessary prefix");
} }
send_msg(&mut *self.stdin.lock().unwrap(), msg).unwrap() send_msg(&mut *self.stdin.lock().unwrap(), msg).unwrap()
} }
fn recv<'a>(&self, cb: Box<dyn FnOnce(&[u8]) + Send + 'a>) -> futures::future::BoxFuture<()> {
async {
}
}
} }

View File

@@ -39,7 +39,7 @@ fn main() {
Commands::Lex { file } => { Commands::Lex { file } => {
let extensions = (args.extension.iter()) let extensions = (args.extension.iter())
.map(|f| Subprocess::new(Command::new(f.as_os_str()), logger.clone()).unwrap()) .map(|f| Subprocess::new(Command::new(f.as_os_str()), logger.clone()).unwrap())
.map(|cmd| Extension::new_process(Arc::new(cmd), logger.clone()).unwrap()) .map(|cmd| Extension::new(Arc::new(cmd), logger.clone()).unwrap())
.collect_vec(); .collect_vec();
let systems = init_systems(&args.system, &extensions).unwrap(); let systems = init_systems(&args.system, &extensions).unwrap();
let mut file = File::open(file.as_std_path()).unwrap(); let mut file = File::open(file.as_std_path()).unwrap();

View File

@@ -0,0 +1,63 @@
thread 'main' panicked at /rust/deps\annotate-snippets-0.9.2\src\display_list\from_snippet.rs:275:9:
SourceAnnotation range `(100, 102)` is bigger than source length `100`
stack backtrace:
0: 0x7fffc1edead3 - std::backtrace_rs::backtrace::dbghelp64::trace
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\..\..\backtrace\src\backtrace\dbghelp64.rs:91
1: 0x7fffc1edead3 - std::backtrace_rs::backtrace::trace_unsynchronized
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\..\..\backtrace\src\backtrace\mod.rs:66
2: 0x7fffc1edead3 - std::backtrace::Backtrace::create
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\backtrace.rs:331
3: 0x7fffc1edea1a - std::backtrace::Backtrace::force_capture
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\backtrace.rs:312
4: 0x7fffc350c6bd - core[fb98b8b4feea0183]::slice::sort::unstable::heapsort::heapsort::<((rustc_lint_defs[b054f3c0774bcbdc]::Level, &str), usize), <((rustc_lint_defs[b054f3c0774bcbdc]::Level, &str), usize) as core[fb98b8b4feea0183]::cmp::PartialOrd>::lt>
5: 0x7fffc1efa4ae - alloc::boxed::impl$30::call
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\alloc\src\boxed.rs:2027
6: 0x7fffc1efa4ae - std::panicking::rust_panic_with_hook
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:836
7: 0x7fffc1efa209 - std::panicking::begin_panic_handler::closure$0
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:701
8: 0x7fffc1ef78af - std::sys::backtrace::__rust_end_short_backtrace<std::panicking::begin_panic_handler::closure_env$0,never$>
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\sys\backtrace.rs:168
9: 0x7fffc1ef9e0e - std::panicking::begin_panic_handler
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:692
10: 0x7fffc4ddba91 - core::panicking::panic_fmt
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\core\src\panicking.rs:75
11: 0x7ff6008d1f04 - <unknown>
12: 0x7ff6006c56c5 - <unknown>
13: 0x7fffc1f29a2a - core::fmt::rt::Argument::fmt
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\core\src\fmt\rt.rs:177
14: 0x7fffc1f29a2a - core::fmt::write
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\core\src\fmt\mod.rs:1440
15: 0x7fffc1eea19b - std::io::Write::write_fmt
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\mod.rs:1887
16: 0x7fffc1eea19b - std::io::stdio::impl$26::write_fmt
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:1024
17: 0x7fffc1eeade6 - std::io::stdio::impl$25::write_fmt
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:998
18: 0x7fffc1eeade6 - std::io::stdio::print_to
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:1122
19: 0x7fffc1eeade6 - std::io::stdio::_eprint
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\io\stdio.rs:1244
20: 0x7ff6005a494b - <unknown>
21: 0x7ff6005a065d - <unknown>
22: 0x7ff60059c57c - <unknown>
23: 0x7ff60058a246 - <unknown>
24: 0x7ff60058a70c - <unknown>
25: 0x7fffc1edc62c - std::rt::lang_start_internal::closure$1
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\rt.rs:174
26: 0x7fffc1edc62c - std::panicking::try::do_call
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:584
27: 0x7fffc1edc62c - std::panicking::try
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panicking.rs:547
28: 0x7fffc1edc62c - std::panic::catch_unwind
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\panic.rs:358
29: 0x7fffc1edc62c - std::rt::lang_start_internal
at /rustc/b1a7dfb91106018f47ed9dc9b27aee1977682868/library\std\src\rt.rs:174
30: 0x7ff6005a5dbc - <unknown>
31: 0x7ff6008e3bd0 - <unknown>
32: 0x7ff8c09a7374 - BaseThreadInitThunk
33: 0x7ff8c167cc91 - RtlUserThreadStart
rustc version: 1.86.0-nightly (b1a7dfb91 2025-01-10)
platform: x86_64-pc-windows-msvc