diff --git a/.github/workflows/artifact.yaml b/.github/workflows/artifact.yaml index bb668905..d27805ed 100644 --- a/.github/workflows/artifact.yaml +++ b/.github/workflows/artifact.yaml @@ -7,7 +7,7 @@ env: jobs: sdist: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false env: @@ -57,7 +57,7 @@ jobs: retention-days: 1 manylinux_2_17_amd64: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -131,7 +131,7 @@ jobs: retention-days: 1 musllinux_1_2: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -204,7 +204,7 @@ jobs: retention-days: 1 manylinux_2_17_non_amd64: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: @@ -432,7 +432,7 @@ jobs: pypi: name: PyPI - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 if: "startsWith(github.ref, 'refs/tags/')" needs: [ sdist, diff --git a/.github/workflows/debug.yaml b/.github/workflows/debug.yaml index 098c0c83..d01395b1 100644 --- a/.github/workflows/debug.yaml +++ b/.github/workflows/debug.yaml @@ -3,7 +3,7 @@ on: push jobs: debug: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: fail-fast: false matrix: diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index aaa5b77c..df817411 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -2,7 +2,7 @@ name: lint on: push jobs: lint: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/setup-python@v5 with: diff --git a/Cargo.lock b/Cargo.lock index 2f13efc5..af50f431 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -32,9 +32,9 @@ checksum = "b993cd767a2bc7307dd87622311ca22c44329cc7a21366206bfa0896827b2bad" [[package]] name = "autocfg" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "beef" @@ -62,9 +62,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.96" +version = "1.0.97" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "065a29261d53ba54260972629f9ca6bffa69bac13cd1fed61420f7fa68b9f8bd" +checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4" [[package]] name = "cfg-if" @@ -132,9 +132,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "libc", @@ -174,9 +174,9 @@ checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" [[package]] name = "no-panic" -version = "0.1.29" +version = "0.1.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c711522eedec2a96bb3672ad60a03561cb28934ab1e9b97d2ecb58e07c79ef52" +checksum = "8540b7d99a20166178b42a05776aef900cdbfec397f861dfc7819bf1d7760b3d" dependencies = [ "proc-macro2", "quote", @@ -185,9 +185,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] @@ -227,9 +227,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.81" +version = "1.0.82" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +checksum = "8ad3d49ab951a01fbaafe34f2ec74122942fe18a3f9814c3268f1bb72042131b" dependencies = [ "unicode-ident", ] @@ -265,33 +265,33 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.15" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" +checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" [[package]] name = "ryu" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" dependencies = [ "no-panic", ] [[package]] name = "serde" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddc6f9cc94d67c0e21aaf7eda3a010fd3af78ebf6e096aa6e2e13c79749cce4f" +checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.200" +version = "1.0.201" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "856f046b9400cee3c8c94ed572ecdb752444c24528c035cd35882aad6f492bcb" +checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" dependencies = [ "proc-macro2", "quote", @@ -300,9 +300,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.116" +version = "1.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" dependencies = [ "itoa", "ryu", @@ -329,9 +329,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "syn" -version = "2.0.60" +version = "2.0.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +checksum = "bf5be731623ca1a1fb7d8be6f261a3be6d3e2337b8a1f97be944d020c8fcb704" dependencies = [ "proc-macro2", "quote", @@ -373,18 +373,18 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "ae87e3fcd617500e5d106f0380cf7b77f3c6092aae37191433159dda23cfb087" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "15e934569e47891f7d9411f1a451d947a60e000ab3bd24fbb970f000387d1b3b" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 63db6d36..d30d9699 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,14 +38,19 @@ unstable-simd = [] # Include runtime-detected functions that use AVX512VL. Requires unstable-simd and amd64. avx512 = [] +# Build yyjson as a backend and panic if it fails. The default is to attempt +# to build and on failure fall back to another backend. +yyjson = [] + no-panic = [ "itoa/no-panic", "ryu/no-panic", ] -# Build yyjson as a backend and panic if it fails. The default is to attempt -# to build and on failure fall back to another backend. -yyjson = [] +# Features detected by build.rs. Do not specify. +intrinsics = [] +optimize = [] +strict_provenance = [] [dependencies] ahash = { version = "^0.8.9", default-features = false, features = ["compile-time-rng"] } diff --git a/build.rs b/build.rs index 0d8477d5..0326fadb 100644 --- a/build.rs +++ b/build.rs @@ -3,6 +3,15 @@ use std::env; fn main() { + println!("cargo:rustc-check-cfg=cfg(optimize)"); + println!("cargo:rustc-check-cfg=cfg(intrinsics)"); + println!("cargo:rustc-check-cfg=cfg(Py_3_8)"); + println!("cargo:rustc-check-cfg=cfg(Py_3_9)"); + println!("cargo:rustc-check-cfg=cfg(Py_3_10)"); + println!("cargo:rustc-check-cfg=cfg(Py_3_11)"); + println!("cargo:rustc-check-cfg=cfg(Py_3_12)"); + println!("cargo:rustc-check-cfg=cfg(Py_3_13)"); + println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=include/yyjson/*"); println!("cargo:rerun-if-env-changed=CC"); diff --git a/script/develop b/script/develop index f18bb24c..039a39ef 100755 --- a/script/develop +++ b/script/develop @@ -6,6 +6,7 @@ export UNSAFE_PYO3_SKIP_VERSION_CHECK=1 export CC="${CC:-clang}" export LD="${LD:-lld}" +export TARGET="${TARGET:-x86_64-unknown-linux-gnu}" echo "CC: ${CC}, LD: ${LD}, LD_LIBRARY_PATH: ${LD_LIBRARY_PATH}" @@ -13,6 +14,6 @@ export CFLAGS="-Os -fstrict-aliasing -fno-plt -flto=full -emit-llvm" export LDFLAGS="-fuse-ld=${LD} -Wl,-plugin-opt=also-emit-llvm -Wl,--as-needed -Wl,-zrelro,-znow" export RUSTFLAGS="-C linker=${CC} -C link-arg=-fuse-ld=${LD} -C linker-plugin-lto -C lto=fat -C link-arg=-Wl,-zrelro,-znow -Z mir-opt-level=4 -Z virtual-function-elimination -Z threads=8" -maturin build "$@" +maturin build --target="${TARGET}" "$@" uv pip install target/wheels/*.whl diff --git a/src/lib.rs b/src/lib.rs index 0f501828..ea7d3dcf 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -323,7 +323,7 @@ pub unsafe extern "C" fn dumps( if num_args & 3 == 3 { optsptr = Some(NonNull::new_unchecked(*args.offset(2))); } - if !kwnames.is_null() { + if unlikely!(!kwnames.is_null()) { for i in 0..=Py_SIZE(kwnames).saturating_sub(1) { let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t); if arg == typeref::DEFAULT { @@ -347,15 +347,15 @@ pub unsafe extern "C" fn dumps( } let mut optsbits: i32 = 0; - if let Some(opts) = optsptr { - if opts.as_ptr() == typeref::NONE { - } else if (*opts.as_ptr()).ob_type != typeref::INT_TYPE { - return raise_dumps_exception_fixed("Invalid opts"); - } else { + if unlikely!(optsptr.is_some()) { + let opts = optsptr.unwrap(); + if (*opts.as_ptr()).ob_type == typeref::INT_TYPE { optsbits = PyLong_AsLong(optsptr.unwrap().as_ptr()) as i32; - if !(0..=opt::MAX_OPT).contains(&optsbits) { + if unlikely!(!(0..=opt::MAX_OPT).contains(&optsbits)) { return raise_dumps_exception_fixed("Invalid opts"); } + } else if unlikely!(opts.as_ptr() != typeref::NONE) { + return raise_dumps_exception_fixed("Invalid opts"); } } diff --git a/src/serialize/per_type/fragment.rs b/src/serialize/per_type/fragment.rs index c3b2e74c..e0614d67 100644 --- a/src/serialize/per_type/fragment.rs +++ b/src/serialize/per_type/fragment.rs @@ -26,25 +26,24 @@ impl Serialize for FragmentSerializer { where S: Serializer, { - let buffer: &[u8]; unsafe { let fragment: *mut Fragment = self.ptr as *mut Fragment; let ob_type = ob_type!((*fragment).contents); - if ob_type == BYTES_TYPE { - buffer = core::slice::from_raw_parts( + let buffer: &[u8] = if ob_type == BYTES_TYPE { + core::slice::from_raw_parts( PyBytes_AS_STRING((*fragment).contents) as *const u8, PyBytes_GET_SIZE((*fragment).contents) as usize, - ); + ) } else if ob_type == STR_TYPE { let uni = unicode_to_str((*fragment).contents); if unlikely!(uni.is_none()) { err!(SerializeError::InvalidStr) } - buffer = uni.unwrap().as_bytes(); + uni.unwrap().as_bytes() } else { err!(SerializeError::InvalidFragment) - } + }; + serializer.serialize_bytes(buffer) } - serializer.serialize_bytes(buffer) } } diff --git a/src/serialize/writer/json.rs b/src/serialize/writer/json.rs index bcfce2a5..34fbab3d 100644 --- a/src/serialize/writer/json.rs +++ b/src/serialize/writer/json.rs @@ -593,7 +593,35 @@ where } } -#[cfg(all(feature = "unstable-simd", target_arch = "x86_64", feature = "avx512"))] +#[cfg(all( + feature = "unstable-simd", + target_arch = "x86_64", + feature = "avx512", + target_feature = "avx512vl" +))] +#[inline(always)] +fn format_escaped_str(writer: &mut W, value: &str) +where + W: ?Sized + io::Write + WriteExt, +{ + unsafe { + reserve_str!(writer, value); + + let written = format_escaped_str_impl_512vl( + writer.as_mut_buffer_ptr(), + value.as_bytes().as_ptr(), + value.len(), + ); + writer.set_written(written); + } +} + +#[cfg(all( + feature = "unstable-simd", + target_arch = "x86_64", + feature = "avx512", + not(target_feature = "avx512vl") +))] #[inline(always)] fn format_escaped_str(writer: &mut W, value: &str) where