MCPcopy Create free account
hub / github.com/dylan-sutton-chavez/edge-python / exec_make_class

Method exec_make_class

compiler/src/modules/vm/dispatch.rs:869–938  ·  view source on GitHub ↗
(&mut self, op: u16, ip: usize, cache: &OpcodeCache, chunk: &SSAChunk, caller_slots: &[Val])

Source from the content-addressed store, hash-verified

867
868 #[inline(never)]
869 fn exec_make_class(&mut self, op: u16, ip: usize, cache: &OpcodeCache, chunk: &SSAChunk, caller_slots: &[Val]) -> Result<(), VmErr> {
870 // Operand layout mirrors `class_def_with`: low byte = class chunk index, high byte = base count.
871 let class_idx = (op & 0xFF) as usize;
872 let num_bases = (op >> 8) as usize;
873 // Pop bases first so a misencoded operand fails before we touch the body.
874 let bases = self.pop_n(num_bases)?;
875 for &b in &bases {
876 if !b.is_heap() || !matches!(self.heap.get(b), HeapObj::Class(..)) {
877 return Err(cold_type("base class must be a class object"));
878 }
879 }
880 let Some(body) = chunk.classes.get(class_idx) else {
881 return Err(cold_runtime("class index out of range"));
882 };
883 let mut class_slots = self.fill_builtins(&body.names);
884 // Class bodies can read enclosing module-level names, not only builtins.
885 let mut injected: Vec<(usize, Val)> = Vec::new();
886 for (i, name) in body.names.iter().enumerate() {
887 let bare = ssa_strip(name);
888 if class_slots.get(i).is_some_and(|v| v.is_undef())
889 && let Some(gv) = self.module_state.get(bare).or_else(|| self.globals.get(bare)).copied()
890 {
891 class_slots[i] = gv;
892 injected.push((i, gv));
893 }
894 }
895 // Pin caller slots as GC roots so a nested class/function body can't sweep them.
896 let snap = self.live_slots.len();
897 self.live_slots.extend_from_slice(caller_slots);
898 let exec_result = self.exec(body, &mut class_slots);
899 self.live_slots.truncate(snap);
900 exec_result?;
901 let mut methods: Vec<(String, Val)> = Vec::new();
902 for (i, name) in body.names.iter().enumerate() {
903 if let Some(&v) = class_slots.get(i)
904 && !v.is_undef() {
905 // Skip injected module globals, unless the body reassigned the slot.
906 if injected.iter().any(|&(j, gv)| j == i && v.0 == gv.0) { continue; }
907 let base = ssa_strip(name);
908 let is_builtin_shadow = v.is_heap()
909 && matches!(self.heap.get(v), HeapObj::NativeFn(_))
910 && self.globals.get(base).copied() == Some(v);
911 if is_builtin_shadow { continue; }
912 if let Some(pos) = methods.iter().position(|(n, _)| n == base) {
913 methods[pos].1 = v;
914 } else {
915 methods.push((base.to_string(), v));
916 }
917 }
918 }
919 // Name comes from the StoreName target; skip any decorator `Call`s emitted between.
920 let fused = cache.fused_ref();
921 let mut j = ip;
922 while matches!(fused.get(j).map(|i| i.opcode), Some(OpCode::Call)) { j += 1; }
923 let name_str = fused.get(j)
924 .filter(|i| i.opcode == OpCode::StoreName)
925 .and_then(|i| chunk.names.get(i.operand as usize))
926 .map(|n| ssa_strip(n))

Callers 1

dispatchMethod · 0.80

Calls 15

cold_typeFunction · 0.85
cold_runtimeFunction · 0.85
ssa_stripFunction · 0.85
pop_nMethod · 0.80
is_heapMethod · 0.80
fill_builtinsMethod · 0.80
is_undefMethod · 0.80
pushMethod · 0.80
execMethod · 0.80
fused_refMethod · 0.80
c3_mergeMethod · 0.80
insertMethod · 0.80

Tested by

no test coverage detected