kobako 0.9.2 → 0.10.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.
@@ -30,13 +30,6 @@ module Kobako
30
30
  # +0x7fff_ffff+ (2³¹ − 1). Allocation beyond the cap raises
31
31
  # immediately — no silent truncation, no wrap, no ID reuse.
32
32
  class Handles
33
- # Reflective gadget types that are never minted as a Capability Handle
34
- # ({docs/behavior.md B-43}[link:../../../docs/behavior.md]): wrapping a
35
- # +Binding+ / +Method+ / +UnboundMethod+ would hand the guest a callable
36
- # proxy onto host reflection (a returned +Binding+ reaches +Binding#eval+).
37
- UNWRAPPABLE_TYPES = [Binding, Method, UnboundMethod].freeze
38
- private_constant :UNWRAPPABLE_TYPES
39
-
40
33
  # Build a fresh, empty table. +next_id+ is an internal seam that
41
34
  # sets the starting value of the monotonic counter (defaults to 1 per
42
35
  # B-15); tests pass a value near +Kobako::Handle::MAX_ID+ to exercise
@@ -97,13 +90,16 @@ module Kobako
97
90
  private
98
91
 
99
92
  # Refuse to mint a Capability Handle for a reflective gadget
100
- # ({UNWRAPPABLE_TYPES}, B-43). Raising here keeps the rule at the single
101
- # mint point, so it holds on both the Service-return (B-14) and the
102
- # +#run+ host→guest auto-wrap (B-34) paths.
93
+ # ({docs/behavior.md B-43}[link:../../../docs/behavior.md]): a +Binding+ /
94
+ # +Method+ / +UnboundMethod+ would hand the guest a callable proxy onto
95
+ # host reflection (a returned +Binding+ reaches +Binding#eval+). Raising
96
+ # here keeps the rule at the single mint point, so it holds on both the
97
+ # Service-return (B-14) and the +#run+ host→guest auto-wrap (B-34) paths.
103
98
  def reject_unwrappable!(object)
104
- return unless UNWRAPPABLE_TYPES.any? { |type| object.is_a?(type) }
105
-
106
- raise SandboxError, "a #{object.class} cannot cross as a Capability Handle"
99
+ case object
100
+ when Binding, Method, UnboundMethod
101
+ raise SandboxError, "a #{object.class} cannot cross as a Capability Handle"
102
+ end
107
103
  end
108
104
 
109
105
  # Guard {#alloc} against issuing an ID past the B-21 cap. Returns +nil+
@@ -37,6 +37,7 @@ module Kobako
37
37
  @namespaces = {} # : Hash[String, Kobako::Namespace]
38
38
  @handler = handler
39
39
  @sealed = false
40
+ @encoded = nil # : String?
40
41
  end
41
42
 
42
43
  # Declare or retrieve the Namespace named +name+ (idempotent —
@@ -80,14 +81,32 @@ module Kobako
80
81
  # Arrays, so none of the kobako ext types actually fire. Structure:
81
82
  # +[["Namespace", ["MemberA", "MemberB"]], ...]+. Returns a binary
82
83
  # +String+ of msgpack bytes.
84
+ #
85
+ # Once sealed, the bytes are computed once and reused for every
86
+ # subsequent invocation: B-33 seals Service registration (B-07 /
87
+ # B-08) at the first invocation, so the preamble is exactly the
88
+ # bindings that existed at that moment — a bind reaching a
89
+ # +Kobako::Namespace+ after the seal raises +ArgumentError+ (E-45)
90
+ # and never alters Frame 1.
83
91
  def encode
84
- Codec::Encoder.encode(@namespaces.values.map(&:to_preamble))
92
+ return @encoded if @encoded
93
+
94
+ bytes = Codec::Encoder.encode(@namespaces.values.map(&:to_preamble)).freeze
95
+ @encoded = bytes if @sealed
96
+ bytes
85
97
  end
