Skip to content

Commit f9e72ce

Browse files
Fix: Dictionary equality comparison in deep value equality.
1 parent 8f8ee37 commit f9e72ce

File tree

4 files changed

+19
-19
lines changed

4 files changed

+19
-19
lines changed

compiler/src/modules/vm/cache.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// vm/cache.rs
22

3-
use super::types::{Val, eq_vals_deep};
3+
use super::types::{Val, eq_vals_with_heap};
44
use crate::modules::parser::OpCode;
55
use alloc::{vec, vec::Vec};
66
use hashbrown::HashMap;
@@ -96,7 +96,7 @@ impl Templates {
9696
.find(|e| {
9797
e.hits >= TPL_THRESH
9898
&& e.args.len() == args.len()
99-
&& e.args.iter().zip(args).all(|(a, b)| eq_vals_deep(*a, *b, heap))
99+
&& e.args.iter().zip(args).all(|(a, b)| eq_vals_with_heap(*a, *b, heap))
100100
})
101101
.map(|e| e.result)
102102
}
@@ -105,7 +105,7 @@ impl Templates {
105105
let v = self.map.entry(fi).or_default();
106106
if let Some(e) = v.iter_mut().find(|e| {
107107
e.args.len() == args.len()
108-
&& e.args.iter().zip(args).all(|(a, b)| eq_vals_deep(*a, *b, heap))
108+
&& e.args.iter().zip(args).all(|(a, b)| eq_vals_with_heap(*a, *b, heap))
109109
}) {
110110
e.hits += 1; e.result = result;
111111
} else if v.len() < 256 {

compiler/src/modules/vm/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,9 +417,12 @@ pub(crate) fn exec(&mut self, chunk: &SSAChunk, slots: &mut Vec<Option<Val>>) ->
417417

418418
// Comparison (cached)
419419

420-
OpCode::Eq => { let (a, b) = self.pop2()?; cached_binop!(self.heap, rip, &ins.opcode, a, b, cache); self.push(Val::bool(self.eq_vals(a, b))); }
420+
OpCode::Eq => { let (a, b) = self.pop2()?; cached_binop!(self.heap, rip, &ins.opcode, a, b, cache); self.push(Val::bool(eq_vals_with_heap(a, b, &self.heap))); }
421421
OpCode::Lt => { let (a, b) = self.pop2()?; cached_binop!(self.heap, rip, &ins.opcode, a, b, cache); let r = self.lt_vals(a, b)?; self.push(Val::bool(r)); }
422-
OpCode::NotEq => { let (a,b) = self.pop2()?; self.push(Val::bool(!self.eq_vals(a,b))); }
422+
OpCode::NotEq => {
423+
let (a, b) = self.pop2()?;
424+
self.push(Val::bool(!eq_vals_with_heap(a, b, &self.heap)));
425+
}
423426
OpCode::Gt => { let (a,b) = self.pop2()?; let r=self.lt_vals(b,a)?; self.push(Val::bool(r)); }
424427
OpCode::LtEq => { let (a,b) = self.pop2()?; let r=self.lt_vals(b,a)?; self.push(Val::bool(!r)); }
425428
OpCode::GtEq => { let (a,b) = self.pop2()?; let r=self.lt_vals(a,b)?; self.push(Val::bool(!r)); }

compiler/src/modules/vm/ops.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,6 @@ impl<'a> VM<'a> {
107107
self.display(v)
108108
}
109109

110-
pub fn eq_vals(&self, a: Val, b: Val) -> bool {
111-
super::types::eq_vals_deep(a, b, &self.heap)
112-
}
113-
114110
pub fn lt_vals(&self, a: Val, b: Val) -> Result<bool, VmErr> {
115111
if let (Some(ba), Some(bb)) = (self.to_bigint(a), self.to_bigint(b)) {
116112
return Ok(ba.cmp(&bb) == core::cmp::Ordering::Less);
@@ -131,18 +127,17 @@ impl<'a> VM<'a> {
131127
pub fn contains(&self, container: Val, item: Val) -> bool {
132128
if !container.is_heap() { return false; }
133129
match self.heap.get(container) {
134-
HeapObj::List(v) => v.borrow().iter().any(|x| self.eq_vals(*x, item)),
135-
HeapObj::Tuple(v) => v.iter().any(|x| self.eq_vals(*x, item)),
130+
HeapObj::List(v) => v.borrow().iter().any(|x| eq_vals_with_heap(*x, item, &self.heap)),
131+
HeapObj::Tuple(v) => v.iter().any(|x| eq_vals_with_heap(*x, item, &self.heap)),
136132
HeapObj::Dict(p) => p.borrow().contains_key(&item),
137-
HeapObj::Set(s) => s.borrow().iter().any(|x| self.eq_vals(*x, item)),
133+
HeapObj::Set(s) => s.borrow().iter().any(|x| eq_vals_with_heap(*x, item, &self.heap)),
138134
HeapObj::Str(s) => {
139135
if item.is_heap() { if let HeapObj::Str(sub) = self.heap.get(item) { return s.contains(sub.as_str()); } }
140136
false
141137
}
142138
_ => false,
143139
}
144140
}
145-
146141
pub fn add_vals(&mut self, a: Val, b: Val) -> Result<Val, VmErr> {
147142
if let (Some(ba), Some(bb)) = (self.to_bigint(a), self.to_bigint(b)) {
148143
return self.bigint_to_val(ba.add(&bb));

compiler/src/modules/vm/types.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -561,24 +561,26 @@ pub(super) fn eq_dict(a: &DictMap, b: &DictMap, eq: impl Fn(Val,Val)->bool) -> b
561561
a.len() == b.len() && a.iter().all(|(k,v)| b.get(&k).map_or(false, |&v2| eq(v,v2)))
562562
}
563563

564-
pub fn eq_vals_deep(a: Val, b: Val, heap: &HeapPool) -> bool {
564+
pub fn eq_vals_with_heap(a: Val, b: Val, heap: &HeapPool) -> bool {
565565
if let (Some(ba), Some(bb)) = (bigint_of(a, heap), bigint_of(b, heap)) {
566566
return ba.cmp(&bb) == core::cmp::Ordering::Equal;
567567
}
568+
568569
if !a.is_heap() || !b.is_heap() {
569570
if a.is_int() && b.is_int() { return a.as_int() == b.as_int(); }
570571
if a.is_float() && b.is_float() { return a.as_float() == b.as_float(); }
571572
if a.is_int() && b.is_float() { return (a.as_int() as f64) == b.as_float(); }
572573
if a.is_float() && b.is_int() { return a.as_float() == (b.as_int() as f64); }
573574
return a.0 == b.0;
574575
}
576+
575577
match (heap.get(a), heap.get(b)) {
576578
(HeapObj::BigInt(x), HeapObj::BigInt(y)) => x.cmp(y) == core::cmp::Ordering::Equal,
577-
(HeapObj::Str(x), HeapObj::Str(y)) => x == y,
578-
(HeapObj::Tuple(x), HeapObj::Tuple(y)) => eq_seq(x, y, |a,b| eq_vals_deep(a,b,heap)),
579-
(HeapObj::List(x), HeapObj::List(y)) => eq_seq(&x.borrow(), &y.borrow(), |a,b| eq_vals_deep(a,b,heap)),
580-
(HeapObj::Set(x), HeapObj::Set(y)) => eq_set(&x.borrow(), &y.borrow(), |a,b| eq_vals_deep(a,b,heap)),
581-
(HeapObj::Dict(x), HeapObj::Dict(y)) => eq_dict(&x.borrow(), &y.borrow(), |a,b| eq_vals_deep(a,b,heap)),
579+
(HeapObj::Str(x), HeapObj::Str(y)) => x == y,
580+
(HeapObj::Tuple(x), HeapObj::Tuple(y)) => eq_seq(x, y, |a,b| eq_vals_with_heap(a, b, heap)),
581+
(HeapObj::List(x), HeapObj::List(y)) => eq_seq(&x.borrow(), &y.borrow(), |a,b| eq_vals_with_heap(a, b, heap)),
582+
(HeapObj::Set(x), HeapObj::Set(y)) => eq_set(&x.borrow(), &y.borrow(), |a,b| eq_vals_with_heap(a, b, heap)),
583+
(HeapObj::Dict(x), HeapObj::Dict(y)) => eq_dict(&x.borrow(), &y.borrow(), |a,b| eq_vals_with_heap(a, b, heap)),
582584
_ => false,
583585
}
584586
}

0 commit comments

Comments
 (0)