From e0d246fe1fa75405305ec4390ba6815049246726 Mon Sep 17 00:00:00 2001 From: Lawrence Bethlenfalvy Date: Sun, 12 Jan 2025 02:02:01 +0100 Subject: [PATCH] Committing for reference --- Cargo.lock | 526 ++++++++++++++++++++++++ SWAP.md | 17 +- orchid-base/Cargo.toml | 1 + orchid-base/src/builtin.rs | 29 ++ orchid-base/src/interner.rs | 1 + orchid-base/src/lib.rs | 1 + orchid-base/src/msg.rs | 20 +- orchid-base/src/reqnot.rs | 109 +++-- orchid-extension/Cargo.toml | 2 + orchid-extension/src/entrypoint.rs | 5 + orchid-extension/src/msg.rs | 9 +- orchid-host/Cargo.toml | 2 + orchid-host/src/extension.rs | 166 ++++---- orchid-host/src/macros.rs | 2 +- orchid-host/src/subprocess.rs | 39 +- orcx/src/main.rs | 2 +- rustc-ice-2025-01-12T01_00_58-10688.txt | 63 +++ 17 files changed, 826 insertions(+), 168 deletions(-) create mode 100644 orchid-base/src/builtin.rs create mode 100644 rustc-ice-2025-01-12T01_00_58-10688.txt diff --git a/Cargo.lock b/Cargo.lock index a641642..db92253 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -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" diff --git a/SWAP.md b/SWAP.md index 91c640f..6574e98 100644 --- a/SWAP.md +++ b/SWAP.md @@ -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 \ No newline at end of file +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` + diff --git a/orchid-base/Cargo.toml b/orchid-base/Cargo.toml index 02a721e..3e21641 100644 --- a/orchid-base/Cargo.toml +++ b/orchid-base/Cargo.toml @@ -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" diff --git a/orchid-base/src/builtin.rs b/orchid-base/src/builtin.rs new file mode 100644 index 0000000..c60dc93 --- /dev/null +++ b/orchid-base/src/builtin.rs @@ -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>>; + fn recv<'a>(&self, cb: Box) -> Pin>>; +} + +pub struct ExtInit { + pub header: api::ExtensionHeader, + pub port: Box, +} +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 } +} diff --git a/orchid-base/src/interner.rs b/orchid-base/src/interner.rs index c95c0cf..78716bd 100644 --- a/orchid-base/src/interner.rs +++ b/orchid-base/src/interner.rs @@ -248,6 +248,7 @@ pub fn interner() -> impl DerefMut { G(g) } +/// Initialize the interner in replica mode. No messages are sent at this point. pub fn init_replica(req: impl DynRequester + 'static) { let mut g = INTERNER.lock().unwrap(); assert!(g.is_none(), "Attempted to initialize replica interner after first use"); diff --git a/orchid-base/src/lib.rs b/orchid-base/src/lib.rs index 9a9237a..4567e4b 100644 --- a/orchid-base/src/lib.rs +++ b/orchid-base/src/lib.rs @@ -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; diff --git a/orchid-base/src/msg.rs b/orchid-base/src/msg.rs index 82e33a8..ea243f9 100644 --- a/orchid-base/src/msg.rs +++ b/orchid-base/src/msg.rs @@ -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> { - let len = u32::decode(read); +pub async fn recv_msg(mut read: Pin<&mut impl Read>) -> io::Result> { + 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) } diff --git a/orchid-base/src/reqnot.rs b/orchid-base/src/reqnot.rs index 2a24173..b19c15f 100644 --- a/orchid-base/src/reqnot.rs +++ b/orchid-base/src/reqnot.rs @@ -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 = for<'a> FnMut(&'a [u8], ReqNot) + DynClone + Send + 'static; + pub trait SendFn = + for<'a> FnMut(&'a [u8], ReqNot) -> Pin + 'a>> + + DynClone + Send + 'static; pub trait ReqFn = - FnMut(RequestHandle, ::Req) -> Receipt + DynClone + Send + Sync + 'static; + for<'a> FnMut(RequestHandle, ::Req) -> Pin>> + + DynClone + Send + Sync + 'static; pub trait NotifFn = - for<'a> FnMut(::Notif, ReqNot) + DynClone + Send + Sync + 'static; + for<'a> FnMut(::Notif, ReqNot) -> Pin>> + + DynClone + Send + Sync + 'static; } fn get_id(message: &[u8]) -> (u64, &[u8]) { @@ -38,35 +40,44 @@ pub trait ReqHandlish { } #[derive(destructure)] -pub struct RequestHandle { +pub struct RequestHandle<'a, MS: MsgSet> { defer_drop: RefCell>>, fulfilled: AtomicBool, id: u64, + _reqlt: PhantomData<&'a mut ()>, parent: ReqNot, } -impl RequestHandle { +impl<'a, MS: MsgSet + 'static> RequestHandle<'a, MS> { fn new(parent: ReqNot, 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 { self.parent.clone() } - pub fn handle(&self, _: &U, rep: &U::Response) -> Receipt { self.respond(rep) } - pub fn will_handle_as(&self, _: &U) -> ReqTypToken { ReqTypToken(PhantomData) } - pub fn handle_as(&self, _: ReqTypToken, rep: &U::Response) -> Receipt { - self.respond(rep) + pub async fn handle(&self, _: &U, rep: &U::Response) -> Receipt<'a> { + self.respond(rep).await } - pub fn respond(&self, response: &impl Encode) -> Receipt { + pub fn will_handle_as(&self, _: &U) -> ReqTypToken { ReqTypToken(PhantomData) } + pub async fn handle_as(&self, _: ReqTypToken, 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 ReqHandlish for RequestHandle { +impl ReqHandlish for RequestHandle<'_, MS> { fn defer_drop(&self, val: impl Any) { self.defer_drop.borrow_mut().push(Box::new(val)) } } -impl Drop for RequestHandle { +impl 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 { send: Box>, notif: Box>, req: Box>, - responses: HashMap>>, + responses: HashMap>>, } /// Wraps a raw message buffer to save on copying. @@ -105,44 +116,43 @@ impl ReqNot { } /// 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(::Notif::decode(&mut &payload[..]), self.clone()) + notif(::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 = ::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::Notif>>(&self, notif: N) { + pub async fn notify::Notif>>(&self, notif: N) { let mut send = clone_box(&*self.0.lock().unwrap().send); let mut buf = vec![0; 8]; let msg: ::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>>; } -pub struct MappedRequester<'a, T>(Box RawReply + Send + Sync + 'a>); +pub struct MappedRequester<'a, T>( + Box Pin>> + Send + Sync + 'a>, +); impl<'a, T> MappedRequester<'a, T> { fn new(req: U) -> Self where T: Into { @@ -152,38 +162,43 @@ impl<'a, T> MappedRequester<'a, T> { impl 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>> { + self.0(data) + } } impl DynRequester for ReqNot { type Transfer = ::Req; - fn raw_request(&self, req: Self::Transfer) -> RawReply { + fn raw_request(&self, req: Self::Transfer) -> Pin>> { 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>(&self, data: R) -> R::Response; + async fn request>(&self, data: R) -> R::Response; fn map<'a, U: Into>(self) -> MappedRequester<'a, U> where Self: Sized + 'a { MappedRequester::new(self) } } impl Requester for This { - fn request>(&self, data: R) -> R::Response { - R::Response::decode(&mut &self.raw_request(data.into())[..]) + async fn request>(&self, data: R) -> R::Response { + R::Response::decode(&mut &self.raw_request(data.into()).await[..]) } } @@ -195,6 +210,7 @@ impl Clone for ReqNot { 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::::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::::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"), ); diff --git a/orchid-extension/Cargo.toml b/orchid-extension/Cargo.toml index d429189..eac1ab2 100644 --- a/orchid-extension/Cargo.toml +++ b/orchid-extension/Cargo.toml @@ -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" diff --git a/orchid-extension/src/entrypoint.rs b/orchid-extension/src/entrypoint.rs index 8a485fa..327bf63 100644 --- a/orchid-extension/src/entrypoint.rs +++ b/orchid-extension/src/entrypoint.rs @@ -81,6 +81,11 @@ pub fn extension_main(data: ExtensionData) { } } +pub struct ExtensionOwner { + rn: ReqNot, + onmessage: Mutex, +} + fn extension_main_logic(data: ExtensionData) { let api::HostHeader { log_strategy } = api::HostHeader::decode(&mut std::io::stdin().lock()); let mut buf = Vec::new(); diff --git a/orchid-extension/src/msg.rs b/orchid-extension/src/msg.rs index 05fa165..07dc633 100644 --- a/orchid-extension/src/msg.rs +++ b/orchid-extension/src/msg.rs @@ -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> { 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> { recv_msg(pin!(io::stdin())).await } diff --git a/orchid-host/Cargo.toml b/orchid-host/Cargo.toml index c41c8be..5365ec7 100644 --- a/orchid-host/Cargo.toml +++ b/orchid-host/Cargo.toml @@ -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" diff --git a/orchid-host/src/extension.rs b/orchid-host/src/extension.rs index 67a8a27..5ac5476 100644 --- a/orchid-host/src/extension.rs +++ b/orchid-host/src/extension.rs @@ -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; - -/// 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, + port: Mutex>, // child: Mutex, // child_stdin: Mutex, reqnot: ReqNot, @@ -153,84 +140,81 @@ fn rel_expr(sys: api::SysId, extk: api::ExprTicket) { #[derive(Clone)] pub struct Extension(Arc); impl Extension { - pub fn new_process(port: Arc, logger: Logger) -> io::Result { - let eh = port.header(); - let ret = Arc::new_cyclic(|weak: &Weak| 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::::from_api(si.0).arc()), - api::IntReq::ExternStrv(vi) => hand.handle( - &vi, - &Arc::new( - Tok::>>::from_api(vi.0).iter().map(|t| t.to_api()).collect_vec(), + pub fn new(fac: Box, logger: Logger) -> io::Result { + Ok(Self(Arc::new_cyclic(|weak: &Weak| { + 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::::from_api(si.0).arc()), + api::IntReq::ExternStrv(vi) => hand.handle( + &vi, + &Arc::new( + Tok::>>::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, + ¯o_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, - ¯o_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 { 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) => { diff --git a/orchid-host/src/macros.rs b/orchid-host/src/macros.rs index d11d6c7..62e37b1 100644 --- a/orchid-host/src/macros.rs +++ b/orchid-host/src/macros.rs @@ -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>; diff --git a/orchid-host/src/subprocess.rs b/orchid-host/src/subprocess.rs index b552937..100bed4 100644 --- a/orchid-host/src/subprocess.rs +++ b/orchid-host/src/subprocess.rs @@ -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, - stdin: Mutex, - set_onmessage: SyncSender, - header: api::ExtensionHeader, -} -impl Subprocess { - pub fn new(mut cmd: process::Command, logger: Logger) -> io::Result { +pub struct ExtensionCommand(pub process::Command, pub Logger); +impl ExtFactory for ExtensionCommand { + fn run(self: Box, 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, + stdin: Mutex, + stdout: Mutex, + header: api::ExtensionHeader, +} +impl Subprocess { + pub fn new(mut cmd: process::Command, logger: Logger) -> io::Result {} +} 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) -> futures::future::BoxFuture<()> { + async { + + } + } } diff --git a/orcx/src/main.rs b/orcx/src/main.rs index 373c9f3..c67964d 100644 --- a/orcx/src/main.rs +++ b/orcx/src/main.rs @@ -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(); diff --git a/rustc-ice-2025-01-12T01_00_58-10688.txt b/rustc-ice-2025-01-12T01_00_58-10688.txt new file mode 100644 index 0000000..963941d --- /dev/null +++ b/rustc-ice-2025-01-12T01_00_58-10688.txt @@ -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 + 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 - + 12: 0x7ff6006c56c5 - + 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 - + 21: 0x7ff6005a065d - + 22: 0x7ff60059c57c - + 23: 0x7ff60058a246 - + 24: 0x7ff60058a70c - + 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 - + 31: 0x7ff6008e3bd0 - + 32: 0x7ff8c09a7374 - BaseThreadInitThunk + 33: 0x7ff8c167cc91 - RtlUserThreadStart + + +rustc version: 1.86.0-nightly (b1a7dfb91 2025-01-10) +platform: x86_64-pc-windows-msvc \ No newline at end of file