substrate-lang 0.9.4 → 0.10.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.
Files changed (199) hide show
  1. package/README.md +1 -1
  2. package/build/compiler/{binary.cdd2ffb408dd@0+0.wasm → binary.2d43b43d1600@0+0.wasm} +0 -0
  3. package/build/compiler/checker.4dd4556dd421@0+0.wasm +0 -0
  4. package/build/compiler/{compile.da85f9bc4478@0+0.wasm → compile.5d8f6407af2a@0+0.wasm} +0 -0
  5. package/build/compiler/{core.0410ffbdc488@0+0.wasm → core.f2defb75e00b@0+0.wasm} +0 -0
  6. package/build/compiler/expander.967ce443d379@0+0.wasm +0 -0
  7. package/build/compiler/fs.01b8aab4a9a8@0+0.wasm +0 -0
  8. package/build/compiler/{leb128.ba77430f659f@0+0.wasm → leb128.15d814b7b4f2@0+0.wasm} +0 -0
  9. package/build/compiler/{link.be6e641afa93@0+0.wasm → link.b826ea7c8f17@0+0.wasm} +0 -0
  10. package/build/compiler/{macros.b695763c0ca3@0+0.wasm → macros.b269e0c42784@0+0.wasm} +0 -0
  11. package/build/compiler/{main.cbbdf42e34c2@0+0.wasm → main.4fc52f204d54@0+0.wasm} +0 -0
  12. package/build/compiler/{ops.324f0a665fab@0+0.wasm → ops.515b5e05f646@0+0.wasm} +0 -0
  13. package/build/compiler/{path.1b5fd988b6f3@0+0.wasm → path.5a6286472cd4@0+0.wasm} +0 -0
  14. package/build/compiler/program +21 -21
  15. package/build/compiler/{prune.29dde307bdee@0+0.wasm → prune.406215c3e4f8@0+0.wasm} +0 -0
  16. package/build/compiler/reader.694b03770bf0@0+0.wasm +0 -0
  17. package/build/compiler/roots.cefd10e93684@0+0.wasm +0 -0
  18. package/build/compiler/{running.b99787c2d180@0+0.wasm → running.0d25dbaec018@0+0.wasm} +0 -0
  19. package/build/compiler/serialize.b0d82f3d63d2@0+0.wasm +0 -0
  20. package/build/compiler/{sha256.f6c742932dde@0+0.wasm → sha256.a6c32b04d799@0+0.wasm} +0 -0
  21. package/build/compiler/substrate.5ee5d0b4d3e7@0+0.wasm +0 -0
  22. package/build/compiler/{syntax.fadc832db29f@0+0.wasm → syntax.32f3e40b61c7@0+0.wasm} +0 -0
  23. package/build/compiler/{writer.550227768eb9@0+0.wasm → writer.00b7802cbe39@0+0.wasm} +0 -0
  24. package/build/sub/{base64.454b045156d2@0+0.wasm → base64.a26bdcf60a2d@0+0.wasm} +0 -0
  25. package/build/sub/build.459c5b9412bd@0+0.wasm +0 -0
  26. package/build/sub/chromium.3d5818f2707d@0+0.wasm +0 -0
  27. package/build/sub/common.1edc613607a0@0+0.wasm +0 -0
  28. package/build/sub/deflate.23f7c4679260@0+0.wasm +0 -0
  29. package/build/sub/doc.0775df5de6fe@0+0.wasm +0 -0
  30. package/build/sub/{doc.f18ad14060e9@0+0.wasm → doc.ef9965d5d402@0+0.wasm} +0 -0
  31. package/build/sub/env.e5451da6e747@0+0.wasm +0 -0
  32. package/build/sub/events.bf5473ebf220@0+0.wasm +0 -0
  33. package/build/sub/fetch.7790d4943758@0+0.wasm +0 -0
  34. package/build/sub/fetch.96b2d10f025e@0+0.wasm +0 -0
  35. package/build/sub/files.ad0469fdf6fa@0+0.wasm +0 -0
  36. package/build/sub/fs.01b8aab4a9a8@0+0.wasm +0 -0
  37. package/build/sub/git.dc4c0e757ebe@0+0.wasm +0 -0
  38. package/build/sub/grants.c54776c0d7e3@0+0.wasm +0 -0
  39. package/build/sub/gzip.16e372eda1cf@0+0.wasm +0 -0
  40. package/build/sub/hash.660682e4f491@0+0.wasm +0 -0
  41. package/build/sub/{html.0b0362932a75@0+0.wasm → html.a23126eb949a@0+0.wasm} +0 -0
  42. package/build/sub/{html.3b3c8d7d9971@0+0.wasm → html.e9ed37f34977@0+0.wasm} +0 -0
  43. package/build/sub/{inflate.3cfa17586072@0+0.wasm → inflate.59bb61f14001@0+0.wasm} +0 -0
  44. package/build/sub/json.55590d2f518a@0+0.wasm +0 -0
  45. package/build/sub/manifest.ef317480deb0@0+0.wasm +0 -0
  46. package/build/sub/{map.e582eae03ec2@0+0.wasm → map.f455cca6a42a@0+0.wasm} +0 -0
  47. package/build/sub/pack.e02836264f6a@0+0.wasm +0 -0
  48. package/build/sub/{path.1b5fd988b6f3@0+0.wasm → path.5a6286472cd4@0+0.wasm} +0 -0
  49. package/build/sub/path.6891ffea73ca@0+0.wasm +0 -0
  50. package/build/sub/process.7106571fa723@0+0.wasm +0 -0
  51. package/build/sub/program +48 -48
  52. package/build/sub/read.0b93933d62a2@0+0.wasm +0 -0
  53. package/build/sub/{reader.d256e69e09e2@0+0.wasm → reader.694b03770bf0@0+0.wasm} +0 -0
  54. package/build/sub/{root.02141d04d568@0+0.wasm → root.f10a4906f460@0+0.wasm} +0 -0
  55. package/build/sub/{roots.e366210c01d6@0+0.wasm → roots.cefd10e93684@0+0.wasm} +0 -0
  56. package/build/sub/{sha256.f6c742932dde@0+0.wasm → sha256.a6c32b04d799@0+0.wasm} +0 -0
  57. package/build/sub/{sha512.9fee24e95460@0+0.wasm → sha512.c24a792d7891@0+0.wasm} +0 -0
  58. package/build/sub/site.1732b58ec0e8@0+0.wasm +0 -0
  59. package/build/sub/site.ae3913b0b0f4@0+0.wasm +0 -0
  60. package/build/sub/store.a24d7a25daa6@0+0.wasm +0 -0
  61. package/build/sub/stream.126e3bd5d626@0+0.wasm +0 -0
  62. package/build/sub/sub.2e3092140706@0+0.wasm +0 -0
  63. package/build/sub/substrate.5ee5d0b4d3e7@0+0.wasm +0 -0
  64. package/build/sub/{syntax.fadc832db29f@0+0.wasm → syntax.32f3e40b61c7@0+0.wasm} +0 -0
  65. package/build/sub/tar.2a633861e654@0+0.wasm +0 -0
  66. package/build/sub/test.9bd59c73f65e@0+0.wasm +0 -0
  67. package/build/sub/{text.8ff142d72fd7@0+0.wasm → text.1bc90482bd43@0+0.wasm} +0 -0
  68. package/build/sub/{timer.d3454726b3bf@0+0.wasm → timer.f35eb62ae446@0+0.wasm} +0 -0
  69. package/build/sub/upgrade.39ee449b00d5@0+0.wasm +0 -0
  70. package/build/sub/{utf8.e82afeb9e953@0+0.wasm → utf8.e7216bd054e1@0+0.wasm} +0 -0
  71. package/build/sub/worker.762a9d642af0@0+0.wasm +0 -0
  72. package/build/sub/writer.00b7802cbe39@0+0.wasm +0 -0
  73. package/package.json +1 -1
  74. package/std/archive/tar.sub +30 -23
  75. package/std/browser/chromium.sub +5 -4
  76. package/std/browser/devtools.sub +24 -19
  77. package/std/compress/gzip.sub +18 -16
  78. package/std/compress/inflate.sub +7 -4
  79. package/std/crypto/password.sub +3 -3
  80. package/std/doc/doc.sub +2 -2
  81. package/std/encoding/json.sub +20 -8
  82. package/std/encoding/wire.sub +9 -7
  83. package/std/http/form.sub +2 -2
  84. package/std/http/multipart.sub +8 -10
  85. package/std/http/route.sub +9 -4
  86. package/std/http/server.sub +14 -11
  87. package/std/http/session.sub +2 -2
  88. package/std/http/static.sub +5 -5
  89. package/std/meta/derive.sub +0 -2
  90. package/std/meta/method.sub +41 -0
  91. package/std/meta/type-info.sub +30 -37
  92. package/std/package/files.sub +24 -25
  93. package/std/package/git.sub +26 -33
  94. package/std/package/hash.sub +8 -8
  95. package/std/package/manifest.sub +67 -42
  96. package/std/package/map.sub +1 -1
  97. package/std/package/pack.sub +13 -13
  98. package/std/package/read.sub +7 -6
  99. package/std/package/site.sub +7 -7
  100. package/std/package/store.sub +16 -12
  101. package/std/package.sub +7 -6
  102. package/std/test/browser.sub +9 -8
  103. package/std/test/build.sub +2 -2
  104. package/std/test/page.sub +31 -26
  105. package/std/test/run.sub +8 -7
  106. package/std/test/test.sub +12 -13
  107. package/std/vector/vector.sub +75 -0
  108. package/std/web/canvas.sub +3 -3
  109. package/std/web/dom.sub +45 -11
  110. package/std/web/gpu-commands.sub +439 -0
  111. package/std/web/gpu.sub +17 -424
  112. package/std/web/patches.sub +45 -10
  113. package/substrate/VERSION +1 -1
  114. package/substrate/compiler/checker.sub +40 -212
  115. package/substrate/compiler/compile.sub +3 -3
  116. package/substrate/compiler/expander.sub +32 -50
  117. package/substrate/compiler/main.sub +9 -9
  118. package/substrate/compiler/reader.sub +4 -4
  119. package/substrate/compiler/roots.sub +8 -8
  120. package/substrate/compiler/running.sub +1 -1
  121. package/substrate/compiler/serialize.sub +56 -49
  122. package/substrate/compiler/substrate.sub +53 -11
  123. package/substrate/host/errors.mjs +3 -2
  124. package/substrate/host/events.sub +3 -16
  125. package/substrate/host/fs.mjs +5 -4
  126. package/substrate/host/fs.sub +135 -102
  127. package/substrate/host/grants.mjs +1 -1
  128. package/substrate/host/grants.sub +8 -7
  129. package/substrate/host/modules/fake.mjs +1 -1
  130. package/substrate/host/modules/websocket.mjs +4 -4
  131. package/substrate/host/modules/websocket.sub +8 -6
  132. package/substrate/host/node/env.mjs +12 -6
  133. package/substrate/host/node/env.sub +21 -16
  134. package/substrate/host/node/fs.mjs +1 -1
  135. package/substrate/host/node/net.mjs +2 -2
  136. package/substrate/host/node/net.sub +13 -6
  137. package/substrate/host/node/process.mjs +4 -4
  138. package/substrate/host/node/process.sub +25 -24
  139. package/substrate/host/node/signal.mjs +3 -2
  140. package/substrate/host/node/signal.sub +9 -6
  141. package/substrate/host/node/watch.mjs +1 -1
  142. package/substrate/host/node/watch.sub +11 -9
  143. package/substrate/host/stream.sub +2 -0
  144. package/substrate/host/subhost-core.mjs +9 -1
  145. package/substrate/host/web/audio.mjs +17 -9
  146. package/substrate/host/web/audio.sub +9 -3
  147. package/substrate/host/web/clipboard.mjs +2 -2
  148. package/substrate/host/web/clipboard.sub +10 -3
  149. package/substrate/host/web/dom.mjs +165 -64
  150. package/substrate/host/web/dom.sub +9 -27
  151. package/substrate/host/web/files.mjs +2 -2
  152. package/substrate/host/web/files.sub +6 -2
  153. package/substrate/host/web/fs.mjs +3 -3
  154. package/substrate/host/web/gpu.mjs +63 -25
  155. package/substrate/host/web/gpu.sub +18 -4
  156. package/substrate/host/web/location.mjs +18 -2
  157. package/substrate/host/web/location.sub +19 -7
  158. package/substrate/host/worker-side.mjs +3 -1
  159. package/substrate/host/worker.mjs +6 -5
  160. package/substrate/host/worker.sub +10 -10
  161. package/build/compiler/checker.2b0ea87ed311@0+0.wasm +0 -0
  162. package/build/compiler/expander.80707e1666d6@0+0.wasm +0 -0
  163. package/build/compiler/fs.5017b627cbd2@0+0.wasm +0 -0
  164. package/build/compiler/reader.d256e69e09e2@0+0.wasm +0 -0
  165. package/build/compiler/roots.e366210c01d6@0+0.wasm +0 -0
  166. package/build/compiler/serialize.a12536bbbe9a@0+0.wasm +0 -0
  167. package/build/compiler/substrate.728c690187f2@0+0.wasm +0 -0
  168. package/build/sub/build.115aeefc15e8@0+0.wasm +0 -0
  169. package/build/sub/chromium.fc0bfea0fbe6@0+0.wasm +0 -0
  170. package/build/sub/common.997c21b0b8cf@0+0.wasm +0 -0
  171. package/build/sub/deflate.3138a38325a1@0+0.wasm +0 -0
  172. package/build/sub/doc.e3f9a998cd91@0+0.wasm +0 -0
  173. package/build/sub/env.861d55fff974@0+0.wasm +0 -0
  174. package/build/sub/events.2c981f6f1ec7@0+0.wasm +0 -0
  175. package/build/sub/fetch.b0ce8f8b3da8@0+0.wasm +0 -0
  176. package/build/sub/fetch.d62aa5fc9623@0+0.wasm +0 -0
  177. package/build/sub/files.1706cc0941c0@0+0.wasm +0 -0
  178. package/build/sub/fs.5017b627cbd2@0+0.wasm +0 -0
  179. package/build/sub/git.1c5791236e35@0+0.wasm +0 -0
  180. package/build/sub/grants.cd99dff2854e@0+0.wasm +0 -0
  181. package/build/sub/gzip.9ebea150f218@0+0.wasm +0 -0
  182. package/build/sub/hash.ba8330dad9ff@0+0.wasm +0 -0
  183. package/build/sub/json.af2e0ae20084@0+0.wasm +0 -0
  184. package/build/sub/manifest.6e014ac19e5d@0+0.wasm +0 -0
  185. package/build/sub/pack.4295e4f5bdbd@0+0.wasm +0 -0
  186. package/build/sub/path.de22f6659534@0+0.wasm +0 -0
  187. package/build/sub/process.ca10ac0b8a62@0+0.wasm +0 -0
  188. package/build/sub/read.279fafcda508@0+0.wasm +0 -0
  189. package/build/sub/site.76aa8286c257@0+0.wasm +0 -0
  190. package/build/sub/site.e6e415bc3170@0+0.wasm +0 -0
  191. package/build/sub/store.c48db3345968@0+0.wasm +0 -0
  192. package/build/sub/stream.27fd2fe858e1@0+0.wasm +0 -0
  193. package/build/sub/sub.c0fb7310de12@0+0.wasm +0 -0
  194. package/build/sub/substrate.728c690187f2@0+0.wasm +0 -0
  195. package/build/sub/tar.692c0e8827cd@0+0.wasm +0 -0
  196. package/build/sub/test.1fd2ff8123bf@0+0.wasm +0 -0
  197. package/build/sub/upgrade.2a9219e6a45d@0+0.wasm +0 -0
  198. package/build/sub/worker.ea1e11f8f5e2@0+0.wasm +0 -0
  199. package/build/sub/writer.550227768eb9@0+0.wasm +0 -0
