@live-codes/ocaml 0.0.0-stage → 0.1.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 (130) hide show
  1. package/LICENSE +220 -0
  2. package/README.md +165 -2
  3. package/THIRD-PARTY-NOTICES.md +52 -0
  4. package/assets/compiler/compile_stdout.browser.js +27856 -0
  5. package/assets/compiler/jsoo.js +12631 -0
  6. package/assets/compiler/package.json +3 -0
  7. package/assets/compiler/runtime/bigarray.js +1072 -0
  8. package/assets/compiler/runtime/bigstring.js +137 -0
  9. package/assets/compiler/runtime/domain.js +393 -0
  10. package/assets/compiler/runtime/dynlink.js +91 -0
  11. package/assets/compiler/runtime/float32.js +486 -0
  12. package/assets/compiler/runtime/fs.js +416 -0
  13. package/assets/compiler/runtime/fs_fake.js +600 -0
  14. package/assets/compiler/runtime/fs_node.js +609 -0
  15. package/assets/compiler/runtime/fs_quickjs.js +532 -0
  16. package/assets/compiler/runtime/gc.js +201 -0
  17. package/assets/compiler/runtime/graphics.js +1053 -0
  18. package/assets/compiler/runtime/ieee_754.js +621 -0
  19. package/assets/compiler/runtime/int64.js +516 -0
  20. package/assets/compiler/runtime/io.js +739 -0
  21. package/assets/compiler/runtime/jslib.js +553 -0
  22. package/assets/compiler/runtime/jslib_js_of_ocaml.js +81 -0
  23. package/assets/compiler/runtime/lexing.js +240 -0
  24. package/assets/compiler/runtime/manifest.txt +31 -0
  25. package/assets/compiler/runtime/marshal.js +863 -0
  26. package/assets/compiler/runtime/md5.js +236 -0
  27. package/assets/compiler/runtime/mlBytes.js +1007 -0
  28. package/assets/compiler/runtime/nat.js +469 -0
  29. package/assets/compiler/runtime/parsing.js +317 -0
  30. package/assets/compiler/runtime/prng.js +84 -0
  31. package/assets/compiler/runtime/promise.js +45 -0
  32. package/assets/compiler/runtime/runtime.js +16688 -0
  33. package/assets/compiler/runtime/runtime_events.js +90 -0
  34. package/assets/compiler/runtime/stdlib.js +363 -0
  35. package/assets/compiler/runtime/sync.js +35 -0
  36. package/assets/compiler/runtime/toplevel.js +150 -0
  37. package/assets/compiler/runtime/unix.js +914 -0
  38. package/assets/compiler/runtime/weak.js +247 -0
  39. package/assets/compiler/stdlib.js +254 -0
  40. package/assets/compiler/worker.js +46 -0
  41. package/assets/interpreter/libs/greet.cma +0 -0
  42. package/assets/interpreter/libs/greet.cmi +0 -0
  43. package/assets/interpreter/libs/manifest.txt +1 -0
  44. package/assets/interpreter/package.json +3 -0
  45. package/assets/interpreter/stdlib/camlinternalFormat.cmi +0 -0
  46. package/assets/interpreter/stdlib/camlinternalFormatBasics.cmi +0 -0
  47. package/assets/interpreter/stdlib/camlinternalLazy.cmi +0 -0
  48. package/assets/interpreter/stdlib/camlinternalMod.cmi +0 -0
  49. package/assets/interpreter/stdlib/camlinternalOO.cmi +0 -0
  50. package/assets/interpreter/stdlib/std_exit.cmi +0 -0
  51. package/assets/interpreter/stdlib/stdlib.cmi +0 -0
  52. package/assets/interpreter/stdlib/stdlib__Arg.cmi +0 -0
  53. package/assets/interpreter/stdlib/stdlib__Array.cmi +0 -0
  54. package/assets/interpreter/stdlib/stdlib__ArrayLabels.cmi +0 -0
  55. package/assets/interpreter/stdlib/stdlib__Atomic.cmi +0 -0
  56. package/assets/interpreter/stdlib/stdlib__Bigarray.cmi +0 -0
  57. package/assets/interpreter/stdlib/stdlib__Bool.cmi +0 -0
  58. package/assets/interpreter/stdlib/stdlib__Buffer.cmi +0 -0
  59. package/assets/interpreter/stdlib/stdlib__Bytes.cmi +0 -0
  60. package/assets/interpreter/stdlib/stdlib__BytesLabels.cmi +0 -0
  61. package/assets/interpreter/stdlib/stdlib__Callback.cmi +0 -0
  62. package/assets/interpreter/stdlib/stdlib__Char.cmi +0 -0
  63. package/assets/interpreter/stdlib/stdlib__Complex.cmi +0 -0
  64. package/assets/interpreter/stdlib/stdlib__Condition.cmi +0 -0
  65. package/assets/interpreter/stdlib/stdlib__Digest.cmi +0 -0
  66. package/assets/interpreter/stdlib/stdlib__Domain.cmi +0 -0
  67. package/assets/interpreter/stdlib/stdlib__Dynarray.cmi +0 -0
  68. package/assets/interpreter/stdlib/stdlib__Effect.cmi +0 -0
  69. package/assets/interpreter/stdlib/stdlib__Either.cmi +0 -0
  70. package/assets/interpreter/stdlib/stdlib__Ephemeron.cmi +0 -0
  71. package/assets/interpreter/stdlib/stdlib__Filename.cmi +0 -0
  72. package/assets/interpreter/stdlib/stdlib__Float.cmi +0 -0
  73. package/assets/interpreter/stdlib/stdlib__Format.cmi +0 -0
  74. package/assets/interpreter/stdlib/stdlib__Fun.cmi +0 -0
  75. package/assets/interpreter/stdlib/stdlib__Gc.cmi +0 -0
  76. package/assets/interpreter/stdlib/stdlib__Hashtbl.cmi +0 -0
  77. package/assets/interpreter/stdlib/stdlib__Iarray.cmi +0 -0
  78. package/assets/interpreter/stdlib/stdlib__In_channel.cmi +0 -0
  79. package/assets/interpreter/stdlib/stdlib__Int.cmi +0 -0
  80. package/assets/interpreter/stdlib/stdlib__Int32.cmi +0 -0
  81. package/assets/interpreter/stdlib/stdlib__Int64.cmi +0 -0
  82. package/assets/interpreter/stdlib/stdlib__Lazy.cmi +0 -0
  83. package/assets/interpreter/stdlib/stdlib__Lexing.cmi +0 -0
  84. package/assets/interpreter/stdlib/stdlib__List.cmi +0 -0
  85. package/assets/interpreter/stdlib/stdlib__ListLabels.cmi +0 -0
  86. package/assets/interpreter/stdlib/stdlib__Map.cmi +0 -0
  87. package/assets/interpreter/stdlib/stdlib__Marshal.cmi +0 -0
  88. package/assets/interpreter/stdlib/stdlib__MoreLabels.cmi +0 -0
  89. package/assets/interpreter/stdlib/stdlib__Mutex.cmi +0 -0
  90. package/assets/interpreter/stdlib/stdlib__Nativeint.cmi +0 -0
  91. package/assets/interpreter/stdlib/stdlib__Obj.cmi +0 -0
  92. package/assets/interpreter/stdlib/stdlib__Oo.cmi +0 -0
  93. package/assets/interpreter/stdlib/stdlib__Option.cmi +0 -0
  94. package/assets/interpreter/stdlib/stdlib__Out_channel.cmi +0 -0
  95. package/assets/interpreter/stdlib/stdlib__Pair.cmi +0 -0
  96. package/assets/interpreter/stdlib/stdlib__Parsing.cmi +0 -0
  97. package/assets/interpreter/stdlib/stdlib__Pqueue.cmi +0 -0
  98. package/assets/interpreter/stdlib/stdlib__Printexc.cmi +0 -0
  99. package/assets/interpreter/stdlib/stdlib__Printf.cmi +0 -0
  100. package/assets/interpreter/stdlib/stdlib__Queue.cmi +0 -0
  101. package/assets/interpreter/stdlib/stdlib__Random.cmi +0 -0
  102. package/assets/interpreter/stdlib/stdlib__Repr.cmi +0 -0
  103. package/assets/interpreter/stdlib/stdlib__Result.cmi +0 -0
  104. package/assets/interpreter/stdlib/stdlib__Scanf.cmi +0 -0
  105. package/assets/interpreter/stdlib/stdlib__Semaphore.cmi +0 -0
  106. package/assets/interpreter/stdlib/stdlib__Seq.cmi +0 -0
  107. package/assets/interpreter/stdlib/stdlib__Set.cmi +0 -0
  108. package/assets/interpreter/stdlib/stdlib__Stack.cmi +0 -0
  109. package/assets/interpreter/stdlib/stdlib__StdLabels.cmi +0 -0
  110. package/assets/interpreter/stdlib/stdlib__String.cmi +0 -0
  111. package/assets/interpreter/stdlib/stdlib__StringLabels.cmi +0 -0
  112. package/assets/interpreter/stdlib/stdlib__Sys.cmi +0 -0
  113. package/assets/interpreter/stdlib/stdlib__Type.cmi +0 -0
  114. package/assets/interpreter/stdlib/stdlib__Uchar.cmi +0 -0
  115. package/assets/interpreter/stdlib/stdlib__Unit.cmi +0 -0
  116. package/assets/interpreter/stdlib/stdlib__Weak.cmi +0 -0
  117. package/assets/interpreter/stdlib/topdirs.cmi +0 -0
  118. package/assets/interpreter/stdlib/units.txt +75 -0
  119. package/assets/interpreter/stdlib/unix.cmi +0 -0
  120. package/assets/interpreter/stdlib/unixLabels.cmi +0 -0
  121. package/assets/interpreter/worker-entry.js +39 -0
  122. package/assets/interpreter/worker.js +42356 -0
  123. package/bin/copy-assets.mjs +75 -0
  124. package/package.json +41 -4
  125. package/src/compiler/compile.js +170 -0
  126. package/src/compiler/index.js +46 -0
  127. package/src/compiler/worker.js +46 -0
  128. package/src/index.js +12 -0
  129. package/src/interpreter/api.js +182 -0
  130. package/src/interpreter/index.js +5 -0
