makepad/platform/script/tests/hook_scope.rs
Admin 62d4f31b1e script: Splash VM heaps, isolates and lazy system modules
Every heap ref carries its heap tag, generation checks always on, rooted
async values. Splash isolates get a domain table and curated minimal
preludes; system modules under `mod` expand lazily on first touch. No
wall-clock script caps: isolation and force-stop instead.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-13 12:26:21 +02:00

48 lines
2.1 KiB
Rust

//! Host->script hook lookups against a Splash-shaped body: the script is
//! wrapped in an auto-closed object literal, and a `let`/`fn` that shadows
//! an existing name opens a child scope the module scope cannot see into.
//! The body remembers the scope it ended in for exactly that.
use makepad_script::*;
fn test_vm() -> ScriptVm<'static> {
let host = Box::leak(Box::new(ScriptVmHost::new(0i32, ())));
ScriptVm {
host: host.host_context(),
bx: Box::new(ScriptVmBase::new()),
}
}
fn scopes(vm: &mut ScriptVm, file: &str) -> (ScriptObject, Option<ScriptObject>) {
let bodies = vm.bx.code.bodies.borrow();
bodies.iter().find_map(|body| match &body.source {
ScriptSource::Mod(m) if m.file == file => {
Some((body.scope.as_object(), body.end_scope.as_ref().map(|s| s.as_object())))
}
_ => None,
}).expect("body")
}
#[test]
fn hooks_resolve_in_the_scope_the_body_ended_in() {
let mut vm = test_vm();
vm.bx.captured_errors = Some(Vec::new());
// `fs` is defined twice: the second `let` shadows and opens a child scope.
let code = "let fs = 1\n{height: 1, let fs = 2\nfn before(){ 7 }\nfn on_x(){ 42 }\n{}\n";
vm.with_instruction_limit(500_000, |vm| {
vm.eval(ScriptMod::new("", "", "hook_scope", 0, 0, &code, &[]))
});
let errors = vm.take_errors();
assert!(errors.is_empty(), "eval errored: {errors:?}");
let (module, end) = scopes(&mut vm, "hook_scope");
let end = end.expect("the body recorded the scope it ended in");
let from_module = vm.bx.heap.scope_value(module, id!(on_x), NoTrap);
assert!(from_module.is_nil() || from_module.is_err(), "the module scope should not see past the shadowing let");
let on_x = vm.bx.heap.scope_value(end, id!(on_x), NoTrap);
assert!(!on_x.is_nil() && !on_x.is_err(), "on_x not found in the end scope");
let result = vm.with_instruction_limit(500_000, |vm| vm.call(on_x, &[]));
assert_eq!(format!("{result:?}"), "42", "on_x returned {result:?}");
let before = vm.bx.heap.scope_value(end, id!(before), NoTrap);
assert!(!before.is_nil() && !before.is_err(), "before not found in the end scope");
}