From e733b7ecf99a2d3f255bc775d0f1df213c0db2fe Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:15:02 +0200 Subject: [PATCH 001/520] Update `libc` to 0.2.177 --- Cargo.lock | 303 +++++++++++++++++++++++++---------------------------- Cargo.toml | 2 +- 2 files changed, 144 insertions(+), 161 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 718631a8d6..f96b527dfe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -40,9 +40,9 @@ dependencies = [ [[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", ] @@ -100,22 +100,22 @@ dependencies = [ [[package]] name = "anstyle-query" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2" +checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc" dependencies = [ - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] name = "anstyle-wincon" -version = "3.0.10" +version = "3.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a" +checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d" dependencies = [ "anstyle", "once_cell_polyfill", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -231,9 +231,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-fips-sys" -version = "0.13.9" +version = "0.13.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede71ad84efb06d748d9af3bc500b14957a96282a69a6833b1420dcacb411cc3" +checksum = "57900537c00a0565a35b63c4c281b372edfc9744b072fd4a3b414350a8f5ed48" dependencies = [ "bindgen 0.72.1", "cc", @@ -245,9 +245,9 @@ dependencies = [ [[package]] name = "aws-lc-rs" -version = "1.14.1" +version = "1.15.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879b6c89592deb404ba4dc0ae6b58ffd1795c78991cbb5b8bc441c48a070440d" +checksum = "6b5ce75405893cd713f9ab8e297d8e438f624dde7d706108285f7e17a25a180f" dependencies = [ "aws-lc-fips-sys", "aws-lc-sys", @@ -257,11 +257,10 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.32.3" +version = "0.34.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "107a4e9d9cab9963e04e84bb8dee0e25f2a987f9a8bad5ed054abd439caa8f8c" +checksum = "179c3777a8b5e70e90ea426114ffc565b2c1a9f82f6c4a0c5a34aa6ef5e781b6" dependencies = [ - "bindgen 0.72.1", "cc", "cmake", "dunce", @@ -286,7 +285,7 @@ version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -306,7 +305,7 @@ version = "0.72.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "993776b509cfb49c750f11b8f07a46fa23e0a1386ffc01fb1e7d343efc387895" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cexpr", "clang-sys", "itertools 0.13.0", @@ -328,9 +327,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.4" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" +checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3" [[package]] name = "blake2" @@ -361,9 +360,9 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" dependencies = [ "memchr", "regex-automata", @@ -435,9 +434,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.41" +version = "1.2.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7" +checksum = "cd405d82c84ff7f35739f175f67d8b9fb7687a0e84ccdc78bd3568839827cf07" dependencies = [ "find-msvc-tools", "jobserver", @@ -535,18 +534,18 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.49" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4512b90fa68d3a9932cea5184017c5d200f5921df706d45e853537dea51508f" +checksum = "c9e340e012a1bf4935f5282ed1436d1489548e8f72308207ea5df0e23d2d03f8" dependencies = [ "clap_builder", ] [[package]] name = "clap_builder" -version = "4.5.49" +version = "4.5.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0025e98baa12e766c67ba13ff4695a887a1eba19569aad00a472546795bd6730" +checksum = "d76b5d13eaa18c901fd2f7fca939fefe3a0727a953561fefdf3b2922b8569d00" dependencies = [ "anstyle", "clap_lex", @@ -926,9 +925,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -1052,9 +1051,9 @@ dependencies = [ [[package]] name = "dns-lookup" -version = "3.0.0" +version = "3.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "853d5bcf0b73bd5e6d945b976288621825c7166e9f06c5a035ae1aaf42d1b64f" +checksum = "6e39034cee21a2f5bbb66ba0e3689819c4bb5d00382a282006e802a7ffa6c41d" dependencies = [ "cfg-if", "libc", @@ -1174,9 +1173,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" +checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "flagset" @@ -1222,9 +1221,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "libz-rs-sys", @@ -1260,9 +1259,9 @@ checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -1270,9 +1269,9 @@ dependencies = [ [[package]] name = "get-size-derive2" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3814abc7da8ab18d2fd820f5b540b5e39b6af0a32de1bdd7c47576693074843" +checksum = "ff47daa61505c85af126e9dd64af6a342a33dc0cccfe1be74ceadc7d352e6efd" dependencies = [ "attribute-derive", "quote", @@ -1281,13 +1280,13 @@ dependencies = [ [[package]] name = "get-size2" -version = "0.7.0" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfe2cec5b5ce8fb94dcdb16a1708baa4d0609cc3ce305ca5d3f6f2ffb59baed" +checksum = "ac7bb8710e1f09672102be7ddf39f764d8440ae74a9f4e30aaa4820dcdffa4af" dependencies = [ "compact_str", "get-size-derive2", - "hashbrown 0.16.0", + "hashbrown 0.16.1", "smallvec", ] @@ -1374,9 +1373,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.16.0" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" +checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100" [[package]] name = "heck" @@ -1413,11 +1412,11 @@ dependencies = [ [[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]] @@ -1446,19 +1445,22 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6717a8d2a5a929a1a2eb43a12812498ed141a0bcfb7e8f7844fbdbe4303bba9f" +checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" dependencies = [ "equivalent", - "hashbrown 0.16.0", + "hashbrown 0.16.1", ] [[package]] name = "indoc" -version = "2.0.6" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +checksum = "79cf5c93f93228cf8efb3ba362535fb11199ac548a09ce117c9b1adc3030d706" +dependencies = [ + "rustversion", +] [[package]] name = "inout" @@ -1472,9 +1474,9 @@ dependencies = [ [[package]] name = "insta" -version = "1.43.2" +version = "1.44.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fdb647ebde000f43b5b53f773c30cf9b0cb4300453208713fa38b2c70935a0" +checksum = "dfd3461e1f00283105bdf97c3a1aca2b3f8456eb809a96938d2b190cd4dbc6d2" dependencies = [ "console", "once_cell", @@ -1501,9 +1503,9 @@ dependencies = [ [[package]] name = "is_terminal_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695" [[package]] name = "itertools" @@ -1531,22 +1533,22 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "jiff" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49" +checksum = "49cce2b81f2098e7e3efc35bc2e0a6b7abec9d34128283d7a26fa8f32a6dbb35" dependencies = [ "jiff-static", "log", "portable-atomic", "portable-atomic-util", - "serde", + "serde_core", ] [[package]] name = "jiff-static" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" +checksum = "980af8b43c3ad5d8d349ace167ec8170839f753a42d233ba19e08afe1850fa69" dependencies = [ "proc-macro2", "quote", @@ -1587,9 +1589,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.81" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +checksum = "b011eec8cc36da2aab2d5cff675ec18454fad408585853910a202391cf9f8e65" dependencies = [ "once_cell", "wasm-bindgen", @@ -1710,7 +1712,7 @@ version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "libc", ] @@ -1951,7 +1953,7 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "71e2746dc3a24dd78b3cfcb7be93368c6de9963d30f43a6a73998a9cf4b17b46" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -1964,7 +1966,7 @@ version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "cfg_aliases", "libc", @@ -2036,9 +2038,9 @@ dependencies = [ [[package]] name = "num_enum" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973b4e44ce6cad84ce69d797acf9a044532e4184c4f267913d1b546a0727b7a" +checksum = "b1207a7e20ad57b847bbddc6776b968420d38292bbfe2089accff5e19e82454c" dependencies = [ "num_enum_derive", "rustversion", @@ -2046,9 +2048,9 @@ dependencies = [ [[package]] name = "num_enum_derive" -version = "0.7.4" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77e878c846a8abae00dd069496dbe8751b16ac1c3d6bd2a7283a938e8228f90d" +checksum = "ff32365de1b6743cb203b710788263c44a03de03802daf96092f2da4fe6ba4d7" dependencies = [ "proc-macro2", "quote", @@ -2072,9 +2074,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" [[package]] name = "once_cell_polyfill" -version = "1.70.1" +version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad" +checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] name = "oorandom" @@ -2084,11 +2086,11 @@ checksum = "d6790f58c7ff633d8771f42965289203411a5e5c68388703c06e14f24770b41e" [[package]] name = "openssl" -version = "0.10.74" +version = "0.10.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ad14dd45412269e1a30f52ad8f0664f0f4f4a89ee8fe28c3b3527021ebb654" +checksum = "08838db121398ad17ab8531ce9de97b244589089e290a384c900cb9ff7434328" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "foreign-types", "libc", @@ -2116,18 +2118,18 @@ checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-src" -version = "300.5.3+3.5.4" +version = "300.5.4+3.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6bad8cd0233b63971e232cc9c5e83039375b8586d2312f31fda85db8f888c2" +checksum = "a507b3792995dae9b0df8a1c1e3771e8418b7c2d9f0baeba32e6fe8b06c7cb72" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.110" +version = "0.9.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a9f0075ba3c21b09f8e8b2026584b1d18d49388648f2fbbf3c97ea8deced8e2" +checksum = "82cab2d520aa75e3c58898289429321eb788c3106963d0dc886ec7a5f4adc321" dependencies = [ "cc", "libc", @@ -2419,9 +2421,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.101" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" +checksum = "5ee95bc4ef87b8d5ba32e8b7714ccc834865276eab0aed5c9958d00ec45f49e8" dependencies = [ "unicode-ident", ] @@ -2498,9 +2500,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.41" +version = "1.0.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce25767e7b499d1b604768e7cde645d14cc8584231ea6b295e9c9eb22c02e1d1" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" dependencies = [ "proc-macro2", ] @@ -2643,7 +2645,7 @@ version = "0.5.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", ] [[package]] @@ -2753,7 +2755,7 @@ version = "0.0.0" source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.1#2bffef59665ce7d2630dfd72ee99846663660db8" dependencies = [ "aho-corasick", - "bitflags 2.9.4", + "bitflags 2.10.0", "compact_str", "get-size2", "is-macro", @@ -2771,7 +2773,7 @@ name = "ruff_python_parser" version = "0.0.0" source = "git+https://github.com/astral-sh/ruff.git?tag=0.14.1#2bffef59665ce7d2630dfd72ee99846663660db8" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "bstr", "compact_str", "get-size2", @@ -2835,7 +2837,7 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "errno", "libc", "linux-raw-sys", @@ -2953,7 +2955,7 @@ name = "rustpython-codegen" version = "0.4.0" dependencies = [ "ahash", - "bitflags 2.9.4", + "bitflags 2.10.0", "indexmap", "insta", "itertools 0.14.0", @@ -2977,7 +2979,7 @@ name = "rustpython-common" version = "0.4.0" dependencies = [ "ascii", - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "getrandom 0.3.4", "itertools 0.14.0", @@ -3016,7 +3018,7 @@ dependencies = [ name = "rustpython-compiler-core" version = "0.4.0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "itertools 0.14.0", "lz4_flex", "malachite-bigint", @@ -3105,7 +3107,7 @@ dependencies = [ name = "rustpython-sre_engine" version = "0.4.0" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "criterion", "num_enum", "optional", @@ -3208,7 +3210,7 @@ version = "0.4.0" dependencies = [ "ahash", "ascii", - "bitflags 2.9.4", + "bitflags 2.10.0", "bstr", "caseless", "cfg-if", @@ -3319,7 +3321,7 @@ version = "17.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e902948a25149d50edc1a8e0141aad50f54e22ba83ff988cf8f7c9ef07f50564" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "cfg-if", "clipboard-win", "fd-lock", @@ -3406,7 +3408,7 @@ version = "3.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3297343eaf830f66ede390ea39da1d462b6b0c1b000f420d0a83f898bbbe6ef" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.10.1", "core-foundation-sys", "libc", @@ -3479,11 +3481,11 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.9" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3" +checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" dependencies = [ - "serde", + "serde_core", ] [[package]] @@ -3634,9 +3636,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.107" +version = "2.0.111" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a26dbd934e5451d21ef060c018dae56fc073894c5a7896f882928a76e6d081b" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" dependencies = [ "proc-macro2", "quote", @@ -3671,7 +3673,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.9.4", + "bitflags 2.10.0", "core-foundation 0.9.4", "system-configuration-sys", ] @@ -3870,44 +3872,42 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.23" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362" +checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" dependencies = [ - "serde", + "indexmap", + "serde_core", "serde_spanned", "toml_datetime", - "toml_edit", + "toml_parser", + "toml_writer", + "winnow", ] [[package]] name = "toml_datetime" -version = "0.6.11" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" +checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" dependencies = [ - "serde", + "serde_core", ] [[package]] -name = "toml_edit" -version = "0.22.27" +name = "toml_parser" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" dependencies = [ - "indexmap", - "serde", - "serde_spanned", - "toml_datetime", - "toml_write", "winnow", ] [[package]] -name = "toml_write" -version = "0.1.2" +name = "toml_writer" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" +checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" [[package]] name = "twox-hash" @@ -4055,15 +4055,15 @@ checksum = "061dbb8cc7f108532b6087a0065eff575e892a4bcb503dc57323a197457cc202" [[package]] name = "unicode-ident" -version = "1.0.19" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d" +checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" [[package]] name = "unicode-normalization" -version = "0.1.24" +version = "0.1.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +checksum = "5fd4f6878c9cb28d874b009da9e8d183b5abc80117c40bbd187a1fde336be6e8" dependencies = [ "tinyvec", ] @@ -4196,9 +4196,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +checksum = "da95793dfc411fbbd93f5be7715b0578ec61fe87cb1a42b12eb625caa5c5ea60" dependencies = [ "cfg-if", "once_cell", @@ -4207,25 +4207,11 @@ dependencies = [ "wasm-bindgen-shared", ] -[[package]] -name = "wasm-bindgen-backend" -version = "0.2.104" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" -dependencies = [ - "bumpalo", - "log", - "proc-macro2", - "quote", - "syn", - "wasm-bindgen-shared", -] - [[package]] name = "wasm-bindgen-futures" -version = "0.4.54" +version = "0.4.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" +checksum = "551f88106c6d5e7ccc7cd9a16f312dd3b5d36ea8b4954304657d5dfba115d4a0" dependencies = [ "cfg-if", "js-sys", @@ -4236,9 +4222,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +checksum = "04264334509e04a7bf8690f2384ef5265f05143a4bff3889ab7a3269adab59c2" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -4246,22 +4232,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +checksum = "420bc339d9f322e562942d52e115d57e950d12d88983a14c79b86859ee6c7ebc" dependencies = [ + "bumpalo", "proc-macro2", "quote", "syn", - "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.104" +version = "0.2.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +checksum = "76f218a38c84bcb33c25ec7059b07847d465ce0e0a76b995e134a45adcb6af76" dependencies = [ "unicode-ident", ] @@ -4280,9 +4266,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.81" +version = "0.3.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +checksum = "3a1f95c0d03a47f4ae1f7a64643a6bb97465d9b740f0fa8f90ea33915c99a9a1" dependencies = [ "js-sys", "wasm-bindgen", @@ -4684,12 +4670,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "0.7.13" +version = "0.7.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" -dependencies = [ - "memchr", -] +checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829" [[package]] name = "winreg" @@ -4703,9 +4686,9 @@ dependencies = [ [[package]] name = "winresource" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edcacf11b6f48dd21b9ba002f991bdd5de29b2da8cc2800412f4b80f677e4957" +checksum = "f1ef04dd590e94ff7431a8eda99d5ca659e688d60e930bd0a330062acea4608f" dependencies = [ "toml", "version_check", @@ -4771,18 +4754,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.27" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c" +checksum = "4ea879c944afe8a2b25fef16bb4ba234f47c694565e97383b36f3a878219065c" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.27" +version = "0.8.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831" +checksum = "cf955aa904d6040f70dc8e9384444cb1030aed272ba3cb09bbc4ab9e7c1f34f5" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 53d1eb6ea2..8993ce145f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -175,7 +175,7 @@ insta = "1.42" itertools = "0.14.0" is-macro = "0.3.7" junction = "1.3.0" -libc = "0.2.169" +libc = "0.2.177" libffi = "4.1" log = "0.4.28" nix = { version = "0.30", features = ["fs", "user", "process", "term", "time", "signal", "ioctl", "socket", "sched", "zerocopy", "dir", "hostname", "net", "poll"] } From 081a8f0451317f776388c5160d67db51fd2fa1bd Mon Sep 17 00:00:00 2001 From: ShaharNaveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Thu, 27 Nov 2025 17:16:42 +0200 Subject: [PATCH 002/520] Regenerate libc constatnts --- crates/vm/src/stdlib/posix.rs | 6 +++--- scripts/libc_posix.py | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/vm/src/stdlib/posix.rs b/crates/vm/src/stdlib/posix.rs index e8a01d0e68..071f93d7ee 100644 --- a/crates/vm/src/stdlib/posix.rs +++ b/crates/vm/src/stdlib/posix.rs @@ -202,8 +202,7 @@ pub mod module { #[pyattr] use libc::{ CLD_CONTINUED, CLD_DUMPED, CLD_EXITED, CLD_KILLED, CLD_STOPPED, CLD_TRAPPED, F_LOCK, - F_TEST, F_TLOCK, F_ULOCK, O_NDELAY, O_NOCTTY, O_SYNC, P_ALL, P_PGID, P_PID, SCHED_FIFO, - SCHED_RR, + F_TEST, F_TLOCK, F_ULOCK, O_SYNC, P_ALL, P_PGID, P_PID, SCHED_FIFO, SCHED_RR, }; #[cfg(any( @@ -217,7 +216,8 @@ pub mod module { target_os = "redox" ))] #[pyattr] - use libc::{O_ASYNC, WEXITED, WNOWAIT, WSTOPPED}; + use libc::{O_ASYNC, O_NDELAY, O_NOCTTY, WEXITED, WNOWAIT, WSTOPPED}; + #[pyattr] const EX_OK: i8 = exitcode::OK as i8; diff --git a/scripts/libc_posix.py b/scripts/libc_posix.py index 9ed6890e70..73f082a065 100644 --- a/scripts/libc_posix.py +++ b/scripts/libc_posix.py @@ -13,7 +13,7 @@ ) # TODO: Exclude matches if they have `(` after (those are functions) -LIBC_VERSION = "0.2.175" +LIBC_VERSION = "0.2.177" EXCLUDE = frozenset( { From 1b3261a090b4331cfcc60e8bad2ced92f0f8fb28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 28 Nov 2025 08:39:46 +0900 Subject: [PATCH 003/520] Bump node-forge from 1.3.1 to 1.3.2 in /wasm/demo (#6297) Bumps [node-forge](https://github.com/digitalbazaar/forge) from 1.3.1 to 1.3.2. - [Changelog](https://github.com/digitalbazaar/forge/blob/main/CHANGELOG.md) - [Commits](https://github.com/digitalbazaar/forge/compare/v1.3.1...v1.3.2) --- updated-dependencies: - dependency-name: node-forge dependency-version: 1.3.2 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- wasm/demo/package-lock.json | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/wasm/demo/package-lock.json b/wasm/demo/package-lock.json index e3cf79298a..3acc105e3c 100644 --- a/wasm/demo/package-lock.json +++ b/wasm/demo/package-lock.json @@ -775,7 +775,8 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.5.0.tgz", "integrity": "sha512-hqJHYaQb5OptNunnyAnkHyM8aCjZ1MEIDTQu1iIbbTD/xops91NB5yq1ZK/dC2JDbVWtF23zUtl9JE2NqwT87A==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", @@ -831,6 +832,7 @@ "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.3", "fast-uri": "^3.0.1", @@ -1149,6 +1151,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", @@ -3495,9 +3498,9 @@ } }, "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.2.tgz", + "integrity": "sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw==", "dev": true, "license": "(BSD-3-Clause OR GPL-2.0)", "engines": { @@ -3824,6 +3827,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.8", "picocolors": "^1.1.1", @@ -5082,7 +5086,8 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "dev": true, - "license": "0BSD" + "license": "0BSD", + "peer": true }, "node_modules/type-fest": { "version": "2.19.0", @@ -5266,6 +5271,7 @@ "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.7", "@types/estree": "^1.0.6", @@ -5313,6 +5319,7 @@ "integrity": "sha512-MfwFQ6SfwinsUVi0rNJm7rHZ31GyTcpVE5pgVA3hwFRb7COD4TzjUUwhGWKfO50+xdc2MQPuEBBJoqIMGt3JDw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@discoveryjs/json-ext": "^0.6.1", "@webpack-cli/configtest": "^3.0.1", From 0e6e256f8e1448411d7c86d5fa23ec3fe72f4296 Mon Sep 17 00:00:00 2001 From: Wildan M Date: Fri, 28 Nov 2025 06:41:22 +0700 Subject: [PATCH 004/520] Fix redox compilation in stdlib (#6298) --- crates/stdlib/src/posixsubprocess.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/stdlib/src/posixsubprocess.rs b/crates/stdlib/src/posixsubprocess.rs index 7f418c8993..4da6a6858d 100644 --- a/crates/stdlib/src/posixsubprocess.rs +++ b/crates/stdlib/src/posixsubprocess.rs @@ -441,15 +441,14 @@ fn close_dir_fds(keep: KeepFds<'_>) -> nix::Result<()> { fn close_filetable_fds(keep: KeepFds<'_>) -> nix::Result<()> { use nix::fcntl; use std::os::fd::{FromRawFd, OwnedFd}; - let fd = fcntl::open( + let filetable = fcntl::open( c"/scheme/thisproc/current/filetable", fcntl::OFlag::O_RDONLY, nix::sys::stat::Mode::empty(), )?; - let filetable = unsafe { OwnedFd::from_raw_fd(fd) }; let read_one = || -> nix::Result<_> { let mut byte = 0; - let n = nix::unistd::read(filetable.as_raw_fd(), std::slice::from_mut(&mut byte))?; + let n = nix::unistd::read(&filetable, std::slice::from_mut(&mut byte))?; Ok((n > 0).then_some(byte)) }; while let Some(c) = read_one()? { From f37ea525650d975a8a87fa8052e1785612684ab1 Mon Sep 17 00:00:00 2001 From: Ashwin Naren Date: Mon, 31 Mar 2025 21:42:54 -0700 Subject: [PATCH 005/520] Ctypes more pointer implementation fix import add more classes ctypes overhall updates fix build fix warnings, pass test fix panic on improper library load test on macos formatting tmp minor updates --- crates/vm/src/stdlib/ctypes.rs | 11 +- crates/vm/src/stdlib/ctypes/array.rs | 1 + crates/vm/src/stdlib/ctypes/base.rs | 22 +- crates/vm/src/stdlib/ctypes/field.rs | 134 ++++++++ crates/vm/src/stdlib/ctypes/function.rs | 386 +++++++++++++++--------- crates/vm/src/stdlib/ctypes/pointer.rs | 41 ++- crates/vm/src/stdlib/ctypes/thunk.rs | 22 ++ crates/vm/src/stdlib/ctypes/util.rs | 24 ++ extra_tests/snippets/stdlib_ctypes.py | 11 +- 9 files changed, 491 insertions(+), 161 deletions(-) create mode 100644 crates/vm/src/stdlib/ctypes/field.rs create mode 100644 crates/vm/src/stdlib/ctypes/thunk.rs create mode 100644 crates/vm/src/stdlib/ctypes/util.rs diff --git a/crates/vm/src/stdlib/ctypes.rs b/crates/vm/src/stdlib/ctypes.rs index 8ea4dd165e..ac74418354 100644 --- a/crates/vm/src/stdlib/ctypes.rs +++ b/crates/vm/src/stdlib/ctypes.rs @@ -2,11 +2,14 @@ pub(crate) mod array; pub(crate) mod base; +pub(crate) mod field; pub(crate) mod function; pub(crate) mod library; pub(crate) mod pointer; pub(crate) mod structure; +pub(crate) mod thunk; pub(crate) mod union; +pub(crate) mod util; use crate::builtins::PyModule; use crate::class::PyClassImpl; @@ -17,14 +20,18 @@ pub fn extend_module_nodes(vm: &VirtualMachine, module: &Py) { let ctx = &vm.ctx; PyCSimpleType::make_class(ctx); array::PyCArrayType::make_class(ctx); + field::PyCFieldType::make_class(ctx); + pointer::PyCPointerType::make_class(ctx); extend_module!(vm, module, { "_CData" => PyCData::make_class(ctx), "_SimpleCData" => PyCSimple::make_class(ctx), "Array" => array::PyCArray::make_class(ctx), + "CField" => field::PyCField::make_class(ctx), "CFuncPtr" => function::PyCFuncPtr::make_class(ctx), "_Pointer" => pointer::PyCPointer::make_class(ctx), "_pointer_type_cache" => ctx.new_dict(), "Structure" => structure::PyCStructure::make_class(ctx), + "CThunkObject" => thunk::PyCThunk::make_class(ctx), "Union" => union::PyCUnion::make_class(ctx), }) } @@ -207,7 +214,9 @@ pub(crate) mod _ctypes { // TODO: load_flags let cache = library::libcache(); let mut cache_write = cache.write(); - let (id, _) = cache_write.get_or_insert_lib(&name, vm).unwrap(); + let (id, _) = cache_write + .get_or_insert_lib(&name, vm) + .map_err(|e| vm.new_os_error(e.to_string()))?; Ok(id) } diff --git a/crates/vm/src/stdlib/ctypes/array.rs b/crates/vm/src/stdlib/ctypes/array.rs index 5290ec42f3..a1adf847a9 100644 --- a/crates/vm/src/stdlib/ctypes/array.rs +++ b/crates/vm/src/stdlib/ctypes/array.rs @@ -106,6 +106,7 @@ impl PyCArray { } impl PyCArray { + #[allow(unused)] pub fn to_arg(&self, _vm: &VirtualMachine) -> PyResult { let value = self.value.read(); let py_bytes = value.downcast_ref::().unwrap(); diff --git a/crates/vm/src/stdlib/ctypes/base.rs b/crates/vm/src/stdlib/ctypes/base.rs index 23cb505ada..f5a25ad740 100644 --- a/crates/vm/src/stdlib/ctypes/base.rs +++ b/crates/vm/src/stdlib/ctypes/base.rs @@ -276,25 +276,25 @@ impl PyCSimple { let value = unsafe { (*self.value.as_ptr()).clone() }; if let Ok(i) = value.try_int(vm) { let i = i.as_bigint(); - if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::u8().as_raw_ptr()) { - return i.to_u8().map(|r: u8| libffi::middle::Arg::new(&r)); + return if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::u8().as_raw_ptr()) { + i.to_u8().map(|r: u8| libffi::middle::Arg::new(&r)) } else if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::i8().as_raw_ptr()) { - return i.to_i8().map(|r: i8| libffi::middle::Arg::new(&r)); + i.to_i8().map(|r: i8| libffi::middle::Arg::new(&r)) } else if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::u16().as_raw_ptr()) { - return i.to_u16().map(|r: u16| libffi::middle::Arg::new(&r)); + i.to_u16().map(|r: u16| libffi::middle::Arg::new(&r)) } else if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::i16().as_raw_ptr()) { - return i.to_i16().map(|r: i16| libffi::middle::Arg::new(&r)); + i.to_i16().map(|r: i16| libffi::middle::Arg::new(&r)) } else if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::u32().as_raw_ptr()) { - return i.to_u32().map(|r: u32| libffi::middle::Arg::new(&r)); + i.to_u32().map(|r: u32| libffi::middle::Arg::new(&r)) } else if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::i32().as_raw_ptr()) { - return i.to_i32().map(|r: i32| libffi::middle::Arg::new(&r)); + i.to_i32().map(|r: i32| libffi::middle::Arg::new(&r)) } else if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::u64().as_raw_ptr()) { - return i.to_u64().map(|r: u64| libffi::middle::Arg::new(&r)); + i.to_u64().map(|r: u64| libffi::middle::Arg::new(&r)) } else if std::ptr::eq(ty.as_raw_ptr(), libffi::middle::Type::i64().as_raw_ptr()) { - return i.to_i64().map(|r: i64| libffi::middle::Arg::new(&r)); + i.to_i64().map(|r: i64| libffi::middle::Arg::new(&r)) } else { - return None; - } + None + }; } if let Ok(_f) = value.try_float(vm) { todo!(); diff --git a/crates/vm/src/stdlib/ctypes/field.rs b/crates/vm/src/stdlib/ctypes/field.rs new file mode 100644 index 0000000000..b50b8b54ac --- /dev/null +++ b/crates/vm/src/stdlib/ctypes/field.rs @@ -0,0 +1,134 @@ +use crate::builtins::PyType; +use crate::builtins::PyTypeRef; +use crate::stdlib::ctypes::PyCData; +use crate::types::Constructor; +use crate::types::Representable; +use crate::{Py, PyResult, VirtualMachine}; + +#[pyclass(name = "PyCFieldType", base = PyType, module = "_ctypes")] +#[derive(PyPayload, Debug)] +pub struct PyCFieldType { + pub(super) inner: PyCField, +} + +#[pyclass] +impl PyCFieldType {} + +#[pyclass( + name = "CField", + base = PyCData, + metaclass = "PyCFieldType", + module = "_ctypes" +)] +#[derive(Debug, PyPayload)] +pub struct PyCField { + byte_offset: usize, + byte_size: usize, + #[allow(unused)] + index: usize, + proto: PyTypeRef, + anonymous: bool, + bitfield_size: bool, + bit_offset: u8, + name: String, +} + +impl Representable for PyCField { + fn repr_str(zelf: &Py, _vm: &VirtualMachine) -> PyResult { + let tp_name = zelf.proto.name().to_string(); + if zelf.bitfield_size != false { + Ok(format!( + "<{} type={}, ofs={byte_offset}, bit_size={bitfield_size}, bit_offset={bit_offset}", + zelf.name, + tp_name, + byte_offset = zelf.byte_offset, + bitfield_size = zelf.bitfield_size, + bit_offset = zelf.bit_offset + )) + } else { + Ok(format!( + "<{} type={tp_name}, ofs={}, size={}", + zelf.name, zelf.byte_offset, zelf.byte_size + )) + } + } +} + +#[derive(Debug, FromArgs)] +pub struct PyCFieldConstructorArgs { + // PyObject *name, PyObject *proto, + // Py_ssize_t byte_size, Py_ssize_t byte_offset, + // Py_ssize_t index, int _internal_use, + // PyObject *bit_size_obj, PyObject *bit_offset_obj +} + +impl Constructor for PyCField { + type Args = PyCFieldConstructorArgs; + + fn py_new(_cls: PyTypeRef, _args: Self::Args, vm: &VirtualMachine) -> PyResult { + Err(vm.new_type_error("Cannot instantiate a PyCField".to_string())) + } +} + +#[pyclass(flags(BASETYPE, IMMUTABLETYPE), with(Constructor, Representable))] +impl PyCField { + #[pygetset] + fn size(&self) -> usize { + self.byte_size + } + + #[pygetset] + fn bit_size(&self) -> bool { + self.bitfield_size + } + + #[pygetset] + fn is_bitfield(&self) -> bool { + self.bitfield_size + } + + #[pygetset] + fn is_anonymous(&self) -> bool { + self.anonymous + } + + #[pygetset] + fn name(&self) -> String { + self.name.clone() + } + + #[pygetset(name = "type")] + fn type_(&self) -> PyTypeRef { + self.proto.clone() + } + + #[pygetset] + fn offset(&self) -> usize { + self.byte_offset + } + + #[pygetset] + fn byte_offset(&self) -> usize { + self.byte_offset + } + + #[pygetset] + fn byte_size(&self) -> usize { + self.byte_size + } + + #[pygetset] + fn bit_offset(&self) -> u8 { + self.bit_offset + } +} + +#[inline(always)] +pub const fn low_bit(offset: usize) -> usize { + offset & 0xFFFF +} + +#[inline(always)] +pub const fn high_bit(offset: usize) -> usize { + offset >> 16 +} diff --git a/crates/vm/src/stdlib/ctypes/function.rs b/crates/vm/src/stdlib/ctypes/function.rs index 6703dcc0f5..88d0fbb35e 100644 --- a/crates/vm/src/stdlib/ctypes/function.rs +++ b/crates/vm/src/stdlib/ctypes/function.rs @@ -1,142 +1,117 @@ // spell-checker:disable -use crate::builtins::{PyStr, PyTupleRef, PyTypeRef}; +use crate::builtins::{PyNone, PyStr, PyTuple, PyTupleRef, PyType, PyTypeRef}; use crate::convert::ToPyObject; use crate::function::FuncArgs; use crate::stdlib::ctypes::PyCData; -use crate::stdlib::ctypes::array::PyCArray; use crate::stdlib::ctypes::base::{PyCSimple, ffi_type_from_str}; +use crate::types::Representable; use crate::types::{Callable, Constructor}; -use crate::{Py, PyObjectRef, PyResult, VirtualMachine}; +use crate::{AsObject, Py, PyObjectRef, PyPayload, PyResult, VirtualMachine}; use crossbeam_utils::atomic::AtomicCell; use libffi::middle::{Arg, Cif, CodePtr, Type}; use libloading::Symbol; use num_traits::ToPrimitive; use rustpython_common::lock::PyRwLock; -use std::ffi::CString; +use std::ffi::{self, CString, c_void}; use std::fmt::Debug; -// https://github.com/python/cpython/blob/4f8bb3947cfbc20f970ff9d9531e1132a9e95396/Modules/_ctypes/callproc.c#L15 +// See also: https://github.com/python/cpython/blob/4f8bb3947cfbc20f970ff9d9531e1132a9e95396/Modules/_ctypes/callproc.c#L15 -#[derive(Debug)] -pub struct Function { - args: Vec, - // TODO: no protection from use-after-free - pointer: CodePtr, - cif: Cif, +type FP = unsafe extern "C" fn(); + +pub trait ArgumentType { + fn to_ffi_type(&self, vm: &VirtualMachine) -> PyResult; + fn convert_object(&self, value: PyObjectRef, vm: &VirtualMachine) -> PyResult; } -unsafe impl Send for Function {} -unsafe impl Sync for Function {} +impl ArgumentType for PyTypeRef { + fn to_ffi_type(&self, vm: &VirtualMachine) -> PyResult { + let typ = self + .get_class_attr(vm.ctx.intern_str("_type_")) + .ok_or(vm.new_type_error("Unsupported argument type".to_string()))?; + let typ = typ + .downcast_ref::() + .ok_or(vm.new_type_error("Unsupported argument type".to_string()))?; + let typ = typ.to_string(); + let typ = typ.as_str(); + let converted_typ = ffi_type_from_str(typ); + if let Some(typ) = converted_typ { + Ok(typ) + } else { + Err(vm.new_type_error(format!("Unsupported argument type: {}", typ))) + } + } -type FP = unsafe extern "C" fn(); + fn convert_object(&self, value: PyObjectRef, vm: &VirtualMachine) -> PyResult { + // if self.fast_isinstance::(vm) { + // let array = value.downcast::()?; + // return Ok(Arg::from(array.as_ptr())); + // } + if let Ok(simple) = value.downcast::() { + let typ = ArgumentType::to_ffi_type(self, vm)?; + let arg = simple + .to_arg(typ, vm) + .ok_or(vm.new_type_error("Unsupported argument type".to_string()))?; + return Ok(arg); + } + Err(vm.new_type_error("Unsupported argument type".to_string())) + } +} -impl Function { - pub unsafe fn load( - library: &libloading::Library, - function: &str, - args: &[PyObjectRef], - ret_type: &Option, +pub trait ReturnType { + fn to_ffi_type(&self) -> Option; + fn from_ffi_type( + &self, + value: *mut ffi::c_void, vm: &VirtualMachine, - ) -> PyResult { - // map each arg to a PyCSimple - let args = args - .iter() - .map(|arg| { - if let Some(arg) = arg.downcast_ref::() { - let converted = ffi_type_from_str(&arg._type_); - return match converted { - Some(t) => Ok(t), - None => Err(vm.new_type_error("Invalid type")), // TODO: add type name - }; - } - if let Some(arg) = arg.downcast_ref::() { - let t = arg.typ.read(); - let ty_attributes = t.attributes.read(); - let ty_pystr = ty_attributes - .get(vm.ctx.intern_str("_type_")) - .ok_or_else(|| vm.new_type_error("Expected a ctypes simple type"))?; - let ty_str = ty_pystr - .downcast_ref::() - .ok_or_else(|| vm.new_type_error("Expected a ctypes simple type"))? - .to_string(); - let converted = ffi_type_from_str(&ty_str); - match converted { - Some(_t) => { - // TODO: Use - Ok(Type::void()) - } - None => Err(vm.new_type_error("Invalid type")), // TODO: add type name - } - } else { - Err(vm.new_type_error("Expected a ctypes simple type")) - } - }) - .collect::>>()?; - let c_function_name = CString::new(function) - .map_err(|_| vm.new_value_error("Function name contains null bytes"))?; - let pointer: Symbol<'_, FP> = unsafe { - library - .get(c_function_name.as_bytes()) - .map_err(|err| err.to_string()) - .map_err(|err| vm.new_attribute_error(err))? - }; - let code_ptr = CodePtr(*pointer as *mut _); - let return_type = match ret_type { - // TODO: Fix this - Some(_t) => { - return Err(vm.new_not_implemented_error("Return type not implemented")); - } - None => Type::c_int(), - }; - let cif = Cif::new(args.clone(), return_type); - Ok(Function { - args, - cif, - pointer: code_ptr, - }) + ) -> PyResult>; +} + +impl ReturnType for PyTypeRef { + fn to_ffi_type(&self) -> Option { + ffi_type_from_str(self.name().to_string().as_str()) } - pub unsafe fn call( + fn from_ffi_type( &self, - args: Vec, - vm: &VirtualMachine, - ) -> PyResult { - let args = args - .into_iter() - .enumerate() - .map(|(count, arg)| { - // none type check - if let Some(d) = arg.downcast_ref::() { - return Ok(d.to_arg(self.args[count].clone(), vm).unwrap()); - } - if let Some(d) = arg.downcast_ref::() { - return Ok(d.to_arg(vm).unwrap()); - } - Err(vm.new_type_error("Expected a ctypes simple type")) - }) - .collect::>>()?; - // TODO: FIX return - let result: i32 = unsafe { self.cif.call(self.pointer, &args) }; - Ok(vm.ctx.new_int(result).into()) + _value: *mut ffi::c_void, + _vm: &VirtualMachine, + ) -> PyResult> { + todo!() + } +} + +impl ReturnType for PyNone { + fn to_ffi_type(&self) -> Option { + ffi_type_from_str("void") + } + + fn from_ffi_type( + &self, + _value: *mut ffi::c_void, + _vm: &VirtualMachine, + ) -> PyResult> { + Ok(None) } } #[pyclass(module = "_ctypes", name = "CFuncPtr", base = PyCData)] #[derive(PyPayload)] pub struct PyCFuncPtr { - pub name: PyRwLock, - pub _flags_: AtomicCell, - // FIXME(arihant2math): This shouldn't be an option, setting the default as the none type should work - // This is a workaround for now and I'll fix it later - pub _restype_: PyRwLock>, + pub name: PyRwLock>, + pub ptr: PyRwLock>, + pub needs_free: AtomicCell, + pub arg_types: PyRwLock>>, + pub res_type: PyRwLock>, + pub _flags_: AtomicCell, pub handler: PyObjectRef, } impl Debug for PyCFuncPtr { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("PyCFuncPtr") - .field("name", &self.name) + .field("flags", &self._flags_) .finish() } } @@ -156,10 +131,43 @@ impl Constructor for PyCFuncPtr { .nth(1) .ok_or(vm.new_type_error("Expected a tuple with at least 2 elements"))? .clone(); + let handle = handler.try_int(vm); + let handle = match handle { + Ok(handle) => handle.as_bigint().clone(), + Err(_) => handler + .get_attr("_handle", vm)? + .try_int(vm)? + .as_bigint() + .clone(), + }; + let library_cache = crate::stdlib::ctypes::library::libcache().read(); + let library = library_cache + .get_lib( + handle + .to_usize() + .ok_or(vm.new_value_error("Invalid handle".to_string()))?, + ) + .ok_or_else(|| vm.new_value_error("Library not found".to_string()))?; + let inner_lib = library.lib.lock(); + + let terminated = format!("{}\0", &name); + let code_ptr = if let Some(lib) = &*inner_lib { + let pointer: Symbol<'_, FP> = unsafe { + lib.get(terminated.as_bytes()) + .map_err(|err| err.to_string()) + .map_err(|err| vm.new_attribute_error(err))? + }; + Some(CodePtr(*pointer as *mut _)) + } else { + None + }; Ok(Self { + ptr: PyRwLock::new(code_ptr), + needs_free: AtomicCell::new(false), + arg_types: PyRwLock::new(None), _flags_: AtomicCell::new(0), - name: PyRwLock::new(name), - _restype_: PyRwLock::new(None), + res_type: PyRwLock::new(None), + name: PyRwLock::new(Some(name)), handler, } .to_pyobject(vm)) @@ -169,53 +177,145 @@ impl Constructor for PyCFuncPtr { impl Callable for PyCFuncPtr { type Args = FuncArgs; fn call(zelf: &Py, args: Self::Args, vm: &VirtualMachine) -> PyResult { - unsafe { - let handle = zelf.handler.get_attr("_handle", vm)?; - let handle = handle.try_int(vm)?.as_bigint().clone(); - let library_cache = crate::stdlib::ctypes::library::libcache().read(); - let library = library_cache - .get_lib( - handle - .to_usize() - .ok_or(vm.new_value_error("Invalid handle"))?, - ) - .ok_or_else(|| vm.new_value_error("Library not found"))?; - let inner_lib = library.lib.lock(); - let name = zelf.name.read(); - let res_type = zelf._restype_.read(); - let func = Function::load( - inner_lib - .as_ref() - .ok_or_else(|| vm.new_value_error("Library not found"))?, - &name, - &args.args, - &res_type, - vm, - )?; - func.call(args.args, vm) + // This is completely seperate from the C python implementation + + // Cif init + let arg_types: Vec<_> = match zelf.arg_types.read().clone() { + Some(tys) => tys, + None => args + .args + .clone() + .into_iter() + .map(|a| a.class().as_object().to_pyobject(vm).downcast().unwrap()) + .collect(), + }; + let ffi_arg_types = arg_types + .clone() + .iter() + .map(|t| ArgumentType::to_ffi_type(t, vm)) + .collect::>>()?; + let return_type = zelf.res_type.read(); + let ffi_return_type = return_type + .as_ref() + .map(|t| ReturnType::to_ffi_type(&t.clone().downcast::().unwrap())) + .flatten() + .unwrap_or_else(|| Type::i32()); + let cif = Cif::new(ffi_arg_types, ffi_return_type); + + // Call the function + let ffi_args = args + .args + .into_iter() + .enumerate() + .map(|(n, arg)| { + let arg_type = arg_types + .get(n) + .ok_or_else(|| vm.new_type_error("argument amount mismatch".to_string()))?; + arg_type.convert_object(arg, vm) + }) + .collect::, _>>()?; + let pointer = zelf.ptr.read(); + let code_ptr = pointer + .as_ref() + .ok_or_else(|| vm.new_type_error("Function pointer not set".to_string()))?; + let mut output: c_void = unsafe { cif.call(*code_ptr, &ffi_args) }; + let return_type = return_type + .as_ref() + .map(|f| { + f.clone() + .downcast::() + .unwrap() + .from_ffi_type(&mut output, vm) + .ok() + .flatten() + }) + .unwrap_or_else(|| Some(vm.ctx.new_int(output as i32).as_object().to_pyobject(vm))); + if let Some(return_type) = return_type { + Ok(return_type) + } else { + Ok(vm.ctx.none()) } } } -#[pyclass(flags(BASETYPE), with(Callable, Constructor))] -impl PyCFuncPtr { - #[pygetset] - fn __name__(&self) -> String { - self.name.read().clone() +impl Representable for PyCFuncPtr { + fn repr_str(zelf: &Py, _vm: &VirtualMachine) -> PyResult { + let index = zelf.ptr.read(); + let index = index.map(|ptr| ptr.0 as usize).unwrap_or(0); + let type_name = zelf.class().name(); + #[cfg(windows)] + { + let index = index - 0x1000; + return Ok(format!("")); + } + Ok(format!("<{type_name} object at {index:#x}>")) } +} - #[pygetset(setter)] - fn set___name__(&self, name: String) { - *self.name.write() = name; - } +// TODO: fix +unsafe impl Send for PyCFuncPtr {} +unsafe impl Sync for PyCFuncPtr {} +#[pyclass(flags(BASETYPE), with(Callable, Constructor, Representable))] +impl PyCFuncPtr { #[pygetset(name = "_restype_")] - fn restype(&self) -> Option { - self._restype_.read().as_ref().cloned() + fn restype(&self) -> Option { + self.res_type.read().as_ref().cloned() } #[pygetset(name = "_restype_", setter)] - fn set_restype(&self, restype: PyTypeRef) { - *self._restype_.write() = Some(restype); + fn set_restype(&self, restype: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + // has to be type, callable, or none + // TODO: Callable support + if vm.is_none(&restype) || restype.downcast_ref::().is_some() { + *self.res_type.write() = Some(restype); + Ok(()) + } else { + Err(vm.new_type_error("restype must be a type, a callable, or None".to_string())) + } + } + + #[pygetset(name = "argtypes")] + fn argtypes(&self, vm: &VirtualMachine) -> PyTupleRef { + PyTuple::new_ref( + self.arg_types + .read() + .clone() + .unwrap_or_default() + .into_iter() + .map(|t| t.to_pyobject(vm)) + .collect(), + &vm.ctx, + ) + } + + #[pygetset(name = "argtypes", setter)] + fn set_argtypes(&self, argtypes: PyObjectRef, vm: &VirtualMachine) -> PyResult<()> { + let none = vm.is_none(&argtypes); + if none { + *self.arg_types.write() = None; + Ok(()) + } else { + let tuple = argtypes.downcast::().unwrap(); + *self.arg_types.write() = Some( + tuple + .iter() + .map(|obj| obj.clone().downcast::().unwrap()) + .collect::>(), + ); + Ok(()) + } + } + + #[pygetset] + fn __name__(&self) -> Option { + self.name.read().clone() + } + + #[pygetset(setter)] + fn set___name__(&self, name: String) -> PyResult<()> { + *self.name.write() = Some(name); + // TODO: update handle and stuff + Ok(()) } } diff --git a/crates/vm/src/stdlib/ctypes/pointer.rs b/crates/vm/src/stdlib/ctypes/pointer.rs index d1360f9862..e072312562 100644 --- a/crates/vm/src/stdlib/ctypes/pointer.rs +++ b/crates/vm/src/stdlib/ctypes/pointer.rs @@ -1,5 +1,40 @@ -#[pyclass(name = "Pointer", module = "_ctypes")] -pub struct PyCPointer {} +use rustpython_common::lock::PyRwLock; + +use crate::builtins::PyType; +use crate::stdlib::ctypes::PyCData; +use crate::{PyObjectRef, PyResult}; + +#[pyclass(name = "PyCPointerType", base = PyType, module = "_ctypes")] +#[derive(PyPayload, Debug)] +pub struct PyCPointerType { + pub inner: PyCPointer, +} + +#[pyclass] +impl PyCPointerType {} + +#[pyclass( + name = "_Pointer", + base = PyCData, + metaclass = "PyCPointerType", + module = "_ctypes" +)] +#[derive(Debug, PyPayload)] +pub struct PyCPointer { + contents: PyRwLock, +} #[pyclass(flags(BASETYPE, IMMUTABLETYPE))] -impl PyCPointer {} +impl PyCPointer { + // TODO: not correct + #[pygetset] + fn contents(&self) -> PyResult { + let contents = self.contents.read().clone(); + Ok(contents) + } + #[pygetset(setter)] + fn set_contents(&self, contents: PyObjectRef) -> PyResult<()> { + *self.contents.write() = contents; + Ok(()) + } +} diff --git a/crates/vm/src/stdlib/ctypes/thunk.rs b/crates/vm/src/stdlib/ctypes/thunk.rs new file mode 100644 index 0000000000..a65b04684b --- /dev/null +++ b/crates/vm/src/stdlib/ctypes/thunk.rs @@ -0,0 +1,22 @@ +//! Yes, really, this is not a typo. + +// typedef struct { +// PyObject_VAR_HEAD +// ffi_closure *pcl_write; /* the C callable, writeable */ +// void *pcl_exec; /* the C callable, executable */ +// ffi_cif cif; +// int flags; +// PyObject *converters; +// PyObject *callable; +// PyObject *restype; +// SETFUNC setfunc; +// ffi_type *ffi_restype; +// ffi_type *atypes[1]; +// } CThunkObject; + +#[pyclass(name = "CThunkObject", module = "_ctypes")] +#[derive(Debug, PyPayload)] +pub struct PyCThunk {} + +#[pyclass] +impl PyCThunk {} diff --git a/crates/vm/src/stdlib/ctypes/util.rs b/crates/vm/src/stdlib/ctypes/util.rs new file mode 100644 index 0000000000..df5d318668 --- /dev/null +++ b/crates/vm/src/stdlib/ctypes/util.rs @@ -0,0 +1,24 @@ +use crate::PyObjectRef; + +#[pyclass(name, module = "_ctypes")] +#[derive(Debug, PyPayload)] +pub struct StgInfo { + pub initialized: i32, + pub size: usize, // number of bytes + pub align: usize, // alignment requirements + pub length: usize, // number of fields + // ffi_type_pointer: ffi::ffi_type, + pub proto: PyObjectRef, // Only for Pointer/ArrayObject + pub setfunc: Option, // Only for simple objects + pub getfunc: Option, // Only for simple objects + pub paramfunc: Option, + + /* Following fields only used by PyCFuncPtrType_Type instances */ + pub argtypes: Option, // tuple of CDataObjects + pub converters: Option, // tuple([t.from_param for t in argtypes]) + pub restype: Option, // CDataObject or NULL + pub checker: Option, + pub module: Option, + pub flags: i32, // calling convention and such + pub dict_final: u8, +} diff --git a/extra_tests/snippets/stdlib_ctypes.py b/extra_tests/snippets/stdlib_ctypes.py index 32ed17d19f..3ef6df689f 100644 --- a/extra_tests/snippets/stdlib_ctypes.py +++ b/extra_tests/snippets/stdlib_ctypes.py @@ -40,7 +40,6 @@ def create_string_buffer(init, size=None): size = len(init) + 1 _sys.audit("ctypes.create_string_buffer", init, size) buftype = c_char.__mul__(size) - print(type(c_char.__mul__(size))) # buftype = c_char * size buf = buftype() buf.value = init @@ -334,8 +333,14 @@ def LoadLibrary(self, name): test_byte_array = create_string_buffer(b"Hello, World!\n") assert test_byte_array._length_ == 15 -if _os.name == "posix" or _sys.platform == "darwin": - pass +if _os.name == "posix": + if _sys.platform == "darwin": + libc = cdll.LoadLibrary("libc.dylib") + libc.rand() + i = c_int(1) + print("start srand") + print(libc.srand(i)) + print(test_byte_array) else: import os From 14cf4e32d04b234549fae3ae0dddb0b34a09f76a Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Fri, 28 Nov 2025 23:41:42 +0900 Subject: [PATCH 006/520] Fix PyCSimple --- crates/vm/src/stdlib/ctypes/base.rs | 5 +++-- crates/vm/src/stdlib/ctypes/field.rs | 2 +- crates/vm/src/stdlib/ctypes/function.rs | 16 ++++++++-------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/crates/vm/src/stdlib/ctypes/base.rs b/crates/vm/src/stdlib/ctypes/base.rs index f5a25ad740..1b07d73f8d 100644 --- a/crates/vm/src/stdlib/ctypes/base.rs +++ b/crates/vm/src/stdlib/ctypes/base.rs @@ -218,11 +218,12 @@ impl Constructor for PyCSimple { _ => vm.ctx.none(), // "z" | "Z" | "P" } }; - Ok(PyCSimple { + PyCSimple { _type_, value: AtomicCell::new(value), } - .to_pyobject(vm)) + .into_ref_with_type(vm, cls) + .map(Into::into) } } diff --git a/crates/vm/src/stdlib/ctypes/field.rs b/crates/vm/src/stdlib/ctypes/field.rs index b50b8b54ac..20aded85a7 100644 --- a/crates/vm/src/stdlib/ctypes/field.rs +++ b/crates/vm/src/stdlib/ctypes/field.rs @@ -36,7 +36,7 @@ pub struct PyCField { impl Representable for PyCField { fn repr_str(zelf: &Py, _vm: &VirtualMachine) -> PyResult { let tp_name = zelf.proto.name().to_string(); - if zelf.bitfield_size != false { + if zelf.bitfield_size { Ok(format!( "<{} type={}, ofs={byte_offset}, bit_size={bitfield_size}, bit_offset={bit_offset}", zelf.name, diff --git a/crates/vm/src/stdlib/ctypes/function.rs b/crates/vm/src/stdlib/ctypes/function.rs index 88d0fbb35e..bb4cc65212 100644 --- a/crates/vm/src/stdlib/ctypes/function.rs +++ b/crates/vm/src/stdlib/ctypes/function.rs @@ -13,7 +13,7 @@ use libffi::middle::{Arg, Cif, CodePtr, Type}; use libloading::Symbol; use num_traits::ToPrimitive; use rustpython_common::lock::PyRwLock; -use std::ffi::{self, CString, c_void}; +use std::ffi::{self, c_void}; use std::fmt::Debug; // See also: https://github.com/python/cpython/blob/4f8bb3947cfbc20f970ff9d9531e1132a9e95396/Modules/_ctypes/callproc.c#L15 @@ -61,6 +61,7 @@ impl ArgumentType for PyTypeRef { pub trait ReturnType { fn to_ffi_type(&self) -> Option; + #[allow(clippy::wrong_self_convention)] fn from_ffi_type( &self, value: *mut ffi::c_void, @@ -197,9 +198,8 @@ impl Callable for PyCFuncPtr { let return_type = zelf.res_type.read(); let ffi_return_type = return_type .as_ref() - .map(|t| ReturnType::to_ffi_type(&t.clone().downcast::().unwrap())) - .flatten() - .unwrap_or_else(|| Type::i32()); + .and_then(|t| ReturnType::to_ffi_type(&t.clone().downcast::().unwrap())) + .unwrap_or_else(Type::i32); let cif = Cif::new(ffi_arg_types, ffi_return_type); // Call the function @@ -243,12 +243,12 @@ impl Representable for PyCFuncPtr { let index = zelf.ptr.read(); let index = index.map(|ptr| ptr.0 as usize).unwrap_or(0); let type_name = zelf.class().name(); - #[cfg(windows)] - { + if cfg!(windows) { let index = index - 0x1000; - return Ok(format!("")); + Ok(format!("")) + } else { + Ok(format!("<{type_name} object at {index:#x}>")) } - Ok(format!("<{type_name} object at {index:#x}>")) } } From 8af105fc4ff5f5eb8e9a534b826b27ec47a6a576 Mon Sep 17 00:00:00 2001 From: Jeong YunWon Date: Fri, 28 Nov 2025 23:46:14 +0900 Subject: [PATCH 007/520] Make mergeable --- crates/vm/src/stdlib/ctypes.rs | 1 - crates/vm/src/stdlib/ctypes/field.rs | 11 +---------- crates/vm/src/stdlib/ctypes/function.rs | 2 ++ crates/vm/src/stdlib/ctypes/pointer.rs | 3 ++- crates/vm/src/stdlib/ctypes/util.rs | 24 ------------------------ extra_tests/snippets/stdlib_ctypes.py | 12 ++++++------ 6 files changed, 11 insertions(+), 42 deletions(-) delete mode 100644 crates/vm/src/stdlib/ctypes/util.rs diff --git a/crates/vm/src/stdlib/ctypes.rs b/crates/vm/src/stdlib/ctypes.rs index ac74418354..92629dcadb 100644 --- a/crates/vm/src/stdlib/ctypes.rs +++ b/crates/vm/src/stdlib/ctypes.rs @@ -9,7 +9,6 @@ pub(crate) mod pointer; pub(crate) mod structure; pub(crate) mod thunk; pub(crate) mod union; -pub(crate) mod util; use crate::builtins::PyModule; use crate::class::PyClassImpl; diff --git a/crates/vm/src/stdlib/ctypes/field.rs b/crates/vm/src/stdlib/ctypes/field.rs index 20aded85a7..e4e3bd6a09 100644 --- a/crates/vm/src/stdlib/ctypes/field.rs +++ b/crates/vm/src/stdlib/ctypes/field.rs @@ -8,6 +8,7 @@ use crate::{Py, PyResult, VirtualMachine}; #[pyclass(name = "PyCFieldType", base = PyType, module = "_ctypes")] #[derive(PyPayload, Debug)] pub struct PyCFieldType { + #[allow(dead_code)] pub(super) inner: PyCField, } @@ -122,13 +123,3 @@ impl PyCField { self.bit_offset } } - -#[inline(always)] -pub const fn low_bit(offset: usize) -> usize { - offset & 0xFFFF -} - -#[inline(always)] -pub const fn high_bit(offset: usize) -> usize { - offset >> 16 -} diff --git a/crates/vm/src/stdlib/ctypes/function.rs b/crates/vm/src/stdlib/ctypes/function.rs index bb4cc65212..64a230ad56 100644 --- a/crates/vm/src/stdlib/ctypes/function.rs +++ b/crates/vm/src/stdlib/ctypes/function.rs @@ -102,10 +102,12 @@ impl ReturnType for PyNone { pub struct PyCFuncPtr { pub name: PyRwLock>, pub ptr: PyRwLock>, + #[allow(dead_code)] pub needs_free: AtomicCell, pub arg_types: PyRwLock>>, pub res_type: PyRwLock>, pub _flags_: AtomicCell, + #[allow(dead_code)] pub handler: PyObjectRef, } diff --git a/crates/vm/src/stdlib/ctypes/pointer.rs b/crates/vm/src/stdlib/ctypes/pointer.rs index e072312562..b60280c73c 100644 --- a/crates/vm/src/stdlib/ctypes/pointer.rs +++ b/crates/vm/src/stdlib/ctypes/pointer.rs @@ -7,7 +7,8 @@ use crate::{PyObjectRef, PyResult}; #[pyclass(name = "PyCPointerType", base = PyType, module = "_ctypes")] #[derive(PyPayload, Debug)] pub struct PyCPointerType { - pub inner: PyCPointer, + #[allow(dead_code)] + pub(crate) inner: PyCPointer, } #[pyclass] diff --git a/crates/vm/src/stdlib/ctypes/util.rs b/crates/vm/src/stdlib/ctypes/util.rs deleted file mode 100644 index df5d318668..0000000000 --- a/crates/vm/src/stdlib/ctypes/util.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::PyObjectRef; - -#[pyclass(name, module = "_ctypes")] -#[derive(Debug, PyPayload)] -pub struct StgInfo { - pub initialized: i32, - pub size: usize, // number of bytes - pub align: usize, // alignment requirements - pub length: usize, // number of fields - // ffi_type_pointer: ffi::ffi_type, - pub proto: PyObjectRef, // Only for Pointer/ArrayObject - pub setfunc: Option, // Only for simple objects - pub getfunc: Option, // Only for simple objects - pub paramfunc: Option, - - /* Following fields only used by PyCFuncPtrType_Type instances */ - pub argtypes: Option, // tuple of CDataObjects - pub converters: Option, // tuple([t.from_param for t in argtypes]) - pub restype: Option, // CDataObject or NULL - pub checker: Option, - pub module: Option, - pub flags: i32, // calling convention and such - pub dict_final: u8, -} diff --git a/extra_tests/snippets/stdlib_ctypes.py b/extra_tests/snippets/stdlib_ctypes.py index 3ef6df689f..b4bc05dcb4 100644 --- a/extra_tests/snippets/stdlib_ctypes.py +++ b/extra_tests/snippets/stdlib_ctypes.py @@ -338,9 +338,9 @@ def LoadLibrary(self, name): libc = cdll.LoadLibrary("libc.dylib") libc.rand() i = c_int(1) - print("start srand") - print(libc.srand(i)) - print(test_byte_array) + # print("start srand") + # print(libc.srand(i)) + # print(test_byte_array) else: import os @@ -348,9 +348,9 @@ def LoadLibrary(self, name): libc.rand() i = c_int(1) print("start srand") - print(libc.srand(i)) - print(test_byte_array) - print(test_byte_array._type_) + # print(libc.srand(i)) + # print(test_byte_array) + # print(test_byte_array._type_) # print("start printf") # libc.printf(test_byte_array) From fef9de22c4d31eb062073ba4752aa5a8ed18ad45 Mon Sep 17 00:00:00 2001 From: Shahar Naveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Fri, 28 Nov 2025 17:46:27 +0200 Subject: [PATCH 008/520] Remove `Rotate*` & `Duplicate*` instructions (#6303) * Remove `Instruction::Duplicate2?` * Remove `Instruction::Rotate*` instructions * Fix jit * Update snapshot --- crates/codegen/src/compile.rs | 38 +++++++++-------- ...pile__tests__nested_double_async_with.snap | 2 +- crates/compiler-core/src/bytecode.rs | 11 ----- crates/jit/tests/common.rs | 12 ------ crates/vm/src/frame.rs | 41 ++++--------------- 5 files changed, 30 insertions(+), 74 deletions(-) diff --git a/crates/codegen/src/compile.rs b/crates/codegen/src/compile.rs index 5f8caebf27..b2dc10cda6 100644 --- a/crates/codegen/src/compile.rs +++ b/crates/codegen/src/compile.rs @@ -1063,7 +1063,7 @@ impl Compiler { if let Stmt::Expr(StmtExpr { value, .. }) = &last { self.compile_expression(value)?; - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); emit!(self, Instruction::PrintExpr); } else { self.compile_statement(last)?; @@ -1094,7 +1094,7 @@ impl Compiler { Stmt::FunctionDef(_) | Stmt::ClassDef(_) => { let pop_instructions = self.current_block().instructions.pop(); let store_inst = compiler_unwrap_option(self, pop_instructions); // pop Instruction::Store - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); self.current_block().instructions.push(store_inst); } _ => self.emit_load_const(ConstantData::None), @@ -1656,7 +1656,7 @@ impl Compiler { for (i, target) in targets.iter().enumerate() { if i + 1 != targets.len() { - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); } self.compile_store(target)?; } @@ -1917,7 +1917,7 @@ impl Compiler { ); } - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); self.store_name(name.as_ref())?; } TypeParam::ParamSpec(TypeParamParamSpec { name, default, .. }) => { @@ -1943,7 +1943,7 @@ impl Compiler { ); } - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); self.store_name(name.as_ref())?; } TypeParam::TypeVarTuple(TypeParamTypeVarTuple { name, default, .. }) => { @@ -1970,7 +1970,7 @@ impl Compiler { ); } - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); self.store_name(name.as_ref())?; } }; @@ -2030,7 +2030,7 @@ impl Compiler { // check if this handler can handle the exception: if let Some(exc_type) = type_ { // Duplicate exception for test: - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); // Check exception type: self.compile_expression(exc_type)?; @@ -2251,11 +2251,11 @@ impl Compiler { // Handle docstring if present if let Some(doc) = doc_str { - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); self.emit_load_const(ConstantData::Str { value: doc.to_string().into(), }); - emit!(self, Instruction::Rotate2); + emit!(self, Instruction::Swap { index: 2 }); let doc_attr = self.name("__doc__"); emit!(self, Instruction::StoreAttr { idx: doc_attr }); } @@ -2726,7 +2726,7 @@ impl Compiler { if let Some(classcell_idx) = classcell_idx { emit!(self, Instruction::LoadClosure(classcell_idx.to_u32())); - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); let classcell = self.name("__classcell__"); emit!(self, Instruction::StoreLocal(classcell)); } else { @@ -4121,8 +4121,8 @@ impl Compiler { for (op, val) in mid_ops.iter().zip(mid_exprs) { self.compile_expression(val)?; // store rhs for the next comparison in chain - emit!(self, Instruction::Duplicate); - emit!(self, Instruction::Rotate3); + emit!(self, Instruction::Swap { index: 2 }); + emit!(self, Instruction::CopyItem { index: 2_u32 }); compile_cmpop(self, op); @@ -4151,7 +4151,7 @@ impl Compiler { // early exit left us with stack: `rhs, comparison_result`. We need to clean up rhs. self.switch_to_block(break_block); - emit!(self, Instruction::Rotate2); + emit!(self, Instruction::Swap { index: 2 }); emit!(self, Instruction::Pop); self.switch_to_block(after_block); @@ -4322,7 +4322,8 @@ impl Compiler { // But we can't use compile_subscript directly because we need DUP_TOP2 self.compile_expression(value)?; self.compile_expression(slice)?; - emit!(self, Instruction::Duplicate2); + emit!(self, Instruction::CopyItem { index: 2_u32 }); + emit!(self, Instruction::CopyItem { index: 2_u32 }); emit!(self, Instruction::Subscript); AugAssignKind::Subscript } @@ -4330,7 +4331,7 @@ impl Compiler { let attr = attr.as_str(); self.check_forbidden_name(attr, NameUsage::Store)?; self.compile_expression(value)?; - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); let idx = self.name(attr); emit!(self, Instruction::LoadAttr { idx }); AugAssignKind::Attr { idx } @@ -4350,12 +4351,13 @@ impl Compiler { } AugAssignKind::Subscript => { // stack: CONTAINER SLICE RESULT - emit!(self, Instruction::Rotate3); + emit!(self, Instruction::Swap { index: 3 }); + emit!(self, Instruction::Swap { index: 2 }); emit!(self, Instruction::StoreSubscript); } AugAssignKind::Attr { idx } => { // stack: CONTAINER RESULT - emit!(self, Instruction::Rotate2); + emit!(self, Instruction::Swap { index: 2 }); emit!(self, Instruction::StoreAttr { idx }); } } @@ -4896,7 +4898,7 @@ impl Compiler { range: _, }) => { self.compile_expression(value)?; - emit!(self, Instruction::Duplicate); + emit!(self, Instruction::CopyItem { index: 1_u32 }); self.compile_store(target)?; } Expr::FString(fstring) => { diff --git a/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap b/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap index 82c02d5ea3..dc624c7b6a 100644 --- a/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap +++ b/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap @@ -49,7 +49,7 @@ expression: "compile_exec(\"\\\nfor stop_exc in (StopIteration('spam'), StopAsyn 39 WithCleanupFinish 40 PopBlock 41 Jump (59) - >> 42 Duplicate + >> 42 CopyItem (1) 6 43 LoadNameAny (7, Exception) 44 TestOperation (ExceptionMatch) diff --git a/crates/compiler-core/src/bytecode.rs b/crates/compiler-core/src/bytecode.rs index 2cfb70e278..fe28517cda 100644 --- a/crates/compiler-core/src/bytecode.rs +++ b/crates/compiler-core/src/bytecode.rs @@ -614,10 +614,6 @@ pub enum Instruction { index: Arg, }, ToBool, - Rotate2, - Rotate3, - Duplicate, - Duplicate2, GetIter, GetLen, CallIntrinsic1 { @@ -1475,9 +1471,6 @@ impl Instruction { Pop => -1, Swap { .. } => 0, ToBool => 0, - Rotate2 | Rotate3 => 0, - Duplicate => 1, - Duplicate2 => 2, GetIter => 0, GetLen => 1, CallIntrinsic1 { .. } => 0, // Takes 1, pushes 1 @@ -1678,10 +1671,6 @@ impl Instruction { Pop => w!(Pop), Swap { index } => w!(Swap, index), ToBool => w!(ToBool), - Rotate2 => w!(Rotate2), - Rotate3 => w!(Rotate3), - Duplicate => w!(Duplicate), - Duplicate2 => w!(Duplicate2), GetIter => w!(GetIter), // GET_LEN GetLen => w!(GetLen), diff --git a/crates/jit/tests/common.rs b/crates/jit/tests/common.rs index a88d3207f2..5dafeaeb80 100644 --- a/crates/jit/tests/common.rs +++ b/crates/jit/tests/common.rs @@ -164,18 +164,6 @@ impl StackMachine { self.stack.push(StackValue::Function(func)); } } - Instruction::Duplicate => { - let value = self.stack.last().unwrap().clone(); - self.stack.push(value); - } - Instruction::Rotate2 => { - let i = self.stack.len() - 2; - self.stack[i..].rotate_right(1); - } - Instruction::Rotate3 => { - let i = self.stack.len() - 3; - self.stack[i..].rotate_right(1); - } Instruction::ReturnConst { idx } => { let idx = idx.get(arg); self.stack.push(constants[idx as usize].clone().into()); diff --git a/crates/vm/src/frame.rs b/crates/vm/src/frame.rs index ab90f52b2d..8deaada082 100644 --- a/crates/vm/src/frame.rs +++ b/crates/vm/src/frame.rs @@ -719,32 +719,16 @@ impl ExecutingFrame<'_> { self.state.stack.swap(i, j); Ok(None) } - // bytecode::Instruction::ToBool => { - // dbg!("Shouldn't be called outside of match statements for now") - // let value = self.pop_value(); - // // call __bool__ - // let result = value.try_to_bool(vm)?; - // self.push_value(vm.ctx.new_bool(result).into()); - // Ok(None) - // } - bytecode::Instruction::Duplicate => { - // Duplicate top of stack - let value = self.top_value(); - self.push_value(value.to_owned()); - Ok(None) - } - bytecode::Instruction::Duplicate2 => { - // Duplicate top 2 of stack - let len = self.state.stack.len(); - self.push_value(self.state.stack[len - 2].clone()); - self.push_value(self.state.stack[len - 1].clone()); - Ok(None) + /* + bytecode::Instruction::ToBool => { + dbg!("Shouldn't be called outside of match statements for now") + let value = self.pop_value(); + // call __bool__ + let result = value.try_to_bool(vm)?; + self.push_value(vm.ctx.new_bool(result).into()); + Ok(None) } - // splitting the instructions like this offloads the cost of "dynamic" dispatch (on the - // amount to rotate) to the opcode dispatcher, and generates optimized code for the - // concrete cases we actually have - bytecode::Instruction::Rotate2 => self.execute_rotate(2), - bytecode::Instruction::Rotate3 => self.execute_rotate(3), + */ bytecode::Instruction::BuildString { size } => { let s = self .pop_multiple(size.get(arg) as usize) @@ -1685,13 +1669,6 @@ impl ExecutingFrame<'_> { } } - #[inline(always)] - fn execute_rotate(&mut self, amount: usize) -> FrameResult { - let i = self.state.stack.len() - amount; - self.state.stack[i..].rotate_right(1); - Ok(None) - } - fn execute_subscript(&mut self, vm: &VirtualMachine) -> FrameResult { let b_ref = self.pop_value(); let a_ref = self.pop_value(); From 23ec5a55adc7053a105235cd2dfe6ee078c9e712 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" <69878+youknowone@users.noreply.github.com> Date: Sat, 29 Nov 2025 01:32:52 +0900 Subject: [PATCH 009/520] Fix import ctypes and Lib/ctypes/__init__.py from cpython3.13.9 (#6304) * Fix ctypes import blockers * Update Lib/ctypes/__init__.py from cpython3.13.9 --- Lib/ctypes/__init__.py | 39 ++++--- crates/vm/src/stdlib/ctypes.rs | 79 +++++++++++-- crates/vm/src/stdlib/ctypes/array.rs | 7 +- crates/vm/src/stdlib/ctypes/base.rs | 15 +++ crates/vm/src/stdlib/ctypes/function.rs | 148 ++++++++++++++++-------- 5 files changed, 211 insertions(+), 77 deletions(-) diff --git a/Lib/ctypes/__init__.py b/Lib/ctypes/__init__.py index a5d27daff0..3599e13ed2 100644 --- a/Lib/ctypes/__init__.py +++ b/Lib/ctypes/__init__.py @@ -347,6 +347,19 @@ def __init__(self, name, mode=DEFAULT_MODE, handle=None, use_errno=False, use_last_error=False, winmode=None): + if name: + name = _os.fspath(name) + + # If the filename that has been provided is an iOS/tvOS/watchOS + # .fwork file, dereference the location to the true origin of the + # binary. + if name.endswith(".fwork"): + with open(name) as f: + name = _os.path.join( + _os.path.dirname(_sys.executable), + f.read().strip() + ) + self._name = name flags = self._func_flags_ if use_errno: @@ -467,6 +480,8 @@ def LoadLibrary(self, name): if _os.name == "nt": pythonapi = PyDLL("python dll", None, _sys.dllhandle) +elif _sys.platform == "android": + pythonapi = PyDLL("libpython%d.%d.so" % _sys.version_info[:2]) elif _sys.platform == "cygwin": pythonapi = PyDLL("libpython%d.%d.dll" % _sys.version_info[:2]) else: @@ -498,15 +513,14 @@ def WinError(code=None, descr=None): c_ssize_t = c_longlong # functions + from _ctypes import _memmove_addr, _memset_addr, _string_at_addr, _cast_addr ## void *memmove(void *, const void *, size_t); -# XXX: RUSTPYTHON -# memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) +memmove = CFUNCTYPE(c_void_p, c_void_p, c_void_p, c_size_t)(_memmove_addr) ## void *memset(void *, int, size_t) -# XXX: RUSTPYTHON -# memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) +memset = CFUNCTYPE(c_void_p, c_void_p, c_int, c_size_t)(_memset_addr) def PYFUNCTYPE(restype, *argtypes): class CFunctionType(_CFuncPtr): @@ -515,17 +529,15 @@ class CFunctionType(_CFuncPtr): _flags_ = _FUNCFLAG_CDECL | _FUNCFLAG_PYTHONAPI return CFunctionType -# XXX: RUSTPYTHON -# _cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) +_cast = PYFUNCTYPE(py_object, c_void_p, py_object, py_object)(_cast_addr) def cast(obj, typ): return _cast(obj, obj, typ) -# XXX: RUSTPYTHON -# _string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) +_string_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_string_at_addr) def string_at(ptr, size=-1): - """string_at(addr[, size]) -> string + """string_at(ptr[, size]) -> string - Return the string at addr.""" + Return the byte string at void *ptr.""" return _string_at(ptr, size) try: @@ -533,12 +545,11 @@ def string_at(ptr, size=-1): except ImportError: pass else: - # XXX: RUSTPYTHON - # _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) + _wstring_at = PYFUNCTYPE(py_object, c_void_p, c_int)(_wstring_at_addr) def wstring_at(ptr, size=-1): - """wstring_at(addr[, size]) -> string + """wstring_at(ptr[, size]) -> string - Return the string at addr.""" + Return the wide-character string at void *ptr.""" return _wstring_at(ptr, size) diff --git a/crates/vm/src/stdlib/ctypes.rs b/crates/vm/src/stdlib/ctypes.rs index 92629dcadb..500ddbfb06 100644 --- a/crates/vm/src/stdlib/ctypes.rs +++ b/crates/vm/src/stdlib/ctypes.rs @@ -189,6 +189,7 @@ pub(crate) mod _ctypes { } } + #[cfg(windows)] #[pyfunction(name = "LoadLibrary")] fn load_library_windows( name: String, @@ -203,20 +204,33 @@ pub(crate) mod _ctypes { Ok(id) } + #[cfg(not(windows))] #[pyfunction(name = "dlopen")] fn load_library_unix( - name: String, + name: Option, _load_flags: OptionalArg, vm: &VirtualMachine, ) -> PyResult { // TODO: audit functions first // TODO: load_flags - let cache = library::libcache(); - let mut cache_write = cache.write(); - let (id, _) = cache_write - .get_or_insert_lib(&name, vm) - .map_err(|e| vm.new_os_error(e.to_string()))?; - Ok(id) + match name { + Some(name) => { + let cache = library::libcache(); + let mut cache_write = cache.write(); + let (id, _) = cache_write + .get_or_insert_lib(&name, vm) + .map_err(|e| vm.new_os_error(e.to_string()))?; + Ok(id) + } + None => { + // If None, call libc::dlopen(null, mode) to get the current process handle + let handle = unsafe { libc::dlopen(std::ptr::null(), libc::RTLD_NOW) }; + if handle.is_null() { + return Err(vm.new_os_error("dlopen() error")); + } + Ok(handle as usize) + } + } } #[pyfunction(name = "FreeLibrary")] @@ -228,10 +242,57 @@ pub(crate) mod _ctypes { } #[pyfunction(name = "POINTER")] - pub fn pointer(_cls: PyTypeRef) {} + pub fn create_pointer_type(cls: PyObjectRef, vm: &VirtualMachine) -> PyResult { + // Get the _pointer_type_cache + let ctypes_module = vm.import("_ctypes", 0)?; + let cache = ctypes_module.get_attr("_pointer_type_cache", vm)?; + + // Check if already in cache using __getitem__ + if let Ok(cached) = vm.call_method(&cache, "__getitem__", (cls.clone(),)) + && !vm.is_none(&cached) + { + return Ok(cached); + } + + // Get the _Pointer base class + let pointer_base = ctypes_module.get_attr("_Pointer", vm)?; + + // Create the name for the pointer type + let name = if let Ok(type_obj) = cls.get_attr("__name__", vm) { + format!("LP_{}", type_obj.str(vm)?) + } else if let Ok(s) = cls.str(vm) { + format!("LP_{}", s) + } else { + "LP_unknown".to_string() + }; + + // Create a new type that inherits from _Pointer + let type_type = &vm.ctx.types.type_type; + let bases = vm.ctx.new_tuple(vec![pointer_base]); + let dict = vm.ctx.new_dict(); + dict.set_item("_type_", cls.clone(), vm)?; + + let new_type = type_type + .as_object() + .call((vm.ctx.new_str(name), bases, dict), vm)?; + + // Store in cache using __setitem__ + vm.call_method(&cache, "__setitem__", (cls, new_type.clone()))?; + + Ok(new_type) + } #[pyfunction(name = "pointer")] - pub fn pointer_fn(_inst: PyObjectRef) {} + pub fn create_pointer_inst(obj: PyObjectRef, vm: &VirtualMachine) -> PyResult { + // Get the type of the object + let obj_type = obj.class().to_owned(); + + // Create pointer type for this object's type + let ptr_type = create_pointer_type(obj_type.into(), vm)?; + + // Create an instance of the pointer type with the object + ptr_type.call((obj,), vm) + } #[pyfunction] fn _pointer_type_cache() -> PyObjectRef { diff --git a/crates/vm/src/stdlib/ctypes/array.rs b/crates/vm/src/stdlib/ctypes/array.rs index a1adf847a9..a46322460a 100644 --- a/crates/vm/src/stdlib/ctypes/array.rs +++ b/crates/vm/src/stdlib/ctypes/array.rs @@ -72,13 +72,14 @@ impl std::fmt::Debug for PyCArray { impl Constructor for PyCArray { type Args = (PyTypeRef, usize); - fn py_new(_cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult { - Ok(Self { + fn py_new(cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult { + Self { typ: PyRwLock::new(args.0), length: AtomicCell::new(args.1), value: PyRwLock::new(vm.ctx.none()), } - .into_pyobject(vm)) + .into_ref_with_type(vm, cls) + .map(Into::into) } } diff --git a/crates/vm/src/stdlib/ctypes/base.rs b/crates/vm/src/stdlib/ctypes/base.rs index 1b07d73f8d..29f3b9da2a 100644 --- a/crates/vm/src/stdlib/ctypes/base.rs +++ b/crates/vm/src/stdlib/ctypes/base.rs @@ -171,6 +171,21 @@ impl PyCSimpleType { .clone(), )) } + + #[pyclassmethod] + fn from_param(cls: PyTypeRef, value: PyObjectRef, vm: &VirtualMachine) -> PyResult { + // If the value is already an instance of the requested type, return it + if value.fast_isinstance(&cls) { + return Ok(value); + } + + // Check for _as_parameter_ attribute + let Ok(as_parameter) = value.get_attr("_as_parameter_", vm) else { + return Err(vm.new_type_error("wrong type")); + }; + + PyCSimpleType::from_param(cls, as_parameter, vm) + } } #[pyclass( diff --git a/crates/vm/src/stdlib/ctypes/function.rs b/crates/vm/src/stdlib/ctypes/function.rs index 64a230ad56..c1db4d58f8 100644 --- a/crates/vm/src/stdlib/ctypes/function.rs +++ b/crates/vm/src/stdlib/ctypes/function.rs @@ -120,60 +120,106 @@ impl Debug for PyCFuncPtr { } impl Constructor for PyCFuncPtr { - type Args = (PyTupleRef, FuncArgs); + type Args = FuncArgs; - fn py_new(_cls: PyTypeRef, (tuple, _args): Self::Args, vm: &VirtualMachine) -> PyResult { - let name = tuple - .first() - .ok_or(vm.new_type_error("Expected a tuple with at least 2 elements"))? - .downcast_ref::() - .ok_or(vm.new_type_error("Expected a string"))? - .to_string(); - let handler = tuple - .into_iter() - .nth(1) - .ok_or(vm.new_type_error("Expected a tuple with at least 2 elements"))? - .clone(); - let handle = handler.try_int(vm); - let handle = match handle { - Ok(handle) => handle.as_bigint().clone(), - Err(_) => handler - .get_attr("_handle", vm)? - .try_int(vm)? - .as_bigint() - .clone(), - }; - let library_cache = crate::stdlib::ctypes::library::libcache().read(); - let library = library_cache - .get_lib( - handle - .to_usize() - .ok_or(vm.new_value_error("Invalid handle".to_string()))?, - ) - .ok_or_else(|| vm.new_value_error("Library not found".to_string()))?; - let inner_lib = library.lib.lock(); - - let terminated = format!("{}\0", &name); - let code_ptr = if let Some(lib) = &*inner_lib { - let pointer: Symbol<'_, FP> = unsafe { - lib.get(terminated.as_bytes()) - .map_err(|err| err.to_string()) - .map_err(|err| vm.new_attribute_error(err))? + fn py_new(cls: PyTypeRef, args: Self::Args, vm: &VirtualMachine) -> PyResult { + // Handle different argument forms like CPython: + // 1. Empty args: create uninitialized + // 2. One integer argument: function address + // 3. Tuple argument: (name, dll) form + + if args.args.is_empty() { + return Self { + ptr: PyRwLock::new(None), + needs_free: AtomicCell::new(false), + arg_types: PyRwLock::new(None), + _flags_: AtomicCell::new(0), + res_type: PyRwLock::new(None), + name: PyRwLock::new(None), + handler: vm.ctx.none(), + } + .into_ref_with_type(vm, cls) + .map(Into::into); + } + + let first_arg = &args.args[0]; + + // Check if first argument is an integer (function address) + if let Ok(addr) = first_arg.try_int(vm) { + let ptr_val = addr.as_bigint().to_usize().unwrap_or(0); + return Self { + ptr: PyRwLock::new(Some(CodePtr(ptr_val as *mut _))), + needs_free: AtomicCell::new(false), + arg_types: PyRwLock::new(None), + _flags_: AtomicCell::new(0), + res_type: PyRwLock::new(None), + name: PyRwLock::new(Some(format!("CFuncPtr@{:#x}", ptr_val))), + handler: vm.ctx.new_int(ptr_val).into(), + } + .into_ref_with_type(vm, cls) + .map(Into::into); + } + + // Check if first argument is a tuple (name, dll) form + if let Some(tuple) = first_arg.downcast_ref::() { + let name = tuple + .first() + .ok_or(vm.new_type_error("Expected a tuple with at least 2 elements"))? + .downcast_ref::() + .ok_or(vm.new_type_error("Expected a string"))? + .to_string(); + let handler = tuple + .iter() + .nth(1) + .ok_or(vm.new_type_error("Expected a tuple with at least 2 elements"))? + .clone(); + + // Get library handle and load function + let handle = handler.try_int(vm); + let handle = match handle { + Ok(handle) => handle.as_bigint().clone(), + Err(_) => handler + .get_attr("_handle", vm)? + .try_int(vm)? + .as_bigint() + .clone(), }; - Some(CodePtr(*pointer as *mut _)) - } else { - None - }; - Ok(Self { - ptr: PyRwLock::new(code_ptr), - needs_free: AtomicCell::new(false), - arg_types: PyRwLock::new(None), - _flags_: AtomicCell::new(0), - res_type: PyRwLock::new(None), - name: PyRwLock::new(Some(name)), - handler, + let library_cache = crate::stdlib::ctypes::library::libcache().read(); + let library = library_cache + .get_lib( + handle + .to_usize() + .ok_or(vm.new_value_error("Invalid handle".to_string()))?, + ) + .ok_or_else(|| vm.new_value_error("Library not found".to_string()))?; + let inner_lib = library.lib.lock(); + + let terminated = format!("{}\0", &name); + let code_ptr = if let Some(lib) = &*inner_lib { + let pointer: Symbol<'_, FP> = unsafe { + lib.get(terminated.as_bytes()) + .map_err(|err| err.to_string()) + .map_err(|err| vm.new_attribute_error(err))? + }; + Some(CodePtr(*pointer as *mut _)) + } else { + None + }; + + return Self { + ptr: PyRwLock::new(code_ptr), + needs_free: AtomicCell::new(false), + arg_types: PyRwLock::new(None), + _flags_: AtomicCell::new(0), + res_type: PyRwLock::new(None), + name: PyRwLock::new(Some(name)), + handler, + } + .into_ref_with_type(vm, cls) + .map(Into::into); } - .to_pyobject(vm)) + + Err(vm.new_type_error("Expected an integer address or a tuple")) } } From a81912857d6151689ff8cb62dd7fec320cf33212 Mon Sep 17 00:00:00 2001 From: "Jeong, YunWon" <69878+youknowone@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:15:25 +0900 Subject: [PATCH 010/520] Ctypes __mul__ (#6305) --- crates/vm/src/stdlib/ctypes/base.rs | 52 +++++++++++++++++++++----- crates/vm/src/stdlib/ctypes/pointer.rs | 49 ++++++++++++++++++++++-- 2 files changed, 88 insertions(+), 13 deletions(-) diff --git a/crates/vm/src/stdlib/ctypes/base.rs b/crates/vm/src/stdlib/ctypes/base.rs index 29f3b9da2a..6fdb79e11e 100644 --- a/crates/vm/src/stdlib/ctypes/base.rs +++ b/crates/vm/src/stdlib/ctypes/base.rs @@ -3,8 +3,9 @@ use crate::builtins::PyType; use crate::builtins::{PyBytes, PyFloat, PyInt, PyNone, PyStr, PyTypeRef}; use crate::convert::ToPyObject; use crate::function::{Either, OptionalArg}; +use crate::protocol::PyNumberMethods; use crate::stdlib::ctypes::_ctypes::new_simple_type; -use crate::types::Constructor; +use crate::types::{AsNumber, Constructor}; use crate::{AsObject, Py, PyObjectRef, PyPayload, PyRef, PyResult, TryFromObject, VirtualMachine}; use crossbeam_utils::atomic::AtomicCell; use num_traits::ToPrimitive; @@ -158,9 +159,10 @@ pub struct PyCData { impl PyCData {} #[pyclass(module = "_ctypes", name = "PyCSimpleType", base = PyType)] +#[derive(Debug, PyPayload)] pub struct PyCSimpleType {} -#[pyclass(flags(BASETYPE))] +#[pyclass(flags(BASETYPE), with(AsNumber))] impl PyCSimpleType { #[allow(clippy::new_ret_no_self)] #[pymethod] @@ -186,6 +188,33 @@ impl PyCSimpleType { PyCSimpleType::from_param(cls, as_parameter, vm) } + + #[pymethod] + fn __mul__(cls: PyTypeRef, n: isize, vm: &VirtualMachine) -> PyResult { + PyCSimple::repeat(cls, n, vm) + } +} + +impl AsNumber for PyCSimpleType { + fn as_number() -> &'static PyNumberMethods { + static AS_NUMBER: PyNumberMethods = PyNumberMethods { + multiply: Some(|a, b, vm| { + // a is a PyCSimpleType instance (type object like c_char) + // b is int (array size) + let cls = a + .downcast_ref::() + .ok_or_else(|| vm.new_type_error("expected type".to_owned()))?; + let n = b + .try_index(vm)? + .as_bigint() + .to_isize() + .ok_or_else(|| vm.new_overflow_error("array size too large".to_owned()))?; + PyCSimple::repeat(cls.to_owned(), n, vm) + }), + ..PyNumberMethods::NOT_IMPLEMENTED + }; + &AS_NUMBER + } } #[pyclass( @@ -215,8 +244,18 @@ impl Constructor for PyCSimple { let attributes = cls.get_attributes(); let _type_ = attributes .iter() - .find(|(k, _)| k.to_object().str(vm).unwrap().to_string() == *"_type_") - .unwrap() + .find(|(k, _)| { + k.to_object() + .str(vm) + .map(|s| s.to_string() == "_type_") + .unwrap_or(false) + }) + .ok_or_else(|| { + vm.new_type_error(format!( + "cannot create '{}' instances: no _type_ attribute", + cls.name() + )) + })? .1 .str(vm)? .to_string(); @@ -276,11 +315,6 @@ impl PyCSimple { } .to_pyobject(vm)) } - - #[pyclassmethod] - fn __mul__(cls: PyTypeRef, n: isize, vm: &VirtualMachine) -> PyResult { - PyCSimple::repeat(cls, n, vm) - } } impl PyCSimple { diff --git a/crates/vm/src/stdlib/ctypes/pointer.rs b/crates/vm/src/stdlib/ctypes/pointer.rs index b60280c73c..3eb6f68e6d 100644 --- a/crates/vm/src/stdlib/ctypes/pointer.rs +++ b/crates/vm/src/stdlib/ctypes/pointer.rs @@ -1,8 +1,13 @@ +use crossbeam_utils::atomic::AtomicCell; +use num_traits::ToPrimitive; use rustpython_common::lock::PyRwLock; -use crate::builtins::PyType; +use crate::builtins::{PyType, PyTypeRef}; +use crate::convert::ToPyObject; +use crate::protocol::PyNumberMethods; use crate::stdlib::ctypes::PyCData; -use crate::{PyObjectRef, PyResult}; +use crate::types::AsNumber; +use crate::{PyObjectRef, PyResult, VirtualMachine}; #[pyclass(name = "PyCPointerType", base = PyType, module = "_ctypes")] #[derive(PyPayload, Debug)] @@ -11,8 +16,44 @@ pub struct PyCPointerType { pub(crate) inner: PyCPointer, } -#[pyclass] -impl PyCPointerType {} +#[pyclass(flags(IMMUTABLETYPE), with(AsNumber))] +impl PyCPointerType { + #[pymethod] + fn __mul__(cls: PyTypeRef, n: isize, vm: &VirtualMachine) -> PyResult { + use super::array::{PyCArray, PyCArrayType}; + if n < 0 { + return Err(vm.new_value_error(format!("Array length must be >= 0, not {n}"))); + } + Ok(PyCArrayType { + inner: PyCArray { + typ: PyRwLock::new(cls), + length: AtomicCell::new(n as usize), + value: PyRwLock::new(vm.ctx.none()), + }, + } + .to_pyobject(vm)) + } +} + +impl AsNumber for PyCPointerType { + fn as_number() -> &'static PyNumberMethods { + static AS_NUMBER: PyNumberMethods = PyNumberMethods { + multiply: Some(|a, b, vm| { + let cls = a + .downcast_ref::() + .ok_or_else(|| vm.new_type_error("expected type".to_owned()))?; + let n = b + .try_index(vm)? + .as_bigint() + .to_isize() + .ok_or_else(|| vm.new_overflow_error("array size too large".to_owned()))?; + PyCPointerType::__mul__(cls.to_owned(), n, vm) + }), + ..PyNumberMethods::NOT_IMPLEMENTED + }; + &AS_NUMBER + } +} #[pyclass( name = "_Pointer", From 7d8f0b989c542ee856615ee7e569898081312479 Mon Sep 17 00:00:00 2001 From: Shahar Naveh <50263213+ShaharNaveh@users.noreply.github.com> Date: Sat, 29 Nov 2025 02:02:52 +0200 Subject: [PATCH 011/520] Split `TestOperator` instruction (#6306) * Split `TestOperator` inatruction * Update snapshot * Set as have label --- crates/codegen/src/compile.rs | 48 +++-------- ...pile__tests__nested_double_async_with.snap | 69 ++++++++-------- crates/compiler-core/src/bytecode.rs | 54 ++++++++----- crates/vm/src/frame.rs | 81 +++++++++++-------- 4 files changed, 123 insertions(+), 129 deletions(-) diff --git a/crates/codegen/src/compile.rs b/crates/codegen/src/compile.rs index b2dc10cda6..4a4f17edcf 100644 --- a/crates/codegen/src/compile.rs +++ b/crates/codegen/src/compile.rs @@ -36,7 +36,7 @@ use rustpython_compiler_core::{ Mode, OneIndexed, PositionEncoding, SourceFile, SourceLocation, bytecode::{ self, Arg as OpArgMarker, BinaryOperator, CodeObject, ComparisonOperator, ConstantData, - Instruction, OpArg, OpArgType, UnpackExArgs, + Instruction, Invert, OpArg, OpArgType, UnpackExArgs, }, }; use rustpython_wtf8::Wtf8Buf; @@ -2034,20 +2034,7 @@ impl Compiler { // Check exception type: self.compile_expression(exc_type)?; - emit!( - self, - Instruction::TestOperation { - op: bytecode::TestOperator::ExceptionMatch, - } - ); - - // We cannot handle this exception type: - emit!( - self, - Instruction::PopJumpIfFalse { - target: next_handler, - } - ); + emit!(self, Instruction::JumpIfNotExcMatch(next_handler)); // We have a match, store in name (except x as y) if let Some(alias) = name { @@ -3477,12 +3464,7 @@ impl Compiler { // 4. Load None. self.emit_load_const(ConstantData::None); // 5. Compare with IS_OP 1. - emit!( - self, - Instruction::TestOperation { - op: bytecode::TestOperator::IsNot - } - ); + emit!(self, Instruction::IsOp(Invert::Yes)); // At this point the TOS is a tuple of (nargs + n_attrs) attributes (or None). pc.on_top += 1; @@ -3648,12 +3630,8 @@ impl Compiler { // Check if copy is None (consumes the copy like POP_JUMP_IF_NONE) self.emit_load_const(ConstantData::None); - emit!( - self, - Instruction::TestOperation { - op: bytecode::TestOperator::IsNot - } - ); + emit!(self, Instruction::IsOp(Invert::Yes)); + // Stack: [subject, keys_tuple, values_tuple, bool] self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?; // Stack: [subject, keys_tuple, values_tuple] @@ -3948,12 +3926,7 @@ impl Compiler { Singleton::True => ConstantData::Boolean { value: true }, }); // Compare using the "Is" operator. - emit!( - self, - Instruction::TestOperation { - op: bytecode::TestOperator::Is - } - ); + emit!(self, Instruction::IsOp(Invert::No)); // Jump to the failure label if the comparison is false. self.jump_to_fail_pop(pc, JumpOp::PopJumpIfFalse)?; Ok(()) @@ -4082,7 +4055,6 @@ impl Compiler { let (last_val, mid_exprs) = exprs.split_last().unwrap(); use bytecode::ComparisonOperator::*; - use bytecode::TestOperator::*; let compile_cmpop = |c: &mut Self, op: &CmpOp| match op { CmpOp::Eq => emit!(c, Instruction::CompareOperation { op: Equal }), CmpOp::NotEq => emit!(c, Instruction::CompareOperation { op: NotEqual }), @@ -4092,10 +4064,10 @@ impl Compiler { CmpOp::GtE => { emit!(c, Instruction::CompareOperation { op: GreaterOrEqual }) } - CmpOp::In => emit!(c, Instruction::TestOperation { op: In }), - CmpOp::NotIn => emit!(c, Instruction::TestOperation { op: NotIn }), - CmpOp::Is => emit!(c, Instruction::TestOperation { op: Is }), - CmpOp::IsNot => emit!(c, Instruction::TestOperation { op: IsNot }), + CmpOp::In => emit!(c, Instruction::ContainsOp(Invert::No)), + CmpOp::NotIn => emit!(c, Instruction::ContainsOp(Invert::Yes)), + CmpOp::Is => emit!(c, Instruction::IsOp(Invert::No)), + CmpOp::IsNot => emit!(c, Instruction::IsOp(Invert::Yes)), }; // a == b == c == d diff --git a/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap b/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap index dc624c7b6a..3042e35f17 100644 --- a/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap +++ b/crates/codegen/src/snapshots/rustpython_codegen__compile__tests__nested_double_async_with.snap @@ -1,5 +1,5 @@ --- -source: compiler/codegen/src/compile.rs +source: crates/codegen/src/compile.rs expression: "compile_exec(\"\\\nfor stop_exc in (StopIteration('spam'), StopAsyncIteration('ham')):\n with self.subTest(type=type(stop_exc)):\n try:\n async with egg():\n raise stop_exc\n except Exception as ex:\n self.assertIs(ex, stop_exc)\n else:\n self.fail(f'{stop_exc} was suppressed')\n\")" --- 1 0 SetupLoop @@ -11,7 +11,7 @@ expression: "compile_exec(\"\\\nfor stop_exc in (StopIteration('spam'), StopAsyn 6 CallFunctionPositional(1) 7 BuildTuple (2) 8 GetIter - >> 9 ForIter (73) + >> 9 ForIter (72) 10 StoreLocal (2, stop_exc) 2 11 LoadNameAny (3, self) @@ -21,7 +21,7 @@ expression: "compile_exec(\"\\\nfor stop_exc in (StopIteration('spam'), StopAsyn 15 CallFunctionPositional(1) 16 LoadConst (("type")) 17 CallMethodKeyword (1) - 18 SetupWith (70) + 18 SetupWith (69) 19 Pop 3 20 SetupExcept (42) @@ -48,41 +48,40 @@ expression: "compile_exec(\"\\\nfor stop_exc in (StopIteration('spam'), StopAsyn 38 Resume (3) 39 WithCleanupFinish 40 PopBlock - 41 Jump (59) + 41 Jump (58) >> 42 CopyItem (1) 6 43 LoadNameAny (7, Exception) - 44 TestOperation (ExceptionMatch) - 45 PopJumpIfFalse (58) - 46 StoreLocal (8, ex) + 44 JUMP_IF_NOT_EXC_MATCH(57) + 45 StoreLocal (8, ex) - 7 47 LoadNameAny (3, self) - 48 LoadMethod (9, assertIs) - 49 LoadNameAny (8, ex) - 50 LoadNameAny (2, stop_exc) - 51 CallMethodPositional (2) - 52 Pop - 53 PopException - 54 LoadConst (None) - 55 StoreLocal (8, ex) - 56 DeleteLocal (8, ex) - 57 Jump (68) - >> 58 Raise (Reraise) + 7 46 LoadNameAny (3, self) + 47 LoadMethod (9, assertIs) + 48 LoadNameAny (8, ex) + 49 LoadNameAny (2, stop_exc) + 50 CallMethodPositional (2) + 51 Pop + 52 PopException + 53 LoadConst (None) + 54 StoreLocal (8, ex) + 55 DeleteLocal (8, ex) + 56 Jump (67) + >> 57 Raise (Reraise) - 9 >> 59 LoadNameAny (3, self) - 60 LoadMethod (10, fail) - 61 LoadConst ("") - 62 LoadNameAny (2, stop_exc) - 63 FormatValue (None) - 64 LoadConst (" was suppressed") - 65 BuildString (2) - 66 CallMethodPositional (1) - 67 Pop + 9 >> 58 LoadNameAny (3, self) + 59 LoadMethod (10, fail) + 60 LoadConst ("") + 61 LoadNameAny (2, stop_exc) + 62 FormatValue (None) + 63 LoadConst (" was suppressed") + 64 BuildString (2) + 65 CallMethodPositional (1) + 66 Pop - 2 >> 68 PopBlock - 69 EnterFinally - >> 70 WithCleanupStart - 71 WithCleanupFinish - 72 Jump (9) - >> 73 PopBlock - 74 ReturnConst (None) + 2 >> 67 PopBlock + 68 EnterFinally + >> 69 WithCleanupStart + 70 WithCleanupFinish + 71 Jump (9) + >> 72 PopBlock + 73 ReturnConst (None) diff --git a/crates/compiler-core/src/bytecode.rs b/crates/compiler-core/src/bytecode.rs index fe28517cda..144054860e 100644 --- a/crates/compiler-core/src/bytecode.rs +++ b/crates/compiler-core/src/bytecode.rs @@ -577,6 +577,10 @@ pub enum Instruction { Subscript, StoreSubscript, DeleteSubscript, + /// Performs `is` comparison, or `is not` if `invert` is 1. + IsOp(Arg), + /// Performs `in` comparison, or `not in` if `invert` is 1. + ContainsOp(Arg), StoreAttr { idx: Arg, }, @@ -600,9 +604,6 @@ pub enum Instruction { LoadAttr { idx: Arg, }, - TestOperation { - op: Arg, - }, CompareOperation { op: Arg, }, @@ -628,6 +629,10 @@ pub enum Instruction { Break { target: Arg