/* StarForth — Steady-State Virtual Machine Runtime Copyright (c) 2023–2025 Robert A. James All rights reserved. This file is part of the StarForth project. Licensed under the StarForth License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: https://github.com/star.4th@proton.me/StarForth/LICENSE.txt This software is provided "AS IS", WITHOUT WARRANTY OF ANY KIND, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and noninfringement. See the License for the specific language governing permissions and limitations under the License. */ /** * vm_frame.h - per-VM execution frame stack (FABRIC-3.8.md §3.12, Stage FR). * * Captain Bob, 2026-09-23: "give frames IDs and call by ID" -- frames stack * per VM, each with an ID. Each VM owns one VMFrameStack describing the * nested execution levels running on ITS OWN native stack: an interpret of * its own dictionary, a nested VM-EXEC into another VM's dictionary (a * frame on the caller's stack whose vm_id is the target), a drain of one of * its messages, or its parked idle point. Every frame carries a system-wide * unique VMFrameID and names the executing VM by VMUuid -- by ID, never by * pointer, so nothing here can dangle after a VM dies. * * What used to be loose per-VM flags is now derived from this stack * (vm_core.c / kernel_hermes.c / switch.c): the ownership gate, the drain * guard, parked-idle, and log attribution. * * Embedded in `struct VM` as `VM.frames` (own header per * feedback_dedicated_headers_not_inline_fields). `vm.h` is shared with the * hosted build, so this header must not typedef `VM`; it uses `struct VM *`. */ #ifndef STARKERNEL_VM_FRAME_H #define STARKERNEL_VM_FRAME_H #include #include "starkernel/vm_uuid.h" /* VMUuid */ struct VM; /** System-wide unique, monotonic, never reused. 0 = no frame. */ typedef uint64_t VMFrameID; typedef enum { VM_FRAME_INTERPRET = 1, /**< vm_interpret() of vm_id's dictionary */ VM_FRAME_DRAIN = 2, /**< interpreting one of vm_id's own kernel-Hermes messages */ VM_FRAME_IDLE = 3 /**< vm_id parked at its switch trampoline's idle point */ } VMFrameKind; typedef struct VMFrameEntry { VMFrameID id; VMUuid vm_id; /**< the VM executing at this level (held by ID) */ uint32_t kind; /**< VMFrameKind */ } VMFrameEntry; typedef struct VMFrameStack { VMFrameEntry *entries; /**< growable; grown by allocate-copy-free */ int count; int cap; int max; /**< high-water mark (DoE-observable) */ } VMFrameStack; #ifdef __STARKERNEL__ /** Reserve initial capacity (called at birth so the hot path rarely grows). 0 ok, -1 fail. */ int vm_frame_reserve(VMFrameStack *s, int cap); /** Push a frame; returns its new ID, or 0 if the stack could not grow (caller fails closed). */ VMFrameID vm_frame_push(VMFrameStack *s, VMUuid vm_id, uint32_t kind); /** Pop by ID. A top that isn't `id` is corruption: logged, and `id` is removed wherever it is. */ void vm_frame_pop(VMFrameStack *s, VMFrameID id); /** Nonzero if the top frame exists and has this kind and vm_id. */ int vm_frame_top_is(const VMFrameStack *s, VMUuid vm_id, uint32_t kind); /** Nonzero if any frame on the stack has this kind and vm_id. */ int vm_frame_has(const VMFrameStack *s, VMUuid vm_id, uint32_t kind); /** Release the stack's storage (vm_cleanup). */ void vm_frame_free(VMFrameStack *s); /** The frame stack of the VM physically owning the running native stack * (sk_vm_switch_current_vm()), or the boot stack before the switch * mechanism is seeded. Defined in vm_core.c. */ VMFrameStack *vm_frame_current_stack(void); /** vm_interpret() with an explicit frame kind (VM_FRAME_INTERPRET for plain * interpretation; the drain uses VM_FRAME_DRAIN). Defined in vm_core.c. */ void vm_interpret_kind(struct VM *vm, const char *input, uint32_t kind); #endif #endif /* STARKERNEL_VM_FRAME_H */