Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 9c33ff9

Browse files
committed
Fix big-endian PyStr
1 parent 3b03a4a commit 9c33ff9

File tree

3 files changed

+72
-23
lines changed

3 files changed

+72
-23
lines changed

.github/workflows/artifact.yaml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,35 @@ jobs:
269269
if-no-files-found: "error"
270270
compression-level: 0
271271

272+
- name: setup-qemu-container
273+
if: "matrix.target.arch == 's390x'"
274+
uses: sandervocke/setup-qemu-container@v1
275+
with:
276+
container: registry.fedoraproject.org/fedora:42
277+
arch: ${{ matrix.target.arch }}
278+
podman_args: "-v .:/orjson -v /tmp:/tmp --workdir /orjson"
279+
280+
- name: setup-shell-wrapper
281+
uses: sandervocke/setup-shell-wrapper@v1
282+
283+
- name: Emulated Test
284+
if: "matrix.target.arch == 's390x'"
285+
shell: wrap-shell {0}
286+
env:
287+
WRAP_SHELL: run-in-container.sh
288+
run: |
289+
set -eou pipefail
290+
291+
dnf install --setopt=install_weak_deps=false -y ${{ matrix.python.interpreter }} python3-uv
292+
293+
uv venv --python ${{ matrix.python.interpreter }}
294+
source .venv/bin/activate
295+
296+
uv pip install -r test/requirements.txt
297+
uv pip install dist/orjson*.whl
298+
299+
pytest -v test
300+
272301
musllinux_amd64:
273302
runs-on: ubuntu-24.04
274303
timeout-minutes: 10

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1088,8 +1088,9 @@ is prudent to pin the nightly version because that channel can introduce
10881088
breaking changes. There is a significant performance benefit to using
10891089
nightly.
10901090

1091-
orjson is tested for amd64, aarch64, and i686 on Linux and cross-compiles for
1092-
arm7, ppc64le, and s390x. It is tested for either aarch64 or amd64 on macOS and
1091+
orjson is tested on native hardware for amd64, aarch64, and i686 on Linux and
1092+
for arm7, ppc64le, and s390x is cross-compiled and may be tested via
1093+
emulation. It is tested for either aarch64 or amd64 on macOS and
10931094
cross-compiles for the other, depending on version. For Windows it is
10941095
tested on amd64 and i686.
10951096

src/str/pystr.rs

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
// SPDX-License-Identifier: (Apache-2.0 OR MIT)
22

33
use crate::typeref::{EMPTY_UNICODE, STR_TYPE};
4+
#[cfg(target_endian = "little")]
45
use crate::util::isize_to_usize;
5-
6+
#[cfg(target_endian = "little")]
67
use core::ffi::c_void;
78
use core::ptr::NonNull;
8-
use pyo3_ffi::{PyASCIIObject, PyCompactUnicodeObject, PyObject};
9+
#[cfg(target_endian = "little")]
10+
use pyo3_ffi::PyCompactUnicodeObject;
11+
use pyo3_ffi::{PyASCIIObject, PyObject};
912

1013
fn to_str_via_ffi(op: *mut PyObject) -> Option<&'static str> {
1114
let mut str_size: pyo3_ffi::Py_ssize_t = 0;
@@ -32,29 +35,21 @@ pub fn set_str_create_fn() {
3235
}
3336
}
3437

35-
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
36-
const STATE_COMPACT_ASCII: u32 = u32::from_le(0b000000000000000000_0_1_1_001_00000000);
37-
38-
#[cfg(not(all(Py_3_14, Py_GIL_DISABLED)))]
39-
const STATE_COMPACT_ASCII: u32 = u32::from_le(0b000000000000000000000000_0_1_1_001_00);
40-
41-
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
42-
const STATE_COMPACT: u32 = u32::from_le(0b000000000000000000_0_0_1_000_00000000);
43-
44-
#[cfg(not(all(Py_3_14, Py_GIL_DISABLED)))]
45-
const STATE_COMPACT: u32 = u32::from_le(0b000000000000000000000000_0_0_1_000_00);
38+
#[cfg(all(target_endian = "little", Py_3_14, Py_GIL_DISABLED))]
39+
const STATE_KIND_SHIFT: usize = 8;
4640

