diff --git a/Cargo.lock b/Cargo.lock index 153110dac1..fa97839d6c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -44,9 +44,9 @@ dependencies = [ [[package]] name = "adler2" -version = "2.0.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" [[package]] name = "ahash" @@ -89,9 +89,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.18" +version = "0.6.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192" dependencies = [ "anstyle", "anstyle-parse", @@ -110,31 +110,31 @@ checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.2" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.7" +version = "3.0.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" dependencies = [ "anstyle", - "once_cell", - "windows-sys 0.59.0", + "once_cell_polyfill", + "windows-sys 0.60.2", ] [[package]] @@ -199,9 +199,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "base64" @@ -272,9 +272,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" [[package]] name = "byteorder" @@ -296,9 +296,9 @@ checksum = "3a57a50948117a233b27f9bf73ab74709ab90d245216c4707cc16eea067a50bb" [[package]] name = "cc" -version = "1.2.17" +version = "1.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" dependencies = [ "jobserver", "libc", @@ -319,9 +319,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.40" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", @@ -365,15 +365,24 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" +checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" + +[[package]] +name = "cobs" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1" +dependencies = [ + "thiserror", +] [[package]] name = "colorchoice" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" +checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" [[package]] name = "concurrent-queue" @@ -411,11 +420,32 @@ dependencies = [ "libc", ] +[[package]] +name = "cranelift-bitset" +version = "0.121.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebb6f5d0df5bd0d02c63ec48e8f2e38a176b123f59e084f22caf89a0d0593e7e" +dependencies = [ + "serde", + "serde_derive", +] + +[[package]] +name = "cranelift-entity" +version = "0.121.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee832f8329fa87c5df6c1d64a8506a58031e6f8a190d9b21b1900272a4dbb47d" +dependencies = [ + "cranelift-bitset", + "serde", + "serde_derive", +] + [[package]] name = "crc" -version = "3.2.1" +version = "3.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +checksum = "9710d3b3739c2e349eb44fe848ad0b7c8cb1e42bd87ee49371df2f7acaf3e675" dependencies = [ "crc-catalog", ] @@ -428,9 +458,9 @@ checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" [[package]] name = "crc32fast" -version = "1.4.2" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ "cfg-if", ] @@ -459,9 +489,18 @@ dependencies = [ [[package]] name = "defmt" -version = "0.3.10" +version = "0.3.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0963443817029b2024136fc4dd07a5107eb8f977eaf18fcd1fdeb11306b64ad" +dependencies = [ + "defmt 1.0.1", +] + +[[package]] +name = "defmt" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f6162c53f659f65d00619fe31f14556a6e9f8752ccc4a41bd177ffcf3d6130" +checksum = "548d977b6da32fa1d1fda2876453da1e7df63ad0304c8b3dae4dbe7b96f39b78" dependencies = [ "bitflags 1.3.2", "defmt-macros", @@ -469,9 +508,9 @@ dependencies = [ [[package]] name = "defmt-macros" -version = "0.4.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d135dd939bad62d7490b0002602d35b358dce5fd9233a709d3c1ef467d4bde6" +checksum = "3d4fc12a85bcf441cfe44344c4b72d58493178ce635338a3f3b78943aceb258e" dependencies = [ "defmt-parser", "proc-macro-error2", @@ -482,18 +521,18 @@ dependencies = [ [[package]] name = "defmt-parser" -version = "0.4.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3983b127f13995e68c1e29071e5d115cd96f215ccb5e6812e3728cd6f92653b3" +checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ "thiserror", ] [[package]] name = "deranged" -version = "0.4.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ "powerfmt", ] @@ -525,6 +564,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "361a90feb7004eca4019fb28352a9465666b24f840f5c3cddf0ff13920590b89" +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + [[package]] name = "embedded-io" version = "0.6.1" @@ -554,21 +599,27 @@ dependencies = [ "syn", ] +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + [[package]] name = "errno" -version = "0.3.10" +version = "0.3.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "event-listener" -version = "5.4.0" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" dependencies = [ "concurrent-queue", "pin-project-lite", @@ -576,9 +627,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -604,21 +655,21 @@ checksum = "784a4df722dc6267a04af36895398f59d21d07dce47232adf31ec0ff2fa45e67" [[package]] name = "filetime" -version = "0.2.25" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +checksum = "bc0505cd1b6fa6580283f6bdf70a73fcf4aba1184038c90902b92b3dd0df63ed" dependencies = [ "cfg-if", "libc", "libredox", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", "miniz_oxide", @@ -639,11 +690,17 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" dependencies = [ "percent-encoding", ] @@ -682,9 +739,9 @@ checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.6.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" dependencies = [ "fastrand", "futures-core", @@ -714,13 +771,13 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi 0.11.1+wasi-snapshot-preview1", ] [[package]] @@ -732,9 +789,15 @@ dependencies = [ "cfg-if", "libc", "r-efi", - "wasi 0.14.2+wasi-0.2.4", + "wasi 0.14.3+wasi-0.2.4", ] +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + [[package]] name = "git2" version = "0.20.2" @@ -773,6 +836,10 @@ name = "hashbrown" version = "0.15.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", + "serde", +] [[package]] name = "heapless" @@ -830,7 +897,7 @@ dependencies = [ "built", "cfg-if", "crossbeam-utils", - "embedded-io", + "embedded-io 0.6.1", "enum_dispatch", "fdt", "float-cmp", @@ -868,6 +935,8 @@ dependencies = [ "uhyve-interface", "virtio-spec", "volatile 0.6.1", + "wasi 0.11.1+wasi-snapshot-preview1", + "wasmtime", "x86_64", "zerocopy", ] @@ -924,9 +993,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "iana-time-zone" -version = "0.1.62" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -934,7 +1003,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.52.0", + "windows-core", ] [[package]] @@ -1034,9 +1103,9 @@ dependencies = [ [[package]] name = "idna" -version = "1.0.3" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" dependencies = [ "idna_adapter", "smallvec", @@ -1053,6 +1122,17 @@ dependencies = [ "icu_properties", ] +[[package]] +name = "indexmap" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2481980430f9f78649238835720ddccc57e52df14ffce1c6f37391d61b563e9" +dependencies = [ + "equivalent", + "hashbrown", + "serde", +] + [[package]] name = "interrupt-mutex" version = "0.1.0" @@ -1087,9 +1167,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jobserver" -version = "0.1.33" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38f262f097c174adebe41eb73d66ae9c06b2844fb0da69969647bbddd9b0538a" +checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33" dependencies = [ "getrandom 0.3.3", "libc", @@ -1107,9 +1187,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.174" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libgit2-sys" @@ -1123,11 +1203,17 @@ dependencies = [ "pkg-config", ] +[[package]] +name = "libm" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" + [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "391290121bad3d37fbddad76d8f5d1c1c314cfc646d143d7e07a3086ddff0ce3" dependencies = [ "bitflags 2.9.3", "libc", @@ -1148,9 +1234,15 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" @@ -1190,6 +1282,15 @@ dependencies = [ "crc", ] +[[package]] +name = "mach2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640282b302c0bb0a2a8e0233ead9035e3bed871f0b7e81fe4a1ec829765db44" +dependencies = [ + "libc", +] + [[package]] name = "managed" version = "0.8.0" @@ -1198,9 +1299,18 @@ checksum = "0ca88d725a0a943b096803bd34e73a4437208b6077654cc4ecb2947a5f91618d" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0" + +[[package]] +name = "memfd" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix 0.38.44", +] [[package]] name = "memory_addresses" @@ -1221,9 +1331,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" dependencies = [ "adler2", ] @@ -1314,11 +1424,26 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" -version = "1.21.1" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "once_cell_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" [[package]] name = "one-shot-mutex" @@ -1379,9 +1504,9 @@ dependencies = [ [[package]] name = "percent-encoding" -version = "2.3.1" +version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "phf" @@ -1439,11 +1564,23 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" +[[package]] +name = "postcard" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "serde", +] + [[package]] name = "potential_utf" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" dependencies = [ "zerovec", ] @@ -1494,6 +1631,38 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "psm" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e944464ec8536cd1beb0bbfd96987eb5e3b72f2ecdafdc5c769a37f1fa2ae1f" +dependencies = [ + "cc", +] + +[[package]] +name = "pulley-interpreter" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be14280b69a9cbb6ada02a7aa5f7b3f1b72d1043b5bc9336990b700525dea6e3" +dependencies = [ + "cranelift-bitset", + "log", + "pulley-macros", + "wasmtime-math", +] + +[[package]] +name = "pulley-macros" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "076f1be746801280af4c96c4407b5fd1d09cfa53ab27ba0ac7dd8f207e7bbf83" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "quote" version = "1.0.40" @@ -1560,9 +1729,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "5407465600fb0548f1442edf71dd20683c6ed326200ace4b1ef0763521bb3b77" dependencies = [ "bitflags 2.9.3", ] @@ -1575,7 +1744,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom 0.2.16", "libc", "untrusted", "windows-sys 0.52.0", @@ -1613,22 +1782,35 @@ checksum = "8188909339ccc0c68cfb5a04648313f09621e8b87dc03095454f1a11f6c5d436" [[package]] name = "rustix" -version = "1.0.3" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ "bitflags 2.9.3", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", "windows-sys 0.59.0", ] +[[package]] +name = "rustix" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +dependencies = [ + "bitflags 2.9.3", + "errno", + "libc", + "linux-raw-sys 0.9.4", + "windows-sys 0.60.2", +] + [[package]] name = "rustls" -version = "0.23.25" +version = "0.23.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" +checksum = "c0ebcbd2f03de0fc1122ad9bb24b127a5a6cd51d72604a3f3c50ac459762b6cc" dependencies = [ "log", "once_cell", @@ -1650,15 +1832,18 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] [[package]] name = "rustls-webpki" -version = "0.103.0" +version = "0.103.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" +checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" dependencies = [ "ring", "rustls-pki-types", @@ -1667,9 +1852,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "safe-mmio" @@ -1749,9 +1934,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -1793,6 +1978,9 @@ name = "smallvec" version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" +dependencies = [ + "serde", +] [[package]] name = "smoltcp" @@ -1803,7 +1991,7 @@ dependencies = [ "bitflags 1.3.2", "byteorder", "cfg-if", - "defmt", + "defmt 0.3.100", "heapless 0.8.0", "log", "managed", @@ -1901,6 +2089,12 @@ dependencies = [ "xattr", ] +[[package]] +name = "target-lexicon" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e502f78cdbb8ba4718f566c418c52bc729126ffd16baee5baa718cf25dd5a69a" + [[package]] name = "thiserror" version = "2.0.16" @@ -2037,9 +2231,9 @@ dependencies = [ [[package]] name = "ureq-proto" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5b6cabebbecc4c45189ab06b52f956206cea7d8c8a20851c35a85cb169224cc" +checksum = "bbe120bb823a0061680e66e9075942fcdba06d46551548c2c259766b9558bc9a" dependencies = [ "base64", "http", @@ -2049,13 +2243,14 @@ dependencies = [ [[package]] name = "url" -version = "2.5.4" +version = "2.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] @@ -2090,9 +2285,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "virtio-spec" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d48795f97c4b2b552fa2bd4d9549831ce622579088e1f1e7d3ba57eee74f21f" +checksum = "98a3331a2a575016037262a2744834e996a21a360d536f5c75d91e6e18f3ce58" dependencies = [ "allocator-api2", "bitfield-struct", @@ -2140,17 +2335,17 @@ dependencies = [ [[package]] name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +version = "0.11.1+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasi" -version = "0.14.2+wasi-0.2.4" +version = "0.14.3+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +checksum = "6a51ae83037bdd272a9e28ce236db8c07016dd0d50c27038b3f407533c030c95" dependencies = [ - "wit-bindgen-rt", + "wit-bindgen", ] [[package]] @@ -2211,6 +2406,122 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasmparser" +version = "0.233.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b51cb03afce7964bbfce46602d6cb358726f36430b6ba084ac6020d8ce5bc102" +dependencies = [ + "bitflags 2.9.3", + "hashbrown", + "indexmap", + "serde", +] + +[[package]] +name = "wasmtime" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec10e50038f22ab407fdd8708120b8feed3450a02618efcf26ca47e82122927d" +dependencies = [ + "anyhow", + "bitflags 2.9.3", + "bumpalo", + "cc", + "cfg-if", + "hashbrown", + "indexmap", + "libc", + "log", + "mach2", + "memfd", + "object", + "postcard", + "psm", + "pulley-interpreter", + "rustix 1.0.8", + "serde", + "serde_derive", + "smallvec", + "target-lexicon", + "wasmparser", + "wasmtime-asm-macros", + "wasmtime-environ", + "wasmtime-jit-icache-coherence", + "wasmtime-math", + "wasmtime-slab", + "wasmtime-versioned-export-macros", + "windows-sys 0.59.0", +] + +[[package]] +name = "wasmtime-asm-macros" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d379cda46d6fd18619e282a75fbb09b70b3d0f166b605f45b4059dfaf9dc6ce" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "wasmtime-environ" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317081a0cbbb1f749d348b262575608fc082d47ab11b6247bbe9163eeb955777" +dependencies = [ + "anyhow", + "cranelift-bitset", + "cranelift-entity", + "gimli", + "indexmap", + "log", + "object", + "postcard", + "serde", + "serde_derive", + "smallvec", + "target-lexicon", + "wasmparser", +] + +[[package]] +name = "wasmtime-jit-icache-coherence" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea6b740d1a35f2cebfe88e013ac8a4a84ff8dabc3a392df920abf554e871cf2" +dependencies = [ + "anyhow", + "cfg-if", + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "wasmtime-math" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62fa317691aedc64aae3a86b3d786e4b2b0007bc0b56e0b6098b8b5a85ab2134" +dependencies = [ + "libm", +] + +[[package]] +name = "wasmtime-slab" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a06819d24370273021054b50589e3078e7f5cfac15515e58b3fbbebf5e5b39" + +[[package]] +name = "wasmtime-versioned-export-macros" +version = "34.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca100ed168ffc9b37aefc07a5be440645eab612a2ff6e2ff884e8cc3740e666" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "webpki-roots" version = "1.0.2" @@ -2244,12 +2555,12 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows" -version = "0.61.1" +version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ "windows-collections", - "windows-core 0.61.0", + "windows-core", "windows-future", "windows-link", "windows-numerics", @@ -2261,23 +2572,14 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" dependencies = [ - "windows-core 0.61.0", + "windows-core", ] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.61.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" -dependencies = [ - "windows-targets", -] - -[[package]] -name = "windows-core" -version = "0.61.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4763c1de310c86d75a878046489e2e5ba02c649d185f21c67d4cf8a56d098980" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" dependencies = [ "windows-implement", "windows-interface", @@ -2288,12 +2590,13 @@ dependencies = [ [[package]] name = "windows-future" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1d6bbefcb7b60acd19828e1bc965da6fcf18a7e39490c5f8be71e54a19ba32" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ - "windows-core 0.61.0", + "windows-core", "windows-link", + "windows-threading", ] [[package]] @@ -2320,9 +2623,9 @@ dependencies = [ [[package]] name = "windows-link" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" [[package]] name = "windows-numerics" @@ -2330,24 +2633,24 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-core 0.61.0", + "windows-core", "windows-link", ] [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] [[package]] name = "windows-strings" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a2ba9642430ee452d5a7aa78d72907ebe8cfda358e8cb7918a2050581322f97" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -2358,7 +2661,7 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", ] [[package]] @@ -2367,7 +2670,16 @@ version = "0.59.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" dependencies = [ - "windows-targets", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", ] [[package]] @@ -2376,14 +2688,40 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", ] [[package]] @@ -2392,42 +2730,84 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -2435,13 +2815,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "windows_x86_64_msvc" +version = "0.53.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" -dependencies = [ - "bitflags 2.9.3", -] +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "wit-bindgen" +version = "0.45.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052283831dbae3d879dc7f51f3d92703a316ca49f91540417d38591826127814" [[package]] name = "writeable" @@ -2463,7 +2846,7 @@ dependencies = [ [[package]] name = "x86_64" version = "0.15.2" -source = "git+https://github.com/rust-osdev/x86_64.git#72954bba37d591341ee5a982df4e06f23ec9b738" +source = "git+https://github.com/rust-osdev/x86_64.git#fd55fa6d508ab0cd0fb269baab98219b80ffdbae" dependencies = [ "bit_field", "bitflags 2.9.3", @@ -2474,12 +2857,12 @@ dependencies = [ [[package]] name = "xattr" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d65cbf2f12c15564212d48f4e3dfb87923d25d611f2aed18f4cb23f0413d89e" +checksum = "af3a19837351dc82ba89f8a125e22a3c475f05aba604acc023d62b2739ae2909" dependencies = [ "libc", - "rustix", + "rustix 1.0.8", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 0a821ace3d..fbf0d395fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,6 +76,7 @@ vga = [] virtio = ["dep:virtio"] virtio-net = ["virtio"] vsock = ["virtio", "pci"] +wasm = ["wasmtime", "wasi", "mmap"] [lints.rust] rust_2018_idioms = "warn" @@ -144,6 +145,8 @@ time = { version = "0.3", default-features = false } volatile = "0.6" zerocopy = { version = "0.8", default-features = false } uhyve-interface = "0.1.3" +wasmtime = { version = "34.0.2", default-features = false, features = ["runtime", "custom-virtual-memory"], optional = true } +wasi = { version = "0.11", default-features = false, optional = true } [dependencies.smoltcp] version = "0.12" diff --git a/src/arch/aarch64/kernel/longjmp.s b/src/arch/aarch64/kernel/longjmp.s new file mode 100644 index 0000000000..f930d09382 --- /dev/null +++ b/src/arch/aarch64/kernel/longjmp.s @@ -0,0 +1,18 @@ +# The code is derived from the musl implementation +# of longjmp. +.section .text +.global longjmp +longjmp: + # IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers + ldp x19, x20, [x0,#0] + ldp x21, x22, [x0,#16] + ldp x23, x24, [x0,#32] + ldp x25, x26, [x0,#48] + ldp x27, x28, [x0,#64] + ldp x29, x30, [x0,#80] + ldr x2, [x0,#104] + mov sp, x2 + + cmp w1, 0 + csinc w0, w1, wzr, ne + br x30 \ No newline at end of file diff --git a/src/arch/aarch64/kernel/mod.rs b/src/arch/aarch64/kernel/mod.rs index 2f30e67d3f..49b8d0b9ec 100644 --- a/src/arch/aarch64/kernel/mod.rs +++ b/src/arch/aarch64/kernel/mod.rs @@ -31,6 +31,9 @@ use crate::arch::aarch64::mm::paging::{BasePageSize, PageSize}; use crate::config::*; use crate::env; +global_asm!(include_str!("setjmp.s")); +global_asm!(include_str!("longjmp.s")); + #[repr(align(8))] pub(crate) struct AlignedAtomicU32(AtomicU32); diff --git a/src/arch/aarch64/kernel/setjmp.s b/src/arch/aarch64/kernel/setjmp.s new file mode 100644 index 0000000000..5c3f751ad7 --- /dev/null +++ b/src/arch/aarch64/kernel/setjmp.s @@ -0,0 +1,16 @@ +# The code is derived from the musl implementation +# of setjmp. +.section .text +.global setjmp +setjmp: + # IHI0055B_aapcs64.pdf 5.1.1, 5.1.2 callee saved registers + stp x19, x20, [x0,#0] + stp x21, x22, [x0,#16] + stp x23, x24, [x0,#32] + stp x25, x26, [x0,#48] + stp x27, x28, [x0,#64] + stp x29, x30, [x0,#80] + mov x2, sp + str x2, [x0,#104] + mov x0, #0 + ret diff --git a/src/arch/riscv64/kernel/longjmp.s b/src/arch/riscv64/kernel/longjmp.s new file mode 100644 index 0000000000..3d04fd8054 --- /dev/null +++ b/src/arch/riscv64/kernel/longjmp.s @@ -0,0 +1,23 @@ +# The code is derived from the musl implementation +# of longjmp. +.section .text +.global longjmp +longjmp: + ld s0, 0(a0) + ld s1, 8(a0) + ld s2, 16(a0) + ld s3, 24(a0) + ld s4, 32(a0) + ld s5, 40(a0) + ld s6, 48(a0) + ld s7, 56(a0) + ld s8, 64(a0) + ld s9, 72(a0) + ld s10, 80(a0) + ld s11, 88(a0) + ld sp, 96(a0) + ld ra, 104(a0) + + seqz a0, a1 + add a0, a0, a1 + ret \ No newline at end of file diff --git a/src/arch/riscv64/kernel/mod.rs b/src/arch/riscv64/kernel/mod.rs index c415467589..b5d959d839 100644 --- a/src/arch/riscv64/kernel/mod.rs +++ b/src/arch/riscv64/kernel/mod.rs @@ -19,6 +19,7 @@ mod start; pub mod switch; pub mod systemtime; use alloc::vec::Vec; +use core::arch::global_asm; use core::ptr; use core::sync::atomic::{AtomicPtr, AtomicU32, AtomicU64, Ordering}; @@ -35,6 +36,9 @@ use crate::env; use crate::init_cell::InitCell; use crate::mm::physicalmem::PHYSICAL_FREE_LIST; +global_asm!(include_str!("setjmp.s")); +global_asm!(include_str!("longjmp.s")); + // Used to store information about available harts. The index of the hart in the vector // represents its CpuId and does not need to match its hart_id pub(crate) static HARTS_AVAILABLE: InitCell> = InitCell::new(Vec::new()); diff --git a/src/arch/riscv64/kernel/setjmp.s b/src/arch/riscv64/kernel/setjmp.s new file mode 100644 index 0000000000..393bbeb622 --- /dev/null +++ b/src/arch/riscv64/kernel/setjmp.s @@ -0,0 +1,22 @@ +# The code is derived from the musl implementation +# of setjmp. +.section .text +.global setjmp +setjmp: + sd s0, 0(a0) + sd s1, 8(a0) + sd s2, 16(a0) + sd s3, 24(a0) + sd s4, 32(a0) + sd s5, 40(a0) + sd s6, 48(a0) + sd s7, 56(a0) + sd s8, 64(a0) + sd s9, 72(a0) + sd s10, 80(a0) + sd s11, 88(a0) + sd sp, 96(a0) + sd ra, 104(a0) + + li a0, 0 + ret diff --git a/src/arch/x86_64/kernel/longjmp.s b/src/arch/x86_64/kernel/longjmp.s new file mode 100644 index 0000000000..fd0bdfd9c3 --- /dev/null +++ b/src/arch/x86_64/kernel/longjmp.s @@ -0,0 +1,19 @@ +# The code is derived from the musl implementation +# of longjmp. +# +# Copyright 2011-2012 Nicholas J. Kain, +# licensed under standard MIT license +.section .text +.global longjmp +longjmp: + xor eax,eax + cmp esi, 1 /* CF = val ? 0 : 1 */ + adc eax, esi /* eax = val + !val */ + mov rbx, [rdi] + mov rbp, [rdi+8] + mov r12, [rdi+16] + mov r13, [rdi+24] + mov r14, [rdi+32] + mov r15, [rdi+40] + mov rsp, [rdi+48] + jmp [rdi+56] \ No newline at end of file diff --git a/src/arch/x86_64/kernel/mod.rs b/src/arch/x86_64/kernel/mod.rs index 7921abe5d2..e25d9f3821 100644 --- a/src/arch/x86_64/kernel/mod.rs +++ b/src/arch/x86_64/kernel/mod.rs @@ -1,5 +1,6 @@ #[cfg(feature = "common-os")] use core::arch::asm; +use core::arch::global_asm; use core::ptr; use core::sync::atomic::{AtomicPtr, AtomicU32, Ordering}; @@ -42,6 +43,9 @@ pub(crate) mod systemtime; #[cfg(feature = "vga")] pub mod vga; +global_asm!(include_str!("setjmp.s")); +global_asm!(include_str!("longjmp.s")); + pub fn get_ram_address() -> PhysAddr { PhysAddr::new(env::boot_info().hardware_info.phys_addr_range.start) } diff --git a/src/arch/x86_64/kernel/setjmp.s b/src/arch/x86_64/kernel/setjmp.s new file mode 100644 index 0000000000..33fe89bbe1 --- /dev/null +++ b/src/arch/x86_64/kernel/setjmp.s @@ -0,0 +1,20 @@ +# The code is derived from the musl implementation +# of setjmp. +# +# Copyright 2011-2012 Nicholas J. Kain, +# licensed under standard MIT license +.section .text +.global setjmp +setjmp: +mov [rdi], rbx +mov [rdi+8], rbp +mov [rdi+16], r12 +mov [rdi+24], r13 +mov [rdi+32], r14 +mov [rdi+40], r15 +lea rdx, [rsp+8] # rsp without current ret addr +mov [rdi+48], rdx +mov rdi, rsp # save return addr ptr for new rip +mov [rdi+56], rdx +xor rax, rax +ret diff --git a/src/arch/x86_64/mm/paging.rs b/src/arch/x86_64/mm/paging.rs index 109770afc4..b9798c4e23 100644 --- a/src/arch/x86_64/mm/paging.rs +++ b/src/arch/x86_64/mm/paging.rs @@ -173,7 +173,7 @@ pub fn map( if let Ok((_frame, flush)) = unmap { unmapped = true; flush.flush(); - debug!("Had to unmap page {page:?} before mapping."); + trace!("Had to unmap page {page:?} before mapping."); } let map = unsafe { mapper.map_to(page, frame, flags, &mut *frame_allocator) }; match map { @@ -267,7 +267,7 @@ where // FIXME: Some sentinel pages around stacks are supposed to be unmapped. // We should handle this case there instead of here. Err(UnmapError::PageNotMapped) => { - debug!("Tried to unmap {page:?}, which was not mapped."); + trace!("Tried to unmap {page:?}, which was not mapped."); } Err(err) => panic!("{err:?}"), } diff --git a/src/drivers/net/virtio/mod.rs b/src/drivers/net/virtio/mod.rs index 86397e8f05..28babb25ac 100644 --- a/src/drivers/net/virtio/mod.rs +++ b/src/drivers/net/virtio/mod.rs @@ -265,6 +265,12 @@ impl smoltcp::phy::TxToken for TxToken<'_> { result }; + #[cfg(feature = "wasm")] + if let Some(ref mut wasm_manager) = crate::wasm::WASM_MANAGER.lock().as_mut() { + crate::wasm::INPUT.lock().push_back(packet.to_vec()); + let _ = wasm_manager.call_func::<(), ()>("pcap_writer", ()); + } + let mut header = Box::new_in(::default(), DeviceAlloc); // If a checksum calculation by the host is necessary, we have to inform the host within the header @@ -361,6 +367,14 @@ impl smoltcp::phy::RxToken for RxToken<'_> { .unwrap(); } + #[cfg(feature = "wasm")] + if let Some(ref mut wasm_manager) = crate::wasm::WASM_MANAGER.lock().as_mut() { + crate::wasm::INPUT + .lock() + .push_back(combined_packets.to_vec()); + let _ = wasm_manager.call_func::<(), ()>("pcap_writer", ()); + } + f(&combined_packets) } } diff --git a/src/executor/mod.rs b/src/executor/mod.rs index 04d4a73b59..65335cfb46 100644 --- a/src/executor/mod.rs +++ b/src/executor/mod.rs @@ -108,12 +108,18 @@ pub(crate) fn run() { /// Spawns a future on the executor. #[cfg_attr( - not(any(feature = "shell", feature = "tcp", feature = "udp", feature = "vsock")), + not(any( + feature = "shell", + feature = "tcp", + feature = "udp", + feature = "vsock", + feature = "wasm" + )), expect(dead_code) )] pub(crate) fn spawn(future: F) where - F: Future + Send + 'static, + F: Future + 'static + core::marker::Send, { core_local::ex().spawn(AsyncTask::new(future)).detach(); } @@ -169,19 +175,18 @@ where { if let Some(mut guard) = crate::executor::network::NIC.try_lock() { let delay = if let Ok(nic) = guard.as_nic_mut() { + nic.set_polling_mode(false); + nic.poll_delay(Instant::from_micros_const(now.try_into().unwrap())) .map(|d| d.total_micros()) } else { None }; + core_local::core_scheduler().add_network_timer( delay.map(|d| crate::arch::processor::get_timer_ticks() + d), ); } - - if let Ok(device) = crate::executor::network::NIC.lock().as_nic_mut() { - device.set_polling_mode(false); - } } return t; diff --git a/src/lib.rs b/src/lib.rs index 326d7db3ba..dbfb2e31cc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,6 +82,8 @@ mod shell; mod synch; pub mod syscalls; pub mod time; +#[cfg(feature = "wasm")] +pub mod wasm; mod built_info { include!(concat!(env!("OUT_DIR"), "/built.rs")); diff --git a/src/wasm/capi.rs b/src/wasm/capi.rs new file mode 100644 index 0000000000..20fac44d7e --- /dev/null +++ b/src/wasm/capi.rs @@ -0,0 +1,354 @@ +use align_address::Align; +use free_list::{PageLayout, PageRange}; +use hermit_sync::InterruptTicketMutex; +use memory_addresses::{PhysAddr, VirtAddr}; + +use crate::arch; +#[cfg(target_arch = "x86_64")] +use crate::arch::mm::paging::PageTableEntryFlagsExt; +use crate::arch::mm::paging::{BasePageSize, PageSize, PageTableEntryFlags}; + +bitflags! { + /// Flags to either `wasmtime_mmap_{new,remap}` or `wasmtime_mprotect`. + #[repr(C)] + #[derive(Debug, Copy, Clone, Default)] + pub struct WasmProt: u32 { + /// Indicates that the memory region should be readable. + const Read = 1 << 0; + /// Indicates that the memory region should be writable. + const Write = 1 << 1; + /// Indicates that the memory region should be executable. + const Exec = 1 << 2; + } +} + +/// Handler function for traps in Wasmtime passed to `wasmtime_init_traps`. +/// +/// This function is invoked whenever a trap is caught by the system. For +/// example this would be invoked during a signal handler on Linux. This +/// function is passed a number of parameters indicating information about the +/// trap: +/// +/// * `ip` - the instruction pointer at the time of the trap. +/// * `fp` - the frame pointer register's value at the time of the trap. +/// * `has_faulting_addr` - whether this trap is associated with an access +/// violation (e.g. a segfault) meaning memory was accessed when it shouldn't +/// be. If this is `true` then the next parameter is filled in. +/// * `faulting_addr` - if `has_faulting_addr` is true then this is the address +/// that was attempted to be accessed. Otherwise this value is not used. +/// +/// If this function returns then the trap was not handled by Wasmtime. This +/// means that it's left up to the embedder how to deal with the trap/signal +/// depending on its default behavior. This could mean forwarding to a +/// non-Wasmtime handler, aborting the process, logging then crashing, etc. The +/// meaning of a trap that's not handled by Wasmtime depends on the context in +/// which the trap was generated. +/// +/// When this function does not return it's because `wasmtime_longjmp` is +/// used to handle a Wasm-based trap. +#[allow(non_camel_case_types)] +pub type wasmtime_trap_handler_t = + extern "C" fn(ip: usize, fp: usize, has_faulting_addr: bool, faulting_addr: usize); + +/// Abstract pointer type used in the `wasmtime_memory_image_*` APIs which +/// is defined by the embedder. +#[allow(non_camel_case_types)] +pub enum wasmtime_memory_image {} + +/// We support only single threaded application and use lock to get access to the TLS variable. +static TLS: InterruptTicketMutex = InterruptTicketMutex::new(0); + +/// Wasmtime requires a single pointer's space of TLS to be used at runtime, +/// and this function returns the current value of the TLS variable. +/// +/// This value should default to `NULL`. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_tls_get() -> *mut u8 { + *TLS.lock() as *mut u8 +} + +// Sets the current TLS value for Wasmtime to the provided value. +/// +/// This value should be returned when later calling `wasmtime_tls_get`. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_tls_set(ptr: *mut u8) { + *TLS.lock() = ptr as usize; +} + +/// Returns the page size, in bytes, of the current system. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_page_size() -> usize { + BasePageSize::SIZE as usize +} + +/// Creates a new virtual memory mapping of the `size` specified with +/// protection bits specified in `prot_flags`. +/// +/// Memory can be lazily committed. +/// +/// Stores the base pointer of the new mapping in `ret` on success. +/// +/// Returns 0 on success and an error code on failure. +/// +/// Similar to `mmap(0, size, prot_flags, MAP_PRIVATE, 0, -1)` on Linux. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_mmap_new(size: usize, prot_flags: WasmProt, ret: &mut *mut u8) -> i32 { + let size = size.align_up(BasePageSize::SIZE as usize); + let layout = PageLayout::from_size(size).unwrap(); + let page_range = crate::mm::virtualmem::KERNEL_FREE_LIST + .lock() + .allocate(layout) + .unwrap(); + let virtual_address = VirtAddr::from(page_range.start()); + if prot_flags.is_empty() { + *ret = virtual_address.as_mut_ptr(); + return 0; + } + let frame_layout = PageLayout::from_size(size).unwrap(); + let frame_range = crate::mm::physicalmem::PHYSICAL_FREE_LIST + .lock() + .allocate(frame_layout) + .expect("Failed to allocate Physical Memory for wasmtime"); + let physical_address = PhysAddr::from(frame_range.start()); + + let count = size / BasePageSize::SIZE as usize; + let mut flags = PageTableEntryFlags::empty(); + flags.normal().writable(); + if prot_flags.contains(WasmProt::Write) { + flags.writable(); + } + if !prot_flags.contains(WasmProt::Exec) { + flags.execute_disable(); + } + + arch::mm::paging::map::(virtual_address, physical_address, count, flags); + + *ret = virtual_address.as_mut_ptr(); + + 0 +} + +/// Remaps the virtual memory starting at `addr` going for `size` bytes to +/// the protections specified with a new blank mapping. +/// +/// This will unmap any prior mappings and decommit them. New mappings for +/// anonymous memory are used to replace these mappings and the new area +/// should have the protection specified by `prot_flags`. +/// +/// Returns 0 on success and an error code on failure. +/// +/// Similar to `mmap(addr, size, prot_flags, MAP_PRIVATE | MAP_FIXED, 0, -1)` on Linux. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_mmap_remap(_addr: *mut u8, _size: usize, _prot_flags: WasmProt) -> i32 { + error!("Currently. HermitOS doesn't support wasmtime_mmap_remap!"); + -1 +} + +/// Unmaps memory at the specified `ptr` for `size` bytes. +/// +/// The memory should be discarded and decommitted and should generate a +/// segfault if accessed after this function call. +/// +/// Returns 0 on success and an error code on failure. +/// +/// Similar to `munmap` on Linux. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_munmap(ptr: *mut u8, size: usize) -> i32 { + let virtual_address = VirtAddr::new(ptr as u64); + let size = size.align_up(BasePageSize::SIZE as usize); + + if let Some(phys_addr) = arch::mm::paging::virtual_to_physical(virtual_address) { + arch::mm::paging::unmap::( + virtual_address, + size / BasePageSize::SIZE as usize, + ); + let range = PageRange::from_start_len(phys_addr.as_usize(), size).unwrap(); + unsafe { + crate::mm::physicalmem::PHYSICAL_FREE_LIST + .lock() + .deallocate(range) + .unwrap(); + } + } + + let range = PageRange::from_start_len(virtual_address.as_usize(), size).unwrap(); + unsafe { + crate::mm::virtualmem::KERNEL_FREE_LIST + .lock() + .deallocate(range) + .unwrap(); + } + + 0 +} + +/// Configures the protections associated with a region of virtual memory +/// starting at `ptr` and going to `size`. +/// +/// Returns 0 on success and an error code on failure. +/// +/// Similar to `mprotect` on Linux. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_mprotect(ptr: *mut u8, size: usize, prot_flags: WasmProt) -> i32 { + let count = size / BasePageSize::SIZE as usize; + let mut flags = PageTableEntryFlags::empty(); + flags.normal().writable(); + if prot_flags.contains(WasmProt::Write) { + flags.writable(); + } + if !prot_flags.contains(WasmProt::Exec) { + flags.execute_disable(); + } + + let virtual_address = VirtAddr::new(ptr as u64); + + if let Some(physical_address) = arch::mm::paging::virtual_to_physical(virtual_address) { + arch::mm::paging::map::(virtual_address, physical_address, count, flags); + 0 + } else { + let frame_layout = PageLayout::from_size(size).unwrap(); + let frame_range = crate::mm::physicalmem::PHYSICAL_FREE_LIST + .lock() + .allocate(frame_layout) + .expect("Failed to allocate Physical Memory for TaskStacks"); + let physical_address = PhysAddr::from(frame_range.start()); + arch::mm::paging::map::(virtual_address, physical_address, count, flags); + 0 + } +} + +unsafe extern "C" { + fn setjmp(buf: *const u8) -> i32; + fn longjmp(jmp_buf: *const u8, val: i32) -> !; +} + +/// Used to setup a frame on the stack to longjmp back to in the future. +/// +/// This function is used for handling traps in WebAssembly and is paried +/// with `wasmtime_longjmp`. +/// +/// * `jmp_buf` - this argument is filled in with a pointer which if used +/// will be passed to `wasmtime_longjmp` later on by the runtime. +/// * `callback` - this callback should be invoked after `jmp_buf` is +/// configured. +/// * `payload` and `callee` - the two arguments to pass to `callback`. +/// +/// Returns 0 if `wasmtime_longjmp` was used to return to this function. +/// Returns 1 if `wasmtime_longjmp` was not called and `callback` returned. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_setjmp( + jmp_buf: *mut *const u8, + callback: extern "C" fn(*mut u8, *mut u8), + payload: *mut u8, + callee: *mut u8, +) -> i32 { + let buf: [u8; 64] = [0; 64]; + + unsafe { + if setjmp(buf.as_ptr()) != 0 { + return 0; + } + + *jmp_buf = buf.as_ptr(); + } + + callback(payload, callee); + + 1 +} + +/// Paired with `wasmtime_setjmp` this is used to jump back to the `setjmp` +/// point. +/// +/// The argument here was originally passed to `wasmtime_setjmp` through its +/// out-param. +/// +/// This function cannot return. +/// +/// This function may be invoked from the `wasmtime_trap_handler_t` +/// configured by `wasmtime_init_traps`. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_longjmp(jmp_buf: *const u8) -> ! { + unsafe { + longjmp(jmp_buf, 1); + } +} + +/// Initializes trap-handling logic for this platform. +/// +/// Wasmtime's implementation of WebAssembly relies on the ability to catch +/// signals/traps/etc. For example divide-by-zero may raise a machine +/// exception. Out-of-bounds memory accesses may also raise a machine +/// exception. This function is used to initialize trap handling. +/// +/// The `handler` provided is a function pointer to invoke whenever a trap +/// is encountered. The `handler` is invoked whenever a trap is caught by +/// the system. +/// +/// Returns 0 on success and an error code on failure. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_init_traps(_handler: wasmtime_trap_handler_t) -> i32 { + 0 +} + +/// Attempts to create a new in-memory image of the `ptr`/`len` combo which +/// can be mapped to virtual addresses in the future. +/// +/// On success the returned `wasmtime_memory_image` pointer is stored into `ret`. +/// This value stored can be `NULL` to indicate that an image cannot be +/// created but no failure occurred. The structure otherwise will later be +/// deallocated with `wasmtime_memory_image_free` and +/// `wasmtime_memory_image_map_at` will be used to map the image into new +/// regions of the address space. +/// +/// The `ptr` and `len` arguments are only valid for this function call, if +/// the image needs to refer to them in the future then it must make a copy. +/// +/// Both `ptr` and `len` are guaranteed to be page-aligned. +/// +/// Returns 0 on success and an error code on failure. Note that storing +/// `NULL` into `ret` is not considered a failure, and failure is used to +/// indicate that something fatal has happened and Wasmtime will propagate +/// the error upwards. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_memory_image_new( + _ptr: *const u8, + _len: usize, + _ret: &mut *mut wasmtime_memory_image, +) -> i32 { + error!("Currently. HermitOS doesn't support wasmtime_memory_image_new!"); + -1 +} + +/// Maps the `image` provided to the virtual address at `addr` and `len`. +/// +/// This semantically should make it such that `addr` and `len` looks the +/// same as the contents of what the memory image was first created with. +/// The mappings of `addr` should be private and changes do not reflect back +/// to `wasmtime_memory_image`. +/// +/// In effect this is to create a copy-on-write mapping at `addr`/`len` +/// pointing back to the memory used by the image originally. +/// +/// Note that the memory region will be unmapped with `wasmtime_munmap` in +/// the future. +/// +/// Aborts the process on failure. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_memory_image_map_at( + _image: *mut wasmtime_memory_image, + _addr: *mut u8, + _len: usize, +) -> i32 { + error!("Currently. HermitOS doesn't support wasmtime_memory_image_map_at!"); + -1 +} + +/// Deallocates the provided `wasmtime_memory_image`. +/// +/// Note that mappings created from this image are not guaranteed to be +/// deallocated and/or unmapped before this is called. +#[unsafe(no_mangle)] +pub extern "C" fn wasmtime_memory_image_free(_image: *mut wasmtime_memory_image) { + error!("Currently. HermitOS doesn't support wasmtime_memory_image_free!"); +} diff --git a/src/wasm/mod.rs b/src/wasm/mod.rs new file mode 100644 index 0000000000..ad56fa89d3 --- /dev/null +++ b/src/wasm/mod.rs @@ -0,0 +1,751 @@ +use alloc::borrow::ToOwned; +use alloc::collections::VecDeque; +use alloc::string::String; +use alloc::vec::Vec; +use core::ffi::CStr; +use core::future; +use core::mem::MaybeUninit; +use core::pin::pin; +use core::task::Poll; + +use hermit_sync::{InterruptTicketMutex, Lazy}; +use wasi::*; +use wasmtime::*; +use zerocopy::IntoBytes; + +use crate::executor::{WakerRegistration, spawn}; +use crate::fd::{self, remove_object}; +use crate::kernel::systemtime::now_micros; + +mod capi; + +#[derive(Debug, Clone, PartialEq)] +enum Descriptor { + None, + Stdin, + Stdout, + Stderr, + Directory(String), + RawFd(fd::FileDescriptor), +} + +impl Descriptor { + #[inline] + pub fn is_none(&self) -> bool { + *self == Self::None + } +} + +bitflags! { + /// Options for opening files + #[derive(Debug, Copy, Clone, Default)] + pub(crate) struct Oflags: i32 { + /// Create file if it does not exist. + const OFLAGS_CREAT = 1 << 0; + /// Fail if not a directory. + const OFLAGS_DIRECTORY = 1 << 1; + /// Fail if file already exists. + const OFLAGS_EXCL = 1 << 2; + /// Truncate file to size 0. + const OFLAGS_TRUNC = 1 << 3; + } +} + +pub(crate) static WASM_MANAGER: InterruptTicketMutex> = + InterruptTicketMutex::new(None); +pub(crate) static INPUT: InterruptTicketMutex>> = + InterruptTicketMutex::new(VecDeque::new()); +static OUTPUT: InterruptTicketMutex = InterruptTicketMutex::new(WasmStdout::new()); +static FD: InterruptTicketMutex> = InterruptTicketMutex::new(Vec::new()); + +struct WasmStdout { + pub data: VecDeque<(Descriptor, Vec)>, + pub waker: WakerRegistration, +} + +impl WasmStdout { + pub const fn new() -> Self { + Self { + data: VecDeque::new(), + waker: WakerRegistration::new(), + } + } + + pub fn write(&mut self, desc: &Descriptor, buf: &[u8]) { + self.data.push_back((desc.clone(), buf.to_vec())); + self.waker.wake(); + } +} + +#[allow(dead_code)] +pub(crate) struct WasmManager { + store: Store, + instance: Instance, +} + +impl WasmManager { + pub fn new(data: &[u8]) -> Self { + static MODULE_AND_ARGS: Lazy> = Lazy::new(|| vec![b"dummy\0"]); + let mut config: Config = Config::new(); + config.memory_init_cow(false); + config.memory_guard_size(8192); + config.wasm_simd(false); + config.wasm_relaxed_simd(false); + + let engine = Engine::new(&config).unwrap(); + let module = unsafe { Module::deserialize(&engine, data).unwrap() }; + let mut linker = Linker::new(&engine); + linker + .func_wrap("env", "now", || { + crate::arch::kernel::systemtime::now_micros() + }) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "path_open", + |mut caller: Caller<'_, _>, + _fd: i32, + _dirflags: i32, + path_ptr: i32, + path_len: i32, + oflags: i32, + _fs_rights_base: Rights, + _fs_rights_inheriting: Rights, + _fdflags: i32, + fd_ptr: i32| { + let oflags = Oflags::from_bits(oflags).unwrap(); + if let Some(Extern::Memory(mem)) = caller.get_export("memory") { + let mut path = vec![0u8; path_len.try_into().unwrap()]; + + let _ = mem.read( + caller.as_context_mut(), + path_ptr.try_into().unwrap(), + path.as_mut_bytes(), + ); + let path = "/".to_owned() + str::from_utf8(&path).unwrap(); + + let mut flags = fd::OpenOption::empty(); + if oflags.contains(Oflags::OFLAGS_CREAT) { + flags |= fd::OpenOption::O_CREAT; + } + if oflags.contains(Oflags::OFLAGS_TRUNC) { + flags |= fd::OpenOption::O_TRUNC; + } + flags |= fd::OpenOption::O_RDWR; + + let mode = fd::AccessPermission::from_bits(0).unwrap(); + let mut c_path = vec![0u8; path.len() + 1]; + c_path[..path.len()].copy_from_slice(path.as_bytes()); + let path = CStr::from_bytes_until_nul(&c_path) + .unwrap() + .to_str() + .unwrap(); + { + let raw_fd = crate::fs::open(path, flags, mode).unwrap(); + let mut guard = FD.lock(); + for (i, entry) in guard.iter_mut().enumerate() { + if entry.is_none() { + *entry = Descriptor::RawFd(raw_fd); + let _ = mem.write( + caller.as_context_mut(), + fd_ptr.try_into().unwrap(), + i.as_bytes(), + ); + + guard.push(Descriptor::RawFd(raw_fd)); + + return i32::from(ERRNO_SUCCESS.raw()); + } + } + + let new_fd: i32 = (guard.len() - 1).try_into().unwrap(); + let _ = mem.write( + caller.as_context_mut(), + fd_ptr.try_into().unwrap(), + new_fd.as_bytes(), + ); + } + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_INVAL.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "fd_read", + |mut caller: Caller<'_, _>, + fd: i32, + iovs_ptr: i32, + iovs_len: i32, + nread_ptr: i32| { + let _fd = if fd <= 2 { + fd + } else { + panic!("fd_read: invalid file descriptor {}", fd); + }; + + if let Some(Extern::Memory(mem)) = caller.get_export("memory") { + let mut iovs = vec![0i32; (2 * iovs_len).try_into().unwrap()]; + let _ = mem.read( + caller.as_context(), + iovs_ptr.try_into().unwrap(), + iovs.as_mut_bytes(), + ); + + let mut nread_bytes: i32 = 0; + let i = 0; + if let Some(data) = INPUT.lock().pop_front() { + let _len = iovs[i + 1]; + + if !data.is_empty() { + let _ = mem.write( + caller.as_context_mut(), + iovs[i].try_into().unwrap(), + &data, + ); + + nread_bytes += data.len() as i32; + } + } + + let _ = mem.write( + caller.as_context_mut(), + nread_ptr.try_into().unwrap(), + nread_bytes.as_bytes(), + ); + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_INVAL.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "fd_write", + |mut caller: Caller<'_, u32>, + fd: i32, + iovs_ptr: i32, + iovs_len: i32, + nwritten_ptr: i32| { + let desc = match fd { + fd::STDIN_FILENO => Descriptor::Stdin, + fd::STDOUT_FILENO => Descriptor::Stdout, + fd::STDERR_FILENO => Descriptor::Stderr, + _ => Descriptor::RawFd(fd), + }; + + if let Some(Extern::Memory(mem)) = caller.get_export("memory") { + let mut iovs = vec![0i32; (2 * iovs_len).try_into().unwrap()]; + let _ = mem.read( + caller.as_context(), + iovs_ptr.try_into().unwrap(), + iovs.as_mut_bytes(), + ); + + let mut nwritten_bytes: i32 = 0; + let mut i = 0; + while i < iovs.len() { + let len = iovs[i + 1]; + + // len = 0 => ignore entry nothing to write + if len == 0 { + i += 2; + continue; + } + + let mut data: Vec> = + Vec::with_capacity(len.try_into().unwrap()); + unsafe { + data.set_len(len as usize); + } + + let _ = mem.read( + caller.as_context(), + iovs[i].try_into().unwrap(), + unsafe { data.assume_init_mut() }, + ); + OUTPUT + .lock() + .write(&desc, unsafe { data.assume_init_mut() }); + nwritten_bytes += len; + + i += 2; + } + + let _ = mem.write( + caller.as_context_mut(), + nwritten_ptr.try_into().unwrap(), + nwritten_bytes.as_bytes(), + ); + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_INVAL.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "environ_get", + |mut _caller: Caller<'_, _>, _env_ptr: i32, _env_buffer_ptr: i32| { + i32::from(ERRNO_SUCCESS.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "environ_sizes_get", + |mut caller: Caller<'_, _>, + number_env_variables_ptr: i32, + env_buffer_size_ptr: i32| { + if let Some(Extern::Memory(mem)) = caller.get_export("memory") { + let env_buffer_size: u32 = 0; + let number_env_variables: u32 = 0; + + let _ = mem.write( + caller.as_context_mut(), + number_env_variables_ptr.try_into().unwrap(), + number_env_variables.as_bytes(), + ); + let _ = mem.write( + caller.as_context_mut(), + env_buffer_size_ptr.try_into().unwrap(), + env_buffer_size.as_bytes(), + ); + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_INVAL.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "args_get", + |mut caller: Caller<'_, _>, argv_ptr: i32, argv_buf_ptr: i32| { + if let Some(Extern::Memory(mem)) = caller.get_export("memory") { + let mut pos: u32 = argv_buf_ptr as u32; + for (i, element) in MODULE_AND_ARGS.iter().enumerate() { + let _ = mem.write( + caller.as_context_mut(), + (argv_ptr + (i * size_of::()) as i32) + .try_into() + .unwrap(), + pos.as_bytes(), + ); + + let _ = mem.write( + caller.as_context_mut(), + pos.try_into().unwrap(), + element, + ); + + pos += element.len() as u32; + } + } + i32::from(ERRNO_SUCCESS.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "args_sizes_get", + move |mut caller: Caller<'_, _>, number_args_ptr: i32, args_size_ptr: i32| { + let nargs: u32 = MODULE_AND_ARGS.len().try_into().unwrap(); + // Currently, we ignore the arguments + if let Some(Extern::Memory(mem)) = caller.get_export("memory") { + let _ = mem.write( + caller.as_context_mut(), + number_args_ptr.try_into().unwrap(), + nargs.as_bytes(), + ); + + let nargs_size: u32 = MODULE_AND_ARGS + .iter() + .fold(0, |acc, arg| acc + arg.len()) + .try_into() + .unwrap(); + let _ = mem.write( + caller.as_context_mut(), + args_size_ptr.try_into().unwrap(), + nargs_size.as_bytes(), + ); + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_INVAL.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "fd_prestat_get", + |mut caller: Caller<'_, _>, fd: i32, prestat_ptr: i32| { + let guard = FD.lock(); + if fd < guard.len().try_into().unwrap() + && let Some(Extern::Memory(mem)) = caller.get_export("memory") + && let Descriptor::Directory(name) = &guard[fd as usize] + { + let stat = Prestat { + tag: PREOPENTYPE_DIR.raw(), + u: PrestatU { + dir: PrestatDir { + pr_name_len: name.len(), + }, + }, + }; + + let _ = mem.write( + caller.as_context_mut(), + prestat_ptr.try_into().unwrap(), + unsafe { + core::slice::from_raw_parts( + (&raw const stat).cast::(), + size_of::(), + ) + }, + ); + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_BADF.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "clock_time_get", + |mut caller: Caller<'_, _>, clock_id: i32, _precision: i64, timestamp_ptr: i32| { + match clock_id { + 0 => { + let usec = crate::arch::kernel::systemtime::now_micros(); + if let Some(Extern::Memory(mem)) = caller.get_export("memory") { + let nanos = usec * 1000; + let _ = mem.write( + caller.as_context_mut(), + timestamp_ptr.try_into().unwrap(), + nanos.as_bytes(), + ); + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_INVAL.raw()) + } + 1 => { + warn!("Unsupported clock_id"); + i32::from(ERRNO_INVAL.raw()) + } + _ => i32::from(ERRNO_INVAL.raw()), + } + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "fd_prestat_dir_name", + |mut caller: Caller<'_, _>, fd: i32, path_ptr: i32, path_len: i32| { + let guard = FD.lock(); + if fd < guard.len().try_into().unwrap() + && let Descriptor::Directory(path) = &guard[fd as usize] + { + if let Some(Extern::Memory(mem)) = caller.get_export( + "memory +", + ) { + if path_len < path.len().try_into().unwrap() { + return i32::from(ERRNO_INVAL.raw()); + } + + let _ = mem.write( + caller.as_context_mut(), + path_ptr.try_into().unwrap(), + path.as_bytes(), + ); + } + + return i32::from(ERRNO_SUCCESS.raw()); + } + + i32::from(ERRNO_BADF.raw()) + }, + ) + .unwrap(); + linker + .func_wrap("wasi_snapshot_preview1", "fd_close", |fd: i32| { + let mut guard = FD.lock(); + if fd < guard.len().try_into().unwrap() + && let Descriptor::RawFd(os_fd) = guard[fd as usize] + { + let _obj = remove_object(os_fd); + guard[fd as usize] = Descriptor::None; + } + + i32::from(ERRNO_SUCCESS.raw()) + }) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "fd_fdstat_get", + |_: i32, _: i32| { + warn!("Unsupported function fd_fdstat_get"); + i32::from(ERRNO_SUCCESS.raw()) + }, + ) + .unwrap(); + linker + .func_wrap( + "wasi_snapshot_preview1", + "fd_seek", + |_: i32, _: i64, _: i32, _: i32| { + warn!("Unsupported function fd_seek"); + i32::from(ERRNO_SUCCESS.raw()) + }, + ) + .unwrap(); + linker + .func_wrap("wasi_snapshot_preview1", "proc_exit", |_: i32| { + error!("Panic in WASM module"); + }) + .unwrap(); + + // All wasm objects operate within the context of a "store". Each + // `Store` has a type parameter to store host-specific data, which in + // this case we're using `4` for. + let mut store = Store::new(&engine, 4); + let instance = linker.instantiate(&mut store, &module).unwrap(); + + Self { store, instance } + } + + #[allow(dead_code)] + pub fn call_func(&mut self, name: &str, arg: P) -> Result + where + P: wasmtime::WasmParams, + R: wasmtime::WasmResults, + { + let func = self + .instance + .get_typed_func::(&mut self.store, name)?; + func.call(&mut self.store, arg) + } +} + +async fn wasm_run() { + future::poll_fn(|cx| { + if let Some(mut guard) = OUTPUT.try_lock() { + if let Some((fd, data)) = guard.data.pop_front() { + let obj = match fd { + Descriptor::Stdout => crate::core_scheduler() + .get_object(fd::STDOUT_FILENO) + .unwrap(), + Descriptor::Stderr => crate::core_scheduler() + .get_object(fd::STDERR_FILENO) + .unwrap(), + Descriptor::RawFd(raw_fd) => { + crate::core_scheduler().get_object(raw_fd).unwrap() + } + _ => panic!("Unsuppted {fd:?}"), + }; + + drop(guard); + while pin!(obj.write(&data)).poll(cx).is_pending() {} + + cx.waker().wake_by_ref(); + Poll::<()>::Pending + } else { + guard.waker.register(cx.waker()); + Poll::<()>::Pending + } + } else { + cx.waker().wake_by_ref(); + Poll::<()>::Pending + } + }) + .await; +} + +#[hermit_macro::system] +#[unsafe(no_mangle)] +pub extern "C" fn sys_load_binary(ptr: *const u8, len: usize) -> i32 { + info!("Loading WebAssembly binary..."); + + let start = now_micros(); + let slice = unsafe { core::slice::from_raw_parts(ptr, len) }; + let wasm_manager = WasmManager::new(slice); + + *WASM_MANAGER.lock() = Some(wasm_manager); + let end = now_micros(); + info!("Time to initiate WASM module {} usec", end - start); + + { + let mut guard = FD.lock(); + guard.push(Descriptor::Stdin); + guard.push(Descriptor::Stdout); + guard.push(Descriptor::Stderr); + guard.push(Descriptor::Directory(String::from("tmp"))); + guard.push(Descriptor::Directory(String::from("root"))); + } + + /*if let Some(ref mut wasm_manager) = crate::wasm::WASM_MANAGER.lock().as_mut() { + let _ = wasm_manager.call_func::<(), ()>("hello_world", ()); + }*/ + + spawn(wasm_run()); + + 0 +} + +#[hermit_macro::system] +#[unsafe(no_mangle)] +pub extern "C" fn sys_unload_binary() -> i32 { + *WASM_MANAGER.lock() = None; + FD.lock().clear(); + + 0 +} + +/*#[hermit_macro::system] +#[unsafe(no_mangle)] +pub extern "C" fn sys_dhrystone() -> i32 { + if let Some(ref mut wasm_manager) = WASM_MANAGER.lock().as_mut() { + // And finally we can call the wasm function + info!("Call function dhrystone"); + wasm_manager.call_func::<(), ()>("_start", ()).unwrap(); + } + + 0 +} + +#[hermit_macro::system] +#[unsafe(no_mangle)] +pub extern "C" fn sys_foo() -> i32 { + use core::hint::black_box; + + if let Some(ref mut wasm_manager) = WASM_MANAGER.lock().as_mut() { + // And finally we can call the wasm function + info!("Call function foo"); + wasm_manager.call_func::<(), ()>("foo", ()).unwrap(); + + const RUNS: u64 = 1_000_000; + let start = now_micros(); + for _ in 0..RUNS { + #[allow(clippy::unit_arg)] + black_box(wasm_manager.call_func::<(), ()>("foo", ()).unwrap()); + } + let end = now_micros(); + info!( + "Average time to call the WASM function foo: {} nsec", + (1000 * (end - start)) / RUNS + ); + + let start = now_micros(); + for _ in 0..RUNS { + #[allow(clippy::unit_arg)] + black_box(native_foo()); + } + let end = now_micros(); + + info!( + "Time to call {} times the function foo: {} nsec", + RUNS, + 1000 * (end - start) + ); + } + + 0 +} + +#[inline(never)] +fn native_fibonacci(n: u64) -> u64 { + match n { + 0 => 0, + 1 => 1, + _ => native_fibonacci(n - 1) + native_fibonacci(n - 2), + } +} + +#[inline(never)] +fn native_foo() {} + +#[inline(never)] +fn measure_fibonacci(n: u64) { + use core::hint::black_box; + const RUNS: u64 = 100; + info!("Measure native_fibonacci({n})"); + + let start = now_micros(); + for _ in 0..RUNS { + black_box(native_fibonacci(black_box(n))); + } + let end = now_micros(); + info!( + "Average time to call native_fibonacci({}): {} usec", + n, + (end - start) / RUNS + ); +} + +#[hermit_macro::system] +#[unsafe(no_mangle)] +pub extern "C" fn sys_fibonacci() -> i32 { + use core::hint::black_box; + + info!("Try to find function fibonacci"); + + measure_fibonacci(30); + + if let Some(ref mut wasm_manager) = WASM_MANAGER.lock().as_mut() { + // And finally we can call the wasm function + info!("Call function fibonacci"); + let result = wasm_manager.call_func::("fibonacci", 30).unwrap(); + info!("fibonacci(30) = {result}"); + assert!( + result == 832_040, + "Error in the calculation of fibonacci(30) " + ); + + const RUNS: u64 = 100; + let n = 30; + let start = now_micros(); + for _ in 0..RUNS { + black_box(wasm_manager.call_func::("fibonacci", n).unwrap()); + } + let end = now_micros(); + info!( + "Average time to call fibonacci({}) in WASM: {} usec", + n, + (end - start) / RUNS + ); + + info!( + "Average time to call measure_fibonacci({}) in WASM: {} usec", + n, + wasm_manager + .call_func::("measure_fibonacci", n) + .unwrap() + ); + } + + 0 +}*/