@grain/stdlib 0.5.13 → 0.6.1
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.
- package/CHANGELOG.md +201 -0
- package/LICENSE +1 -1
- package/README.md +25 -2
- package/array.gr +1512 -199
- package/array.md +2032 -94
- package/bigint.gr +239 -140
- package/bigint.md +450 -106
- package/buffer.gr +595 -102
- package/buffer.md +903 -145
- package/bytes.gr +401 -110
- package/bytes.md +551 -63
- package/char.gr +228 -49
- package/char.md +373 -7
- package/exception.gr +26 -12
- package/exception.md +29 -5
- package/float32.gr +130 -109
- package/float32.md +185 -57
- package/float64.gr +112 -99
- package/float64.md +185 -57
- package/hash.gr +62 -40
- package/hash.md +27 -3
- package/int16.gr +430 -0
- package/int16.md +618 -0
- package/int32.gr +200 -269
- package/int32.md +254 -289
- package/int64.gr +142 -225
- package/int64.md +254 -289
- package/int8.gr +511 -0
- package/int8.md +786 -0
- package/json.gr +2071 -0
- package/json.md +646 -0
- package/list.gr +120 -68
- package/list.md +125 -80
- package/map.gr +560 -57
- package/map.md +672 -56
- package/marshal.gr +239 -227
- package/marshal.md +36 -4
- package/number.gr +626 -676
- package/number.md +738 -153
- package/option.gr +33 -35
- package/option.md +58 -42
- package/package.json +2 -2
- package/path.gr +148 -187
- package/path.md +47 -96
- package/pervasives.gr +75 -416
- package/pervasives.md +85 -180
- package/priorityqueue.gr +433 -74
- package/priorityqueue.md +422 -54
- package/queue.gr +362 -80
- package/queue.md +433 -38
- package/random.gr +67 -75
- package/random.md +68 -40
- package/range.gr +135 -63
- package/range.md +198 -43
- package/rational.gr +284 -0
- package/rational.md +545 -0
- package/regex.gr +933 -1066
- package/regex.md +59 -60
- package/result.gr +23 -25
- package/result.md +54 -39
- package/runtime/atof/common.gr +78 -82
- package/runtime/atof/common.md +22 -10
- package/runtime/atof/decimal.gr +102 -127
- package/runtime/atof/decimal.md +28 -7
- package/runtime/atof/lemire.gr +56 -71
- package/runtime/atof/lemire.md +9 -1
- package/runtime/atof/parse.gr +83 -110
- package/runtime/atof/parse.md +12 -2
- package/runtime/atof/slow.gr +28 -35
- package/runtime/atof/slow.md +9 -1
- package/runtime/atof/table.gr +19 -18
- package/runtime/atof/table.md +10 -2
- package/runtime/atoi/parse.gr +153 -136
- package/runtime/atoi/parse.md +50 -1
- package/runtime/bigint.gr +410 -517
- package/runtime/bigint.md +71 -57
- package/runtime/compare.gr +176 -85
- package/runtime/compare.md +31 -1
- package/runtime/dataStructures.gr +144 -32
- package/runtime/dataStructures.md +267 -31
- package/runtime/debugPrint.gr +34 -15
- package/runtime/debugPrint.md +37 -5
- package/runtime/equal.gr +53 -52
- package/runtime/equal.md +30 -1
- package/runtime/exception.gr +38 -47
- package/runtime/exception.md +10 -8
- package/runtime/gc.gr +23 -152
- package/runtime/gc.md +13 -17
- package/runtime/malloc.gr +31 -31
- package/runtime/malloc.md +11 -3
- package/runtime/numberUtils.gr +193 -174
- package/runtime/numberUtils.md +29 -9
- package/runtime/numbers.gr +1695 -1021
- package/runtime/numbers.md +1098 -134
- package/runtime/string.gr +543 -245
- package/runtime/string.md +76 -6
- package/runtime/unsafe/constants.gr +30 -13
- package/runtime/unsafe/constants.md +80 -0
- package/runtime/unsafe/conv.gr +55 -28
- package/runtime/unsafe/conv.md +41 -9
- package/runtime/unsafe/memory.gr +10 -30
- package/runtime/unsafe/memory.md +15 -19
- package/runtime/unsafe/tags.gr +37 -21
- package/runtime/unsafe/tags.md +88 -8
- package/runtime/unsafe/wasmf32.gr +30 -36
- package/runtime/unsafe/wasmf32.md +64 -56
- package/runtime/unsafe/wasmf64.gr +30 -36
- package/runtime/unsafe/wasmf64.md +64 -56
- package/runtime/unsafe/wasmi32.gr +49 -66
- package/runtime/unsafe/wasmi32.md +102 -94
- package/runtime/unsafe/wasmi64.gr +52 -79
- package/runtime/unsafe/wasmi64.md +108 -100
- package/runtime/utils/printing.gr +13 -15
- package/runtime/utils/printing.md +11 -3
- package/runtime/wasi.gr +294 -295
- package/runtime/wasi.md +62 -42
- package/set.gr +574 -64
- package/set.md +634 -54
- package/stack.gr +181 -64
- package/stack.md +271 -42
- package/string.gr +453 -533
- package/string.md +241 -151
- package/uint16.gr +369 -0
- package/uint16.md +585 -0
- package/uint32.gr +470 -0
- package/uint32.md +737 -0
- package/uint64.gr +471 -0
- package/uint64.md +737 -0
- package/uint8.gr +369 -0
- package/uint8.md +585 -0
- package/uri.gr +1093 -0
- package/uri.md +477 -0
- package/{sys → wasi}/file.gr +914 -500
- package/{sys → wasi}/file.md +454 -50
- package/wasi/process.gr +292 -0
- package/{sys → wasi}/process.md +164 -6
- package/wasi/random.gr +77 -0
- package/wasi/random.md +80 -0
- package/{sys → wasi}/time.gr +15 -22
- package/{sys → wasi}/time.md +5 -5
- package/immutablearray.gr +0 -929
- package/immutablearray.md +0 -1038
- package/immutablemap.gr +0 -493
- package/immutablemap.md +0 -479
- package/immutablepriorityqueue.gr +0 -360
- package/immutablepriorityqueue.md +0 -291
- package/immutableset.gr +0 -498
- package/immutableset.md +0 -449
- package/runtime/debug.gr +0 -2
- package/runtime/debug.md +0 -6
- package/runtime/unsafe/errors.gr +0 -36
- package/runtime/unsafe/errors.md +0 -204
- package/sys/process.gr +0 -254
- package/sys/random.gr +0 -79
- package/sys/random.md +0 -66
package/{sys → wasi}/file.gr
RENAMED
|
@@ -1,56 +1,60 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Utilities for accessing the filesystem & working with files.
|
|
3
3
|
*
|
|
4
4
|
* Many of the functions in this module are not intended to be used directly, but rather for other libraries to be built on top of them.
|
|
5
5
|
*
|
|
6
|
-
* @example
|
|
6
|
+
* @example from "wasi/file" include File
|
|
7
7
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
8
|
+
module File
|
|
9
|
+
|
|
10
|
+
from "runtime/unsafe/wasmi32" include WasmI32
|
|
11
|
+
use WasmI32.{
|
|
12
|
+
(+),
|
|
13
|
+
(-),
|
|
14
|
+
(*),
|
|
15
|
+
(<<),
|
|
16
|
+
(>>),
|
|
17
|
+
(>>>),
|
|
18
|
+
(==),
|
|
19
|
+
(!=),
|
|
20
|
+
(<),
|
|
21
|
+
(<=),
|
|
22
|
+
(>),
|
|
23
|
+
(>=),
|
|
24
|
+
(&),
|
|
25
|
+
(|),
|
|
26
|
+
}
|
|
27
|
+
from "runtime/unsafe/wasmi64" include WasmI64
|
|
28
|
+
from "runtime/wasi" include Wasi
|
|
29
|
+
from "runtime/unsafe/memory" include Memory
|
|
30
|
+
from "runtime/dataStructures" include DataStructures
|
|
31
|
+
use DataStructures.{
|
|
29
32
|
tagSimpleNumber,
|
|
33
|
+
untagSimpleNumber,
|
|
30
34
|
allocateArray,
|
|
35
|
+
allocateBytes,
|
|
31
36
|
allocateString,
|
|
37
|
+
newInt32,
|
|
32
38
|
newInt64,
|
|
33
39
|
allocateInt64,
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
import List from "list"
|
|
40
|
+
}
|
|
37
41
|
|
|
38
|
-
|
|
39
|
-
* @section Types: Type declarations included in the File module.
|
|
40
|
-
*/
|
|
42
|
+
from "list" include List
|
|
41
43
|
|
|
42
44
|
/**
|
|
43
45
|
* Represents a handle to an open file on the system.
|
|
44
46
|
*/
|
|
45
|
-
|
|
47
|
+
provide enum FileDescriptor {
|
|
46
48
|
FileDescriptor(Number),
|
|
47
49
|
}
|
|
48
50
|
|
|
49
51
|
/**
|
|
50
52
|
* Flags that determine how paths should be resolved when looking up a file or directory.
|
|
51
53
|
*/
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
provide enum LookupFlag {
|
|
55
|
+
/**
|
|
56
|
+
* Follow symlinks
|
|
57
|
+
*/
|
|
54
58
|
SymlinkFollow,
|
|
55
59
|
}
|
|
56
60
|
|
|
@@ -75,14 +79,22 @@ let combineLookupFlags = dirflags => {
|
|
|
75
79
|
/**
|
|
76
80
|
* Flags that determine how a file or directory should be opened.
|
|
77
81
|
*/
|
|
78
|
-
|
|
79
|
-
|
|
82
|
+
provide enum OpenFlag {
|
|
83
|
+
/**
|
|
84
|
+
* Create file if it does not exist.
|
|
85
|
+
*/
|
|
80
86
|
Create,
|
|
81
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Fail if not a directory.
|
|
89
|
+
*/
|
|
82
90
|
Directory,
|
|
83
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Fail if file already exists.
|
|
93
|
+
*/
|
|
84
94
|
Exclusive,
|
|
85
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Truncate file to size 0.
|
|
97
|
+
*/
|
|
86
98
|
Truncate,
|
|
87
99
|
}
|
|
88
100
|
|
|
@@ -111,76 +123,134 @@ let combineOpenFlags = dirflags => {
|
|
|
111
123
|
* Flags that determine which rights a `FileDescriptor` should have
|
|
112
124
|
* and which rights new `FileDescriptor`s should inherit from it.
|
|
113
125
|
*/
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
126
|
+
provide enum Rights {
|
|
127
|
+
/**
|
|
128
|
+
* The right to invoke `fdDatasync`.
|
|
129
|
+
* If `PathOpen` is set, includes the right to invoke
|
|
130
|
+
* `pathOpen` with `FdFlag::Dsync`.
|
|
131
|
+
*/
|
|
118
132
|
FdDatasync,
|
|
119
|
-
|
|
120
|
-
|
|
133
|
+
/**
|
|
134
|
+
* The right to invoke `fdRead`.
|
|
135
|
+
* If `Rights::FdSeek` is set, includes the right to invoke `fdPread`.
|
|
136
|
+
*/
|
|
121
137
|
FdRead,
|
|
122
|
-
|
|
138
|
+
/**
|
|
139
|
+
* The right to invoke `fdSeek`. This flag implies `Rights::FdTell`.
|
|
140
|
+
*/
|
|
123
141
|
FdSeek,
|
|
124
|
-
|
|
142
|
+
/**
|
|
143
|
+
* The right to invoke `fdSetFlags`.
|
|
144
|
+
*/
|
|
125
145
|
FdSetFlags,
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
146
|
+
/**
|
|
147
|
+
* The right to invoke `fdSync`.
|
|
148
|
+
* If `PathOpen` is set, includes the right to invoke
|
|
149
|
+
* `pathOpen` with `FdFlag::Rsync` and `FdFlag::Dsync`.
|
|
150
|
+
*/
|
|
129
151
|
FdSync,
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
152
|
+
/**
|
|
153
|
+
* The right to invoke `fdSeek` in such a way that the file offset
|
|
154
|
+
* remains unaltered (i.e., `Whence::Current` with offset zero), or to
|
|
155
|
+
* invoke `fdTell`.
|
|
156
|
+
*/
|
|
133
157
|
FdTell,
|
|
134
|
-
|
|
135
|
-
|
|
158
|
+
/**
|
|
159
|
+
* The right to invoke `fdWrite`.
|
|
160
|
+
* If `Rights::FdSeek` is set, includes the right to invoke `fdPwrite`.
|
|
161
|
+
*/
|
|
136
162
|
FdWrite,
|
|
137
|
-
|
|
163
|
+
/**
|
|
164
|
+
* The right to invoke `fdAdvise`.
|
|
165
|
+
*/
|
|
138
166
|
FdAdvise,
|
|
139
|
-
|
|
167
|
+
/**
|
|
168
|
+
* The right to invoke `fdAllocate`.
|
|
169
|
+
*/
|
|
140
170
|
FdAllocate,
|
|
141
|
-
|
|
171
|
+
/**
|
|
172
|
+
* The right to invoke `pathCreateDirectory`.
|
|
173
|
+
*/
|
|
142
174
|
PathCreateDirectory,
|
|
143
|
-
|
|
175
|
+
/**
|
|
176
|
+
* If `PathOpen` is set, the right to invoke `pathOpen` with `OpenFlag::Create`.
|
|
177
|
+
*/
|
|
144
178
|
PathCreateFile,
|
|
145
|
-
|
|
146
|
-
|
|
179
|
+
/**
|
|
180
|
+
* The right to invoke `pathLink` with the file descriptor as the
|
|
181
|
+
* source directory.
|
|
182
|
+
*/
|
|
147
183
|
PathLinkSource,
|
|
148
|
-
|
|
149
|
-
|
|
184
|
+
/**
|
|
185
|
+
* The right to invoke `pathLink` with the file descriptor as the
|
|
186
|
+
* target directory.
|
|
187
|
+
*/
|
|
150
188
|
PathLinkTarget,
|
|
151
|
-
|
|
189
|
+
/**
|
|
190
|
+
* The right to invoke `pathOpen`.
|
|
191
|
+
*/
|
|
152
192
|
PathOpen,
|
|
153
|
-
|
|
193
|
+
/**
|
|
194
|
+
* The right to invoke `fdReaddir`.
|
|
195
|
+
*/
|
|
154
196
|
FdReaddir,
|
|
155
|
-
|
|
197
|
+
/**
|
|
198
|
+
* The right to invoke `pathReadlink`.
|
|
199
|
+
*/
|
|
156
200
|
PathReadlink,
|
|
157
|
-
|
|
201
|
+
/**
|
|
202
|
+
* The right to invoke `pathRename` with the file descriptor as the source directory.
|
|
203
|
+
*/
|
|
158
204
|
PathRenameSource,
|
|
159
|
-
|
|
205
|
+
/**
|
|
206
|
+
* The right to invoke `pathRename` with the file descriptor as the target directory.
|
|
207
|
+
*/
|
|
160
208
|
PathRenameTarget,
|
|
161
|
-
|
|
209
|
+
/**
|
|
210
|
+
* The right to invoke `pathFilestats`.
|
|
211
|
+
*/
|
|
162
212
|
PathFilestats,
|
|
163
|
-
|
|
164
|
-
|
|
213
|
+
/**
|
|
214
|
+
* The right to change a file's size (there's no `pathSetSize`).
|
|
215
|
+
* If `PathOpen` is set, includes the right to invoke `pathOpen` with `OpenFlag::Truncate`.
|
|
216
|
+
*/
|
|
165
217
|
PathSetSize,
|
|
166
|
-
|
|
218
|
+
/**
|
|
219
|
+
* The right to invoke `pathSetAccessTime`, `pathSetAccessTimeNow`, `pathSetModifiedTime`, or `pathSetModifiedTimeNow`.
|
|
220
|
+
*/
|
|
167
221
|
PathSetTimes,
|
|
168
|
-
|
|
222
|
+
/**
|
|
223
|
+
* The right to invoke `fdFilestats`.
|
|
224
|
+
*/
|
|
169
225
|
FdFilestats,
|
|
170
|
-
|
|
226
|
+
/**
|
|
227
|
+
* The right to invoke `fdSetSize`.
|
|
228
|
+
*/
|
|
171
229
|
FdSetSize,
|
|
172
|
-
|
|
230
|
+
/**
|
|
231
|
+
* The right to invoke `fdSetAccessTime`, `fdSetAccessTimeNow`, `fdSetModifiedTime`, or `fdSetModifiedTimeNow`.
|
|
232
|
+
*/
|
|
173
233
|
FdSetTimes,
|
|
174
|
-
|
|
234
|
+
/**
|
|
235
|
+
* The right to invoke `pathSymlink`.
|
|
236
|
+
*/
|
|
175
237
|
PathSymlink,
|
|
176
|
-
|
|
238
|
+
/**
|
|
239
|
+
* The right to invoke `pathRemoveDirectory`.
|
|
240
|
+
*/
|
|
177
241
|
PathRemoveDirectory,
|
|
178
|
-
|
|
242
|
+
/**
|
|
243
|
+
* The right to invoke `pathUnlinkFile`.
|
|
244
|
+
*/
|
|
179
245
|
PathUnlinkFile,
|
|
180
|
-
|
|
181
|
-
|
|
246
|
+
/**
|
|
247
|
+
* If `Rights::FdRead` is set, includes the right to invoke `pollOneoff` (not yet implemented) to subscribe to `EventType::FdRead`.
|
|
248
|
+
* If `Rights::FdWrite` is set, includes the right to invoke `pollOneoff` (not yet implemented) to subscribe to `EventType::FdWrite`.
|
|
249
|
+
*/
|
|
182
250
|
PollFdReadwrite,
|
|
183
|
-
|
|
251
|
+
/**
|
|
252
|
+
* The right to invoke `sockShutdown` (not yet implemented).
|
|
253
|
+
*/
|
|
184
254
|
SockShutdown,
|
|
185
255
|
}
|
|
186
256
|
|
|
@@ -248,6 +318,7 @@ let _RIGHT_SOCK_SHUTDOWN = 268435456N
|
|
|
248
318
|
// TODO(#775): This has specific ordering requirements because of ambiguous type inference
|
|
249
319
|
@unsafe
|
|
250
320
|
let rec combineRightsHelp = (acc, dirflags) => {
|
|
321
|
+
use WasmI64.{ (|) }
|
|
251
322
|
match (dirflags) {
|
|
252
323
|
[] => acc,
|
|
253
324
|
[hd, ...tl] => {
|
|
@@ -288,7 +359,7 @@ let rec combineRightsHelp = (acc, dirflags) => {
|
|
|
288
359
|
0N
|
|
289
360
|
},
|
|
290
361
|
}
|
|
291
|
-
combineRightsHelp(
|
|
362
|
+
combineRightsHelp(flag | acc, tl)
|
|
292
363
|
},
|
|
293
364
|
}
|
|
294
365
|
}
|
|
@@ -300,14 +371,22 @@ let combineRights = dirflags => {
|
|
|
300
371
|
/**
|
|
301
372
|
* Flags that determine the mode(s) that a `FileDescriptor` operates in.
|
|
302
373
|
*/
|
|
303
|
-
|
|
304
|
-
|
|
374
|
+
provide enum FdFlag {
|
|
375
|
+
/**
|
|
376
|
+
* Append mode: Data written to the file is always appended to the file's end.
|
|
377
|
+
*/
|
|
305
378
|
Append,
|
|
306
|
-
|
|
379
|
+
/**
|
|
380
|
+
* Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized.
|
|
381
|
+
*/
|
|
307
382
|
Dsync,
|
|
308
|
-
|
|
383
|
+
/**
|
|
384
|
+
* Non-blocking mode.
|
|
385
|
+
*/
|
|
309
386
|
Nonblock,
|
|
310
|
-
|
|
387
|
+
/**
|
|
388
|
+
* Synchronized read I/O operations.
|
|
389
|
+
*/
|
|
311
390
|
Rsync,
|
|
312
391
|
// Write according to synchronized I/O file integrity completion. In
|
|
313
392
|
// addition to synchronizing the data stored in the file, the implementation
|
|
@@ -340,22 +419,38 @@ let combineFdFlags = dirflags => {
|
|
|
340
419
|
/**
|
|
341
420
|
* The type of file a `FileDescriptor` refers to.
|
|
342
421
|
*/
|
|
343
|
-
|
|
344
|
-
|
|
422
|
+
provide enum Filetype {
|
|
423
|
+
/**
|
|
424
|
+
* The type of the file descriptor or file is unknown or is different from any of the other types specified.
|
|
425
|
+
*/
|
|
345
426
|
Unknown,
|
|
346
|
-
|
|
427
|
+
/**
|
|
428
|
+
* The file descriptor or file refers to a block device inode.
|
|
429
|
+
*/
|
|
347
430
|
BlockDevice,
|
|
348
|
-
|
|
431
|
+
/**
|
|
432
|
+
* The file descriptor or file refers to a character device inode.
|
|
433
|
+
*/
|
|
349
434
|
CharacterDevice,
|
|
350
|
-
|
|
435
|
+
/**
|
|
436
|
+
* The file descriptor or file refers to a directory inode.
|
|
437
|
+
*/
|
|
351
438
|
Directory,
|
|
352
|
-
|
|
439
|
+
/**
|
|
440
|
+
* The file descriptor or file refers to a regular file inode.
|
|
441
|
+
*/
|
|
353
442
|
RegularFile,
|
|
354
|
-
|
|
443
|
+
/**
|
|
444
|
+
* The file descriptor or file refers to a datagram socket.
|
|
445
|
+
*/
|
|
355
446
|
SocketDatagram,
|
|
356
|
-
|
|
447
|
+
/**
|
|
448
|
+
* The file descriptor or file refers to a byte-stream socket.
|
|
449
|
+
*/
|
|
357
450
|
SocketStream,
|
|
358
|
-
|
|
451
|
+
/**
|
|
452
|
+
* The file refers to a symbolic link inode.
|
|
453
|
+
*/
|
|
359
454
|
SymbolicLink,
|
|
360
455
|
}
|
|
361
456
|
|
|
@@ -378,19 +473,25 @@ let filetypeFromNumber = filetype => {
|
|
|
378
473
|
/**
|
|
379
474
|
* Flags that determine where seeking should begin in a file.
|
|
380
475
|
*/
|
|
381
|
-
|
|
382
|
-
|
|
476
|
+
provide enum Whence {
|
|
477
|
+
/**
|
|
478
|
+
* Seek relative to start-of-file.
|
|
479
|
+
*/
|
|
383
480
|
Set,
|
|
384
|
-
|
|
481
|
+
/**
|
|
482
|
+
* Seek relative to current position.
|
|
483
|
+
*/
|
|
385
484
|
Current,
|
|
386
|
-
|
|
485
|
+
/**
|
|
486
|
+
* Seek relative to end-of-file.
|
|
487
|
+
*/
|
|
387
488
|
End,
|
|
388
489
|
}
|
|
389
490
|
|
|
390
491
|
/**
|
|
391
492
|
* Information about a `FileDescriptor`.
|
|
392
493
|
*/
|
|
393
|
-
|
|
494
|
+
provide record Stats {
|
|
394
495
|
filetype: Filetype,
|
|
395
496
|
flags: List<FdFlag>,
|
|
396
497
|
rights: List<Rights>,
|
|
@@ -400,7 +501,7 @@ export record Stats {
|
|
|
400
501
|
/**
|
|
401
502
|
* Information about the file that a `FileDescriptor` refers to.
|
|
402
503
|
*/
|
|
403
|
-
|
|
504
|
+
provide record Filestats {
|
|
404
505
|
device: Int64,
|
|
405
506
|
inode: Int64,
|
|
406
507
|
filetype: Filetype,
|
|
@@ -414,32 +515,31 @@ export record Filestats {
|
|
|
414
515
|
/**
|
|
415
516
|
* An entry in a directory.
|
|
416
517
|
*/
|
|
417
|
-
|
|
518
|
+
provide record DirectoryEntry {
|
|
418
519
|
inode: Int64,
|
|
419
520
|
filetype: Filetype,
|
|
420
521
|
path: String,
|
|
421
522
|
}
|
|
422
523
|
|
|
423
524
|
/**
|
|
424
|
-
*
|
|
525
|
+
* Information about a preopened directory
|
|
425
526
|
*/
|
|
527
|
+
provide enum Prestat {
|
|
528
|
+
Dir{ prefix: String, fd: FileDescriptor },
|
|
529
|
+
}
|
|
426
530
|
|
|
427
531
|
/**
|
|
428
532
|
* The `FileDescriptor` for `stdin`.
|
|
429
533
|
*/
|
|
430
|
-
|
|
534
|
+
provide let stdin = FileDescriptor(0)
|
|
431
535
|
/**
|
|
432
536
|
* The `FileDescriptor` for `stdout`.
|
|
433
537
|
*/
|
|
434
|
-
|
|
538
|
+
provide let stdout = FileDescriptor(1)
|
|
435
539
|
/**
|
|
436
540
|
* The `FileDescriptor` for `stderr`.
|
|
437
541
|
*/
|
|
438
|
-
|
|
439
|
-
/**
|
|
440
|
-
* The `FileDescriptor` for the current working directory of the process.
|
|
441
|
-
*/
|
|
442
|
-
export let pwdfd = FileDescriptor(3)
|
|
542
|
+
provide let stderr = FileDescriptor(2)
|
|
443
543
|
|
|
444
544
|
/**
|
|
445
545
|
* Open a file or directory.
|
|
@@ -454,20 +554,21 @@ export let pwdfd = FileDescriptor(3)
|
|
|
454
554
|
* @returns `Ok(fd)` of the opened file or directory if successful or `Err(exception)` otherwise
|
|
455
555
|
*/
|
|
456
556
|
@unsafe
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
) => {
|
|
557
|
+
provide let pathOpen = (
|
|
558
|
+
dirFd: FileDescriptor,
|
|
559
|
+
dirFlags: List<LookupFlag>,
|
|
560
|
+
path: String,
|
|
561
|
+
openFlags: List<OpenFlag>,
|
|
562
|
+
rights: List<Rights>,
|
|
563
|
+
rightsInheriting: List<Rights>,
|
|
564
|
+
flags: List<FdFlag>,
|
|
565
|
+
) => {
|
|
467
566
|
let dirFdArg = dirFd
|
|
468
567
|
let pathArg = path
|
|
469
568
|
let rightsInheritingArg = rightsInheriting
|
|
470
|
-
let dirFd = match (dirFd) {
|
|
569
|
+
let dirFd = match (dirFd) {
|
|
570
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
571
|
+
}
|
|
471
572
|
|
|
472
573
|
let combinedDirFlags = combineLookupFlags(dirFlags)
|
|
473
574
|
|
|
@@ -495,16 +596,15 @@ export let pathOpen =
|
|
|
495
596
|
combinedFsFlags,
|
|
496
597
|
newFd
|
|
497
598
|
)
|
|
498
|
-
if (err != Wasi._ESUCCESS) {
|
|
499
|
-
Memory.free(newFd)
|
|
500
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
501
|
-
} else {
|
|
502
|
-
let fd = FileDescriptor(tagSimpleNumber(WasmI32.load(newFd, 0n)))
|
|
503
599
|
|
|
600
|
+
if (err != Wasi._ESUCCESS) {
|
|
504
601
|
Memory.free(newFd)
|
|
505
|
-
|
|
506
|
-
Ok(fd)
|
|
602
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
507
603
|
}
|
|
604
|
+
|
|
605
|
+
let fd = FileDescriptor(tagSimpleNumber(WasmI32.load(newFd, 0n)))
|
|
606
|
+
Memory.free(newFd)
|
|
607
|
+
return Ok(fd)
|
|
508
608
|
}
|
|
509
609
|
|
|
510
610
|
/**
|
|
@@ -515,14 +615,16 @@ export let pathOpen =
|
|
|
515
615
|
* @returns `Ok((contents, numBytes))` of bytes read and the number of bytes read if successful or `Err(exception)` otherwise
|
|
516
616
|
*/
|
|
517
617
|
@unsafe
|
|
518
|
-
|
|
618
|
+
provide let fdRead = (fd: FileDescriptor, size: Number) => {
|
|
519
619
|
let fdArg = fd
|
|
520
|
-
let fd = match (fd) {
|
|
620
|
+
let fd = match (fd) {
|
|
621
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
622
|
+
}
|
|
521
623
|
|
|
522
624
|
let n = WasmI32.fromGrain(size) >> 1n
|
|
523
625
|
|
|
524
626
|
let iovs = Memory.malloc(3n * 4n)
|
|
525
|
-
let strPtr =
|
|
627
|
+
let strPtr = allocateBytes(n)
|
|
526
628
|
|
|
527
629
|
WasmI32.store(iovs, strPtr + 2n * 4n, 0n)
|
|
528
630
|
WasmI32.store(iovs, n, 4n)
|
|
@@ -533,16 +635,13 @@ export let fdRead = (fd: FileDescriptor, size: Number) => {
|
|
|
533
635
|
if (err != Wasi._ESUCCESS) {
|
|
534
636
|
Memory.free(iovs)
|
|
535
637
|
Memory.free(strPtr)
|
|
536
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
537
|
-
} else {
|
|
538
|
-
nread = WasmI32.load(nread, 0n)
|
|
539
|
-
|
|
540
|
-
WasmI32.store(strPtr, nread, 4n)
|
|
541
|
-
|
|
542
|
-
Memory.free(iovs)
|
|
543
|
-
|
|
544
|
-
Ok((WasmI32.toGrain(strPtr): String, tagSimpleNumber(nread)))
|
|
638
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
545
639
|
}
|
|
640
|
+
|
|
641
|
+
nread = WasmI32.load(nread, 0n)
|
|
642
|
+
WasmI32.store(strPtr, nread, 4n)
|
|
643
|
+
Memory.free(iovs)
|
|
644
|
+
return Ok((WasmI32.toGrain(strPtr): Bytes, tagSimpleNumber(nread)))
|
|
546
645
|
}
|
|
547
646
|
|
|
548
647
|
/**
|
|
@@ -554,17 +653,19 @@ export let fdRead = (fd: FileDescriptor, size: Number) => {
|
|
|
554
653
|
* @returns `Ok((contents, numBytes))` of bytes read and the number of bytes read if successful or `Err(exception)` otherwise
|
|
555
654
|
*/
|
|
556
655
|
@unsafe
|
|
557
|
-
|
|
656
|
+
provide let fdPread = (fd: FileDescriptor, offset: Int64, size: Number) => {
|
|
558
657
|
let fdArg = fd
|
|
559
658
|
let offsetArg = offset
|
|
560
|
-
let fd = match (fd) {
|
|
659
|
+
let fd = match (fd) {
|
|
660
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
661
|
+
}
|
|
561
662
|
|
|
562
663
|
let offset = WasmI64.load(WasmI32.fromGrain(offset), 8n)
|
|
563
664
|
|
|
564
665
|
let n = WasmI32.fromGrain(size) >> 1n
|
|
565
666
|
|
|
566
667
|
let iovs = Memory.malloc(3n * 4n)
|
|
567
|
-
let strPtr =
|
|
668
|
+
let strPtr = allocateBytes(n)
|
|
568
669
|
|
|
569
670
|
WasmI32.store(iovs, strPtr + 2n * 4n, 0n)
|
|
570
671
|
WasmI32.store(iovs, n, 4n)
|
|
@@ -575,16 +676,60 @@ export let fdPread = (fd: FileDescriptor, offset: Int64, size: Number) => {
|
|
|
575
676
|
if (err != Wasi._ESUCCESS) {
|
|
576
677
|
Memory.free(iovs)
|
|
577
678
|
Memory.free(strPtr)
|
|
578
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
579
|
-
}
|
|
580
|
-
nread = WasmI32.load(nread, 0n)
|
|
679
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
680
|
+
}
|
|
581
681
|
|
|
582
|
-
|
|
682
|
+
nread = WasmI32.load(nread, 0n)
|
|
683
|
+
WasmI32.store(strPtr, nread, 4n)
|
|
684
|
+
Memory.free(iovs)
|
|
685
|
+
return Ok((WasmI32.toGrain(strPtr): Bytes, tagSimpleNumber(nread)))
|
|
686
|
+
}
|
|
583
687
|
|
|
584
|
-
|
|
688
|
+
/**
|
|
689
|
+
* Get information about a preopened directory.
|
|
690
|
+
*
|
|
691
|
+
* @param fd: The file descriptor to check
|
|
692
|
+
* @returns `Ok(Dir{prefix, fd})` if successful or `Err(exception)` otherwise
|
|
693
|
+
*
|
|
694
|
+
* @since v0.6.0
|
|
695
|
+
*/
|
|
696
|
+
@unsafe
|
|
697
|
+
provide let fdPrestatGet = (fd: FileDescriptor) => {
|
|
698
|
+
let fdArg = fd
|
|
699
|
+
let fd = match (fd) {
|
|
700
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
let dir = Memory.malloc(8n)
|
|
704
|
+
let err = Wasi.fd_prestat_get(fd, dir)
|
|
705
|
+
if (err != Wasi._ESUCCESS) {
|
|
706
|
+
Memory.free(dir)
|
|
707
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
let prefixLen = WasmI32.load(dir, 4n)
|
|
711
|
+
Memory.free(dir)
|
|
712
|
+
|
|
713
|
+
let prefix = allocateString(prefixLen)
|
|
714
|
+
let err = Wasi.fd_prestat_dir_name(fd, prefix + 8n, prefixLen)
|
|
715
|
+
if (err != Wasi._ESUCCESS) {
|
|
716
|
+
Memory.free(prefix)
|
|
717
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
718
|
+
}
|
|
585
719
|
|
|
586
|
-
|
|
720
|
+
if (
|
|
721
|
+
prefixLen > 0n &&
|
|
722
|
+
WasmI32.eqz(WasmI32.load8U(prefix + prefixLen - 1n, 8n))
|
|
723
|
+
) {
|
|
724
|
+
// in uvwasi environments the string is null-terminated and the size is reported including it
|
|
725
|
+
// https://github.com/grain-lang/grain/issues/1818
|
|
726
|
+
WasmI32.store(prefix, prefixLen - 1n, 4n)
|
|
587
727
|
}
|
|
728
|
+
|
|
729
|
+
let prefix = WasmI32.toGrain(prefix): String
|
|
730
|
+
let fd = fdArg
|
|
731
|
+
|
|
732
|
+
return Ok(Dir{ prefix, fd })
|
|
588
733
|
}
|
|
589
734
|
|
|
590
735
|
/**
|
|
@@ -595,9 +740,11 @@ export let fdPread = (fd: FileDescriptor, offset: Int64, size: Number) => {
|
|
|
595
740
|
* @returns `Ok(numBytes)` of the number of bytes written if successful or `Err(Exception)` otherwise
|
|
596
741
|
*/
|
|
597
742
|
@unsafe
|
|
598
|
-
|
|
743
|
+
provide let fdWrite = (fd: FileDescriptor, data: Bytes) => {
|
|
599
744
|
let fdArg = fd
|
|
600
|
-
let fd = match (fd) {
|
|
745
|
+
let fd = match (fd) {
|
|
746
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
747
|
+
}
|
|
601
748
|
|
|
602
749
|
let iovs = Memory.malloc(3n * 4n)
|
|
603
750
|
let strPtr = WasmI32.fromGrain(data)
|
|
@@ -610,14 +757,12 @@ export let fdWrite = (fd: FileDescriptor, data: String) => {
|
|
|
610
757
|
let err = Wasi.fd_write(fd, iovs, 1n, nwritten)
|
|
611
758
|
if (err != Wasi._ESUCCESS) {
|
|
612
759
|
Memory.free(iovs)
|
|
613
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
614
|
-
} else {
|
|
615
|
-
nwritten = WasmI32.load(nwritten, 0n)
|
|
616
|
-
|
|
617
|
-
Memory.free(iovs)
|
|
618
|
-
|
|
619
|
-
Ok(tagSimpleNumber(nwritten))
|
|
760
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
620
761
|
}
|
|
762
|
+
|
|
763
|
+
nwritten = WasmI32.load(nwritten, 0n)
|
|
764
|
+
Memory.free(iovs)
|
|
765
|
+
return Ok(tagSimpleNumber(nwritten))
|
|
621
766
|
}
|
|
622
767
|
|
|
623
768
|
/**
|
|
@@ -629,10 +774,12 @@ export let fdWrite = (fd: FileDescriptor, data: String) => {
|
|
|
629
774
|
* @returns `Ok(numBytes)` of the number of bytes written if successful or `Err(exception)` otherwise
|
|
630
775
|
*/
|
|
631
776
|
@unsafe
|
|
632
|
-
|
|
777
|
+
provide let fdPwrite = (fd: FileDescriptor, data: Bytes, offset: Int64) => {
|
|
633
778
|
let fdArg = fd
|
|
634
779
|
let offsetArg = offset
|
|
635
|
-
let fd = match (fd) {
|
|
780
|
+
let fd = match (fd) {
|
|
781
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
782
|
+
}
|
|
636
783
|
|
|
637
784
|
let iovs = Memory.malloc(3n * 4n)
|
|
638
785
|
let strPtr = WasmI32.fromGrain(data)
|
|
@@ -647,14 +794,12 @@ export let fdPwrite = (fd: FileDescriptor, data: String, offset: Int64) => {
|
|
|
647
794
|
let err = Wasi.fd_pwrite(fd, iovs, 1n, offset, nwritten)
|
|
648
795
|
if (err != Wasi._ESUCCESS) {
|
|
649
796
|
Memory.free(iovs)
|
|
650
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
651
|
-
} else {
|
|
652
|
-
nwritten = WasmI32.load(nwritten, 0n)
|
|
653
|
-
|
|
654
|
-
Memory.free(iovs)
|
|
655
|
-
|
|
656
|
-
Ok(tagSimpleNumber(nwritten))
|
|
797
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
657
798
|
}
|
|
799
|
+
|
|
800
|
+
nwritten = WasmI32.load(nwritten, 0n)
|
|
801
|
+
Memory.free(iovs)
|
|
802
|
+
return Ok(tagSimpleNumber(nwritten))
|
|
658
803
|
}
|
|
659
804
|
|
|
660
805
|
/**
|
|
@@ -666,11 +811,13 @@ export let fdPwrite = (fd: FileDescriptor, data: String, offset: Int64) => {
|
|
|
666
811
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
667
812
|
*/
|
|
668
813
|
@unsafe
|
|
669
|
-
|
|
814
|
+
provide let fdAllocate = (fd: FileDescriptor, offset: Int64, size: Int64) => {
|
|
670
815
|
let fdArg = fd
|
|
671
816
|
let offsetArg = offset
|
|
672
817
|
let sizeArg = size
|
|
673
|
-
let fd = match (fd) {
|
|
818
|
+
let fd = match (fd) {
|
|
819
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
820
|
+
}
|
|
674
821
|
|
|
675
822
|
let offset = WasmI64.load(WasmI32.fromGrain(offset), 8n)
|
|
676
823
|
|
|
@@ -678,10 +825,10 @@ export let fdAllocate = (fd: FileDescriptor, offset: Int64, size: Int64) => {
|
|
|
678
825
|
|
|
679
826
|
let err = Wasi.fd_allocate(fd, offset, size)
|
|
680
827
|
if (err != Wasi._ESUCCESS) {
|
|
681
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
682
|
-
} else {
|
|
683
|
-
Ok(void)
|
|
828
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
684
829
|
}
|
|
830
|
+
|
|
831
|
+
return Ok(void)
|
|
685
832
|
}
|
|
686
833
|
|
|
687
834
|
/**
|
|
@@ -691,16 +838,18 @@ export let fdAllocate = (fd: FileDescriptor, offset: Int64, size: Int64) => {
|
|
|
691
838
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
692
839
|
*/
|
|
693
840
|
@unsafe
|
|
694
|
-
|
|
841
|
+
provide let fdClose = (fd: FileDescriptor) => {
|
|
695
842
|
let fdArg = fd
|
|
696
|
-
let fd = match (fd) {
|
|
843
|
+
let fd = match (fd) {
|
|
844
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
845
|
+
}
|
|
697
846
|
|
|
698
847
|
let err = Wasi.fd_close(fd)
|
|
699
848
|
if (err != Wasi._ESUCCESS) {
|
|
700
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
701
|
-
} else {
|
|
702
|
-
Ok(void)
|
|
849
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
703
850
|
}
|
|
851
|
+
|
|
852
|
+
return Ok(void)
|
|
704
853
|
}
|
|
705
854
|
|
|
706
855
|
/**
|
|
@@ -710,16 +859,18 @@ export let fdClose = (fd: FileDescriptor) => {
|
|
|
710
859
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
711
860
|
*/
|
|
712
861
|
@unsafe
|
|
713
|
-
|
|
862
|
+
provide let fdDatasync = (fd: FileDescriptor) => {
|
|
714
863
|
let fdArg = fd
|
|
715
|
-
let fd = match (fd) {
|
|
864
|
+
let fd = match (fd) {
|
|
865
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
866
|
+
}
|
|
716
867
|
|
|
717
868
|
let err = Wasi.fd_datasync(fd)
|
|
718
869
|
if (err != Wasi._ESUCCESS) {
|
|
719
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
720
|
-
} else {
|
|
721
|
-
Ok(void)
|
|
870
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
722
871
|
}
|
|
872
|
+
|
|
873
|
+
return Ok(void)
|
|
723
874
|
}
|
|
724
875
|
|
|
725
876
|
/**
|
|
@@ -729,16 +880,18 @@ export let fdDatasync = (fd: FileDescriptor) => {
|
|
|
729
880
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
730
881
|
*/
|
|
731
882
|
@unsafe
|
|
732
|
-
|
|
883
|
+
provide let fdSync = (fd: FileDescriptor) => {
|
|
733
884
|
let fdArg = fd
|
|
734
|
-
let fd = match (fd) {
|
|
885
|
+
let fd = match (fd) {
|
|
886
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
887
|
+
}
|
|
735
888
|
|
|
736
889
|
let err = Wasi.fd_sync(fd)
|
|
737
890
|
if (err != Wasi._ESUCCESS) {
|
|
738
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
739
|
-
} else {
|
|
740
|
-
Ok(void)
|
|
891
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
741
892
|
}
|
|
893
|
+
|
|
894
|
+
return Ok(void)
|
|
742
895
|
}
|
|
743
896
|
|
|
744
897
|
let orderedFdflags = [Append, Dsync, Nonblock, Rsync, Sync]
|
|
@@ -781,56 +934,53 @@ let orderedRights = [
|
|
|
781
934
|
* @returns `Ok(stats)` of the `Stats` associated with the file descriptor if successful or `Err(exception)` otherwise
|
|
782
935
|
*/
|
|
783
936
|
@unsafe
|
|
784
|
-
|
|
937
|
+
provide let fdStats = (fd: FileDescriptor) => {
|
|
785
938
|
let fdArg = fd
|
|
786
|
-
let fd = match (fd) {
|
|
939
|
+
let fd = match (fd) {
|
|
940
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
941
|
+
}
|
|
787
942
|
|
|
788
943
|
let structPtr = Memory.malloc(24n)
|
|
789
944
|
|
|
790
945
|
let err = Wasi.fd_fdstat_get(fd, structPtr)
|
|
791
946
|
if (err != Wasi._ESUCCESS) {
|
|
792
947
|
Memory.free(structPtr)
|
|
793
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
794
|
-
}
|
|
795
|
-
|
|
948
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
949
|
+
}
|
|
950
|
+
let filetype = WasmI32.load8U(structPtr, 0n)
|
|
796
951
|
|
|
797
|
-
|
|
952
|
+
let filetype = filetypeFromNumber(filetype)
|
|
798
953
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
let (&) = WasmI64.and
|
|
806
|
-
let (>) = WasmI64.gtU
|
|
807
|
-
let (<<) = WasmI64.shl
|
|
954
|
+
let flagsToWasmVal = (flag, i) => {
|
|
955
|
+
let fdflags = WasmI32.load16U(structPtr, 4n)
|
|
956
|
+
WasmI32.gtU(fdflags & 1n << (WasmI32.fromGrain(i) >> 1n), 0n)
|
|
957
|
+
}
|
|
958
|
+
let fdflagsList = List.filteri(flagsToWasmVal, orderedFdflags)
|
|
959
|
+
use WasmI64.{ (&), gtU as (>), (<<) }
|
|
808
960
|
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
961
|
+
let flagsToWasmVal = (flag, i) => {
|
|
962
|
+
let rights = WasmI64.load(structPtr, 8n)
|
|
963
|
+
(rights & 1N << WasmI64.extendI32U(WasmI32.fromGrain(i) >> 1n)) > 0N
|
|
964
|
+
}
|
|
965
|
+
let rightsList = List.filteri(flagsToWasmVal, orderedRights)
|
|
814
966
|
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
let rightsInheritingList = List.filteri(flagsToWasmVal, orderedRights)
|
|
967
|
+
let flagsToWasmVal = (flag, i) => {
|
|
968
|
+
let rightsInheriting = WasmI64.load(structPtr, 16n)
|
|
969
|
+
(rightsInheriting & 1N << WasmI64.extendI32U(WasmI32.fromGrain(i) >> 1n)) >
|
|
970
|
+
0N
|
|
971
|
+
}
|
|
972
|
+
let rightsInheritingList = List.filteri(flagsToWasmVal, orderedRights)
|
|
822
973
|
|
|
823
|
-
|
|
974
|
+
Memory.free(structPtr)
|
|
824
975
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
}
|
|
976
|
+
return Ok(
|
|
977
|
+
{
|
|
978
|
+
filetype,
|
|
979
|
+
flags: fdflagsList,
|
|
980
|
+
rights: rightsList,
|
|
981
|
+
rightsInheriting: rightsInheritingList,
|
|
982
|
+
},
|
|
983
|
+
)
|
|
834
984
|
}
|
|
835
985
|
|
|
836
986
|
/**
|
|
@@ -841,19 +991,21 @@ export let fdStats = (fd: FileDescriptor) => {
|
|
|
841
991
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
842
992
|
*/
|
|
843
993
|
@unsafe
|
|
844
|
-
|
|
994
|
+
provide let fdSetFlags = (fd: FileDescriptor, flags: List<FdFlag>) => {
|
|
845
995
|
let fdArg = fd
|
|
846
996
|
let flagsArg = flags
|
|
847
|
-
let fd = match (fd) {
|
|
997
|
+
let fd = match (fd) {
|
|
998
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
999
|
+
}
|
|
848
1000
|
|
|
849
1001
|
let flags = combineFdFlags(flags)
|
|
850
1002
|
|
|
851
1003
|
let err = Wasi.fd_fdstat_set_flags(fd, flags)
|
|
852
1004
|
if (err != Wasi._ESUCCESS) {
|
|
853
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
854
|
-
} else {
|
|
855
|
-
Ok(void)
|
|
1005
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
856
1006
|
}
|
|
1007
|
+
|
|
1008
|
+
return Ok(void)
|
|
857
1009
|
}
|
|
858
1010
|
|
|
859
1011
|
/**
|
|
@@ -865,26 +1017,27 @@ export let fdSetFlags = (fd: FileDescriptor, flags: List<FdFlag>) => {
|
|
|
865
1017
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
866
1018
|
*/
|
|
867
1019
|
@unsafe
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
) => {
|
|
1020
|
+
provide let fdSetRights = (
|
|
1021
|
+
fd: FileDescriptor,
|
|
1022
|
+
rights: List<Rights>,
|
|
1023
|
+
rightsInheriting: List<Rights>,
|
|
1024
|
+
) => {
|
|
874
1025
|
let fdArg = fd
|
|
875
1026
|
let rightsArg = rights
|
|
876
1027
|
let rightsInheritingArg = rightsInheriting
|
|
877
|
-
let fd = match (fd) {
|
|
1028
|
+
let fd = match (fd) {
|
|
1029
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1030
|
+
}
|
|
878
1031
|
|
|
879
1032
|
let rights = combineRights(rights)
|
|
880
1033
|
let rightsInheriting = combineRights(rightsInheriting)
|
|
881
1034
|
|
|
882
1035
|
let err = Wasi.fd_fdstat_set_rights(fd, rights, rightsInheriting)
|
|
883
1036
|
if (err != Wasi._ESUCCESS) {
|
|
884
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
885
|
-
} else {
|
|
886
|
-
Ok(void)
|
|
1037
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
887
1038
|
}
|
|
1039
|
+
|
|
1040
|
+
return Ok(void)
|
|
888
1041
|
}
|
|
889
1042
|
|
|
890
1043
|
/**
|
|
@@ -894,38 +1047,34 @@ export let fdSetRights =
|
|
|
894
1047
|
* @returns `Ok(info)` of the `Filestats` associated with the file descriptor if successful or `Err(exception)` otherwise
|
|
895
1048
|
*/
|
|
896
1049
|
@unsafe
|
|
897
|
-
|
|
1050
|
+
provide let fdFilestats = (fd: FileDescriptor) => {
|
|
898
1051
|
let fdArg = fd
|
|
899
|
-
let fd = match (fd) {
|
|
1052
|
+
let fd = match (fd) {
|
|
1053
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1054
|
+
}
|
|
900
1055
|
|
|
901
1056
|
let filestats = Memory.malloc(64n)
|
|
902
1057
|
|
|
903
1058
|
let err = Wasi.fd_filestat_get(fd, filestats)
|
|
904
1059
|
if (err != Wasi._ESUCCESS) {
|
|
905
1060
|
Memory.free(filestats)
|
|
906
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
907
|
-
}
|
|
908
|
-
let device = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 0n))): Int64
|
|
909
|
-
let inode = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 8n))): Int64
|
|
910
|
-
let filetype = filetypeFromNumber(WasmI32.load8U(filestats, 16n))
|
|
911
|
-
let linkcount = WasmI32.toGrain(
|
|
912
|
-
newInt64(WasmI64.load(filestats, 24n))
|
|
913
|
-
): Int64
|
|
914
|
-
let size = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 32n))): Int64
|
|
915
|
-
let accessed = WasmI32.toGrain(
|
|
916
|
-
newInt64(WasmI64.load(filestats, 40n))
|
|
917
|
-
): Int64
|
|
918
|
-
let modified = WasmI32.toGrain(
|
|
919
|
-
newInt64(WasmI64.load(filestats, 48n))
|
|
920
|
-
): Int64
|
|
921
|
-
let changed = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 56n))): Int64
|
|
1061
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1062
|
+
}
|
|
922
1063
|
|
|
923
|
-
|
|
1064
|
+
let device = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 0n))): Int64
|
|
1065
|
+
let inode = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 8n))): Int64
|
|
1066
|
+
let filetype = filetypeFromNumber(WasmI32.load8U(filestats, 16n))
|
|
1067
|
+
let linkcount = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 24n))): Int64
|
|
1068
|
+
let size = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 32n))): Int64
|
|
1069
|
+
let accessed = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 40n))): Int64
|
|
1070
|
+
let modified = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 48n))): Int64
|
|
1071
|
+
let changed = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 56n))): Int64
|
|
924
1072
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1073
|
+
Memory.free(filestats)
|
|
1074
|
+
|
|
1075
|
+
return Ok(
|
|
1076
|
+
{ device, inode, filetype, linkcount, size, accessed, modified, changed },
|
|
1077
|
+
)
|
|
929
1078
|
}
|
|
930
1079
|
|
|
931
1080
|
/**
|
|
@@ -936,19 +1085,21 @@ export let fdFilestats = (fd: FileDescriptor) => {
|
|
|
936
1085
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
937
1086
|
*/
|
|
938
1087
|
@unsafe
|
|
939
|
-
|
|
1088
|
+
provide let fdSetSize = (fd: FileDescriptor, size: Int64) => {
|
|
940
1089
|
let fdArg = fd
|
|
941
1090
|
let sizeArg = size
|
|
942
|
-
let fd = match (fd) {
|
|
1091
|
+
let fd = match (fd) {
|
|
1092
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1093
|
+
}
|
|
943
1094
|
|
|
944
1095
|
let size = WasmI64.load(WasmI32.fromGrain(size), 8n)
|
|
945
1096
|
|
|
946
1097
|
let err = Wasi.fd_filestat_set_size(fd, size)
|
|
947
1098
|
if (err != Wasi._ESUCCESS) {
|
|
948
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
949
|
-
} else {
|
|
950
|
-
Ok(void)
|
|
1099
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
951
1100
|
}
|
|
1101
|
+
|
|
1102
|
+
return Ok(void)
|
|
952
1103
|
}
|
|
953
1104
|
|
|
954
1105
|
/**
|
|
@@ -959,18 +1110,20 @@ export let fdSetSize = (fd: FileDescriptor, size: Int64) => {
|
|
|
959
1110
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
960
1111
|
*/
|
|
961
1112
|
@unsafe
|
|
962
|
-
|
|
1113
|
+
provide let fdSetAccessTime = (fd: FileDescriptor, timestamp: Int64) => {
|
|
963
1114
|
let fdArg = fd
|
|
964
|
-
let fd = match (fd) {
|
|
1115
|
+
let fd = match (fd) {
|
|
1116
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1117
|
+
}
|
|
965
1118
|
|
|
966
1119
|
let time = WasmI64.load(WasmI32.fromGrain(timestamp), 8n)
|
|
967
1120
|
|
|
968
1121
|
let err = Wasi.fd_filestat_set_times(fd, time, 0N, Wasi._TIME_SET_ATIM)
|
|
969
1122
|
if (err != Wasi._ESUCCESS) {
|
|
970
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
971
|
-
} else {
|
|
972
|
-
Ok(void)
|
|
1123
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
973
1124
|
}
|
|
1125
|
+
|
|
1126
|
+
return Ok(void)
|
|
974
1127
|
}
|
|
975
1128
|
|
|
976
1129
|
/**
|
|
@@ -980,16 +1133,18 @@ export let fdSetAccessTime = (fd: FileDescriptor, timestamp: Int64) => {
|
|
|
980
1133
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
981
1134
|
*/
|
|
982
1135
|
@unsafe
|
|
983
|
-
|
|
1136
|
+
provide let fdSetAccessTimeNow = (fd: FileDescriptor) => {
|
|
984
1137
|
let fdArg = fd
|
|
985
|
-
let fd = match (fd) {
|
|
1138
|
+
let fd = match (fd) {
|
|
1139
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1140
|
+
}
|
|
986
1141
|
|
|
987
1142
|
let err = Wasi.fd_filestat_set_times(fd, 0N, 0N, Wasi._TIME_SET_ATIM_NOW)
|
|
988
1143
|
if (err != Wasi._ESUCCESS) {
|
|
989
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
990
|
-
} else {
|
|
991
|
-
Ok(void)
|
|
1144
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
992
1145
|
}
|
|
1146
|
+
|
|
1147
|
+
return Ok(void)
|
|
993
1148
|
}
|
|
994
1149
|
|
|
995
1150
|
/**
|
|
@@ -1000,18 +1155,20 @@ export let fdSetAccessTimeNow = (fd: FileDescriptor) => {
|
|
|
1000
1155
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1001
1156
|
*/
|
|
1002
1157
|
@unsafe
|
|
1003
|
-
|
|
1158
|
+
provide let fdSetModifiedTime = (fd: FileDescriptor, timestamp: Int64) => {
|
|
1004
1159
|
let fdArg = fd
|
|
1005
|
-
let fd = match (fd) {
|
|
1160
|
+
let fd = match (fd) {
|
|
1161
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1162
|
+
}
|
|
1006
1163
|
|
|
1007
1164
|
let time = WasmI64.load(WasmI32.fromGrain(timestamp), 8n)
|
|
1008
1165
|
|
|
1009
1166
|
let err = Wasi.fd_filestat_set_times(fd, 0N, time, Wasi._TIME_SET_MTIM)
|
|
1010
1167
|
if (err != Wasi._ESUCCESS) {
|
|
1011
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1012
|
-
} else {
|
|
1013
|
-
Ok(void)
|
|
1168
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1014
1169
|
}
|
|
1170
|
+
|
|
1171
|
+
return Ok(void)
|
|
1015
1172
|
}
|
|
1016
1173
|
|
|
1017
1174
|
/**
|
|
@@ -1021,16 +1178,18 @@ export let fdSetModifiedTime = (fd: FileDescriptor, timestamp: Int64) => {
|
|
|
1021
1178
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1022
1179
|
*/
|
|
1023
1180
|
@unsafe
|
|
1024
|
-
|
|
1181
|
+
provide let fdSetModifiedTimeNow = (fd: FileDescriptor) => {
|
|
1025
1182
|
let fdArg = fd
|
|
1026
|
-
let fd = match (fd) {
|
|
1183
|
+
let fd = match (fd) {
|
|
1184
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1185
|
+
}
|
|
1027
1186
|
|
|
1028
1187
|
let err = Wasi.fd_filestat_set_times(fd, 0N, 0N, Wasi._TIME_SET_MTIM_NOW)
|
|
1029
1188
|
if (err != Wasi._ESUCCESS) {
|
|
1030
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1031
|
-
} else {
|
|
1032
|
-
Ok(void)
|
|
1189
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1033
1190
|
}
|
|
1191
|
+
|
|
1192
|
+
return Ok(void)
|
|
1034
1193
|
}
|
|
1035
1194
|
|
|
1036
1195
|
/**
|
|
@@ -1040,9 +1199,11 @@ export let fdSetModifiedTimeNow = (fd: FileDescriptor) => {
|
|
|
1040
1199
|
* @returns `Ok(dirEntries)` of an array of `DirectoryEntry` for each entry in the directory if successful or `Err(exception)` otherwise
|
|
1041
1200
|
*/
|
|
1042
1201
|
@unsafe
|
|
1043
|
-
|
|
1202
|
+
provide let fdReaddir = (fd: FileDescriptor) => {
|
|
1044
1203
|
let fdArg = fd
|
|
1045
|
-
let fd = match (fd) {
|
|
1204
|
+
let fd = match (fd) {
|
|
1205
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1206
|
+
}
|
|
1046
1207
|
|
|
1047
1208
|
let structWidth = 24n
|
|
1048
1209
|
|
|
@@ -1056,94 +1217,87 @@ export let fdReaddir = (fd: FileDescriptor) => {
|
|
|
1056
1217
|
if (err != Wasi._ESUCCESS) {
|
|
1057
1218
|
Memory.free(buf)
|
|
1058
1219
|
Memory.free(bufUsed)
|
|
1059
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1060
|
-
}
|
|
1061
|
-
let used = WasmI32.load(bufUsed, 0n)
|
|
1220
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1221
|
+
}
|
|
1062
1222
|
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
hasErr = Some(Err(Wasi.SystemError(tagSimpleNumber(err))))
|
|
1099
|
-
break
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
if (WasmI32.load(bufUsed, 0n) != bufLen) {
|
|
1103
|
-
break
|
|
1104
|
-
} else {
|
|
1105
|
-
let curLen = WasmI32.load(buf, 16n)
|
|
1106
|
-
cookie = WasmI64.load(buf, 0n)
|
|
1107
|
-
let nextDirentPtr = buf + structWidth + curLen
|
|
1108
|
-
bufLen = WasmI32.load(nextDirentPtr, 16n) + structWidth * 2n
|
|
1109
|
-
}
|
|
1223
|
+
let used = WasmI32.load(bufUsed, 0n)
|
|
1224
|
+
|
|
1225
|
+
if (used <= 0n) {
|
|
1226
|
+
Memory.free(buf)
|
|
1227
|
+
Memory.free(bufUsed)
|
|
1228
|
+
return Ok(WasmI32.toGrain(allocateArray(0n)): Array<DirectoryEntry>)
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
bufLen = WasmI32.load(buf, 16n) + structWidth * 2n
|
|
1232
|
+
|
|
1233
|
+
Memory.free(buf)
|
|
1234
|
+
|
|
1235
|
+
// simple linked list
|
|
1236
|
+
// ptr +0n -> current buffer
|
|
1237
|
+
// ptr +4n -> bufs
|
|
1238
|
+
let mut bufs = 0n
|
|
1239
|
+
|
|
1240
|
+
let mut numEntries = 0n
|
|
1241
|
+
|
|
1242
|
+
while (true) {
|
|
1243
|
+
numEntries += 1n
|
|
1244
|
+
|
|
1245
|
+
buf = Memory.malloc(bufLen)
|
|
1246
|
+
let cons = Memory.malloc(8n)
|
|
1247
|
+
WasmI32.store(cons, buf, 0n)
|
|
1248
|
+
WasmI32.store(cons, bufs, 4n)
|
|
1249
|
+
bufs = cons
|
|
1250
|
+
|
|
1251
|
+
let err = Wasi.fd_readdir(fd, buf, bufLen, cookie, bufUsed)
|
|
1252
|
+
if (err != Wasi._ESUCCESS) {
|
|
1253
|
+
while (bufs != 0n) {
|
|
1254
|
+
Memory.free(WasmI32.load(bufs, 0n))
|
|
1255
|
+
let next = WasmI32.load(bufs, 4n)
|
|
1256
|
+
Memory.free(bufs)
|
|
1257
|
+
bufs = next
|
|
1110
1258
|
}
|
|
1259
|
+
Memory.free(bufUsed)
|
|
1260
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1261
|
+
}
|
|
1111
1262
|
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
Memory.free(bufUsed)
|
|
1263
|
+
if (WasmI32.load(bufUsed, 0n) != bufLen) {
|
|
1264
|
+
break
|
|
1265
|
+
}
|
|
1116
1266
|
|
|
1117
|
-
|
|
1267
|
+
let curLen = WasmI32.load(buf, 16n)
|
|
1268
|
+
cookie = WasmI64.load(buf, 0n)
|
|
1269
|
+
let nextDirentPtr = buf + structWidth + curLen
|
|
1270
|
+
bufLen = WasmI32.load(nextDirentPtr, 16n) + structWidth * 2n
|
|
1271
|
+
}
|
|
1118
1272
|
|
|
1119
|
-
|
|
1120
|
-
let ent = WasmI32.load(bufs, 0n)
|
|
1273
|
+
Memory.free(bufUsed)
|
|
1121
1274
|
|
|
1122
|
-
|
|
1275
|
+
let arr = allocateArray(numEntries)
|
|
1123
1276
|
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
Memory.copy(dirname + 8n, ent + structWidth, dirnameLen)
|
|
1127
|
-
let path = WasmI32.toGrain(dirname): String
|
|
1277
|
+
for (let mut i = numEntries - 1n; i >= 0n; i -= 1n) {
|
|
1278
|
+
let ent = WasmI32.load(bufs, 0n)
|
|
1128
1279
|
|
|
1129
|
-
|
|
1280
|
+
let inode = WasmI32.toGrain(newInt64(WasmI64.load(ent, 8n))): Int64
|
|
1130
1281
|
|
|
1131
|
-
|
|
1282
|
+
let dirnameLen = WasmI32.load(ent, 16n)
|
|
1283
|
+
let dirname = allocateString(dirnameLen)
|
|
1284
|
+
Memory.copy(dirname + 8n, ent + structWidth, dirnameLen)
|
|
1285
|
+
let path = WasmI32.toGrain(dirname): String
|
|
1132
1286
|
|
|
1133
|
-
|
|
1287
|
+
let filetype = filetypeFromNumber(WasmI32.load8U(ent, 20n))
|
|
1134
1288
|
|
|
1135
|
-
|
|
1136
|
-
Memory.free(bufs)
|
|
1137
|
-
Memory.free(ent)
|
|
1289
|
+
let dirent = WasmI32.fromGrain({ inode, path, filetype })
|
|
1138
1290
|
|
|
1139
|
-
|
|
1140
|
-
}
|
|
1291
|
+
WasmI32.store(arr + i * 4n, Memory.incRef(dirent), 8n)
|
|
1141
1292
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1293
|
+
let next = WasmI32.load(bufs, 4n)
|
|
1294
|
+
Memory.free(bufs)
|
|
1295
|
+
Memory.free(ent)
|
|
1296
|
+
|
|
1297
|
+
bufs = next
|
|
1146
1298
|
}
|
|
1299
|
+
|
|
1300
|
+
return Ok(WasmI32.toGrain(arr): Array<DirectoryEntry>)
|
|
1147
1301
|
}
|
|
1148
1302
|
|
|
1149
1303
|
/**
|
|
@@ -1154,21 +1308,23 @@ export let fdReaddir = (fd: FileDescriptor) => {
|
|
|
1154
1308
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1155
1309
|
*/
|
|
1156
1310
|
@unsafe
|
|
1157
|
-
|
|
1311
|
+
provide let fdRenumber = (fromFd: FileDescriptor, toFd: FileDescriptor) => {
|
|
1158
1312
|
let fromFdArg = fromFd
|
|
1159
1313
|
let toFdArg = toFd
|
|
1160
1314
|
let fromFd = match (fromFd) {
|
|
1161
1315
|
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1162
1316
|
}
|
|
1163
1317
|
|
|
1164
|
-
let toFd = match (toFd) {
|
|
1318
|
+
let toFd = match (toFd) {
|
|
1319
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1320
|
+
}
|
|
1165
1321
|
|
|
1166
1322
|
let err = Wasi.fd_renumber(fromFd, toFd)
|
|
1167
1323
|
if (err != Wasi._ESUCCESS) {
|
|
1168
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1169
|
-
} else {
|
|
1170
|
-
Ok(void)
|
|
1324
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1171
1325
|
}
|
|
1326
|
+
|
|
1327
|
+
return Ok(void)
|
|
1172
1328
|
}
|
|
1173
1329
|
|
|
1174
1330
|
/**
|
|
@@ -1180,11 +1336,13 @@ export let fdRenumber = (fromFd: FileDescriptor, toFd: FileDescriptor) => {
|
|
|
1180
1336
|
* @returns `Ok(offset)` of the new offset of the file descriptor, relative to the start of the file, if successful or `Err(exception)` otherwise
|
|
1181
1337
|
*/
|
|
1182
1338
|
@unsafe
|
|
1183
|
-
|
|
1339
|
+
provide let fdSeek = (fd: FileDescriptor, offset: Int64, whence: Whence) => {
|
|
1184
1340
|
let fdArg = fd
|
|
1185
1341
|
let offsetArg = offset
|
|
1186
1342
|
let whenceArg = whence
|
|
1187
|
-
let fd = match (fd) {
|
|
1343
|
+
let fd = match (fd) {
|
|
1344
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1345
|
+
}
|
|
1188
1346
|
|
|
1189
1347
|
let offset = WasmI64.load(WasmI32.fromGrain(offset), 8n)
|
|
1190
1348
|
|
|
@@ -1200,10 +1358,10 @@ export let fdSeek = (fd: FileDescriptor, offset: Int64, whence: Whence) => {
|
|
|
1200
1358
|
let err = Wasi.fd_seek(fd, offset, whence, newoffsetPtr)
|
|
1201
1359
|
if (err != Wasi._ESUCCESS) {
|
|
1202
1360
|
Memory.free(newoffset)
|
|
1203
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1204
|
-
} else {
|
|
1205
|
-
Ok(WasmI32.toGrain(newoffset): Int64)
|
|
1361
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1206
1362
|
}
|
|
1363
|
+
|
|
1364
|
+
return Ok(WasmI32.toGrain(newoffset): Int64)
|
|
1207
1365
|
}
|
|
1208
1366
|
|
|
1209
1367
|
/**
|
|
@@ -1213,9 +1371,11 @@ export let fdSeek = (fd: FileDescriptor, offset: Int64, whence: Whence) => {
|
|
|
1213
1371
|
* @returns `Ok(offset)` of the offset of the file descriptor, relative to the start of the file, if successful or `Err(exception)` otherwise
|
|
1214
1372
|
*/
|
|
1215
1373
|
@unsafe
|
|
1216
|
-
|
|
1374
|
+
provide let fdTell = (fd: FileDescriptor) => {
|
|
1217
1375
|
let fdArg = fd
|
|
1218
|
-
let fd = match (fd) {
|
|
1376
|
+
let fd = match (fd) {
|
|
1377
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1378
|
+
}
|
|
1219
1379
|
|
|
1220
1380
|
let offset = allocateInt64()
|
|
1221
1381
|
let offsetPtr = offset + 8n
|
|
@@ -1223,10 +1383,10 @@ export let fdTell = (fd: FileDescriptor) => {
|
|
|
1223
1383
|
let err = Wasi.fd_tell(fd, offsetPtr)
|
|
1224
1384
|
if (err != Wasi._ESUCCESS) {
|
|
1225
1385
|
Memory.free(offset)
|
|
1226
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1227
|
-
} else {
|
|
1228
|
-
Ok(WasmI32.toGrain(offset): Int64)
|
|
1386
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1229
1387
|
}
|
|
1388
|
+
|
|
1389
|
+
return Ok(WasmI32.toGrain(offset): Int64)
|
|
1230
1390
|
}
|
|
1231
1391
|
|
|
1232
1392
|
/**
|
|
@@ -1237,9 +1397,11 @@ export let fdTell = (fd: FileDescriptor) => {
|
|
|
1237
1397
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1238
1398
|
*/
|
|
1239
1399
|
@unsafe
|
|
1240
|
-
|
|
1400
|
+
provide let pathCreateDirectory = (fd: FileDescriptor, path: String) => {
|
|
1241
1401
|
let fdArg = fd
|
|
1242
|
-
let fd = match (fd) {
|
|
1402
|
+
let fd = match (fd) {
|
|
1403
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1404
|
+
}
|
|
1243
1405
|
|
|
1244
1406
|
let stringPtr = WasmI32.fromGrain(path)
|
|
1245
1407
|
|
|
@@ -1247,10 +1409,10 @@ export let pathCreateDirectory = (fd: FileDescriptor, path: String) => {
|
|
|
1247
1409
|
|
|
1248
1410
|
let err = Wasi.path_create_directory(fd, stringPtr + 8n, size)
|
|
1249
1411
|
if (err != Wasi._ESUCCESS) {
|
|
1250
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1251
|
-
} else {
|
|
1252
|
-
Ok(void)
|
|
1412
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1253
1413
|
}
|
|
1414
|
+
|
|
1415
|
+
return Ok(void)
|
|
1254
1416
|
}
|
|
1255
1417
|
|
|
1256
1418
|
/**
|
|
@@ -1262,14 +1424,15 @@ export let pathCreateDirectory = (fd: FileDescriptor, path: String) => {
|
|
|
1262
1424
|
* @returns `Ok(info)` of the `Filestats` associated with the file descriptor if successful or `Err(exception)` otherwise
|
|
1263
1425
|
*/
|
|
1264
1426
|
@unsafe
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
) => {
|
|
1427
|
+
provide let pathFilestats = (
|
|
1428
|
+
fd: FileDescriptor,
|
|
1429
|
+
dirFlags: List<LookupFlag>,
|
|
1430
|
+
path: String,
|
|
1431
|
+
) => {
|
|
1271
1432
|
let fdArg = fd
|
|
1272
|
-
let fd = match (fd) {
|
|
1433
|
+
let fd = match (fd) {
|
|
1434
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1435
|
+
}
|
|
1273
1436
|
|
|
1274
1437
|
let combinedDirFlags = combineLookupFlags(dirFlags)
|
|
1275
1438
|
|
|
@@ -1288,29 +1451,23 @@ export let pathFilestats =
|
|
|
1288
1451
|
)
|
|
1289
1452
|
if (err != Wasi._ESUCCESS) {
|
|
1290
1453
|
Memory.free(filestats)
|
|
1291
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1292
|
-
}
|
|
1293
|
-
let device = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 0n))): Int64
|
|
1294
|
-
let inode = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 8n))): Int64
|
|
1295
|
-
let filetype = filetypeFromNumber(WasmI32.load8U(filestats, 16n))
|
|
1296
|
-
let linkcount = WasmI32.toGrain(
|
|
1297
|
-
newInt64(WasmI64.load(filestats, 24n))
|
|
1298
|
-
): Int64
|
|
1299
|
-
let size = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 32n))): Int64
|
|
1300
|
-
let accessed = WasmI32.toGrain(
|
|
1301
|
-
newInt64(WasmI64.load(filestats, 40n))
|
|
1302
|
-
): Int64
|
|
1303
|
-
let modified = WasmI32.toGrain(
|
|
1304
|
-
newInt64(WasmI64.load(filestats, 48n))
|
|
1305
|
-
): Int64
|
|
1306
|
-
let changed = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 56n))): Int64
|
|
1454
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1455
|
+
}
|
|
1307
1456
|
|
|
1308
|
-
|
|
1457
|
+
let device = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 0n))): Int64
|
|
1458
|
+
let inode = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 8n))): Int64
|
|
1459
|
+
let filetype = filetypeFromNumber(WasmI32.load8U(filestats, 16n))
|
|
1460
|
+
let linkcount = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 24n))): Int64
|
|
1461
|
+
let size = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 32n))): Int64
|
|
1462
|
+
let accessed = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 40n))): Int64
|
|
1463
|
+
let modified = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 48n))): Int64
|
|
1464
|
+
let changed = WasmI32.toGrain(newInt64(WasmI64.load(filestats, 56n))): Int64
|
|
1309
1465
|
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1466
|
+
Memory.free(filestats)
|
|
1467
|
+
|
|
1468
|
+
return Ok(
|
|
1469
|
+
{ device, inode, filetype, linkcount, size, accessed, modified, changed },
|
|
1470
|
+
)
|
|
1314
1471
|
}
|
|
1315
1472
|
|
|
1316
1473
|
/**
|
|
@@ -1323,15 +1480,16 @@ export let pathFilestats =
|
|
|
1323
1480
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1324
1481
|
*/
|
|
1325
1482
|
@unsafe
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
) => {
|
|
1483
|
+
provide let pathSetAccessTime = (
|
|
1484
|
+
fd: FileDescriptor,
|
|
1485
|
+
dirFlags: List<LookupFlag>,
|
|
1486
|
+
path: String,
|
|
1487
|
+
timestamp: Int64,
|
|
1488
|
+
) => {
|
|
1333
1489
|
let fdArg = fd
|
|
1334
|
-
let fd = match (fd) {
|
|
1490
|
+
let fd = match (fd) {
|
|
1491
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1492
|
+
}
|
|
1335
1493
|
|
|
1336
1494
|
let combinedDirFlags = combineLookupFlags(dirFlags)
|
|
1337
1495
|
|
|
@@ -1351,10 +1509,10 @@ export let pathSetAccessTime =
|
|
|
1351
1509
|
Wasi._TIME_SET_ATIM
|
|
1352
1510
|
)
|
|
1353
1511
|
if (err != Wasi._ESUCCESS) {
|
|
1354
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1355
|
-
} else {
|
|
1356
|
-
Ok(void)
|
|
1512
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1357
1513
|
}
|
|
1514
|
+
|
|
1515
|
+
return Ok(void)
|
|
1358
1516
|
}
|
|
1359
1517
|
|
|
1360
1518
|
/**
|
|
@@ -1366,14 +1524,15 @@ export let pathSetAccessTime =
|
|
|
1366
1524
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1367
1525
|
*/
|
|
1368
1526
|
@unsafe
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
) => {
|
|
1527
|
+
provide let pathSetAccessTimeNow = (
|
|
1528
|
+
fd: FileDescriptor,
|
|
1529
|
+
dirFlags: List<LookupFlag>,
|
|
1530
|
+
path: String,
|
|
1531
|
+
) => {
|
|
1375
1532
|
let fdArg = fd
|
|
1376
|
-
let fd = match (fd) {
|
|
1533
|
+
let fd = match (fd) {
|
|
1534
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1535
|
+
}
|
|
1377
1536
|
|
|
1378
1537
|
let combinedDirFlags = combineLookupFlags(dirFlags)
|
|
1379
1538
|
|
|
@@ -1391,10 +1550,10 @@ export let pathSetAccessTimeNow =
|
|
|
1391
1550
|
Wasi._TIME_SET_ATIM_NOW
|
|
1392
1551
|
)
|
|
1393
1552
|
if (err != Wasi._ESUCCESS) {
|
|
1394
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1395
|
-
} else {
|
|
1396
|
-
Ok(void)
|
|
1553
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1397
1554
|
}
|
|
1555
|
+
|
|
1556
|
+
return Ok(void)
|
|
1398
1557
|
}
|
|
1399
1558
|
|
|
1400
1559
|
/**
|
|
@@ -1407,15 +1566,16 @@ export let pathSetAccessTimeNow =
|
|
|
1407
1566
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1408
1567
|
*/
|
|
1409
1568
|
@unsafe
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
) => {
|
|
1569
|
+
provide let pathSetModifiedTime = (
|
|
1570
|
+
fd: FileDescriptor,
|
|
1571
|
+
dirFlags: List<LookupFlag>,
|
|
1572
|
+
path: String,
|
|
1573
|
+
timestamp: Int64,
|
|
1574
|
+
) => {
|
|
1417
1575
|
let fdArg = fd
|
|
1418
|
-
let fd = match (fd) {
|
|
1576
|
+
let fd = match (fd) {
|
|
1577
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1578
|
+
}
|
|
1419
1579
|
|
|
1420
1580
|
let combinedDirFlags = combineLookupFlags(dirFlags)
|
|
1421
1581
|
|
|
@@ -1435,10 +1595,10 @@ export let pathSetModifiedTime =
|
|
|
1435
1595
|
Wasi._TIME_SET_MTIM
|
|
1436
1596
|
)
|
|
1437
1597
|
if (err != Wasi._ESUCCESS) {
|
|
1438
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1439
|
-
} else {
|
|
1440
|
-
Ok(void)
|
|
1598
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1441
1599
|
}
|
|
1600
|
+
|
|
1601
|
+
return Ok(void)
|
|
1442
1602
|
}
|
|
1443
1603
|
|
|
1444
1604
|
/**
|
|
@@ -1450,14 +1610,15 @@ export let pathSetModifiedTime =
|
|
|
1450
1610
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1451
1611
|
*/
|
|
1452
1612
|
@unsafe
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
) => {
|
|
1613
|
+
provide let pathSetModifiedTimeNow = (
|
|
1614
|
+
fd: FileDescriptor,
|
|
1615
|
+
dirFlags: List<LookupFlag>,
|
|
1616
|
+
path: String,
|
|
1617
|
+
) => {
|
|
1459
1618
|
let fdArg = fd
|
|
1460
|
-
let fd = match (fd) {
|
|
1619
|
+
let fd = match (fd) {
|
|
1620
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1621
|
+
}
|
|
1461
1622
|
|
|
1462
1623
|
let combinedDirFlags = combineLookupFlags(dirFlags)
|
|
1463
1624
|
|
|
@@ -1475,10 +1636,10 @@ export let pathSetModifiedTimeNow =
|
|
|
1475
1636
|
Wasi._TIME_SET_MTIM_NOW
|
|
1476
1637
|
)
|
|
1477
1638
|
if (err != Wasi._ESUCCESS) {
|
|
1478
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1479
|
-
} else {
|
|
1480
|
-
Ok(void)
|
|
1639
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1481
1640
|
}
|
|
1641
|
+
|
|
1642
|
+
return Ok(void)
|
|
1482
1643
|
}
|
|
1483
1644
|
|
|
1484
1645
|
/**
|
|
@@ -1492,14 +1653,13 @@ export let pathSetModifiedTimeNow =
|
|
|
1492
1653
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1493
1654
|
*/
|
|
1494
1655
|
@unsafe
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
) => {
|
|
1656
|
+
provide let pathLink = (
|
|
1657
|
+
sourceFd: FileDescriptor,
|
|
1658
|
+
dirFlags: List<LookupFlag>,
|
|
1659
|
+
sourcePath: String,
|
|
1660
|
+
targetFd: FileDescriptor,
|
|
1661
|
+
targetPath: String,
|
|
1662
|
+
) => {
|
|
1503
1663
|
let sourceFdArg = sourceFd
|
|
1504
1664
|
let targetFdArg = targetFd
|
|
1505
1665
|
let sourceFd = match (sourceFd) {
|
|
@@ -1528,10 +1688,10 @@ export let pathLink =
|
|
|
1528
1688
|
targetSize
|
|
1529
1689
|
)
|
|
1530
1690
|
if (err != Wasi._ESUCCESS) {
|
|
1531
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1532
|
-
} else {
|
|
1533
|
-
Ok(void)
|
|
1691
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1534
1692
|
}
|
|
1693
|
+
|
|
1694
|
+
return Ok(void)
|
|
1535
1695
|
}
|
|
1536
1696
|
|
|
1537
1697
|
/**
|
|
@@ -1543,14 +1703,15 @@ export let pathLink =
|
|
|
1543
1703
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1544
1704
|
*/
|
|
1545
1705
|
@unsafe
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
) => {
|
|
1706
|
+
provide let pathSymlink = (
|
|
1707
|
+
fd: FileDescriptor,
|
|
1708
|
+
sourcePath: String,
|
|
1709
|
+
targetPath: String,
|
|
1710
|
+
) => {
|
|
1552
1711
|
let fdArg = fd
|
|
1553
|
-
let fd = match (fd) {
|
|
1712
|
+
let fd = match (fd) {
|
|
1713
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1714
|
+
}
|
|
1554
1715
|
|
|
1555
1716
|
let sourcePtr = WasmI32.fromGrain(sourcePath)
|
|
1556
1717
|
let targetPtr = WasmI32.fromGrain(targetPath)
|
|
@@ -1566,10 +1727,10 @@ export let pathSymlink =
|
|
|
1566
1727
|
targetSize
|
|
1567
1728
|
)
|
|
1568
1729
|
if (err != Wasi._ESUCCESS) {
|
|
1569
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1570
|
-
} else {
|
|
1571
|
-
Ok(void)
|
|
1730
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1572
1731
|
}
|
|
1732
|
+
|
|
1733
|
+
return Ok(void)
|
|
1573
1734
|
}
|
|
1574
1735
|
|
|
1575
1736
|
/**
|
|
@@ -1580,19 +1741,21 @@ export let pathSymlink =
|
|
|
1580
1741
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1581
1742
|
*/
|
|
1582
1743
|
@unsafe
|
|
1583
|
-
|
|
1744
|
+
provide let pathUnlink = (fd: FileDescriptor, path: String) => {
|
|
1584
1745
|
let fdArg = fd
|
|
1585
|
-
let fd = match (fd) {
|
|
1746
|
+
let fd = match (fd) {
|
|
1747
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1748
|
+
}
|
|
1586
1749
|
|
|
1587
1750
|
let pathPtr = WasmI32.fromGrain(path)
|
|
1588
1751
|
let pathSize = WasmI32.load(pathPtr, 4n)
|
|
1589
1752
|
|
|
1590
1753
|
let err = Wasi.path_unlink_file(fd, pathPtr + 8n, pathSize)
|
|
1591
1754
|
if (err != Wasi._ESUCCESS) {
|
|
1592
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1593
|
-
} else {
|
|
1594
|
-
Ok(void)
|
|
1755
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1595
1756
|
}
|
|
1757
|
+
|
|
1758
|
+
return Ok(void)
|
|
1596
1759
|
}
|
|
1597
1760
|
|
|
1598
1761
|
/**
|
|
@@ -1604,10 +1767,12 @@ export let pathUnlink = (fd: FileDescriptor, path: String) => {
|
|
|
1604
1767
|
* @returns `Ok((contents, numBytes))` of the bytes read and the number of bytes read if successful or `Err(exception)` otherwise
|
|
1605
1768
|
*/
|
|
1606
1769
|
@unsafe
|
|
1607
|
-
|
|
1770
|
+
provide let pathReadlink = (fd: FileDescriptor, path: String, size: Number) => {
|
|
1608
1771
|
let fdArg = fd
|
|
1609
1772
|
let sizeArg = size
|
|
1610
|
-
let fd = match (fd) {
|
|
1773
|
+
let fd = match (fd) {
|
|
1774
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1775
|
+
}
|
|
1611
1776
|
|
|
1612
1777
|
let pathPtr = WasmI32.fromGrain(path)
|
|
1613
1778
|
let pathSize = WasmI32.load(pathPtr, 4n)
|
|
@@ -1623,13 +1788,13 @@ export let pathReadlink = (fd: FileDescriptor, path: String, size: Number) => {
|
|
|
1623
1788
|
if (err != Wasi._ESUCCESS) {
|
|
1624
1789
|
Memory.free(grainStrPtr)
|
|
1625
1790
|
Memory.free(nread)
|
|
1626
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1627
|
-
} else {
|
|
1628
|
-
let read = tagSimpleNumber(WasmI32.load(nread, 0n))
|
|
1629
|
-
Memory.free(nread)
|
|
1630
|
-
|
|
1631
|
-
Ok((WasmI32.toGrain(grainStrPtr): String, read))
|
|
1791
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1632
1792
|
}
|
|
1793
|
+
|
|
1794
|
+
let read = tagSimpleNumber(WasmI32.load(nread, 0n))
|
|
1795
|
+
Memory.free(nread)
|
|
1796
|
+
|
|
1797
|
+
return Ok((WasmI32.toGrain(grainStrPtr): String, read))
|
|
1633
1798
|
}
|
|
1634
1799
|
|
|
1635
1800
|
/**
|
|
@@ -1640,19 +1805,21 @@ export let pathReadlink = (fd: FileDescriptor, path: String, size: Number) => {
|
|
|
1640
1805
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1641
1806
|
*/
|
|
1642
1807
|
@unsafe
|
|
1643
|
-
|
|
1808
|
+
provide let pathRemoveDirectory = (fd: FileDescriptor, path: String) => {
|
|
1644
1809
|
let fdArg = fd
|
|
1645
|
-
let fd = match (fd) {
|
|
1810
|
+
let fd = match (fd) {
|
|
1811
|
+
FileDescriptor(n) => WasmI32.fromGrain(n) >> 1n,
|
|
1812
|
+
}
|
|
1646
1813
|
|
|
1647
1814
|
let pathPtr = WasmI32.fromGrain(path)
|
|
1648
1815
|
let pathSize = WasmI32.load(pathPtr, 4n)
|
|
1649
1816
|
|
|
1650
1817
|
let err = Wasi.path_remove_directory(fd, pathPtr + 8n, pathSize)
|
|
1651
1818
|
if (err != Wasi._ESUCCESS) {
|
|
1652
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1653
|
-
} else {
|
|
1654
|
-
Ok(void)
|
|
1819
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1655
1820
|
}
|
|
1821
|
+
|
|
1822
|
+
return Ok(void)
|
|
1656
1823
|
}
|
|
1657
1824
|
|
|
1658
1825
|
/**
|
|
@@ -1665,13 +1832,12 @@ export let pathRemoveDirectory = (fd: FileDescriptor, path: String) => {
|
|
|
1665
1832
|
* @returns `Ok(void)` if successful or `Err(exception)` otherwise
|
|
1666
1833
|
*/
|
|
1667
1834
|
@unsafe
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
) => {
|
|
1835
|
+
provide let pathRename = (
|
|
1836
|
+
sourceFd: FileDescriptor,
|
|
1837
|
+
sourcePath: String,
|
|
1838
|
+
targetFd: FileDescriptor,
|
|
1839
|
+
targetPath: String,
|
|
1840
|
+
) => {
|
|
1675
1841
|
let sourceFdArg = sourceFd
|
|
1676
1842
|
let targetFdArg = targetFd
|
|
1677
1843
|
let sourceFd = match (sourceFd) {
|
|
@@ -1697,8 +1863,256 @@ export let pathRename =
|
|
|
1697
1863
|
targetSize
|
|
1698
1864
|
)
|
|
1699
1865
|
if (err != Wasi._ESUCCESS) {
|
|
1700
|
-
Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1866
|
+
return Err(Wasi.SystemError(tagSimpleNumber(err)))
|
|
1867
|
+
}
|
|
1868
|
+
|
|
1869
|
+
return Ok(void)
|
|
1870
|
+
}
|
|
1871
|
+
|
|
1872
|
+
@unsafe
|
|
1873
|
+
let _CHAR_SLASH = 0x2fn
|
|
1874
|
+
@unsafe
|
|
1875
|
+
let _CHAR_DOT = 0x2en
|
|
1876
|
+
|
|
1877
|
+
@unsafe
|
|
1878
|
+
let stripPrefixes = (path: String) => {
|
|
1879
|
+
let origPathPtr = WasmI32.fromGrain(path)
|
|
1880
|
+
let mut pathPtr = origPathPtr
|
|
1881
|
+
let mut pathLen = WasmI32.load(pathPtr, 4n)
|
|
1882
|
+
pathPtr += 8n
|
|
1883
|
+
|
|
1884
|
+
while (true) {
|
|
1885
|
+
if (WasmI32.load8U(pathPtr, 0n) == _CHAR_SLASH) {
|
|
1886
|
+
pathPtr += 1n
|
|
1887
|
+
pathLen -= 1n
|
|
1888
|
+
} else if (
|
|
1889
|
+
WasmI32.load8U(pathPtr, 0n) == _CHAR_DOT &&
|
|
1890
|
+
WasmI32.load8U(pathPtr, 1n) == _CHAR_SLASH
|
|
1891
|
+
) {
|
|
1892
|
+
pathPtr += 2n
|
|
1893
|
+
pathLen -= 2n
|
|
1894
|
+
} else if (WasmI32.load8U(pathPtr, 0n) == _CHAR_DOT && pathLen == 1n) {
|
|
1895
|
+
pathPtr += 1n
|
|
1896
|
+
pathLen -= 1n
|
|
1897
|
+
break
|
|
1898
|
+
} else {
|
|
1899
|
+
break
|
|
1900
|
+
}
|
|
1901
|
+
}
|
|
1902
|
+
|
|
1903
|
+
if (pathPtr == origPathPtr) {
|
|
1904
|
+
path
|
|
1905
|
+
} else {
|
|
1906
|
+
let strippedPath = allocateString(pathLen)
|
|
1907
|
+
Memory.copy(strippedPath + 8n, pathPtr, pathLen)
|
|
1908
|
+
WasmI32.toGrain(strippedPath): String
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
|
|
1912
|
+
let mut preopens = None
|
|
1913
|
+
@unsafe
|
|
1914
|
+
let populatePreopens = () => {
|
|
1915
|
+
let mut preopenedDirs = []
|
|
1916
|
+
// Skip stdin, stdout, and stderr.
|
|
1917
|
+
for (let mut fd = 3n; fd != 0n; fd += 1n) {
|
|
1918
|
+
let fd = FileDescriptor(tagSimpleNumber(fd))
|
|
1919
|
+
match (fdPrestatGet(fd)) {
|
|
1920
|
+
Ok(Dir{ prefix, fd }) =>
|
|
1921
|
+
preopenedDirs = [(fd, stripPrefixes(prefix)), ...preopenedDirs],
|
|
1922
|
+
// We've reached a bad file descriptor; we're done.
|
|
1923
|
+
Err(Wasi.SystemError(e)) when untagSimpleNumber(e) == Wasi._EBADF =>
|
|
1924
|
+
break,
|
|
1925
|
+
Err(_) => fail "Failed to populate preopens",
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
preopens = Some(preopenedDirs)
|
|
1929
|
+
preopenedDirs
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
@unsafe
|
|
1933
|
+
let prefixMatches = (prefix, prefixLen, path, pathLen) => {
|
|
1934
|
+
// Allow an empty string as a prefix of any relative path.
|
|
1935
|
+
if (WasmI32.load8U(path, 0n) != _CHAR_SLASH && prefixLen == 0n) {
|
|
1936
|
+
return true
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1939
|
+
// Check whether any bytes of the prefix differ.
|
|
1940
|
+
if (Memory.compare(path, prefix, prefixLen) != 0n) {
|
|
1941
|
+
return false
|
|
1942
|
+
}
|
|
1943
|
+
|
|
1944
|
+
// Ignore trailing slashes in directory names.
|
|
1945
|
+
let mut i = prefixLen
|
|
1946
|
+
while (i > 0n && WasmI32.load8U(prefix + i - 1n, 0n) == _CHAR_SLASH) {
|
|
1947
|
+
i -= 1n
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
// Match only complete path components.
|
|
1951
|
+
let last = WasmI32.load8U(path + i, 0n)
|
|
1952
|
+
return last == _CHAR_SLASH || i == pathLen
|
|
1953
|
+
}
|
|
1954
|
+
|
|
1955
|
+
@unsafe
|
|
1956
|
+
let rec findPath = (path, pathLen, preopens, bestMatch) => {
|
|
1957
|
+
match (preopens) {
|
|
1958
|
+
[(fd, prefix) as preopen, ...preopens] => {
|
|
1959
|
+
let prefix = WasmI32.fromGrain(prefix)
|
|
1960
|
+
let prefixLen = WasmI32.load(prefix, 4n)
|
|
1961
|
+
let prefix = prefix + 8n
|
|
1962
|
+
|
|
1963
|
+
let (hasBestMatch, matchLen) = match (bestMatch) {
|
|
1964
|
+
Some((matchPrefix, _)) =>
|
|
1965
|
+
(
|
|
1966
|
+
true,
|
|
1967
|
+
tagSimpleNumber(WasmI32.load(WasmI32.fromGrain(matchPrefix), 4n)),
|
|
1968
|
+
),
|
|
1969
|
+
None => (false, 0),
|
|
1970
|
+
}
|
|
1971
|
+
|
|
1972
|
+
let bestMatch = if (
|
|
1973
|
+
(!hasBestMatch || pathLen > untagSimpleNumber(matchLen)) &&
|
|
1974
|
+
prefixMatches(prefix, prefixLen, path, pathLen)
|
|
1975
|
+
) {
|
|
1976
|
+
Some(preopen)
|
|
1977
|
+
} else {
|
|
1978
|
+
bestMatch
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
findPath(path, pathLen, preopens, bestMatch)
|
|
1982
|
+
},
|
|
1983
|
+
[] => {
|
|
1984
|
+
match (bestMatch) {
|
|
1985
|
+
Some((fd, prefix)) => {
|
|
1986
|
+
let matchLen = WasmI32.load(WasmI32.fromGrain(prefix), 4n)
|
|
1987
|
+
let mut computed = path + matchLen
|
|
1988
|
+
while (WasmI32.load8U(computed, 0n) == _CHAR_SLASH) {
|
|
1989
|
+
computed += 1n
|
|
1990
|
+
}
|
|
1991
|
+
let computedPath = if (computed == path + pathLen) {
|
|
1992
|
+
"."
|
|
1993
|
+
} else {
|
|
1994
|
+
let computedLen = path + pathLen - computed
|
|
1995
|
+
let computedPath = allocateString(computedLen)
|
|
1996
|
+
Memory.copy(computedPath + 8n, computed, computedLen)
|
|
1997
|
+
WasmI32.toGrain(computedPath): String
|
|
1998
|
+
}
|
|
1999
|
+
Ok((fd, computedPath))
|
|
2000
|
+
},
|
|
2001
|
+
None => Err(Wasi.SystemError(tagSimpleNumber(Wasi._ENOENT))),
|
|
2002
|
+
}
|
|
2003
|
+
},
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
|
|
2007
|
+
@unsafe
|
|
2008
|
+
let findPath = (path: String) => {
|
|
2009
|
+
let pathPtr = WasmI32.fromGrain(path)
|
|
2010
|
+
let mut pathLen = WasmI32.load(pathPtr, 4n)
|
|
2011
|
+
let mut pathPtr = pathPtr + 8n
|
|
2012
|
+
|
|
2013
|
+
// ignore leading `/` characters
|
|
2014
|
+
while (WasmI32.load8U(pathPtr, 0n) == _CHAR_SLASH) {
|
|
2015
|
+
pathPtr += 1n
|
|
2016
|
+
pathLen -= 1n
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
let preopens = match (preopens) {
|
|
2020
|
+
Some(preopens) => preopens,
|
|
2021
|
+
None => populatePreopens(),
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
let matchingPath = findPath(pathPtr, pathLen, preopens, None)
|
|
2025
|
+
ignore(path)
|
|
2026
|
+
matchingPath
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
// explicit just in case we ever want to support changing directories
|
|
2030
|
+
let cwd = "/"
|
|
2031
|
+
|
|
2032
|
+
@unsafe
|
|
2033
|
+
let makeAbsolute = (path: String) => {
|
|
2034
|
+
let origPathPtr = WasmI32.fromGrain(path)
|
|
2035
|
+
let mut pathPtr = origPathPtr
|
|
2036
|
+
let mut pathLen = WasmI32.load(pathPtr, 4n)
|
|
2037
|
+
pathPtr += 8n
|
|
2038
|
+
|
|
2039
|
+
// already absolute
|
|
2040
|
+
if (WasmI32.load8U(pathPtr, 0n) == _CHAR_SLASH) {
|
|
2041
|
+
return path
|
|
2042
|
+
}
|
|
2043
|
+
|
|
2044
|
+
// pointing at the current dirextory
|
|
2045
|
+
if (
|
|
2046
|
+
pathLen == 0n ||
|
|
2047
|
+
pathLen == 1n && WasmI32.load8U(pathPtr, 0n) == _CHAR_DOT ||
|
|
2048
|
+
pathLen == 2n &&
|
|
2049
|
+
WasmI32.load8U(pathPtr, 0n) == _CHAR_DOT &&
|
|
2050
|
+
WasmI32.load8U(pathPtr, 1n) == _CHAR_SLASH
|
|
2051
|
+
) {
|
|
2052
|
+
return cwd
|
|
2053
|
+
}
|
|
2054
|
+
|
|
2055
|
+
// strip leading ./
|
|
2056
|
+
if (
|
|
2057
|
+
WasmI32.load8U(pathPtr, 0n) == _CHAR_DOT &&
|
|
2058
|
+
WasmI32.load8U(pathPtr, 1n) == _CHAR_SLASH
|
|
2059
|
+
) {
|
|
2060
|
+
pathPtr += 2n
|
|
2061
|
+
pathLen -= 2n
|
|
2062
|
+
}
|
|
2063
|
+
|
|
2064
|
+
let mut cwdPtr = WasmI32.fromGrain(cwd)
|
|
2065
|
+
let cwdLen = WasmI32.load(cwdPtr, 4n)
|
|
2066
|
+
cwdPtr += 8n
|
|
2067
|
+
|
|
2068
|
+
let needSlash = WasmI32.load8U(cwdPtr + cwdLen - 1n, 0n) != _CHAR_SLASH
|
|
2069
|
+
|
|
2070
|
+
if (needSlash) {
|
|
2071
|
+
let fullPath = allocateString(cwdLen + 1n + pathLen)
|
|
2072
|
+
Memory.copy(fullPath + 8n, cwdPtr, cwdLen)
|
|
2073
|
+
WasmI32.store8(fullPath + 8n + cwdLen, _CHAR_SLASH, 0n)
|
|
2074
|
+
Memory.copy(fullPath + 8n + cwdLen + 1n, pathPtr, pathLen)
|
|
2075
|
+
return WasmI32.toGrain(fullPath): String
|
|
1701
2076
|
} else {
|
|
1702
|
-
|
|
2077
|
+
let fullPath = allocateString(cwdLen + pathLen)
|
|
2078
|
+
Memory.copy(fullPath + 8n, cwdPtr, cwdLen)
|
|
2079
|
+
Memory.copy(fullPath + 8n + cwdLen, pathPtr, pathLen)
|
|
2080
|
+
return WasmI32.toGrain(fullPath): String
|
|
2081
|
+
}
|
|
2082
|
+
}
|
|
2083
|
+
|
|
2084
|
+
/**
|
|
2085
|
+
* Similar to `pathOpen`, but resolves the path relative to preopened directories.
|
|
2086
|
+
*
|
|
2087
|
+
* @param path: The path to the file or directory
|
|
2088
|
+
* @param openFlags: Flags that decide how the path will be opened
|
|
2089
|
+
* @param rights: The rights that dictate what may be done with the returned file descriptor
|
|
2090
|
+
* @param rightsInheriting: The rights that dictate what may be done with file descriptors derived from this file descriptor
|
|
2091
|
+
* @param flags: Flags which affect read/write operations on this file descriptor
|
|
2092
|
+
* @returns `Ok(fd)` of the opened file or directory if successful or `Err(exception)` otherwise
|
|
2093
|
+
*
|
|
2094
|
+
* @since v0.6.0
|
|
2095
|
+
*/
|
|
2096
|
+
@unsafe
|
|
2097
|
+
provide let open = (
|
|
2098
|
+
path: String,
|
|
2099
|
+
openFlags: List<OpenFlag>,
|
|
2100
|
+
rights: List<Rights>,
|
|
2101
|
+
rightsInheriting: List<Rights>,
|
|
2102
|
+
flags: List<FdFlag>,
|
|
2103
|
+
) => {
|
|
2104
|
+
match (findPath(makeAbsolute(path))) {
|
|
2105
|
+
Ok((fd, relativePath)) => {
|
|
2106
|
+
pathOpen(
|
|
2107
|
+
fd,
|
|
2108
|
+
[SymlinkFollow],
|
|
2109
|
+
relativePath,
|
|
2110
|
+
openFlags,
|
|
2111
|
+
rights,
|
|
2112
|
+
rightsInheriting,
|
|
2113
|
+
flags
|
|
2114
|
+
)
|
|
2115
|
+
},
|
|
2116
|
+
Err(e) => Err(e),
|
|
1703
2117
|
}
|
|
1704
2118
|
}
|