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"
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]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "bitflags"
version = "2.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
[[package]]
name = "bitvec"
version = "1.0.1"
@@ -114,6 +239,19 @@ dependencies = [
"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]]
name = "borsh"
version = "1.5.3"
@@ -137,6 +275,12 @@ dependencies = [
"syn 2.0.95",
]
[[package]]
name = "bumpalo"
version = "3.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c"
[[package]]
name = "bytecheck"
version = "0.6.12"
@@ -235,6 +379,15 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "const_panic"
version = "0.2.11"
@@ -250,6 +403,12 @@ dependencies = [
"libc",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crypto-common"
version = "0.1.6"
@@ -334,6 +493,49 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "fnv"
version = "1.0.7"
@@ -352,6 +554,108 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "generic-array"
version = "0.14.7"
@@ -373,6 +677,18 @@ dependencies = [
"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]]
name = "hashbrown"
version = "0.12.3"
@@ -399,6 +715,12 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc"
[[package]]
name = "ident_case"
version = "1.0.1"
@@ -436,6 +758,16 @@ version = "1.0.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "konst"
version = "0.3.16"
@@ -463,6 +795,15 @@ version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "lazy_static"
version = "1.5.0"
@@ -475,6 +816,21 @@ version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "memchr"
version = "2.7.4"
@@ -536,6 +892,7 @@ dependencies = [
name = "orchid-base"
version = "0.1.0"
dependencies = [
"async-std",
"derive_destructure",
"dyn-clone",
"hashbrown 0.15.2",
@@ -558,8 +915,10 @@ name = "orchid-extension"
version = "0.1.0"
dependencies = [
"ahash 0.8.11",
"async-std",
"derive_destructure",
"dyn-clone",
"futures",
"hashbrown 0.15.2",
"itertools",
"konst",
@@ -580,7 +939,9 @@ dependencies = [
name = "orchid-host"
version = "0.1.0"
dependencies = [
"async-std",
"derive_destructure",
"futures",
"hashbrown 0.15.2",
"itertools",
"lazy_static",
@@ -630,12 +991,56 @@ dependencies = [
"num-traits",
]
[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
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]]
name = "ppv-lite86"
version = "0.2.20"
@@ -834,6 +1239,19 @@ dependencies = [
"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]]
name = "ryu"
version = "1.0.18"
@@ -904,6 +1322,15 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
[[package]]
name = "slab"
version = "0.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
[[package]]
name = "stdio-perftest"
version = "0.1.0"
@@ -991,6 +1418,22 @@ dependencies = [
"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]]
name = "trait-set"
version = "0.3.0"
@@ -1047,6 +1490,12 @@ version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a"
[[package]]
name = "value-bag"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2"
[[package]]
name = "version_check"
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"
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]]
name = "winapi-util"
version = "0.1.9"

17
SWAP.md
View File

@@ -1,12 +1,17 @@
### 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 actually write macro system as recorded in note
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
[dependencies]
async-std = "1.13.0"
derive_destructure = "1.0.0"
dyn-clone = "1.0.17"
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)
}
/// Initialize the interner in replica mode. No messages are sent at this point.
pub fn init_replica(req: impl DynRequester<Transfer = api::IntReq> + 'static) {
let mut g = INTERNER.lock().unwrap();
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 boxed_iter;
pub mod builtin;
pub mod char_filter;
pub mod clone;
pub mod combine;

View File

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

View File

@@ -1,32 +1,34 @@
use std::any::Any;
use std::cell::RefCell;
use std::future::Future;
use std::marker::PhantomData;
use std::ops::{BitAnd, Deref};
use std::pin::Pin;
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::mpsc::{SyncSender, sync_channel};
use std::sync::{Arc, Mutex};
use std::{mem, thread};
use async_std::channel::{self, Sender};
use async_std::future;
use derive_destructure::destructure;
use dyn_clone::{DynClone, clone_box};
use hashbrown::HashMap;
use orchid_api_traits::{Channel, Coding, Decode, Encode, MsgSet, Request};
use trait_set::trait_set;
pub struct Receipt;
impl Receipt {
pub fn off_thread(name: String, cb: impl FnOnce() -> Self + Send + 'static) -> Self {
thread::Builder::new().name(name).spawn(cb).unwrap();
Self
}
}
pub struct Receipt<'a>(PhantomData<&'a mut ()>);
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> =
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> =
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]) {
@@ -38,35 +40,44 @@ pub trait ReqHandlish {
}
#[derive(destructure)]
pub struct RequestHandle<MS: MsgSet> {
pub struct RequestHandle<'a, MS: MsgSet> {
defer_drop: RefCell<Vec<Box<dyn Any>>>,
fulfilled: AtomicBool,
id: u64,
_reqlt: PhantomData<&'a mut ()>,
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 {
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 handle<U: Request>(&self, _: &U, rep: &U::Response) -> Receipt { self.respond(rep) }
pub fn will_handle_as<U: Request>(&self, _: &U) -> ReqTypToken<U> { ReqTypToken(PhantomData) }
pub fn handle_as<U: Request>(&self, _: ReqTypToken<U>, rep: &U::Response) -> Receipt {
self.respond(rep)
pub async fn handle<U: Request>(&self, _: &U, rep: &U::Response) -> Receipt<'a> {
self.respond(rep).await
}
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);
let mut buf = (!self.id).to_be_bytes().to_vec();
response.encode(&mut buf);
let mut send = clone_box(&*self.reqnot().0.lock().unwrap().send);
(send)(&buf, self.parent.clone());
Receipt
(send)(&buf, self.parent.clone()).await;
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)) }
}
impl<MS: MsgSet> Drop for RequestHandle<MS> {
impl<MS: MsgSet> Drop for RequestHandle<'_, MS> {
fn drop(&mut self) {
let done = self.fulfilled.load(Ordering::Relaxed);
debug_assert!(done, "Request {} dropped without response", self.id)
@@ -80,7 +91,7 @@ pub struct ReqNotData<T: MsgSet> {
send: Box<dyn SendFn<T>>,
notif: Box<dyn NotifFn<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.
@@ -105,44 +116,43 @@ impl<T: MsgSet> ReqNot<T> {
}
/// 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 (id, payload) = get_id(message);
if id == 0 {
let mut notif = clone_box(&*g.notif);
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) {
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 {
let message = <T::In as Channel>::Req::decode(&mut &payload[..]);
let mut req = clone_box(&*g.req);
mem::drop(g);
let rn = self.clone();
thread::Builder::new()
.name(format!("request {id}"))
.spawn(move || req(RequestHandle::new(rn, id), message))
.unwrap();
req(RequestHandle::new(rn, id), message).await;
}
}
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 buf = vec![0; 8];
let msg: <T::Out as Channel>::Notif = notif.into();
msg.encode(&mut buf);
send(&buf, self.clone())
send(&buf, self.clone()).await
}
}
pub trait DynRequester: Send + Sync {
type Transfer;
/// 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> {
fn new<U: DynRequester + 'a>(req: U) -> Self
where T: Into<U::Transfer> {
@@ -152,38 +162,43 @@ impl<'a, T> MappedRequester<'a, T> {
impl<T> DynRequester for MappedRequester<'_, 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> {
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 id = g.id;
g.id += 1;
let mut buf = id.to_be_bytes().to_vec();
req.encode(&mut buf);
let (send, recv) = sync_channel(1);
let (send, recv) = channel::bounded(1);
g.responses.insert(id, send);
let mut send = clone_box(&*g.send);
mem::drop(g);
send(&buf, self.clone());
RawReply(recv.recv().unwrap())
let rn = self.clone();
Box::pin(async move {
send(&buf, rn).await;
RawReply(recv.recv().await.unwrap())
})
}
}
pub trait Requester: DynRequester {
#[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."]
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>
where Self: Sized + 'a {
MappedRequester::new(self)
}
}
impl<This: DynRequester + ?Sized> Requester for This {
fn request<R: Request + Into<Self::Transfer>>(&self, data: R) -> R::Response {
R::Response::decode(&mut &self.raw_request(data.into())[..])
async fn request<R: Request + Into<Self::Transfer>>(&self, data: R) -> R::Response {
R::Response::decode(&mut &self.raw_request(data.into()).await[..])
}
}
@@ -195,6 +210,7 @@ impl<T: MsgSet> Clone for ReqNot<T> {
mod test {
use std::sync::{Arc, Mutex};
use async_std::future;
use orchid_api_derive::Coding;
use orchid_api_traits::{Channel, Request};
@@ -225,11 +241,16 @@ mod test {
let received = Arc::new(Mutex::new(None));
let receiver = ReqNot::<TestMsgSet>::new(
|_, _| 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"),
);
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 request"),
);

View File

@@ -7,8 +7,10 @@ edition = "2021"
[dependencies]
ahash = "0.8.11"
async-std = "1.13.0"
derive_destructure = "1.0.0"
dyn-clone = "1.0.17"
futures = "0.3.31"
hashbrown = "0.15.2"
itertools = "0.14.0"
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) {
let api::HostHeader { log_strategy } = api::HostHeader::decode(&mut std::io::stdin().lock());
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};
pub fn send_parent_msg(msg: &[u8]) -> io::Result<()> { send_msg(&mut io::stdout().lock(), msg) }
pub fn recv_parent_msg() -> io::Result<Vec<u8>> { recv_msg(&mut io::stdin().lock()) }
pub async fn send_parent_msg(msg: &[u8]) -> io::Result<()> {
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
[dependencies]
async-std = "1.13.0"
derive_destructure = "1.0.0"
futures = "0.3.31"
hashbrown = "0.15.2"
itertools = "0.14.0"
lazy_static = "1.5.0"

View File

@@ -12,6 +12,7 @@ use hashbrown::hash_map::Entry;
use itertools::Itertools;
use lazy_static::lazy_static;
use orchid_api_traits::Request;
use orchid_base::builtin::{ExtFactory, ExtPort};
use orchid_base::char_filter::char_filter_match;
use orchid_base::clone;
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()) }
}
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
/// 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
/// upgrading fails.
#[derive(destructure)]
pub struct ExtensionData {
port: Arc<dyn ExtensionPort>,
port: Mutex<Box<dyn ExtPort>>,
// child: Mutex<process::Child>,
// child_stdin: Mutex<ChildStdin>,
reqnot: ReqNot<api::HostMsgSet>,
@@ -153,84 +140,81 @@ fn rel_expr(sys: api::SysId, extk: api::ExprTicket) {
#[derive(Clone)]
pub struct Extension(Arc<ExtensionData>);
impl Extension {
pub fn new_process(port: Arc<dyn ExtensionPort>, logger: Logger) -> io::Result<Self> {
let eh = port.header();
let ret = Arc::new_cyclic(|weak: &Weak<ExtensionData>| ExtensionData {
systems: (eh.systems.iter().cloned())
.map(|decl| SystemCtor { decl, ext: weak.clone() })
.collect(),
logger,
port: port.clone(),
reqnot: ReqNot::new(
clone!(weak; move |sfn, _| {
let data = weak.upgrade().unwrap();
data.logger.log_buf("Downsending", sfn);
data.port.send(sfn);
}),
clone!(weak; move |notif, _| match notif {
api::ExtHostNotif::ExprNotif(api::ExprNotif::Acquire(acq)) => acq_expr(acq.0, acq.1),
api::ExtHostNotif::ExprNotif(api::ExprNotif::Release(rel)) => rel_expr(rel.0, rel.1),
api::ExtHostNotif::ExprNotif(api::ExprNotif::Move(mov)) => {
acq_expr(mov.inc, mov.expr);
rel_expr(mov.dec, mov.expr);
},
api::ExtHostNotif::Log(api::Log(str)) => weak.upgrade().unwrap().logger.log(str),
}),
|hand, req| match req {
api::ExtHostReq::Ping(ping) => hand.handle(&ping, &()),
api::ExtHostReq::IntReq(intreq) => match intreq {
api::IntReq::InternStr(s) => hand.handle(&s, &intern(&**s.0).to_api()),
api::IntReq::InternStrv(v) => hand.handle(&v, &intern(&*v.0).to_api()),
api::IntReq::ExternStr(si) => hand.handle(&si, &Tok::<String>::from_api(si.0).arc()),
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(),
pub fn new(fac: Box<dyn ExtFactory>, logger: Logger) -> io::Result<Self> {
Ok(Self(Arc::new_cyclic(|weak: &Weak<ExtensionData>| {
let (eh, port) = fac.run(Box::new(clone!(weak; move |msg| {
weak.upgrade().inspect(|xd| xd.reqnot.receive(msg));
})));
ExtensionData {
systems: (eh.systems.iter().cloned())
.map(|decl| SystemCtor { decl, ext: weak.clone() })
.collect(),
logger,
port: Mutex::new(port),
reqnot: ReqNot::new(
clone!(weak; move |sfn, _| {
let data = weak.upgrade().unwrap();
data.logger.log_buf("Downsending", sfn);
data.port.lock().unwrap().send(sfn);
}),
clone!(weak; move |notif, _| match notif {
api::ExtHostNotif::ExprNotif(api::ExprNotif::Acquire(acq)) => acq_expr(acq.0, acq.1),
api::ExtHostNotif::ExprNotif(api::ExprNotif::Release(rel)) => rel_expr(rel.0, rel.1),
api::ExtHostNotif::ExprNotif(api::ExprNotif::Move(mov)) => {
acq_expr(mov.inc, mov.expr);
rel_expr(mov.dec, mov.expr);
},
api::ExtHostNotif::Log(api::Log(str)) => weak.upgrade().unwrap().logger.log(str),
}),
|hand, req| match req {
api::ExtHostReq::Ping(ping) => hand.handle(&ping, &()),
api::ExtHostReq::IntReq(intreq) => match intreq {
api::IntReq::InternStr(s) => hand.handle(&s, &intern(&**s.0).to_api()),
api::IntReq::InternStrv(v) => hand.handle(&v, &intern(&*v.0).to_api()),
api::IntReq::ExternStr(si) => hand.handle(&si, &Tok::<String>::from_api(si.0).arc()),
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() }
}
@@ -380,7 +364,7 @@ impl fmt::Debug for System {
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))
.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() {
Err(_) => write!(f, "expressions unavailable"),
Ok(r) => {

View File

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

View File

@@ -1,24 +1,20 @@
use std::io::{self, BufRead as _, Write};
use std::path::PathBuf;
use std::sync::Mutex;
use std::sync::mpsc::{SyncSender, sync_channel};
use std::sync::mpsc::sync_channel;
use std::{process, thread};
use async_std::sync::Mutex;
use orchid_api_traits::{Decode, Encode};
use orchid_base::builtin::{ExtInit, ExtPort};
use orchid_base::logging::Logger;
use orchid_base::msg::{recv_msg, send_msg};
use crate::api;
use crate::extension::{ExtensionPort, OnMessage};
pub struct Subprocess {
child: Mutex<process::Child>,
stdin: Mutex<process::ChildStdin>,
set_onmessage: SyncSender<OnMessage>,
header: api::ExtensionHeader,
}
impl Subprocess {
pub fn new(mut cmd: process::Command, logger: Logger) -> io::Result<Self> {
pub struct ExtensionCommand(pub process::Command, pub Logger);
impl ExtFactory for ExtensionCommand {
fn run(self: Box<Self>, onmessage: OnMessage) -> ExtInit {
let Self(mut cmd, logger) = *self;
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 mut child = cmd
@@ -54,19 +50,32 @@ impl Subprocess {
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 {
fn drop(&mut self) { self.child.lock().unwrap().wait().expect("Extension exited with error"); }
}
impl ExtensionPort for Subprocess {
fn set_onmessage(&self, callback: OnMessage) { self.set_onmessage.send(callback).unwrap(); }
fn header(&self) -> &orchid_api::ExtensionHeader { &self.header }
impl ExtPort for Subprocess {
fn send(&self, msg: &[u8]) {
if msg.starts_with(&[0, 0, 0, 0x1c]) {
panic!("Received unnecessary prefix");
}
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 } => {
let extensions = (args.extension.iter())
.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();
let systems = init_systems(&args.system, &extensions).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