Serialize a code object in CPython field order. Split varnames/cellvars/freevars are reassembled into co_localsplusnames/co_localspluskinds.
(buf: &mut W, code: &CodeObject<C>)
| 896 | /// Split varnames/cellvars/freevars are reassembled into |
| 897 | /// co_localsplusnames/co_localspluskinds. |
| 898 | pub fn serialize_code<W: Write, C: Constant>(buf: &mut W, code: &CodeObject<C>) { |
| 899 | // 1–5: scalar fields |
| 900 | buf.write_u32(code.arg_count); |
| 901 | buf.write_u32(code.posonlyarg_count); |
| 902 | buf.write_u32(code.kwonlyarg_count); |
| 903 | buf.write_u32(code.max_stackdepth); |
| 904 | buf.write_u32(code.flags.bits()); |
| 905 | |
| 906 | // 6: co_code (TYPE_STRING) — bytecode already uses flat localsplus indices |
| 907 | let bytecode = code.instructions.original_bytes(); |
| 908 | buf.write_u8(Type::Bytes as u8); |
| 909 | write_vec(buf, &bytecode); |
| 910 | |
| 911 | // 7: co_consts (TYPE_TUPLE) |
| 912 | buf.write_u8(Type::Tuple as u8); |
| 913 | write_len(buf, code.constants.len()); |
| 914 | for constant in &*code.constants { |
| 915 | serialize_value(buf, constant.borrow_constant().into()).unwrap_or_else(|x| match x {}) |
| 916 | } |
| 917 | |
| 918 | // 8: co_names (tuple of strings) |
| 919 | write_marshal_name_tuple(buf, &code.names); |
| 920 | |
| 921 | // 9: co_localsplusnames — varnames ++ cell_only ++ freevars |
| 922 | let cell_only_names: Vec<&str> = code |
| 923 | .cellvars |
| 924 | .iter() |
| 925 | .filter(|cv| !code.varnames.iter().any(|v| v.as_ref() == cv.as_ref())) |
| 926 | .map(|cv| cv.as_ref()) |
| 927 | .collect(); |
| 928 | let total_lp_count = code.varnames.len() + cell_only_names.len() + code.freevars.len(); |
| 929 | buf.write_u8(Type::Tuple as u8); |
| 930 | write_len(buf, total_lp_count); |
| 931 | for n in code.varnames.iter() { |
| 932 | write_marshal_str(buf, n.as_ref()); |
| 933 | } |
| 934 | for &n in &cell_only_names { |
| 935 | write_marshal_str(buf, n); |
| 936 | } |
| 937 | for n in code.freevars.iter() { |
| 938 | write_marshal_str(buf, n.as_ref()); |
| 939 | } |
| 940 | // 10: co_localspluskinds — use the stored kinds directly |
| 941 | buf.write_u8(Type::Bytes as u8); |
| 942 | write_vec(buf, &code.localspluskinds); |
| 943 | |
| 944 | // 11: co_filename |
| 945 | write_marshal_str(buf, code.source_path.as_ref()); |
| 946 | // 12: co_name |
| 947 | write_marshal_str(buf, code.obj_name.as_ref()); |
| 948 | // 13: co_qualname |
| 949 | write_marshal_str(buf, code.qualname.as_ref()); |
| 950 | // 14: co_firstlineno |
| 951 | buf.write_u32(code.first_line_number.map_or(0, |x| x.get() as _)); |
| 952 | // 15: co_linetable |
| 953 | buf.write_u8(Type::Bytes as u8); |
| 954 | write_vec(buf, &code.linetable); |
| 955 | // 16: co_exceptiontable |
no test coverage detected