src/ffi/fragment.rs (177 lines of code) (raw):

// SPDX-License-Identifier: (Apache-2.0 OR MIT) use core::ffi::c_char; #[cfg(Py_GIL_DISABLED)] use std::sync::atomic::{AtomicIsize, AtomicU32, AtomicU64}; use core::ptr::null_mut; use pyo3_ffi::*; // https://docs.python.org/3/c-api/typeobj.html#typedef-examples #[cfg(Py_GIL_DISABLED)] #[allow(non_upper_case_globals)] const _Py_IMMORTAL_REFCNT_LOCAL: u32 = u32::MAX; #[repr(C)] pub struct Fragment { #[cfg(Py_GIL_DISABLED)] pub ob_tid: usize, #[cfg(Py_GIL_DISABLED)] pub _padding: u16, #[cfg(Py_GIL_DISABLED)] pub ob_mutex: PyMutex, #[cfg(Py_GIL_DISABLED)] pub ob_gc_bits: u8, #[cfg(Py_GIL_DISABLED)] pub ob_ref_local: AtomicU32, #[cfg(Py_GIL_DISABLED)] pub ob_ref_shared: AtomicIsize, #[cfg(not(Py_GIL_DISABLED))] pub ob_refcnt: pyo3_ffi::Py_ssize_t, pub ob_type: *mut pyo3_ffi::PyTypeObject, pub contents: *mut pyo3_ffi::PyObject, } #[cold] #[inline(never)] #[cfg_attr(feature = "optimize", optimize(size))] fn raise_args_exception() { unsafe { let msg = "orjson.Fragment() takes exactly 1 positional argument"; let err_msg = PyUnicode_FromStringAndSize(msg.as_ptr() as *const c_char, msg.len() as isize); PyErr_SetObject(PyExc_TypeError, err_msg); Py_DECREF(err_msg); }; } #[unsafe(no_mangle)] #[cold] #[cfg_attr(feature = "optimize", optimize(size))] pub unsafe extern "C" fn orjson_fragment_tp_new( _subtype: *mut PyTypeObject, args: *mut PyObject, kwds: *mut PyObject, ) -> *mut PyObject { unsafe { if Py_SIZE(args) != 1 || !kwds.is_null() { raise_args_exception(); null_mut() } else { let contents = PyTuple_GET_ITEM(args, 0); Py_INCREF(contents); let obj = Box::new(Fragment { #[cfg(Py_GIL_DISABLED)] ob_tid: 0, #[cfg(Py_GIL_DISABLED)] _padding: 0, #[cfg(Py_GIL_DISABLED)] ob_mutex: PyMutex::new(), #[cfg(Py_GIL_DISABLED)] ob_gc_bits: 0, #[cfg(Py_GIL_DISABLED)] ob_ref_local: AtomicU32::new(0), #[cfg(Py_GIL_DISABLED)] ob_ref_shared: AtomicIsize::new(0), #[cfg(not(Py_GIL_DISABLED))] ob_refcnt: 1, ob_type: crate::typeref::FRAGMENT_TYPE, contents: contents, }); Box::into_raw(obj) as *mut PyObject } } } #[unsafe(no_mangle)] #[cold] #[cfg_attr(feature = "optimize", optimize(size))] pub unsafe extern "C" fn orjson_fragment_dealloc(object: *mut PyObject) { unsafe { Py_DECREF((*(object as *mut Fragment)).contents); std::alloc::dealloc(object as *mut u8, std::alloc::Layout::new::<Fragment>()); } } #[cfg(Py_GIL_DISABLED)] const FRAGMENT_TP_FLAGS: AtomicU64 = AtomicU64::new(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE); #[cfg(all(Py_3_10, not(Py_GIL_DISABLED)))] const FRAGMENT_TP_FLAGS: core::ffi::c_ulong = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_IMMUTABLETYPE; #[cfg(not(Py_3_10))] const FRAGMENT_TP_FLAGS: core::ffi::c_ulong = Py_TPFLAGS_DEFAULT; #[unsafe(no_mangle)] #[cold] #[cfg_attr(feature = "optimize", optimize(size))] pub unsafe extern "C" fn orjson_fragmenttype_new() -> *mut PyTypeObject { unsafe { let ob = Box::new(PyTypeObject { ob_base: PyVarObject { ob_base: PyObject { #[cfg(Py_GIL_DISABLED)] ob_tid: 0, #[cfg(Py_GIL_DISABLED)] _padding: 0, #[cfg(Py_GIL_DISABLED)] ob_mutex: PyMutex::new(), #[cfg(Py_GIL_DISABLED)] ob_gc_bits: 0, #[cfg(Py_GIL_DISABLED)] ob_ref_local: AtomicU32::new(_Py_IMMORTAL_REFCNT_LOCAL), #[cfg(Py_GIL_DISABLED)] ob_ref_shared: AtomicIsize::new(0), #[cfg(all(Py_3_12, not(Py_GIL_DISABLED)))] ob_refcnt: pyo3_ffi::PyObjectObRefcnt { ob_refcnt: 0 }, #[cfg(not(Py_3_12))] ob_refcnt: 0, ob_type: core::ptr::addr_of_mut!(PyType_Type), }, ob_size: 0, }, tp_name: "orjson.Fragment\0".as_ptr() as *const c_char, tp_basicsize: core::mem::size_of::<Fragment>() as isize, tp_itemsize: 0, tp_dealloc: Some(orjson_fragment_dealloc), tp_init: None, tp_new: Some(orjson_fragment_tp_new), tp_flags: FRAGMENT_TP_FLAGS, // ... tp_bases: null_mut(), tp_cache: null_mut(), tp_del: None, tp_finalize: None, tp_free: None, tp_is_gc: None, tp_mro: null_mut(), tp_subclasses: null_mut(), tp_vectorcall: None, tp_version_tag: 0, tp_weaklist: null_mut(), #[cfg(not(Py_3_9))] tp_print: None, tp_vectorcall_offset: 0, tp_getattr: None, tp_setattr: None, tp_as_async: null_mut(), tp_repr: None, tp_as_number: null_mut(), tp_as_sequence: null_mut(), tp_as_mapping: null_mut(), tp_hash: None, tp_call: None, tp_str: None, tp_getattro: None, tp_setattro: None, tp_as_buffer: null_mut(), tp_doc: core::ptr::null_mut(), tp_traverse: None, tp_clear: None, tp_richcompare: None, tp_weaklistoffset: 0, tp_iter: None, tp_iternext: None, tp_methods: null_mut(), tp_members: null_mut(), tp_getset: null_mut(), tp_base: null_mut(), tp_dict: null_mut(), tp_descr_get: None, tp_descr_set: None, tp_dictoffset: 0, tp_alloc: None, #[cfg(Py_3_12)] tp_watched: 0, }); let ob_ptr = Box::into_raw(ob); PyType_Ready(ob_ptr); ob_ptr } }