substrate-lang 0.9.4 → 0.10.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 (188) 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 +6 -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/substrate/VERSION +1 -1
  109. package/substrate/compiler/checker.sub +40 -212
  110. package/substrate/compiler/compile.sub +3 -3
  111. package/substrate/compiler/expander.sub +32 -50
  112. package/substrate/compiler/main.sub +9 -9
  113. package/substrate/compiler/reader.sub +4 -4
  114. package/substrate/compiler/roots.sub +8 -8
  115. package/substrate/compiler/running.sub +1 -1
  116. package/substrate/compiler/serialize.sub +56 -49
  117. package/substrate/compiler/substrate.sub +53 -11
  118. package/substrate/host/errors.mjs +3 -2
  119. package/substrate/host/events.sub +3 -16
  120. package/substrate/host/fs.mjs +5 -4
  121. package/substrate/host/fs.sub +135 -102
  122. package/substrate/host/grants.mjs +1 -1
  123. package/substrate/host/grants.sub +8 -7
  124. package/substrate/host/modules/fake.mjs +1 -1
  125. package/substrate/host/modules/websocket.mjs +4 -4
  126. package/substrate/host/modules/websocket.sub +8 -6
  127. package/substrate/host/node/env.mjs +12 -6
  128. package/substrate/host/node/env.sub +21 -16
  129. package/substrate/host/node/fs.mjs +1 -1
  130. package/substrate/host/node/net.mjs +2 -2
  131. package/substrate/host/node/net.sub +13 -6
  132. package/substrate/host/node/process.mjs +4 -4
  133. package/substrate/host/node/process.sub +25 -24
  134. package/substrate/host/node/signal.mjs +3 -2
  135. package/substrate/host/node/signal.sub +9 -6
  136. package/substrate/host/node/watch.mjs +1 -1
  137. package/substrate/host/node/watch.sub +11 -9
  138. package/substrate/host/stream.sub +2 -0
  139. package/substrate/host/subhost-core.mjs +9 -1
  140. package/substrate/host/web/clipboard.mjs +2 -2
  141. package/substrate/host/web/clipboard.sub +10 -3
  142. package/substrate/host/web/files.mjs +2 -2
  143. package/substrate/host/web/files.sub +6 -2
  144. package/substrate/host/web/fs.mjs +3 -3
  145. package/substrate/host/web/location.mjs +3 -1
  146. package/substrate/host/web/location.sub +8 -4
  147. package/substrate/host/worker-side.mjs +3 -1
  148. package/substrate/host/worker.mjs +6 -5
  149. package/substrate/host/worker.sub +10 -10
  150. package/build/compiler/checker.2b0ea87ed311@0+0.wasm +0 -0
  151. package/build/compiler/expander.80707e1666d6@0+0.wasm +0 -0
  152. package/build/compiler/fs.5017b627cbd2@0+0.wasm +0 -0
  153. package/build/compiler/reader.d256e69e09e2@0+0.wasm +0 -0
  154. package/build/compiler/roots.e366210c01d6@0+0.wasm +0 -0
  155. package/build/compiler/serialize.a12536bbbe9a@0+0.wasm +0 -0
  156. package/build/compiler/substrate.728c690187f2@0+0.wasm +0 -0
  157. package/build/sub/build.115aeefc15e8@0+0.wasm +0 -0
  158. package/build/sub/chromium.fc0bfea0fbe6@0+0.wasm +0 -0
  159. package/build/sub/common.997c21b0b8cf@0+0.wasm +0 -0
  160. package/build/sub/deflate.3138a38325a1@0+0.wasm +0 -0
  161. package/build/sub/doc.e3f9a998cd91@0+0.wasm +0 -0
  162. package/build/sub/env.861d55fff974@0+0.wasm +0 -0
  163. package/build/sub/events.2c981f6f1ec7@0+0.wasm +0 -0
  164. package/build/sub/fetch.b0ce8f8b3da8@0+0.wasm +0 -0
  165. package/build/sub/fetch.d62aa5fc9623@0+0.wasm +0 -0
  166. package/build/sub/files.1706cc0941c0@0+0.wasm +0 -0
  167. package/build/sub/fs.5017b627cbd2@0+0.wasm +0 -0
  168. package/build/sub/git.1c5791236e35@0+0.wasm +0 -0
  169. package/build/sub/grants.cd99dff2854e@0+0.wasm +0 -0
  170. package/build/sub/gzip.9ebea150f218@0+0.wasm +0 -0
  171. package/build/sub/hash.ba8330dad9ff@0+0.wasm +0 -0
  172. package/build/sub/json.af2e0ae20084@0+0.wasm +0 -0
  173. package/build/sub/manifest.6e014ac19e5d@0+0.wasm +0 -0
  174. package/build/sub/pack.4295e4f5bdbd@0+0.wasm +0 -0
  175. package/build/sub/path.de22f6659534@0+0.wasm +0 -0
  176. package/build/sub/process.ca10ac0b8a62@0+0.wasm +0 -0
  177. package/build/sub/read.279fafcda508@0+0.wasm +0 -0
  178. package/build/sub/site.76aa8286c257@0+0.wasm +0 -0
  179. package/build/sub/site.e6e415bc3170@0+0.wasm +0 -0
  180. package/build/sub/store.c48db3345968@0+0.wasm +0 -0
  181. package/build/sub/stream.27fd2fe858e1@0+0.wasm +0 -0
  182. package/build/sub/sub.c0fb7310de12@0+0.wasm +0 -0
  183. package/build/sub/substrate.728c690187f2@0+0.wasm +0 -0
  184. package/build/sub/tar.692c0e8827cd@0+0.wasm +0 -0
  185. package/build/sub/test.1fd2ff8123bf@0+0.wasm +0 -0
  186. package/build/sub/upgrade.2a9219e6a45d@0+0.wasm +0 -0
  187. package/build/sub/worker.ea1e11f8f5e2@0+0.wasm +0 -0
  188. package/build/sub/writer.550227768eb9@0+0.wasm +0 -0
