|
| 1 | +diff --git a/src/deserialize/deserializer.rs b/src/deserialize/deserializer.rs |
| 2 | +index 41cf7f1..99cd68e 100644 |
| 3 | +--- a/src/deserialize/deserializer.rs |
| 4 | ++++ b/src/deserialize/deserializer.rs |
| 5 | +@@ -292,7 +292,10 @@ impl<'de> Deserializer<'de> { |
| 6 | + marker => Err(Error::InvalidType(marker)), |
| 7 | + }?; |
| 8 | + let value = self.deserialize()?; |
| 9 | ++ #[cfg(not(GraalPy))] |
| 10 | + let pyhash = unsafe { (*key.as_ptr().cast::<pyo3::ffi::PyASCIIObject>()).hash }; |
| 11 | ++ #[cfg(GraalPy)] |
| 12 | ++ let pyhash = unsafe { pyo3::ffi::PyObject_Hash(key.as_ptr()) }; |
| 13 | + let _ = ffi!(_PyDict_SetItem_KnownHash( |
| 14 | + dict_ptr, |
| 15 | + key.as_ptr(), |
| 16 | +@@ -471,7 +474,7 @@ impl<'de> Deserializer<'de> { |
| 17 | + let ptr = ffi!(PyTuple_New(len as pyo3::ffi::Py_ssize_t)); |
| 18 | + for i in 0..len { |
| 19 | + let elem = self.deserialize_map_key()?; |
| 20 | +- ffi!(PyTuple_SET_ITEM( |
| 21 | ++ ffi!(PyTuple_SetItem( |
| 22 | + ptr, |
| 23 | + i as pyo3::ffi::Py_ssize_t, |
| 24 | + elem.as_ptr() |
| 25 | +diff --git a/src/ext.rs b/src/ext.rs |
| 26 | +index b2573b4..9668d4f 100644 |
| 27 | +--- a/src/ext.rs |
| 28 | ++++ b/src/ext.rs |
| 29 | +@@ -22,7 +22,7 @@ unsafe extern "C" fn ext_new( |
| 30 | + ); |
| 31 | + return null_mut(); |
| 32 | + } |
| 33 | +- let tag = PyTuple_GET_ITEM(args, 0); |
| 34 | ++ let tag = PyTuple_GetItem(args, 0); |
| 35 | + if PyLong_Check(tag) == 0 { |
| 36 | + PyErr_SetString( |
| 37 | + PyExc_TypeError, |
| 38 | +@@ -30,7 +30,7 @@ unsafe extern "C" fn ext_new( |
| 39 | + ); |
| 40 | + return null_mut(); |
| 41 | + } |
| 42 | +- let data = PyTuple_GET_ITEM(args, 1); |
| 43 | ++ let data = PyTuple_GetItem(args, 1); |
| 44 | + if PyBytes_Check(data) == 0 { |
| 45 | + PyErr_SetString( |
| 46 | + PyExc_TypeError, |
| 47 | +diff --git a/src/ffi.rs b/src/ffi.rs |
| 48 | +index 4e5ddc3..20c9db4 100644 |
| 49 | +--- a/src/ffi.rs |
| 50 | ++++ b/src/ffi.rs |
| 51 | +@@ -7,13 +7,16 @@ use std::ptr::NonNull; |
| 52 | + #[allow(non_snake_case)] |
| 53 | + #[inline(always)] |
| 54 | + pub unsafe fn PyBytes_AS_STRING(op: *mut PyObject) -> *const c_char { |
| 55 | +- &(*op.cast::<PyBytesObject>()).ob_sval as *const c_char |
| 56 | ++ #[cfg(not(any(PyPy, GraalPy, Py_LIMITED_API)))] |
| 57 | ++ return &(*op.cast::<PyBytesObject>()).ob_sval as *const c_char; |
| 58 | ++ #[cfg(any(PyPy, GraalPy, Py_LIMITED_API))] |
| 59 | ++ return crate::PyBytes_AsString(op); |
| 60 | + } |
| 61 | + |
| 62 | + #[allow(non_snake_case)] |
| 63 | + #[inline(always)] |
| 64 | + pub unsafe fn PyBytes_GET_SIZE(op: *mut PyObject) -> Py_ssize_t { |
| 65 | +- (*op.cast::<PyVarObject>()).ob_size |
| 66 | ++ Py_SIZE(op) |
| 67 | + } |
| 68 | + |
| 69 | + #[repr(C)] |
| 70 | +@@ -63,11 +66,21 @@ pub fn pylong_is_positive(op: *mut PyObject) -> bool { |
| 71 | + unsafe { (*(op as *mut PyLongObject)).long_value.lv_tag & SIGN_MASK == 0 } |
| 72 | + } |
| 73 | + |
| 74 | +-#[cfg(not(Py_3_12))] |
| 75 | ++#[cfg(not(any(Py_3_12, GraalPy)))] |
| 76 | + pub fn pylong_is_positive(op: *mut PyObject) -> bool { |
| 77 | + unsafe { (*(op as *mut PyVarObject)).ob_size > 0 } |
| 78 | + } |
| 79 | + |
| 80 | ++extern "C" { |
| 81 | ++ #[cfg(not(PyPy))] |
| 82 | ++ pub fn _PyLong_Sign(v: *mut PyObject) -> c_int; |
| 83 | ++} |
| 84 | ++ |
| 85 | ++#[cfg(GraalPy)] |
| 86 | ++pub fn pylong_is_positive(op: *mut PyObject) -> bool { |
| 87 | ++ unsafe { _PyLong_Sign(op) > 0 } |
| 88 | ++} |
| 89 | ++ |
| 90 | + pub struct PyDictIter { |
| 91 | + op: *mut PyObject, |
| 92 | + pos: isize, |
| 93 | +diff --git a/src/lib.rs b/src/lib.rs |
| 94 | +index f10b1c4..1a9768b 100644 |
| 95 | +--- a/src/lib.rs |
| 96 | ++++ b/src/lib.rs |
| 97 | +@@ -143,7 +143,7 @@ fn raise_unpackb_exception(msg: &str) -> *mut PyObject { |
| 98 | + let err_msg = |
| 99 | + PyUnicode_FromStringAndSize(msg.as_ptr() as *const c_char, msg.len() as isize); |
| 100 | + let args = PyTuple_New(1); |
| 101 | +- PyTuple_SET_ITEM(args, 0, err_msg); |
| 102 | ++ PyTuple_SetItem(args, 0, err_msg); |
| 103 | + PyErr_SetObject(typeref::MsgpackDecodeError, args); |
| 104 | + Py_DECREF(args); |
| 105 | + }; |
| 106 | +@@ -199,10 +199,10 @@ pub unsafe extern "C" fn unpackb( |
| 107 | + if !kwnames.is_null() { |
| 108 | + let tuple_size = PyTuple_GET_SIZE(kwnames); |
| 109 | + for i in 0..tuple_size { |
| 110 | +- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t); |
| 111 | +- if arg == typeref::EXT_HOOK { |
| 112 | ++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t); |
| 113 | ++ if PyUnicode_Compare(arg, typeref::EXT_HOOK) == 0 { |
| 114 | + ext_hook = Some(NonNull::new_unchecked(*args.offset(num_args + i))); |
| 115 | +- } else if arg == typeref::OPTION { |
| 116 | ++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 { |
| 117 | + optsptr = Some(NonNull::new_unchecked(*args.offset(num_args + i))); |
| 118 | + } else { |
| 119 | + return raise_unpackb_exception("unpackb() got an unexpected keyword argument"); |
| 120 | +@@ -247,15 +247,15 @@ pub unsafe extern "C" fn packb( |
| 121 | + if !kwnames.is_null() { |
| 122 | + let tuple_size = PyTuple_GET_SIZE(kwnames); |
| 123 | + for i in 0..tuple_size { |
| 124 | +- let arg = PyTuple_GET_ITEM(kwnames, i as Py_ssize_t); |
| 125 | +- if arg == typeref::DEFAULT { |
| 126 | ++ let arg = PyTuple_GetItem(kwnames, i as Py_ssize_t); |
| 127 | ++ if PyUnicode_Compare(arg, typeref::DEFAULT) == 0 { |
| 128 | + if unlikely!(default.is_some()) { |
| 129 | + return raise_packb_exception( |
| 130 | + "packb() got multiple values for argument: 'default'", |
| 131 | + ); |
| 132 | + } |
| 133 | + default = Some(NonNull::new_unchecked(*args.offset(num_args + i))); |
| 134 | +- } else if arg == typeref::OPTION { |
| 135 | ++ } else if PyUnicode_Compare(arg, typeref::OPTION) == 0 { |
| 136 | + if unlikely!(optsptr.is_some()) { |
| 137 | + return raise_packb_exception( |
| 138 | + "packb() got multiple values for argument: 'option'", |
| 139 | +diff --git a/src/serialize/datetime.rs b/src/serialize/datetime.rs |
| 140 | +index 63212d6..5ac2b2b 100644 |
| 141 | +--- a/src/serialize/datetime.rs |
| 142 | ++++ b/src/serialize/datetime.rs |
| 143 | +@@ -61,9 +61,14 @@ pub struct Time { |
| 144 | + |
| 145 | + impl Time { |
| 146 | + pub fn new(ptr: *mut pyo3::ffi::PyObject, opts: Opt) -> Result<Self, TimeError> { |
| 147 | ++ #[cfg(not(GraalPy))] |
| 148 | + if unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_Time)).hastzinfo != 0 } { |
| 149 | + return Err(TimeError::HasTimezone); |
| 150 | + } |
| 151 | ++ #[cfg(GraalPy)] |
| 152 | ++ if unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(ptr) != crate::typeref::NONE } { |
| 153 | ++ return Err(TimeError::HasTimezone); |
| 154 | ++ } |
| 155 | + Ok(Time { |
| 156 | + ptr: ptr, |
| 157 | + opts: opts, |
| 158 | +@@ -114,23 +119,28 @@ impl std::fmt::Display for DateTimeError { |
| 159 | + } |
| 160 | + |
| 161 | + fn utcoffset(ptr: *mut pyo3::ffi::PyObject) -> Result<Offset, DateTimeError> { |
| 162 | ++ #[cfg(not(GraalPy))] |
| 163 | + if !unsafe { (*(ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } { |
| 164 | + return Ok(Offset::default()); |
| 165 | + } |
| 166 | + |
| 167 | + let tzinfo = ffi!(PyDateTime_DATE_GET_TZINFO(ptr)); |
| 168 | ++ #[cfg(GraalPy)] |
| 169 | ++ if unsafe { tzinfo == crate::typeref::NONE } { |
| 170 | ++ return Ok(Offset::default()); |
| 171 | ++ } |
| 172 | + let py_offset: *mut pyo3::ffi::PyObject; |
| 173 | + if ffi!(PyObject_HasAttr(tzinfo, CONVERT_METHOD_STR)) == 1 { |
| 174 | + // pendulum |
| 175 | +- py_offset = ffi!(PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR)); |
| 176 | ++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(ptr, UTCOFFSET_METHOD_STR) }; |
| 177 | + } else if ffi!(PyObject_HasAttr(tzinfo, NORMALIZE_METHOD_STR)) == 1 { |
| 178 | + // pytz |
| 179 | +- let normalized = ffi!(PyObject_CallMethodOneArg(tzinfo, NORMALIZE_METHOD_STR, ptr)); |
| 180 | +- py_offset = ffi!(PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR)); |
| 181 | ++ let normalized = ffi!(PyObject_CallMethodObjArgs(tzinfo, NORMALIZE_METHOD_STR, ptr, std::ptr::null_mut::<crate::PyObject>())); |
| 182 | ++ py_offset = unsafe { pyo3::ffi::compat::PyObject_CallMethodNoArgs(normalized, UTCOFFSET_METHOD_STR) }; |
| 183 | + ffi!(Py_DECREF(normalized)); |
| 184 | + } else if ffi!(PyObject_HasAttr(tzinfo, DST_STR)) == 1 { |
| 185 | + // dateutil/arrow, datetime.timezone.utc |
| 186 | +- py_offset = ffi!(PyObject_CallMethodOneArg(tzinfo, UTCOFFSET_METHOD_STR, ptr)); |
| 187 | ++ py_offset = ffi!(PyObject_CallMethodObjArgs(tzinfo, UTCOFFSET_METHOD_STR, ptr, std::ptr::null_mut::<crate::PyObject>())); |
| 188 | + } else { |
| 189 | + return Err(DateTimeError::LibraryUnsupported); |
| 190 | + } |
| 191 | +@@ -193,7 +203,10 @@ impl TimeLike for DateTime { |
| 192 | + |
| 193 | + impl DateTimeLike for DateTime { |
| 194 | + fn has_tz(&self) -> bool { |
| 195 | +- unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 } |
| 196 | ++ #[cfg(not(GraalPy))] |
| 197 | ++ return unsafe { (*(self.ptr as *mut pyo3::ffi::PyDateTime_DateTime)).hastzinfo == 1 }; |
| 198 | ++ #[cfg(GraalPy)] |
| 199 | ++ return unsafe { pyo3::ffi::PyDateTime_TIME_GET_TZINFO(self.ptr) != crate::typeref::NONE }; |
| 200 | + } |
| 201 | + |
| 202 | + fn offset(&self) -> Offset { |
| 203 | +diff --git a/src/serialize/numpy.rs b/src/serialize/numpy.rs |
| 204 | +index afc5cdf..4d007bd 100644 |
| 205 | +--- a/src/serialize/numpy.rs |
| 206 | ++++ b/src/serialize/numpy.rs |
| 207 | +@@ -392,8 +392,8 @@ impl NumpyDatetimeUnit { |
| 208 | + fn from_pyobject(ptr: *mut PyObject) -> Self { |
| 209 | + let dtype = ffi!(PyObject_GetAttr(ptr, DTYPE_STR)); |
| 210 | + let descr = ffi!(PyObject_GetAttr(dtype, DESCR_STR)); |
| 211 | +- let el0 = ffi!(PyList_GET_ITEM(descr, 0)); |
| 212 | +- let descr_str = ffi!(PyTuple_GET_ITEM(el0, 1)); |
| 213 | ++ let el0 = ffi!(PyList_GetItem(descr, 0)); |
| 214 | ++ let descr_str = ffi!(PyTuple_GetItem(el0, 1)); |
| 215 | + let uni = crate::unicode::unicode_to_str(descr_str).unwrap(); |
| 216 | + if uni.len() < 5 { |
| 217 | + return Self::NaT; |
| 218 | +diff --git a/src/serialize/serializer.rs b/src/serialize/serializer.rs |
| 219 | +index 309e6e1..6f7dec7 100644 |
| 220 | +--- a/src/serialize/serializer.rs |
| 221 | ++++ b/src/serialize/serializer.rs |
| 222 | +@@ -864,7 +864,7 @@ impl Serialize for DictTupleKey { |
| 223 | + let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize; |
| 224 | + let mut seq = serializer.serialize_seq(Some(len)).unwrap(); |
| 225 | + for i in 0..len { |
| 226 | +- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize)); |
| 227 | ++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize)); |
| 228 | + let value = DictKey::new(item, self.opts, self.recursion + 1); |
| 229 | + seq.serialize_element(&value)?; |
| 230 | + } |
| 231 | +diff --git a/src/serialize/tuple.rs b/src/serialize/tuple.rs |
| 232 | +index fa81cb6..9b66019 100644 |
| 233 | +--- a/src/serialize/tuple.rs |
| 234 | ++++ b/src/serialize/tuple.rs |
| 235 | +@@ -41,7 +41,7 @@ impl Serialize for Tuple { |
| 236 | + let len = ffi!(PyTuple_GET_SIZE(self.ptr)) as usize; |
| 237 | + let mut seq = serializer.serialize_seq(Some(len)).unwrap(); |
| 238 | + for i in 0..len { |
| 239 | +- let item = ffi!(PyTuple_GET_ITEM(self.ptr, i as isize)); |
| 240 | ++ let item = ffi!(PyTuple_GetItem(self.ptr, i as isize)); |
| 241 | + let value = PyObject::new( |
| 242 | + item, |
| 243 | + self.opts, |
| 244 | +diff --git a/src/serialize/writer.rs b/src/serialize/writer.rs |
| 245 | +index a790bdd..35346d9 100644 |
| 246 | +--- a/src/serialize/writer.rs |
| 247 | ++++ b/src/serialize/writer.rs |
| 248 | +@@ -27,7 +27,6 @@ impl BytesWriter { |
| 249 | + pub fn finish(&mut self) -> NonNull<PyObject> { |
| 250 | + unsafe { |
| 251 | + std::ptr::write(self.buffer_ptr(), 0); |
| 252 | +- (*self.bytes.cast::<PyVarObject>()).ob_size = self.len as Py_ssize_t; |
| 253 | + self.resize(self.len); |
| 254 | + NonNull::new_unchecked(self.bytes as *mut PyObject) |
| 255 | + } |
| 256 | +@@ -35,10 +34,14 @@ impl BytesWriter { |
| 257 | + |
| 258 | + fn buffer_ptr(&self) -> *mut u8 { |
| 259 | + unsafe { |
| 260 | +- std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!( |
| 261 | ++ #[cfg(not(GraalPy))] |
| 262 | ++ return std::mem::transmute::<*mut [c_char; 1], *mut u8>(std::ptr::addr_of_mut!( |
| 263 | + (*self.bytes).ob_sval |
| 264 | + )) |
| 265 | +- .add(self.len) |
| 266 | ++ .add(self.len); |
| 267 | ++ #[cfg(GraalPy)] |
| 268 | ++ return std::mem::transmute::<*mut i8, *mut u8>(PyBytes_AsString(self.bytes.cast::<PyObject>())) |
| 269 | ++ .add(self.len); |
| 270 | + } |
| 271 | + } |
| 272 | + |
| 273 | +diff --git a/src/unicode.rs b/src/unicode.rs |
| 274 | +index 53aca09..552fa6c 100644 |
| 275 | +--- a/src/unicode.rs |
| 276 | ++++ b/src/unicode.rs |
| 277 | +@@ -6,6 +6,7 @@ use pyo3::ffi::*; |
| 278 | + |
| 279 | + // see unicodeobject.h for documentation |
| 280 | + |
| 281 | ++#[cfg(not(GraalPy))] |
| 282 | + pub fn unicode_from_str(buf: &str) -> *mut PyObject { |
| 283 | + if buf.is_empty() { |
| 284 | + ffi!(Py_INCREF(EMPTY_UNICODE)); |
| 285 | +@@ -27,6 +28,13 @@ pub fn unicode_from_str(buf: &str) -> *mut PyObject { |
| 286 | + } |
| 287 | + } |
| 288 | + |
| 289 | ++#[cfg(GraalPy)] |
| 290 | ++pub fn unicode_from_str(buf: &str) -> *mut PyObject { |
| 291 | ++ unsafe { |
| 292 | ++ PyUnicode_FromStringAndSize(buf.as_ptr() as *const i8, buf.len() as isize) |
| 293 | ++ } |
| 294 | ++} |
| 295 | ++ |
| 296 | + fn pyunicode_ascii(buf: &str) -> *mut PyObject { |
| 297 | + unsafe { |
| 298 | + let ptr = ffi!(PyUnicode_New(buf.len() as isize, 127)); |
| 299 | +@@ -80,6 +88,7 @@ fn pyunicode_fourbyte(buf: &str, num_chars: usize) -> *mut PyObject { |
| 300 | + |
| 301 | + #[inline] |
| 302 | + pub fn hash_str(op: *mut PyObject) -> Py_hash_t { |
| 303 | ++ #[cfg(not(GraalPy))] |
| 304 | + unsafe { |
| 305 | + let data_ptr: *mut c_void = if (*op.cast::<PyASCIIObject>()).compact() == 1 |
| 306 | + && (*op.cast::<PyASCIIObject>()).ascii() == 1 |
| 307 | +@@ -92,7 +101,11 @@ pub fn hash_str(op: *mut PyObject) -> Py_hash_t { |
| 308 | + (*(op as *mut PyASCIIObject)).length * ((*(op as *mut PyASCIIObject)).kind()) as isize; |
| 309 | + let hash = _Py_HashBytes(data_ptr, num_bytes); |
| 310 | + (*op.cast::<PyASCIIObject>()).hash = hash; |
| 311 | +- hash |
| 312 | ++ return hash; |
| 313 | ++ } |
| 314 | ++ #[cfg(GraalPy)] |
| 315 | ++ unsafe { |
| 316 | ++ return PyObject_Hash(op); |
| 317 | + } |
| 318 | + } |
| 319 | + |
| 320 | +@@ -109,19 +122,24 @@ pub fn unicode_to_str_via_ffi(op: *mut PyObject) -> Option<&'static str> { |
| 321 | + |
| 322 | + #[inline] |
| 323 | + pub fn unicode_to_str(op: *mut PyObject) -> Option<&'static str> { |
| 324 | ++ #[cfg(not(GraalPy))] |
| 325 | + unsafe { |
| 326 | + if unlikely!((*op.cast::<PyASCIIObject>()).compact() == 0) { |
| 327 | +- unicode_to_str_via_ffi(op) |
| 328 | ++ return unicode_to_str_via_ffi(op); |
| 329 | + } else if (*op.cast::<PyASCIIObject>()).ascii() == 1 { |
| 330 | + let ptr = op.cast::<PyASCIIObject>().offset(1) as *const u8; |
| 331 | + let len = (*op.cast::<PyASCIIObject>()).length as usize; |
| 332 | +- Some(str_from_slice!(ptr, len)) |
| 333 | ++ return Some(str_from_slice!(ptr, len)); |
| 334 | + } else if (*op.cast::<PyCompactUnicodeObject>()).utf8_length != 0 { |
| 335 | + let ptr = (*op.cast::<PyCompactUnicodeObject>()).utf8 as *const u8; |
| 336 | + let len = (*op.cast::<PyCompactUnicodeObject>()).utf8_length as usize; |
| 337 | +- Some(str_from_slice!(ptr, len)) |
| 338 | ++ return Some(str_from_slice!(ptr, len)); |
| 339 | + } else { |
| 340 | +- unicode_to_str_via_ffi(op) |
| 341 | ++ return unicode_to_str_via_ffi(op); |
| 342 | + } |
| 343 | + } |
| 344 | ++ #[cfg(GraalPy)] |
| 345 | ++ unsafe { |
| 346 | ++ return unicode_to_str_via_ffi(op); |
| 347 | ++ } |
| 348 | + } |
| 349 | +diff --git a/src/util.rs b/src/util.rs |
| 350 | +index 2bcc32d..89faf1a 100644 |
| 351 | +--- a/src/util.rs |
| 352 | ++++ b/src/util.rs |
| 353 | +@@ -8,7 +8,7 @@ macro_rules! py_is { |
| 354 | + |
| 355 | + macro_rules! ob_type { |
| 356 | + ($obj:expr) => { |
| 357 | +- unsafe { (*($obj as *mut pyo3::ffi::PyObject)).ob_type } |
| 358 | ++ unsafe { pyo3::ffi::Py_TYPE($obj as *mut pyo3::ffi::PyObject) } |
| 359 | + }; |
| 360 | + } |
| 361 | + |
| 362 | +-- |
| 363 | +2.43.0 |
| 364 | + |
0 commit comments