@@ -0,0 +1,609 @@
1
+ // Js_of_ocaml runtime support
2
+ // http://www.ocsigen.org/js_of_ocaml/
3
+ // Copyright (C) 2014 Jérôme Vouillon, Hugo Heuzard
4
+ // Laboratoire PPS - CNRS Université Paris Diderot
5
+ //
6
+ // This program is free software; you can redistribute it and/or modify
7
+ // it under the terms of the GNU Lesser General Public License as published by
8
+ // the Free Software Foundation, with linking exception;
9
+ // either version 2.1 of the License, or (at your option) any later version.
10
+ //
11
+ // This program is distributed in the hope that it will be useful,
12
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ // GNU Lesser General Public License for more details.
15
+ //
16
+ // You should have received a copy of the GNU Lesser General Public License
17
+ // along with this program; if not, write to the Free Software
18
+ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19
+
20
+ //Provides: jsoo_is_win32
21
+ var jsoo_is_win32 =
22
+ globalThis.Deno?.build?.os === "windows" ||
23
+ globalThis.process?.platform === "win32";
24
+
25
+ //Provides: fs_node_supported
26
+ function fs_node_supported() {
27
+ return globalThis.process?.versions?.node !== undefined;
28
+ }
29
+ //Provides: fs_node_supported
30
+ //If: browser
31
+ function fs_node_supported() {
32
+ return false;
33
+ }
34
+
35
+ //Provides: MlNodeDevice
36
+ //Requires: MlNodeFd, caml_raise_sys_error, caml_string_of_jsstring
37
+ //Requires: caml_raise_nodejs_error, ocaml_stats_from_node_stats
38
+ //Requires: jsoo_is_win32
39
+ class MlNodeDevice {
40
+ constructor(root) {
41
+ this.fs = require("node:fs");
42
+ this.root = root;
43
+ }
44
+
45
+ nm(name) {
46
+ return this.root + name;
47
+ }
48
+
49
+ exists(name) {
50
+ try {
51
+ return this.fs.existsSync(this.nm(name)) ? 1 : 0;
52
+ } catch (err) {
53
+ return 0;
54
+ }
55
+ }
56
+
57
+ isFile(name) {
58
+ try {
59
+ return this.fs.statSync(this.nm(name)).isFile() ? 1 : 0;
60
+ } catch (err) {
61
+ caml_raise_sys_error(err.toString());
62
+ }
63
+ }
64
+
65
+ mkdir(name, mode, raise_unix) {
66
+ try {
67
+ this.fs.mkdirSync(this.nm(name), { mode: mode });
68
+ return 0;
69
+ } catch (err) {
70
+ caml_raise_nodejs_error(err, raise_unix);
71
+ }
72
+ }
73
+
74
+ rmdir(name, raise_unix) {
75
+ try {
76
+ this.fs.rmdirSync(this.nm(name));
77
+ return 0;
78
+ } catch (err) {
79
+ caml_raise_nodejs_error(err, raise_unix);
80
+ }
81
+ }
82
+
83
+ readdir(name, raise_unix) {
84
+ try {
85
+ return this.fs.readdirSync(this.nm(name));
86
+ } catch (err) {
87
+ caml_raise_nodejs_error(err, raise_unix);
88
+ }
89
+ }
90
+
91
+ is_dir(name) {
92
+ try {
93
+ return this.fs.statSync(this.nm(name)).isDirectory() ? 1 : 0;
94
+ } catch (err) {
95
+ caml_raise_sys_error(err.toString());
96
+ }
97
+ }
98
+
99
+ unlink(name, raise_unix) {
100
+ try {
101
+ this.fs.unlinkSync(this.nm(name));
102
+ return 0;
103
+ } catch (err) {
104
+ caml_raise_nodejs_error(err, raise_unix);
105
+ }
106
+ }
107
+
108
+ utimes(name, atime, mtime, raise_unix) {
109
+ try {
110
+ if (atime === 0 && mtime === 0) {
111
+ atime = Date.now() / 1000;
112
+ mtime = atime;
113
+ }
114
+ this.fs.utimesSync(this.nm(name), atime, mtime);
115
+ return 0;
116
+ } catch (err) {
117
+ caml_raise_nodejs_error(err, raise_unix);
118
+ }
119
+ }
120
+
121
+ truncate(name, len, raise_unix) {
122
+ try {
123
+ // do not truncate [len] to 32 bits; node accepts up to 2^53
124
+ this.fs.truncateSync(this.nm(name), len);
125
+ return 0;
126
+ } catch (err) {
127
+ caml_raise_nodejs_error(err, raise_unix);
128
+ }
129
+ }
130
+
131
+ access(name, f, raise_unix) {
132
+ var consts = this.fs.constants;
133
+ var res = 0;
134
+ for (var key in f) {
135
+ switch (key) {
136
+ case "r":
137
+ res |= consts.R_OK;
138
+ break;
139
+ case "w":
140
+ res |= consts.W_OK;
141
+ break;
142
+ case "x":
143
+ res |= jsoo_is_win32 ? consts.R_OK : consts.X_OK;
144
+ break;
145
+ case "f":
146
+ res |= consts.F_OK;
147
+ break;
148
+ }
149
+ }
150
+ try {
151
+ this.fs.accessSync(this.nm(name), res);
152
+ return 0;
153
+ } catch (err) {
154
+ caml_raise_nodejs_error(err, raise_unix);
155
+ }
156
+ }
157
+
158
+ open(name, f, perms, raise_unix) {
159
+ var consts = this.fs.constants;
160
+ var res = 0;
161
+ for (var key in f) {
162
+ switch (key) {
163
+ case "rdonly":
164
+ res |= consts.O_RDONLY;
165
+ break;
166
+ case "wronly":
167
+ res |= consts.O_WRONLY;
168
+ break;
169
+ case "rdwr":
170
+ res |= consts.O_RDWR;
171
+ break;
172
+ case "append":
173
+ res |= consts.O_APPEND;
174
+ break;
175
+ case "create":
176
+ res |= consts.O_CREAT;
177
+ break;
178
+ case "truncate":
179
+ res |= consts.O_TRUNC;
180
+ break;
181
+ case "excl":
182
+ res |= consts.O_EXCL;
183
+ break;
184
+ case "binary":
185
+ res |= consts.O_BINARY;
186
+ break;
187
+ case "text":
188
+ res |= consts.O_TEXT;
189
+ break;
190
+ case "nonblock":
191
+ res |= consts.O_NONBLOCK;
192
+ break;
193
+ case "noctty":
194
+ res |= consts.O_NOCTTY;
195
+ break;
196
+ case "dsync":
197
+ res |= consts.O_DSYNC;
198
+ break;
199
+ case "sync":
200
+ res |= consts.O_SYNC;
201
+ break;
202
+ }
203
+ }
204
+ try {
205
+ var fd = this.fs.openSync(this.nm(name), res, perms);
206
+ return new MlNodeFd(fd, f);
207
+ } catch (err) {
208
+ caml_raise_nodejs_error(err, raise_unix);
209
+ }
210
+ }
211
+
212
+ slash(name) {
213
+ return /\/$/.test(name) ? name : name + "/";
214
+ }
215
+
216
+ rename(o, n, raise_unix) {
217
+ if (jsoo_is_win32) {
218
+ try {
219
+ var target = this.nm(n);
220
+ var source = this.nm(o);
221
+ var target_stats, source_stats;
222
+ if (
223
+ (target_stats = this.fs.statSync(target, {
224
+ throwIfNoEntry: false,
225
+ })) &&
226
+ (source_stats = this.fs.statSync(source, {
227
+ throwIfNoEntry: false,
228
+ })) &&
229
+ source_stats.isDirectory()
230
+ ) {
231
+ if (target_stats.isDirectory()) {
232
+ if (!this.slash(target).startsWith(this.slash(source)))
233
+ try {
234
+ this.fs.rmdirSync(target);
235
+ } catch {}
236
+ } else {
237
+ var err = new Error(
238
+ `ENOTDIR: not a directory, rename '${source}' -> '${target}'`,
239
+ );
240
+ throw Object.assign(err, {
241
+ errno: -20,
242
+ code: "ENOTDIR",
243
+ syscall: "rename",
244
+ path: target,
245
+ });
246
+ }
247
+ }
248
+ this.fs.renameSync(this.nm(o), this.nm(n));
249
+ } catch (err) {
250
+ caml_raise_nodejs_error(err, raise_unix);
251
+ }
252
+ } else {
253
+ try {
254
+ this.fs.renameSync(this.nm(o), this.nm(n));
255
+ } catch (err) {
256
+ caml_raise_nodejs_error(err, raise_unix);
257
+ }
258
+ }
259
+ }
260
+
261
+ stat(name, large, raise_unix) {
262
+ try {
263
+ var js_stats = this.fs.statSync(this.nm(name));
264
+ return ocaml_stats_from_node_stats(js_stats, large);
265
+ } catch (err) {
266
+ caml_raise_nodejs_error(err, raise_unix);
267
+ }
268
+ }
269
+
270
+ lstat(name, large, raise_unix) {
271
+ try {
272
+ var js_stats = this.fs.lstatSync(this.nm(name));
273
+ return ocaml_stats_from_node_stats(js_stats, large);
274
+ } catch (err) {
275
+ caml_raise_nodejs_error(err, raise_unix);
276
+ }
277
+ }
278
+
279
+ chmod(name, perms, raise_unix) {
280
+ try {
281
+ this.fs.chmodSync(this.nm(name), perms);
282
+ return 0;
283
+ } catch (err) {
284
+ caml_raise_nodejs_error(err, raise_unix);
285
+ }
286
+ }
287
+
288
+ link(target, path, raise_unix) {
289
+ try {
290
+ this.fs.linkSync(this.nm(target), this.nm(path));
291
+ return 0;
292
+ } catch (err) {
293
+ caml_raise_nodejs_error(err, raise_unix);
294
+ }
295
+ }
296
+
297
+ symlink(to_dir, target, path, raise_unix) {
298
+ try {
299
+ this.fs.symlinkSync(
300
+ target,
301
+ this.nm(path),
302
+ to_dir === 0 ? null : to_dir[1] ? "dir" : "file",
303
+ );
304
+ return 0;
305
+ } catch (err) {
306
+ caml_raise_nodejs_error(err, raise_unix);
307
+ }
308
+ }
309
+
310
+ readlink(name, raise_unix) {
311
+ try {
312
+ var link = this.fs.readlinkSync(this.nm(name), "utf8");
313
+ return caml_string_of_jsstring(link);
314
+ } catch (err) {
315
+ caml_raise_nodejs_error(err, raise_unix);
316
+ }
317
+ }
318
+
319
+ opendir(name, raise_unix) {
320
+ try {
321
+ return this.fs.opendirSync(this.nm(name));
322
+ } catch (err) {
323
+ caml_raise_nodejs_error(err, raise_unix);
324
+ }
325
+ }
326
+ }
327
+
328
+ //Provides: ocaml_stats_from_node_stats
329
+ //Requires: caml_int64_of_float
330
+ function ocaml_stats_from_node_stats(js_stats, large) {
331
+ /* ===Unix.file_kind===
332
+ * type file_kind =
333
+ * S_REG (** Regular file *)
334
+ * | S_DIR (** Directory *)
335
+ * | S_CHR (** Character device *)
336
+ * | S_BLK (** Block device *)
337
+ * | S_LNK (** Symbolic link *)
338
+ * | S_FIFO (** Named pipe *)
339
+ * | S_SOCK (** Socket *)
340
+ */
341
+ var file_kind;
342
+ if (js_stats.isFile()) {
343
+ file_kind = 0;
344
+ } else if (js_stats.isDirectory()) {
345
+ file_kind = 1;
346
+ } else if (js_stats.isCharacterDevice()) {
347
+ file_kind = 2;
348
+ } else if (js_stats.isBlockDevice()) {
349
+ file_kind = 3;
350
+ } else if (js_stats.isSymbolicLink()) {
351
+ file_kind = 4;
352
+ } else if (js_stats.isFIFO()) {
353
+ file_kind = 5;
354
+ } else if (js_stats.isSocket()) {
355
+ file_kind = 6;
356
+ }
357
+ /* ===Unix.stats===
358
+ * type stats =
359
+ * { st_dev : int; (** Device number *)
360
+ * st_ino : int; (** Inode number *)
361
+ * st_kind : file_kind; (** Kind of the file *)
362
+ * st_perm : file_perm; (** Access rights *)
363
+ * st_nlink : int; (** Number of links *)
364
+ * st_uid : int; (** User id of the owner *)
365
+ * st_gid : int; (** Group ID of the file's group *)
366
+ * st_rdev : int; (** Device ID (if special file) *)
367
+ * st_size : int; (** Size in bytes *)
368
+ * st_atime : float; (** Last access time *)
369
+ * st_mtime : float; (** Last modification time *)
370
+ * st_ctime : float; (** Last status change time *)
371
+ * }
372
+ */
373
+ return BLOCK(
374
+ 0,
375
+ js_stats.dev,
376
+ js_stats.ino | 0,
377
+ file_kind,
378
+ js_stats.mode & 0o7777,
379
+ js_stats.nlink,
380
+ js_stats.uid,
381
+ js_stats.gid,
382
+ js_stats.rdev,
383
+ large ? caml_int64_of_float(js_stats.size) : js_stats.size | 0,
384
+ js_stats.atimeMs / 1000,
385
+ js_stats.mtimeMs / 1000,
386
+ js_stats.ctimeMs / 1000,
387
+ );
388
+ }
389
+
390
+ //Provides: MlNodeDevice
391
+ //If: browser
392
+ class MlNodeDevice {}
393
+
394
+ //Provides: MlNodeFd
395
+ //Requires: MlFile, caml_uint8_array_of_string, caml_uint8_array_of_bytes, caml_bytes_set, caml_raise_sys_error
396
+ //Requires: caml_raise_nodejs_error, caml_raise_system_error, ocaml_stats_from_node_stats
397
+ class MlNodeFd extends MlFile {
398
+ constructor(fd, flags) {
399
+ super();
400
+ this.fs = require("node:fs");
401
+ this.fd = fd;
402
+ this.flags = flags;
403
+ try {
404
+ var stats = this.fs.fstatSync(fd);
405
+ flags.noSeek =
406
+ stats.isCharacterDevice() || stats.isFIFO() || stats.isSocket();
407
+ // Like native [O_APPEND], the offset starts at the beginning of the
408
+ // file; each [write] repositions to the end (see [write] below).
409
+ this.offset = 0;
410
+ } catch (err) {
411
+ // The fstat will fail on standard streams under Windows with node
412
+ // 18 (and lower). See https://github.com/libuv/libuv/pull/3811.
413
+ flags.noSeek = true;
414
+ this.offset = 0;
415
+ }
416
+ this.seeked = false;
417
+ }
418
+
419
+ truncate(len, raise_unix) {
420
+ try {
421
+ // do not truncate [len] to 32 bits, and do not move the fd
422
+ // offset: POSIX ftruncate leaves it unchanged
423
+ this.fs.ftruncateSync(this.fd, len);
424
+ } catch (err) {
425
+ caml_raise_nodejs_error(err, raise_unix);
426
+ }
427
+ }
428
+
429
+ isatty() {
430
+ var tty = require("node:tty");
431
+ return tty.isatty(this.fd) ? 1 : 0;
432
+ }
433
+
434
+ length() {
435
+ try {
436
+ return this.fs.fstatSync(this.fd).size;
437
+ } catch (err) {
438
+ caml_raise_sys_error(err.toString());
439
+ }
440
+ }
441
+
442
+ write(buf, buf_offset, len, raise_unix) {
443
+ try {
444
+ // [O_APPEND]: every write goes to the end of the file. The OS already
445
+ // enforces this for the bytes (the fd was opened with O_APPEND); we
446
+ // refresh the tracked offset so [pos]/[lseek] report the native value.
447
+ if (this.flags.append && !this.flags.noSeek) this.offset = this.length();
448
+ if (this.flags.noSeek || !this.seeked) {
449
+ var written = this.fs.writeSync(this.fd, buf, buf_offset, len);
450
+ } else {
451
+ var written = this.fs.writeSync(
452
+ this.fd,
453
+ buf,
454
+ buf_offset,
455
+ len,
456
+ this.offset,
457
+ );
458
+ }
459
+ this.offset += written;
460
+ } catch (err) {
461
+ caml_raise_nodejs_error(err, raise_unix);
462
+ }
463
+ return written;
464
+ }
465
+
466
+ read(a, buf_offset, len, raise_unix) {
467
+ try {
468
+ if (this.flags.noSeek || !this.seeked) {
469
+ var read = this.fs.readSync(this.fd, a, buf_offset, len);
470
+ } else {
471
+ var read = this.fs.readSync(this.fd, a, buf_offset, len, this.offset);
472
+ }
473
+ this.offset += read;
474
+ return read;
475
+ } catch (err) {
476
+ caml_raise_nodejs_error(err, raise_unix);
477
+ }
478
+ }
479
+
480
+ seek(offset, whence, raise_unix) {
481
+ if (this.flags.noSeek) {
482
+ caml_raise_system_error(raise_unix, "ESPIPE", "lseek", "illegal seek");
483
+ }
484
+ switch (whence) {
485
+ case 0:
486
+ break;
487
+ case 1:
488
+ offset += this.offset;
489
+ break;
490
+ case 2:
491
+ offset += this.length();
492
+ break;
493
+ }
494
+ if (offset < 0) {
495
+ caml_raise_system_error(
496
+ raise_unix,
497
+ "EINVAL",
498
+ "lseek",
499
+ "invalid argument",
500
+ );
501
+ }
502
+ this.offset = offset;
503
+ this.seeked = true;
504
+ return this.offset;
505
+ }
506
+
507
+ pos() {
508
+ return this.offset;
509
+ }
510
+
511
+ stat(large) {
512
+ try {
513
+ var js_stats = this.fs.fstatSync(this.fd);
514
+ return ocaml_stats_from_node_stats(js_stats, large);
515
+ } catch (err) {
516
+ caml_raise_nodejs_error(err, /* raise Unix_error */ 1);
517
+ }
518
+ }
519
+
520
+ chmod(perms) {
521
+ try {
522
+ this.fs.fchmodSync(this.fd, perms);
523
+ return 0;
524
+ } catch (err) {
525
+ caml_raise_nodejs_error(err, /* raise Unix_error */ 1);
526
+ }
527
+ }
528
+
529
+ sync() {
530
+ try {
531
+ this.fs.fsyncSync(this.fd);
532
+ return 0;
533
+ } catch (err) {
534
+ caml_raise_nodejs_error(err, /* raise Unix_error */ 1);
535
+ }
536
+ }
537
+
538
+ close(raise_unix) {
539
+ try {
540
+ this.fs.closeSync(this.fd);
541
+ return 0;
542
+ } catch (err) {
543
+ caml_raise_nodejs_error(err, raise_unix);
544
+ }
545
+ }
546
+
547
+ check_stream_semantics(cmd) {
548
+ try {
549
+ var js_stats = this.fs.fstatSync(this.fd);
550
+ } catch (err) {
551
+ caml_raise_nodejs_error(err, /* raise Unix_error */ 1, cmd);
552
+ }
553
+ if (
554
+ !(
555
+ js_stats.isFile() ||
556
+ js_stats.isCharacterDevice() ||
557
+ js_stats.isFIFO() ||
558
+ js_stats.isSocket()
559
+ )
560
+ )
561
+ caml_raise_system_error(
562
+ /* raise Unix_error */ 1,
563
+ "EINVAL",
564
+ cmd,
565
+ "invalid argument",
566
+ );
567
+ }
568
+ }
569
+
570
+ //Provides: MlNodeFd
571
+ //If: browser
572
+ class MlNodeFd {}
573
+
574
+ //Provides: caml_sys_open_for_node
575
+ //Requires: MlNodeFd
576
+ function caml_sys_open_for_node(fd, flags) {
577
+ if (flags.altname) {
578
+ try {
579
+ var fs = require("node:fs");
580
+ var fd2 = fs.openSync(flags.altname, "rs");
581
+ return new MlNodeFd(fd2, flags);
582
+ } catch (e) {}
583
+ }
584
+ return new MlNodeFd(fd, flags);
585
+ }
586
+
587
+ //Provides: caml_sys_open_for_node
588
+ //If: browser
589
+ function caml_sys_open_for_node(_fd, _flags) {
590
+ return null;
591
+ }
592
+
593
+ //Provides: caml_raise_nodejs_error
594
+ //Requires: caml_raise_with_args, make_unix_err_args, caml_named_value
595
+ //Requires: caml_raise_sys_error
596
+ function caml_raise_nodejs_error(err, raise_unix, cmd) {
597
+ var unix_error = caml_named_value("Unix.Unix_error");
598
+ if (raise_unix && unix_error) {
599
+ var args = make_unix_err_args(
600
+ err.code,
601
+ cmd || err.syscall,
602
+ err.path,
603
+ err.errno,
604
+ );
605
+ caml_raise_with_args(unix_error, args);
606
+ } else {
607
+ caml_raise_sys_error(err.toString());
608
+ }
609
+ }