86
98
 
87
- # Mark the registry as sealed. Called by +Sandbox+ on the first
88
- # invocation. After sealing, #define raises ArgumentError. Idempotent.
99
+ # Mark the registry as sealed and propagate the seal to every
100
+ # declared +Kobako::Namespace+
101
+ # ({docs/behavior.md B-33}[link:../../../docs/behavior.md]). Called
102
+ # by +Sandbox+ on the first invocation. After sealing, #define
103
+ # raises ArgumentError (E-18) and +Namespace#bind+ raises
104
+ # ArgumentError (E-45). Idempotent.
89
105
  def seal!
106
+ return self if @sealed
107
+
90
108
  @sealed = true
109
+ @namespaces.each_value(&:seal!)
91
110
  self
92
111
  end
93
112
 
@@ -31,6 +31,7 @@ module Kobako
31
31
 
32
32
  def initialize
33
33
  @entries = [] # : Array[Kobako::Snippet::Source | Kobako::Snippet::Binary]
34
+ @encoded = nil # : String?
34
35
  end
35
36
 
36
37
  # Serialize the registered snippets to wire bytes. Each entry
@@ -42,8 +43,14 @@ module Kobako
42
43
  # carriers — this collection-tier method reads their attributes
43
44
  # externally via +entry_payload+ rather than asking each entry to
44
45
  # self-encode.
46
+ #
47
+ # The bytes are memoized — the table is replayed verbatim on every
48
+ # invocation after B-33 seals it, so Frame 3 never changes between
49
+ # encodes; {#register} drops the memo while the table is still open.
45
50
  def encode
46
- Codec::Encoder.encode(@entries.map { |entry| entry_payload(entry) })
51
+ return @encoded if @encoded
52
+
53
+ @encoded = Codec::Encoder.encode(@entries.map { |entry| entry_payload(entry) }).freeze
47
54
  end
48
55
 
49
56
  # Register one preloaded snippet in either of two forms
@@ -68,6 +75,7 @@ module Kobako
68
75
  # missing keywords, wrong types, malformed +name+ (E-34), or
69
76
  # duplicate +code:+ +name+ (E-33).
70
77
  def register(code: nil, name: nil, binary: nil)
78
+ @encoded = nil
71
79
  if binary
72
80
  raise ArgumentError, "cannot combine binary: with code: / name:" if code || name
73
81
 
@@ -64,7 +64,11 @@ module Kobako
64
64
  case value
65
65
  when String then Utils.assert_utf8!(value, "str payload") if value.encoding == Encoding::UTF_8
66
66
  when Array then value.each { |v| validate_utf8!(v) }
67
- when Hash then value.each { |pair| validate_utf8!(pair) }
67
+ when Hash
68
+ value.each do |key, val|
69
+ validate_utf8!(key)
70
+ validate_utf8!(val)
71
+ end
68
72
  end
69
73
  end
70
74
  end
data/lib/kobako/errors.rb CHANGED
@@ -21,7 +21,7 @@ module Kobako
21
21
  # call that failed and was not rescued inside the
22
22
  # script).
23
23
  #
24
- # A fourth branch sits outside the invocation taxonomy:
24
+ # Two further branches sit outside the invocation taxonomy:
25
25
  #
26
26
  # * {SetupError} — construction layer. Raised by `Kobako::Sandbox.new`
27
27
  # when the wasm runtime cannot be built from the
@@ -29,6 +29,9 @@ module Kobako
29
29
  # ({docs/behavior.md E-40 / E-41}[link:../../docs/behavior.md]).
30
30
  # Not an invocation outcome, so it never passes
31
31
  # through the two-step attribution decision.
32
+ # * {PoolTimeoutError} — pool checkout layer. Raised by `Kobako::Pool#with`
33
+ # when the checkout wait exceeds +checkout_timeout+
34
+ # ({docs/behavior.md E-46}[link:../../docs/behavior.md]).
32
35
  #
33
36
  # Subclasses pinned by docs/behavior.md Error Classes:
34
37
  #
@@ -137,4 +140,11 @@ module Kobako
137
140
  # snippet failures while callers wanting bytecode-specific handling
138
141
  # can `rescue Kobako::BytecodeError` directly.
139
142
  class BytecodeError < SandboxError; end
143
+
144
+ # Pool checkout layer. Raised by +Kobako::Pool#with+ when the checkout
145
+ # wait exceeded the configured +checkout_timeout+ while every slot was
146
+ # held ({docs/behavior.md E-46}[link:../../docs/behavior.md]). No
147
+ # Sandbox state is touched — retrying succeeds as soon as a holder
148
+ # returns its Sandbox.
149
+ class PoolTimeoutError < Error; end
140
150
  end
@@ -18,15 +18,20 @@ module Kobako
18
18
  def initialize(name)
19
19
  @name = name
20
20
  @members = {} # : Hash[String, untyped]
21
+ @sealed = false
21
22
  end
22
23
 
23
24
  # Bind +object+ under +member+ inside this Namespace. +member+ is a
24
25
  # constant-form name as a +Symbol+ or +String+. +object+ is any Ruby
25
26
  # object that responds to the methods guest code will invoke. Returns
26
27
  # +self+ for chaining. Raises +ArgumentError+ when +member+ does not
27
- # match the constant pattern, or a Member of the same name is already
28
- # bound ({docs/behavior.md B-11}[link:../../docs/behavior.md]).
28
+ # match the constant pattern, when a Member of the same name is
29
+ # already bound ({docs/behavior.md B-11}[link:../../docs/behavior.md]),
30
+ # or when the owning Sandbox's first invocation has sealed Service
31
+ # registration ({docs/behavior.md E-45}[link:../../docs/behavior.md]).
29
32
  def bind(member, object)
33
+ raise ArgumentError, "cannot bind after first Sandbox invocation" if @sealed
34
+
30
35
  member_str = validate_member_name!(member)
31
36
  raise ArgumentError, "Member #{@name}::#{member_str} is already bound" if @members.key?(member_str)
32
37
 
@@ -34,6 +39,15 @@ module Kobako
34
39
  self
35
40
  end
36
41
 
42
+ # Mark this Namespace as sealed ({docs/behavior.md B-33}[link:../../docs/behavior.md]).
43
+ # Called by +Kobako::Catalog::Namespaces#seal!+ on the owning
44
+ # Sandbox's first invocation; afterwards {#bind} raises
45
+ # +ArgumentError+ (E-45). Idempotent; returns +self+.
46
+ def seal!
47
+ @sealed = true
48
+ self
49
+ end
50
+
37
51
  # Member lookup; raises +KeyError+ when no Member is registered
38
52
  # under +member+.
39
53
  def fetch(member)
@@ -0,0 +1,182 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "errors"
4
+ require_relative "sandbox"
5
+
6
+ module Kobako
7
+ # Kobako::Pool — a bounded set of warm, identically set-up Sandboxes
8
+ # handed out one exclusive holder at a time
9
+ # ({docs/behavior.md B-46..B-48}[link:../../docs/behavior.md]).
10
+ #
11
+ # Construction forwards every +Kobako::Sandbox.new+ keyword verbatim
12
+ # and holds the optional block as the per-Sandbox setup hook; a
13
+ # checkout prefers an idle Sandbox and constructs a new one only when
14
+ # none is idle and fewer than +slots+ exist (B-46). +#with+ blocks up
15
+ # to +checkout_timeout+ seconds when every slot is held (E-46), applies
16
+ # the +TrapError+ discard-and-recreate contract at checkin (B-47), and
17
+ # the Pool releases everything with its own reachability — there is no
18
+ # teardown verb (B-48).
19
+ class Pool
20
+ # The +#with+ wait bound applied when +checkout_timeout+ is not given
21
+ # ({docs/behavior.md B-46}[link:../../docs/behavior.md]).
22
+ DEFAULT_CHECKOUT_TIMEOUT_SECONDS = 5.0
23
+
24
+ # Build a Pool of up to +slots+ Sandboxes
25
+ # ({docs/behavior.md B-46}[link:../../docs/behavior.md]). +slots+ is
26
+ # a positive Integer; +checkout_timeout+ bounds the +#with+ wait in
27
+ # seconds (+nil+ waits indefinitely); every other keyword is
28
+ # forwarded verbatim to +Kobako::Sandbox.new+. The optional block
29
+ # runs exactly once per constructed Sandbox — it is the setup window
30
+ # for +#define+ / +#preload+ before that Sandbox's first checkout.
31
+ # No Sandbox is constructed here. Raises +ArgumentError+ for an
32
+ # invalid +slots+ / +checkout_timeout+
33
+ # ({docs/behavior.md E-47}[link:../../docs/behavior.md]).
34
+ def initialize(slots:, checkout_timeout: DEFAULT_CHECKOUT_TIMEOUT_SECONDS, **sandbox_options, &setup)
35
+ validate_slots!(slots)
36
+ @slots = slots
37
+ @checkout_timeout = normalize_checkout_timeout(checkout_timeout)
38
+ @sandbox_options = sandbox_options
39
+ @setup = setup
40
+ @idle = [] # : Array[Kobako::Sandbox]
41
+ @constructed = 0
42
+ @mutex = Mutex.new
43
+ @slot_freed = ConditionVariable.new
44
+ end
45
+
46
+ # Yield one exclusively-held Sandbox to the block and return the
47
+ # block's value ({docs/behavior.md B-47}[link:../../docs/behavior.md]).
48
+ # Blocks while every slot is held; raises +Kobako::PoolTimeoutError+
49
+ # once the wait exceeds +checkout_timeout+
50
+ # ({docs/behavior.md E-46}[link:../../docs/behavior.md]). The Sandbox
51
+ # returns to the pool at block exit — unless the block raised
52
+ # +Kobako::TrapError+, in which case the unrecoverable Sandbox is
53
+ # discarded and its slot refills by a fresh construction on next
54
+ # demand.
55
+ def with
56
+ sandbox = checkout
57
+ begin
58
+ yield sandbox
59
+ rescue TrapError
60
+ release_capacity!
61
+ sandbox = nil
62
+ raise
63
+ ensure
64
+ checkin(sandbox) if sandbox
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ # Acquire a Sandbox and hand it over in pre-invocation state — empty
71
+ # output buffers and truncation predicates false (B-47).
72
+ def checkout
73
+ acquire.tap(&:reset_invocation_state!)
74
+ end
75
+
76
+ # The idle-first claim loop (B-46): an idle Sandbox wins, unclaimed
77
+ # capacity constructs, and a full pool waits for a checkin.
78
+ def acquire
79
+ timeout = @checkout_timeout
80
+ deadline = timeout && (monotonic_now + timeout)
81
+ loop do
82
+ action, sandbox = claim_or_wait(deadline)
83
+ return sandbox if action == :idle && sandbox
84
+ return construct_slot if action == :build
85
+ end
86
+ end
87
+
88
+ # Single locked decision point for one claim attempt. Waiting
89
+ # happens inside the lock (so a checkin can wake it); construction
90
+ # happens outside (so a slow setup block never holds the lock) —
91
+ # capacity is reserved here and released by +construct_slot+ on
92
+ # failure.
93
+ def claim_or_wait(deadline)
94
+ @mutex.synchronize do
95
+ return [:idle, @idle.pop] unless @idle.empty?
96
+
97
+ if @constructed < @slots
98
+ @constructed += 1
99
+ return [:build, nil]
100
+ end
101
+
102
+ await_slot!(deadline)
103
+ [:retry, nil]
104
+ end
105
+ end
106
+
107
+ # Wait for a checkin or freed capacity; raises
108
+ # +Kobako::PoolTimeoutError+ once +deadline+ has passed (E-46). Must
109
+ # run while holding +@mutex+.
110
+ def await_slot!(deadline)
111
+ remaining = deadline && (deadline - monotonic_now)
112
+ if remaining && remaining <= 0
113
+ raise PoolTimeoutError,
114
+ "no Sandbox returned within #{@checkout_timeout}s: all #{@slots} slots are held"
115
+ end
116
+
117
+ @slot_freed.wait(@mutex, remaining)
118
+ end
119
+
120
+ # Construct and set up one pooled Sandbox against the capacity
121
+ # reserved by +claim_or_wait+. Construction and setup-block errors
122
+ # propagate to the checkout caller unchanged (B-46); the reserved
123
+ # capacity is released so a later checkout can retry.
124
+ def construct_slot
125
+ done = false
126
+ sandbox = Sandbox.new(**@sandbox_options)
127
+ @setup&.call(sandbox)
128
+ done = true
129
+ sandbox
130
+ ensure
131
+ release_capacity! unless done
132
+ end
133
+
134
+ # Return a Sandbox to the idle list and wake one waiting checkout.
135
+ def checkin(sandbox)
136
+ @mutex.synchronize do
137
+ @idle.push(sandbox)
138
+ @slot_freed.signal
139
+ end
140
+ end
141
+
142
+ # Give back reserved-but-unfilled capacity — a failed construction or
143
+ # a discarded Sandbox — and wake one waiting checkout to claim it.
144
+ def release_capacity!
145
+ @mutex.synchronize do
146
+ @constructed -= 1
147
+ @slot_freed.signal
148
+ end
149
+ end
150
+
151
+ # The wait deadline runs on the monotonic clock so a wall-clock jump
152
+ # cannot stretch or cut the checkout wait.
153
+ def monotonic_now
154
+ Process.clock_gettime(Process::CLOCK_MONOTONIC)
155
+ end
156
+
157
+ # E-47 pre-flight for +slots+ — no coercion, a positive Integer is
158
+ # the only accepted shape.
159
+ def validate_slots!(slots)
160
+ return if slots.is_a?(Integer) && slots.positive?
161
+
162
+ raise ArgumentError, "slots must be a positive Integer, got #{slots.inspect}"
163
+ end
164
+
165
+ # Coerce +checkout_timeout+ into the Float seconds the wait loop
166
+ # consumes, or +nil+ to wait indefinitely — the E-39 normalisation
167
+ # idiom applied to E-47.
168
+ def normalize_checkout_timeout(checkout_timeout)
169
+ return nil if checkout_timeout.nil?
170
+ unless checkout_timeout.is_a?(Numeric)
171
+ raise ArgumentError, "checkout_timeout must be Numeric or nil, got #{checkout_timeout.inspect}"
172
+ end
173
+
174
+ seconds = checkout_timeout.to_f
175
+ unless seconds.positive? && seconds.finite?
176
+ raise ArgumentError, "checkout_timeout must be > 0 and finite (got #{checkout_timeout})"
177
+ end
178
+
179
+ seconds
180
+ end
181
+ end
182
+ end
@@ -206,6 +206,22 @@ module Kobako
206
206
  end
207
207
  end
208
208
 
209
+ # Reset all per-invocation observable state to its pre-invocation
210
+ # sentinels — both per-channel captures
211
+ # ({docs/behavior.md B-05}[link:../../docs/behavior.md]) and the
212
+ # per-last-invocation usage record
213
+ # ({docs/behavior.md B-35}[link:../../docs/behavior.md]). Shared by
214
+ # +#initialize+ (first-time setup) and +#begin_invocation!+
215
+ # (between-invocation reset) so both paths agree on what
216
+ # "pre-invocation state" means; +Kobako::Pool+ calls it at checkout
217
+ # so a pooled Sandbox hands over empty output buffers
218
+ # ({docs/behavior.md B-47}[link:../../docs/behavior.md]).
219
+ def reset_invocation_state!
220
+ @stdout_capture = Capture::EMPTY
221
+ @stderr_capture = Capture::EMPTY
222
+ @usage = Usage::EMPTY
223
+ end
224
+
209
225
  private
210
226
 
211
227
  # Configure the +Runtime+'s host↔guest dispatch wiring
@@ -237,20 +253,6 @@ module Kobako
237
253
  reset_invocation_state!
238
254
  end
239
255
 
240
- # Reset all per-invocation observable state to its pre-invocation
241
- # sentinels — both per-channel captures
242
- # ({docs/behavior.md B-05}[link:../../docs/behavior.md]) and the
243
- # per-last-invocation usage record
244
- # ({docs/behavior.md B-35}[link:../../docs/behavior.md]). Shared by
245
- # +#initialize+ (first-time setup) and +#begin_invocation!+
246
- # (between-invocation reset) so both paths agree on what
247
- # "pre-invocation state" means.
248
- def reset_invocation_state!
249
- @stdout_capture = Capture::EMPTY
250
- @stderr_capture = Capture::EMPTY
251
- @usage = Usage::EMPTY
252
- end
253
-
254
256
  # Read the per-last-invocation +wall_time+ and +memory_peak+ from
