diff --git a/Cargo.lock b/Cargo.lock index 45fa439..b1b1056 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -64,9 +64,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.15" +version = "0.6.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" +checksum = "23a1e53f0f5d86382dafe1cf314783b2044280f406e7e1506368220ad11b1338" dependencies = [ "anstyle", "anstyle-parse", @@ -79,43 +79,43 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" +checksum = "8365de52b16c035ff4fcafe0092ba9390540e3e352870ac09933bebcaa2c8c56" [[package]] name = "anstyle-parse" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.1" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.4" +version = "3.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" dependencies = [ "anstyle", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "anyhow" -version = "1.0.89" +version = "1.0.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86fdf8605db99b54d3cd748a44c6d04df638eb5dafb219b135d0149bd0db01f6" +checksum = "c042108f3ed77fd83760a5fd79b53be043192bb3b9dba91d8c574c0ada7850c8" dependencies = [ "backtrace", ] @@ -226,9 +226,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.7.2" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "428d9aa8fbc0670b7b8d6030a7fadd0f86151cae55e4dbbece15f3780a3dfaf3" +checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cap-fs-ext" @@ -309,9 +309,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.30" +version = "1.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b16803a61b81d9eabb7eae2588776c4c1e584b738ede45fdbb4c972cec1e9945" +checksum = "c2e7962b54006dcfcc61cb72735f4d89bb97061dd6a7ed882ec6b8ee53714c6f" dependencies = [ "jobserver", "libc", @@ -372,9 +372,9 @@ checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" [[package]] name = "colorchoice" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "component-init" @@ -714,9 +714,9 @@ checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" [[package]] name = "encoding_rs" -version = "0.8.34" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] @@ -1197,9 +1197,9 @@ checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67" [[package]] name = "libc" -version = "0.2.159" +version = "0.2.161" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "561d97a539a36e26a9a5fad1ea11a3039a67714694aaa379433e580854bc3dc5" +checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" [[package]] name = "libm" @@ -1224,16 +1224,6 @@ version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" -[[package]] -name = "lock_api" -version = "0.4.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] - [[package]] name = "log" version = "0.4.22" @@ -1347,29 +1337,6 @@ version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" -[[package]] -name = "parking_lot" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] - -[[package]] -name = "parking_lot_core" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] - [[package]] name = "paste" version = "1.0.15" @@ -1384,9 +1351,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" [[package]] name = "pin-utils" @@ -1439,9 +1406,9 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.22" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" dependencies = [ "proc-macro2", "syn", @@ -1449,9 +1416,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.87" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3e4daa0dcf6feba26f985457cdf104d4b4256fc5a09547140f3631bb076b19a" +checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e" dependencies = [ "unicode-ident", ] @@ -1487,16 +1454,16 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.20.3" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53bdbb96d49157e65d45cc287af5f32ffadd5f4761438b527b055fb0d4bb8233" +checksum = "3d922163ba1f79c04bc49073ba7b32fd5a8d3b76a87c955921234b8e77333c51" dependencies = [ "cfg-if", "indoc", "libc", "memoffset", "num-bigint", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -1506,9 +1473,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.20.3" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deaa5745de3f5231ce10517a1f5dd97d53e5a2fd77aa6b5842292085831d48d7" +checksum = "bc38c5feeb496c8321091edf3d63e9a6829eab4b863b4a6a65f26f3e9cc6b179" dependencies = [ "once_cell", "target-lexicon", @@ -1516,9 +1483,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.20.3" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b42531d03e08d4ef1f6e85a2ed422eb678b8cd62b762e53891c05faf0d4afa" +checksum = "94845622d88ae274d2729fcefc850e63d7a3ddff5e3ce11bd88486db9f1d357d" dependencies = [ "libc", "pyo3-build-config", @@ -1526,9 +1493,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.20.3" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7305c720fa01b8055ec95e484a6eca7a83c841267f0dd5280f0c8b8551d2c158" +checksum = "e655aad15e09b94ffdb3ce3d217acf652e26bbc37697ef012f5e5e348c716e5e" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -1538,11 +1505,11 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.20.3" +version = "0.22.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c7e9b68bb9c3149c5b0cade5d07f953d6d125eb4337723c4ccdb665f1f96185" +checksum = "ae1e3f09eecd94618f60a455a23def79f79eba4dc561a97324bf9ac8c6df30ce" dependencies = [ - "heck 0.4.1", + "heck 0.5.0", "proc-macro2", "pyo3-build-config", "quote", @@ -1667,9 +1634,9 @@ dependencies = [ [[package]] name = "regex" -version = "1.11.0" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38200e5ee88914975b69f657f0801b6f6dccafd44fd9326302a4aaeecfacb1d8" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1739,12 +1706,6 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "semver" version = "1.0.23" @@ -1756,18 +1717,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" +checksum = "3ea7893ff5e2466df8d720bb615088341b295f849602c6956047f8f80f0e9bc1" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.210" +version = "1.0.213" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" +checksum = "7e85ad2009c50b58e87caa8cd6dac16bdf511bbfb7af6c33df902396aa480fa5" dependencies = [ "proc-macro2", "quote", @@ -1776,9 +1737,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.128" +version = "1.0.132" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" +checksum = "d726bfaff4b320266d395898905d0eba0345aae23b54aee3a737e260fd46db03" dependencies = [ "itoa", "memchr", @@ -1894,9 +1855,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "syn" -version = "2.0.79" +version = "2.0.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89132cd0bf050864e1d38dc3bbc07a0eb8e7530af26344d3d2bbbef83499f590" +checksum = "5023162dfcd14ef8f32034d8bcd4cc5ddc61ef7a247c024a33e24e1f24d21b56" dependencies = [ "proc-macro2", "quote", @@ -1970,18 +1931,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d50af8abc119fb8bb6dbabcfa89656f46f84aa0ac7688088608076ad2b459a84" +checksum = "5d11abd9594d9b38965ef50805c5e469ca9cc6f197f883f717e0269a3057b3d5" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.64" +version = "1.0.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08904e7672f5eb876eaaf87e0ce17857500934f4981c4a0ab2b4aa98baac7fc3" +checksum = "ae71770322cbd277e69d762a16c444af02aa0575ac0d174f0b9562d3b37f8602" dependencies = [ "proc-macro2", "quote", @@ -2005,9 +1966,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.40.0" +version = "1.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" +checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" dependencies = [ "backtrace", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 53b309f..a683b40 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ name = "componentize_py" crate-type = ["cdylib", "rlib"] [dependencies] -anyhow = { version = "1.0.89", features = ["backtrace"] } +anyhow = { version = "1.0.91", features = ["backtrace"] } clap = { version = "4.5.20", features = ["derive"] } tar = "0.4.42" tempfile = "3.13.0" @@ -22,8 +22,8 @@ wasmparser = "0.219.0" indexmap = "2.6.0" bincode = "1.3.3" heck = "0.5.0" -pyo3 = { version = "0.20.0", features = [ - "abi3-py37", +pyo3 = { version = "0.22.5", features = [ + "abi3-py39", "extension-module", ], optional = true } wasmtime = "25.0.2" @@ -34,17 +34,17 @@ component-init = { git = "https://github.com/dicej/component-init", rev = "6964d wasm-convert = { git = "https://github.com/dicej/wasm-convert", rev = "a42b419" } async-trait = "0.1.83" futures = "0.3.31" -tokio = { version = "1.40.0", features = [ +tokio = { version = "1.41.0", features = [ "macros", "rt", "rt-multi-thread", "fs", ] } -bytes = "1.7.2" +bytes = "1.8.0" pretty_env_logger = "0.5.0" cap-std = "3.3.0" im-rc = "15.1.0" -serde = { version = "1.0.210", features = ["derive"] } +serde = { version = "1.0.213", features = ["derive"] } toml = "0.8.19" semver = "1.0.23" diff --git a/pyproject.toml b/pyproject.toml index 0af9ac7..dafe369 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,5 +1,5 @@ [build-system] -requires = ["maturin>=0.15,<0.16"] +requires = ["maturin>=1.0,<2.0"] build-backend = "maturin" [tool.maturin] diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 57cc423..5ea009e 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -7,9 +7,9 @@ edition = "2021" crate-type = ["staticlib"] [dependencies] -anyhow = "1.0.89" +anyhow = "1.0.91" once_cell = "1.20.2" -pyo3 = { version = "0.20.0", features = ["abi3-py311", "num-bigint"] } +pyo3 = { version = "0.22.5", features = ["abi3-py312", "num-bigint"] } componentize-py-shared = { path = "../shared" } num-bigint = "0.4.6" wit-bindgen = "0.34.0" diff --git a/runtime/pyo3-config-clippy.txt b/runtime/pyo3-config-clippy.txt index df2054b..b0b78fa 100644 --- a/runtime/pyo3-config-clippy.txt +++ b/runtime/pyo3-config-clippy.txt @@ -1,8 +1,8 @@ implementation=CPython -version=3.11 +version=3.12 shared=false abi3=false -lib_name=python3.11 +lib_name=python3.12 pointer_width=64 build_flags= suppress_build_script_link_lines=false diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index e166bce..0561178 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -12,15 +12,19 @@ use { pyo3::{ exceptions::PyAssertionError, intern, - types::{PyBool, PyBytes, PyDict, PyList, PyMapping, PyModule, PyString, PyTuple}, - Py, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject, + types::{ + PyAnyMethods, PyBool, PyBytes, PyBytesMethods, PyDict, PyList, PyListMethods, + PyMapping, PyMappingMethods, PyModule, PyModuleMethods, PyString, PyTuple, + }, + AsPyPointer, Borrowed, Bound, Py, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject, }, std::{ alloc::{self, Layout}, ffi::c_void, mem::{self, MaybeUninit}, + ops::DerefMut, ptr, slice, str, - sync::Once, + sync::{Mutex, Once}, }, wasi::cli::environment, }; @@ -45,6 +49,13 @@ static DROP_RESOURCE: OnceCell = OnceCell::new(); static SEED: OnceCell = OnceCell::new(); static ARGV: OnceCell> = OnceCell::new(); +struct Borrow { + handle: i32, + drop: u32, +} + +static BORROWS: Mutex> = Mutex::new(Vec::new()); + const DISCRIMINANT_FIELD_INDEX: i32 = 0; const PAYLOAD_FIELD_INDEX: i32 = 1; @@ -127,9 +138,9 @@ extern "C" { #[pyo3::pyfunction] #[pyo3(pass_module)] fn call_import<'a>( - module: &'a PyModule, + module: Bound<'a, PyModule>, index: u32, - params: Vec<&PyAny>, + params: Vec>, result_count: usize, ) -> PyResult> { let mut results = vec![MaybeUninit::<&PyAny>::uninit(); result_count]; @@ -150,7 +161,7 @@ fn call_import<'a>( #[pyo3::pyfunction] #[pyo3(pass_module)] -fn drop_resource(module: &PyModule, index: u32, handle: usize) -> PyResult<()> { +fn drop_resource(module: &Bound, index: u32, handle: usize) -> PyResult<()> { let params = [handle]; unsafe { componentize_py_call_indirect( @@ -165,7 +176,7 @@ fn drop_resource(module: &PyModule, index: u32, handle: usize) -> PyResult<()> { #[pyo3::pymodule] #[pyo3(name = "componentize_py_runtime")] -fn componentize_py_module(_py: Python<'_>, module: &PyModule) -> PyResult<()> { +fn componentize_py_module(_py: Python<'_>, module: &Bound) -> PyResult<()> { module.add_function(pyo3::wrap_pyfunction!(call_import, module)?)?; module.add_function(pyo3::wrap_pyfunction!(drop_resource, module)?) } @@ -176,7 +187,7 @@ fn do_init(app_name: String, symbols: Symbols, stub_wasi: bool) -> Result<()> { pyo3::prepare_freethreaded_python(); Python::with_gil(|py| { - let app = match py.import(app_name.as_str()) { + let app = match py.import_bound(app_name.as_str()) { Ok(app) => app, Err(e) => { e.print(py); @@ -198,37 +209,37 @@ fn do_init(app_name: String, symbols: Symbols, stub_wasi: bool) -> Result<()> { protocol, name, }) => Export::Freestanding { - name: PyString::intern(py, name).into(), + name: PyString::intern_bound(py, name).into(), instance: py - .import(module.as_str())? + .import_bound(module.as_str())? .getattr(protocol.as_str())? .call0()? .into(), }, FunctionExport::Freestanding(Function { protocol, name }) => { Export::Freestanding { - name: PyString::intern(py, name).into(), + name: PyString::intern_bound(py, name).into(), instance: app.getattr(protocol.as_str())?.call0()?.into(), } } FunctionExport::Constructor(Constructor { module, protocol }) => { Export::Constructor( - py.import(module.as_str())? + py.import_bound(module.as_str())? .getattr(protocol.as_str())? .into(), ) } FunctionExport::Method(name) => { - Export::Method(PyString::intern(py, name).into()) + Export::Method(PyString::intern_bound(py, name).into()) } FunctionExport::Static(Static { module, protocol, name, }) => Export::Static { - name: PyString::intern(py, name).into(), + name: PyString::intern_bound(py, name).into(), class: py - .import(module.as_str())? + .import_bound(module.as_str())? .getattr(protocol.as_str())? .into(), }, @@ -252,13 +263,13 @@ fn do_init(app_name: String, symbols: Symbols, stub_wasi: bool) -> Result<()> { }) => match kind { OwnedKind::Record(fields) => Type::Record { constructor: py - .import(package.as_str())? + .import_bound(package.as_str())? .getattr(name.as_str())? .into(), fields, }, OwnedKind::Variant(cases) => { - let package = py.import(package.as_str())?; + let package = py.import_bound(package.as_str())?; let cases = cases .iter() @@ -272,7 +283,7 @@ fn do_init(app_name: String, symbols: Symbols, stub_wasi: bool) -> Result<()> { }) .collect::>>()?; - let types_to_discriminants = PyDict::new(py); + let types_to_discriminants = PyDict::new_bound(py); for (index, case) in cases.iter().enumerate() { types_to_discriminants .set_item(&case.constructor, index)?; @@ -285,21 +296,21 @@ fn do_init(app_name: String, symbols: Symbols, stub_wasi: bool) -> Result<()> { } OwnedKind::Enum(count) => Type::Enum { constructor: py - .import(package.as_str())? + .import_bound(package.as_str())? .getattr(name.as_str())? .into(), count: count.try_into().unwrap(), }, OwnedKind::Flags(u32_count) => Type::Flags { constructor: py - .import(package.as_str())? + .import_bound(package.as_str())? .getattr(name.as_str())? .into(), u32_count: u32_count.try_into().unwrap(), }, OwnedKind::Resource(Resource { local, remote }) => Type::Resource { constructor: py - .import(package.as_str())? + .import_bound(package.as_str())? .getattr(name.as_str())? .into(), local, @@ -317,16 +328,16 @@ fn do_init(app_name: String, symbols: Symbols, stub_wasi: bool) -> Result<()> { ) .unwrap(); - let types = py.import(symbols.types_package.as_str())?; + let types = py.import_bound(symbols.types_package.as_str())?; SOME_CONSTRUCTOR.set(types.getattr("Some")?.into()).unwrap(); OK_CONSTRUCTOR.set(types.getattr("Ok")?.into()).unwrap(); ERR_CONSTRUCTOR.set(types.getattr("Err")?.into()).unwrap(); let environ = py - .import("os")? + .import_bound("os")? .getattr("environ")? - .downcast::() + .downcast_into::() .unwrap(); let keys = environ.keys()?; @@ -338,24 +349,24 @@ fn do_init(app_name: String, symbols: Symbols, stub_wasi: bool) -> Result<()> { ENVIRON.set(environ.into()).unwrap(); FINALIZE - .set(py.import("weakref")?.getattr("finalize")?.into()) + .set(py.import_bound("weakref")?.getattr("finalize")?.into()) .unwrap(); DROP_RESOURCE .set( - py.import("componentize_py_runtime")? + py.import_bound("componentize_py_runtime")? .getattr("drop_resource")? .into(), ) .unwrap(); - SEED.set(py.import("random")?.getattr("seed")?.into()) + SEED.set(py.import_bound("random")?.getattr("seed")?.into()) .unwrap(); let argv = py - .import("sys")? + .import_bound("sys")? .getattr("argv")? - .downcast::() + .downcast_into::() .unwrap(); for i in 0..argv.len() { @@ -422,21 +433,23 @@ pub unsafe extern "C" fn componentize_py_dispatch( ); // todo: is this sound, or do we need to `.into_iter().map(MaybeUninit::assume_init).collect()` instead? - let params_py = mem::transmute::>, Vec<&PyAny>>(params_py); + let mut params_py = mem::transmute::>, Vec<&PyAny>>(params_py) + .into_iter() + .map(|p| Bound::from_borrowed_ptr(py, p.as_ptr())); if !*STUB_WASI.get().unwrap() { static ONCE: Once = Once::new(); ONCE.call_once(|| { // We must call directly into the host to get the runtime environment since libc's version will only // contain the build-time pre-init snapshot. - let environ = ENVIRON.get().unwrap().as_ref(py); + let environ = ENVIRON.get().unwrap().bind(py); for (k, v) in environment::get_environment() { environ.set_item(k, v).unwrap(); } // Likewise for CLI arguments. for arg in environment::get_arguments() { - ARGV.get().unwrap().as_ref(py).append(arg).unwrap(); + ARGV.get().unwrap().bind(py).append(arg).unwrap(); } // Call `random.seed()` to ensure we get a fresh seed rather than the one that got baked in during @@ -448,15 +461,18 @@ pub unsafe extern "C" fn componentize_py_dispatch( let export = &EXPORTS.get().unwrap()[export]; let result = match export { Export::Freestanding { instance, name } => { - instance.call_method1(py, name.as_ref(py), PyTuple::new(py, params_py)) + instance.call_method1(py, name, PyTuple::new_bound(py, params_py)) } - Export::Constructor(class) => class.call1(py, PyTuple::new(py, params_py)), - Export::Method(name) => params_py[0] - .call_method1(name.as_ref(py), PyTuple::new(py, ¶ms_py[1..])) + Export::Constructor(class) => class.call1(py, PyTuple::new_bound(py, params_py)), + Export::Method(name) => params_py + // Call method on self with remaining iterator elements + .next() + .unwrap() + .call_method1(name, PyTuple::new_bound(py, params_py)) .map(|r| r.into()), Export::Static { class, name } => class - .getattr(py, name.as_ref(py)) - .and_then(|function| function.call1(py, PyTuple::new(py, params_py))), + .getattr(py, name) + .and_then(|function| function.call1(py, PyTuple::new_bound(py, params_py))), }; let result = match return_style { @@ -473,8 +489,8 @@ pub unsafe extern "C" fn componentize_py_dispatch( if ERR_CONSTRUCTOR .get() .unwrap() - .as_ref(py) - .eq(result.get_type(py)) + .bind(py) + .eq(result.get_type_bound(py)) .unwrap() { result.to_object(py) @@ -486,7 +502,6 @@ pub unsafe extern "C" fn componentize_py_dispatch( }, }; - let result = result.into_ref(py); let result_array = [result]; componentize_py_call_indirect( @@ -495,6 +510,19 @@ pub unsafe extern "C" fn componentize_py_dispatch( results_canon, to_canon, ); + + let borrows = mem::take(BORROWS.lock().unwrap().deref_mut()); + for Borrow { handle, drop } in borrows { + let params = [handle]; + unsafe { + componentize_py_call_indirect( + &py as *const _ as _, + params.as_ptr() as _, + ptr::null_mut(), + drop, + ); + } + } }); } @@ -513,8 +541,8 @@ pub unsafe extern "C" fn componentize_py_free(ptr: *mut u8, size: usize, align: } #[export_name = "componentize-py#ToCanonBool"] -pub extern "C" fn componentize_py_to_canon_bool(_py: &Python, value: &PyAny) -> u32 { - if value.is_true().unwrap() { +pub extern "C" fn componentize_py_to_canon_bool(_py: &Python, value: Borrowed) -> u32 { + if value.is_truthy().unwrap() { 1 } else { 0 @@ -522,27 +550,27 @@ pub extern "C" fn componentize_py_to_canon_bool(_py: &Python, value: &PyAny) -> } #[export_name = "componentize-py#ToCanonI32"] -pub extern "C" fn componentize_py_to_canon_i32(_py: &Python, value: &PyAny) -> i32 { +pub extern "C" fn componentize_py_to_canon_i32(_py: &Python, value: Borrowed) -> i32 { value.extract().unwrap() } #[export_name = "componentize-py#ToCanonI64"] -pub extern "C" fn componentize_py_to_canon_i64(_py: &Python, value: &PyAny) -> i64 { +pub extern "C" fn componentize_py_to_canon_i64(_py: &Python, value: Borrowed) -> i64 { value.extract().unwrap() } #[export_name = "componentize-py#ToCanonF32"] -pub extern "C" fn componentize_py_to_canon_f32(_py: &Python, value: &PyAny) -> f32 { +pub extern "C" fn componentize_py_to_canon_f32(_py: &Python, value: Borrowed) -> f32 { value.extract().unwrap() } #[export_name = "componentize-py#ToCanonF64"] -pub extern "C" fn componentize_py_to_canon_f64(_py: &Python, value: &PyAny) -> f64 { +pub extern "C" fn componentize_py_to_canon_f64(_py: &Python, value: Borrowed) -> f64 { value.extract().unwrap() } #[export_name = "componentize-py#ToCanonChar"] -pub extern "C" fn componentize_py_to_canon_char(_py: &Python, value: &PyAny) -> u32 { +pub extern "C" fn componentize_py_to_canon_char(_py: &Python, value: Borrowed) -> u32 { let value = value.extract::().unwrap(); assert!(value.chars().count() == 1); value.chars().next().unwrap() as u32 @@ -553,7 +581,7 @@ pub extern "C" fn componentize_py_to_canon_char(_py: &Python, value: &PyAny) -> #[export_name = "componentize-py#ToCanonString"] pub unsafe extern "C" fn componentize_py_to_canon_string( _py: &Python, - value: &PyAny, + value: Borrowed, destination: *mut (*const u8, usize), ) { let value = value.extract::().unwrap().into_bytes(); @@ -567,10 +595,10 @@ pub unsafe extern "C" fn componentize_py_to_canon_string( #[export_name = "componentize-py#GetField"] pub extern "C" fn componentize_py_get_field<'a>( py: &'a Python, - value: &'a PyAny, + value: Borrowed<'_, 'a, PyAny>, ty: usize, field: usize, -) -> &'a PyAny { +) -> Bound<'a, PyAny> { match &TYPES.get().unwrap()[ty] { Type::Record { fields, .. } => value.getattr(fields[field].as_str()).unwrap(), Type::Variant { @@ -578,9 +606,8 @@ pub extern "C" fn componentize_py_get_field<'a>( cases, } => { let discriminant = types_to_discriminants - .as_ref(*py) + .bind(*py) .get_item(value.get_type()) - .unwrap() .unwrap(); match i32::try_from(field).unwrap() { @@ -589,7 +616,7 @@ pub extern "C" fn componentize_py_get_field<'a>( if cases[discriminant.extract::().unwrap()].has_payload { value.getattr("value").unwrap() } else { - py.None().into_ref(*py) + py.None().into_bound(*py) } } _ => unreachable!(), @@ -597,7 +624,7 @@ pub extern "C" fn componentize_py_get_field<'a>( } Type::Enum { .. } => match i32::try_from(field).unwrap() { DISCRIMINANT_FIELD_INDEX => value.getattr("value").unwrap(), - PAYLOAD_FIELD_INDEX => py.None().into_ref(*py), + PAYLOAD_FIELD_INDEX => py.None().into_bound(*py), _ => unreachable!(), }, Type::Flags { u32_count, .. } => { @@ -613,28 +640,22 @@ pub extern "C" fn componentize_py_get_field<'a>( unsafe { mem::transmute::(value) } .to_object(*py) - .into_ref(*py) - .downcast() - .unwrap() + .into_bound(*py) } Type::Option => match i32::try_from(field).unwrap() { DISCRIMINANT_FIELD_INDEX => if value.is_none() { 0 } else { 1 } .to_object(*py) - .into_ref(*py) - .downcast() - .unwrap(), - PAYLOAD_FIELD_INDEX => value, + .into_bound(*py), + PAYLOAD_FIELD_INDEX => value.to_owned(), _ => unreachable!(), }, Type::NestingOption => match i32::try_from(field).unwrap() { DISCRIMINANT_FIELD_INDEX => if value.is_none() { 0 } else { 1 } .to_object(*py) - .into_ref(*py) - .downcast() - .unwrap(), + .into_bound(*py), PAYLOAD_FIELD_INDEX => { if value.is_none() { - value + value.to_owned() } else { value.getattr("value").unwrap() } @@ -645,7 +666,7 @@ pub extern "C" fn componentize_py_get_field<'a>( DISCRIMINANT_FIELD_INDEX => if OK_CONSTRUCTOR .get() .unwrap() - .as_ref(*py) + .bind(*py) .eq(value.get_type()) .unwrap() { @@ -653,7 +674,7 @@ pub extern "C" fn componentize_py_get_field<'a>( } else if ERR_CONSTRUCTOR .get() .unwrap() - .as_ref(*py) + .bind(*py) .eq(value.get_type()) .unwrap() { @@ -662,7 +683,7 @@ pub extern "C" fn componentize_py_get_field<'a>( unreachable!() } .to_object(*py) - .into_ref(*py), + .into_bound(*py), PAYLOAD_FIELD_INDEX => value.getattr("value").unwrap(), _ => unreachable!(), }, @@ -679,7 +700,7 @@ pub extern "C" fn componentize_py_get_field<'a>( } #[export_name = "componentize-py#GetListLength"] -pub extern "C" fn componentize_py_get_list_length(_py: &Python, value: &PyAny) -> usize { +pub extern "C" fn componentize_py_get_list_length(_py: &Python, value: Borrowed) -> usize { if let Ok(bytes) = value.downcast::() { bytes.len().unwrap() } else { @@ -689,83 +710,86 @@ pub extern "C" fn componentize_py_get_list_length(_py: &Python, value: &PyAny) - #[export_name = "componentize-py#GetListElement"] pub extern "C" fn componentize_py_get_list_element<'a>( - _py: &'a Python, - value: &'a PyAny, + _py: &Python<'a>, + value: Borrowed<'_, 'a, PyAny>, index: usize, -) -> &'a PyAny { +) -> Bound<'a, PyAny> { value.downcast::().unwrap().get_item(index).unwrap() } #[export_name = "componentize-py#FromCanonBool"] -pub extern "C" fn componentize_py_from_canon_bool<'a>(py: &'a Python<'a>, value: u32) -> &'a PyAny { - PyBool::new(*py, value != 0) +pub extern "C" fn componentize_py_from_canon_bool<'a>( + py: &Python<'a>, + value: u32, +) -> Bound<'a, PyBool> { + PyBool::new_bound(*py, value != 0).to_owned() } #[export_name = "componentize-py#FromCanonI32"] -pub extern "C" fn componentize_py_from_canon_i32<'a>(py: &'a Python<'a>, value: i32) -> &'a PyAny { - value.to_object(*py).into_ref(*py).downcast().unwrap() +pub extern "C" fn componentize_py_from_canon_i32(py: &Python, value: i32) -> Py { + value.to_object(*py) } #[export_name = "componentize-py#FromCanonI64"] -pub extern "C" fn componentize_py_from_canon_i64<'a>(py: &'a Python<'a>, value: i64) -> &'a PyAny { - value.to_object(*py).into_ref(*py).downcast().unwrap() +pub extern "C" fn componentize_py_from_canon_i64(py: &Python, value: i64) -> Py { + value.to_object(*py) } #[export_name = "componentize-py#FromCanonF32"] -pub extern "C" fn componentize_py_from_canon_f32<'a>(py: &'a Python<'a>, value: f32) -> &'a PyAny { - value.to_object(*py).into_ref(*py).downcast().unwrap() +pub extern "C" fn componentize_py_from_canon_f32(py: &Python, value: f32) -> Py { + value.to_object(*py) } #[export_name = "componentize-py#FromCanonF64"] -pub extern "C" fn componentize_py_from_canon_f64<'a>(py: &'a Python<'a>, value: f64) -> &'a PyAny { - value.to_object(*py).into_ref(*py).downcast().unwrap() +pub extern "C" fn componentize_py_from_canon_f64(py: &Python, value: f64) -> Py { + value.to_object(*py) } #[export_name = "componentize-py#FromCanonChar"] -pub extern "C" fn componentize_py_from_canon_char<'a>(py: &'a Python<'a>, value: u32) -> &'a PyAny { - char::from_u32(value) - .unwrap() - .to_string() - .to_object(*py) - .into_ref(*py) - .downcast() - .unwrap() +pub extern "C" fn componentize_py_from_canon_char(py: &Python, value: u32) -> Py { + char::from_u32(value).unwrap().to_string().to_object(*py) } /// # Safety /// TODO #[export_name = "componentize-py#FromCanonString"] pub unsafe extern "C" fn componentize_py_from_canon_string<'a>( - py: &'a Python, + py: &Python<'a>, data: *const u8, len: usize, -) -> &'a PyAny { - PyString::new(*py, unsafe { +) -> Bound<'a, PyString> { + PyString::new_bound(*py, unsafe { str::from_utf8_unchecked(slice::from_raw_parts(data, len)) }) - .as_ref() } /// # Safety /// TODO #[export_name = "componentize-py#Init"] pub unsafe extern "C" fn componentize_py_init<'a>( - py: &'a Python<'a>, + py: &Python<'a>, ty: usize, data: *const &'a PyAny, len: usize, -) -> &'a PyAny { +) -> Bound<'a, PyAny> { match &TYPES.get().unwrap()[ty] { - Type::Record { constructor, .. } => constructor - .call1(*py, PyTuple::new(*py, slice::from_raw_parts(data, len))) - .unwrap() - .into_ref(*py), + Type::Record { constructor, .. } => { + let elements = slice::from_raw_parts(data, len) + .iter() + .map(|e| Bound::from_borrowed_ptr(*py, e.as_ptr())); + constructor + .call1(*py, PyTuple::new_bound(*py, elements)) + .unwrap() + .into_bound(*py) + } Type::Variant { cases, .. } => { assert!(len == 2); - let discriminant = - ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())) - .extract::() - .unwrap(); + let discriminant = Bound::from_borrowed_ptr( + *py, + ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())).as_ptr(), + ) + .extract::() + .unwrap(); let case = &cases[usize::try_from(discriminant).unwrap()]; if case.has_payload { case.constructor.call1( @@ -778,14 +802,16 @@ pub unsafe extern "C" fn componentize_py_init<'a>( case.constructor.call1(*py, ()) } .unwrap() - .into_ref(*py) + .into_bound(*py) } Type::Enum { constructor, count } => { assert!(len == 2); - let discriminant = - ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())) - .extract::() - .unwrap(); + let discriminant = Bound::from_borrowed_ptr( + *py, + ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())).as_ptr(), + ) + .extract::() + .unwrap(); assert!(discriminant < *count); constructor .call1( @@ -795,7 +821,7 @@ pub unsafe extern "C" fn componentize_py_init<'a>( )),), ) .unwrap() - .into_ref(*py) + .into_bound(*py) } Type::Flags { constructor, @@ -808,36 +834,45 @@ pub unsafe extern "C" fn componentize_py_init<'a>( (BigUint::new( slice::from_raw_parts(data, len) .iter() - .map(|&v| mem::transmute::(v.extract().unwrap())) + .map(|v| { + mem::transmute::( + Bound::from_borrowed_ptr(*py, v.as_ptr()).extract().unwrap(), + ) + }) .collect(), ),), ) .unwrap() - .into_ref(*py) + .into_bound(*py) } Type::Option => { assert!(len == 2); - let discriminant = - ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())) - .extract::() - .unwrap(); - + let discriminant = Bound::from_borrowed_ptr( + *py, + ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())).as_ptr(), + ) + .extract::() + .unwrap(); match discriminant { - 0 => py.None().into_ref(*py), - 1 => ptr::read(data.offset(isize::try_from(PAYLOAD_FIELD_INDEX).unwrap())), - + 0 => py.None().into_bound(*py), + 1 => Bound::from_borrowed_ptr( + *py, + ptr::read(data.offset(isize::try_from(PAYLOAD_FIELD_INDEX).unwrap())).as_ptr(), + ), _ => unreachable!(), } } Type::NestingOption => { assert!(len == 2); - let discriminant = - ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())) - .extract::() - .unwrap(); + let discriminant = Bound::from_borrowed_ptr( + *py, + ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())).as_ptr(), + ) + .extract::() + .unwrap(); match discriminant { - 0 => py.None().into_ref(*py), + 0 => py.None().into_bound(*py), 1 => SOME_CONSTRUCTOR .get() @@ -849,17 +884,19 @@ pub unsafe extern "C" fn componentize_py_init<'a>( ),), ) .unwrap() - .into_ref(*py), + .into_bound(*py), _ => unreachable!(), } } Type::Result => { assert!(len == 2); - let discriminant = - ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())) - .extract::() - .unwrap(); + let discriminant = Bound::from_borrowed_ptr( + *py, + ptr::read(data.offset(isize::try_from(DISCRIMINANT_FIELD_INDEX).unwrap())).as_ptr(), + ) + .extract::() + .unwrap(); match discriminant { 0 => OK_CONSTRUCTOR.get().unwrap(), @@ -873,29 +910,36 @@ pub unsafe extern "C" fn componentize_py_init<'a>( ),), ) .unwrap() - .into_ref(*py) + .into_bound(*py) } Type::Tuple(length) => { assert!(*length == len); - PyTuple::new(*py, slice::from_raw_parts(data, len)) + let elements = slice::from_raw_parts(data, len) + .iter() + .map(|e| Bound::from_borrowed_ptr(*py, e.as_ptr())); + PyTuple::new_bound(*py, elements).into_any() } Type::Handle | Type::Resource { .. } => unreachable!(), } } #[export_name = "componentize-py#MakeList"] -pub extern "C" fn componentize_py_make_list<'a>(py: &'a Python) -> &'a PyList { - PyList::empty(*py) +pub extern "C" fn componentize_py_make_list<'a>(py: &Python<'a>) -> Bound<'a, PyList> { + PyList::empty_bound(*py) } #[export_name = "componentize-py#ListAppend"] -pub extern "C" fn componentize_py_list_append(_py: &Python, list: &PyList, element: &PyAny) { +pub extern "C" fn componentize_py_list_append( + _py: &Python, + list: Borrowed, + element: Borrowed, +) { list.append(element).unwrap(); } #[export_name = "componentize-py#None"] -pub extern "C" fn componentize_py_none<'a>(py: &'a Python) -> &'a PyAny { - py.None().into_ref(*py) +pub extern "C" fn componentize_py_none(py: &Python) -> Py { + py.None() } /// # Safety @@ -903,7 +947,7 @@ pub extern "C" fn componentize_py_none<'a>(py: &'a Python) -> &'a PyAny { #[export_name = "componentize-py#GetBytes"] pub unsafe extern "C" fn componentize_py_get_bytes( _py: &Python, - src: &PyBytes, + src: Borrowed, dst: *mut u8, len: usize, ) { @@ -915,11 +959,11 @@ pub unsafe extern "C" fn componentize_py_get_bytes( /// TODO #[export_name = "componentize-py#MakeBytes"] pub unsafe extern "C" fn componentize_py_make_bytes<'a>( - py: &'a Python, + py: &Python<'a>, src: *const u8, len: usize, -) -> &'a PyAny { - PyBytes::new_with(*py, len, |dst| { +) -> Bound<'a, PyBytes> { + PyBytes::new_bound_with(*py, len, |dst| { dst.copy_from_slice(slice::from_raw_parts(src, len)); Ok(()) }) @@ -928,12 +972,12 @@ pub unsafe extern "C" fn componentize_py_make_bytes<'a>( #[export_name = "componentize-py#FromCanonHandle"] pub extern "C" fn componentize_py_from_canon_handle<'a>( - py: &'a Python<'a>, + py: &Python<'a>, value: i32, borrow: i32, local: i32, resource: i32, -) -> &'a PyAny { +) -> Bound<'a, PyAny> { let ty = &TYPES.get().unwrap()[usize::try_from(resource).unwrap()]; let Type::Resource { constructor, @@ -946,7 +990,7 @@ pub extern "C" fn componentize_py_from_canon_handle<'a>( if local != 0 { if borrow != 0 { - unsafe { PyObject::from_borrowed_ptr(*py, value as usize as _) }.into_ref(*py) + unsafe { PyObject::from_borrowed_ptr(*py, value as usize as _) }.into_bound(*py) } else { let Some(LocalResource { rep, .. }) = resource_local else { panic!("expected local resource, found {ty:?}"); @@ -966,7 +1010,7 @@ pub extern "C" fn componentize_py_from_canon_handle<'a>( } }; - let value = unsafe { PyObject::from_borrowed_ptr(*py, rep as _) }.into_ref(*py); + let value = unsafe { PyObject::from_borrowed_ptr(*py, rep as _) }.into_bound(*py); value .delattr(intern!(*py, "__componentize_py_handle")) @@ -985,18 +1029,25 @@ pub extern "C" fn componentize_py_from_canon_handle<'a>( panic!("expected remote resource, found {ty:?}"); }; + if borrow != 0 { + BORROWS.lock().unwrap().push(Borrow { + handle: value, + drop: *drop, + }); + } + let instance = constructor .call_method1( *py, intern!(*py, "__new__"), - PyTuple::new(*py, [constructor]), + PyTuple::new_bound(*py, [constructor]), ) .unwrap(); let handle = value.to_object(*py); instance - .setattr(*py, intern!(*py, "handle"), handle.clone()) + .setattr(*py, intern!(*py, "handle"), handle.clone_ref(*py)) .unwrap(); let finalizer = FINALIZE @@ -1005,7 +1056,7 @@ pub extern "C" fn componentize_py_from_canon_handle<'a>( .call1( *py, ( - instance.clone(), + instance.clone_ref(*py), DROP_RESOURCE.get().unwrap(), drop.to_object(*py), handle, @@ -1017,14 +1068,14 @@ pub extern "C" fn componentize_py_from_canon_handle<'a>( .setattr(*py, intern!(*py, "finalizer"), finalizer) .unwrap(); - instance.into_ref(*py) + instance.into_bound(*py) } } #[export_name = "componentize-py#ToCanonHandle"] pub extern "C" fn componentize_py_to_canon_handle( py: &Python, - value: &PyAny, + value: Borrowed, borrow: i32, local: i32, resource: i32, @@ -1043,7 +1094,7 @@ pub extern "C" fn componentize_py_to_canon_handle( if value.hasattr(name).unwrap() { value.getattr(name).unwrap().extract().unwrap() } else { - let rep = PyObject::from(value).into_ptr(); + let rep = PyObject::from(value.to_owned()).into_ptr(); let handle = { let params = [rep as usize]; let mut results = [MaybeUninit::::uninit()]; @@ -1068,7 +1119,7 @@ pub extern "C" fn componentize_py_to_canon_handle( .call1( *py, ( - instance.clone(), + instance.clone_ref(*py), DROP_RESOURCE.get().unwrap(), drop.to_object(*py), handle, diff --git a/src/python.rs b/src/python.rs index 48ffc60..7929430 100644 --- a/src/python.rs +++ b/src/python.rs @@ -1,5 +1,10 @@ use { - pyo3::{exceptions::PyAssertionError, types::PyModule, PyResult, Python}, + pyo3::{ + exceptions::PyAssertionError, + pybacked::PyBackedStr, + types::{PyAnyMethods, PyModule, PyModuleMethods}, + Bound, PyResult, Python, + }, std::{ffi::OsString, path::PathBuf}, tokio::runtime::Runtime, }; @@ -13,8 +18,8 @@ fn python_componentize( world: Option<&str>, features: Vec, all_features: bool, - python_path: Vec<&str>, - module_worlds: Vec<(&str, &str)>, + python_path: Vec, + module_worlds: Vec<(PyBackedStr, PyBackedStr)>, app_name: &str, output_path: PathBuf, stub_wasi: bool, @@ -25,8 +30,11 @@ fn python_componentize( world, &features, all_features, - &python_path, - &module_worlds, + &python_path.iter().map(|s| s.as_ref()).collect::>(), + &module_worlds + .iter() + .map(|(a, b)| (a.as_ref(), b.as_ref())) + .collect::>(), app_name, &output_path, None, @@ -62,7 +70,7 @@ fn python_generate_bindings( #[pyo3(name = "script")] fn python_script(py: Python) -> PyResult<()> { crate::command::run( - py.import("sys")? + py.import_bound("sys")? .getattr("argv")? .extract::>()?, ) @@ -70,10 +78,10 @@ fn python_script(py: Python) -> PyResult<()> { } #[pyo3::pymodule] -fn componentize_py(_py: Python, module: &PyModule) -> PyResult<()> { - module.add_function(pyo3::wrap_pyfunction!(python_componentize, module)?)?; - module.add_function(pyo3::wrap_pyfunction!(python_generate_bindings, module)?)?; - module.add_function(pyo3::wrap_pyfunction!(python_script, module)?)?; +fn componentize_py(_py: Python, module: Bound) -> PyResult<()> { + module.add_function(pyo3::wrap_pyfunction!(python_componentize, &module)?)?; + module.add_function(pyo3::wrap_pyfunction!(python_generate_bindings, &module)?)?; + module.add_function(pyo3::wrap_pyfunction!(python_script, &module)?)?; Ok(()) } diff --git a/test-generator/Cargo.toml b/test-generator/Cargo.toml index 9ecb9cc..9f603f4 100644 --- a/test-generator/Cargo.toml +++ b/test-generator/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition = "2021" [dependencies] -anyhow = "1.0.89" +anyhow = "1.0.91" getrandom = "0.2.15" hex = "0.4.3" proptest = "1.5.0"