47-
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
48-
const STATE_KIND_MASK: u32 = u32::from_le(0b111_00000000);
41+
#[cfg(all(target_endian = "little", not(all(Py_3_14, Py_GIL_DISABLED))))]
42+
const STATE_KIND_SHIFT: usize = 2;
4943

50-
#[cfg(all(Py_3_14, Py_GIL_DISABLED))]
51-
const STATE_KIND_SHIFT: usize = 8;
44+
#[cfg(target_endian = "little")]
45+
const STATE_KIND_MASK: u32 = 7 << STATE_KIND_SHIFT;
5246

53-
#[cfg(not(all(Py_3_14, Py_GIL_DISABLED)))]
54-
const STATE_KIND_MASK: u32 = u32::from_le(0b111_00);
47+
#[cfg(target_endian = "little")]
48+
const STATE_COMPACT_ASCII: u32 =
49+
1 << STATE_KIND_SHIFT | 1 << (STATE_KIND_SHIFT + 3) | 1 << (STATE_KIND_SHIFT + 4);
5550

56-
#[cfg(not(all(Py_3_14, Py_GIL_DISABLED)))]
57-
const STATE_KIND_SHIFT: usize = 2;
51+
#[cfg(target_endian = "little")]
52+
const STATE_COMPACT: u32 = 1 << (STATE_KIND_SHIFT + 3);
5853

5954
#[repr(transparent)]
6055
#[derive(Copy, Clone)]
@@ -96,6 +91,7 @@ impl PyStr {
9691
}
9792
}
9893

94+
#[cfg(target_endian = "little")]
9995
pub fn hash(&mut self) {
10096
unsafe {
10197
let ptr = self.ptr.as_ptr().cast::<PyASCIIObject>();
@@ -118,7 +114,24 @@ impl PyStr {
118114
}
119115
}
120116

117+
#[cfg(not(target_endian = "little"))]
118+
pub fn hash(&mut self) {
119+
unsafe {
120+
let data_ptr = ffi!(PyUnicode_DATA(self.ptr.as_ptr()));
121+
#[allow(clippy::cast_possible_wrap)]
122+
let num_bytes =
123+
ffi!(PyUnicode_KIND(self.ptr.as_ptr())) as isize * ffi!(Py_SIZE(self.ptr.as_ptr()));
124+
#[cfg(Py_3_14)]
125+
let hash = pyo3_ffi::Py_HashBuffer(data_ptr, num_bytes);
126+
#[cfg(not(Py_3_14))]
127+
let hash = pyo3_ffi::_Py_HashBytes(data_ptr, num_bytes);
128+
(*self.ptr.as_ptr().cast::<PyASCIIObject>()).hash = hash;
129+
debug_assert!((*self.ptr.as_ptr().cast::<PyASCIIObject>()).hash != -1);
130+
}
131+
}
132+
121133
#[inline(always)]
134+
#[cfg(target_endian = "little")]
122135
pub fn to_str(self) -> Option<&'static str> {
123136
unsafe {
124137
let op = self.ptr.as_ptr();
@@ -140,6 +153,12 @@ impl PyStr {
140153
}
141154
}
142155

156+
#[inline(always)]
157+
#[cfg(not(target_endian = "little"))]
158+
pub fn to_str(self) -> Option<&'static str> {
159+
to_str_via_ffi(self.ptr.as_ptr())
160+
}
161+
143162
pub fn as_ptr(self) -> *mut PyObject {
144163
self.ptr.as_ptr()
145164
}

0 commit comments

Comments
 (0)