feat: expose precise observations for synchronous read-only calls

This commit is contained in:
2026-10-24 02:17:02 +08:00
parent ee68a0c54c
commit 1aecc7e952
2 changed files with 27 additions and 1 deletions
+15 -1
View File
@@ -59,9 +59,23 @@ impl Vm {
arguments: &[Value],
limits: ExecutionLimits,
) -> Result<(Value, Vec<ObjectRef>), VmError> {
let (value, reads) =
self.call_read_only_precise_with_limits(function, arguments, limits)?;
Ok((value, reads.objects))
}
/// Synchronous read-only call with precise observations as well as the
/// conservative object list. Result ownership and hard limits match call().
/// ReadSet and all identities/value snapshots inside it are borrowed only.
pub fn call_read_only_precise_with_limits(
&mut self,
function: ObjectRef,
arguments: &[Value],
limits: ExecutionLimits,
) -> Result<(Value, crate::ReadSet), VmError> {
let scope = self.objects.begin_read_only();
let result = self.call_with_limits(function, arguments, limits);
let reads = self.objects.end_read_only(scope)?;
let reads = self.objects.end_read_only_precise(scope)?;
result.map(|value| (value, reads))
}
+12
View File
@@ -1749,6 +1749,18 @@ fn named_reads_ignore_unrelated_globals_but_track_missing_shadow_and_payload_kin
assert!(reads.contains(&globals) && reads.contains(&builtins));
vm.release_value(value).unwrap();
vm.dict_set(globals, text("_"), text("unrelated")).unwrap();
let (value, synchronous) = vm
.call_read_only_precise_with_limits(function, &[], ExecutionLimits::default())
.unwrap();
assert_eq!(value, text("builtin"));
assert_eq!(synchronous.dependencies, dependencies);
assert_eq!(synchronous.objects, reads);
vm.release_value(value).unwrap();
let (value, conservative) = vm
.call_read_only_with_limits(function, &[], ExecutionLimits::default())
.unwrap();
assert_eq!(conservative, reads);
vm.release_value(value).unwrap();
assert!(
dependencies
.iter()