@@ -50,7 +50,7 @@ export function netModule(grants, certificate) {
50
50
  });
51
51
  } else server.listen(port, host);
52
52
  } catch (e) {
53
- caller.fail(err, e.message);
53
+ caller.fail(err, e.message, errorOf(e));
54
54
  return 0;
55
55
  }
56
56
  id = next++;
@@ -81,7 +81,7 @@ export function netModule(grants, certificate) {
81
81
  ? tls.connect({ host, port, servername, ca, allowHalfOpen: true, lookup })
82
82
  : net.connect({ host, port, allowHalfOpen: true, lookup });
83
83
  } catch (e) {
84
- caller.fail(err, e.message);
84
+ caller.fail(err, e.message, errorOf(e));
85
85
  return 0;
86
86
  }
87
87
  let connected = false;
@@ -14,12 +14,19 @@
14
14
  (const net-connected u32 3)
15
15
  (const net-failed u32 4)
16
16
 
17
- (define (net-listen [port u32] [host string] [secure bool] [most u32] [tag (ptr void)] [err (ptr string)]) -> u32
18
- (cast u32 (listen (cast i32 port) (cast i32 (-> host bytes)) (cast i32 (-> host length)) secure (cast i32 most)
19
- (cast i32 tag) (cast i32 err))))
17
+ (define (net-listen [port u32] [host string] [secure bool] [most u32] [tag (ptr void)] [id (ptr u32)]
18
+ [err (ptr error)]) -> bool
19
+ (let ([why string] [n u32 0])
20
+ (set! n (cast u32 (listen (cast i32 port) (cast i32 (-> host bytes)) (cast i32 (-> host length)) secure
21
+ (cast i32 most) (cast i32 tag) (cast i32 (& why)))))
22
+ (unless (== id 0) (set! (@ id) n))
23
+ (or (!= n 0) (host-failed! (& why) err))))
20
24
 
