kobako 0.29.0 → 0.30.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 (201) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/CHANGELOG.md +217 -10
  4. data/Cargo.lock +139 -141
  5. data/README.md +96 -574
  6. data/ROADMAP.md +2 -1
  7. data/crates/kobako-runtime/CHANGELOG.md +269 -1
  8. data/crates/kobako-runtime/Cargo.toml +25 -15
  9. data/crates/kobako-runtime/README.md +7 -3
  10. data/crates/kobako-runtime/src/dispatch.rs +1 -1
  11. data/crates/kobako-runtime/src/endpoint/buffer.rs +192 -0
  12. data/crates/kobako-runtime/src/endpoint/capture.rs +115 -0
  13. data/crates/kobako-runtime/src/endpoint/dispatch.rs +253 -0
  14. data/crates/kobako-runtime/src/endpoint/invoke.rs +194 -0
  15. data/crates/kobako-runtime/src/endpoint/memory_cap.rs +238 -0
  16. data/crates/kobako-runtime/src/endpoint.rs +166 -0
  17. data/crates/kobako-runtime/src/filesystem/bind/fid.rs +82 -0
  18. data/crates/kobako-runtime/src/filesystem/{directory/spelling.rs → bind/lookup.rs} +91 -49
  19. data/crates/kobako-runtime/src/filesystem/bind/walk.rs +249 -0
  20. data/crates/kobako-runtime/src/filesystem/bind.rs +2665 -0
  21. data/crates/kobako-runtime/src/filesystem/overlay/file.rs +89 -0
  22. data/crates/kobako-runtime/src/filesystem/overlay/inode.rs +106 -0
  23. data/crates/kobako-runtime/src/filesystem/overlay/path.rs +285 -0
  24. data/crates/kobako-runtime/src/filesystem/overlay/stack/copy_up.rs +135 -0
  25. data/crates/kobako-runtime/src/filesystem/overlay/stack/dir.rs +263 -0
  26. data/crates/kobako-runtime/src/filesystem/overlay/stack/namei.rs +135 -0
  27. data/crates/kobako-runtime/src/filesystem/overlay/stack/readdir.rs +57 -0
  28. data/crates/kobako-runtime/src/filesystem/overlay/stack.rs +227 -734
  29. data/crates/kobako-runtime/src/filesystem/overlay.rs +2649 -1135
  30. data/crates/kobako-runtime/src/filesystem/path.rs +2 -41
  31. data/crates/kobako-runtime/src/filesystem/pipe.rs +221 -0
  32. data/crates/kobako-runtime/src/filesystem/rdir.rs +101 -0
  33. data/crates/kobako-runtime/src/filesystem/tmpfs/tmpfile.rs +32 -0
  34. data/crates/kobako-runtime/src/filesystem/tmpfs/whiteout.rs +85 -0
  35. data/crates/kobako-runtime/src/filesystem/tmpfs/xattr.rs +22 -0
  36. data/crates/kobako-runtime/src/filesystem/tmpfs.rs +1985 -0
  37. data/crates/kobako-runtime/src/filesystem/wrap.rs +224 -0
  38. data/crates/kobako-runtime/src/filesystem.rs +21 -387
  39. data/crates/kobako-runtime/src/hashtable.rs +44 -0
  40. data/crates/kobako-runtime/src/lib.rs +11 -6
  41. data/crates/kobako-runtime/src/locking/seqlock.rs +66 -0
  42. data/crates/kobako-runtime/src/locking.rs +218 -0
  43. data/crates/kobako-runtime/src/mount.rs +31 -104
  44. data/crates/kobako-runtime/src/profile.rs +137 -1
  45. data/crates/kobako-runtime/src/sched.rs +210 -0
  46. data/crates/kobako-runtime/src/security.rs +696 -0
  47. data/crates/kobako-runtime/src/vfs/attr.rs +162 -0
  48. data/crates/kobako-runtime/src/vfs/cred.rs +334 -0
  49. data/crates/kobako-runtime/src/vfs/dentry.rs +1412 -0
  50. data/crates/kobako-runtime/src/vfs/errno.rs +153 -0
  51. data/crates/kobako-runtime/src/vfs/file.rs +1915 -0
  52. data/crates/kobako-runtime/src/vfs/inode.rs +429 -0
  53. data/crates/kobako-runtime/src/vfs/kern_path.rs +217 -0
  54. data/crates/kobako-runtime/src/vfs/mount.rs +59 -0
  55. data/crates/kobako-runtime/src/vfs/namei.rs +5708 -0
  56. data/crates/kobako-runtime/src/vfs/openat2.rs +116 -0
  57. data/crates/kobako-runtime/src/vfs/path.rs +64 -0
  58. data/crates/kobako-runtime/src/vfs/readdir.rs +163 -0
  59. data/crates/kobako-runtime/src/vfs/stat.rs +157 -0
  60. data/crates/kobako-runtime/src/vfs/super_block.rs +122 -0
  61. data/crates/kobako-runtime/src/vfs/utimes.rs +289 -0
  62. data/crates/kobako-runtime/src/vfs.rs +60 -0
  63. data/crates/kobako-runtime/tests/linux_baseline/calls.rs +171 -0
  64. data/crates/kobako-runtime/tests/linux_baseline/concurrent.rs +276 -0
  65. data/crates/kobako-runtime/tests/linux_baseline/kobako.rs +323 -0
  66. data/crates/kobako-runtime/tests/linux_baseline/linux-baseline-expected.txt +16 -0
  67. data/crates/kobako-runtime/tests/linux_baseline/linux.rs +449 -0
  68. data/crates/kobako-runtime/tests/linux_baseline/main.rs +611 -0
  69. data/crates/kobako-runtime/tests/linux_baseline/permissions.rs +236 -0
  70. data/crates/kobako-transport/CHANGELOG.md +8 -2
  71. data/crates/kobako-transport/Cargo.toml +3 -3
  72. data/crates/kobako-transport/README.md +6 -5
  73. data/crates/kobako-transport/src/envelope/bytes.rs +33 -25
  74. data/crates/kobako-transport/src/envelope/call.rs +5 -5
  75. data/crates/kobako-transport/src/envelope/compile_reply.rs +2 -2
  76. data/crates/kobako-transport/src/envelope/error_record.rs +3 -3
  77. data/crates/kobako-transport/src/envelope/fault.rs +2 -2
  78. data/crates/kobako-transport/src/envelope/outcome.rs +3 -3
  79. data/crates/kobako-transport/src/envelope/preamble.rs +12 -12
  80. data/crates/kobako-transport/src/envelope/reply.rs +2 -2
  81. data/crates/kobako-transport/src/envelope/request.rs +2 -2
  82. data/crates/kobako-transport/src/envelope/run.rs +1 -1
  83. data/crates/kobako-transport/src/envelope/unsupported.rs +2 -2
  84. data/crates/kobako-transport/src/envelope.rs +2 -2
  85. data/crates/kobako-wasmtime/CHANGELOG.md +154 -8
  86. data/crates/kobako-wasmtime/Cargo.toml +15 -14
  87. data/crates/kobako-wasmtime/README.md +9 -5
  88. data/crates/kobako-wasmtime/src/abi.rs +12 -20
  89. data/crates/kobako-wasmtime/src/ambient.rs +1 -2
  90. data/crates/kobako-wasmtime/src/cache.rs +5 -5
  91. data/crates/kobako-wasmtime/src/config.rs +22 -7
  92. data/crates/kobako-wasmtime/src/descriptors.rs +133 -100
  93. data/crates/kobako-wasmtime/src/driver.rs +29 -96
  94. data/crates/kobako-wasmtime/src/exports.rs +5 -16
  95. data/crates/kobako-wasmtime/src/guest.rs +38 -0
  96. data/crates/kobako-wasmtime/src/imports.rs +14 -8
  97. data/crates/kobako-wasmtime/src/instance_pre.rs +3 -3
  98. data/crates/kobako-wasmtime/src/invocation.rs +26 -46
  99. data/crates/kobako-wasmtime/src/lib.rs +1 -4
  100. data/crates/kobako-wasmtime/src/limiter.rs +6 -230
  101. data/crates/kobako-wasmtime/src/preview1/differential/mount.rs +69 -46
  102. data/crates/kobako-wasmtime/src/preview1/differential.rs +121 -7
  103. data/crates/kobako-wasmtime/src/preview1/errno.rs +74 -206
  104. data/crates/kobako-wasmtime/src/preview1/fd.rs +1248 -500
  105. data/crates/kobako-wasmtime/src/preview1/memory.rs +117 -150
  106. data/crates/kobako-wasmtime/src/preview1/mount_view/wrap.rs +211 -0
  107. data/crates/kobako-wasmtime/src/preview1/mount_view.rs +1939 -672
  108. data/crates/kobako-wasmtime/src/preview1/path.rs +230 -349
  109. data/crates/kobako-wasmtime/src/preview1/poll.rs +148 -100
  110. data/crates/kobako-wasmtime/src/preview1/sock.rs +6 -23
  111. data/crates/kobako-wasmtime/src/preview1/testsuite-expected.txt +6 -0
  112. data/crates/kobako-wasmtime/src/preview1/testsuite.rs +157 -0
  113. data/crates/kobako-wasmtime/src/preview1.rs +464 -413
  114. data/crates/kobako-wasmtime/src/trap.rs +9 -9
  115. data/crates/kobako-wasmtime/src/wasi.rs +53 -37
  116. data/crates/kobako-wasmtime/tests/{guest_file.rs → integration/guest_file.rs} +232 -201
  117. data/crates/kobako-wasmtime/tests/integration/main.rs +29 -0
  118. data/crates/kobako-wasmtime/tests/{preamble_flags.rs → integration/preamble_flags.rs} +1 -1
  119. data/crates/kobako-wasmtime/tests/{snippet_compile.rs → integration/snippet_compile.rs} +1 -1
  120. data/crates/kobako-wasmtime/tests/{unanswered_call.rs → integration/unanswered_call.rs} +1 -1
  121. data/crates/kobako-wasmtime/tests/{unsupported_call.rs → integration/unsupported_call.rs} +1 -1
  122. data/crates/kobako-wasmtime/witx/typenames.witx +750 -0
  123. data/crates/kobako-wasmtime/witx/wasi_snapshot_preview1.witx +441 -0
  124. data/data/kobako.wasm +0 -0
  125. data/ext/kobako/Cargo.toml +1 -1
  126. data/ext/kobako/src/runtime/bridge.rs +1 -1
  127. data/ext/kobako/src/runtime/errors.rs +1 -1
  128. data/ext/kobako/src/runtime/escape.rs +28 -14
  129. data/ext/kobako/src/runtime/filesystem/grants.rs +21 -5
  130. data/ext/kobako/src/runtime/filesystem/ruby.rs +464 -156
  131. data/ext/kobako/src/runtime/filesystem.rs +109 -137
  132. data/ext/kobako/src/runtime/gvl.rs +43 -8
  133. data/ext/kobako/src/runtime/snapshot.rs +1 -1
  134. data/ext/kobako/src/runtime.rs +6 -1
  135. data/lib/kobako/catalog/extensions.rb +5 -5
  136. data/lib/kobako/catalog/flags.rb +2 -2
  137. data/lib/kobako/catalog/handles.rb +6 -6
  138. data/lib/kobako/catalog/mount.rb +2 -10
  139. data/lib/kobako/catalog/services.rb +2 -2
  140. data/lib/kobako/catalog/snippets.rb +7 -7
  141. data/lib/kobako/catalog.rb +1 -1
  142. data/lib/kobako/codec/decoder.rb +10 -10
  143. data/lib/kobako/codec/ext_types.rb +3 -5
  144. data/lib/kobako/codec/handle_walk.rb +4 -6
  145. data/lib/kobako/codec/nesting.rb +7 -7
  146. data/lib/kobako/codec/utils.rb +1 -1
  147. data/lib/kobako/codec/value_budget.rb +3 -3
  148. data/lib/kobako/context.rb +5 -5
  149. data/lib/kobako/filesystem.rb +44 -13
  150. data/lib/kobako/payload/arguments.rb +2 -2
  151. data/lib/kobako/pool.rb +4 -4
  152. data/lib/kobako/sandbox.rb +28 -28
  153. data/lib/kobako/sandbox_options.rb +2 -3
  154. data/lib/kobako/snippet/bytecode.rb +1 -1
  155. data/lib/kobako/snippet/source.rb +1 -1
  156. data/lib/kobako/transport/dispatcher.rb +5 -5
  157. data/lib/kobako/transport/exposure.rb +2 -2
  158. data/lib/kobako/transport/reflection.rb +7 -7
  159. data/lib/kobako/transport/run.rb +5 -5
  160. data/lib/kobako/transport/yielder.rb +1 -1
  161. data/lib/kobako/version.rb +1 -1
  162. data/lib/kobako.rb +34 -0
  163. data/release-please-config.json +1 -0
  164. data/sig/kobako/catalog/extensions.rbs +3 -3
  165. data/sig/kobako/catalog/handles.rbs +3 -3
  166. data/sig/kobako/catalog/mount.rbs +0 -4
  167. data/sig/kobako/catalog/services.rbs +1 -1
  168. data/sig/kobako/catalog/snippets.rbs +3 -3
  169. data/sig/kobako/catalog.rbs +1 -1
  170. data/sig/kobako/codec/decoder.rbs +1 -1
  171. data/sig/kobako/codec/handle_walk.rbs +1 -1
  172. data/sig/kobako/codec/nesting.rbs +2 -2
  173. data/sig/kobako/codec/utils.rbs +1 -1
  174. data/sig/kobako/codec/value_budget.rbs +1 -1
  175. data/sig/kobako/codec.rbs +1 -2
  176. data/sig/kobako/context.rbs +1 -1
  177. data/sig/kobako/filesystem.rbs +19 -14
  178. data/sig/kobako/guest_yielder.rbs +1 -1
  179. data/sig/kobako/payload/arguments.rbs +1 -1
  180. data/sig/kobako/pool.rbs +2 -2
  181. data/sig/kobako/runtime.rbs +1 -1
  182. data/sig/kobako/sandbox.rbs +3 -5
  183. data/sig/kobako/sandbox_options.rbs +1 -1
  184. data/sig/kobako/transport/dispatcher.rbs +2 -2
  185. data/sig/kobako/transport/exposure.rbs +1 -1
  186. data/sig/kobako/transport/reflection.rbs +2 -2
  187. data/sig/kobako/transport/run.rbs +3 -3
  188. data/sig/kobako/transport.rbs +1 -1
  189. metadata +67 -19
  190. data/crates/kobako-runtime/src/filesystem/directory.rs +0 -1082
  191. data/crates/kobako-runtime/src/filesystem/memory.rs +0 -1100
  192. data/crates/kobako-runtime/src/filesystem/overlay/exclusive.rs +0 -88
  193. data/crates/kobako-runtime/src/filesystem/temporary.rs +0 -167
  194. data/crates/kobako-wasmtime/src/capture.rs +0 -96
  195. data/crates/kobako-wasmtime/src/dispatch.rs +0 -125
  196. data/crates/kobako-wasmtime/src/guest_mem.rs +0 -271
  197. data/crates/kobako-wasmtime/src/io.rs +0 -89
  198. data/crates/kobako-wasmtime/src/preview1/args.rs +0 -60
  199. data/crates/kobako-wasmtime/src/preview1/beneath.rs +0 -188
  200. /data/crates/kobako-wasmtime/tests/{compile_posture.rs → integration/compile_posture.rs} +0 -0
  201. /data/crates/kobako-wasmtime/tests/{support → integration/support}/mod.rs +0 -0
