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.
- checksums.yaml +4 -4
- data/Cargo.lock +1 -1
- data/README.md +85 -5
- data/data/kobako.wasm +0 -0
- data/ext/kobako/Cargo.toml +1 -1
- data/ext/kobako/src/wasm/cache.rs +12 -4
- data/ext/kobako/src/wasm/dispatch.rs +15 -14
- data/ext/kobako/src/wasm/host_state.rs +111 -5
- data/ext/kobako/src/wasm/instance.rs +135 -33
- data/ext/kobako/src/wasm.rs +1 -0
- data/lib/kobako/codec/decoder.rb +0 -2
- data/lib/kobako/codec/factory.rb +13 -10
- data/lib/kobako/codec/utils.rb +105 -13
- data/lib/kobako/handle.rb +62 -0
- data/lib/kobako/handle_table.rb +119 -0
- data/lib/kobako/invocation.rb +56 -25
- data/lib/kobako/outcome.rb +42 -12
- data/lib/kobako/rpc/dispatcher.rb +22 -20
- data/lib/kobako/rpc/envelope.rb +7 -7
- data/lib/kobako/rpc/fault.rb +1 -1
- data/lib/kobako/rpc/server.rb +12 -24
- data/lib/kobako/rpc/wire_error.rb +23 -0
- data/lib/kobako/sandbox.rb +77 -24
- data/lib/kobako/usage.rb +41 -0
- data/lib/kobako/version.rb +1 -1
- data/lib/kobako.rb +1 -0
- data/sig/kobako/codec/factory.rbs +1 -1
- data/sig/kobako/codec/utils.rbs +10 -0
- data/sig/kobako/handle.rbs +19 -0
- data/sig/kobako/handle_table.rbs +23 -0
- data/sig/kobako/invocation.rbs +3 -1
- data/sig/kobako/outcome.rbs +1 -1
- data/sig/kobako/rpc/dispatcher.rbs +7 -7
- data/sig/kobako/rpc/envelope.rbs +3 -3
- data/sig/kobako/rpc/server.rbs +1 -7
- data/sig/kobako/rpc/wire_error.rbs +6 -0
- data/sig/kobako/sandbox.rbs +7 -1
- data/sig/kobako/usage.rbs +11 -0
- data/sig/kobako/wasm.rbs +2 -0
- metadata +9 -5
- data/lib/kobako/rpc/handle.rb +0 -39
- data/lib/kobako/rpc/handle_table.rb +0 -107
- data/sig/kobako/rpc/handle.rbs +0 -19
- 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
|
data/sig/kobako/rpc/handle.rbs
DELETED
|
@@ -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
|