21
- (define (net-connect [port u32] [host string] [secure bool] [tag (ptr void)] [err (ptr string)]) -> u32
22
- (cast u32 (connect (cast i32 port) (cast i32 (-> host bytes)) (cast i32 (-> host length)) secure (cast i32 tag)
23
- (cast i32 err))))
25
+ (define (net-connect [port u32] [host string] [secure bool] [tag (ptr void)] [id (ptr u32)] [err (ptr error)]) -> bool
26
+ (let ([why string] [n u32 0])
27
+ (set! n (cast u32 (connect (cast i32 port) (cast i32 (-> host bytes)) (cast i32 (-> host length)) secure
28
+ (cast i32 tag) (cast i32 (& why)))))
29
+ (unless (== id 0) (set! (@ id) n))
30
+ (or (!= n 0) (host-failed! (& why) err))))
24
31
 
25
32
  (define (net-close [id u32]) (close (cast i32 id)))
@@ -84,7 +84,7 @@ export function processes(grants, loader, setup = {}) {
84
84
  const l = launched(file ?? program, entries(caller.string(ap, al)));
85
85
  process = child.spawn(l.command, l.args, { cwd, env, stdio: modes });
86
86
  } catch (e) {
87
- caller.fail(err, e.message);
87
+ caller.fail(err, e.message, errorOf(e));
88
88
  return 0;
89
89
  }