@@ -0,0 +1,441 @@
1
+ ;; WASI Preview. This is an evolution of the API that WASI initially
2
+ ;; launched with.
3
+ ;;
4
+ ;; Some content here is derived from [CloudABI](https://github.com/NuxiNL/cloudabi).
5
+ ;;
6
+ ;; This is a `witx` file. See [here](https://github.com/WebAssembly/WASI/blob/main/legacy/tools/witx-docs.md)
7
+ ;; for an explanation of what that means.
8
+
9
+ (use "typenames.witx")
10
+
11
+ (module $wasi_snapshot_preview1
12
+ ;;; Linear memory to be accessed by WASI functions that need it.
13
+ (import "memory" (memory))
14
+
15
+
16
+
17
+
18
+ ;;; Provide file advisory information on a file descriptor.
19
+ ;;; Note: This is similar to `posix_fadvise` in POSIX.
20
+ (@interface func (export "fd_advise")
21
+ (param $fd $fd)
22
+ ;;; The offset within the file to which the advisory applies.
23
+ (param $offset $filesize)
24
+ ;;; The length of the region to which the advisory applies.
25
+ (param $len $filesize)
26
+ ;;; The advice.
27
+ (param $advice $advice)
28
+ (result $error (expected (error $errno)))
29
+ )
30
+
31
+ ;;; Force the allocation of space in a file.
32
+ ;;; Note: This is similar to `posix_fallocate` in POSIX.
33
+ (@interface func (export "fd_allocate")
34
+ (param $fd $fd)
35
+ ;;; The offset at which to start the allocation.
36
+ (param $offset $filesize)
37
+ ;;; The length of the area that is allocated.
38
+ (param $len $filesize)
39
+ (result $error (expected (error $errno)))
40
+ )
41
+
42
+ ;;; Close a file descriptor.
43
+ ;;; Note: This is similar to `close` in POSIX.
44
+ (@interface func (export "fd_close")
45
+ (param $fd $fd)
46
+ (result $error (expected (error $errno)))
47
+ )
48
+
49
+ ;;; Synchronize the data of a file to disk.
50
+ ;;; Note: This is similar to `fdatasync` in POSIX.
51
+ (@interface func (export "fd_datasync")
52
+ (param $fd $fd)
53
+ (result $error (expected (error $errno)))
54
+ )
55
+
56
+ ;;; Get the attributes of a file descriptor.
57
+ ;;; Note: This returns similar flags to `fsync(fd, F_GETFL)` in POSIX, as well as additional fields.
58
+ (@interface func (export "fd_fdstat_get")
59
+ (param $fd $fd)
60
+ ;;; The buffer where the file descriptor's attributes are stored.
61
+ (result $error (expected $fdstat (error $errno)))
62
+ )
63
+
64
+ ;;; Adjust the flags associated with a file descriptor.
65
+ ;;; Note: This is similar to `fcntl(fd, F_SETFL, flags)` in POSIX.
66
+ (@interface func (export "fd_fdstat_set_flags")
67
+ (param $fd $fd)
68
+ ;;; The desired values of the file descriptor flags.
69
+ (param $flags $fdflags)
70
+ (result $error (expected (error $errno)))
71
+ )
72
+
73
+ ;;; Adjust the rights associated with a file descriptor.
74
+ ;;; This can only be used to remove rights, and returns `errno::notcapable` if called in a way that would attempt to add rights
75
+ (@interface func (export "fd_fdstat_set_rights")
76
+ (param $fd $fd)
77
+ ;;; The desired rights of the file descriptor.
78
+ (param $fs_rights_base $rights)
79
+ (param $fs_rights_inheriting $rights)
80
+ (result $error (expected (error $errno)))
81
+ )
82
+
83
+ ;;; Return the attributes of an open file.
84
+ (@interface func (export "fd_filestat_get")
85
+ (param $fd $fd)
86
+ ;;; The buffer where the file's attributes are stored.
87
+ (result $error (expected $filestat (error $errno)))
88
+ )
89
+
90
+ ;;; Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros.
91
+ ;;; Note: This is similar to `ftruncate` in POSIX.
92
+ (@interface func (export "fd_filestat_set_size")
93
+ (param $fd $fd)
94
+ ;;; The desired file size.
95
+ (param $size $filesize)
96
+ (result $error (expected (error $errno)))
97
+ )
98
+
99
+ ;;; Adjust the timestamps of an open file or directory.
100
+ ;;; Note: This is similar to `futimens` in POSIX.
101
+ (@interface func (export "fd_filestat_set_times")
102
+ (param $fd $fd)
103
+ ;;; The desired values of the data access timestamp.
104
+ (param $atim $timestamp)
105
+ ;;; The desired values of the data modification timestamp.
106
+ (param $mtim $timestamp)
107
+ ;;; A bitmask indicating which timestamps to adjust.
108
+ (param $fst_flags $fstflags)
109
+ (result $error (expected (error $errno)))
110
+ )
111
+
112
+ ;;; Read from a file descriptor, without using and updating the file descriptor's offset.
113
+ ;;; Note: This is similar to `preadv` in POSIX.
114
+ (@interface func (export "fd_pread")
115
+ (param $fd $fd)
116
+ ;;; List of scatter/gather vectors in which to store data.
117
+ (param $iovs $iovec_array)
118
+ ;;; The offset within the file at which to read.
119
+ (param $offset $filesize)
120
+ ;;; The number of bytes read.
121
+ (result $error (expected $size (error $errno)))
122
+ )
123
+
124
+ ;;; Return a description of the given preopened file descriptor.
125
+ (@interface func (export "fd_prestat_get")
126
+ (param $fd $fd)
127
+ ;;; The buffer where the description is stored.
128
+ (result $error (expected $prestat (error $errno)))
129
+ )
130
+
131
+ ;;; Return a description of the given preopened file descriptor.
132
+ (@interface func (export "fd_prestat_dir_name")
133
+ (param $fd $fd)
134
+ ;;; A buffer into which to write the preopened directory name.
135
+ (param $path (@witx pointer u8))
136
+ (param $path_len $size)
137
+ (result $error (expected (error $errno)))
138
+ )
139
+
140
+ ;;; Write to a file descriptor, without using and updating the file descriptor's offset.
141
+ ;;; Note: This is similar to `pwritev` in POSIX.
142
+ (@interface func (export "fd_pwrite")
143
+ (param $fd $fd)
144
+ ;;; List of scatter/gather vectors from which to retrieve data.
145
+ (param $iovs $ciovec_array)
146
+ ;;; The offset within the file at which to write.
147
+ (param $offset $filesize)
148
+ ;;; The number of bytes written.
149
+ (result $error (expected $size (error $errno)))
150
+ )
151
+
152
+ ;;; Read from a file descriptor.
153
+ ;;; Note: This is similar to `readv` in POSIX.
154
+ (@interface func (export "fd_read")
155
+ (param $fd $fd)
156
+ ;;; List of scatter/gather vectors to which to store data.
157
+ (param $iovs $iovec_array)
158
+ ;;; The number of bytes read.
159
+ (result $error (expected $size (error $errno)))
160
+ )
161
+
162
+ ;;; Read directory entries from a directory.
163
+ ;;; When successful, the contents of the output buffer consist of a sequence of
164
+ ;;; directory entries. Each directory entry consists of a `dirent` object,
165
+ ;;; followed by `dirent::d_namlen` bytes holding the name of the directory
166
+ ;;; entry.
167
+ ;;
168
+ ;;; This function fills the output buffer as much as possible, potentially
169
+ ;;; truncating the last directory entry. This allows the caller to grow its
170
+ ;;; read buffer size in case it's too small to fit a single large directory
171
+ ;;; entry, or skip the oversized directory entry.
172
+ (@interface func (export "fd_readdir")
173
+ (param $fd $fd)
174
+ ;;; The buffer where directory entries are stored
175
+ (param $buf (@witx pointer u8))
176
+ (param $buf_len $size)
177
+ ;;; The location within the directory to start reading
178
+ (param $cookie $dircookie)
179
+ ;;; The number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached.
180
+ (result $error (expected $size (error $errno)))
181
+ )
182
+
183
+ ;;; Atomically replace a file descriptor by renumbering another file descriptor.
184
+ ;;
185
+ ;;; Due to the strong focus on thread safety, this environment does not provide
186
+ ;;; a mechanism to duplicate or renumber a file descriptor to an arbitrary
187
+ ;;; number, like `dup2()`. This would be prone to race conditions, as an actual
188
+ ;;; file descriptor with the same number could be allocated by a different
189
+ ;;; thread at the same time.
190
+ ;;
191
+ ;;; This function provides a way to atomically renumber file descriptors, which
192
+ ;;; would disappear if `dup2()` were to be removed entirely.
193
+ (@interface func (export "fd_renumber")
194
+ (param $fd $fd)
195
+ ;;; The file descriptor to overwrite.
196
+ (param $to $fd)
197
+ (result $error (expected (error $errno)))
198
+ )
199
+
200
+ ;;; Move the offset of a file descriptor.
201
+ ;;; Note: This is similar to `lseek` in POSIX.
202
+ (@interface func (export "fd_seek")
203
+ (param $fd $fd)
204
+ ;;; The number of bytes to move.
205
+ (param $offset $filedelta)
206
+ ;;; The base from which the offset is relative.
207
+ (param $whence $whence)
208
+ ;;; The new offset of the file descriptor, relative to the start of the file.
209
+ (result $error (expected $filesize (error $errno)))
210
+ )
211
+
212
+ ;;; Synchronize the data and metadata of a file to disk.
213
+ ;;; Note: This is similar to `fsync` in POSIX.
214
+ (@interface func (export "fd_sync")
215
+ (param $fd $fd)
216
+ (result $error (expected (error $errno)))
217
+ )
218
+
219
+ ;;; Return the current offset of a file descriptor.
220
+ ;;; Note: This is similar to `lseek(fd, 0, SEEK_CUR)` in POSIX.
221
+ (@interface func (export "fd_tell")
222
+ (param $fd $fd)
223
+ ;;; The current offset of the file descriptor, relative to the start of the file.
224
+ (result $error (expected $filesize (error $errno)))
225
+ )
226
+
227
+ ;;; Write to a file descriptor.
228
+ ;;; Note: This is similar to `writev` in POSIX.
229
+ (@interface func (export "fd_write")
230
+ (param $fd $fd)
231
+ ;;; List of scatter/gather vectors from which to retrieve data.
232
+ (param $iovs $ciovec_array)
233
+ (result $error (expected $size (error $errno)))
234
+ )
235
+
236
+ ;;; Create a directory.
237
+ ;;; Note: This is similar to `mkdirat` in POSIX.
238
+ (@interface func (export "path_create_directory")
239
+ (param $fd $fd)
240
+ ;;; The path at which to create the directory.
241
+ (param $path string)
242
+ (result $error (expected (error $errno)))
243
+ )
244
+
245
+ ;;; Return the attributes of a file or directory.
246
+ ;;; Note: This is similar to `stat` in POSIX.
247
+ (@interface func (export "path_filestat_get")
248
+ (param $fd $fd)
249
+ ;;; Flags determining the method of how the path is resolved.
250
+ (param $flags $lookupflags)
251
+ ;;; The path of the file or directory to inspect.
252
+ (param $path string)
253
+ ;;; The buffer where the file's attributes are stored.
254
+ (result $error (expected $filestat (error $errno)))
255
+ )
256
+
257
+ ;;; Adjust the timestamps of a file or directory.
258
+ ;;; Note: This is similar to `utimensat` in POSIX.
259
+ (@interface func (export "path_filestat_set_times")
260
+ (param $fd $fd)
261
+ ;;; Flags determining the method of how the path is resolved.
262
+ (param $flags $lookupflags)
263
+ ;;; The path of the file or directory to operate on.
264
+ (param $path string)
265
+ ;;; The desired values of the data access timestamp.
266
+ (param $atim $timestamp)
267
+ ;;; The desired values of the data modification timestamp.
268
+ (param $mtim $timestamp)
269
+ ;;; A bitmask indicating which timestamps to adjust.
270
+ (param $fst_flags $fstflags)
271
+ (result $error (expected (error $errno)))
272
+ )
273
+
274
+ ;;; Create a hard link.
275
+ ;;; Note: This is similar to `linkat` in POSIX.
276
+ (@interface func (export "path_link")
277
+ (param $old_fd $fd)
278
+ ;;; Flags determining the method of how the path is resolved.
279
+ (param $old_flags $lookupflags)
280
+ ;;; The source path from which to link.
281
+ (param $old_path string)
282
+ ;;; The working directory at which the resolution of the new path starts.
283
+ (param $new_fd $fd)
284
+ ;;; The destination path at which to create the hard link.
285
+ (param $new_path string)
286
+ (result $error (expected (error $errno)))
287
+ )
288
+
289
+ ;;; Open a file or directory.
290
+ ;;
291
+ ;;; The returned file descriptor is not guaranteed to be the lowest-numbered
292
+ ;;; file descriptor not currently open; it is randomized to prevent
293
+ ;;; applications from depending on making assumptions about indexes, since this
294
+ ;;; is error-prone in multi-threaded contexts. The returned file descriptor is
295
+ ;;; guaranteed to be less than 2**31.
296
+ ;;
297
+ ;;; Note: This is similar to `openat` in POSIX.
298
+ (@interface func (export "path_open")
299
+ (param $fd $fd)
300
+ ;;; Flags determining the method of how the path is resolved.
301
+ (param $dirflags $lookupflags)
302
+ ;;; The relative path of the file or directory to open, relative to the
303
+ ;;; `path_open::fd` directory.
304
+ (param $path string)
305
+ ;;; The method by which to open the file.
306
+ (param $oflags $oflags)
307
+ ;;; The initial rights of the newly created file descriptor. The
308
+ ;;; implementation is allowed to return a file descriptor with fewer rights
309
+ ;;; than specified, if and only if those rights do not apply to the type of
310
+ ;;; file being opened.
311
+ ;;
312
+ ;;; The *base* rights are rights that will apply to operations using the file
313
+ ;;; descriptor itself, while the *inheriting* rights are rights that apply to
314
+ ;;; file descriptors derived from it.
315
+ (param $fs_rights_base $rights)
316
+ (param $fs_rights_inheriting $rights)
317
+ (param $fdflags $fdflags)
318
+ ;;; The file descriptor of the file that has been opened.
319
+ (result $error (expected $fd (error $errno)))
320
+ )
321
+
322
+ ;;; Read the contents of a symbolic link.
323
+ ;;; Note: This is similar to `readlinkat` in POSIX.
324
+ (@interface func (export "path_readlink")
325
+ (param $fd $fd)
326
+ ;;; The path of the symbolic link from which to read.
327
+ (param $path string)
328
+ ;;; The buffer to which to write the contents of the symbolic link.
329
+ (param $buf (@witx pointer u8))
330
+ (param $buf_len $size)
331
+ ;;; The number of bytes placed in the buffer.
332
+ (result $error (expected $size (error $errno)))
333
+ )
334
+
335
+ ;;; Remove a directory.
336
+ ;;; Return `errno::notempty` if the directory is not empty.
337
+ ;;; Note: This is similar to `unlinkat(fd, path, AT_REMOVEDIR)` in POSIX.
338
+ (@interface func (export "path_remove_directory")
339
+ (param $fd $fd)
340
+ ;;; The path to a directory to remove.
341
+ (param $path string)
342
+ (result $error (expected (error $errno)))
343
+ )
344
+
345
+ ;;; Rename a file or directory.
346
+ ;;; Note: This is similar to `renameat` in POSIX.
347
+ (@interface func (export "path_rename")
348
+ (param $fd $fd)
349
+ ;;; The source path of the file or directory to rename.
350
+ (param $old_path string)
351
+ ;;; The working directory at which the resolution of the new path starts.
352
+ (param $new_fd $fd)
353
+ ;;; The destination path to which to rename the file or directory.
354
+ (param $new_path string)
355
+ (result $error (expected (error $errno)))
356
+ )
357
+
358
+ ;;; Create a symbolic link.
359
+ ;;; Note: This is similar to `symlinkat` in POSIX.
360
+ (@interface func (export "path_symlink")
361
+ ;;; The contents of the symbolic link.
362
+ (param $old_path string)
363
+ (param $fd $fd)
364
+ ;;; The destination path at which to create the symbolic link.
365
+ (param $new_path string)
366
+ (result $error (expected (error $errno)))
367
+ )
368
+
369
+
370
+ ;;; Unlink a file.
371
+ ;;; Return `errno::isdir` if the path refers to a directory.
372
+ ;;; Note: This is similar to `unlinkat(fd, path, 0)` in POSIX.
373
+ (@interface func (export "path_unlink_file")
374
+ (param $fd $fd)
375
+ ;;; The path to a file to unlink.
376
+ (param $path string)
377
+ (result $error (expected (error $errno)))
378
+ )
379
+
380
+ ;;; Concurrently poll for the occurrence of a set of events.
381
+ (@interface func (export "poll_oneoff")
382
+ ;;; The events to which to subscribe.
383
+ (param $in (@witx const_pointer $subscription))
384
+ ;;; The events that have occurred.
385
+ (param $out (@witx pointer $event))
386
+ ;;; Both the number of subscriptions and events.
387
+ (param $nsubscriptions $size)
388
+ ;;; The number of events stored.
389
+ (result $error (expected $size (error $errno)))
390
+ )
391
+
392
+
393
+
394
+
395
+
396
+ ;;; Accept a new incoming connection.
397
+ ;;; Note: This is similar to `accept` in POSIX.
398
+ (@interface func (export "sock_accept")
399
+ ;;; The listening socket.
400
+ (param $fd $fd)
401
+ ;;; The desired values of the file descriptor flags.
402
+ (param $flags $fdflags)
403
+ ;;; New socket connection
404
+ (result $error (expected $fd (error $errno)))
405
+ )
406
+
407
+ ;;; Receive a message from a socket.
408
+ ;;; Note: This is similar to `recv` in POSIX, though it also supports reading
409
+ ;;; the data into multiple buffers in the manner of `readv`.
410
+ (@interface func (export "sock_recv")
411
+ (param $fd $fd)
412
+ ;;; List of scatter/gather vectors to which to store data.
413
+ (param $ri_data $iovec_array)
414
+ ;;; Message flags.
415
+ (param $ri_flags $riflags)
416
+ ;;; Number of bytes stored in ri_data and message flags.
417
+ (result $error (expected (tuple $size $roflags) (error $errno)))
418
+ )
419
+
420
+ ;;; Send a message on a socket.
421
+ ;;; Note: This is similar to `send` in POSIX, though it also supports writing
422
+ ;;; the data from multiple buffers in the manner of `writev`.
423
+ (@interface func (export "sock_send")
424
+ (param $fd $fd)
425
+ ;;; List of scatter/gather vectors to which to retrieve data
426
+ (param $si_data $ciovec_array)
427
+ ;;; Message flags.
428
+ (param $si_flags $siflags)
429
+ ;;; Number of bytes transmitted.
430
+ (result $error (expected $size (error $errno)))
431
+ )
432
+
433
+ ;;; Shut down socket send and receive channels.
434
+ ;;; Note: This is similar to `shutdown` in POSIX.
435
+ (@interface func (export "sock_shutdown")
436
+ (param $fd $fd)
437
+ ;;; Which channels on the socket to shut down.
438
+ (param $how $sdflags)
439
+ (result $error (expected (error $errno)))
440
+ )
441
+ )
data/data/kobako.wasm CHANGED
Binary file
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "kobako"
3
- version = "0.29.0"
3
+ version = "0.30.0"
4
4
  edition = "2021"
5
5
  authors = ["Aotokitsuruya <contact@aotoki.me>"]
6
6
  license = "Apache-2.0"
@@ -21,7 +21,7 @@ use kobako_transport::envelope::{Call, Fault, FaultKind, Reply, Target, YieldRep
21
21
 
22
22
  /// The names each side of this seam branches on — one per Reply and
23
23
  /// Yield Reply arm. Neutral Symbols rather than the envelope's tag bytes,
24
- /// the same way `Snapshot#outcome` names its arms: the core envelope is
24
+ /// the same way `Snapshot#outcome` names its arms: the Envelope is
25
25
  /// this side's to read, so no byte value of it reaches Ruby.
26
26
  const ARM_OK: &str = "ok";
27
27
  const ARM_FAULT: &str = "fault";
@@ -58,7 +58,7 @@ pub(super) fn trap_class(ruby: &Ruby, trap: &Trap) -> ExceptionClass {
58
58
  }
59
59
  }
60
60
 
61
- /// The verb prefix is left to `Kobako::Context#invoke!`.
61
+ /// The verb prefix is left to `Kobako::Context#invoke`.
62
62
  pub(super) fn trap_to_magnus(ruby: &Ruby, trap: Trap) -> MagnusError {
63
63
  MagnusError::new(trap_class(ruby, &trap), trap.to_string())
64
64
  }
@@ -1,8 +1,8 @@
1
1
  //! What a Host App's callback raises that is not a `StandardError`:
2
- //! `Interrupt`, `exit`, `throw`, `Timeout`. These belong to the host, so
3
- //! the callback holds one here instead of answering the guest with it,
4
- //! the invocation ends at its next host call, and the run raises it again
5
- //! once control is back in Ruby.
2
+ //! `Interrupt`, `exit`, `throw`, `Timeout`, and any interrupt delivered to the
3
+ //! Thread while a run gives up the GVL. These belong to the host, so one is held
4
+ //! here instead of answering the guest with it, the invocation ends at its next
5
+ //! host call, and the run raises it again once control is back in Ruby.
6
6
  //!
7
7
  //! The slot is per thread, as each invocation runs on its caller's
8
8
  //! thread. A nested invocation takes what its own run held before the
@@ -14,39 +14,53 @@ use magnus::value::BoxValue;
14
14
  use magnus::{Error as MagnusError, Ruby, Value};
15
15
 
16
16
  thread_local! {
17
- static HELD: RefCell<Option<Held>> = const { RefCell::new(None) };
17
+ static ESCAPE: RefCell<Option<Escape>> = const { RefCell::new(None) };
18
18
  }
19
19
 
20
20
  /// The error and, when it carries one, its exception kept rooted while
21
21
  /// the guest finishes unwinding.
22
- struct Held {
22
+ struct Escape {
23
23
  error: MagnusError,
24
24
  _rooted: Option<BoxValue<Value>>,
25
25
  }
26
26
 
27
27
  /// Hold `error` unless it is a `StandardError`, which comes back for the
28
- /// callback to answer the guest with; the first one held wins.
28
+ /// callback to answer the guest with.
29
29
  pub(super) fn hold(ruby: &Ruby, error: MagnusError) -> Result<(), MagnusError> {
30
30
  if error.is_kind_of(ruby.exception_standard_error()) {
31
31
  return Err(error);
32
32
  }
33
- HELD.with(|held| {
34
- held.borrow_mut().get_or_insert_with(|| Held {
33
+ keep(error);
34
+ Ok(())
35
+ }
36
+
37
+ /// Run what is pending on this Thread, holding what it raises, whatever its
38
+ /// class: no callback asked for it, so no guest is answered with it.
39
+ pub(super) fn hold_interrupts() {
40
+ let ruby = Ruby::get().expect("a Thread that was not given up holds the GVL");
41
+ if let Err(error) = ruby.thread_check_ints() {
42
+ keep(error);
43
+ }
44
+ }
45
+
46
+ /// Keep `error` for the host; the first one kept wins.
47
+ fn keep(error: MagnusError) {
48
+ ESCAPE.with(|held| {
49
+ held.borrow_mut().get_or_insert_with(|| Escape {
35
50
  _rooted: error.value().map(BoxValue::new),
36
51
  error,
37
52
  });
38
53
  });
39
- Ok(())
40
54
  }
41
55
 
42
- /// Whether a callback on this thread holds an error for the host.
56
+ /// Whether this thread holds an error for the host.
43
57
  pub(super) fn pending() -> bool {
44
- HELD.with(|held| held.borrow().is_some())
58
+ ESCAPE.with(|held| held.borrow().is_some())
45
59
  }
46
60
 
47
- /// Raise what a callback held, once the run is back in Ruby.
61
+ /// Raise what was held, once the run is back in Ruby.
48
62
  pub(super) fn resume() -> Result<(), MagnusError> {
49
- match HELD.with(|held| held.borrow_mut().take()) {
63
+ match ESCAPE.with(|held| held.borrow_mut().take()) {
50
64
  Some(held) => Err(held.error),
51
65
  None => Ok(()),
52
66
  }
@@ -5,13 +5,12 @@
5
5
  use std::sync::Arc;
6
6
 
7
7
  use magnus::value::{Opaque, ReprValue};
8
- use magnus::{prelude::*, Error as MagnusError, RArray, RString, Ruby, Value};
8
+ use magnus::{prelude::*, Error as MagnusError, RArray, RString, Ruby, Symbol, Value};
9
9
 
10
- use kobako_runtime::filesystem::Access;
11
10
  use kobako_runtime::grant::Grant;
12
- use kobako_runtime::mount::{Mount, Policy};
11
+ use kobako_runtime::mount::{Access, Mount, Policy};
13
12
 
14
- use super::{to_access, to_filesystem};
13
+ use super::to_filesystem;
15
14
  use crate::runtime::pinned_value::PinnedValue;
16
15
  use crate::runtime::{escape, gvl};
17
16
 
@@ -35,7 +34,24 @@ fn to_mount(at: Value, access: Value, filesystem: Value) -> Result<Mount, Magnus
35
34
  .map_err(|err| MagnusError::new(ruby.exception_arg_error(), err.to_string()))
36
35
  }
37
36
 
38
- /// A mount's block, asked in its access's place. A block raising a
37
+ fn to_access(access: Value) -> Result<Access, MagnusError> {
38
+ let name = Symbol::from_value(access)
39
+ .map(|symbol| symbol.name())
40
+ .transpose()?;
41
+ match name.as_deref() {
42
+ Some("read") => Ok(Access::Read),
43
+ Some("read_write") => Ok(Access::ReadWrite),
44
+ _ => Err(MagnusError::new(
45
+ Ruby::get().expect("Ruby thread").exception_arg_error(),
46
+ format!(
47
+ "access must be :read or :read_write, got {}",
48
+ access.inspect()
49
+ ),
50
+ )),
51
+ }
52
+ }
53
+
54
+ /// A mount's block, asked what its access allows. A block raising a
39
55
  /// StandardError refuses, so the guest's open fails and its script goes
40
56
  /// on; anything else it raises is held for the host.
41
57
  struct RubyPolicy {