Skip to content

Commit 10261b5

Browse files
anakrishCopilot
andcommitted
refactor(rvm): migrate to Object/Set API; snapshot IterationState pairs
Migrates ~55 sites across src/rvm/ to the new Object/Set API. IterationState refactor (replaces BTreeMap::range / BTreeSet::range loop resumption): - IterationState::Object now stores Rc<[(Value, Value)]> + pos. No second BTreeMap::get during iteration; no defensive None branch. Symmetric with IterationState::Set { values, pos }. - Snapshot is built via iter() / keys() — matches the interpreter's iteration contract, preserving dual-path equivalence. - Per-push check_memory_limit_if_needed() during snapshot construction maintains the allocator-limit guarantee even for large input collections. Drops dead clones of iteration_key/iteration_value in the suspendable comprehension yield path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent f489c3b commit 10261b5

7 files changed

Lines changed: 165 additions & 258 deletions

File tree

src/rvm/program/metadata.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
//! values are converted through [`MetadataValue`] — a postcard/bincode-safe
1212
//! enum that avoids `deserialize_any`.
1313
14+
use crate::collections::{Object, Set};
1415
use crate::Rc;
15-
use alloc::collections::BTreeMap;
16-
use alloc::collections::BTreeSet;
16+
use alloc::collections::{BTreeMap, BTreeSet};
1717
use alloc::string::String;
1818
use alloc::vec::Vec;
1919
use serde::{Deserialize, Serialize};
@@ -52,7 +52,7 @@ impl ProgramMetadata {
5252
pub fn to_value(&self) -> crate::value::Value {
5353
use crate::value::Value;
5454

55-
let mut obj = BTreeMap::new();
55+
let mut obj = Object::new();
5656
obj.insert(
5757
Value::String("compiler_version".into()),
5858
Value::String(self.compiler_version.as_str().into()),
@@ -75,7 +75,7 @@ impl ProgramMetadata {
7575
);
7676

7777
if !self.annotations.is_empty() {
78-
let mut annotations_obj = BTreeMap::new();
78+
let mut annotations_obj = Object::new();
7979
for (k, v) in &self.annotations {
8080
annotations_obj.insert(Value::String(k.as_str().into()), v.clone());
8181
}
@@ -198,7 +198,7 @@ impl MetadataValue {
198198
match *self {
199199
MetadataValue::String(ref s) => Value::String(s.as_str().into()),
200200
MetadataValue::StringSet(ref set) => {
201-
let mut bset = alloc::collections::BTreeSet::new();
201+
let mut bset = Set::new();
202202
for s in set {
203203
bset.insert(Value::String(s.as_str().into()));
204204
}
@@ -211,7 +211,7 @@ impl MetadataValue {
211211
Value::Array(Rc::new(values))
212212
}
213213
MetadataValue::Map(ref map) => {
214-
let mut obj = BTreeMap::new();
214+
let mut obj = Object::new();
215215
for (k, v) in map {
216216
obj.insert(Value::String(k.as_str().into()), v.to_value());
217217
}
@@ -257,7 +257,6 @@ mod metadata_serde {
257257
mod tests {
258258
use super::*;
259259
use crate::value::Value;
260-
use alloc::collections::BTreeSet;
261260

262261
/// Round-trip: Value → MetadataValue → Value must be equivalent for
263262
/// all lossless variants (strings, bools, integers, arrays, objects).
@@ -299,7 +298,7 @@ mod tests {
299298

300299
#[test]
301300
fn round_trip_string_set() {
302-
let mut set = BTreeSet::new();
301+
let mut set = Set::new();
303302
set.insert(Value::String("a".into()));
304303
set.insert(Value::String("b".into()));
305304
let v = Value::Set(Rc::new(set));
@@ -326,7 +325,7 @@ mod tests {
326325

327326
#[test]
328327
fn mixed_set_uses_list() {
329-
let mut set = BTreeSet::new();
328+
let mut set = Set::new();
330329
set.insert(Value::String("a".into()));
331330
set.insert(Value::from(1_i64));
332331
let v = Value::Set(Rc::new(set));

src/rvm/program/serialization/value.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
3-
use alloc::collections::{BTreeMap, BTreeSet};
43
use alloc::format;
54
use alloc::string::String;
65
use alloc::vec::Vec;
@@ -10,6 +9,7 @@ use serde::de::{self, EnumAccess, VariantAccess as _, Visitor};
109
use serde::ser::{SerializeSeq as _, SerializeTuple as _};
1110
use serde::{Deserialize, Serialize};
1211

12+
use crate::collections::{Object, Set};
1313
use crate::number::Number;
1414
use crate::value::Value;
1515

@@ -117,7 +117,7 @@ impl<'a> Serialize for BinaryValueSlice<'a> {
117117
}
118118
}
119119

120-
struct BinarySetRef<'a>(&'a BTreeSet<Value>);
120+
struct BinarySetRef<'a>(&'a Set);
121121

122122
impl<'a> Serialize for BinarySetRef<'a> {
123123
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -132,7 +132,7 @@ impl<'a> Serialize for BinarySetRef<'a> {
132132
}
133133
}
134134

135-
struct BinaryObjectRef<'a>(&'a BTreeMap<Value, Value>);
135+
struct BinaryObjectRef<'a>(&'a Object);
136136

137137
impl<'a> Serialize for BinaryObjectRef<'a> {
138138
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -253,19 +253,19 @@ impl<'de> Visitor<'de> for BinaryValueVisitor {
253253
}
254254
(BinaryVariant::Set, variant) => {
255255
let items: Vec<BinaryValue> = variant.newtype_variant()?;
256-
let mut set = BTreeSet::new();
256+
let mut set = Set::new();
257257
for item in items {
258258
set.insert(item.into_value());
259259
}
260-
Ok(BinaryValue(Value::from(set)))
260+
Ok(BinaryValue(Value::Set(crate::Rc::new(set))))
261261
}
262262
(BinaryVariant::Object, variant) => {
263263
let entries: Vec<(BinaryValue, BinaryValue)> = variant.newtype_variant()?;
264-
let mut map = BTreeMap::new();
264+
let mut map = Object::new();
265265
for (key, value) in entries {
266266
map.insert(key.into_value(), value.into_value());
267267
}
268-
Ok(BinaryValue(Value::from(map)))
268+
Ok(BinaryValue(Value::Object(crate::Rc::new(map))))
269269
}
270270
(BinaryVariant::Undefined, variant) => {
271271
variant.unit_variant()?;

src/rvm/vm/arithmetic.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
// Disable both to keep patterns consistent within this file.
77
#![allow(clippy::pattern_type_mismatch, clippy::needless_borrowed_reference)]
88

9-
use alloc::collections::BTreeSet;
10-
119
use crate::number::Number;
1210
use crate::value::Value;
1311

@@ -32,8 +30,8 @@ impl RegoVM {
3230
match (a, b) {
3331
(&Value::Number(ref x), &Value::Number(ref y)) => Ok(Value::from(x.sub(y)?)),
3432
(&Value::Set(ref left), &Value::Set(ref right)) => {
35-
let diff: BTreeSet<Value> = left.difference(right).cloned().collect();
36-
Ok(Value::from_set(diff))
33+
let diff = left.difference(right);
34+
Ok(diff.into_value())
3735
}
3836
_ => Err(VmError::InvalidSubtraction {
3937
left: a.clone(),

0 commit comments

Comments
 (0)