Class: Kobako::Catalog::Handles
- Inherits:
-
Object
- Object
- Kobako::Catalog::Handles
- Defined in:
- lib/kobako/catalog/handles.rb
Overview
Host-side mapping from opaque integer Handle IDs to Ruby objects. The table is owned by Kobako::Sandbox (docs/behavior.md B-19) and injected into the per-Sandbox Kobako::Catalog::Namespaces so guest→host dispatch resolves Handle targets and arguments against the same table that host→guest wire encoding allocates into (docs/behavior.md B-14, B-34).
Lifecycle invariants (docs/behavior.md):
- {docs/behavior.md B-15}[link:../../../docs/behavior.md] — Handle IDs
are allocated by a monotonically increasing counter scoped to a
single invocation. The first ID issued in an invocation is 1; ID 0
is reserved as the invalid sentinel and is never returned by
+#alloc+.
- {docs/behavior.md B-19}[link:../../../docs/behavior.md] — At every
invocation boundary (via +#reset!+), every Handle issued under the
old state becomes invalid. Reset applies uniformly regardless of
allocation source (B-14 Service return or B-34 host-injected
argument).
- {docs/behavior.md B-21}[link:../../../docs/behavior.md] — The cap is
+0x7fff_ffff+ (2³¹ − 1). Allocation beyond the cap raises
immediately — no silent truncation, no wrap, no ID reuse.
Instance Method Summary collapse
-
#alloc(object) ⇒ Object
Bind
objectin the table and return aKobako::Handletoken for it. -
#fetch(id) ⇒ Object
Resolve a Handle ID to its bound object.
-
#initialize(next_id: 1) ⇒ Handles
constructor
Build a fresh, empty table.
-
#reset! ⇒ Object
Clear all entries AND reset the counter to 1.
-
#size ⇒ Object
Number of currently-bound entries.
Constructor Details
#initialize(next_id: 1) ⇒ Handles
Build a fresh, empty table. next_id is an internal seam that sets the starting value of the monotonic counter (defaults to 1 per B-15); tests pass a value near Kobako::Handle::MAX_ID to exercise the cap-exhaustion path without 2³¹ allocations.
37 38 39 40 |
# File 'lib/kobako/catalog/handles.rb', line 37 def initialize(next_id: 1) @entries = {} # : Hash[Integer, untyped] @next_id = next_id end |
Instance Method Details
#alloc(object) ⇒ Object
Bind object in the table and return a Kobako::Handle token for it. object is any host-side Ruby object to bind. Returns a freshly-allocated Kobako::Handle whose #id falls in [Kobako::Handle::MIN_ID, Kobako::Handle::MAX_ID]. Raises Kobako::HandlerExhaustedError if the next ID would exceed the cap. The cap is anchored on Kobako::Handle — the wire codec and the allocator share the same invariant (docs/behavior.md B-21).
Returning a Handle (rather than a bare Integer id) keeps the allocator’s output a domain entity; Kobako::Handle.restore is reserved for the codec’s wire-decode path, where the id is the only thing the bytes carry.
55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/kobako/catalog/handles.rb', line 55 def alloc(object) id = @next_id cap = Kobako::Handle::MAX_ID if id > cap raise HandlerExhaustedError, "Out of handle allocations: too many host objects were referenced " \ "in a single invocation (limit #{cap})" end @entries[id] = object @next_id = id + 1 Kobako::Handle.restore(id) end |
#fetch(id) ⇒ Object
Resolve a Handle ID to its bound object. id is a Handle ID previously returned by #alloc. Returns the bound object. Raises Kobako::SandboxError if id is not currently bound.
72 73 74 75 |
# File 'lib/kobako/catalog/handles.rb', line 72 def fetch(id) require_bound!(id) @entries[id] end |
#reset! ⇒ Object
Clear all entries AND reset the counter to 1. Called at the per-invocation boundary by Kobako::Sandbox — see docs/behavior.md B-19. Returns self.
80 81 82 83 84 |
# File 'lib/kobako/catalog/handles.rb', line 80 def reset! @entries.clear @next_id = 1 self end |
#size ⇒ Object
Number of currently-bound entries. Used by tests of the Dispatcher and Codec::Utils#deep_wrap to observe whether each path allocates exactly the Handle entries it should — the Handles table itself never consults its own size, but the surrounding code’s allocation contract is part of the observable boundary.
91 92 93 |
# File 'lib/kobako/catalog/handles.rb', line 91 def size @entries.size end |