90
90
  const id = next++;
@@ -130,7 +130,7 @@ export function processes(grants, loader, setup = {}) {
130
130
  new DataView(caller.memory().buffer).setUint32(caller.u(op), p, true);
131
131
  return r.status !== null ? r.status : 128 + (os.constants.signals[r.signal] || 0);
132
132
  } catch (e) {
133
- caller.fail(err, e.message);
133
+ caller.fail(err, e.message, errorOf(e));
134
134
  return -1;
135
135
  } finally {
136
136
  if (dir) fs.rmSync(dir, { recursive: true, force: true });
@@ -146,7 +146,7 @@ export function processes(grants, loader, setup = {}) {
146
146
  const l = launched(file ?? program, entries(caller.string(ap, al)), program);
147
147
  become(l.command, [l.argv0, ...l.args], env);
148
148
  } catch (e) {
149
- caller.fail(err, e.message);
149
+ caller.fail(err, e.message, errorOf(e));
150
150
  }
151
151
  return -1;
152
152
  },
@@ -161,7 +161,7 @@ export function processes(grants, loader, setup = {}) {
161
161
  const l = launched(file ?? program, entries(caller.string(ap, al)), program);
162
162
  setup.atEnd = { file: l.command, argv: [l.argv0, ...l.args], env };
163
163
  } catch (e) {
164
- caller.fail(err, e.message);
164
+ caller.fail(err, e.message, errorOf(e));
165
165
  return -1;
166
166
  }
167
167
  return 0;
