Skip to documentation
SLOP

tiny.machine.Instance

Reference tiny.machine Instance

Defined in tiny.machine.

Operates one K0 guest that is running now, borrowing its storage and whatever backs its guest memory, so every lifecycle call goes through this handle.

API (23)

Actions

Public operations.

Fields and members

Public fields and members.

No direct callersNo direct callstiny.machineInstance
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/machine/src/instance/owner.zig:261

zig
/// Operates one K0 guest that is running now, borrowing its storage and/// whatever backs its guest memory, so every lifecycle call goes through this/// handle. Each borrowed region keeps its address until `deinit`. Starting a/// new lifecycle in the same storage makes copied handles stale, because the/// session identity moves on.pub const Instance = struct {    storage: *Storage,    ram: []align(layout.page_bytes) u8,    memory: core.memory.Access,    session_identity: u64,    /// Boots K0 from an ELF image and its execution manifest under the profile    /// the input names, so a caller performs a cold start of a guest. That    /// profile decides whether Linux KVM or the reference interpreter carries    /// the guest. A ready outcome keeps `storage` and exactly `ram_bytes` bytes    /// of RAM until `deinit`. Anything the validator turns away, and any    /// backend that fails to come up, comes back as rejected. A host lacking    /// the backend comes back as unavailable.    pub fn init(        storage: *Storage,        ram: []align(layout.page_bytes) u8,        input: types.Input,    ) StartResult {        return switch (input.profile.backend) {            .linux_kvm_single_vcpu_v1 => initSelected(                storage,                ram,                input,                .accelerator,                null,                accelerator.start,            ),            .portable_x86_64_interpreter_v1 => initSelected(                storage,                ram,                input,                .reference,                null,                reference.start,            ),        };    }    /// Rebuilds the guest named by the expected checkpoint root inside    /// caller-owned RAM, under the selected profile, so the caller brings a    /// captured guest back into RAM it owns. A ready outcome keeps the storage    /// and the RAM until `deinit`. A host lacking the backend comes back as    /// unavailable, before anything reaches RAM. Every other failure comes back    /// as rejected.    pub fn restore(        storage: *Storage,        ram: []align(layout.page_bytes) u8,        input: types.RestoreInput,    ) RestoreResult {        return switch (input.profile.backend) {            .linux_kvm_single_vcpu_v1 => restoreSelected(                storage,                ram,                input,                .accelerator,                null,                accelerator.acquireRestore,            ),            .portable_x86_64_interpreter_v1 => restoreSelected(                storage,                ram,                input,                .reference,                null,                null,            ),        };    }    /// Brings the portable interpreter up over pages read from a store that    /// authenticates them, so a caller restores a captured guest through store    /// pages. The root provider and every buffer of branch storage have to    /// outlive the instance, up to `deinit`. Each write takes a branch page    /// from a fixed supply, and running out comes back as    /// `MemoryCapacityExceeded`.    pub fn restoreShared(        storage: *Storage,        root_storage: checkpoint.roots.Storage,        branch_storage: checkpoint.roots.branch.Storage,        input: types.SharedRestoreInput,    ) RestoreResult {        return restoreSharedSelected(            storage,            root_storage,            branch_storage,            input,        );    }    /// Gives up whatever the backend holds and closes this lifecycle, so the    /// caller gets its buffers back. Calling it twice, or calling it on a stale    /// copied handle, does nothing. Afterward the storage and the memory    /// backing are the caller's to use again.    pub fn deinit(self: *@This()) void {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return;        if (owner.phase == .closed) return;        switch (owner.active_backend) {            .accelerator => accelerator.deinit(backendState(owner)),            .reference => reference.deinit(backendState(owner)),            .none => {},        }        owner.phase = .closed;        owner.active_backend = .none;        owner.manifest_bytes = 0;        owner.ram_address = 0;        owner.memory_identity = 0;        owner.memory_kind = .none;        owner.quiescence_receipt = null;    }    /// Says whether this handle is the one driving the lifecycle its storage    /// currently holds, so a caller can tell whether a copied handle remains    /// the live one.    pub fn active(self: *const @This()) bool {        const owner = ownerState(self.storage);        return ownsLifecycle(self, owner) and owner.phase != .closed;    }    /// Names the stage the lifecycle has reached, so the caller knows which    /// calls are legal right now. A closed storage and a stale handle both    /// answer `closed`.    pub fn phase(self: *const @This()) types.RunPhase {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return .closed;        return owner.phase;    }    /// Copies bytes out of guest memory, starting at a byte offset counted from    /// zero, into a buffer the caller owns, so the caller can read guest state    /// from outside the guest. A closed handle, and any failure reaching the    /// memory, come back as `MemoryError`.    pub fn readMemory(        self: *const @This(),        address: usize,        output: []u8,    ) MemoryError!void {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        return self.memory.read(address, output);    }    /// Copies caller-owned bytes into guest memory at a byte offset counted    /// from zero, so the caller can change guest state from outside the guest.    /// A closed handle, a range outside the guest, a page that fails its digest    /// check, and exhausted branch storage all come back as `MemoryError`.    pub fn writeMemory(        self: *@This(),        address: usize,        input: []const u8,    ) MemoryError!void {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        return self.memory.write(address, input);    }    /// Counts the writable guest pages this instance has resident, so the    /// caller can see how many pages a shared restore has copied. A guest    /// living in the caller's RAM counts every page of it. A guest restored    /// from a store counts the pages copied into branch storage.    pub fn privatePageCount(self: *const @This()) MemoryError!u16 {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        return switch (owner.memory_kind) {            .linear => @intCast(checkpoint.page_count),            .branch => owner.branch.privatePageCount(),            .none => error.Closed,        };    }    /// Measures what this instance's guest memory holds in bytes, so the caller    /// can determine what one instance is holding. A guest living in the    /// caller's RAM measures `ram_bytes`. A guest restored from a store adds up    /// its branch bookkeeping, the digests it has authenticated, and the pages    /// it has copied.    pub fn residentMemoryBytes(self: *const @This()) MemoryError!u64 {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        return switch (owner.memory_kind) {            .linear => layout.ram_bytes,            .branch => owner.branch.residentBytes(),            .none => error.Closed,        };    }    /// Lets the selected backend carry the guest until it reaches one boundary    /// this namespace reports, so the caller advances the guest. A doorbell    /// taken while the guest is ready, and one taken while it is quiescent,    /// both move the lifecycle along. Any other boundary that comes back puts    /// the lifecycle into its failed stage. A boundary carrying no guest    /// progress is passed over and the backend is asked again, up to a limit.    /// The limit is 128 tries, and reaching it comes back as `WouldBlock`.    pub fn run(self: *@This()) RunError!types.Exit {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        const running_phase = owner.phase;        switch (running_phase) {            .booting, .input_delivered => {},            .draining_activation => return error.EventDrainRequired,            .awaiting_input => return error.InputRequired,            .draining_input => return error.EventDrainRequired,            .awaiting_acknowledgement => return error.AcknowledgementRequired,            .awaiting_reactivation => return error.ReactivationRequired,            .closed, .failed, .capturing_checkpoint, .completing_io => return error.Closed,        }        for (0..run_stutter_limit) |_| {            const raw = runBackend(owner) catch |failure| {                owner.phase = .failed;                return mapRunFailure(failure);            };            if (std.meta.activeTag(raw) == .stutter) continue;            const normalized = normalize(raw);            if (std.meta.activeTag(raw) == .io) {                owner.phase = .completing_io;                completePendingIo(owner) catch |failure| {                    owner.phase = .failed;                    return mapRunFailure(failure);                };                owner.phase = running_phase;            }            return applyExit(owner, running_phase, normalized);        }        return error.WouldBlock;    }    /// Reports the position an input is admitted against once the events the    /// activation produced have been taken, so the caller obtains the guest    /// position needed to admit an input. The guest has to be waiting for    /// input. Both rings have to be settled, the one carrying requests and the    /// one carrying events.    pub fn admissionBasis(        self: *const @This(),    ) BasisError!input_admission.Basis {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        if (owner.phase != .awaiting_input) return error.InputUnavailable;        if (owner.activation_stage != .complete) {            return error.ActivationEventsPending;        }        const requests = try os.abi.RequestRing.frontiers(            try layout.requestRingAccess(self.memory),            owner.fence,        );        const events = try os.abi.EventRing.frontiers(            try layout.eventRingAccess(self.memory),            owner.fence,        );        if (requests.consumed != 0 or requests.produced != 0 or            events.consumed != os.k0.events_per_activation or            events.produced != os.k0.events_per_activation)        {            return error.EventReceiptMismatch;        }        return basis(owner);    }    /// Checks one admitted input against the position and the authority in    /// force, then writes it where the guest reads, so an admitted input    /// reaches the guest. The delivery value is copied during the call. A phase    /// that forbids the call, a ring that will not take the input, a memory    /// failure, and an admission that does not check out all leave the turn    /// unacknowledged.    pub fn deliverAdmitted(        self: *@This(),        value: *const input_admission.Delivery,    ) DeliveryError!void {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        const owned = value.*;        if (owner.phase == .input_delivered or owner.phase == .draining_input) {            return error.InputAlreadyDelivered;        }        if (owner.phase == .awaiting_acknowledgement) {            return error.AcknowledgementRequired;        }        if (owner.phase != .awaiting_input) return error.InputUnavailable;        if (owner.activation_stage != .complete) {            return error.ActivationEventsPending;        }        try input_admission.verifyDelivery(basis(owner), owner.fence, &owned);        const requests = try layout.requestRingAccess(self.memory);        const events = try layout.eventRingAccess(self.memory);        const request_frontiers = try os.abi.RequestRing.frontiers(            requests,            owner.fence,        );        const event_frontiers = try os.abi.EventRing.frontiers(            events,            owner.fence,        );        if (request_frontiers.consumed != 0 or            request_frontiers.produced != 0 or            event_frontiers.consumed != os.k0.events_per_activation or            event_frontiers.produced != os.k0.events_per_activation)        {            return error.EventReceiptMismatch;        }        const request_sequence = std.math.add(            u64,            request_frontiers.produced,            1,        ) catch return error.SequenceExhausted;        const event_count: u64 = switch (owned.admission.record) {            .terminal => os.k0.events_per_terminal_input,            else => os.k0.events_per_nonterminal_input,        };        const final_event_sequence = std.math.add(            u64,            event_frontiers.produced,            event_count,        ) catch return error.SequenceExhausted;        var wire: os.abi.MessageWire = undefined;        try delivery.encode(            owner.fence,            request_sequence,            &owned.admission,            &wire,        );        try os.abi.RequestRing.push(requests, owner.fence, &wire);        owner.pending = .{            .delivery = owned,            .request_frontiers = request_frontiers,            .event_frontiers = event_frontiers,            .request_sequence = request_sequence,            .final_event_sequence = final_event_sequence,            .stage = .semantic,            .block_root = null,            .quiescence = null,            .event_transcript_digest = @splat(0),            .semantic_transcript_digest = @splat(0),        };        owner.phase = .input_delivered;    }    /// Moves every event of the current doorbell's group into a buffer the    /// caller owns, for the caller has to take them before the turn can be    /// acknowledged. That buffer may not overlap the handle, its storage, or    /// guest memory. When validation fails, the ring keeps its entries.    pub fn takeEvents(        self: *@This(),        output: *types.EventBatch,    ) EventError!void {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        const output_bytes = std.mem.asBytes(output);        if (image_admission.buffersOverlap(output_bytes, std.mem.asBytes(self))) {            return error.OutputAliasesInstance;        }        if (image_admission.buffersOverlap(output_bytes, &self.storage.bytes)) {            return error.OutputAliasesOwner;        }        if (self.memory.aliases(output_bytes)) {            return error.OutputAliasesRam;        }        if (owner.phase == .draining_activation) {            return takeActivationEvents(owner, self.memory, output);        }        if (owner.phase != .draining_input) return error.InputUnavailable;        return takeInputEvents(owner, self.memory, output);    }    /// Closes a turn whose events have all been taken, after the delivery    /// digest matches and both ring cursors have settled, so the caller    /// concludes the turn. Closing it builds the evidence for the quiescent    /// turn and moves the lifecycle to `awaiting_reactivation`.    pub fn acknowledge(        self: *@This(),        receipt: input_admission.DeliveryReceipt,    ) AcknowledgeError!void {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        if (owner.phase != .awaiting_acknowledgement) {            return error.InputUnavailable;        }        const pending = owner.pending orelse return error.InputUnavailable;        if (pending.stage != .complete) return error.EventDrainRequired;        if (!std.meta.eql(receipt, pending.delivery.receipt)) {            return error.DeliveryReceiptMismatch;        }        const settled = try settledRings(owner, self.memory, pending);        const committed = try prepareCommit(owner, pending, settled);        owner.source_root = committed.basis.source_root;        owner.frontiers = committed.basis.frontiers;        owner.outstanding_effect = committed.basis.outstanding_effect;        owner.block_root = committed.block_root.digest;        owner.terminal_offset = committed.terminal_offset;        owner.semantic_frontier = committed.semantic_frontier;        owner.root_generation = committed.root_generation;        owner.terminal_count = committed.terminal_count;        owner.pending = null;        owner.quiescence_receipt = committed.receipt;        owner.phase = .awaiting_reactivation;    }    /// Hands back the checked evidence for the turn that has settled, so the    /// caller receives the receipt for the completed turn. The guest has to be    /// waiting for reactivation. Both rings have to stand where the evidence    /// says they stand.    pub fn quiescenceReceipt(        self: *const @This(),    ) QuiescenceReceiptError!types.QuiescenceReceipt {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        if (owner.phase != .awaiting_reactivation) {            return error.QuiescenceUnavailable;        }        const value = owner.quiescence_receipt orelse            return error.QuiescenceUnavailable;        try quiescence_receipt.verifyForFence(value, owner.fence);        try validateReceiptOwner(owner, value);        const requests = try os.abi.RequestRing.frontiers(            try layout.requestRingAccess(self.memory),            owner.fence,        );        const events = try os.abi.EventRing.frontiers(            try layout.eventRingAccess(self.memory),            owner.fence,        );        if (requests.consumed != value.settled.request_cursor or            requests.produced != value.settled.request_cursor or            events.consumed != value.settled.event_cursor or            events.produced != value.settled.event_cursor)        {            return error.EventReceiptMismatch;        }        return value;    }    /// Writes the settled guest state into checkpoint storage and destination    /// RAM the caller owns, so the caller turns settled state into a retained    /// checkpoint. Both have to stay alive for as long as the checkpoint is    /// used. Buffers that overlap, evidence that does not check out, memory    /// that cannot be read, and a checkpoint that will not build all turn the    /// capture away.    pub fn captureCheckpoint(        self: *@This(),        storage: *checkpoint.Storage,        ram: []align(layout.page_bytes) u8,    ) CaptureCheckpointError!checkpoint.Checkpoint {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        try layout.validateRamBytes(ram.len);        if (image_admission.buffersOverlap(ram, std.mem.asBytes(self))) {            return error.OutputAliasesInstance;        }        if (image_admission.buffersOverlap(ram, &self.storage.bytes)) {            return error.OutputAliasesOwner;        }        if (self.memory.aliases(ram)) {            return error.OutputAliasesRam;        }        if (image_admission.buffersOverlap(&storage.bytes, std.mem.asBytes(self))) {            return error.StorageAliasesInstance;        }        if (image_admission.buffersOverlap(&storage.bytes, &self.storage.bytes)) {            return error.StorageAliasesOwner;        }        if (self.memory.aliases(&storage.bytes)) {            return error.StorageAliasesRam;        }        if (image_admission.buffersOverlap(&storage.bytes, ram)) {            return error.MemoryAliasesStorage;        }        try checkpoint.ensureAvailable(storage);        const receipt_value = try self.quiescenceReceipt();        owner.phase = .capturing_checkpoint;        defer owner.phase = .awaiting_reactivation;        const material = try checkpointMaterial(owner, receipt_value);        if (self.memory.linearRam()) |linear| {            return checkpoint.publish(material, storage, linear, ram);        }        try self.memory.read(0, ram);        const memory = try checkpoint.validatedMemoryDigest(            ram,            material.immutable_image,        );        const identity = try checkpoint.identify(material, memory);        var candidate = try checkpoint.beginMaterialization(storage, ram);        return checkpoint.publishMaterialized(            &candidate,            material,            identity.root,            memory,        );    }    /// Captures the pages that differ from a parent checkpoint the caller owns,    /// so the caller records changed pages against a durable parent. What comes    /// back borrows that parent and the hot storage passed in. A guest whose    /// memory comes from a store answers `MemoryReadFailed`.    pub fn captureHot(        self: *@This(),        parent: *const checkpoint.Checkpoint,        storage: checkpoint.hot.Storage,    ) CaptureHotError!checkpoint.hot.Snapshot {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        const index_bytes = std.mem.sliceAsBytes(storage.indices);        if (image_admission.buffersOverlap(index_bytes, std.mem.asBytes(self)) or            image_admission.buffersOverlap(storage.pages, std.mem.asBytes(self)))        {            return error.OutputAliasesInstance;        }        if (image_admission.buffersOverlap(index_bytes, &self.storage.bytes) or            image_admission.buffersOverlap(storage.pages, &self.storage.bytes))        {            return error.OutputAliasesOwner;        }        const receipt_value = try self.quiescenceReceipt();        owner.phase = .capturing_checkpoint;        defer owner.phase = .awaiting_reactivation;        const linear = self.memory.linearRam() orelse            return error.MemoryReadFailed;        return checkpoint.hot.capture(            parent,            try checkpointMaterial(owner, receipt_value),            linear,            storage,        );    }    /// Sets a settled instance running again under a newer authority, so the    /// caller installs the authority required for the next turn. The new    /// authority names the same world, counts one generation higher, and    /// carries a different token. When it succeeds the lifecycle stands at    /// `booting` again.    pub fn reactivate(        self: *@This(),        fence: os.abi.ActivationFence,    ) ReactivateError!void {        const owner = ownerState(self.storage);        if (!ownsLifecycle(self, owner)) return error.Closed;        if (owner.phase != .awaiting_reactivation) {            return error.InputUnavailable;        }        try os.abi.wire.validateFence(fence);        if (!std.mem.eql(u8, &owner.fence.world, &fence.world)) {            return error.ActivationWorldMismatch;        }        if (fence.generation <= owner.fence.generation) {            return error.ActivationGenerationStale;        }        if (std.mem.eql(u8, &owner.fence.token, &fence.token)) {            return error.ActivationTokenStale;        }        _ = std.math.add(u64, owner.terminal_offset, os.k0.ready_prompt.len) catch            return error.StateCapacityExceeded;        const frame = continuationFrame(owner, fence);        var wire: os.abi.BootWire = undefined;        try os.abi.encodeBootFrame(frame, &wire);        restartBackend(owner, self.memory) catch |failure| {            owner.phase = .failed;            return failure;        };        try layout.reactivateAccess(self.memory, frame, &wire);        owner.fence = fence;        owner.activation_stage = .ready;        owner.quiescence_receipt = null;        owner.phase = .booting;    }};

