kobako 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +1 -1
  3. data/README.md +85 -5
  4. data/data/kobako.wasm +0 -0
  5. data/ext/kobako/Cargo.toml +1 -1
  6. data/ext/kobako/src/wasm/cache.rs +12 -4
  7. data/ext/kobako/src/wasm/dispatch.rs +15 -14
  8. data/ext/kobako/src/wasm/host_state.rs +111 -5
  9. data/ext/kobako/src/wasm/instance.rs +135 -33
  10. data/ext/kobako/src/wasm.rs +1 -0
  11. data/lib/kobako/codec/decoder.rb +0 -2
  12. data/lib/kobako/codec/factory.rb +13 -10
  13. data/lib/kobako/codec/utils.rb +105 -13
  14. data/lib/kobako/handle.rb +62 -0
  15. data/lib/kobako/handle_table.rb +119 -0
  16. data/lib/kobako/invocation.rb +56 -25
  17. data/lib/kobako/outcome.rb +42 -12
  18. data/lib/kobako/rpc/dispatcher.rb +22 -20
  19. data/lib/kobako/rpc/envelope.rb +7 -7
  20. data/lib/kobako/rpc/fault.rb +1 -1
  21. data/lib/kobako/rpc/server.rb +12 -24
  22. data/lib/kobako/rpc/wire_error.rb +23 -0
  23. data/lib/kobako/sandbox.rb +77 -24
  24. data/lib/kobako/usage.rb +41 -0
  25. data/lib/kobako/version.rb +1 -1
  26. data/lib/kobako.rb +1 -0
  27. data/sig/kobako/codec/factory.rbs +1 -1
  28. data/sig/kobako/codec/utils.rbs +10 -0
  29. data/sig/kobako/handle.rbs +19 -0
  30. data/sig/kobako/handle_table.rbs +23 -0
  31. data/sig/kobako/invocation.rbs +3 -1
  32. data/sig/kobako/outcome.rbs +1 -1
  33. data/sig/kobako/rpc/dispatcher.rbs +7 -7
  34. data/sig/kobako/rpc/envelope.rbs +3 -3
  35. data/sig/kobako/rpc/server.rbs +1 -7
  36. data/sig/kobako/rpc/wire_error.rbs +6 -0
  37. data/sig/kobako/sandbox.rbs +7 -1
  38. data/sig/kobako/usage.rbs +11 -0
  39. data/sig/kobako/wasm.rbs +2 -0
  40. metadata +9 -5
  41. data/lib/kobako/rpc/handle.rb +0 -39
  42. data/lib/kobako/rpc/handle_table.rb +0 -107
  43. data/sig/kobako/rpc/handle.rbs +0 -19
  44. data/sig/kobako/rpc/handle_table.rbs +0 -25
