diff --git a/Cargo.lock b/Cargo.lock index c2aa5b5..4c4eba2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,28 +4,22 @@ version = 4 [[package]] name = "aho-corasick" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" dependencies = [ "memchr", ] [[package]] name = "aligned" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "377e4c0ba83e4431b10df45c1d4666f178ea9c552cac93e60c3a88bf32785923" +checksum = "ee4508988c62edf04abd8d92897fca0c2995d907ce1dfeaf369dac3716a40685" dependencies = [ "as-slice", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -37,9 +31,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "as-slice" @@ -52,9 +46,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 = "bindgen" @@ -62,7 +56,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools", @@ -73,7 +67,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.96", + "syn 2.0.113", ] [[package]] @@ -82,7 +76,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools", @@ -93,7 +87,7 @@ dependencies = [ "regex", "rustc-hash", "shlex", - "syn 2.0.96", + "syn 2.0.113", ] [[package]] @@ -104,15 +98,15 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.8.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "bstr" -version = "1.11.3" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "serde", @@ -128,22 +122,22 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.113", ] [[package]] name = "bumpalo" -version = "3.16.0" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +checksum = "5dd9dc738b7a8311c7ade152424974d8115f2cdad61e8dab8dac9f2362298510" [[package]] name = "camino" -version = "1.1.9" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -171,9 +165,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.49" +version = "1.2.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" dependencies = [ "find-msvc-tools", "shlex", @@ -190,9 +184,9 @@ dependencies = [ [[package]] name = "cfg-if" -version = "1.0.0" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" [[package]] name = "cfg_aliases" @@ -202,14 +196,13 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.39" +version = "0.4.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" dependencies = [ - "android-tzdata", "iana-time-zone", "num-traits", - "windows-targets", + "windows-link", ] [[package]] @@ -225,18 +218,18 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.54" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7caa3f9de89ddbe2c607f4101924c5abec803763ae9534e4f4d7d8f84aa81f0" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" dependencies = [ "cc", ] [[package]] name = "const_format" -version = "0.2.34" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "126f97965c8ad46d6d9163268ff28432e8f6a1196a55578867832e3049df63dd" +checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" dependencies = [ "const_format_proc_macros", ] @@ -294,22 +287,22 @@ dependencies = [ [[package]] name = "either" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "embuild" -version = "0.33.0" +version = "0.33.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28a8cbd9507fabce8f2741b9ca45da9e898cc2b0f1c2e53d21cb2436aeac811d" +checksum = "e188ad2bbe82afa841ea4a29880651e53ab86815db036b2cb9f8de3ac32dad75" dependencies = [ "anyhow", "bindgen 0.71.1", "bitflags 1.3.2", "cmake", "filetime", - "globwalk", + "globwalk 0.8.1", "home", "log", "regex", @@ -332,14 +325,20 @@ dependencies = [ "serde", ] +[[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.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -370,21 +369,21 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[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 = "find-msvc-tools" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" +checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" [[package]] name = "fs_at" @@ -402,26 +401,27 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ "cfg-if", "libc", - "wasi", + "r-efi", + "wasip2", ] [[package]] name = "glob" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" +checksum = "0cc23270f6e1808e30a928bdc84dea0b9b4136a8bc82338574f23baf47bbd280" [[package]] name = "globset" -version = "0.4.15" +version = "0.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15f1ce686646e7f1e19bf7d5533fe443a45dbfb990e00629110797578b42fb19" +checksum = "52dfc19153a48bde0cbd630453615c8151bce3a5adfac7a0aebfbf0a1e1f57e3" dependencies = [ "aho-corasick", "bstr", @@ -441,6 +441,23 @@ dependencies = [ "walkdir", ] +[[package]] +name = "globwalk" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf760ebf69878d9fd8f110c89703d90ce35095324d1f1edcb595c63945ee757" +dependencies = [ + "bitflags 2.10.0", + "ignore", + "walkdir", +] + +[[package]] +name = "hashbrown" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" + [[package]] name = "heck" version = "0.4.1" @@ -449,23 +466,24 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "home" -version = "0.5.11" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +checksum = "cc627f471c528ff0c4a49e1d5e60450c8f6461dd6d10ba9dcd3a61d3dff7728d" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "iana-time-zone" -version = "0.1.61" +version = "0.1.64" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" dependencies = [ "android_system_properties", "core-foundation-sys", "iana-time-zone-haiku", "js-sys", + "log", "wasm-bindgen", "windows-core", ] @@ -481,9 +499,9 @@ dependencies = [ [[package]] name = "ignore" -version = "0.4.23" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b" +checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" dependencies = [ "crossbeam-deque", "globset", @@ -495,6 +513,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "indexmap" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +dependencies = [ + "equivalent", + "hashbrown", +] + [[package]] name = "itertools" version = "0.13.0" @@ -506,43 +534,49 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.14" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "js-sys" -version = "0.3.77" +version = "0.3.83" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" dependencies = [ "once_cell", "wasm-bindgen", ] +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libc" -version = "0.2.169" +version = "0.2.179" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" [[package]] name = "libloading" -version = "0.8.6" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" +checksum = "d7c4b02199fee7c5d21a5ae7d8cfa79a6ef5bb2fc834d6e9058e89c825efdc55" dependencies = [ "cfg-if", - "windows-targets", + "windows-link", ] [[package]] name = "libredox" -version = "0.1.3" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +checksum = "3d0b95e02c851351f877147b7deea7b1afb1df71b63aa5f8270716e0c5720616" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.10.0", "libc", "redox_syscall", ] @@ -553,17 +587,23 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + [[package]] name = "log" -version = "0.4.25" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "memchr" -version = "2.7.4" +version = "2.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273" [[package]] name = "minimal-lexical" @@ -577,7 +617,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -595,11 +635,11 @@ dependencies = [ [[package]] name = "normpath" -version = "1.3.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8911957c4b1549ac0dc74e30db9c8b0e66ddcd6d7acc33098f4c63a64a6d7ed" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -613,52 +653,58 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.2" +version = "1.21.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "prettyplease" -version = "0.2.29" +version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.96", + "syn 2.0.113", ] [[package]] name = "proc-macro2" -version = "1.0.93" +version = "1.0.104" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +checksum = "9695f8df41bb4f3d222c95a67532365f569318332d03d5f3f67f37b20e6ebdf0" dependencies = [ "unicode-ident", ] [[package]] name = "quote" -version = "1.0.38" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + [[package]] name = "redox_syscall" -version = "0.5.8" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03a862b389f93e68874fbf580b9de08dd02facb9a788ebadaf4a3fd33cf58834" +checksum = "49f3fe0889e69e2ae9e41f4d6c4c0181701d00e4697b356fb1f74173a5e0ee27" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.10.0", ] [[package]] name = "regex" -version = "1.11.1" +version = "1.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" dependencies = [ "aho-corasick", "memchr", @@ -668,9 +714,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.9" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" dependencies = [ "aho-corasick", "memchr", @@ -679,9 +725,9 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" [[package]] name = "remove_dir_all" @@ -699,34 +745,41 @@ dependencies = [ [[package]] name = "rustc-hash" -version = "2.1.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustix" -version = "0.38.43" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a78891ee6bf2340288408954ac787aa063d8e8817e9f53abb37c695c6d834ef6" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.8.0", + "bitflags 2.10.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", "windows-sys 0.59.0", ] [[package]] -name = "rustversion" -version = "1.0.19" +name = "rustix" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c45b9784283f1b2e7fb61b42047c2fd678ef0960d4f6f1eba131594cc369d4" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.10.0", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", +] [[package]] -name = "ryu" -version = "1.0.18" +name = "rustversion" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "same-file" @@ -739,43 +792,55 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.24" +version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" +checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" dependencies = [ "serde", + "serde_core", ] [[package]] name = "serde" -version = "1.0.217" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.217" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.113", ] [[package]] name = "serde_json" -version = "1.0.136" +version = "1.0.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "336a0c23cf42a38d9eaa7cd22c7040d04e1228a19a933890805ffd00a16437d2" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -786,9 +851,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "stable_deref_trait" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" +checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596" [[package]] name = "strum" @@ -825,9 +890,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.96" +version = "2.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" +checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" dependencies = [ "proc-macro2", "quote", @@ -836,16 +901,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.15.0" +version = "3.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" dependencies = [ - "cfg-if", "fastrand", "getrandom", "once_cell", - "rustix", - "windows-sys 0.59.0", + "rustix 1.1.3", + "windows-sys 0.61.2", ] [[package]] @@ -865,14 +929,20 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.96", + "syn 2.0.113", ] [[package]] name = "unicode-ident" -version = "1.0.14" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" + +[[package]] +name = "unicode-width" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" [[package]] name = "unicode-xid" @@ -896,6 +966,7 @@ version = "1.0.0" dependencies = [ "esp-idf-sys", "wamr-sys", + "wat", ] [[package]] @@ -905,45 +976,36 @@ dependencies = [ "bindgen 0.72.1", "cc", "cmake", + "globwalk 0.9.1", ] [[package]] -name = "wasi" -version = "0.11.0+wasi-snapshot-preview1" +name = "wasip2" +version = "1.0.1+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] [[package]] name = "wasm-bindgen" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" dependencies = [ "cfg-if", "once_cell", "rustversion", "wasm-bindgen-macro", -] - -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.100" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn 2.0.96", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -951,26 +1013,69 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" dependencies = [ + "bumpalo", "proc-macro2", "quote", - "syn 2.0.96", - "wasm-bindgen-backend", + "syn 2.0.113", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.100" +version = "0.2.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.243.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c55db9c896d70bd9fa535ce83cd4e1f2ec3726b0edd2142079f594fc3be1cb35" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.243.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6d8db401b0528ec316dfbe579e6ab4152d61739cfe076706d2009127970159d" +dependencies = [ + "bitflags 2.10.0", + "indexmap", + "semver", +] + +[[package]] +name = "wast" +version = "243.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df21d01c2d91e46cb7a221d79e58a2d210ea02020d57c092e79255cc2999ca7f" +dependencies = [ + "bumpalo", + "leb128fmt", + "memchr", + "unicode-width", + "wasm-encoder", +] + +[[package]] +name = "wat" +version = "1.243.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "226a9a91cd80a50449312fef0c75c23478fcecfcc4092bdebe1dc8e760ef521b" +dependencies = [ + "wast", +] + [[package]] name = "which" version = "4.4.2" @@ -980,25 +1085,75 @@ dependencies = [ "either", "home", "once_cell", - "rustix", + "rustix 0.38.44", ] [[package]] name = "winapi-util" -version = "0.1.9" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "windows-core" -version = "0.52.0" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link", + "windows-result", + "windows-strings", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.113", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" dependencies = [ - "windows-targets", + "windows-link", ] [[package]] @@ -1007,7 +1162,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]] @@ -1016,7 +1171,25 @@ 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.5", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", ] [[package]] @@ -1025,14 +1198,31 @@ 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.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.1", + "windows_aarch64_msvc 0.53.1", + "windows_i686_gnu 0.53.1", + "windows_i686_gnullvm 0.53.1", + "windows_i686_msvc 0.53.1", + "windows_x86_64_gnu 0.53.1", + "windows_x86_64_gnullvm 0.53.1", + "windows_x86_64_msvc 0.53.1", ] [[package]] @@ -1041,44 +1231,104 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" + [[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" + [[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3" + [[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" + [[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" + [[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" + [[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" + [[package]] name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "zmij" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30e0d8dffbae3d840f64bda38e28391faef673a7b5a6017840f2a106c8145868" diff --git a/Cargo.toml b/Cargo.toml index 6c2aa3b..c6999af 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ exclude = [ resolver = "2" [workspace.package] -edition = "2021" +edition = "2024" license = "Apache-2.0 WITH LLVM-exception" authors = ["The WAMR Project Developers"] @@ -29,7 +29,7 @@ categories = ["api-bindings", "wasm"] keywords = ["api-bindings", "wasm", "webassembly"] [dependencies] -wamr-sys = { path = "crates/wamr-sys", version = "1.0.0" } +wamr-sys = { path = "crates/wamr-sys", version = "1.0.0", default-features = false } [target.'cfg( target_os = "espidf" )'.dependencies] esp-idf-sys = { version = "0.36", optional = true } @@ -39,10 +39,50 @@ bindings_header = "./crates/wamr-sys/wasm-micro-runtime/core/iwasm/include/wasm_ component_dirs = ["./crates/wamr-sys/wasm-micro-runtime/build-scripts/esp-idf"] [features] +default = ["std", "default-set", "libc-wasi"] +default-set = ["wamr-sys/default-set"] +std = ["wamr-sys/std"] +esp-idf = ["esp-idf-sys", "wamr-sys/esp-idf"] + +aot = ["wamr-sys/aot"] +aot-stack-frame = ["wamr-sys/aot-stack-frame"] +bulk-memory = ["wamr-sys/bulk-memory"] +bulk-memory-optional = ["wamr-sys/bulk-memory-optional"] custom-section = ["wamr-sys/custom-section"] +debug-interpreter = ["wamr-sys/debug-interpreter"] dump-call-stack = ["wamr-sys/dump-call-stack"] -esp-idf = ["esp-idf-sys", "wamr-sys/esp-idf"] +fast-interpreter = ["wamr-sys/fast-interpreter"] +fast-jit = ["wamr-sys/fast-jit"] +gc = ["wamr-sys/gc"] hw-bound-check = ["wamr-sys/hw-bound-check"] +interpreter = ["wamr-sys/interpreter"] +legacy-exception-handling = ["wamr-sys/legacy-exception-handling"] +libc-builtin = ["wamr-sys/libc-builtin"] +libc-uvwasi = ["wamr-sys/libc-uvwasi", "std", "wasi"] +libc-wasi = ["wamr-sys/libc-wasi", "std", "wasi"] llvmjit = ["wamr-sys/llvmjit"] +memory-profiling = ["wamr-sys/memory-profiling"] +memory64 = ["wamr-sys/memory64"] +mini-loader = ["wamr-sys/mini-loader"] +multi-memory = ["wamr-sys/multi-memory"] multi-module = ["wamr-sys/multi-module"] name-section = ["wamr-sys/name-section"] +pthread = ["wamr-sys/pthread"] +pthread-semaphore = ["wamr-sys/pthread-semaphore"] +reference-types = ["wamr-sys/reference-types"] +shared-memory = ["wamr-sys/shared-memory"] +shrunk-memory = ["wamr-sys/shrunk-memory"] +simd = ["wamr-sys/simd"] +simde = ["wamr-sys/simde"] +tail-call = ["wamr-sys/tail-call"] +threads-manager = ["wamr-sys/threads-manager"] +wasi-nn = ["wamr-sys/wasi-nn"] +wasi-threads = ["wamr-sys/wasi-threads"] + +# Deprecated aliases for backwards compatibility +fast-interp = ["fast-interpreter"] + +wasi = [] + +[dev-dependencies] +wat = "1.243.0" diff --git a/crates/wamr-sys/Cargo.toml b/crates/wamr-sys/Cargo.toml index c8e96aa..565523b 100644 --- a/crates/wamr-sys/Cargo.toml +++ b/crates/wamr-sys/Cargo.toml @@ -29,13 +29,47 @@ include = [ bindgen = "0.72" cc = "1.2" cmake = "0.1" +globwalk = "0.9.1" [features] -custom-section = [] -dump-call-stack = [] +default = [] +default-set = ["aot", "libc-builtin", "libc-wasi", "simd", "reference-types", "bulk-memory", "interpreter", "fast-interpreter"] esp-idf = [] -hw-bound-check = [] -llvmjit = [] -multi-module = [] -name-section = [ "custom-section" ] std = [] + +aot = [] # WAMR_BUILD_AOT +aot-stack-frame = [] # WAMR_BUILD_AOT_STACK_FRAME +bulk-memory = [] # WAMR_BUILD_BULK_MEMORY +bulk-memory-optional = [] # WAMR_BUILD_BULK_MEMORY_OPT +custom-section = [] # WAMR_BUILD_CUSTOM_NAME_SECTION +debug-interpreter = [] # WAMR_BUILD_DEBUG_INTERP +dump-call-stack = [] # WAMR_BUILD_DUMP_CALL_STACK +fast-interpreter = ["interpreter"] +fast-jit = [] # WAMR_BUILD_FAST_JIT +gc = [] # WAMR_BUILD_GC +hw-bound-check = [] # WAMR_DISABLE_HW_BOUND_CHECK +interpreter = [] +legacy-exception-handling = [] # WAMR_BUILD_EXCE_HANDLING +libc-builtin = [] # WAMR_BUILD_LIBC_BUILTIN +libc-uvwasi = [] # WAMR_BUILD_LIBC_UVWASI +libc-wasi = [] # WAMR_BUILD_LIBC_WASI +llvmjit = [] # WAMR_BUILD_JIT +memory-profiling = [] # WAMR_BUILD_MEMORY_PROFILING +memory64 = [] # WAMR_BUILD_MEMORY64 +mini-loader = [] # WAMR_BUILD_MINI_LOADER +multi-memory = [] # WAMR_BUIL_MULTI_MEMORY +multi-module = [] # WAMR_BUILD_MULTI_MODULE +name-section = ["custom-section"] +pthread = [] # WAMR_BUILD_LIB_PTHREAD +pthread-semaphore = ["pthread"] # WAMR_BUILD_LIB_PTHREAD_SEMAPHORE +reference-types = [] # WAMR_BUILD_REF_TYPES +shared-memory = [] # WAMR_BUILD_SHARED_MEMORY +shrunk-memory = [] # WAMR_BUILD_SHRUNK_MEMORY +simd = [] # WAMR_BUILD_SIMD +simde = ["simd"] # WAMR_BUILD_LIB_SIMDE +tail-call = [] # WAMR_BUILD_TAIL_CALL +threads-manager = [] # WAMR_BUILD_THREAD_MGR +wasi-nn = [] # WAMR_BUILD_WASI_NN +wasi-threads = [] # WAMR_BUILD_LIB_WASI_THREADS + +wamrc = [] \ No newline at end of file diff --git a/crates/wamr-sys/build.rs b/crates/wamr-sys/build.rs index 5874615..9048bec 100644 --- a/crates/wamr-sys/build.rs +++ b/crates/wamr-sys/build.rs @@ -3,9 +3,6 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ -extern crate bindgen; -extern crate cmake; - use cmake::Config; use std::{env, path::Path, path::PathBuf}; @@ -41,51 +38,28 @@ fn check_is_espidf() -> bool { && (env::var("WAMR_BUILD_PLATFORM").is_ok() || env::var("WAMR_SHARED_PLATFORM_CONFIG").is_ok()) { - panic!("ESP-IDF build cannot use custom platform build (WAMR_BUILD_PLATFORM) or shared platform config (WAMR_SHARED_PLATFORM_CONFIG)"); + panic!( + "ESP-IDF build cannot use custom platform build (WAMR_BUILD_PLATFORM) or shared platform config (WAMR_SHARED_PLATFORM_CONFIG)" + ); } is_espidf } -fn get_feature_flags() -> (String, String, String, String, String, String) { - let enable_custom_section = if cfg!(feature = "custom-section") { - "1" - } else { - "0" - }; - let enable_dump_call_stack = if cfg!(feature = "dump-call-stack") { - "1" - } else { - "0" - }; - let enable_llvm_jit = if cfg!(feature = "llvmjit") { "1" } else { "0" }; - let enable_multi_module = if cfg!(feature = "multi-module") { - "1" - } else { - "0" - }; - let enable_name_section = if cfg!(feature = "name-section") { - "1" - } else { - "0" +macro_rules! wamr_build_enable_option { + (not; $feature:expr) => { + if cfg!(not(feature = $feature)) { + "1" + } else { + "0" + } }; - let disable_hw_bound_check = if cfg!(feature = "hw-bound-check") { - "0" - } else { - "1" + ($feature:expr) => { + if cfg!(feature = $feature) { "1" } else { "0" } }; - - ( - enable_custom_section.to_string(), - enable_dump_call_stack.to_string(), - enable_llvm_jit.to_string(), - enable_multi_module.to_string(), - enable_name_section.to_string(), - disable_hw_bound_check.to_string(), - ) } -fn link_llvm_libraries(llvm_cfg_path: &String, enable_llvm_jit: &String) { +fn link_llvm_libraries(llvm_cfg_path: &str, enable_llvm_jit: &str) { if enable_llvm_jit == "0" { return; } @@ -109,34 +83,124 @@ fn link_llvm_libraries(llvm_cfg_path: &String, enable_llvm_jit: &String) { } } -fn setup_config( - wamr_root: &PathBuf, - feature_flags: (String, String, String, String, String, String), -) -> Config { - let ( - enable_custom_section, - enable_dump_call_stack, - enable_llvm_jit, - enable_multi_module, - enable_name_section, - disalbe_hw_bound_check, - ) = feature_flags; - - let mut cfg = Config::new(wamr_root); - cfg.define("WAMR_BUILD_AOT", "1") - .define("WAMR_BUILD_INTERP", "1") - .define("WAMR_BUILD_FAST_INTERP", "1") - .define("WAMR_BUILD_JIT", &enable_llvm_jit) - .define("WAMR_BUILD_BULK_MEMORY", "1") - .define("WAMR_BUILD_REF_TYPES", "1") - .define("WAMR_BUILD_SIMD", "1") - .define("WAMR_BUILD_LIBC_WASI", "1") - .define("WAMR_BUILD_LIBC_BUILTIN", "0") - .define("WAMR_DISABLE_HW_BOUND_CHECK", &disalbe_hw_bound_check) - .define("WAMR_BUILD_MULTI_MODULE", &enable_multi_module) - .define("WAMR_BUILD_DUMP_CALL_STACK", &enable_dump_call_stack) - .define("WAMR_BUILD_CUSTOM_NAME_SECTION", &enable_name_section) - .define("WAMR_BUILD_LOAD_CUSTOM_SECTION", &enable_custom_section); +fn setup_config(cmakelists_dir: &PathBuf) -> Config { + let mut cfg = Config::new(cmakelists_dir); + + for (key, value) in [ + ("WAMR_BUILD_AOT", wamr_build_enable_option!("aot")), + ( + "WAMR_BUILD_AOT_STACK_FRAME", + wamr_build_enable_option!("aot-stack-frame"), + ), + ( + "WAMR_BUILD_INTERP", + wamr_build_enable_option!("interpreter"), + ), + ( + "WAMR_BUILD_FAST_INTERP", + wamr_build_enable_option!("fast-interpreter"), + ), + ( + "WAMR_BUILD_SHARED_MEMORY", + wamr_build_enable_option!("shared-memory"), + ), + ( + "WAMR_BUILD_MINI_LOADER", + wamr_build_enable_option!("mini-loader"), + ), + ("WAMR_BUILD_JIT", wamr_build_enable_option!("llvmjit")), + ("WAMR_BUILD_FAST_JIT", wamr_build_enable_option!("fast-jit")), + ( + "WAMR_BUILD_BULK_MEMORY", + wamr_build_enable_option!("bulk-memory"), + ), + ( + "WAMR_BUILD_REF_TYPES", + wamr_build_enable_option!("reference-types"), + ), + ( + "WAMR_BUILD_LIB_PTHREAD", + wamr_build_enable_option!("pthread"), + ), + ( + "WAMR_BUILD_LIB_PTHREAD_SEMAPHORE", + wamr_build_enable_option!("pthread-semaphore"), + ), + ( + "WAMR_BUILD_LIBC_WASI", + wamr_build_enable_option!("libc-wasi"), + ), + ( + "WAMR_BUILD_LIBC_BUILTIN", + wamr_build_enable_option!("libc-builtin"), + ), + ( + "WAMR_BUILD_LIBC_UVWASI", + wamr_build_enable_option!("libc-uvwasi"), + ), + ( + "WAMR_DISABLE_HW_BOUND_CHECK", + wamr_build_enable_option!(not; "hw-bound-check"), + ), + ( + "WAMR_BUILD_MULTI_MODULE", + wamr_build_enable_option!("multi-module"), + ), + ( + "WAMR_BUILD_DUMP_CALL_STACK", + wamr_build_enable_option!("dump-call-stack"), + ), + ( + "WAMR_BUILD_CUSTOM_NAME_SECTION", + wamr_build_enable_option!("name-section"), + ), + ( + "WAMR_BUILD_LOAD_CUSTOM_SECTION", + wamr_build_enable_option!("custom-section"), + ), + ("WAMR_BUILD_SIMD", wamr_build_enable_option!("simd")), + ("WAMR_BUILD_LIB_SIMDE", wamr_build_enable_option!("simde")), + ("WAMR_BUILD_GC", wamr_build_enable_option!("gc")), + ( + "WAMR_BUILD_EXCE_HANDLING", + wamr_build_enable_option!("legacy-exception-handling"), + ), + ("WAMR_BUILD_MEMORY64", wamr_build_enable_option!("memory64")), + ( + "WAMR_BUILD_MULTI_MEMORY", + wamr_build_enable_option!("multi-memory"), + ), + ( + "WAMR_BUILD_THREAD_MGR", + wamr_build_enable_option!("threads-manager"), + ), + ( + "WAMR_BUILD_LIB_WASI_THREADS", + wamr_build_enable_option!("wasi-threads"), + ), + ( + "WAMR_BUILD_TAIL_CALL", + wamr_build_enable_option!("tail-call"), + ), + ( + "WAMR_BUILD_MEMORY_PROFILING", + wamr_build_enable_option!("memory-profiling"), + ), + ( + "WAMR_BUILD_DEBUG_INTERP", + wamr_build_enable_option!("debug-interpreter"), + ), + ("WAMR_BUILD_WASI_NN", wamr_build_enable_option!("wasi-nn")), + ( + "WAMR_BUILD_SHRUNK_MEMORY", + wamr_build_enable_option!("shrunk-memory"), + ), + ] { + cfg.define(key, value); + } + + cfg.define("WASM_API_EXTERN", ""); + cfg.define("WASM_RUNTIME_API_EXTERN", ""); // always assume non-empty strings for these environment variables @@ -153,7 +217,7 @@ fn setup_config( } if let Ok(llvm_cfg_path) = env::var("LLVM_LIB_CFG_PATH") { - link_llvm_libraries(&llvm_cfg_path, &enable_llvm_jit); + link_llvm_libraries(&llvm_cfg_path, wamr_build_enable_option!("llvmjit")); cfg.define("LLVM_DIR", &llvm_cfg_path); } @@ -169,14 +233,29 @@ fn build_wamr_libraries(wamr_root: &PathBuf) { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let vmbuild_path = out_dir.join("vmbuild"); - let feature_flags = get_feature_flags(); - let mut cfg = setup_config(wamr_root, feature_flags); - let dst = cfg.out_dir(vmbuild_path).build_target("vmlib").build(); + let dst = { + let mut cfg = setup_config(wamr_root); + println!("cargo:rustc-link-lib=static=iwasm"); + cfg.out_dir(vmbuild_path).build_target("vmlib").build() + } + .join("build"); + + let dst = if cfg!(target_os = "windows") { + globwalk::GlobWalkerBuilder::from_patterns(&dst, &["iwasm.lib"]) + .build() + .expect("Failed to build glob walker") + .filter_map(Result::ok) + .next() + .and_then(|entry| entry.path().parent().map(|p| p.to_path_buf())) + .unwrap_or(dst) + } else { + dst + }; - println!("cargo:rustc-link-search=native={}/build", dst.display()); - println!("cargo:rustc-link-lib=static=iwasm"); + println!("cargo:rustc-link-search=native={}", dst.display()); } +#[cfg(feature = "wamrc")] fn build_wamrc(wamr_root: &Path) { let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap()); let wamrc_build_path = out_dir.join("wamrcbuild"); @@ -187,7 +266,11 @@ fn build_wamrc(wamr_root: &Path) { Config::new(&wamr_compiler_path) .out_dir(wamrc_build_path) .define("WAMR_BUILD_WITH_CUSTOM_LLVM", "1") - .define("LLVM_DIR", env::var("LLVM_LIB_CFG_PATH").expect("LLVM_LIB_CFG_PATH isn't specified in config.toml")) + .define( + "LLVM_DIR", + env::var("LLVM_LIB_CFG_PATH") + .expect("LLVM_LIB_CFG_PATH isn't specified in config.toml"), + ) .build(); } @@ -223,8 +306,23 @@ fn main() { if !check_is_espidf() { // because the ESP-IDF build procedure differs from the regular one // (build internally by esp-idf-sys), - build_wamr_libraries(&wamr_root); - build_wamrc(&wamr_root); + + std::thread::scope(|t| { + let lib = t.spawn(|| { + build_wamr_libraries(&wamr_root); + }); + #[cfg(feature = "wamrc")] + { + let wamrc = t.spawn(|| { + build_wamrc(&wamr_root); + }); + } + lib.join().expect("lib thread panicked"); + #[cfg(feature = "wamrc")] + { + wamrc.join().expect("wamrc thread panicked"); + } + }); } generate_bindings(&wamr_root); diff --git a/crates/wamr-sys/wasm-micro-runtime b/crates/wamr-sys/wasm-micro-runtime index 2a30386..2a2dd19 160000 --- a/crates/wamr-sys/wasm-micro-runtime +++ b/crates/wamr-sys/wasm-micro-runtime @@ -1 +1 @@ -Subproject commit 2a303861cc916dc182b7fecaa0aacc1b797e7ac6 +Subproject commit 2a2dd19f32ab5476ac707f20e3f419af34290294 diff --git a/src/function.rs b/src/function.rs index 7daf269..3a433ff 100644 --- a/src/function.rs +++ b/src/function.rs @@ -6,19 +6,22 @@ //! an exported wasm function. //! get one via `Function::find_export_func()` -use std::{ffi::CString, marker::PhantomData}; +use alloc::{ffi::CString, string::String, vec, vec::Vec}; +use core::{ffi::c_void, marker::PhantomData}; + use wamr_sys::{ wasm_exec_env_t, wasm_func_get_param_count, wasm_func_get_result_count, wasm_func_get_result_types, wasm_function_inst_t, wasm_runtime_call_wasm, - wasm_runtime_get_exception, wasm_runtime_get_exec_env_singleton, - wasm_runtime_get_wasi_exit_code, wasm_runtime_lookup_function, - wasm_valkind_enum_WASM_EXTERNREF, wasm_valkind_enum_WASM_F32, wasm_valkind_enum_WASM_F64, - wasm_valkind_enum_WASM_FUNCREF, wasm_valkind_enum_WASM_I32, wasm_valkind_enum_WASM_I64, - wasm_valkind_enum_WASM_V128, + wasm_runtime_get_exception, wasm_runtime_lookup_function, wasm_valkind_enum_WASM_EXTERNREF, + wasm_valkind_enum_WASM_F32, wasm_valkind_enum_WASM_F64, wasm_valkind_enum_WASM_FUNCREF, + wasm_valkind_enum_WASM_I32, wasm_valkind_enum_WASM_I64, wasm_valkind_enum_WASM_V128, }; +#[cfg(feature = "wasi")] +use wamr_sys::wasm_runtime_get_wasi_exit_code; + use crate::{ - helper::exception_to_string, instance::Instance, value::WasmValue, ExecError, RuntimeError, + ExecError, RuntimeError, helper::exception_to_string, instance::Instance, value::WasmValue, }; pub struct Function<'instance> { @@ -74,7 +77,7 @@ impl<'instance> Function<'instance> { let mut index: usize = 0; for result_type in result_types.iter() { - match *result_type as u32 { + match *result_type as i32 { wasm_valkind_enum_WASM_I32 | wasm_valkind_enum_WASM_FUNCREF | wasm_valkind_enum_WASM_EXTERNREF => { @@ -114,13 +117,29 @@ impl<'instance> Function<'instance> { pub fn call( &self, instance: &'instance Instance<'instance>, - params: &Vec, + params: &[WasmValue], + ) -> Result, RuntimeError> { + self.call_with_user_data(instance, params, core::ptr::null_mut()) + } + + /// execute an export function. + /// all parameters need to be wrapped in `WasmValue` + /// + /// # Error + /// + /// Return `RuntimeError::ExecutionError` if failed. + #[allow(non_upper_case_globals)] + pub fn call_with_user_data( + &self, + instance: &'instance Instance<'instance>, + params: &[WasmValue], + user_data: *mut c_void, ) -> Result, RuntimeError> { let param_count = unsafe { wasm_func_get_param_count(self.function, instance.get_inner_instance()) }; if param_count > params.len() as u32 { return Err(RuntimeError::ExecutionError(ExecError { - message: "invalid parameters".to_string(), + message: String::from("invalid parameters"), exit_code: 0xff, })); } @@ -128,7 +147,7 @@ impl<'instance> Function<'instance> { // Maintain sufficient allocated space in the vector rather than just declaring its capacity. let result_count = unsafe { wasm_func_get_result_count(self.function, instance.get_inner_instance()) }; - let capacity = std::cmp::max(param_count, result_count) as usize * 4; + let capacity = core::cmp::max(param_count, result_count) as usize * 4; // Populate the parameters in the sufficiently allocated argv vector let mut argv = Vec::with_capacity(capacity); @@ -140,9 +159,11 @@ impl<'instance> Function<'instance> { let call_result: bool; unsafe { let exec_env: wasm_exec_env_t = - wasm_runtime_get_exec_env_singleton(instance.get_inner_instance()); + wamr_sys::wasm_runtime_create_exec_env(instance.get_inner_instance(), 1024 * 1024); + wamr_sys::wasm_runtime_set_user_data(exec_env, user_data); call_result = wasm_runtime_call_wasm(exec_env, self.function, param_count, argv.as_mut_ptr()); + wamr_sys::wasm_runtime_destroy_exec_env(exec_env); }; if !call_result { @@ -150,7 +171,13 @@ impl<'instance> Function<'instance> { let exception_c = wasm_runtime_get_exception(instance.get_inner_instance()); let error_info = ExecError { message: exception_to_string(exception_c), - exit_code: wasm_runtime_get_wasi_exit_code(instance.get_inner_instance()), + exit_code: { + #[cfg(feature = "wasi")] + let code = wasm_runtime_get_wasi_exit_code(instance.get_inner_instance()); + #[cfg(not(feature = "wasi"))] + let code = 0xff; + code + }, }; return Err(RuntimeError::ExecutionError(error_info)); } @@ -164,9 +191,15 @@ impl<'instance> Function<'instance> { #[cfg(test)] mod tests { use super::*; - use crate::{module::Module, runtime::Runtime, wasi_context::WasiCtxBuilder}; + #[cfg(all(feature = "std", feature = "wasi"))] + use crate::wasi_context::WasiCtxBuilder; + use crate::{module::Module, runtime::Runtime}; + #[cfg(all(feature = "std", feature = "wasi"))] use std::{ - process::{Command, Stdio}, path::Path, path::PathBuf, env, fs, + env, fs, + path::Path, + path::PathBuf, + process::{Command, Stdio}, }; #[test] @@ -240,6 +273,7 @@ mod tests { ); } + #[cfg(all(feature = "std", feature = "wasi"))] #[test] fn test_func_in_wasm32_wasi() { let runtime = Runtime::new().unwrap(); @@ -251,9 +285,7 @@ mod tests { assert!(module.is_ok()); let mut module = module.unwrap(); - let wasi_ctx = WasiCtxBuilder::new() - .set_pre_open_path(vec!["."], vec![]) - .build(); + let wasi_ctx = WasiCtxBuilder::new().set_pre_open_path(&["."], &[]).build(); module.set_wasi_context(wasi_ctx); let instance = Instance::new(&runtime, &module, 1024 * 64); @@ -273,6 +305,7 @@ mod tests { assert_eq!(result.unwrap(), vec![WasmValue::I32(27)]); } + #[cfg(all(feature = "std", feature = "wasi"))] #[test] fn test_func_in_wasm32_wasi_w_args() { let runtime = Runtime::new().unwrap(); @@ -285,8 +318,8 @@ mod tests { let mut module = module.unwrap(); let wasi_ctx = WasiCtxBuilder::new() - .set_pre_open_path(vec!["."], vec![]) - .set_arguments(vec!["wasi-demo-app.wasm", "echo", "hi"]) + .set_pre_open_path(&["."], &[]) + .set_arguments(&["wasi-demo-app.wasm", "echo", "hi"]) .build(); module.set_wasi_context(wasi_ctx); @@ -303,6 +336,8 @@ mod tests { println!("{:?}", result.unwrap()); } + #[cfg(all(feature = "std", feature = "wasi"))] + #[ignore] #[test] fn test_func_in_multi_v128_return() { let runtime = Runtime::new().unwrap(); @@ -338,7 +373,8 @@ mod tests { }; let base_entries = fs::read_dir(base); assert!(base_entries.is_ok()); - let found = base_entries.unwrap() + let found = base_entries + .unwrap() .filter_map(|entry| entry.ok()) .map(|entry| { let path = entry.path(); @@ -350,8 +386,20 @@ mod tests { (path, name) }) .filter_map(|(path, name)| { - if name.starts_with("wamr-sys") && path.join("out").join("wamrcbuild").join("bin").join("wamrc").exists() { - Some(path.join("out").join("wamrcbuild").join("bin").join("wamrc")) + if name.starts_with("wamr-sys") + && path + .join("out") + .join("wamrcbuild") + .join("bin") + .join("wamrc") + .exists() + { + Some( + path.join("out") + .join("wamrcbuild") + .join("bin") + .join("wamrc"), + ) } else { None } @@ -365,7 +413,7 @@ mod tests { .arg("-o") .arg(aot_dest.clone()) .arg(wasm_src.clone()) - .stderr(Stdio::piped()) + .stderr(Stdio::piped()) .stdout(Stdio::piped()) .output() .unwrap(); @@ -385,7 +433,7 @@ mod tests { let wrapped_result = function.call(instance, &vec![]); let unwrapped_result = wrapped_result.unwrap(); - + assert_eq!(unwrapped_result.len(), 12); assert_eq!( unwrapped_result, diff --git a/src/helper.rs b/src/helper.rs index 71d0781..7e1d9b3 100644 --- a/src/helper.rs +++ b/src/helper.rs @@ -3,8 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ -use std::ffi::{c_char, CStr}; -use std::string::String; +use alloc::{string::String, string::ToString, vec::Vec}; +use core::ffi::{CStr, c_char}; pub const DEFAULT_ERROR_BUF_SIZE: usize = 128; @@ -29,7 +29,7 @@ pub fn exception_to_string(raw_exception: *const c_char) -> String { #[cfg(test)] mod tests { use super::*; - use std::ffi::CString; + use alloc::ffi::CString; #[test] fn test_error_buf_empty() { diff --git a/src/host_function.rs b/src/host_function.rs index 8aacb41..2328e0a 100644 --- a/src/host_function.rs +++ b/src/host_function.rs @@ -3,9 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception */ +use alloc::{ffi::CString, vec::Vec}; /// This is a wrapper of a host defined(Rust) function. -use std::ffi::{c_void, CString}; -use std::ptr; +use core::ffi::{c_char, c_void}; +use core::ptr; use wamr_sys::NativeSymbol; @@ -40,8 +41,30 @@ impl HostFunctionList { }); let last = self.host_functions.last().unwrap(); - self.native_symbols - .push(pack_host_function(&(last.function_name), function_ptr)); + self.native_symbols.push(pack_host_function( + &(last.function_name), + function_ptr, + ptr::null(), + )); + } + + pub fn register_host_function_with_signature( + &mut self, + function_name: &str, + function_ptr: *mut c_void, + signature: *const c_char, + ) { + self.host_functions.push(HostFunction { + function_name: CString::new(function_name).unwrap(), + function_ptr, + }); + + let last = self.host_functions.last().unwrap(); + self.native_symbols.push(pack_host_function( + &(last.function_name), + function_ptr, + signature, + )); } pub fn get_native_symbols(&mut self) -> &mut Vec { @@ -53,11 +76,15 @@ impl HostFunctionList { } } -pub fn pack_host_function(function_name: &CString, function_ptr: *mut c_void) -> NativeSymbol { +pub fn pack_host_function( + function_name: &CString, + function_ptr: *mut c_void, + signature: *const i8, +) -> NativeSymbol { NativeSymbol { symbol: function_name.as_ptr(), func_ptr: function_ptr, - signature: ptr::null(), + signature, attachment: ptr::null_mut(), } } @@ -68,13 +95,16 @@ mod tests { use crate::{ function::Function, instance::Instance, module::Module, runtime::Runtime, value::WasmValue, }; + #[cfg(feature = "std")] use std::env; + #[cfg(feature = "std")] use std::path::PathBuf; extern "C" fn extra() -> i32 { 100 } + #[cfg(feature = "std")] #[test] #[ignore] fn test_host_function() { diff --git a/src/instance.rs b/src/instance.rs index 2e170a7..0651b53 100644 --- a/src/instance.rs +++ b/src/instance.rs @@ -8,16 +8,20 @@ #![allow(unused_variables)] +use alloc::string::String; use core::{ffi::c_char, marker::PhantomData}; use wamr_sys::{ - wasm_module_inst_t, wasm_runtime_deinstantiate, wasm_runtime_destroy_thread_env, - wasm_runtime_init_thread_env, wasm_runtime_instantiate, + wasm_module_inst_t, wasm_runtime_addr_app_to_native, wasm_runtime_addr_native_to_app, + wasm_runtime_clear_exception, wasm_runtime_deinstantiate, wasm_runtime_destroy_thread_env, + wasm_runtime_get_exception, wasm_runtime_init_thread_env, wasm_runtime_instantiate, + wasm_runtime_module_dup_data, wasm_runtime_module_free, wasm_runtime_module_malloc, + wasm_runtime_set_exception, wasm_runtime_validate_app_addr, }; use crate::{ - helper::error_buf_to_string, helper::DEFAULT_ERROR_BUF_SIZE, module::Module, runtime::Runtime, - RuntimeError, + RuntimeError, helper::DEFAULT_ERROR_BUF_SIZE, helper::error_buf_to_string, module::Module, + runtime::Runtime, }; #[derive(Debug)] @@ -76,12 +80,12 @@ impl<'module> Instance<'module> { 0 => { return Err(RuntimeError::InstantiationFailure(String::from( "instantiation failed", - ))) + ))); } _ => { return Err(RuntimeError::InstantiationFailure(error_buf_to_string( &error_buf, - ))) + ))); } } } @@ -95,6 +99,341 @@ impl<'module> Instance<'module> { pub fn get_inner_instance(&self) -> wasm_module_inst_t { self.instance } + + /// Allocate memory from the module instance's heap + /// + /// This allocates memory from the module instance's heap space. The returned + /// address is an app offset (relative to module memory base), not an absolute address. + /// + /// # Important + /// + /// This function can trigger memory growth, which may invalidate existing native + /// pointers obtained from [`addr_app_to_native`](Self::addr_app_to_native). + /// + /// # Parameters + /// + /// * `size` - The number of bytes to allocate + /// + /// # Returns + /// + /// Returns `Ok((app_offset, native_ptr))` where: + /// * `app_offset` - The offset in the WASM app address space + /// * `native_ptr` - The native (host) pointer to the allocated memory + /// + /// Returns `Err(RuntimeError)` if allocation fails + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// // Allocate 100 bytes + /// let (app_offset, native_ptr) = instance.module_malloc(100)?; + /// + /// // Write data to the allocated memory + /// let data = b"Hello from host!"; + /// unsafe { + /// core::ptr::copy_nonoverlapping( + /// data.as_ptr(), + /// native_ptr as *mut u8, + /// data.len() + /// ); + /// } + /// + /// // app_offset can be passed to WASM functions + /// // Don't forget to free when done + /// instance.module_free(app_offset); + /// # Ok(()) + /// # } + /// ``` + pub fn module_malloc(&self, size: u64) -> Result<(u64, *mut core::ffi::c_void), RuntimeError> { + let mut native_addr: *mut core::ffi::c_void = core::ptr::null_mut(); + let app_offset = unsafe { + wasm_runtime_module_malloc(self.instance, size, &mut native_addr as *mut *mut _) + }; + + if app_offset == 0 { + return Err(RuntimeError::InstantiationFailure(String::from( + "module malloc failed: out of memory", + ))); + } + + Ok((app_offset, native_addr)) + } + + /// Free memory allocated by [`module_malloc`](Self::module_malloc) + /// + /// # Parameters + /// + /// * `ptr` - The app offset returned by [`module_malloc`](Self::module_malloc) + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// let (app_offset, _) = instance.module_malloc(100)?; + /// // ... use the memory ... + /// instance.module_free(app_offset); + /// # Ok(()) + /// # } + /// ``` + pub fn module_free(&self, ptr: u64) { + unsafe { + wasm_runtime_module_free(self.instance, ptr); + } + } + + /// Allocate memory and initialize it with data + /// + /// This is a convenience function that allocates memory from the module heap + /// and copies the provided data into it. + /// + /// # Parameters + /// + /// * `data` - The data to copy into the allocated memory + /// + /// # Returns + /// + /// Returns `Ok(app_offset)` - the offset in the WASM app address space + /// Returns `Err(RuntimeError)` if allocation fails + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// let data = b"Hello from host!"; + /// let app_offset = instance.module_dup_data(data)?; + /// // app_offset can be passed to WASM functions + /// // Don't forget to free when done + /// instance.module_free(app_offset); + /// # Ok(()) + /// # } + /// ``` + pub fn module_dup_data(&self, data: &[u8]) -> Result { + let app_offset = unsafe { + wasm_runtime_module_dup_data( + self.instance, + data.as_ptr() as *const i8, + data.len() as u64, + ) + }; + + if app_offset == 0 { + return Err(RuntimeError::InstantiationFailure(String::from( + "module dup data failed: out of memory", + ))); + } + + Ok(app_offset) + } + + /// Convert app address (relative offset) to native address (absolute pointer) + /// + /// # Important + /// + /// Native addresses can be invalidated on memory growth (except for shared memory). + /// Use this function carefully and avoid caching native pointers across operations + /// that might trigger memory growth. + /// + /// # Parameters + /// + /// * `app_offset` - The app address (offset from memory base) + /// + /// # Returns + /// + /// Returns the native pointer, or null if the address is invalid + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// let (app_offset, _) = instance.module_malloc(100)?; + /// let native_ptr = instance.addr_app_to_native(app_offset); + /// // Use native_ptr... + /// instance.module_free(app_offset); + /// # Ok(()) + /// # } + /// ``` + pub fn addr_app_to_native(&self, app_offset: u64) -> *mut core::ffi::c_void { + unsafe { wasm_runtime_addr_app_to_native(self.instance, app_offset) } + } + + /// Convert native address (absolute pointer) to app address (relative offset) + /// + /// # Parameters + /// + /// * `native_ptr` - The native pointer + /// + /// # Returns + /// + /// Returns the app offset, or 0 if the pointer is not in WASM memory + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// let (app_offset, native_ptr) = instance.module_malloc(100)?; + /// let converted_offset = instance.addr_native_to_app(native_ptr); + /// assert_eq!(app_offset, converted_offset); + /// instance.module_free(app_offset); + /// # Ok(()) + /// # } + /// ``` + pub fn addr_native_to_app(&self, native_ptr: *mut core::ffi::c_void) -> u64 { + unsafe { wasm_runtime_addr_native_to_app(self.instance, native_ptr) } + } + + /// Validate an app address range + /// + /// Check whether an app address range belongs to the WASM module instance's + /// address space (heap or memory space). + /// + /// # Parameters + /// + /// * `app_offset` - The app address to validate + /// * `size` - The size of the memory region to validate + /// + /// # Returns + /// + /// Returns `true` if the address range is valid, `false` otherwise + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// let (app_offset, _) = instance.module_malloc(100)?; + /// assert!(instance.validate_app_addr(app_offset, 100)); + /// assert!(!instance.validate_app_addr(app_offset, 1000)); // too large + /// instance.module_free(app_offset); + /// # Ok(()) + /// # } + /// ``` + pub fn validate_app_addr(&self, app_offset: u64, size: u64) -> bool { + unsafe { wasm_runtime_validate_app_addr(self.instance, app_offset, size) } + } + + /// Get the exception info of the WASM module instance + /// + /// # Returns + /// + /// Returns `Some(String)` with the exception message if an exception occurred, + /// `None` if no exception + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # use wamr_rust_sdk::function::Function; + /// # use wamr_rust_sdk::value::WasmValue; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// # let function = Function::find_export_func(&instance, "test")?; + /// // After calling a function that might fail + /// match function.call(&instance, &vec![]) { + /// Ok(_) => println!("Success"), + /// Err(_) => { + /// if let Some(exception) = instance.get_exception() { + /// eprintln!("Exception: {}", exception); + /// } + /// } + /// } + /// # Ok(()) + /// # } + /// ``` + pub fn get_exception(&self) -> Option { + unsafe { + let exception_ptr = wasm_runtime_get_exception(self.instance); + if exception_ptr.is_null() { + return None; + } + + let c_str = core::ffi::CStr::from_ptr(exception_ptr); + c_str.to_str().ok().map(|s| s.to_string()) + } + } + + /// Set exception info for the WASM module instance + /// + /// This is typically used in host functions to signal an error condition to the WASM module. + /// + /// # Parameters + /// + /// * `exception` - The exception message to set + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// instance.set_exception("Custom error occurred"); + /// # Ok(()) + /// # } + /// ``` + pub fn set_exception(&self, exception: &str) { + use alloc::ffi::CString; + let exception_cstr = CString::new(exception).expect("CString::new failed"); + unsafe { + wasm_runtime_set_exception(self.instance, exception_cstr.as_ptr()); + } + } + + /// Clear the exception info of the WASM module instance + /// + /// # Example + /// + /// ```no_run + /// # use wamr_rust_sdk::{RuntimeError, runtime::Runtime, module::Module, instance::Instance}; + /// # fn example() -> Result<(), RuntimeError> { + /// # let runtime = Runtime::new()?; + /// # let binary = vec![0u8; 0]; + /// # let module = Module::from_vec(&runtime, binary, "test")?; + /// # let instance = Instance::new(&runtime, &module, 1024)?; + /// // Clear any existing exception + /// instance.clear_exception(); + /// # Ok(()) + /// # } + /// ``` + pub fn clear_exception(&self) { + unsafe { + wasm_runtime_clear_exception(self.instance); + } + } } impl Drop for Instance<'_> { @@ -109,9 +448,10 @@ impl Drop for Instance<'_> { #[cfg(test)] mod tests { use super::*; - use crate::runtime::Runtime; + use crate::runtime::{Runtime, RuntimeBuilder}; + use alloc::{vec, vec::Vec}; use wamr_sys::{ - wasm_runtime_get_running_mode, RunningMode_Mode_Interp, RunningMode_Mode_LLVM_JIT, + RunningMode_Mode_Interp, RunningMode_Mode_LLVM_JIT, wasm_runtime_get_running_mode, }; #[test] @@ -229,4 +569,227 @@ mod tests { RunningMode_Mode_Interp ); } + + #[test] + fn test_module_malloc_free() { + let runtime = Runtime::builder().use_system_allocator().build().unwrap(); + + let binary = wat::parse_str(r#" + (module + (memory 1) + (func (export "add") (param i32 i32) (result i32) + (local.get 0) + (local.get 1) + (i32.add) + ) + ) + "#).unwrap(); + + let module = Module::from_vec(&runtime, binary, ""); + assert!(module.is_ok()); + let module = &mut module.unwrap(); + + // Create instance with heap size + let instance = Instance::new_with_args(&runtime, module, 128 * 1024 * 1024, 128 * 1024 * 1024); + assert!(instance.is_ok()); + let instance = instance.unwrap(); + + // Test module_malloc + let result = instance.module_malloc(1024); + if let Err(e) = &result { + eprintln!("module_malloc error: {:?}", e); + } + assert!(result.is_ok()); + let (app_offset, native_ptr) = result.unwrap(); + assert_ne!(app_offset, 0); + assert!(!native_ptr.is_null()); + + // Validate the allocated address + assert!(instance.validate_app_addr(app_offset, 100)); + + // Write some data to the allocated memory + unsafe { + let ptr = native_ptr as *mut u8; + *ptr = 42; + assert_eq!(*ptr, 42); + } + + // Free the memory + instance.module_free(app_offset); + } + + #[test] + fn test_module_dup_data() { + let runtime = RuntimeBuilder::default() + // .run_as_interpreter() + .use_rust_allocator() + .build() + .unwrap(); + + let binary = wat::parse_str(r#" + (module + (memory 1024) + (func (export "add") (param i32 i32) (result i32) + (local.get 0) + (local.get 1) + (i32.add) + ) + ) + "#).unwrap(); + + let module = Module::from_vec(&runtime, binary, "").unwrap(); + + // Create instance with heap size + let instance = Instance::new_with_args(&runtime, &module, 128 * 1024 * 1024, 1024 * 1024); + assert!(instance.is_ok()); + let instance = instance.unwrap(); + + // Test module_dup_data + let test_data = b"Hello from host!"; + let app_offset = instance.module_dup_data(test_data).unwrap(); + assert_ne!(app_offset, 0); + + // Verify the data was copied correctly + let native_ptr = instance.addr_app_to_native(app_offset); + assert!(!native_ptr.is_null()); + + unsafe { + let slice = core::slice::from_raw_parts(native_ptr as *const u8, test_data.len()); + assert_eq!(slice, test_data); + } + + // Free the memory + instance.module_free(app_offset); + } + + #[test] + fn test_addr_conversion() { + let runtime = Runtime::new().unwrap(); + + let binary = wat::parse_str(r#" + (module + (memory 1024) + (func (export "add") (param i32 i32) (result i32) + (local.get 0) + (local.get 1) + (i32.add) + ) + ) + "#).unwrap(); + + let module = Module::from_vec(&runtime, binary, "test"); + assert!(module.is_ok()); + let module = &module.unwrap(); + + // Create instance with heap size + let instance = Instance::new_with_args(&runtime, &module, 128 * 1024 * 1024, 1024 * 1024); + assert!(instance.is_ok()); + let instance = instance.unwrap(); + + // Allocate memory + let result = instance.module_malloc(100); + assert!(result.is_ok()); + let (app_offset, native_ptr) = result.unwrap(); + + // Test addr_app_to_native + let converted_native = instance.addr_app_to_native(app_offset); + assert_eq!(native_ptr, converted_native); + + // Test addr_native_to_app + let converted_app = instance.addr_native_to_app(native_ptr); + assert_eq!(app_offset, converted_app); + + // Free the memory + instance.module_free(app_offset); + } + + #[test] + fn test_validate_app_addr() { + let runtime = Runtime::new().unwrap(); + + let binary = wat::parse_str(r#" + (module + (memory 1) + (func (export "add") (param i32 i32) (result i32) + (local.get 0) + (local.get 1) + (i32.add) + ) + ) + "#).unwrap(); + + let module = Module::from_vec(&runtime, binary, "test"); + assert!(module.is_ok()); + let module = &module.unwrap(); + + // Create instance with small heap size + let instance = Instance::new_with_args(&runtime, &module, 1024, 1024); + assert!(instance.is_ok()); + let instance = instance.unwrap(); + + // Allocate memory + let result = instance.module_malloc(100); + assert!(result.is_ok()); + let (app_offset, _) = result.unwrap(); + println!("app_offset: {app_offset}"); + + // Test validation with valid size (within allocated memory) + assert!(instance.validate_app_addr(app_offset, 100)); + assert!(instance.validate_app_addr(app_offset, 50)); + + // Test validation with invalid size (larger than allocated) + assert!(!instance.validate_app_addr(app_offset, 1000)); + + // Test validation with invalid offset + assert!(!instance.validate_app_addr(0xFFFFFFFF, 100)); + + // Test validation with offset beyond memory bounds + let large_offset = app_offset + 1000000; + assert!(!instance.validate_app_addr(large_offset, 100)); + + // Free the memory + instance.module_free(app_offset); + } + + #[test] + fn test_exception_api() { + let runtime = Runtime::new().unwrap(); + + let binary = vec![ + 0x00, 0x61, 0x73, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x01, 0x07, 0x01, 0x60, 0x02, 0x7f, + 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x07, 0x01, 0x03, 0x61, 0x64, 0x64, + 0x00, 0x00, 0x0a, 0x09, 0x01, 0x07, 0x00, 0x20, 0x00, 0x20, 0x01, 0x6a, 0x0b, + ]; + let binary = binary.into_iter().map(|c| c as u8).collect::>(); + + let module = Module::from_vec(&runtime, binary, "test"); + assert!(module.is_ok()); + let module = &module.unwrap(); + + let instance = Instance::new(&runtime, module, 1024); + assert!(instance.is_ok()); + let instance = instance.unwrap(); + + // Initially no exception + assert_eq!(instance.get_exception(), None); + + // Set an exception + instance.set_exception("Test exception"); + assert_eq!( + instance.get_exception(), + Some(String::from("Exception: Test exception")) + ); + + // Clear the exception + instance.clear_exception(); + assert_eq!(instance.get_exception(), None); + + // Set another exception + instance.set_exception("Another error"); + assert!(instance.get_exception().is_some()); + assert!(instance + .get_exception() + .unwrap() + .contains("Another error")); + } } diff --git a/src/lib.rs b/src/lib.rs index 1762126..c3b9a60 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -70,6 +70,10 @@ //! }; //! use std::path::PathBuf; //! +//! # #[cfg(not(feature = "wasi"))] +//! fn main() {} +//! +//! # #[cfg(feature = "wasi")] //! fn main() -> Result<(), RuntimeError> { //! let runtime = Runtime::new()?; //! @@ -117,6 +121,10 @@ //! 100 //! } //! +//! # #[cfg(not(feature = "wasi"))] +//! fn main() {} +//! +//! # #[cfg(feature = "wasi")] //! fn main() -> Result<(), RuntimeError> { //! let runtime = Runtime::builder() //! .use_system_allocator() @@ -141,9 +149,17 @@ //! ``` //! -use std::error; -use std::fmt; +#![cfg_attr(not(feature = "std"), no_std)] + +use alloc::string::String; +use core::error; +use core::fmt; +use host_function::HostFunctionList; +#[cfg(feature = "std")] use std::io; +use wamr_sys::NativeSymbol; +use wamr_sys::wasm_runtime_register_natives; + pub use wamr_sys as sys; pub mod function; @@ -153,6 +169,10 @@ pub mod instance; pub mod module; pub mod runtime; pub mod value; + +extern crate alloc; + +#[cfg(feature = "std")] pub mod wasi_context; #[derive(Debug)] @@ -168,6 +188,7 @@ pub enum RuntimeError { /// Runtime initialization error. InitializationFailure, /// file operation error. usually while loading(compilation) a .wasm + #[cfg(feature = "std")] WasmFileFSError(std::io::Error), /// A compilation error. usually means that the .wasm file is invalid CompilationError(String), @@ -184,6 +205,7 @@ impl fmt::Display for RuntimeError { match self { RuntimeError::NotImplemented => write!(f, "Not implemented"), RuntimeError::InitializationFailure => write!(f, "Runtime initialization failure"), + #[cfg(feature = "std")] RuntimeError::WasmFileFSError(e) => write!(f, "Wasm file operation error: {}", e), RuntimeError::CompilationError(e) => write!(f, "Wasm compilation error: {}", e), RuntimeError::InstantiationFailure(e) => write!(f, "Wasm instantiation failure: {}", e), @@ -200,14 +222,29 @@ impl fmt::Display for RuntimeError { impl error::Error for RuntimeError { fn source(&self) -> Option<&(dyn error::Error + 'static)> { match self { + #[cfg(feature = "std")] RuntimeError::WasmFileFSError(e) => Some(e), _ => None, } } } +#[cfg(feature = "std")] impl From for RuntimeError { fn from(e: io::Error) -> Self { RuntimeError::WasmFileFSError(e) } } + +pub fn register_host_functions(host_functions: &mut HostFunctionList) { + let module_name_ptr = host_functions.module_name.as_ptr(); + let native_symbols = host_functions.get_native_symbols(); + let n = native_symbols.len() as u32; + unsafe { + wasm_runtime_register_natives( + module_name_ptr, + native_symbols.as_ptr() as *mut NativeSymbol, + n, + ); + } +} diff --git a/src/module.rs b/src/module.rs index 68cbba5..ad7547e 100644 --- a/src/module.rs +++ b/src/module.rs @@ -7,23 +7,28 @@ //! get one via `Module::from_file()` or `Module::from_buf()` use crate::{ - helper::error_buf_to_string, helper::DEFAULT_ERROR_BUF_SIZE, runtime::Runtime, - wasi_context::WasiCtx, RuntimeError, + RuntimeError, helper::DEFAULT_ERROR_BUF_SIZE, helper::error_buf_to_string, runtime::Runtime, }; -use core::marker::PhantomData; -use std::{ - ffi::{c_char, CString}, - fs::File, - io::Read, - path::Path, - ptr, - string::String, - vec::Vec, + +#[cfg(feature = "std")] +use crate::wasi_context::WasiCtx; + +use core::{ffi::c_char, marker::PhantomData}; + +#[cfg(feature = "std")] +use std::{fs::File, io::Read, path::Path}; + +use alloc::{string::String, vec::Vec}; + +use alloc::ffi::CString; + +use wamr_sys::{ + wasm_module_t, wasm_runtime_load, wasm_runtime_set_module_name, wasm_runtime_unload, }; +#[cfg(all(feature = "std", feature = "wasi"))] use wamr_sys::{ - wasm_module_t, wasm_runtime_load, wasm_runtime_set_module_name, wasm_runtime_set_wasi_addr_pool, wasm_runtime_set_wasi_args, - wasm_runtime_set_wasi_ns_lookup_pool, wasm_runtime_unload, + wasm_runtime_set_wasi_ns_lookup_pool, }; #[allow(dead_code)] @@ -33,6 +38,7 @@ pub struct Module<'runtime> { module: wasm_module_t, // to keep the module content in memory content: Vec, + #[cfg(feature = "std")] wasi_ctx: WasiCtx, _phantom: PhantomData<&'runtime Runtime>, } @@ -44,6 +50,7 @@ impl<'runtime> Module<'runtime> { /// /// If the file does not exist or the file cannot be read, an `RuntimeError::WasmFileFSError` will be returned. /// If the wasm file is not a valid wasm file, an `RuntimeError::CompilationError` will be returned. + #[cfg(feature = "std")] pub fn from_file(runtime: &'runtime Runtime, wasm_file: &Path) -> Result { let name = wasm_file.file_name().unwrap().to_str().unwrap(); let mut wasm_file = File::open(wasm_file)?; @@ -54,6 +61,14 @@ impl<'runtime> Module<'runtime> { Self::from_vec(runtime, binary, name) } + pub fn from_buf( + runtime: &'runtime Runtime, + binary: &'runtime [u8], + name: &str, + ) -> Result { + Self::from_vec(runtime, binary.to_vec(), name) + } + /// compile a module int the given buffer, /// /// # Error @@ -66,6 +81,7 @@ impl<'runtime> Module<'runtime> { name: &str, ) -> Result { let mut error_buf: [c_char; DEFAULT_ERROR_BUF_SIZE] = [0; DEFAULT_ERROR_BUF_SIZE]; + let module = unsafe { wasm_runtime_load( content.as_mut_ptr(), @@ -80,12 +96,12 @@ impl<'runtime> Module<'runtime> { 0 => { return Err(RuntimeError::CompilationError(String::from( "load module failed", - ))) + ))); } _ => { return Err(RuntimeError::CompilationError(error_buf_to_string( &error_buf, - ))) + ))); } } } @@ -108,6 +124,7 @@ impl<'runtime> Module<'runtime> { name: String::from(name), module, content, + #[cfg(feature = "std")] wasi_ctx: WasiCtx::default(), _phantom: PhantomData, }) @@ -116,29 +133,30 @@ impl<'runtime> Module<'runtime> { /// set Wasi context for a module /// /// This function should be called before `Instance::new` + #[cfg(all(feature = "std", feature = "wasi"))] pub fn set_wasi_context(&mut self, wasi_ctx: WasiCtx) { self.wasi_ctx = wasi_ctx; let real_paths = if self.wasi_ctx.get_preopen_real_paths().is_empty() { - ptr::null_mut() + core::ptr::null_mut() } else { self.wasi_ctx.get_preopen_real_paths().as_ptr() as *mut *const c_char }; let mapped_paths = if self.wasi_ctx.get_preopen_mapped_paths().is_empty() { - ptr::null_mut() + core::ptr::null_mut() } else { self.wasi_ctx.get_preopen_mapped_paths().as_ptr() as *mut *const c_char }; let env = if self.wasi_ctx.get_env_vars().is_empty() { - ptr::null_mut() + core::ptr::null_mut() } else { self.wasi_ctx.get_env_vars_ptrs().as_ptr() as *mut *const c_char }; let args = if self.wasi_ctx.get_arguments().is_empty() { - ptr::null_mut() + core::ptr::null_mut() } else { self.wasi_ctx.get_arguments_ptrs().as_ptr() as *mut *mut c_char }; @@ -157,7 +175,7 @@ impl<'runtime> Module<'runtime> { ); let ns_lookup_pool = if self.wasi_ctx.get_allowed_dns().is_empty() { - ptr::null_mut() + core::ptr::null_mut() } else { self.wasi_ctx.get_allowed_dns().as_ptr() as *mut *const c_char }; @@ -169,7 +187,7 @@ impl<'runtime> Module<'runtime> { ); let addr_pool = if self.wasi_ctx.get_allowed_address().is_empty() { - ptr::null_mut() + core::ptr::null_mut() } else { self.wasi_ctx.get_allowed_address().as_ptr() as *mut *const c_char }; @@ -201,10 +219,15 @@ impl Drop for Module<'_> { #[cfg(test)] mod tests { use super::*; - use crate::{helper::cstr_to_string, runtime::Runtime, wasi_context::WasiCtxBuilder}; + #[cfg(all(feature = "std", feature = "wasi"))] + use crate::wasi_context::WasiCtxBuilder; + use crate::{helper::cstr_to_string, runtime::Runtime}; + use alloc::{vec, vec::Vec}; + #[cfg(all(feature = "std", feature = "wasi"))] use std::path::PathBuf; use wamr_sys::wasm_runtime_get_module_name; + #[cfg(feature = "std")] #[test] fn test_module_not_exist() { let runtime = Runtime::new(); @@ -238,6 +261,7 @@ mod tests { assert!(module.is_ok()); } + #[cfg(all(feature = "std", feature = "wasi"))] #[test] fn test_module_from_file() { let runtime = Runtime::new().unwrap(); @@ -249,6 +273,7 @@ mod tests { assert!(module.is_ok()); } + #[cfg(all(feature = "std", feature = "wasi"))] #[test] fn test_module_with_wasi_args() { let runtime = Runtime::new().unwrap(); @@ -272,10 +297,10 @@ mod tests { let mut module = module.unwrap(); let wasi_ctx = WasiCtxBuilder::new() - .set_pre_open_path(vec!["."], vec![]) - .set_env_vars(vec![]) - .set_allowed_address(vec![]) - .set_allowed_dns(vec![]) + .set_pre_open_path(&["."], &[]) + .set_env_vars(&[]) + .set_allowed_address(&[]) + .set_allowed_dns(&[]) .build(); module.set_wasi_context(wasi_ctx); diff --git a/src/runtime.rs b/src/runtime.rs index e5f6af6..8f84541 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -7,15 +7,17 @@ //! Every process should have only one instance of this runtime by call //! `Runtime::new()` or `Runtime::builder().build()` once. -use std::ffi::c_void; +use alloc::vec::Vec; +use core::{alloc::Layout, ffi::c_void}; use wamr_sys::{ - mem_alloc_type_t_Alloc_With_Pool, mem_alloc_type_t_Alloc_With_System_Allocator, - wasm_runtime_destroy, wasm_runtime_full_init, wasm_runtime_init, NativeSymbol, - RunningMode_Mode_Interp, RunningMode_Mode_LLVM_JIT, RuntimeInitArgs, + NativeSymbol, RunningMode_Mode_Interp, RunningMode_Mode_LLVM_JIT, RuntimeInitArgs, + mem_alloc_type_t_Alloc_With_Allocator, mem_alloc_type_t_Alloc_With_Pool, + mem_alloc_type_t_Alloc_With_System_Allocator, wasm_runtime_destroy, wasm_runtime_full_init, + wasm_runtime_init, }; -use crate::{host_function::HostFunctionList, RuntimeError}; +use crate::{RuntimeError, host_function::HostFunctionList}; #[allow(dead_code)] #[derive(Debug)] @@ -84,6 +86,40 @@ impl RuntimeBuilder { self } + pub fn use_rust_allocator(mut self) -> RuntimeBuilder { + self.args.mem_alloc_type = mem_alloc_type_t_Alloc_With_Allocator; + self.args.mem_alloc_option.allocator.malloc_func = { + extern "C" fn malloc(size: usize) -> *mut c_void { + unsafe { + alloc::alloc::alloc(Layout::from_size_align(size, 8).unwrap()) as *mut c_void + } + } + malloc as *mut c_void + }; + self.args.mem_alloc_option.allocator.realloc_func = { + extern "C" fn realloc(ptr: *mut c_void, new_size: usize) -> *mut c_void { + unsafe { + alloc::alloc::realloc( + ptr as *mut u8, + Layout::from_size_align(new_size, 8).unwrap(), + new_size, + ) as *mut c_void + } + } + realloc as *mut c_void + }; + + self.args.mem_alloc_option.allocator.free_func = { + extern "C" fn free(ptr: *mut c_void) { + unsafe { + alloc::alloc::dealloc(ptr as *mut u8, Layout::from_size_align(0, 8).unwrap()) + }; + } + free as *mut c_void + }; + self + } + /// system allocator mode /// allocate memory from pool, as a pre-allocated buffer, for runtime consumed memory pub fn use_memory_pool(mut self, mut pool: Vec) -> RuntimeBuilder { diff --git a/src/value.rs b/src/value.rs index 5d12bb7..dcaf093 100644 --- a/src/value.rs +++ b/src/value.rs @@ -5,7 +5,9 @@ //! a wasm value. Always used as function parameters and results -#[derive(Debug, PartialEq)] +use alloc::{vec, vec::Vec}; + +#[derive(Debug, PartialEq, Clone, Copy)] pub enum WasmValue { Void, I32(i32), @@ -22,23 +24,23 @@ impl WasmValue { vec![] } WasmValue::I32(value) => { - let in_u32_array = unsafe { std::mem::transmute::(value) }; + let in_u32_array = unsafe { core::mem::transmute::(value) }; vec![in_u32_array[0]] } WasmValue::I64(value) => { - let in_u32_array = unsafe { std::mem::transmute::(value) }; + let in_u32_array = unsafe { core::mem::transmute::(value) }; vec![in_u32_array[0], in_u32_array[1]] } WasmValue::F32(value) => { - let in_u32_array = unsafe { std::mem::transmute::(value) }; + let in_u32_array = unsafe { core::mem::transmute::(value) }; vec![in_u32_array[0]] } WasmValue::F64(value) => { - let in_u32_array = unsafe { std::mem::transmute::(value) }; + let in_u32_array = unsafe { core::mem::transmute::(value) }; vec![in_u32_array[0], in_u32_array[1]] } WasmValue::V128(value) => { - let in_u32_array = unsafe { std::mem::transmute::(value) }; + let in_u32_array = unsafe { core::mem::transmute::(value) }; vec![ in_u32_array[0], in_u32_array[1], @@ -51,27 +53,27 @@ impl WasmValue { pub fn decode_to_i32(binary: &[u32]) -> WasmValue { let binary: [u32; 1] = [binary[0]]; - WasmValue::I32(unsafe { std::mem::transmute::<[u32; 1], i32>(binary) }) + WasmValue::I32(unsafe { core::mem::transmute::<[u32; 1], i32>(binary) }) } pub fn decode_to_f32(binary: &[u32]) -> WasmValue { let binary: [u32; 1] = [binary[0]]; - WasmValue::F32(unsafe { std::mem::transmute::<[u32; 1], f32>(binary) }) + WasmValue::F32(unsafe { core::mem::transmute::<[u32; 1], f32>(binary) }) } pub fn decode_to_i64(binary: &[u32]) -> WasmValue { let binary: [u32; 2] = [binary[0], binary[1]]; - WasmValue::I64(unsafe { std::mem::transmute::<[u32; 2], i64>(binary) }) + WasmValue::I64(unsafe { core::mem::transmute::<[u32; 2], i64>(binary) }) } pub fn decode_to_f64(binary: &[u32]) -> WasmValue { let binary: [u32; 2] = [binary[0], binary[1]]; - WasmValue::F64(unsafe { std::mem::transmute::<[u32; 2], f64>(binary) }) + WasmValue::F64(unsafe { core::mem::transmute::<[u32; 2], f64>(binary) }) } pub fn decode_to_v128(binary: &[u32]) -> WasmValue { let binary: [u32; 4] = [binary[0], binary[1], binary[2], binary[3]]; - WasmValue::V128(unsafe { std::mem::transmute::<[u32; 4], i128>(binary) }) + WasmValue::V128(unsafe { core::mem::transmute::<[u32; 4], i128>(binary) }) } } diff --git a/src/wasi_context.rs b/src/wasi_context.rs index ff2cb6b..44171eb 100644 --- a/src/wasi_context.rs +++ b/src/wasi_context.rs @@ -5,7 +5,7 @@ //! prepare wasi context -use std::{ffi::c_char, ffi::CString, vec::Vec}; +use std::{ffi::CString, ffi::c_char, vec::Vec}; #[derive(Debug, Default)] struct PreOpen { @@ -60,8 +60,8 @@ impl WasiCtxBuilder { /// This function should be called before `Instance::new` pub fn set_pre_open_path( mut self, - real_paths: Vec<&str>, - mapped_paths: Vec<&str>, + real_paths: &[&str], + mapped_paths: &[&str], ) -> WasiCtxBuilder { self.pre_open.real_paths = real_paths .iter() @@ -81,7 +81,7 @@ impl WasiCtxBuilder { /// This function should be called before `Instance::new` /// /// all wasi args of a module will be spread into the environment variables of the module - pub fn set_env_vars(mut self, envs: Vec<&str>) -> WasiCtxBuilder { + pub fn set_env_vars(mut self, envs: &[&str]) -> WasiCtxBuilder { self.env = envs .iter() .map(|s| CString::new(s.as_bytes()).unwrap()) @@ -98,7 +98,7 @@ impl WasiCtxBuilder { /// set allowed ns , which are part of WASI arguments, for the module /// /// This function should be called before `Instance::new` - pub fn set_allowed_dns(mut self, dns: Vec<&str>) -> WasiCtxBuilder { + pub fn set_allowed_dns(mut self, dns: &[&str]) -> WasiCtxBuilder { self.allowed_dns = dns .iter() .map(|s| CString::new(s.as_bytes()).unwrap()) @@ -110,7 +110,7 @@ impl WasiCtxBuilder { /// set allowed ip addresses, which are part of WASI arguments, for the module /// /// This function should be called before `Instance::new` - pub fn set_allowed_address(mut self, addresses: Vec<&str>) -> WasiCtxBuilder { + pub fn set_allowed_address(mut self, addresses: &[&str]) -> WasiCtxBuilder { self.allowed_address = addresses .iter() .map(|s| CString::new(s.as_bytes()).unwrap()) @@ -122,7 +122,7 @@ impl WasiCtxBuilder { /// set arguments, which are part of WASI arguments, for the module /// /// This function should be called before `Instance::new` - pub fn set_arguments(mut self, args: Vec<&str>) -> WasiCtxBuilder { + pub fn set_arguments(mut self, args: &[&str]) -> WasiCtxBuilder { self.args = args .iter() .map(|s| CString::new(s.as_bytes()).unwrap()) @@ -178,11 +178,11 @@ mod tests { #[test] fn test_wasi_ctx_build() { let wasi_ctx = WasiCtxBuilder::new() - .set_pre_open_path(vec!["a/b/c"], vec!["/dog/cat/rabbit"]) - .set_allowed_address(vec!["1.2.3.4"]) - .set_allowed_dns(vec![]) - .set_env_vars(vec!["path=/usr/local/bin", "HOME=/home/xxx"]) - .set_arguments(vec!["arg1", "arg2"]) + .set_pre_open_path(&["a/b/c"], &["/dog/cat/rabbit"]) + .set_allowed_address(&["1.2.3.4"]) + .set_allowed_dns(&[]) + .set_env_vars(&["path=/usr/local/bin", "HOME=/home/xxx"]) + .set_arguments(&["arg1", "arg2"]) .build(); let mut preopen_iter = wasi_ctx.get_preopen_real_paths().iter();