MCPcopy Index your code
hub / github.com/RustPython/RustPython / co_branches

Method co_branches

crates/vm/src/builtins/code.rs:1073–1149  ·  view source on GitHub ↗
(&self, vm: &VirtualMachine)

Source from the content-addressed store, hash-verified

1071
1072 #[pymethod]
1073 pub fn co_branches(&self, vm: &VirtualMachine) -> PyResult<PyObjectRef> {
1074 let instructions = &self.code.instructions;
1075 let mut branches = Vec::new();
1076 let mut extended_arg: u32 = 0;
1077
1078 for (i, unit) in instructions.iter().enumerate() {
1079 // De-instrument: use base opcode for instrumented variants
1080 let op = unit.op.to_base().unwrap_or(unit.op);
1081 let raw_arg = u32::from(u8::from(unit.arg));
1082
1083 if matches!(op, Instruction::ExtendedArg) {
1084 extended_arg = (extended_arg | raw_arg) << 8;
1085 continue;
1086 }
1087
1088 let oparg = extended_arg | raw_arg;
1089 extended_arg = 0;
1090
1091 let caches = op.cache_entries();
1092 let (src, left, right) = match op {
1093 Instruction::ForIter { .. } => {
1094 // left = fall-through past CACHE entries (continue iteration)
1095 // right = past END_FOR (iterator exhausted, skip cleanup)
1096 // arg is relative forward from after instruction+caches
1097 let after_cache = i + 1 + caches;
1098 let target = after_cache + oparg as usize;
1099 let right = if matches!(
1100 instructions.get(target).map(|u| u.op),
1101 Some(Instruction::EndFor) | Some(Instruction::InstrumentedEndFor)
1102 ) {
1103 (target + 1) * 2
1104 } else {
1105 target * 2
1106 };
1107 (i * 2, after_cache * 2, right)
1108 }
1109 Instruction::PopJumpIfFalse { .. }
1110 | Instruction::PopJumpIfTrue { .. }
1111 | Instruction::PopJumpIfNone { .. }
1112 | Instruction::PopJumpIfNotNone { .. } => {
1113 // left = fall-through past CACHE entries (skip NOT_TAKEN if present)
1114 // right = jump target (relative forward from after instruction+caches)
1115 let after_cache = i + 1 + caches;
1116 let next_op = instructions
1117 .get(after_cache)
1118 .map(|u| u.op.to_base().unwrap_or(u.op));
1119 let fallthrough = if matches!(next_op, Some(Instruction::NotTaken)) {
1120 (after_cache + 1) * 2
1121 } else {
1122 after_cache * 2
1123 };
1124 let right_target = after_cache + oparg as usize;
1125 (i * 2, fallthrough, right_target * 2)
1126 }
1127 Instruction::EndAsyncFor => {
1128 // src = END_SEND position (next_i - oparg)
1129 let next_i = i + 1;
1130 let Some(src_i) = next_i.checked_sub(oparg as usize) else {

Callers 2

get_line_branchesMethod · 0.80
check_branchesMethod · 0.80

Calls 11

newFunction · 0.85
cache_entriesMethod · 0.80
new_listMethod · 0.80
iterMethod · 0.45
to_baseMethod · 0.45
mapMethod · 0.45
getMethod · 0.45
new_tupleMethod · 0.45
pushMethod · 0.45
call_methodMethod · 0.45
as_objectMethod · 0.45

Tested by 2

get_line_branchesMethod · 0.64
check_branchesMethod · 0.64