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

Method exec_inst

compiler/src/modules/vm/dispatch.rs:95–131  ·  view source on GitHub ↗
(&mut self, inst: InstanceCache, chunk: &SSAChunk, slots: &mut [Val])

Source from the content-addressed store, hash-verified

93 /* Instance-dunder fast path. Guards the receiver's class identity, invokes the pre-resolved method bypassing `resolve_attr_silent`, and treats `NotImplemented` as a deopt so reflected dispatch can take over via the slow path. Restores the stack on miss so the slow handler reads its operands unchanged. */
94 #[inline]
95 fn exec_inst(&mut self, inst: InstanceCache, chunk: &SSAChunk, slots: &mut [Val]) -> Result<FastOutcome, VmErr> {
96 let arity = inst.arity as usize;
97 let len = self.stack.len();
98 if len < arity { return Ok(FastOutcome::TypeMiss); }
99
100 let recv_idx = len - arity;
101 let recv = self.stack[recv_idx];
102 if !recv.is_heap() { return Ok(FastOutcome::TypeMiss); }
103 let class_val = match self.heap.get(recv) {
104 HeapObj::Instance(c, _) => *c,
105 _ => return Ok(FastOutcome::TypeMiss),
106 };
107 if class_val.as_heap() != inst.class { return Ok(FastOutcome::TypeMiss); }
108
109 if self.depth >= self.max_calls { return Err(cold_depth()); }
110
111 // Snapshot the operand window before mutating; reused to roll back on deopt.
112 let mut operands: Vec<Val> = Vec::with_capacity(arity);
113 operands.extend_from_slice(&self.stack[recv_idx..len]);
114 self.stack.truncate(recv_idx);
115
116 // SAFETY: `method_bits` was recorded from a live `Val` and `Class` references are immutable, so the function still lives on the heap.
117 let method = unsafe { Val::from_raw(inst.method_bits) };
118 self.pending.method_binding = Some((class_val, recv));
119 self.push(method);
120 for &v in &operands { self.push(v); }
121 self.exec_call(arity as u16, chunk, slots)?;
122
123 let result = self.pop()?;
124 if self.heap.is_not_implemented(result) {
125 // Deopt: restore the original stack window so the slow handler sees its operands.
126 for &v in &operands { self.push(v); }
127 return Ok(FastOutcome::TypeMiss);
128 }
129 self.push(result);
130 Ok(FastOutcome::Done)
131 }
132
133 /* Post-success recording for the instance-dunder IC; ignored when the receiver isn't an instance or the method isn't on its class. */
134 #[inline]

Callers 2

dispatchMethod · 0.80
exec_arith_or_compareMethod · 0.80

Calls 9

cold_depthFunction · 0.85
is_heapMethod · 0.80
as_heapMethod · 0.80
pushMethod · 0.80
exec_callMethod · 0.80
is_not_implementedMethod · 0.80
lenMethod · 0.45
getMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected