kobako 0.27.0 → 0.29.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/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +241 -0
- data/Cargo.lock +132 -126
- data/README.md +240 -147
- data/ROADMAP.md +28 -22
- data/SECURITY.md +2 -2
- data/crates/kobako-runtime/CHANGELOG.md +117 -0
- data/crates/kobako-runtime/Cargo.toml +27 -6
- data/crates/kobako-runtime/README.md +16 -10
- data/crates/kobako-runtime/src/dispatch.rs +8 -0
- data/crates/kobako-runtime/src/error.rs +8 -9
- data/crates/kobako-runtime/src/filesystem/directory/spelling.rs +194 -0
- data/crates/kobako-runtime/src/filesystem/directory.rs +1082 -0
- data/crates/kobako-runtime/src/filesystem/memory.rs +1100 -0
- data/crates/kobako-runtime/src/filesystem/overlay/exclusive.rs +88 -0
- data/crates/kobako-runtime/src/filesystem/overlay/stack.rs +808 -0
- data/crates/kobako-runtime/src/filesystem/overlay.rs +1955 -0
- data/crates/kobako-runtime/src/filesystem/path.rs +60 -0
- data/crates/kobako-runtime/src/filesystem/temporary.rs +167 -0
- data/crates/kobako-runtime/src/filesystem.rs +392 -0
- data/crates/kobako-runtime/src/grant.rs +20 -0
- data/crates/kobako-runtime/src/lib.rs +12 -2
- data/crates/kobako-runtime/src/mount.rs +178 -0
- data/crates/kobako-runtime/src/profile.rs +4 -4
- data/crates/kobako-runtime/src/runtime.rs +43 -17
- data/crates/kobako-runtime/src/snapshot.rs +33 -15
- data/crates/kobako-runtime/src/yielder.rs +14 -6
- data/crates/kobako-transport/CHANGELOG.md +45 -0
- data/crates/kobako-transport/Cargo.toml +1 -1
- data/crates/kobako-transport/README.md +21 -12
- data/crates/kobako-transport/src/abi.rs +11 -14
- data/crates/kobako-transport/src/envelope/bytes.rs +18 -6
- data/crates/kobako-transport/src/envelope/compile_reply.rs +139 -0
- data/crates/kobako-transport/src/envelope/fault.rs +2 -1
- data/crates/kobako-transport/src/envelope/outcome.rs +17 -16
- data/crates/kobako-transport/src/envelope/preamble.rs +513 -0
- data/crates/kobako-transport/src/envelope/reply.rs +103 -61
- data/crates/kobako-transport/src/envelope/request.rs +305 -0
- data/crates/kobako-transport/src/envelope/run.rs +1 -2
- data/crates/kobako-transport/src/envelope/tag.rs +49 -0
- data/crates/kobako-transport/src/envelope/unsupported.rs +105 -0
- data/crates/kobako-transport/src/envelope.rs +19 -12
- data/crates/kobako-transport/src/lib.rs +0 -2
- data/crates/kobako-wasmtime/CHANGELOG.md +163 -0
- data/crates/kobako-wasmtime/Cargo.toml +23 -16
- data/crates/kobako-wasmtime/README.md +6 -4
- data/crates/kobako-wasmtime/src/abi.rs +67 -36
- data/crates/kobako-wasmtime/src/ambient.rs +64 -5
- data/crates/kobako-wasmtime/src/cache.rs +204 -127
- data/crates/kobako-wasmtime/src/capture.rs +4 -11
- data/crates/kobako-wasmtime/src/config.rs +69 -15
- data/crates/kobako-wasmtime/src/descriptors.rs +167 -0
- data/crates/kobako-wasmtime/src/dispatch.rs +95 -87
- data/crates/kobako-wasmtime/src/driver.rs +174 -125
- data/crates/kobako-wasmtime/src/exports.rs +88 -34
- data/crates/kobako-wasmtime/src/guest_mem.rs +151 -138
- data/crates/kobako-wasmtime/src/imports.rs +46 -0
- data/crates/kobako-wasmtime/src/instance_pre.rs +19 -58
- data/crates/kobako-wasmtime/src/invocation.rs +84 -412
- data/crates/kobako-wasmtime/src/io.rs +89 -0
- data/crates/kobako-wasmtime/src/lib.rs +7 -24
- data/crates/kobako-wasmtime/src/limiter.rs +253 -0
- data/crates/kobako-wasmtime/src/preview1/args.rs +60 -0
- data/crates/kobako-wasmtime/src/preview1/beneath.rs +188 -0
- data/crates/kobako-wasmtime/src/preview1/differential/mount.rs +609 -0
- data/crates/kobako-wasmtime/src/preview1/differential.rs +372 -0
- data/crates/kobako-wasmtime/src/preview1/errno.rs +267 -0
- data/crates/kobako-wasmtime/src/preview1/fd.rs +672 -0
- data/crates/kobako-wasmtime/src/preview1/memory.rs +205 -0
- data/crates/kobako-wasmtime/src/preview1/mount_view.rs +2499 -0
- data/crates/kobako-wasmtime/src/preview1/path.rs +421 -0
- data/crates/kobako-wasmtime/src/preview1/poll.rs +333 -0
- data/crates/kobako-wasmtime/src/preview1/sock.rs +30 -0
- data/crates/kobako-wasmtime/src/preview1.rs +461 -0
- data/crates/kobako-wasmtime/src/trap.rs +66 -59
- data/crates/kobako-wasmtime/src/wasi.rs +317 -0
- data/crates/kobako-wasmtime/tests/compile_posture.rs +43 -0
- data/crates/kobako-wasmtime/tests/guest_file.rs +1054 -0
- data/crates/kobako-wasmtime/tests/preamble_flags.rs +70 -0
- data/crates/kobako-wasmtime/tests/snippet_compile.rs +95 -0
- data/crates/kobako-wasmtime/tests/support/mod.rs +30 -0
- data/crates/kobako-wasmtime/tests/unanswered_call.rs +86 -0
- data/crates/kobako-wasmtime/tests/unsupported_call.rs +51 -0
- data/data/kobako.wasm +0 -0
- data/ext/kobako/Cargo.toml +4 -2
- data/ext/kobako/src/runtime/bridge.rs +177 -113
- data/ext/kobako/src/runtime/errors.rs +26 -32
- data/ext/kobako/src/runtime/escape.rs +53 -0
- data/ext/kobako/src/runtime/filesystem/grants.rs +91 -0
- data/ext/kobako/src/runtime/filesystem/ruby.rs +400 -0
- data/ext/kobako/src/runtime/filesystem.rs +236 -0
- data/ext/kobako/src/runtime/gvl.rs +11 -13
- data/ext/kobako/src/runtime/pinned_value.rs +31 -0
- data/ext/kobako/src/runtime/snapshot.rs +127 -0
- data/ext/kobako/src/runtime.rs +190 -312
- data/lib/kobako/capture.rb +1 -4
- data/lib/kobako/catalog/extensions.rb +21 -59
- data/lib/kobako/catalog/flags.rb +29 -0
- data/lib/kobako/catalog/grants.rb +30 -0
- data/lib/kobako/catalog/handles.rb +7 -54
- data/lib/kobako/catalog/mount.rb +27 -0
- data/lib/kobako/catalog/services.rb +17 -60
- data/lib/kobako/catalog/snippets.rb +41 -69
- data/lib/kobako/catalog.rb +13 -10
- data/lib/kobako/codec/decoder.rb +10 -28
- data/lib/kobako/codec/encoder.rb +3 -22
- data/lib/kobako/codec/error.rb +6 -27
- data/lib/kobako/codec/ext_types.rb +72 -94
- data/lib/kobako/codec/handle_walk.rb +65 -130
- data/lib/kobako/codec/nesting.rb +3 -8
- data/lib/kobako/codec/state.rb +21 -11
- data/lib/kobako/codec/utils.rb +6 -34
- data/lib/kobako/codec/value_budget.rb +86 -0
- data/lib/kobako/codec.rb +10 -22
- data/lib/kobako/constant_name.rb +8 -0
- data/lib/kobako/context.rb +83 -117
- data/lib/kobako/errors.rb +57 -132
- data/lib/kobako/execution.rb +16 -21
- data/lib/kobako/extension.rb +23 -40
- data/lib/kobako/filesystem.rb +38 -0
- data/lib/kobako/handle.rb +7 -12
- data/lib/kobako/outcome.rb +51 -80
- data/lib/kobako/payload/arguments.rb +1 -16
- data/lib/kobako/payload.rb +4 -12
- data/lib/kobako/pool.rb +25 -55
- data/lib/kobako/runtime.rb +7 -21
- data/lib/kobako/sandbox.rb +128 -137
- data/lib/kobako/sandbox_options.rb +71 -90
- data/lib/kobako/snippet/bytecode.rb +11 -0
- data/lib/kobako/snippet/source.rb +1 -16
- data/lib/kobako/snippet.rb +2 -10
- data/lib/kobako/transport/block_failure.rb +35 -0
- data/lib/kobako/transport/call.rb +1 -14
- data/lib/kobako/transport/dispatcher.rb +127 -206
- data/lib/kobako/transport/error.rb +6 -20
- data/lib/kobako/transport/exposure.rb +10 -17
- data/lib/kobako/transport/reflection.rb +108 -63
- data/lib/kobako/transport/run.rb +17 -71
- data/lib/kobako/transport/yielder.rb +20 -94
- data/lib/kobako/transport.rb +4 -15
- data/lib/kobako/unresolved.rb +4 -11
- data/lib/kobako/usage.rb +2 -6
- data/lib/kobako/version.rb +1 -1
- data/lib/kobako.rb +1 -0
- data/sig/kobako/catalog/extensions.rbs +2 -2
- data/sig/kobako/catalog/flags.rbs +13 -0
- data/sig/kobako/catalog/grants.rbs +13 -0
- data/sig/kobako/catalog/mount.rbs +28 -0
- data/sig/kobako/catalog/services.rbs +3 -5
- data/sig/kobako/catalog/snippets.rbs +5 -5
- data/sig/kobako/catalog.rbs +1 -0
- data/sig/kobako/codec/ext_types.rbs +10 -8
- data/sig/kobako/codec/handle_walk.rbs +9 -7
- data/sig/kobako/codec/state.rbs +7 -1
- data/sig/kobako/codec/utils.rbs +2 -2
- data/sig/kobako/codec/value_budget.rbs +23 -0
- data/sig/kobako/codec.rbs +4 -2
- data/sig/kobako/constant_name.rbs +3 -0
- data/sig/kobako/context.rbs +15 -8
- data/sig/kobako/errors.rbs +10 -4
- data/sig/kobako/filesystem.rbs +88 -0
- data/sig/kobako/guest_yielder.rbs +9 -0
- data/sig/kobako/outcome.rbs +6 -8
- data/sig/kobako/pool.rbs +1 -1
- data/sig/kobako/runtime.rbs +21 -45
- data/sig/kobako/sandbox.rbs +11 -1
- data/sig/kobako/sandbox_options.rbs +25 -7
- data/sig/kobako/snapshot.rbs +20 -0
- data/sig/kobako/snippet/bytecode.rbs +12 -0
- data/sig/kobako/transport/block_failure.rbs +13 -0
- data/sig/kobako/transport/dispatcher.rbs +15 -19
- data/sig/kobako/transport/exposure.rbs +1 -1
- data/sig/kobako/transport/reflection.rbs +19 -4
- data/sig/kobako/transport/run.rbs +1 -3
- data/sig/kobako/transport/yielder.rbs +5 -9
- data/sig/kobako/transport.rbs +9 -8
- metadata +75 -10
- data/crates/kobako-transport/src/envelope/invocation_frames.rs +0 -241
- data/crates/kobako-wasmtime/src/frames.rs +0 -273
- data/lib/kobako/snippet/binary.rb +0 -26
- data/rust-toolchain.toml +0 -15
- data/sig/kobako/snippet/binary.rbs +0 -12
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Kobako
|
|
2
|
+
# One invocation's result — the whole Snapshot the driver produced.
|
|
3
|
+
class Snapshot
|
|
4
|
+
def outcome: () -> [String, Kobako::Outcome::panic_fields?]
|
|
5
|
+
|
|
6
|
+
def trap_error: () -> Kobako::TrapError?
|
|
7
|
+
|
|
8
|
+
def wall_time: () -> Float
|
|
9
|
+
|
|
10
|
+
def memory_peak: () -> Integer
|
|
11
|
+
|
|
12
|
+
def stdout: () -> String
|
|
13
|
+
|
|
14
|
+
def stdout_truncated?: () -> bool
|
|
15
|
+
|
|
16
|
+
def stderr: () -> String
|
|
17
|
+
|
|
18
|
+
def stderr_truncated?: () -> bool
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -9,39 +9,35 @@ module Kobako
|
|
|
9
9
|
|
|
10
10
|
BREAK_THROW: Symbol
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
BARE_FAULTS: Hash[singleton(StandardError), String]
|
|
13
13
|
|
|
14
|
+
def self.dispatch: (Kobako::Transport::Call call, Kobako::Transport::_ServiceResolver resolver, Kobako::Transport::_HandleTable handles, Kobako::Transport::BlockFailure failure, Kobako::Transport::_GuestYielder guest_yielder) -> [Symbol, String, String?]
|
|
14
15
|
|
|
16
|
+
private
|
|
15
17
|
|
|
18
|
+
def self.run: (Kobako::Transport::Call call, Kobako::Transport::_ServiceResolver resolver, Kobako::Transport::_HandleTable handles, Kobako::Transport::Yielder? yielder) -> untyped
|
|
16
19
|
|
|
17
|
-
def self
|
|
20
|
+
def self.decode_arguments: (String payload) -> [Kobako::Payload::Arguments, bool]
|
|
18
21
|
|
|
19
|
-
def self
|
|
22
|
+
def self.resolve_call_args: (Kobako::Payload::Arguments arguments, Kobako::Codec::_HandleTable handles, bool carried_handle) -> [Array[untyped], Hash[Symbol, untyped]]
|
|
20
23
|
|
|
21
|
-
def self
|
|
24
|
+
def self.caught_fault: (StandardError error, Kobako::Transport::BlockFailure failure) -> [String, String]
|
|
22
25
|
|
|
23
|
-
def self
|
|
26
|
+
def self.invoke: (Kobako::Transport::Exposure exposure, String method, Array[untyped] args, Hash[Symbol, untyped] kwargs, Kobako::Transport::Yielder? yielder) -> untyped
|
|
24
27
|
|
|
25
|
-
def self
|
|
28
|
+
def self.reject_unreachable!: (Kobako::Transport::Exposure exposure, Symbol name) -> void
|
|
26
29
|
|
|
27
|
-
def self
|
|
30
|
+
def self.resolve_arg: (untyped value, Kobako::Codec::_HandleTable handles) -> untyped
|
|
28
31
|
|
|
29
|
-
def self
|
|
32
|
+
def self.resolve_target: (String | Integer target, Kobako::Transport::_ServiceResolver resolver, Kobako::Transport::_HandleTable handles) -> Kobako::Transport::Exposure
|
|
30
33
|
|
|
34
|
+
def self.resolve_path: (String path, Kobako::Transport::_ServiceResolver resolver) -> Kobako::Transport::Exposure
|
|
31
35
|
|
|
32
|
-
def self
|
|
36
|
+
def self.resolve_handle: (Integer id, Kobako::Transport::_HandleTable handles) -> Kobako::Transport::Exposure
|
|
33
37
|
|
|
34
|
-
def self
|
|
38
|
+
def self.encode_ok: (untyped value, Kobako::Codec::_HandleTable handles) -> String
|
|
35
39
|
|
|
36
|
-
def self
|
|
37
|
-
|
|
38
|
-
def self?.resolve_handle: (Integer id, Kobako::Transport::_HandleTable handler) -> Kobako::Transport::Exposure
|
|
39
|
-
|
|
40
|
-
def self?.encode_ok: (untyped value, Kobako::Codec::_HandleTable handler) -> String
|
|
41
|
-
|
|
42
|
-
def self?.wrap_as_handle: (untyped value, Kobako::Codec::_HandleTable handler) -> Kobako::Handle
|
|
43
|
-
|
|
44
|
-
def self?.fault: (String type, String message) -> [String, String]
|
|
40
|
+
def self.fault: (String type, String message) -> [String, String]
|
|
45
41
|
end
|
|
46
42
|
end
|
|
47
43
|
end
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
module Kobako
|
|
2
2
|
module Transport
|
|
3
3
|
module Reflection
|
|
4
|
-
META_OWNERS: Array[Module]
|
|
5
4
|
GADGET_OWNERS: Array[Module]
|
|
6
5
|
CALLABLE_ALLOW: Array[Symbol]
|
|
7
6
|
|
|
8
|
-
def self
|
|
7
|
+
def self.refusal: (Kobako::Transport::Exposure exposure, Symbol name) -> String?
|
|
9
8
|
|
|
10
|
-
def self
|
|
9
|
+
def self.authored?: (UnboundMethod method) -> bool
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
private
|
|
12
|
+
|
|
13
|
+
def self.ambient_copy?: (UnboundMethod method) -> bool
|
|
14
|
+
|
|
15
|
+
def self.ambient_refusal: (untyped target, Symbol name) -> String?
|
|
16
|
+
|
|
17
|
+
def self.defined_refusal: (untyped target, Symbol name, Module klass) -> String?
|
|
18
|
+
|
|
19
|
+
def self.authored_for?: (untyped target, Symbol name, UnboundMethod method, Module klass) -> bool
|
|
20
|
+
|
|
21
|
+
def self.refused: (Symbol name) -> String
|
|
22
|
+
|
|
23
|
+
def self.owner_refusal: (untyped target, Symbol name, Module owner) -> String?
|
|
24
|
+
|
|
25
|
+
def self.lookup_class: (untyped target) -> Module
|
|
26
|
+
|
|
27
|
+
def self.ambient_owner?: (Module owner, untyped target) -> bool
|
|
13
28
|
end
|
|
14
29
|
end
|
|
15
30
|
end
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
module Kobako
|
|
2
2
|
module Transport
|
|
3
3
|
class Run < Data
|
|
4
|
-
NAME_PATTERN: Regexp
|
|
5
|
-
|
|
6
4
|
attr_reader entrypoint: Symbol
|
|
7
5
|
attr_reader args: Array[Kobako::Codec::wire_value]
|
|
8
6
|
attr_reader kwargs: Hash[Symbol, Kobako::Codec::wire_value]
|
|
@@ -11,7 +9,7 @@ module Kobako
|
|
|
11
9
|
|
|
12
10
|
def initialize: (entrypoint: Symbol | String, ?args: Array[untyped], ?kwargs: Hash[untyped, untyped]) -> void
|
|
13
11
|
|
|
14
|
-
def payload: (Kobako::Codec::_HandleTable
|
|
12
|
+
def payload: (Kobako::Codec::_HandleTable handles) -> String
|
|
15
13
|
|
|
16
14
|
private
|
|
17
15
|
|
|
@@ -1,28 +1,24 @@
|
|
|
1
1
|
module Kobako
|
|
2
2
|
module Transport
|
|
3
3
|
class Yielder
|
|
4
|
-
@
|
|
4
|
+
@guest_yielder: Kobako::Transport::_GuestYielder
|
|
5
5
|
@break_tag: Symbol
|
|
6
|
-
@
|
|
6
|
+
@handles: Kobako::Codec::_HandleTable
|
|
7
|
+
@failure: Kobako::Transport::BlockFailure
|
|
7
8
|
@active: bool
|
|
8
|
-
@raised: Kobako::BlockError?
|
|
9
9
|
|
|
10
|
-
def initialize: (Kobako::Transport::_GuestYielder
|
|
11
|
-
|
|
12
|
-
def fault_text: (Exception error) -> String?
|
|
10
|
+
def initialize: (Kobako::Transport::_GuestYielder guest_yielder, Symbol break_tag, Kobako::Codec::_HandleTable handles, Kobako::Transport::BlockFailure failure) -> void
|
|
13
11
|
|
|
14
12
|
def yield: (*untyped args) -> untyped
|
|
15
13
|
|
|
16
14
|
def to_proc: () -> Proc
|
|
17
15
|
|
|
18
|
-
def invalidate
|
|
16
|
+
def invalidate: () -> void
|
|
19
17
|
|
|
20
18
|
private
|
|
21
19
|
|
|
22
20
|
def encode_args: (Array[untyped] args) -> String
|
|
23
21
|
|
|
24
|
-
def remember: (Kobako::BlockError error) -> Kobako::BlockError
|
|
25
|
-
|
|
26
22
|
def decode_body: (String body) -> [untyped, bool]
|
|
27
23
|
|
|
28
24
|
def restore: (untyped value, bool carried_handle) -> untyped
|
data/sig/kobako/transport.rbs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
module Kobako
|
|
2
2
|
module Transport
|
|
3
3
|
# The guest re-entry callable a dispatch hands to a Yielder: invoked
|
|
4
|
-
# with the encoded yield args, it returns the
|
|
5
|
-
#
|
|
4
|
+
# with the encoded yield args, it returns the decoded Yield Reply as an
|
|
5
|
+
# +[arm, body, klass]+ triple.
|
|
6
|
+
# The ext's Kobako::GuestYielder is the production conformer;
|
|
6
7
|
# modelled structurally so the Transport layer needs no upward
|
|
7
8
|
# dependency on Runtime.
|
|
8
9
|
interface _GuestYielder
|
|
@@ -13,13 +14,13 @@ module Kobako
|
|
|
13
14
|
# side already decoded off the core envelope and answering the arm and
|
|
14
15
|
# body it puts on the Reply. Named here so the producer (Context) and the
|
|
15
16
|
# consumer (Runtime) cannot declare it differently.
|
|
16
|
-
type dispatch_proc = ^(String | Integer, String, bool, String, _GuestYielder) -> [
|
|
17
|
+
type dispatch_proc = ^(String | Integer, String, bool, String, _GuestYielder) -> [Symbol, String, String?]
|
|
17
18
|
|
|
18
|
-
#
|
|
19
|
-
#
|
|
20
|
-
#
|
|
21
|
-
# layer needs no upward dependency on
|
|
22
|
-
interface
|
|
19
|
+
# What a dispatch resolves constant-path targets against. The
|
|
20
|
+
# invocation's Kobako::Context is the production conformer, so its
|
|
21
|
+
# overrides answer before the Sandbox's bindings; modelled structurally
|
|
22
|
+
# so the Transport layer needs no upward dependency on Orchestration.
|
|
23
|
+
interface _ServiceResolver
|
|
23
24
|
def lookup: (String target) -> Exposure
|
|
24
25
|
end
|
|
25
26
|
|
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.
|
|
4
|
+
version: 0.29.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aotokitsuruya
|
|
@@ -13,16 +13,22 @@ dependencies:
|
|
|
13
13
|
name: msgpack
|
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
|
15
15
|
requirements:
|
|
16
|
-
- - "
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 1.8.2
|
|
19
|
+
- - "<"
|
|
17
20
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: '
|
|
21
|
+
version: '2'
|
|
19
22
|
type: :runtime
|
|
20
23
|
prerelease: false
|
|
21
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
25
|
requirements:
|
|
23
|
-
- - "
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: 1.8.2
|
|
29
|
+
- - "<"
|
|
24
30
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: '
|
|
31
|
+
version: '2'
|
|
26
32
|
- !ruby/object:Gem::Dependency
|
|
27
33
|
name: rb_sys
|
|
28
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -60,7 +66,18 @@ files:
|
|
|
60
66
|
- crates/kobako-runtime/README.md
|
|
61
67
|
- crates/kobako-runtime/src/dispatch.rs
|
|
62
68
|
- crates/kobako-runtime/src/error.rs
|
|
69
|
+
- crates/kobako-runtime/src/filesystem.rs
|
|
70
|
+
- crates/kobako-runtime/src/filesystem/directory.rs
|
|
71
|
+
- crates/kobako-runtime/src/filesystem/directory/spelling.rs
|
|
72
|
+
- crates/kobako-runtime/src/filesystem/memory.rs
|
|
73
|
+
- crates/kobako-runtime/src/filesystem/overlay.rs
|
|
74
|
+
- crates/kobako-runtime/src/filesystem/overlay/exclusive.rs
|
|
75
|
+
- crates/kobako-runtime/src/filesystem/overlay/stack.rs
|
|
76
|
+
- crates/kobako-runtime/src/filesystem/path.rs
|
|
77
|
+
- crates/kobako-runtime/src/filesystem/temporary.rs
|
|
78
|
+
- crates/kobako-runtime/src/grant.rs
|
|
63
79
|
- crates/kobako-runtime/src/lib.rs
|
|
80
|
+
- crates/kobako-runtime/src/mount.rs
|
|
64
81
|
- crates/kobako-runtime/src/profile.rs
|
|
65
82
|
- crates/kobako-runtime/src/runtime.rs
|
|
66
83
|
- crates/kobako-runtime/src/snapshot.rs
|
|
@@ -72,12 +89,16 @@ files:
|
|
|
72
89
|
- crates/kobako-transport/src/envelope.rs
|
|
73
90
|
- crates/kobako-transport/src/envelope/bytes.rs
|
|
74
91
|
- crates/kobako-transport/src/envelope/call.rs
|
|
92
|
+
- crates/kobako-transport/src/envelope/compile_reply.rs
|
|
75
93
|
- crates/kobako-transport/src/envelope/error_record.rs
|
|
76
94
|
- crates/kobako-transport/src/envelope/fault.rs
|
|
77
|
-
- crates/kobako-transport/src/envelope/invocation_frames.rs
|
|
78
95
|
- crates/kobako-transport/src/envelope/outcome.rs
|
|
96
|
+
- crates/kobako-transport/src/envelope/preamble.rs
|
|
79
97
|
- crates/kobako-transport/src/envelope/reply.rs
|
|
98
|
+
- crates/kobako-transport/src/envelope/request.rs
|
|
80
99
|
- crates/kobako-transport/src/envelope/run.rs
|
|
100
|
+
- crates/kobako-transport/src/envelope/tag.rs
|
|
101
|
+
- crates/kobako-transport/src/envelope/unsupported.rs
|
|
81
102
|
- crates/kobako-transport/src/lib.rs
|
|
82
103
|
- crates/kobako-wasmtime/CHANGELOG.md
|
|
83
104
|
- crates/kobako-wasmtime/Cargo.toml
|
|
@@ -87,15 +108,38 @@ files:
|
|
|
87
108
|
- crates/kobako-wasmtime/src/cache.rs
|
|
88
109
|
- crates/kobako-wasmtime/src/capture.rs
|
|
89
110
|
- crates/kobako-wasmtime/src/config.rs
|
|
111
|
+
- crates/kobako-wasmtime/src/descriptors.rs
|
|
90
112
|
- crates/kobako-wasmtime/src/dispatch.rs
|
|
91
113
|
- crates/kobako-wasmtime/src/driver.rs
|
|
92
114
|
- crates/kobako-wasmtime/src/exports.rs
|
|
93
|
-
- crates/kobako-wasmtime/src/frames.rs
|
|
94
115
|
- crates/kobako-wasmtime/src/guest_mem.rs
|
|
116
|
+
- crates/kobako-wasmtime/src/imports.rs
|
|
95
117
|
- crates/kobako-wasmtime/src/instance_pre.rs
|
|
96
118
|
- crates/kobako-wasmtime/src/invocation.rs
|
|
119
|
+
- crates/kobako-wasmtime/src/io.rs
|
|
97
120
|
- crates/kobako-wasmtime/src/lib.rs
|
|
121
|
+
- crates/kobako-wasmtime/src/limiter.rs
|
|
122
|
+
- crates/kobako-wasmtime/src/preview1.rs
|
|
123
|
+
- crates/kobako-wasmtime/src/preview1/args.rs
|
|
124
|
+
- crates/kobako-wasmtime/src/preview1/beneath.rs
|
|
125
|
+
- crates/kobako-wasmtime/src/preview1/differential.rs
|
|
126
|
+
- crates/kobako-wasmtime/src/preview1/differential/mount.rs
|
|
127
|
+
- crates/kobako-wasmtime/src/preview1/errno.rs
|
|
128
|
+
- crates/kobako-wasmtime/src/preview1/fd.rs
|
|
129
|
+
- crates/kobako-wasmtime/src/preview1/memory.rs
|
|
130
|
+
- crates/kobako-wasmtime/src/preview1/mount_view.rs
|
|
131
|
+
- crates/kobako-wasmtime/src/preview1/path.rs
|
|
132
|
+
- crates/kobako-wasmtime/src/preview1/poll.rs
|
|
133
|
+
- crates/kobako-wasmtime/src/preview1/sock.rs
|
|
98
134
|
- crates/kobako-wasmtime/src/trap.rs
|
|
135
|
+
- crates/kobako-wasmtime/src/wasi.rs
|
|
136
|
+
- crates/kobako-wasmtime/tests/compile_posture.rs
|
|
137
|
+
- crates/kobako-wasmtime/tests/guest_file.rs
|
|
138
|
+
- crates/kobako-wasmtime/tests/preamble_flags.rs
|
|
139
|
+
- crates/kobako-wasmtime/tests/snippet_compile.rs
|
|
140
|
+
- crates/kobako-wasmtime/tests/support/mod.rs
|
|
141
|
+
- crates/kobako-wasmtime/tests/unanswered_call.rs
|
|
142
|
+
- crates/kobako-wasmtime/tests/unsupported_call.rs
|
|
99
143
|
- data/kobako.wasm
|
|
100
144
|
- ext/kobako/Cargo.toml
|
|
101
145
|
- ext/kobako/extconf.rb
|
|
@@ -103,12 +147,21 @@ files:
|
|
|
103
147
|
- ext/kobako/src/runtime.rs
|
|
104
148
|
- ext/kobako/src/runtime/bridge.rs
|
|
105
149
|
- ext/kobako/src/runtime/errors.rs
|
|
150
|
+
- ext/kobako/src/runtime/escape.rs
|
|
151
|
+
- ext/kobako/src/runtime/filesystem.rs
|
|
152
|
+
- ext/kobako/src/runtime/filesystem/grants.rs
|
|
153
|
+
- ext/kobako/src/runtime/filesystem/ruby.rs
|
|
106
154
|
- ext/kobako/src/runtime/gvl.rs
|
|
155
|
+
- ext/kobako/src/runtime/pinned_value.rs
|
|
156
|
+
- ext/kobako/src/runtime/snapshot.rs
|
|
107
157
|
- lib/kobako.rb
|
|
108
158
|
- lib/kobako/capture.rb
|
|
109
159
|
- lib/kobako/catalog.rb
|
|
110
160
|
- lib/kobako/catalog/extensions.rb
|
|
161
|
+
- lib/kobako/catalog/flags.rb
|
|
162
|
+
- lib/kobako/catalog/grants.rb
|
|
111
163
|
- lib/kobako/catalog/handles.rb
|
|
164
|
+
- lib/kobako/catalog/mount.rb
|
|
112
165
|
- lib/kobako/catalog/services.rb
|
|
113
166
|
- lib/kobako/catalog/snippets.rb
|
|
114
167
|
- lib/kobako/codec.rb
|
|
@@ -120,10 +173,13 @@ files:
|
|
|
120
173
|
- lib/kobako/codec/nesting.rb
|
|
121
174
|
- lib/kobako/codec/state.rb
|
|
122
175
|
- lib/kobako/codec/utils.rb
|
|
176
|
+
- lib/kobako/codec/value_budget.rb
|
|
177
|
+
- lib/kobako/constant_name.rb
|
|
123
178
|
- lib/kobako/context.rb
|
|
124
179
|
- lib/kobako/errors.rb
|
|
125
180
|
- lib/kobako/execution.rb
|
|
126
181
|
- lib/kobako/extension.rb
|
|
182
|
+
- lib/kobako/filesystem.rb
|
|
127
183
|
- lib/kobako/handle.rb
|
|
128
184
|
- lib/kobako/outcome.rb
|
|
129
185
|
- lib/kobako/payload.rb
|
|
@@ -133,9 +189,10 @@ files:
|
|
|
133
189
|
- lib/kobako/sandbox.rb
|
|
134
190
|
- lib/kobako/sandbox_options.rb
|
|
135
191
|
- lib/kobako/snippet.rb
|
|
136
|
-
- lib/kobako/snippet/
|
|
192
|
+
- lib/kobako/snippet/bytecode.rb
|
|
137
193
|
- lib/kobako/snippet/source.rb
|
|
138
194
|
- lib/kobako/transport.rb
|
|
195
|
+
- lib/kobako/transport/block_failure.rb
|
|
139
196
|
- lib/kobako/transport/call.rb
|
|
140
197
|
- lib/kobako/transport/dispatcher.rb
|
|
141
198
|
- lib/kobako/transport/error.rb
|
|
@@ -147,12 +204,14 @@ files:
|
|
|
147
204
|
- lib/kobako/usage.rb
|
|
148
205
|
- lib/kobako/version.rb
|
|
149
206
|
- release-please-config.json
|
|
150
|
-
- rust-toolchain.toml
|
|
151
207
|
- sig/kobako.rbs
|
|
152
208
|
- sig/kobako/capture.rbs
|
|
153
209
|
- sig/kobako/catalog.rbs
|
|
154
210
|
- sig/kobako/catalog/extensions.rbs
|
|
211
|
+
- sig/kobako/catalog/flags.rbs
|
|
212
|
+
- sig/kobako/catalog/grants.rbs
|
|
155
213
|
- sig/kobako/catalog/handles.rbs
|
|
214
|
+
- sig/kobako/catalog/mount.rbs
|
|
156
215
|
- sig/kobako/catalog/services.rbs
|
|
157
216
|
- sig/kobako/catalog/snippets.rbs
|
|
158
217
|
- sig/kobako/codec.rbs
|
|
@@ -164,10 +223,14 @@ files:
|
|
|
164
223
|
- sig/kobako/codec/nesting.rbs
|
|
165
224
|
- sig/kobako/codec/state.rbs
|
|
166
225
|
- sig/kobako/codec/utils.rbs
|
|
226
|
+
- sig/kobako/codec/value_budget.rbs
|
|
227
|
+
- sig/kobako/constant_name.rbs
|
|
167
228
|
- sig/kobako/context.rbs
|
|
168
229
|
- sig/kobako/errors.rbs
|
|
169
230
|
- sig/kobako/execution.rbs
|
|
170
231
|
- sig/kobako/extension.rbs
|
|
232
|
+
- sig/kobako/filesystem.rbs
|
|
233
|
+
- sig/kobako/guest_yielder.rbs
|
|
171
234
|
- sig/kobako/handle.rbs
|
|
172
235
|
- sig/kobako/outcome.rbs
|
|
173
236
|
- sig/kobako/payload.rbs
|
|
@@ -176,10 +239,12 @@ files:
|
|
|
176
239
|
- sig/kobako/runtime.rbs
|
|
177
240
|
- sig/kobako/sandbox.rbs
|
|
178
241
|
- sig/kobako/sandbox_options.rbs
|
|
242
|
+
- sig/kobako/snapshot.rbs
|
|
179
243
|
- sig/kobako/snippet.rbs
|
|
180
|
-
- sig/kobako/snippet/
|
|
244
|
+
- sig/kobako/snippet/bytecode.rbs
|
|
181
245
|
- sig/kobako/snippet/source.rbs
|
|
182
246
|
- sig/kobako/transport.rbs
|
|
247
|
+
- sig/kobako/transport/block_failure.rbs
|
|
183
248
|
- sig/kobako/transport/call.rbs
|
|
184
249
|
- sig/kobako/transport/dispatcher.rbs
|
|
185
250
|
- sig/kobako/transport/error.rbs
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
//! The invocation frames — Frame 1's bound constant paths and Frame 3's
|
|
2
|
-
//! preloaded snippets, the two both entry points read before running
|
|
3
|
-
//! anything. The numbering skips Frame 2 because the `#eval` user source
|
|
4
|
-
//! is raw UTF-8 with no envelope of its own.
|
|
5
|
-
//!
|
|
6
|
-
//! Both are mandatory-presence even when empty, so a reader never has to
|
|
7
|
-
//! tell an absent frame from an empty one, and each frame's length reaches
|
|
8
|
-
//! the guest from the channel's own prefix rather than from the envelope.
|
|
9
|
-
|
|
10
|
-
use super::bytes::{Reader, Writer};
|
|
11
|
-
use super::DecodeError;
|
|
12
|
-
|
|
13
|
-
const SNIPPET_SOURCE: u8 = 0;
|
|
14
|
-
const SNIPPET_BYTECODE: u8 = 1;
|
|
15
|
-
|
|
16
|
-
/// Frame 1 — the bound constant paths the guest installs proxies from.
|
|
17
|
-
/// Always present; an empty list means no Service is bound.
|
|
18
|
-
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
|
19
|
-
pub struct Bindings {
|
|
20
|
-
pub paths: Vec<String>,
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
impl Bindings {
|
|
24
|
-
pub fn decode(bytes: &[u8]) -> Result<Self, DecodeError> {
|
|
25
|
-
let mut reader = Reader::new(bytes);
|
|
26
|
-
let paths = reader.text_list()?;
|
|
27
|
-
reader.finish()?;
|
|
28
|
-
Ok(Bindings { paths })
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
pub fn encode(&self) -> Vec<u8> {
|
|
32
|
-
let mut writer = Writer::new();
|
|
33
|
-
writer.list(&self.paths);
|
|
34
|
-
writer.into_bytes()
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/// One preloaded snippet. Source carries the filename the guest compiles
|
|
39
|
-
/// under; bytecode does not, because its filename — when it has one — lives
|
|
40
|
-
/// in the bytecode's own debug section.
|
|
41
|
-
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
42
|
-
pub enum Snippet {
|
|
43
|
-
Source { name: String, body: String },
|
|
44
|
-
Bytecode { body: Vec<u8> },
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/// Frame 3 — the preloaded snippets, in insertion order. Always present;
|
|
48
|
-
/// a zero count means nothing was preloaded.
|
|
49
|
-
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
|
50
|
-
pub struct Snippets {
|
|
51
|
-
pub entries: Vec<Snippet>,
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
impl Snippets {
|
|
55
|
-
pub fn decode(bytes: &[u8]) -> Result<Self, DecodeError> {
|
|
56
|
-
let mut reader = Reader::new(bytes);
|
|
57
|
-
let count = reader.u32()? as usize;
|
|
58
|
-
// Each entry costs at least a kind byte, so a count past the bytes
|
|
59
|
-
// left cannot be satisfied; refusing it bounds the allocation.
|
|
60
|
-
if count > reader.remaining().len() {
|
|
61
|
-
return Err(DecodeError::new(
|
|
62
|
-
"Frame 3 declares more entries than the frame holds",
|
|
63
|
-
));
|
|
64
|
-
}
|
|
65
|
-
let mut entries = Vec::with_capacity(count);
|
|
66
|
-
for _ in 0..count {
|
|
67
|
-
entries.push(match reader.u8()? {
|
|
68
|
-
SNIPPET_SOURCE => Snippet::Source {
|
|
69
|
-
name: reader.text()?.to_owned(),
|
|
70
|
-
body: reader.text()?.to_owned(),
|
|
71
|
-
},
|
|
72
|
-
SNIPPET_BYTECODE => Snippet::Bytecode {
|
|
73
|
-
body: reader.bytes()?.to_vec(),
|
|
74
|
-
},
|
|
75
|
-
_ => return Err(DecodeError::new("Frame 3 snippet kind must be 0 or 1")),
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
reader.finish()?;
|
|
79
|
-
Ok(Snippets { entries })
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
pub fn encode(&self) -> Vec<u8> {
|
|
83
|
-
let mut writer = Writer::new();
|
|
84
|
-
writer.u32(self.entries.len() as u32);
|
|
85
|
-
for entry in &self.entries {
|
|
86
|
-
match entry {
|
|
87
|
-
Snippet::Source { name, body } => {
|
|
88
|
-
writer
|
|
89
|
-
.u8(SNIPPET_SOURCE)
|
|
90
|
-
.bytes(name.as_bytes())
|
|
91
|
-
.bytes(body.as_bytes());
|
|
92
|
-
}
|
|
93
|
-
Snippet::Bytecode { body } => {
|
|
94
|
-
writer.u8(SNIPPET_BYTECODE).bytes(body);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
writer.into_bytes()
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
#[cfg(test)]
|
|
103
|
-
mod tests {
|
|
104
|
-
use super::*;
|
|
105
|
-
|
|
106
|
-
// @behavior WE-050
|
|
107
|
-
#[test]
|
|
108
|
-
fn empty_bindings_round_trip() {
|
|
109
|
-
let encoded = Bindings::default().encode();
|
|
110
|
-
assert_eq!(
|
|
111
|
-
Bindings::decode(&encoded),
|
|
112
|
-
Ok(Bindings::default()),
|
|
113
|
-
"a Sandbox with no bindings must send a present, empty Frame 1"
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
// @behavior WE-051
|
|
118
|
-
#[test]
|
|
119
|
-
fn bindings_round_trip_every_path() {
|
|
120
|
-
let bindings = Bindings {
|
|
121
|
-
paths: vec!["MyService::KV".into(), "File".into()],
|
|
122
|
-
};
|
|
123
|
-
let encoded = bindings.encode();
|
|
124
|
-
assert_eq!(
|
|
125
|
-
Bindings::decode(&encoded),
|
|
126
|
-
Ok(bindings),
|
|
127
|
-
"Frame 1 must carry every bound path in order"
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// @behavior WE-052
|
|
132
|
-
#[test]
|
|
133
|
-
fn snippets_round_trip_both_kinds_in_order() {
|
|
134
|
-
let snippets = Snippets {
|
|
135
|
-
entries: vec![
|
|
136
|
-
Snippet::Source {
|
|
137
|
-
name: "Helper".into(),
|
|
138
|
-
body: "def helper; end".into(),
|
|
139
|
-
},
|
|
140
|
-
Snippet::Bytecode {
|
|
141
|
-
body: vec![0x52, 0x49, 0x54, 0x45],
|
|
142
|
-
},
|
|
143
|
-
],
|
|
144
|
-
};
|
|
145
|
-
let encoded = snippets.encode();
|
|
146
|
-
assert_eq!(
|
|
147
|
-
Snippets::decode(&encoded),
|
|
148
|
-
Ok(snippets),
|
|
149
|
-
"Frame 3 must carry source and bytecode entries in insertion order"
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// @behavior WE-053
|
|
154
|
-
#[test]
|
|
155
|
-
fn an_empty_snippet_table_round_trips() {
|
|
156
|
-
let encoded = Snippets::default().encode();
|
|
157
|
-
assert_eq!(
|
|
158
|
-
Snippets::decode(&encoded),
|
|
159
|
-
Ok(Snippets::default()),
|
|
160
|
-
"a Sandbox with no preloads must send a present, zero-count Frame 3"
|
|
161
|
-
);
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
// @behavior WE-054
|
|
165
|
-
#[test]
|
|
166
|
-
fn golden_layout_pins_the_bindings_as_a_counted_list() {
|
|
167
|
-
let bindings = Bindings {
|
|
168
|
-
paths: vec!["A".into()],
|
|
169
|
-
};
|
|
170
|
-
assert_eq!(
|
|
171
|
-
bindings.encode(),
|
|
172
|
-
vec![
|
|
173
|
-
0, 0, 0, 1, // path count
|
|
174
|
-
0, 0, 0, 1, b'A',
|
|
175
|
-
],
|
|
176
|
-
"Frame 1 must be a counted list of paths, so the count precedes the first entry"
|
|
177
|
-
);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// @behavior WE-055
|
|
181
|
-
#[test]
|
|
182
|
-
fn golden_layout_pins_the_snippet_entry_shape() {
|
|
183
|
-
let snippets = Snippets {
|
|
184
|
-
entries: vec![
|
|
185
|
-
Snippet::Source {
|
|
186
|
-
name: "N".into(),
|
|
187
|
-
body: "b".into(),
|
|
188
|
-
},
|
|
189
|
-
Snippet::Bytecode { body: vec![0x52] },
|
|
190
|
-
],
|
|
191
|
-
};
|
|
192
|
-
assert_eq!(
|
|
193
|
-
snippets.encode(),
|
|
194
|
-
vec![
|
|
195
|
-
0, 0, 0, 2, // entry count
|
|
196
|
-
0, // kind: source
|
|
197
|
-
0, 0, 0, 1, b'N', // name, source only
|
|
198
|
-
0, 0, 0, 1, b'b', // body
|
|
199
|
-
1, // kind: bytecode
|
|
200
|
-
0, 0, 0, 1, 0x52, // body, no name
|
|
201
|
-
],
|
|
202
|
-
"a source entry must encode as kind byte 0 with a name and a bytecode entry as \
|
|
203
|
-
kind byte 1 with none, so the two stay distinguishable by their tag alone"
|
|
204
|
-
);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
// @behavior WE-056
|
|
208
|
-
#[test]
|
|
209
|
-
fn an_unknown_snippet_kind_is_refused() {
|
|
210
|
-
let bytes = {
|
|
211
|
-
let mut w = Writer::new();
|
|
212
|
-
w.u32(1).u8(9);
|
|
213
|
-
w.into_bytes()
|
|
214
|
-
};
|
|
215
|
-
assert!(
|
|
216
|
-
Snippets::decode(&bytes).is_err(),
|
|
217
|
-
"a Frame 3 snippet kind that is neither source nor bytecode must be rejected"
|
|
218
|
-
);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// @behavior WE-057
|
|
222
|
-
#[test]
|
|
223
|
-
fn a_snippet_count_the_frame_cannot_satisfy_is_refused() {
|
|
224
|
-
let bytes = [0xff, 0xff, 0xff, 0xff];
|
|
225
|
-
assert!(
|
|
226
|
-
Snippets::decode(&bytes).is_err(),
|
|
227
|
-
"a Frame 3 count larger than the frame must be rejected before any allocation"
|
|
228
|
-
);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
// @behavior WE-058
|
|
232
|
-
#[test]
|
|
233
|
-
fn trailing_bytes_after_a_frame_are_refused() {
|
|
234
|
-
let mut encoded = Bindings::default().encode();
|
|
235
|
-
encoded.push(0);
|
|
236
|
-
assert!(
|
|
237
|
-
Bindings::decode(&encoded).is_err(),
|
|
238
|
-
"bytes past Frame 1's last field must fail loudly as a framing desync"
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
}
|