@@ -33,54 +33,55 @@
33
33
  (set! (-> o stdout) process-pipe)
34
34
  (set! (-> o stderr) process-pipe))
35
35
 
36
- (define (process-spawn [program string] [args (slice string)] [o (ptr process-options)] [tag (ptr void)]
37
- [err (ptr string)]) -> u32
38
- (let ([defaults process-options] [p o] [a (make-buffer)] [e (make-buffer)] [id u32 0])
36
+ (define (process-spawn [program string] [args (slice string)] [o (ptr process-options)] [tag (ptr void)] [id (ptr u32)]
37
+ [err (ptr error)]) -> bool
38
+ (let ([defaults process-options] [p o] [a (make-buffer)] [e (make-buffer)] [why string] [n u32 0])
39
39
  (when (== p 0)
40
40
  (process-options-init! (& defaults))
41
41
  (set! p (& defaults)))
42
42
  (buffer-add-entries! (& a) args)
43
43
  (buffer-add-entries! (& e) (-> p env))
44
- (set! id (cast u32 (spawn (cast i32 (-> program bytes)) (cast i32 (-> program length)) (cast i32 (-> a bytes))
45
- (cast i32 (-> a length)) (cast i32 (-> p dir bytes)) (cast i32 (-> p dir length))
46
- (cast i32 (-> e bytes)) (cast i32 (-> e length)) (-> p clear) (cast i32 (-> p stdin))
47
- (cast i32 (-> p stdout)) (cast i32 (-> p stderr)) (cast i32 tag) (cast i32 err))))
44
+ (set! n (cast u32 (spawn (cast i32 (-> program bytes)) (cast i32 (-> program length)) (cast i32 (-> a bytes))
45
+ (cast i32 (-> a length)) (cast i32 (-> p dir bytes)) (cast i32 (-> p dir length))
46
+ (cast i32 (-> e bytes)) (cast i32 (-> e length)) (-> p clear) (cast i32 (-> p stdin))
47
+ (cast i32 (-> p stdout)) (cast i32 (-> p stderr)) (cast i32 tag) (cast i32 (& why)))))
48
48
  (buffer-free! (& a))
49
49
  (buffer-free! (& e))
50
- id))
50
+ (unless (== id 0) (set! (@ id) n))
51
+ (or (!= n 0) (host-failed! (& why) err))))
51
52
 
52
53
  (define (process-run [program string] [args (slice string)] [o (ptr process-options)] [input (slice u8)] [timeout u32]
53
- [output (ptr (slice u8))] [err (ptr string)]) -> i32
54
- (let ([defaults process-options] [p o] [a (make-buffer)] [e (make-buffer)] [code i32 0])
54
+ [output (ptr (slice u8))] [status (ptr i32)] [err (ptr error)]) -> bool
55
+ (let ([defaults process-options] [p o] [a (make-buffer)] [e (make-buffer)] [why string])
55
56
  (when (== p 0)
56
57
  (process-options-init! (& defaults))
57
58
  (set! p (& defaults)))
58
59
  (set! (@ output) (slice (cast (ptr u8) 0) 0))
59
60
  (buffer-add-entries! (& a) args)
60
61
  (buffer-add-entries! (& e) (-> p env))
61
- (set! code (run (cast i32 (-> program bytes)) (cast i32 (-> program length)) (cast i32 (-> a bytes)) (cast i32 (-> a length))
62
- (cast i32 (-> p dir bytes)) (cast i32 (-> p dir length)) (cast i32 (-> e bytes)) (cast i32 (-> e length))
63
- (-> p clear) (cast i32 (-> input items)) (cast i32 (-> input length)) (cast i32 timeout)
64
- (cast i32 output) (cast i32 err)))
62
+ (set! (@ status) (run (cast i32 (-> program bytes)) (cast i32 (-> program length)) (cast i32 (-> a bytes))
63
+ (cast i32 (-> a length)) (cast i32 (-> p dir bytes)) (cast i32 (-> p dir length))
64
+ (cast i32 (-> e bytes)) (cast i32 (-> e length)) (-> p clear) (cast i32 (-> input items))
65
+ (cast i32 (-> input length)) (cast i32 timeout) (cast i32 output) (cast i32 (& why))))
65
66
  (buffer-free! (& a))
66
67
  (buffer-free! (& e))
67
- code))
68
+ (or (>= (@ status) 0) (host-failed! (& why) err))))
68
69
 
69
- (define (process-exec [program string] [args (slice string)] [err (ptr string)]) -> i32
70
- (let ([a (make-buffer)] [r i32 0])
70
+ (define (process-exec [program string] [args (slice string)] [err (ptr error)]) -> bool
71
+ (let ([a (make-buffer)] [why string])
71
72
  (buffer-add-entries! (& a) args)
72
- (set! r (exec (cast i32 (-> program bytes)) (cast i32 (-> program length)) (cast i32 (-> a bytes)) (cast i32 (-> a length))
73
- (cast i32 err)))
73
+ (exec (cast i32 (-> program bytes)) (cast i32 (-> program length)) (cast i32 (-> a bytes)) (cast i32 (-> a length))
74
+ (cast i32 (& why)))
74
75
  (buffer-free! (& a))
75
- r))
76
+ (host-failed! (& why) err)))
76
77
 