@@ -1,107 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "handle"
4
-
5
- module Kobako
6
- module RPC
7
- # Host-side mapping from opaque integer Handle IDs to Ruby objects
8
- # (capability proxies). One table is owned per +Kobako::RPC::Server+
9
- # instance (and therefore per +Kobako::Sandbox+ instance). See
10
- # {docs/behavior.md B-15}[link:../../../docs/behavior.md].
11
- #
12
- # Lifecycle invariants ({docs/behavior.md}[link:../../../docs/behavior.md]):
13
- #
14
- # - {docs/behavior.md B-15}[link:../../../docs/behavior.md] — Handle IDs are allocated by
15
- # a monotonically increasing counter scoped to a single `#run`. The
16
- # first ID issued in a run is 1; ID 0 is reserved as the invalid
17
- # sentinel and is never returned by #alloc.
18
- #
19
- # - {docs/behavior.md B-19}[link:../../../docs/behavior.md] — When between `#run`
20
- # invocations (via `#reset!`), every Handle issued under the old state
21
- # becomes invalid.
22
- #
23
- # - {docs/behavior.md B-21}[link:../../../docs/behavior.md] — The cap is `0x7fff_ffff`
24
- # (2³¹ − 1). Allocation beyond the cap raises immediately — no silent
25
- # truncation, no wrap, no ID reuse.
26
- class HandleTable
27
- # Build a fresh, empty HandleTable. +next_id+ is an internal seam that
28
- # sets the starting value of the monotonic counter (defaults to 1 per
29
- # B-15); tests pass a value near +RPC::Handle::MAX_ID+ to exercise
30
- # the cap-exhaustion path without 2³¹ allocations.
31
- def initialize(next_id: 1)
32
- @entries = {} # : Hash[Integer, untyped]
33
- @next_id = next_id
34
- end
35
-
36
- # Bind +object+ in the table and return its newly-allocated Handle ID.
37
- # +object+ is any host-side Ruby object to bind. Returns a freshly-
38
- # allocated Handle ID in +[1, RPC::Handle::MAX_ID]+. Raises
39
- # +Kobako::HandleTableExhausted+ if the next ID would exceed the cap.
40
- # The cap is anchored on +RPC::Handle+ — the wire codec and the
41
- # allocator share the same invariant ({docs/behavior.md B-21}[link:../../../docs/behavior.md]).
42
- def alloc(object)
43
- id = @next_id
44
- cap = RPC::Handle::MAX_ID
45
- raise HandleTableExhausted, "HandleTable exhausted: id #{id} exceeds MAX_ID #{cap}" if id > cap
46
-
47
- @entries[id] = object
48
- @next_id = id + 1
49
- id
50
- end
51
-
52
- # Resolve a Handle ID to its bound object. +id+ is a Handle ID previously
53
- # returned by +#alloc+. Returns the bound object. Raises
54
- # +Kobako::HandleTableError+ if +id+ is not currently bound.
55
- def fetch(id)
56
- require_bound!(id)
57
- @entries[id]
58
- end
59
-
60
- # Remove and return the binding for +id+. +id+ is the Handle ID to
61
- # release. Returns the previously-bound object. Raises
62
- # +Kobako::HandleTableError+ if +id+ is not currently bound.
63
- def release(id)
64
- require_bound!(id)
65
- @entries.delete(id)
66
- end
67
-
68
- # Clear all entries AND reset the counter to 1. Called at the per-run
69
- # boundary — see {docs/behavior.md B-19}[link:../../../docs/behavior.md].
70
- # Returns +self+.
71
- def reset!
72
- @entries.clear
73
- @next_id = 1
74
- self
75
- end
76
-
77
- # Mark the entry at +id+ as disconnected (ABA protection). +id+ is the
78
- # Handle ID to poison; silently ignored if +id+ is not currently bound.
79
- # Returns +self+ for chainability, matching the convention of +#reset!+.
80
- def mark_disconnected(id)
81
- @entries[id] = :disconnected if @entries.key?(id)
82
- self
83
- end
84
-
85
- # Returns the number of currently-bound entries.
86
- def size
87
- @entries.size
88
- end
89
-
90
- # Returns +true+ when +id+ is currently bound, +false+ otherwise.
91
- def include?(id)
92
- @entries.key?(id)
93
- end
94
-
95
- private
96
-
97
- # Single source of truth for the "unknown Handle id" raise shared by
98
- # {#fetch} and {#release}. Returns +nil+ on success; raises
99
- # +Kobako::HandleTableError+ when +id+ is not currently bound.
100
- def require_bound!(id)
101
- return if @entries.key?(id)
102
-
103
- raise HandleTableError, "unknown Handle id: #{id.inspect}"
104
- end
105
- end
106
- end
107
- end
@@ -1,19 +0,0 @@
1
- module Kobako
2
- module RPC
3
- class Handle
4
- MIN_ID: Integer
5
- MAX_ID: Integer
6
-
7
- attr_reader id: Integer
8
-
9
- def initialize: (Integer id) -> void
10
- | (id: Integer) -> void
11
-
12
- def with: (?id: Integer) -> Handle
13
-
14
- def ==: (untyped other) -> bool
15
-
16
- def hash: () -> Integer
17
- end
18
- end
19
- end
@@ -1,25 +0,0 @@
1
- module Kobako
2
- module RPC
3
- class HandleTable
4
- def initialize: (?next_id: Integer) -> void
5
-
6
- def alloc: (untyped object) -> Integer
7
-
8
- def fetch: (Integer id) -> untyped
9
-
10
- def release: (Integer id) -> untyped
11
-
12
- def reset!: () -> self
13
-
14
- def mark_disconnected: (Integer id) -> self
15
-
16
- def size: () -> Integer
17
-
18
- def include?: (Integer id) -> bool
19
-
20
- private
21
-
22
- def require_bound!: (Integer id) -> void
23
- end
24
- end
25
- end