@@ -1,27 +1,14 @@
1
1
  ;; Events from the host. events-take gives the current event's bytes as host calls give them, events-take-text its
2
2
  ;; text and events-take-strings its list; event-handler! sets the handler for a source's untagged events, and a tagged
3
- ;; event goes to its tag's handler (compiler/substrate.sub). A failed event's value is one of the error codes here,
4
- ;; and its text is the reason.
3
+ ;; event goes to its tag's handler (compiler/substrate.sub). A failed event's value is one of the error codes
4
+ ;; (compiler/substrate.sub), and its text is the reason.
5
5
  ;; Sources: dom 1, gpu 2, worker 3, audio 4, timer 5, fetch 6, websocket 7, stream 8, net 9, process 10, storage 11,
6
6
  ;; location 12, clipboard 13, files 14.
7
7
 
8
- (provide events-take events-take! events-take-text events-take-strings event-handler!
9
- error-missing error-unreachable error-refused error-timeout error-invalid error-aborted error-denied
10
- error-in-use error-other error-not-granted)
8
+ (provide events-take events-take! events-take-text events-take-strings event-handler!)
11
9
 
12
10
  (import take "events" "take" (i32 -> i32))
13
11
 
14
- (const error-missing i32 1)
15
- (const error-unreachable i32 2)
16
- (const error-refused i32 3)
17
- (const error-timeout i32 4)
18
- (const error-invalid i32 5)
19
- (const error-aborted i32 6)
20
- (const error-denied i32 7)
21
- (const error-in-use i32 8)
22
- (const error-other i32 9)
23
- (const error-not-granted i32 10)
24
-
25
12
  (define defaults (array handler 64))
26
13
 
27
14
  (define (by-source [source u32] [kind u32] [id u32] [tag (ptr void)] [value i32])
@@ -1,5 +1,6 @@
1
1
  // The host module "fs" (fs.sub), over the files that node/fs.mjs or web/fs.mjs gives.
2
2
  import { joined } from './entries.mjs';
3
+ import { errors, errorOf } from './errors.mjs';
3
4
 
4
5
  const utf8 = new TextEncoder();
5
6
 
@@ -22,7 +23,7 @@ export function fsModule(files) {
22
23
  return f();
23
24
  } catch (e) {
24
25
  if (e instanceof WebAssembly.RuntimeError) throw e;
25
- caller.fail(err, `${path}: ${e.message}`);
26
+ caller.fail(err, `${path}: ${e.message}`, errorOf(e));
26
27
  return failed;
27
28
  }
28
29
  };
