use stet_core::vm_audit::{audit_global_vm, audit_global_vm_unsafe_only};
fn run(source: &[u8]) -> stet::Interpreter {
let mut interp = stet::Interpreter::builder().suppress_output().build();
let _ = stet_engine::eval::parse_and_exec(interp.context(), source);
interp
}
#[test]
fn bootstrap_leaves_no_reclaimable_global_local_refs() {
let mut interp = stet::Interpreter::builder().suppress_output().build();
let ctx = interp.context();
assert!(
!audit_global_vm(ctx).is_empty(),
"expected the PLRM 3.7.5 systemdict exception to be present"
);
let unsafe_refs = audit_global_vm_unsafe_only(ctx);
assert!(
unsafe_refs.is_empty(),
"bootstrap left reclaimable global->local references: {:#?}",
unsafe_refs
);
}
#[test]
fn setpagedevice_keeps_the_page_device_in_global_vm() {
let interp = run(b"<< /PageSize [612 792] >> setpagedevice\n");
let mut interp = interp;
let unsafe_refs = audit_global_vm_unsafe_only(interp.context());
assert!(
unsafe_refs.is_empty(),
"setpagedevice left reclaimable global->local references: {:#?}",
unsafe_refs
);
}
#[test]
fn setpagedevice_across_save_restore_is_clean() {
let mut interp = run(b"/s save def\n\
<< /PageSize [612 792] >> setpagedevice\n\
s restore\n\
<< /PageSize [595 842] >> setpagedevice\n");
let unsafe_refs = audit_global_vm_unsafe_only(interp.context());
assert!(
unsafe_refs.is_empty(),
"setpagedevice across save/restore left reclaimable refs: {:#?}",
unsafe_refs
);
}
#[test]
fn repeated_save_restore_page_device_cycles_stay_clean() {
let mut interp = run(b"20 { /s save def \
<< /PageSize [612 792] >> setpagedevice \
s restore } repeat\n");
let unsafe_refs = audit_global_vm_unsafe_only(interp.context());
assert!(
unsafe_refs.is_empty(),
"repeated save/restore cycles left reclaimable refs: {:#?}",
unsafe_refs
);
}
#[test]
fn error_handling_restores_vm_allocation_mode() {
let mut interp = run(b"/lstr (local) def\n\
true setglobal\n\
{ [lstr] pop } stopped pop\n\
/after currentglobal def\n\
false setglobal\n");
let ctx = interp.context();
let name = ctx
.names
.find(b"after")
.expect("`after` should be interned");
let value = ctx
.dict_load(&stet_core::dict::DictKey::Name(name))
.expect("`after` should be defined");
assert!(
matches!(value.value, stet_core::object::PsValue::Bool(true)),
"an error caught by `stopped` reset the VM allocation mode: {:?}",
value.value
);
}