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

Method handle_bitwise

compiler/src/modules/vm/handlers/arith.rs:271–321  ·  view source on GitHub ↗

i128 bitwise + Shl/Shr (overflow trap); BitNot unary. Set/Set on |/&/^ means union/intersection/symmetric-diff; other types use the bitwise path. */

(&mut self, op: OpCode, chunk: &SSAChunk, slots: &mut [Val])

Source from the content-addressed store, hash-verified

269
270 /* i128 bitwise + Shl/Shr (overflow trap); BitNot unary. Set/Set on |/&/^ means union/intersection/symmetric-diff; other types use the bitwise path. */
271 pub(crate) fn handle_bitwise(&mut self, op: OpCode, chunk: &SSAChunk, slots: &mut [Val]) -> Result<(), VmErr> {
272 // Augmented set bitwise reuses the plain path but mutates the left set in place.
273 let inplace = matches!(op, OpCode::InPlaceBitOr | OpCode::InPlaceBitAnd | OpCode::InPlaceBitXor);
274 let op = match op {
275 OpCode::InPlaceBitOr => OpCode::BitOr,
276 OpCode::InPlaceBitAnd => OpCode::BitAnd,
277 OpCode::InPlaceBitXor => OpCode::BitXor,
278 other => other,
279 };
280 if op == OpCode::BitNot {
281 let v = self.pop()?;
282 let i = self.as_i128(v).ok_or(cold_type("~ requires an integer"))?;
283 let out = self.int_to_val(Some(!i))?;
284 self.push(out);
285 return Ok(());
286 }
287
288 let (a, b) = self.pop2()?;
289
290 // User instance operands dispatch __or__/__and__/__xor__ (and reflected) first.
291 let roots = self.temp_roots.len();
292 self.temp_roots.push(a);
293 self.temp_roots.push(b);
294 let dunder = self.try_binary_dunder(op, a, b, chunk, slots);
295 self.temp_roots.truncate(roots);
296 if let Some(r) = dunder? { self.push(r); return Ok(()); }
297
298 if self.is_set_like(a) && self.is_set_like(b)
299 && matches!(op, OpCode::BitAnd | OpCode::BitOr | OpCode::BitXor) {
300 return if inplace { self.set_iop_and_push(a, b, op) } else { self.set_binop_and_push(a, b, op) };
301 }
302 // `dict | dict` (and `|=`) merges, right operand winning.
303 if op == OpCode::BitOr && a.is_heap() && b.is_heap()
304 && matches!(self.heap.get(a), HeapObj::Dict(_))
305 && matches!(self.heap.get(b), HeapObj::Dict(_)) {
306 let mut merged = DictMap::with_capacity(0);
307 if let HeapObj::Dict(d) = self.heap.get(a) { for (k, v) in d.borrow().entries.iter() { merged.insert(*k, *v, &self.heap); } }
308 if let HeapObj::Dict(d) = self.heap.get(b) { for (k, v) in d.borrow().entries.iter() { merged.insert(*k, *v, &self.heap); } }
309 return self.alloc_and_push_dict(merged);
310 }
311 let result = match op {
312 OpCode::BitAnd => self.bitwise_op(a, b, |x, y| x & y)?,
313 OpCode::BitOr => self.bitwise_op(a, b, |x, y| x | y)?,
314 OpCode::BitXor => self.bitwise_op(a, b, |x, y| x ^ y)?,
315 OpCode::Shl => self.exec_shl(a, b)?,
316 OpCode::Shr => self.exec_shr(a, b)?,
317 _ => return Err(cold_runtime("non-bitwise opcode in handle_bitwise")),
318 };
319 self.push(result);
320 Ok(())
321 }
322
323 fn exec_shl(&mut self, a: Val, b: Val) -> Result<Val, VmErr> {
324 if !b.is_int() { return Err(cold_type("shift count must be an integer")); }

Callers 1

dispatch_genericMethod · 0.80

Calls 15

cold_typeFunction · 0.85
cold_runtimeFunction · 0.85
as_i128Method · 0.80
int_to_valMethod · 0.80
pushMethod · 0.80
pop2Method · 0.80
try_binary_dunderMethod · 0.80
is_set_likeMethod · 0.80
set_iop_and_pushMethod · 0.80
set_binop_and_pushMethod · 0.80
is_heapMethod · 0.80
borrowMethod · 0.80

Tested by

no test coverage detected