255
257
  # the ext and wrap them as a +Kobako::Usage+ value object
256
258
  # ({docs/behavior.md B-35}[link:../../docs/behavior.md]). Runs in
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kobako
4
- VERSION = "0.9.2"
4
+ VERSION = "0.10.0"
5
5
  end
data/lib/kobako.rb CHANGED
@@ -15,3 +15,4 @@ require_relative "kobako/catalog"
15
15
  require_relative "kobako/runtime"
16
16
  require_relative "kobako/snapshot"
17
17
  require_relative "kobako/sandbox"
18
+ require_relative "kobako/pool"
@@ -73,13 +73,28 @@
73
73
  "path": "/wasm/kobako-regexp/README.md"
74
74
  }
75
75
  ]
76
+ },
77
+ "wasm/kobako-baker": {
78
+ "component": "kobako-baker",
79
+ "release-type": "rust",
80
+ "extra-files": [
81
+ {
82
+ "type": "toml",
83
+ "path": "/wasm/kobako-baker/Cargo.lock",
84
+ "jsonpath": "$.package[?(@.name=='kobako-baker')].version"
85
+ },
86
+ {
87
+ "type": "generic",
88
+ "path": "/wasm/kobako-baker/README.md"
89
+ }
90
+ ]
76
91
  }
77
92
  },
78
93
  "plugins": [
79
94
  {
80
95
  "type": "linked-versions",
81
96
  "groupName": "kobako guest crates",
82
- "components": ["kobako-core", "kobako-rs", "kobako-io", "kobako-regexp"]
97
+ "components": ["kobako-core", "kobako-rs", "kobako-io", "kobako-regexp", "kobako-baker"]
83
98
  }
84
99
  ],
