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

Method exec_fast

compiler/src/modules/vm/dispatch.rs:17–91  ·  view source on GitHub ↗
(&mut self, fast: FastOp)

Source from the content-addressed store, hash-verified

15 /* IC fast path: Done (consumed+pushed) / TypeMiss (deopt) / Overflow (keep IC, slow handler raises). */
16 #[inline]
17 fn exec_fast(&mut self, fast: FastOp) -> Result<FastOutcome, VmErr> {
18 let len = self.stack.len();
19 if len < 2 { return Ok(FastOutcome::TypeMiss); }
20
21 let a = self.stack[len - 2];
22 let b = self.stack[len - 1];
23
24 let result = match fast {
25 FastOp::AddFloat if a.is_float() && b.is_float() => Val::float(a.as_float() + b.as_float()),
26 FastOp::AddInt if a.is_int() && b.is_int() => {
27 match a.as_int().checked_add(b.as_int()).and_then(Val::int_checked) {
28 Some(v) => v,
29 None => return Ok(FastOutcome::Overflow),
30 }
31 }
32 FastOp::SubInt if a.is_int() && b.is_int() => {
33 match a.as_int().checked_sub(b.as_int()).and_then(Val::int_checked) {
34 Some(v) => v,
35 None => return Ok(FastOutcome::Overflow),
36 }
37 }
38 FastOp::MulInt if a.is_int() && b.is_int() => {
39 let r = a.as_int() as i128 * b.as_int() as i128;
40 if r >= Val::INT_MIN as i128 && r <= Val::INT_MAX as i128 { Val::int(r as i64) } else { return Ok(FastOutcome::Overflow); }
41 }
42 FastOp::MulFloat if a.is_float() && b.is_float() => Val::float(a.as_float() * b.as_float()),
43 FastOp::ModInt if a.is_int() && b.is_int() => {
44 let bv = b.as_int();
45 if bv == 0 { return Ok(FastOutcome::Overflow); }
46 Val::int(((a.as_int() % bv) + bv) % bv)
47 }
48 FastOp::FloorDivInt if a.is_int() && b.is_int() => {
49 let bv = b.as_int();
50 if bv == 0 { return Ok(FastOutcome::Overflow); }
51 // floored division (toward -inf), not Euclidean; 47-bit operands can't overflow.
52 let av = a.as_int();
53 let q = av / bv;
54 let r = av - q * bv;
55 Val::int(if r != 0 && (r < 0) != (bv < 0) { q - 1 } else { q })
56 }
57
58 FastOp::LtInt if a.is_int() && b.is_int() => Val::bool(a.as_int() < b.as_int()),
59 FastOp::LtFloat if a.is_float() && b.is_float() => Val::bool(a.as_float() < b.as_float()),
60 FastOp::EqInt if a.is_int() && b.is_int() => Val::bool(a.as_int() == b.as_int()),
61 FastOp::GtInt if a.is_int() && b.is_int() => Val::bool(a.as_int() > b.as_int()),
62 FastOp::LtEqInt if a.is_int() && b.is_int() => Val::bool(a.as_int() <= b.as_int()),
63 FastOp::GtEqInt if a.is_int() && b.is_int() => Val::bool(a.as_int() >= b.as_int()),
64 FastOp::NotEqInt if a.is_int() && b.is_int() => Val::bool(a.as_int() != b.as_int()),
65
66 FastOp::EqStr if a.is_heap() && b.is_heap() => {
67 match (self.heap.get(a), self.heap.get(b)) {
68 (HeapObj::Str(x), HeapObj::Str(y)) => Val::bool(x == y),
69 _ => return Ok(FastOutcome::TypeMiss),
70 }
71 }
72
73 FastOp::AddStr if a.is_heap() && b.is_heap() => {
74 let (sa, sb) = match (self.heap.get(a), self.heap.get(b)) {

Callers 1

exec_arith_or_compareMethod · 0.80

Calls 10

is_floatMethod · 0.80
as_floatMethod · 0.80
is_intMethod · 0.80
as_intMethod · 0.80
is_heapMethod · 0.80
charge_stepsMethod · 0.80
pushMethod · 0.80
lenMethod · 0.45
getMethod · 0.45
allocMethod · 0.45

Tested by

no test coverage detected