77
- (define (process-exec-at-end [program string] [args (slice string)] [err (ptr string)]) -> i32
78
- (let ([a (make-buffer)] [r i32 0])
78
+ (define (process-exec-at-end [program string] [args (slice string)] [err (ptr error)]) -> bool
79
+ (let ([a (make-buffer)] [r i32 0] [why string])
79
80
  (buffer-add-entries! (& a) args)
80
81
  (set! r (exec-at-end (cast i32 (-> program bytes)) (cast i32 (-> program length)) (cast i32 (-> a bytes))
81
- (cast i32 (-> a length)) (cast i32 err)))
82
+ (cast i32 (-> a length)) (cast i32 (& why))))
82
83
  (buffer-free! (& a))
83
- r))
84
+ (or (== r 0) (host-failed! (& why) err))))
84
85
 
85
86
  (define (process-stdin [id u32]) -> u32 (cast u32 (stdin (cast i32 id))))
86
87
 
@@ -1,5 +1,6 @@
1
1
  // The host module "signal" (signal.sub) on Node.
2
2
  import os from 'node:os';
3
+ import { errors } from '../errors.mjs';
3
4
 
4
5
  const SOURCE = 16;
5
6
  const RECEIVED = 1;
@@ -18,11 +19,11 @@ export function signals() {
18
19
  listen(np, nl, tag, err) {
19
20
  const name = caller.string(np, nl);
20
21
  if (!Object.hasOwn(os.constants.signals, name)) {
21
- caller.fail(err, `signal.listen: ${name} is not a signal`);
22
+ caller.fail(err, `signal.listen: ${name} is not a signal`, errors.invalid);
22
23
  return 0;
23
24
  }
24
25
  if (forbidden.has(name)) {
25
- caller.fail(err, `signal.listen: ${name} cannot be listened for`);
26
+ caller.fail(err, `signal.listen: ${name} cannot be listened for`, errors.invalid);
26
27
  return 0;
27
28
  }
28
29
  const id = next++;
@@ -1,8 +1,7 @@
1
1
  ;; Signals to the program: the host module "signal", after Deno's addSignalListener. signal-listen listens for the
2
- ;; signal named, such as "SIGINT" or "SIGTERM", and returns the listener's number, or 0 with the reason at err; while
3
- ;; any listener is there, the signal no longer ends the program, and a listener alone does not keep it running. A
4
- ;; received event comes each time the signal arrives. SIGKILL, SIGSTOP, SIGILL, SIGFPE and SIGSEGV cannot be listened
5
- ;; for, and a worker has no signals.
2
+ ;; signal named, such as "SIGINT" or "SIGTERM". While any listener is there, the signal no longer ends the program, and
3
+ ;; a listener alone does not keep it running. A received event comes each time the signal arrives. SIGKILL, SIGSTOP,
4
+ ;; SIGILL, SIGFPE and SIGSEGV cannot be listened for, and a worker has no signals.
6
5
  (provide signal-source signal-received signal-listen signal-stop)
7
6
 
8
7
  (import listen "signal" "listen" (i32 i32 i32 i32 -> i32))
@@ -11,7 +10,11 @@
11
10
  (const signal-source u32 16)
12
11
  (const signal-received u32 1)
13
12
 
14
- (define (signal-listen [name string] [tag (ptr void)] [err (ptr string)]) -> u32
15
- (cast u32 (listen (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 tag) (cast i32 err))))
13
+ (define (signal-listen [name string] [tag (ptr void)] [id (ptr u32)] [err (ptr error)]) -> bool
14
+ (let ([why string] [n u32 0])
15
+ (set! n (cast u32 (listen (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 tag)
16
+ (cast i32 (& why)))))
17
+ (unless (== id 0) (set! (@ id) n))
18
+ (or (!= n 0) (host-failed! (& why) err))))
16
19
 
17
20
  (define (signal-stop [id u32]) (stop (cast i32 id)))
@@ -60,7 +60,7 @@ export function watchModule(grants) {
60
60
  return id;
61
61
  } catch (e) {
62
62
  close(w);
63
- caller.fail(err, `watch.start: ${at}: ${plainMessage(e)}`);
63
+ caller.fail(err, `watch.start: ${at}: ${plainMessage(e)}`, errorOf(e));
64
64
  return 0;
65
65
  }
66
66
  },
@@ -1,8 +1,7 @@
1
1
  ;; Watching files: the host module "watch", after Deno's watchFs. watch-start watches the paths, and everything under
2
- ;; them unless the options' recursive is #f, and returns the watch's number, or 0 with the reason at err. A changed
3
- ;; event's value is watch-create, watch-modify or watch-remove, and its bytes are the absolute paths it is about, as
4
- ;; entries; a rename comes as a remove and a create. Changes under the options' ignore paths are left out. A failed
5
- ;; event ends the watch.
2
+ ;; them unless the options' recursive is #f. A changed event's value is watch-create, watch-modify or watch-remove, and
3
+ ;; its bytes are the absolute paths it is about, as entries; a rename comes as a remove and a create. Changes under the
4
+ ;; options' ignore paths are left out. A failed event ends the watch.
6
5
  (provide watch-source watch-changed watch-failed watch-create watch-modify watch-remove watch-options
7
6
  watch-options-init! watch-start watch-stop)
8
7
 
@@ -23,17 +22,20 @@
23
22
  (set! (-> o recursive) #t)
24
23
  (set! (-> o ignore) 0))
25
24
 
26
- (define (watch-start [paths (slice string)] [o (ptr watch-options)] [tag (ptr void)] [err (ptr string)]) -> u32
27
- (let ([defaults watch-options] [p o] [watched (make-buffer)] [ignored (make-buffer)] [id u32 0])
25
+ (define (watch-start [paths (slice string)] [o (ptr watch-options)] [tag (ptr void)] [id (ptr u32)] [err (ptr error)])
26
+ -> bool
27
+ (let ([defaults watch-options] [p o] [watched (make-buffer)] [ignored (make-buffer)] [why string] [n u32 0])
28
28
  (when (== p 0)
29
29
  (watch-options-init! (& defaults))
30
30
  (set! p (& defaults)))
31
31
  (buffer-add-entries! (& watched) paths)
32
32
  (buffer-add-entries! (& ignored) (-> p ignore))
33
- (set! id (cast u32 (start (cast i32 (-> watched bytes)) (cast i32 (-> watched length)) (-> p recursive)
34
- (cast i32 (-> ignored bytes)) (cast i32 (-> ignored length)) (cast i32 tag) (cast i32 err))))
33
+ (set! n (cast u32 (start (cast i32 (-> watched bytes)) (cast i32 (-> watched length)) (-> p recursive)
34
+ (cast i32 (-> ignored bytes)) (cast i32 (-> ignored length)) (cast i32 tag)
35
+ (cast i32 (& why)))))
35
36
  (buffer-free! (& watched))
36
37
  (buffer-free! (& ignored))
37
- id))
38
+ (unless (== id 0) (set! (@ id) n))
39
+ (or (!= n 0) (host-failed! (& why) err))))
38
40
 
39
41
  (define (watch-stop [w u32]) (stop (cast i32 w)))
@@ -1,6 +1,8 @@
1
1
  ;; Byte streams: the host module "stream", whose ids other modules give out. A read event's value is how many bytes
2
2
  ;; were read, or 0 at the end. A read that stream-take! posts holds no room: its event carries the bytes, at most
3
3
  ;; most of them, for events-take. A finished event comes once everything written before stream-finish has been sent.
4
+ ;; stream-write returns 0 when the stream can take more, and 1 when it is full. It takes the bytes in both cases. After
5
+ ;; a 1, wait for a drained event before writing again. It returns -1 when the stream is not open.
4
6
  (require-unqualified "events.sub")
5
7
 
6
8
  (provide stream-source stream-read stream-drained stream-failed stream-finished
@@ -1,6 +1,7 @@
1
1
  // The JavaScript host, shared by Node (subhost.mjs) and the browser (web/subhost-web.mjs).
2
2
  import { createStreams, STREAM } from './streams.mjs';
3
3
  import { joined } from './entries.mjs';
4
+ import { errors } from './errors.mjs';
4
5
 
5
6
  const utf8 = new TextEncoder();
6
7
  const text = new TextDecoder();
@@ -174,6 +175,7 @@ export function createHost(platform) {
174
175
  // A memory's malloc, from the module that exports both.
175
176
  const allocators = new WeakMap();
176
177
  let lastError = '';
178
+ let failureCode = errors.other;
177
179
  // The running program: its module names in load order, a function that returns a module's bytes, and the files of
178
180
  // the compiled modules its build wrote, keyed by file name (null if it wrote none).
179
181
  let programNames = [];
@@ -330,7 +332,8 @@ export function createHost(platform) {
330
332
  trap: hostTrap,
331
333
  write: (fd, bytes) => platform.write(fd === 2 ? 2 : 1, bytes),
332
334
  give,
333
- fail(err, message) {
335
+ fail(err, message, code = errors.other) {
336
+ failureCode = code;
334
337
  if (!err) return;
335
338
  const p = give(utf8.encode(message), u(err) + 4);
336
339
  new DataView(memory().buffer).setUint32(u(err), p, true);
@@ -377,6 +380,11 @@ export function createHost(platform) {
377
380
  platform.write(fd === 2 ? 2 : 1, memory().subarray(u(ptr), u(ptr) + len));
378
381
  return len;
379
382
  },
383
+ failure_code() {
384
+ const code = failureCode;
385
+ failureCode = errors.other;
386
+ return code;
387
+ },
380
388
  trap(ptr, len) {
381
389
  hostTrap(string(ptr, len));
382
390
  },
@@ -14,7 +14,13 @@ export function audio() {
14
14
  let started = 0;
15
15
 
16
16
  const sounds = new Map();
17
- let loading = 0;
17
+ let nextSound = 1;
18
+ const loading = new Map();
19
+ const counted = (tag, n) => {
20
+ const k = (loading.get(tag) || 0) + n;
21
+ if (k === 0) loading.delete(tag);
22
+ else loading.set(tag, k);
23
+ };
18
24
  let decoder = null;
19
25
 
20
26
  const voices = new Map();
@@ -60,11 +66,12 @@ export function audio() {
60
66
 
61
67
  const module = (caller, app) => ({
62
68
  source: SOURCE,
63
- load(id, ptr, length) {
69
+ load(ptr, length, tag) {
70
+ const id = nextSound++;
64
71
  const name = caller.string(ptr, length);
65
72
  const bytes = app.files.get(resolvePath(app.cwd, name));
66
73
  if (!decoder) decoder = new OfflineAudioContext(1, 1, 44100);
67
- loading++;
74
+ counted(tag, 1);
68
75
  const data = bytes
69
76
  ? Promise.resolve(bytes.slice().buffer)
70
77
  : fetch(name).then((response) => {
@@ -74,21 +81,22 @@ export function audio() {
74
81
  data.then((buffer) => decoder.decodeAudioData(buffer)).then(
75
82
  (decoded) => {
76
83
  sounds.set(id, decoded);
77
- loading--;
84
+ counted(tag, -1);
78
85
  startWaiting();
79
- caller.event(LOADED, id, 0, 0);
86
+ caller.event(LOADED, id, tag, 0);
80
87
  },
81
88
  (e) => {
82
89
  console.error(`audio: cannot load the sound ${name}: ${e.message}`);
83
- loading--;
90
+ counted(tag, -1);
84
91
  startWaiting();
85
- caller.event(FAILED, id, 0, e.name === 'EncodingError' ? errors.invalid : errors.missing,
92
+ caller.event(FAILED, id, tag, e.name === 'EncodingError' ? errors.invalid : errors.missing,
86
93
  utf8.encode(`cannot load the sound ${name}: ${e.message}`));
87
94
  },
88
95
  );
96
+ return id;
89
97
  },
90
- loading() {
91
- return loading;
98
+ loading(tag) {
99
+ return loading.get(tag) || 0;
92
100
  },
93
101
  play(id, volume, rate, loop) {
94
102
  played++;
@@ -1,4 +1,5 @@
1
- ;; Sound: the host module "audio".
1
+ ;; Sound: the host module "audio". audio-load gives the sound's number, and its loaded or failed event goes to tag.
2
+ ;; audio-loading counts the sounds loading for a tag.
2
3
  (provide audio-source audio-loaded audio-failed audio-tone audio-load audio-loading audio-play audio-stop)
3
4
 
4
5
  (const audio-source u32 4)
@@ -6,7 +7,12 @@
6
7
  (const audio-failed u32 2)
7
8
 
8
9
  (import audio-tone "audio" "tone" (i32 f64 f64 f64 f64 ->))
9
- (import audio-load "audio" "load" (i32 i32 i32 ->))
10
- (import audio-loading "audio" "loading" (-> i32))
10
+ (import load "audio" "load" (i32 i32 i32 -> i32))
11
+ (import loading "audio" "loading" (i32 -> i32))
11
12
  (import audio-play "audio" "play" (i32 f64 f64 i32 -> i32))
12
13
  (import audio-stop "audio" "stop" (i32 ->))
14
+
15
+ (define (audio-load [path string] [tag (ptr void)]) -> u32
16
+ (cast u32 (load (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 tag))))
17
+
18
+ (define (audio-loading [tag (ptr void)]) -> u32 (cast u32 (loading (cast i32 tag))))
@@ -1,5 +1,5 @@
1
1
  // The host module "clipboard" (clipboard.sub).
2
- import { errorOf, reasonOf } from '../errors.mjs';
2
+ import { errors, errorOf, reasonOf } from '../errors.mjs';
3
3
 
4
4
  const utf8 = new TextEncoder();
5
5
 
@@ -14,7 +14,7 @@ export function clipboard() {
14
14
  let ended = false;
15
15
  const attempt = (tag, err, ask, answer) => {
16
16
  if (!navigator.clipboard) {
17
- caller.fail(err, 'clipboard: none');
17
+ caller.fail(err, 'clipboard: none', errors.other);
18
18
  return 0;
19
19
  }
20
20
  const id = next++;
@@ -9,7 +9,14 @@
9
9
  (const clipboard-written u32 2)
10
10
  (const clipboard-failed u32 3)
11
11
 
12
- (define (clipboard-read [tag (ptr void)] [err (ptr string)]) -> u32 (cast u32 (read (cast i32 tag) (cast i32 err))))
12
+ (define (clipboard-read [tag (ptr void)] [id (ptr u32)] [err (ptr error)]) -> bool
13
+ (let ([why string] [n u32 0])
14
+ (set! n (cast u32 (read (cast i32 tag) (cast i32 (& why)))))
15
+ (unless (== id 0) (set! (@ id) n))
16
+ (or (!= n 0) (host-failed! (& why) err))))
13
17
 
14
- (define (clipboard-write [text string] [tag (ptr void)] [err (ptr string)]) -> u32
15
- (cast u32 (write (cast i32 (-> text bytes)) (cast i32 (-> text length)) (cast i32 tag) (cast i32 err))))
18
+ (define (clipboard-write [text string] [tag (ptr void)] [id (ptr u32)] [err (ptr error)]) -> bool
19
+ (let ([why string] [n u32 0])
20
+ (set! n (cast u32 (write (cast i32 (-> text bytes)) (cast i32 (-> text length)) (cast i32 tag) (cast i32 (& why)))))
21
+ (unless (== id 0) (set! (@ id) n))
22
+ (or (!= n 0) (host-failed! (& why) err))))