85
100
  "extra-files": [
@@ -1,8 +1,6 @@
1
1
  module Kobako
2
2
  module Catalog
3
3
  class Handles
4
- UNWRAPPABLE_TYPES: Array[Module]
5
-
6
4
  def initialize: (?next_id: Integer) -> void
7
5
 
8
6
  def alloc: (untyped object) -> Kobako::Handle
@@ -52,4 +52,7 @@ module Kobako
52
52
 
53
53
  class BytecodeError < SandboxError
54
54
  end
55
+
56
+ class PoolTimeoutError < Error
57
+ end
55
58
  end
@@ -8,6 +8,8 @@ module Kobako
8
8
 
9
9
  def bind: (Symbol | String member, untyped object) -> self
10
10
 
11
+ def seal!: () -> self
12
+
11
13
  def fetch: (Symbol | String member) -> untyped
12
14
 
13
15
  def to_preamble: () -> [String, Array[String]]
@@ -0,0 +1,44 @@
1
+ module Kobako
2
+ class Pool
3
+ DEFAULT_CHECKOUT_TIMEOUT_SECONDS: Float
4
+
5
+ @slots: Integer
6
+ @checkout_timeout: Float?
7
+ @sandbox_options: Hash[Symbol, untyped]
8
+ @setup: ^(Kobako::Sandbox) -> void | nil
9
+ @idle: Array[Kobako::Sandbox]
10
+ @constructed: Integer
11
+ @mutex: Thread::Mutex
12
+ @slot_freed: Thread::ConditionVariable
13
+
14
+ def initialize: (
15
+ slots: Integer,
16
+ ?checkout_timeout: (Float | Integer)?,
17
+ **untyped sandbox_options
18
+ ) ?{ (Kobako::Sandbox) -> void } -> void
19
+
20
+ def with: [T] () { (Kobako::Sandbox) -> T } -> T
21
+
22
+ private
23
+
24
+ def checkout: () -> Kobako::Sandbox
25
+
26
+ def acquire: () -> Kobako::Sandbox
27
+
28
+ def claim_or_wait: (Float? deadline) -> [Symbol, Kobako::Sandbox?]
29
+
30
+ def await_slot!: (Float? deadline) -> void
31
+
32
+ def construct_slot: () -> Kobako::Sandbox
33
+
34
+ def checkin: (Kobako::Sandbox sandbox) -> void
35
+
36
+ def release_capacity!: () -> void
37
+
38
+ def monotonic_now: () -> Float
39
+
40
+ def validate_slots!: (untyped slots) -> void
41
+
42
+ def normalize_checkout_timeout: ((Float | Integer)? checkout_timeout) -> Float?
43
+ end
44
+ end
@@ -38,12 +38,12 @@ module Kobako
38
38
 
39
39
  def eval: (String code) -> untyped
40
40
 
41
+ def reset_invocation_state!: () -> void
42
+
41
43
  private
42
44
 
43
45
  def install_dispatch_proc!: () -> void
44
46
 
45
- def reset_invocation_state!: () -> void
46
-
47
47
  def begin_invocation!: () -> void
48
48
 
49
49
  def read_usage!: () -> void
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kobako
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aotokitsuruya
@@ -65,6 +65,7 @@ files:
65
65
  - ext/kobako/src/runtime/dispatch.rs
66
66
  - ext/kobako/src/runtime/exports.rs
67
67
  - ext/kobako/src/runtime/guest_mem.rs
68
+ - ext/kobako/src/runtime/instance_pre.rs
68
69
  - ext/kobako/src/runtime/invocation.rs
69
70
  - ext/kobako/src/runtime/trap.rs
70
71
  - ext/kobako/src/snapshot.rs
@@ -86,6 +87,7 @@ files:
86
87
  - lib/kobako/namespace.rb
87
88
  - lib/kobako/outcome.rb
88
89
  - lib/kobako/outcome/panic.rb
90
+ - lib/kobako/pool.rb
89
91
  - lib/kobako/runtime.rb
90
92
  - lib/kobako/sandbox.rb
91
93
  - lib/kobako/sandbox_options.rb
@@ -123,6 +125,7 @@ files:
123
125
  - sig/kobako/namespace.rbs
124
126
  - sig/kobako/outcome.rbs
125
127
  - sig/kobako/outcome/panic.rbs
128
+ - sig/kobako/pool.rbs
126
129
  - sig/kobako/runtime.rbs
127
130
  - sig/kobako/sandbox.rbs
128
131
  - sig/kobako/sandbox_options.rbs