(vm: &VirtualMachine, f: impl FnOnce() -> R)
| 76 | } |
| 77 | |
| 78 | pub fn enter_vm<R>(vm: &VirtualMachine, f: impl FnOnce() -> R) -> R { |
| 79 | VM_STACK.with(|vms| { |
| 80 | // Outermost enter_vm: transition DETACHED → ATTACHED |
| 81 | #[cfg(all(unix, feature = "threading"))] |
| 82 | let was_outermost = vms.borrow().is_empty(); |
| 83 | |
| 84 | vms.borrow_mut().push(vm.into()); |
| 85 | |
| 86 | // Initialize thread slot for this thread if not already done |
| 87 | #[cfg(feature = "threading")] |
| 88 | init_thread_slot_if_needed(vm); |
| 89 | |
| 90 | #[cfg(all(unix, feature = "threading"))] |
| 91 | if was_outermost { |
| 92 | attach_thread(vm); |
| 93 | } |
| 94 | |
| 95 | scopeguard::defer! { |
| 96 | // Outermost exit: transition ATTACHED → DETACHED |
| 97 | #[cfg(all(unix, feature = "threading"))] |
| 98 | if vms.borrow().len() == 1 { |
| 99 | detach_thread(); |
| 100 | } |
| 101 | vms.borrow_mut().pop(); |
| 102 | } |
| 103 | VM_CURRENT.set(vm, f) |
| 104 | }) |
| 105 | } |
| 106 | |
| 107 | /// Initialize thread slot for current thread if not already initialized. |
| 108 | /// Called automatically by enter_vm(). |
no test coverage detected