(
buf: &mut Vec<u8>,
obj: &PyObjectRef,
refs: &mut Option<WriterRefTable>,
version: i32,
vm: &VirtualMachine,
depth: usize,
)
| 170 | } |
| 171 | |
| 172 | fn write_object_depth( |
| 173 | buf: &mut Vec<u8>, |
| 174 | obj: &PyObjectRef, |
| 175 | refs: &mut Option<WriterRefTable>, |
| 176 | version: i32, |
| 177 | vm: &VirtualMachine, |
| 178 | depth: usize, |
| 179 | ) -> PyResult<()> { |
| 180 | use marshal::Write; |
| 181 | if depth == 0 { |
| 182 | return Err(vm.new_value_error("object too deeply nested to marshal".to_string())); |
| 183 | } |
| 184 | |
| 185 | // Singletons: no FLAG_REF needed |
| 186 | let is_singleton = vm.is_none(obj) |
| 187 | || obj.class().is(PyBool::static_type()) |
| 188 | || obj.is(PyStopIteration::static_type()) |
| 189 | || obj.downcast_ref::<crate::builtins::PyEllipsis>().is_some(); |
| 190 | |
| 191 | // FLAG_REF: check if already written, otherwise reserve slot |
| 192 | if !is_singleton |
| 193 | && let Some(rt) = refs.as_mut() |
| 194 | && rt.try_ref(buf, obj) |
| 195 | { |
| 196 | return Ok(()); |
| 197 | } |
| 198 | let type_pos = buf.len(); |
| 199 | let use_ref = refs.is_some() && !is_singleton; |
| 200 | if use_ref { |
| 201 | refs.as_mut().unwrap().reserve(obj); |
| 202 | } |
| 203 | |
| 204 | if vm.is_none(obj) { |
| 205 | buf.write_u8(b'N'); |
| 206 | } else if obj.is(PyStopIteration::static_type()) { |
| 207 | buf.write_u8(b'S'); |
| 208 | } else if obj.class().is(PyBool::static_type()) { |
| 209 | let val = obj |
| 210 | .downcast_ref::<PyInt>() |
| 211 | .is_some_and(|i| !i.as_bigint().is_zero()); |
| 212 | buf.write_u8(if val { b'T' } else { b'F' }); |
| 213 | } else if obj.downcast_ref::<crate::builtins::PyEllipsis>().is_some() { |
| 214 | buf.write_u8(b'.'); |
| 215 | } else if let Some(i) = obj.downcast_ref::<PyInt>() { |
| 216 | // TYPE_INT for i32 range, TYPE_LONG for larger |
| 217 | if let Ok(val) = i32::try_from(i.as_bigint()) { |
| 218 | buf.write_u8(b'i'); |
| 219 | buf.write_u32(val as u32); |
| 220 | } else { |
| 221 | buf.write_u8(b'l'); |
| 222 | let (sign, raw) = i.as_bigint().to_bytes_le(); |
| 223 | let mut digits = Vec::new(); |
| 224 | let mut accum: u32 = 0; |
| 225 | let mut bits = 0u32; |
| 226 | for &byte in &raw { |
| 227 | accum |= (byte as u32) << bits; |
| 228 | bits += 8; |
| 229 | while bits >= 15 { |
no test coverage detected