Deserialize a code object (CPython field order).
(
rdr: &mut R,
bag: Bag,
)
| 191 | |
| 192 | /// Deserialize a code object (CPython field order). |
| 193 | pub fn deserialize_code<R: Read, Bag: ConstantBag>( |
| 194 | rdr: &mut R, |
| 195 | bag: Bag, |
| 196 | ) -> Result<CodeObject<Bag::Constant>> { |
| 197 | // 1–5: scalar fields |
| 198 | let arg_count = rdr.read_u32()?; |
| 199 | let posonlyarg_count = rdr.read_u32()?; |
| 200 | let kwonlyarg_count = rdr.read_u32()?; |
| 201 | let max_stackdepth = rdr.read_u32()?; |
| 202 | let flags = CodeFlags::from_bits_truncate(rdr.read_u32()?); |
| 203 | |
| 204 | // 6: co_code |
| 205 | let code_bytes = read_marshal_bytes(rdr)?; |
| 206 | |
| 207 | // 7: co_consts |
| 208 | let constants = read_marshal_const_tuple(rdr, bag)?; |
| 209 | |
| 210 | // 8: co_names |
| 211 | let names = read_marshal_name_tuple(rdr, &bag)?; |
| 212 | |
| 213 | // 9: co_localsplusnames |
| 214 | let localsplusnames = read_marshal_str_vec(rdr)?; |
| 215 | |
| 216 | // 10: co_localspluskinds |
| 217 | let localspluskinds = read_marshal_bytes(rdr)?; |
| 218 | |
| 219 | // 11–13: filename, name, qualname |
| 220 | let source_path = bag.make_name(&read_marshal_str(rdr)?); |
| 221 | let obj_name = bag.make_name(&read_marshal_str(rdr)?); |
| 222 | let qualname = bag.make_name(&read_marshal_str(rdr)?); |
| 223 | |
| 224 | // 14: co_firstlineno |
| 225 | let first_line_raw = rdr.read_u32()? as i32; |
| 226 | let first_line_number = if first_line_raw > 0 { |
| 227 | OneIndexed::new(first_line_raw as usize) |
| 228 | } else { |
| 229 | None |
| 230 | }; |
| 231 | |
| 232 | // 15–16: linetable, exceptiontable |
| 233 | let linetable = read_marshal_bytes(rdr)?.to_vec().into_boxed_slice(); |
| 234 | let exceptiontable = read_marshal_bytes(rdr)?.to_vec().into_boxed_slice(); |
| 235 | |
| 236 | // Split localsplusnames/kinds → varnames/cellvars/freevars |
| 237 | let lp = split_localplus( |
| 238 | &localsplusnames |
| 239 | .iter() |
| 240 | .map(|s| s.as_str()) |
| 241 | .collect::<Vec<&str>>(), |
| 242 | &localspluskinds, |
| 243 | arg_count, |
| 244 | kwonlyarg_count, |
| 245 | flags, |
| 246 | )?; |
| 247 | |
| 248 | // Bytecode already uses flat localsplus indices (no translation needed) |
| 249 | let instructions = CodeUnits::try_from(code_bytes.as_slice())?; |
| 250 | let locations = linetable_to_locations(&linetable, first_line_raw, instructions.len()); |
no test coverage detected