Source: lib/machine/src/root.zig:92

zig
pub const Instance = instance.Instance;
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateprivate sourcelib.machine.src.instance.ownerprepareCommitprivate sourcelib.machine.src.instance.ownersettledRingsInstanceacknowledge
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateInstanceactive
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.layouteventRingAccessprivate sourcelib.machine.src.instance.layoutrequestRingAccessprivate sourcelib.machine.src.instance.ownerbasisprivate sourcelib.machine.src.instance.ownerownerStateInstanceadmissionBasis
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.layoutvalidateRamBytesInstancequiescenceReceiptprivate sourcelib.machine.src.instance.ownercheckpointMaterialprivate sourcelib.machine.src.instance.ownerownerStateInstancecaptureCheckpoint
Static calls · unresolved targets: 3 · external targets: 9.
Called byCallsNo direct callersInstancequiescenceReceiptprivate sourcelib.machine.src.instance.ownercheckpointMaterialprivate sourcelib.machine.src.instance.ownerownerStateInstancecaptureHot
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerbackendStateprivate sourcelib.machine.src.instance.ownerownerStateInstancedeinit
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.deliveryencodeprivate sourcelib.machine.src.instance.layouteventRingAccessprivate sourcelib.machine.src.instance.layoutrequestRingAccessprivate sourcelib.machine.src.instance.ownerbasisprivate sourcelib.machine.src.instance.ownerownerStateInstancedeliverAdmitted
Static calls · unresolved targets: 1 · external targets: 4.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerinitSelectedInstanceinit
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateInstancephase
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateInstanceprivatePageCount
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsInstancecaptureCheckpointInstancecaptureHotprivate sourcelib.machine.src.instance.layouteventRingAccessprivate sourcelib.machine.src.instance.layoutrequestRingAccessprivate sourcelib.machine.src.instance.ownerownerStateprivate sourcelib.machine.src.instance.ownervalidateReceiptOwnerInstancequiescenceReceipt
Static calls · unresolved targets: 1 · external targets: 3.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.layoutreactivateAccessprivate sourcelib.machine.src.instance.ownercontinuationFrameprivate sourcelib.machine.src.instance.ownerownerStateprivate sourcelib.machine.src.instance.ownerrestartBackendInstancereactivate
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateInstancereadMemory
Static calls · unresolved targets: 2 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateInstanceresidentMemoryBytes
Static calls · unresolved targets: 1 · external targets: 1.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerrestoreSelectedInstancerestore
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerrestoreSharedSelectedInstancerestoreShared
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerapplyExitprivate sourcelib.machine.src.instance.ownercompletePendingIoprivate sourcelib.machine.src.instance.ownermapRunFailureprivate sourcelib.machine.src.instance.ownernormalizeprivate sourcelib.machine.src.instance.ownerownerStateprivate sourcelib.machine.src.instance.ownerrunBackendInstancerun
Static calls · unresolved targets: 1 · external targets: 0.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateprivate sourcelib.machine.src.instance.ownertakeActivationEventsprivate sourcelib.machine.src.instance.ownertakeInputEventsInstancetakeEvents
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callersprivate sourcelib.machine.src.instance.ownerownerStateInstancewriteMemory
Static calls · unresolved targets: 2 · external targets: 0.

Also reachable as

instance.Instance.

Audit

Definitions20
Public names40
Members4
Version26.7.0
Revisiondaab053ee433