@@ -31,7 +32,7 @@ export function fsModule(files) {
31
32
  const using = (h, err, f, failed = -1) => {
32
33
  const open = handles.get(h);
33
34
  if (open) return attempt(open.path, err, () => f(open.file), failed);
34
- caller.fail(err, `file ${h}: Bad file descriptor`);
35
+ caller.fail(err, `file ${h}: Bad file descriptor`, errors.invalid);
35
36
  return failed;
36
37
  };
37
38
  const bytesAt = (ptr, len) => caller.memory().subarray(caller.u(ptr), caller.u(ptr) + len);
@@ -81,7 +82,7 @@ export function fsModule(files) {
81
82
  file_stream(h, write, start, tag, err) {
82
83
  const open = handles.get(h);
83
84
  if (!open) {
84
- caller.fail(err, `file ${h}: Bad file descriptor`);
85
+ caller.fail(err, `file ${h}: Bad file descriptor`, errors.invalid);
85
86
  return 0;
86
87
  }
87
88
  handles.delete(h);
@@ -90,7 +91,7 @@ export function fsModule(files) {
90
91
  } catch (e) {
91
92
  if (e instanceof WebAssembly.RuntimeError) throw e;
92
93
  attempt(open.path, 0, () => open.file.close());
93
- caller.fail(err, `${open.path}: ${e.message}`);
94
+ caller.fail(err, `${open.path}: ${e.message}`, errorOf(e));
94
95
  return 0;
95
96
  }
96
97
  },
@@ -1,8 +1,7 @@
1
1
  ;; Files: the host module "fs", on paths and on open files. fs-list stores a directory's names
2
2
  ;; at into, and fs-read-link, fs-real-path, fs-make-temp-dir, fs-make-temp-file and fs-cwd a path, as host calls give
3
3
  ;; them. fs-stat fills an fs-info, and fs-lstat does too without following a link at the end of the path. fs-remove
4
- ;; removes a file, a link or an empty directory, or when recursive a directory and everything in it. The calls return
5
- ;; 0, or -1 when they fail, and store a failure's reason at err.
4
+ ;; removes a file, a link or an empty directory, or when recursive a directory and everything in it.
6
5
  (provide fs-read-file fs-write-file fs-make-dir fs-info fs-stat fs-lstat fs-list fs-remove fs-rename
7
6
  fs-read-link fs-real-path fs-symlink fs-copy fs-chmod fs-make-temp-dir fs-make-temp-file
8
7
  fs-cwd fs-kind fs-none fs-file fs-directory fs-link fs-other
@@ -37,84 +36,101 @@
37
36
  ;; modified is in milliseconds since 1970, and mode is the file's mode bits, its type's included.
38
37
  (struct fs-info [kind fs-kind] [size i64] [modified f64] [mode u32])
39
38
 
40
- (define (fs-make-dir [path string] [err (ptr string)]) -> i32
41
- (make_dir (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 err)))
39
+ (define (done [r i32] [why (ptr string)] [err (ptr error)]) -> bool (or (== r 0) (host-failed! why err)))
42
40
 
43
- (define (stat-of [path string] [follow bool] [i (ptr fs-info)] [err (ptr string)]) -> i32
44
- (let ([(kind size modified mode) (info (cast i32 (-> path bytes)) (cast i32 (-> path length)) follow (cast i32 err))])
45
- (set! (-> i kind) (cast fs-kind kind))
46
- (set! (-> i size) (cast i64 size))
47
- (set! (-> i modified) modified)
48
- (set! (-> i mode) (cast u32 mode))
49
- (if (== kind 0) -1 0)))
41
+ (define (fs-make-dir [path string] [err (ptr error)]) -> bool
42
+ (let ([why string])
43
+ (done (make_dir (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& why))) (& why) err)))
50
44
 
51
- (define (fs-stat [path string] [i (ptr fs-info)] [err (ptr string)]) -> i32 (stat-of path #t i err))
45
+ (define (stat-of [path string] [follow bool] [i (ptr fs-info)] [err (ptr error)]) -> bool
46
+ (let ([why string])
47
+ (let ([(kind size modified mode)
48
+ (info (cast i32 (-> path bytes)) (cast i32 (-> path length)) follow (cast i32 (& why)))])
49
+ (set! (-> i kind) (cast fs-kind kind))
50
+ (set! (-> i size) (cast i64 size))
51
+ (set! (-> i modified) modified)
52
+ (set! (-> i mode) (cast u32 mode))
53
+ (or (!= kind 0) (host-failed! (& why) err)))))
52
54
 
53
- (define (fs-lstat [path string] [i (ptr fs-info)] [err (ptr string)]) -> i32 (stat-of path #f i err))
55
+ (define (fs-stat [path string] [i (ptr fs-info)] [err (ptr error)]) -> bool (stat-of path #t i err))
54
56
 
55
- (define (fs-list [path string] [into (ptr (slice string))] [err (ptr string)]) -> i32
56
- (let* ([n u32 0] [p (list (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& n)) (cast i32 err))])
57
- (set! (@ into) (entry-strings (cast (ptr u8) p) n))
58
- (if (== p 0) -1 0)))
59
-
60
- (define (fs-remove [path string] [recursive bool] [err (ptr string)]) -> i32
61
- (if recursive
62
- (remove_all (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 err))
63
- (remove (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 err))))
57
+ (define (fs-lstat [path string] [i (ptr fs-info)] [err (ptr error)]) -> bool (stat-of path #f i err))
64
58
 
65
- (define (fs-rename [from string] [to string] [err (ptr string)]) -> i32
66
- (rename (cast i32 (-> from bytes)) (cast i32 (-> from length)) (cast i32 (-> to bytes)) (cast i32 (-> to length))
67
- (cast i32 err)))
68
-
69
- (define (path-given [p i32] [n u32] [into (ptr string)]) -> i32
59
+ (define (fs-list [path string] [into (ptr (slice string))] [err (ptr error)]) -> bool
60
+ (let* ([why string] [n u32 0]
61
+ [p (list (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& n)) (cast i32 (& why)))])
62
+ (set! (@ into) (entry-strings (cast (ptr u8) p) n))
63
+ (or (!= p 0) (host-failed! (& why) err))))
64
+
65
+ (define (fs-remove [path string] [recursive bool] [err (ptr error)]) -> bool
66
+ (let ([why string])
67
+ (done (if recursive
68
+ (remove_all (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& why)))
69
+ (remove (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& why))))
70
+ (& why) err)))
71
+
72
+ (define (fs-rename [from string] [to string] [err (ptr error)]) -> bool
73
+ (let ([why string])
74
+ (done (rename (cast i32 (-> from bytes)) (cast i32 (-> from length)) (cast i32 (-> to bytes))
75
+ (cast i32 (-> to length)) (cast i32 (& why)))
76
+ (& why) err)))
77
+
78
+ (define (path-given [p i32] [n u32] [into (ptr string)] [why (ptr string)] [err (ptr error)]) -> bool
70
79
  (set! (@ into) (cast string (slice (cast (ptr u8) p) n)))
71
- (if (== p 0) -1 0))
80
+ (or (!= p 0) (host-failed! why err)))
72
81
 
73
- (define (fs-read-link [path string] [into (ptr string)] [err (ptr string)]) -> i32
74
- (let* ([n u32 0] [p (read_link (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& n)) (cast i32 err))])
75
- (path-given p n into)))
82
+ (define (fs-read-link [path string] [into (ptr string)] [err (ptr error)]) -> bool
83
+ (let* ([why string] [n u32 0]
84
+ [p (read_link (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& n)) (cast i32 (& why)))])
85
+ (path-given p n into (& why) err)))
76
86
 
77
- (define (fs-real-path [path string] [into (ptr string)] [err (ptr string)]) -> i32
78
- (let* ([n u32 0] [p (real_path (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& n)) (cast i32 err))])
79
- (path-given p n into)))
87
+ (define (fs-real-path [path string] [into (ptr string)] [err (ptr error)]) -> bool
88
+ (let* ([why string] [n u32 0]
89
+ [p (real_path (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 (& n)) (cast i32 (& why)))])
90
+ (path-given p n into (& why) err)))
80
91
 
81
92
  ;; fs-symlink makes a link at path to target, which needs all of -R and -W, as Deno's symlink does.
82
- (define (fs-symlink [target string] [path string] [err (ptr string)]) -> i32
83
- (symlink (cast i32 (-> target bytes)) (cast i32 (-> target length)) (cast i32 (-> path bytes)) (cast i32 (-> path length))
84
- (cast i32 err)))
85
-
86
- (define (fs-copy [from string] [to string] [err (ptr string)]) -> i32
87
- (copy_file (cast i32 (-> from bytes)) (cast i32 (-> from length)) (cast i32 (-> to bytes)) (cast i32 (-> to length))
88
- (cast i32 err)))
89
-
90
- (define (fs-chmod [path string] [mode u32] [err (ptr string)]) -> i32
91
- (chmod (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 mode) (cast i32 err)))
93
+ (define (fs-symlink [target string] [path string] [err (ptr error)]) -> bool
94
+ (let ([why string])
95
+ (done (symlink (cast i32 (-> target bytes)) (cast i32 (-> target length)) (cast i32 (-> path bytes))
96
+ (cast i32 (-> path length)) (cast i32 (& why)))
97
+ (& why) err)))
98
+
99
+ (define (fs-copy [from string] [to string] [err (ptr error)]) -> bool
100
+ (let ([why string])
101
+ (done (copy_file (cast i32 (-> from bytes)) (cast i32 (-> from length)) (cast i32 (-> to bytes))
102
+ (cast i32 (-> to length)) (cast i32 (& why)))
103
+ (& why) err)))
104
+
105
+ (define (fs-chmod [path string] [mode u32] [err (ptr error)]) -> bool
106
+ (let ([why string])
107
+ (done (chmod (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 mode) (cast i32 (& why)))
108
+ (& why) err)))
92
109
 
93
110
  ;; The temporary calls make a new directory or file named prefix, random hexadecimal digits and suffix, in dir, or in
94
111
  ;; the system's temporary directory when dir is empty, and give its path.
95
- (define (make-temp [dir string] [prefix string] [suffix string] [file bool] [into (ptr string)] [err (ptr string)])
96
- -> i32
97
- (let* ([n u32 0]
112
+ (define (make-temp [dir string] [prefix string] [suffix string] [file bool] [into (ptr string)] [err (ptr error)])
113
+ -> bool
114
+ (let* ([why string] [n u32 0]
98
115
  [p (make_temp (cast i32 (-> dir bytes)) (cast i32 (-> dir length)) (cast i32 (-> prefix bytes))
99
116
  (cast i32 (-> prefix length)) (cast i32 (-> suffix bytes)) (cast i32 (-> suffix length)) file
100
- (cast i32 (& n)) (cast i32 err))])
101
- (path-given p n into)))
117
+ (cast i32 (& n)) (cast i32 (& why)))])
118
+ (path-given p n into (& why) err)))
102
119
 
103
- (define (fs-make-temp-dir [dir string] [prefix string] [suffix string] [into (ptr string)] [err (ptr string)]) -> i32
120
+ (define (fs-make-temp-dir [dir string] [prefix string] [suffix string] [into (ptr string)] [err (ptr error)]) -> bool
104
121
  (make-temp dir prefix suffix #f into err))
105
122
 
106
- (define (fs-make-temp-file [dir string] [prefix string] [suffix string] [into (ptr string)] [err (ptr string)]) -> i32
123
+ (define (fs-make-temp-file [dir string] [prefix string] [suffix string] [into (ptr string)] [err (ptr error)]) -> bool
107
124
  (make-temp dir prefix suffix #t into err))
108
125
 
109
- (define (fs-cwd [into (ptr string)] [err (ptr string)]) -> i32
110
- (let* ([n u32 0] [p (cwd (cast i32 (& n)) (cast i32 err))]) (path-given p n into)))
126
+ (define (fs-cwd [into (ptr string)] [err (ptr error)]) -> bool
127
+ (let* ([why string] [n u32 0] [p (cwd (cast i32 (& n)) (cast i32 (& why)))]) (path-given p n into (& why) err)))
111
128
 
112
129
  ;; Open files, read and written at a position. fs-open-file gives a handle opened as flags say, to read when they say
113
- ;; neither read nor write, or 0 when it fails; writing, appending, creating and truncating need -W, and reading -R.
114
- ;; fs-read-at gives the number of bytes it read, fewer at the end of the file, and fs-size the file's size, or -1 when
115
- ;; it fails. fs-read-stream and fs-write-stream make a handle a stream from start, which closes the handle when it
116
- ;; closes, or give 0 when they fail, closing it. fs-read-file stores a file's bytes, from malloc, at into, and
117
- ;; fs-write-file makes a file hold b.
130
+ ;; neither read nor write; writing, appending, creating and truncating need -W, and reading -R. fs-read-at gives the
131
+ ;; number of bytes it read, fewer at the end of the file, and fs-size the file's size. fs-read-stream and
132
+ ;; fs-write-stream make a handle a stream from start, which closes the handle when it closes. If they fail, they close
133
+ ;; the handle. fs-read-file stores a file's bytes, from malloc, at into, and fs-write-file makes a file hold b.
118
134
  (const fs-read-flag u32 1)
119
135
  (const fs-write-flag u32 2)
120
136
  (const fs-append-flag u32 4)
@@ -122,61 +138,78 @@
122
138
  (const fs-create-flag u32 16)
123
139
  (const fs-create-new-flag u32 32)
124
140
 
125
- (define (fs-open-file [path string] [flags u32] [err (ptr string)]) -> u32
126
- (cast u32 (open_file (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 flags) (cast i32 err))))
127
-
128
- (define (fs-read-at [h u32] [into (slice u8)] [at i64] [err (ptr string)]) -> i32
129
- (read_at (cast i32 h) (cast i32 (-> into items)) (cast i32 (-> into length)) (cast f64 at) (cast i32 err)))
130
-
131
- (define (fs-write-at [h u32] [b (slice u8)] [at i64] [err (ptr string)]) -> i32
132
- (write_at (cast i32 h) (cast i32 (-> b items)) (cast i32 (-> b length)) (cast f64 at) (cast i32 err)))
133
-
134
- (define (fs-set-size [h u32] [n i64] [err (ptr string)]) -> i32 (set_file_size (cast i32 h) (cast f64 n) (cast i32 err)))
135
-
136
- (define (fs-sync [h u32] [err (ptr string)]) -> i32 (sync_file (cast i32 h) (cast i32 err)))
137
-
138
- (define (fs-size [h u32] [err (ptr string)]) -> i64 (cast i64 (file_size (cast i32 h) (cast i32 err))))
139
-
140
- (define (fs-close-file [h u32] [err (ptr string)]) -> i32 (close_file (cast i32 h) (cast i32 err)))
141
-
142
- (define (fs-read-stream [h u32] [start i64] [tag (ptr void)] [err (ptr string)]) -> u32
143
- (cast u32 (file_stream (cast i32 h) 0 (cast f64 start) (cast i32 tag) (cast i32 err))))
144
-
145
- (define (fs-write-stream [h u32] [start i64] [tag (ptr void)] [err (ptr string)]) -> u32
146
- (cast u32 (file_stream (cast i32 h) 1 (cast f64 start) (cast i32 tag) (cast i32 err))))
147
-
148
- (define (fs-read-file [path string] [into (ptr (slice u8))] [err (ptr string)]) -> i32
149
- (let* ([h (fs-open-file path fs-read-flag err)] [size i64 0] [room u32 0] [p (ptr u8) 0] [more (ptr u8) 0] [n u32 0]
150
- [got i32 0])
141
+ (define (fs-open-file [path string] [flags u32] [h (ptr u32)] [err (ptr error)]) -> bool
142
+ (let ([why string] [n u32 0])
143
+ (set! n (cast u32 (open_file (cast i32 (-> path bytes)) (cast i32 (-> path length)) (cast i32 flags)
144
+ (cast i32 (& why)))))
145
+ (unless (== h 0) (set! (@ h) n))
146
+ (or (!= n 0) (host-failed! (& why) err))))
147
+
148
+ (define (fs-read-at [h u32] [into (slice u8)] [at i64] [n (ptr u32)] [err (ptr error)]) -> bool
149
+ (let* ([why string]
150
+ [r (read_at (cast i32 h) (cast i32 (-> into items)) (cast i32 (-> into length)) (cast f64 at)
151
+ (cast i32 (& why)))])
152
+ (set! (@ n) (if (< r 0) 0 (cast u32 r)))
153
+ (or (>= r 0) (host-failed! (& why) err))))
154
+
155
+ (define (fs-write-at [h u32] [b (slice u8)] [at i64] [err (ptr error)]) -> bool
156
+ (let ([why string])
157
+ (done (write_at (cast i32 h) (cast i32 (-> b items)) (cast i32 (-> b length)) (cast f64 at) (cast i32 (& why)))
158
+ (& why) err)))
159
+
160
+ (define (fs-set-size [h u32] [n i64] [err (ptr error)]) -> bool
161
+ (let ([why string]) (done (set_file_size (cast i32 h) (cast f64 n) (cast i32 (& why))) (& why) err)))
162
+
163
+ (define (fs-sync [h u32] [err (ptr error)]) -> bool
164
+ (let ([why string]) (done (sync_file (cast i32 h) (cast i32 (& why))) (& why) err)))
165
+
166
+ (define (fs-size [h u32] [size (ptr i64)] [err (ptr error)]) -> bool
167
+ (let* ([why string] [s (file_size (cast i32 h) (cast i32 (& why)))])
168
+ (set! (@ size) (if (< s 0.0) 0 (cast i64 s)))
169
+ (or (>= s 0.0) (host-failed! (& why) err))))
170
+
171
+ (define (fs-close-file [h u32] [err (ptr error)]) -> bool
172
+ (let ([why string]) (done (close_file (cast i32 h) (cast i32 (& why))) (& why) err)))
173
+
174
+ (define (file-stream [h u32] [write i32] [start i64] [tag (ptr void)] [id (ptr u32)] [err (ptr error)]) -> bool
175
+ (let ([why string] [n u32 0])
176
+ (set! n (cast u32 (file_stream (cast i32 h) write (cast f64 start) (cast i32 tag) (cast i32 (& why)))))
177
+ (unless (== id 0) (set! (@ id) n))
178
+ (or (!= n 0) (host-failed! (& why) err))))
179
+
180
+ (define (fs-read-stream [h u32] [start i64] [tag (ptr void)] [id (ptr u32)] [err (ptr error)]) -> bool
181
+ (file-stream h 0 start tag id err))
182
+
183
+ (define (fs-write-stream [h u32] [start i64] [tag (ptr void)] [id (ptr u32)] [err (ptr error)]) -> bool
184
+ (file-stream h 1 start tag id err))
185
+
186
+ (define (fs-read-file [path string] [into (ptr (slice u8))] [err (ptr error)]) -> bool
187
+ (let ([h u32 0] [size i64 0] [room u32 0] [p (ptr u8) 0] [more (ptr u8) 0] [n u32 0] [got u32 0])
151
188
  (set! (@ into) (slice (cast (ptr u8) 0) 0))
152
- (when (== h 0) (return -1))
153
- (set! size (fs-size h err))
189
+ (unless (fs-open-file path fs-read-flag (& h) err) (return #f))
190
+ (fs-size h (& size) 0)
154
191
  (set! room (if (> size 0) (+ (cast u32 (if (> size 2147483583) 2147483583 size)) 1) 4096))
155
192
  (set! p (try-malloc room))
156
193
  (while (!= p 0)
157
- (set! got (fs-read-at h (slice (+ p n) (- room n)) (cast i64 n) err))
158
- (when (< got 0)
194
+ (unless (fs-read-at h (slice (+ p n) (- room n)) (cast i64 n) (& got) err)
159
195
  (free p)
160
196
  (fs-close-file h 0)
161
- (return -1))
162
- (+= n (cast u32 got))
197
+ (return #f))
198
+ (+= n got)
163
199
  (when (< n room)
164
200
  (fs-close-file h 0)
165
201
  (set! (@ into) (slice p n))
166
- (return 0))
202
+ (return #t))
167
203
  (set! more (try-realloc p (* room 2)))
168
204
  (when (== more 0) (free p))
169
205
  (set! p more)
170
206
  (set! room (* room 2)))
171
207
  (fs-close-file h 0)
172
- (when (!= err 0) (set! (@ err) (string-copy "File too large")))
173
- -1))
174
-
175
- (define (fs-write-file [path string] [b (slice u8)] [err (ptr string)]) -> i32
176
- (let ([h (fs-open-file path (bit-or fs-write-flag fs-create-flag fs-truncate-flag) err)] [r i32 0])
177
- (when (== h 0) (return -1))
178
- (set! r (fs-write-at h b 0 err))
179
- (if (< r 0)
180
- (fs-close-file h 0)
181
- (set! r (fs-close-file h err)))
182
- r))
208
+ (error-fail! err error-other "File too large")))
209
+
210
+ (define (fs-write-file [path string] [b (slice u8)] [err (ptr error)]) -> bool
211
+ (let ([h u32 0])
212
+ (and (fs-open-file path (bit-or fs-write-flag fs-create-flag fs-truncate-flag) (& h) err)
213
+ (if (fs-write-at h b 0 err)
214
+ (fs-close-file h err)
215
+ (begin (fs-close-file h 0) #f)))))
@@ -247,7 +247,7 @@ export function within(asked, parent) {
247
247
  if (beyond) {
248
248
  const subnet = beyond.bits === undefined ? '' : `/${beyond.bits}`;
249
249
  const item = k === 'net' ? `${beyond.host}${subnet}${beyond.port === null ? '' : `:${beyond.port}`}` : beyond;
250
- throw new Error(`${beyond === true ? `all ${k}` : `${k} ${item}`} reaches beyond the parent's grants`);
250
+ throw notGranted(`${beyond === true ? `all ${k}` : `${k} ${item}`} reaches beyond the parent's grants`);
251
251
  }
252
252
  const deny = { all: a.deny.all || p.deny.all, items: [...a.deny.items, ...p.deny.items] };
253
253
  out[k] = { all: a.all, items: [...a.items], deny };
@@ -102,16 +102,17 @@
102
102
  (return #t)))
103
103
  #f))
104
104
 
105
- (define (refused [err (ptr string)] [a string] [b string]) -> bool
105
+ (define (refused [err (ptr error)] [a string] [b string]) -> bool
106
106
  (let ([m (make-buffer)])
107
107
  (buffer-add-string! (& m) a)
108
108
  (buffer-add-string! (& m) b)
109
- (set! (@ err) (buffer-string (& m)))
109
+ (error-fail! err error-invalid (buffer-string (& m)))
110
+ (buffer-free! (& m))
110
111
  #f))
111
112
 
112
113
  (define (pushed! [b (ptr buffer)] [s string]) (buffer-add! b (slice (cast (ptr u8) (& s)) (sizeof string))))
113
114
 
114
- (define (split [flag string] [list string] [into (ptr buffer)] [err (ptr string)]) -> bool
115
+ (define (split [flag string] [list string] [into (ptr buffer)] [err (ptr error)]) -> bool
115
116
  (let ([item (make-buffer)] [i u32 0] [n (-> list length)])
116
117
  (while (<= i n)
117
118
  (cond [(and (< (+ i 1) n) (== (@ list i) #\,) (== (@ list (+ i 1)) #\,))
@@ -130,13 +131,13 @@
130
131
  (define (strings-in [b (ptr buffer)]) -> (slice string)
131
132
  (slice (cast (ptr string) (-> b bytes)) (/ (-> b length) (sizeof string))))
132
133
 
133
- (define (listed! [g (ptr grants)] [kind string] [flag string] [list string] [err (ptr string)]) -> bool
134
+ (define (listed! [g (ptr grants)] [kind string] [flag string] [list string] [err (ptr error)]) -> bool
134
135
  (let ([items (make-buffer)])
135
136
  (unless (split flag list (& items) err) (return #f))
136
137
  (let ([l (strings-in (& items))]) (for ([i u32 0]) (< i (-> l length)) (+= i 1) (added! g kind (@ l i))))
137
138
  #t))
138
139
 
139
- (define (fakes! [g (ptr grants)] [flag string] [list string] [err (ptr string)]) -> bool
140
+ (define (fakes! [g (ptr grants)] [flag string] [list string] [err (ptr error)]) -> bool
140
141
  (let ([items (make-buffer)])
141
142
  (unless (split flag list (& items) err) (return #f))
142
143
  (let ([l (strings-in (& items))])
@@ -155,7 +156,7 @@
155
156
  (for ([i u32 0]) (< i (-> s length)) (+= i 1) (when (== (@ s i) #\:) (return i)))
156
157
  (-> s length))
157
158
 
158
- (define (grants-parse! [g (ptr grants)] [flags (slice string)] [err (ptr string)]) -> bool
159
+ (define (grants-parse! [g (ptr grants)] [flags (slice string)] [err (ptr error)]) -> bool
159
160
  (for ([i u32 0]) (< i (-> flags length)) (+= i 1)
160
161
  (let* ([flag (@ flags i)] [eq (equals-at flag)] [name (slice flag 0 eq)] [listed (< eq (-> flag length))]
161
162
  [value (if listed (slice flag (+ eq 1) (-> flag length)) "")] [k grant-kind])
@@ -190,7 +191,7 @@
190
191
  (return #t))))
191
192
  #f)
192
193
 
193
- (define (grants-add! [g (ptr grants)] [head string] [items (slice string)] [err (ptr string)]) -> bool
194
+ (define (grants-add! [g (ptr grants)] [head string] [items (slice string)] [err (ptr error)]) -> bool
194
195
  (let ([k grant-kind] [n (-> items length)])
195
196
  (when (== n 0) (return (refused err head " has no items")))
196
197
  (for ([i u32 0]) (< i n) (+= i 1)
@@ -122,7 +122,7 @@ export function fakeModules(setup, read) {
122
122
  connect(up, ul, pp, pl, hp, hl, tag, err) {
123
123
  const url = new URL(caller.string(up, ul));
124
124
  if (!mayUrl(setup.grants.net, url)) {
125
- caller.fail(err, `websocket.connect: ${url.host} is not granted (--allow-net)`);
125
+ caller.fail(err, `websocket.connect: ${url.host} is not granted (--allow-net)`, errors.notGranted);
126
126
  return 0;
127
127
  }
128
128
  const [protocol = ''] = entries(caller.string(pp, pl));
@@ -1,5 +1,5 @@
1
1
  // The host module "websocket" (websocket.sub).
2
- import { errors } from '../errors.mjs';
2
+ import { errors, errorOf } from '../errors.mjs';
3
3
  import { entries } from '../entries.mjs';
4
4
  import { mayUrl, portOfUrl } from '../grants.mjs';
5
5
 
@@ -46,7 +46,7 @@ export function websocket(grants, guard, node = false) {
46
46
  connect(up, ul, pp, pl, hp, hl, tag, err) {
47
47
  const url = caller.string(up, ul);
48
48
  if (URL.canParse(url) && !mayUrl(grants.net, new URL(url))) {
49
- caller.fail(err, `websocket.connect: ${new URL(url).host} is not granted (--allow-net)`);
49
+ caller.fail(err, `websocket.connect: ${new URL(url).host} is not granted (--allow-net)`, errors.notGranted);
50
50
  return 0;
51
51
  }
52
52
  const protocols = entries(caller.string(pp, pl));
@@ -54,7 +54,7 @@ export function websocket(grants, guard, node = false) {
54
54
  const headers = [];
55
55
  for (let i = 0; i + 1 < list.length; i += 2) headers.push([list[i], list[i + 1]]);
56
56
  if (headers.length > 0 && !node) {
57
- caller.fail(err, 'websocket.connect: a page cannot send headers');
57
+ caller.fail(err, 'websocket.connect: a page cannot send headers', errors.invalid);
58
58
  return 0;
59
59
  }
60
60
  const s = { ws: null, tag, polling: false, opened: false, denied: null };
@@ -65,7 +65,7 @@ export function websocket(grants, guard, node = false) {
65
65
  const dispatcher = guard && URL.canParse(url) ? guard(portOfUrl(new URL(url)), denied) : undefined;
66
66
  s.ws = node ? new WebSocket(url, { protocols, headers, dispatcher }) : new WebSocket(url, protocols);
67
67
  } catch (e) {
68
- caller.fail(err, e.message);
68
+ caller.fail(err, e.message, errorOf(e));
69
69
  return 0;
70
70
  }
71
71
  const id = next++;
@@ -25,19 +25,21 @@
25
25
  (set! (-> o protocols) 0)
26
26
  (set! (-> o headers) 0))
27
27
 
28
- (define (websocket-connect [url string] [o (ptr websocket-options)] [tag (ptr void)] [err (ptr string)]) -> u32
29
- (let ([defaults websocket-options] [p o] [protocols (make-buffer)] [headers (make-buffer)] [id u32 0])
28
+ (define (websocket-connect [url string] [o (ptr websocket-options)] [tag (ptr void)] [id (ptr u32)] [err (ptr error)])
29
+ -> bool
30
+ (let ([defaults websocket-options] [p o] [protocols (make-buffer)] [headers (make-buffer)] [why string] [n u32 0])
30
31
  (when (== p 0)
31
32
  (websocket-options-init! (& defaults))
32
33
  (set! p (& defaults)))
33
34
  (buffer-add-entries! (& protocols) (-> p protocols))
34
35
  (buffer-add-entries! (& headers) (-> p headers))
35
- (set! id (cast u32 (connect (cast i32 (-> url bytes)) (cast i32 (-> url length)) (cast i32 (-> protocols bytes))
36
- (cast i32 (-> protocols length)) (cast i32 (-> headers bytes)) (cast i32 (-> headers length))
37
- (cast i32 tag) (cast i32 err))))
36
+ (set! n (cast u32 (connect (cast i32 (-> url bytes)) (cast i32 (-> url length)) (cast i32 (-> protocols bytes))
37
+ (cast i32 (-> protocols length)) (cast i32 (-> headers bytes))
38
+ (cast i32 (-> headers length)) (cast i32 tag) (cast i32 (& why)))))
38
39
  (buffer-free! (& protocols))
39
40
  (buffer-free! (& headers))
40
- id))
41
+ (unless (== id 0) (set! (@ id) n))
42
+ (or (!= n 0) (host-failed! (& why) err))))
41
43
 
42
44
  (define (websocket-send [id u32] [b (slice u8)] [kind i32]) -> i32
43
45
  (send (cast i32 id) (cast i32 (-> b items)) (cast i32 (-> b length)) kind))
@@ -1,5 +1,6 @@
1
1
  // The host module "env" (env.sub).
2
2
  import { joined } from '../entries.mjs';
3
+ import { errors } from '../errors.mjs';
3
4
  import { mayEnv, unlimited } from '../grants.mjs';
4
5
 
5
6
  const utf8 = new TextEncoder();
@@ -9,11 +10,11 @@ export function env(grants) {
9
10
  const named = (call, ptr, len, err) => {
10
11
  const name = caller.string(ptr, len);
11
12
  if (name === '' || /[=\0]/.test(name)) {
12
- caller.fail(err, `${call}: a variable's name cannot be empty or hold = or NUL`);
13
+ caller.fail(err, `${call}: a variable's name cannot be empty or hold = or NUL`, errors.invalid);
13
14
  return null;
14
15
  }
15
16
  if (!mayEnv(grants.env, name)) {
16
- caller.fail(err, `${call}: ${name} is not granted (--allow-env)`);
17
+ caller.fail(err, `${call}: ${name} is not granted (--allow-env)`, errors.notGranted);
17
18
  return null;
18
19
  }
19
20
  return name;
@@ -21,15 +22,20 @@ export function env(grants) {
21
22
  return {
22
23
  get(ptr, len, out, err) {
23
24
  const name = named('env.get', ptr, len, err);
24
- const value = name === null ? undefined : process.env[name];
25
- return value === undefined ? 0 : caller.give(utf8.encode(value), out);
25
+ if (name === null) return 0;
26
+ const value = process.env[name];
27
+ if (value === undefined) {
28
+ caller.fail(err, `env.get: ${name} is not set`, errors.missing);
29
+ return 0;
30
+ }
31
+ return caller.give(utf8.encode(value), out);
26
32
  },
27
33
  set(np, nl, vp, vl, err) {
28
34
  const name = named('env.set', np, nl, err);
29
35
  if (name === null) return -1;
30
36
  const value = caller.string(vp, vl);
31
37
  if (value.includes('\0')) {
32
- caller.fail(err, "env.set: a variable's value cannot hold NUL");
38
+ caller.fail(err, "env.set: a variable's value cannot hold NUL", errors.invalid);
33
39
  return -1;
34
40
  }
35
41
  process.env[name] = value;
@@ -44,7 +50,7 @@ export function env(grants) {
44
50
  list(out, err) {
45
51
  const all = unlimited(grants.env);
46
52
  if (!all && (grants.env.deny.all || (!grants.env.all && grants.env.items.length === 0))) {
47
- caller.fail(err, 'env.list: the environment is not granted (--allow-env)');
53
+ caller.fail(err, 'env.list: the environment is not granted (--allow-env)', errors.notGranted);
48
54
  return 0;
49
55
  }
50
56
  const names = Object.keys(process.env)
@@ -1,8 +1,7 @@
1
- ;; Environment variables: the host module "env". env-get stores a variable's value at value and returns #t, or returns
2
- ;; #f when it is not set or not granted, with the reason at err. env-set and env-delete change the caller's environment
3
- ;; and return 0, or -1 with the reason at err. Programs the caller runs and workers it starts afterwards see the change;
4
- ;; each gets a copy of the caller's environment when it starts. env-list stores the variables -E grants at into,
5
- ;; NAME=VALUE, in name order, as Deno's toObject does, and returns 0, or -1 without -E.
1
+ ;; Environment variables: the host module "env". env-get stores a variable's value at value, and fails when the
2
+ ;; variable is not set. env-set and env-delete change the caller's environment. Programs the caller runs and workers it
3
+ ;; starts afterwards see the change; each gets a copy of the caller's environment when it starts. env-list stores the
4
+ ;; variables -E grants at into, NAME=VALUE, in name order, as Deno's toObject does.
6
5
  (provide env-get env-set env-delete env-list)
7
6
 
8
7
  (import get "env" "get" (i32 i32 i32 i32 -> i32))
@@ -10,19 +9,25 @@
10
9
  (import drop "env" "delete" (i32 i32 i32 -> i32))
11
10
  (import listed "env" "list" (i32 i32 -> i32))
12
11
 
13
- (define (env-get [name string] [value (ptr string)] [err (ptr string)]) -> bool
14
- (let* ([n u32 0] [p (get (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 (& n)) (cast i32 err))])
12
+ (define (env-get [name string] [value (ptr string)] [err (ptr error)]) -> bool
13
+ (let* ([why string] [n u32 0]
14
+ [p (get (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 (& n)) (cast i32 (& why)))])
15
15
  (set! (@ value) (cast string (slice (cast (ptr u8) p) n)))
16
- (!= p 0)))
16
+ (or (!= p 0) (host-failed! (& why) err))))
17
17
 
18
- (define (env-set [name string] [value string] [err (ptr string)]) -> i32
19
- (put (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 (-> value bytes)) (cast i32 (-> value length))
20
- (cast i32 err)))
18
+ (define (env-set [name string] [value string] [err (ptr error)]) -> bool
19
+ (let ([why string])
20
+ (or (== (put (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 (-> value bytes))
21
+ (cast i32 (-> value length)) (cast i32 (& why)))
22
+ 0)
23
+ (host-failed! (& why) err))))
21
24
 
22
- (define (env-delete [name string] [err (ptr string)]) -> i32
23
- (drop (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 err)))
25
+ (define (env-delete [name string] [err (ptr error)]) -> bool
26
+ (let ([why string])
27
+ (or (== (drop (cast i32 (-> name bytes)) (cast i32 (-> name length)) (cast i32 (& why))) 0)
28
+ (host-failed! (& why) err))))
24
29
 
25
- (define (env-list [into (ptr (slice string))] [err (ptr string)]) -> i32
26
- (let* ([n u32 0] [p (listed (cast i32 (& n)) (cast i32 err))])
30
+ (define (env-list [into (ptr (slice string))] [err (ptr error)]) -> bool
31
+ (let* ([why string] [n u32 0] [p (listed (cast i32 (& n)) (cast i32 (& why)))])
27
32
  (set! (@ into) (entry-strings (cast (ptr u8) p) n))
28
- (if (== p 0) -1 0)))
33
+ (or (!= p 0) (host-failed! (& why) err))))
@@ -20,7 +20,7 @@ const plain = (f) => (...args) => {
20
20
  return f(...args);
21
21
  } catch (e) {
22
22
  if (typeof e.errno !== 'number') throw e;
23
- throw new Error(plainMessage(e));
23
+ throw Object.assign(new Error(plainMessage(e)), { code: e.code });
24
24
  }
25
25
  };
26
26