@greenpandastudios/aug-cli 0.20.1 → 0.21.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 (295) hide show
  1. package/README.md +1 -1
  2. package/docs/assets/benchmarks/execution.svg +774 -637
  3. package/docs/assets/benchmarks/http.svg +278 -249
  4. package/docs/assets/benchmarks/improvements.svg +66 -66
  5. package/docs/assets/benchmarks/kernels-mobile.svg +1 -0
  6. package/docs/assets/benchmarks/kernels.svg +1 -0
  7. package/docs/assets/benchmarks/memory.svg +153 -153
  8. package/docs/benchmark-results.json +227089 -90363
  9. package/docs/compatibility.md +6 -6
  10. package/docs/contributing-benchmarks.md +36 -6
  11. package/docs/dev-containers.md +8 -15
  12. package/docs/dgx-consumers.json +122 -0
  13. package/docs/dgx-gyms.json +784 -0
  14. package/docs/dgx-kernels.json +1170 -0
  15. package/docs/dgx-performance.json +227849 -0
  16. package/docs/dgx-spark.md +64 -0
  17. package/docs/diagnostics.md +1 -1
  18. package/docs/docker.md +16 -17
  19. package/docs/example-projects.json +32 -0
  20. package/docs/examples/approved-design/dependencies/august/{0.20.1 → 0.21.0}/io/contracts.md +3 -3
  21. package/docs/examples/approved-design/domain/app.md +4 -4
  22. package/docs/examples/approved-design/main.md +2 -2
  23. package/docs/examples/calls-benchmark/index.md +36 -0
  24. package/docs/examples/calls-benchmark/main.md +78 -0
  25. package/docs/examples/calls-benchmark/operations.md +60 -0
  26. package/docs/examples/developer-workflow/calculator.md +5 -5
  27. package/docs/examples/developer-workflow/dependencies/august/{0.20.1 → 0.21.0}/io/contracts.md +3 -3
  28. package/docs/examples/developer-workflow/logging/console.md +2 -2
  29. package/docs/examples/developer-workflow/logging/logger.md +2 -2
  30. package/docs/examples/developer-workflow/main.md +2 -2
  31. package/docs/examples/errors-benchmark/index.md +36 -0
  32. package/docs/examples/errors-benchmark/main.md +92 -0
  33. package/docs/examples/errors-benchmark/operations.md +65 -0
  34. package/docs/examples/float-benchmark/index.md +35 -0
  35. package/docs/examples/float-benchmark/main.md +75 -0
  36. package/docs/examples/generic-di/dependencies/august/{0.20.1 → 0.21.0}/io/contracts.md +3 -3
  37. package/docs/examples/generic-di/main.md +2 -2
  38. package/docs/examples/generic-di/types.md +3 -3
  39. package/docs/examples/hello/app/greeter.md +3 -3
  40. package/docs/examples/hello/dependencies/august/{0.20.1 → 0.21.0}/io/contracts.md +3 -3
  41. package/docs/examples/hello/logging/console.md +2 -2
  42. package/docs/examples/hello/logging/logger.md +2 -2
  43. package/docs/examples/hello/main.md +2 -2
  44. package/docs/examples/index.md +18 -1
  45. package/docs/examples/interceptors/app.md +5 -5
  46. package/docs/examples/interceptors/dependencies/august/{0.20.1 → 0.21.0}/io/contracts.md +3 -3
  47. package/docs/examples/interceptors/interceptors.md +2 -2
  48. package/docs/examples/interceptors/logging.md +3 -3
  49. package/docs/examples/interceptors/main.md +2 -2
  50. package/docs/examples/list-benchmark/index.md +35 -0
  51. package/docs/examples/list-benchmark/main.md +78 -0
  52. package/docs/examples/map-churn-benchmark/index.md +35 -0
  53. package/docs/examples/map-churn-benchmark/main.md +106 -0
  54. package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/api.md +104 -0
  55. package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.md +54 -0
  56. package/docs/examples/native-blake3/dependencies/packages/@greenpandastudios/aug-blake3/0.1.3/native.abi-json.md +48 -0
  57. package/docs/examples/native-blake3/hashing.md +93 -0
  58. package/docs/examples/native-blake3/index.md +38 -0
  59. package/docs/examples/native-blake3/main.md +73 -0
  60. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/api.md +406 -0
  61. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.md +51 -0
  62. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.md +63 -0
  63. package/docs/examples/native-pytorch/dependencies/packages/@greenpandastudios/aug-pytorch/0.1.4/native.abi-json.md +161 -0
  64. package/docs/examples/native-pytorch/index.md +38 -0
  65. package/docs/examples/native-pytorch/main.md +73 -0
  66. package/docs/examples/native-pytorch/tensors.md +123 -0
  67. package/docs/examples/native-sqlite/database.md +116 -0
  68. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/api.md +284 -0
  69. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.md +51 -0
  70. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.md +75 -0
  71. package/docs/examples/native-sqlite/dependencies/packages/@greenpandastudios/aug-sqlite/0.1.3/native.abi-json.md +119 -0
  72. package/docs/examples/native-sqlite/index.md +38 -0
  73. package/docs/examples/native-sqlite/main.md +73 -0
  74. package/docs/examples/native-zlib/compression.md +99 -0
  75. package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/api.md +153 -0
  76. package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.md +54 -0
  77. package/docs/examples/native-zlib/dependencies/packages/@greenpandastudios/aug-zlib/0.1.3/native.abi-json.md +76 -0
  78. package/docs/examples/native-zlib/index.md +38 -0
  79. package/docs/examples/native-zlib/main.md +78 -0
  80. package/docs/examples/new-syntax/console.md +2 -2
  81. package/docs/examples/new-syntax/dependencies/august/{0.20.1 → 0.21.0}/io/contracts.md +3 -3
  82. package/docs/examples/new-syntax/greeter.md +3 -3
  83. package/docs/examples/new-syntax/logger.md +2 -2
  84. package/docs/examples/new-syntax/main.md +2 -2
  85. package/docs/examples/ownership-transfer/dependencies/august/{0.20.1 → 0.21.0}/io/contracts.md +3 -3
  86. package/docs/examples/ownership-transfer/main.md +2 -2
  87. package/docs/examples/ownership-transfer/resource.md +2 -2
  88. package/docs/examples/packages-math/aug-package-json.md +1 -1
  89. package/docs/examples/records-benchmark/data.md +55 -0
  90. package/docs/examples/records-benchmark/index.md +36 -0
  91. package/docs/examples/records-benchmark/main.md +85 -0
  92. package/docs/examples/strings-benchmark/index.md +35 -0
  93. package/docs/examples/strings-benchmark/main.md +76 -0
  94. package/docs/examples/tasks-benchmark/index.md +36 -0
  95. package/docs/examples/tasks-benchmark/main.md +89 -0
  96. package/docs/examples/tasks-benchmark/operations.md +58 -0
  97. package/docs/getting-started.md +3 -3
  98. package/docs/grammar.md +2 -2
  99. package/docs/gym-results.json +784 -0
  100. package/docs/implementation-map.md +6 -0
  101. package/docs/index.md +1 -1
  102. package/docs/kernel-results.json +1170 -0
  103. package/docs/language-conformance.md +6 -0
  104. package/docs/language-constructs.md +9 -1
  105. package/docs/learn/index.md +1 -1
  106. package/docs/maintaining-docs.md +1 -1
  107. package/docs/native-implementation.md +276 -0
  108. package/docs/native-interop-llvm-plan.md +342 -0
  109. package/docs/native-package-examples.md +684 -0
  110. package/docs/native-packages.md +179 -0
  111. package/docs/packages.md +2 -2
  112. package/docs/performance.md +50 -29
  113. package/docs/production-readiness.md +11 -1
  114. package/docs/public/downloads/approved-design.zip +0 -0
  115. package/docs/public/downloads/calls-benchmark.zip +0 -0
  116. package/docs/public/downloads/developer-workflow.zip +0 -0
  117. package/docs/public/downloads/errors-benchmark.zip +0 -0
  118. package/docs/public/downloads/float-benchmark.zip +0 -0
  119. package/docs/public/downloads/generic-di.zip +0 -0
  120. package/docs/public/downloads/hello.zip +0 -0
  121. package/docs/public/downloads/interceptors.zip +0 -0
  122. package/docs/public/downloads/json-benchmark.zip +0 -0
  123. package/docs/public/downloads/list-benchmark.zip +0 -0
  124. package/docs/public/downloads/map-churn-benchmark.zip +0 -0
  125. package/docs/public/downloads/native-blake3.zip +0 -0
  126. package/docs/public/downloads/native-pytorch.zip +0 -0
  127. package/docs/public/downloads/native-sqlite.zip +0 -0
  128. package/docs/public/downloads/native-zlib.zip +0 -0
  129. package/docs/public/downloads/new-syntax.zip +0 -0
  130. package/docs/public/downloads/oidc-login.zip +0 -0
  131. package/docs/public/downloads/ownership-transfer.zip +0 -0
  132. package/docs/public/downloads/packages-app.zip +0 -0
  133. package/docs/public/downloads/packages-math.zip +0 -0
  134. package/docs/public/downloads/records-benchmark.zip +0 -0
  135. package/docs/public/downloads/strings-benchmark.zip +0 -0
  136. package/docs/public/downloads/tasks-benchmark.zip +0 -0
  137. package/docs/qualification-results.md +66 -0
  138. package/docs/reference.md +24 -0
  139. package/docs/releasing.md +81 -6
  140. package/docs/research/libtorch-native-qualification.md +115 -0
  141. package/docs/research/native-interop-llvm.md +197 -0
  142. package/docs/research/qualification-methods.md +15 -0
  143. package/docs/roadmap.md +1 -0
  144. package/docs/safety-gyms.md +41 -0
  145. package/docs/tooling.md +16 -15
  146. package/docs/web-library-gaps.md +1 -1
  147. package/docs/web.md +4 -0
  148. package/examples/approved-design/.aug-spec/manifest.json +3 -3
  149. package/examples/approved-design/domain/app.aug.md +4 -4
  150. package/examples/approved-design/main.aug.md +2 -2
  151. package/examples/developer-workflow/.aug-spec/manifest.json +3 -3
  152. package/examples/developer-workflow/calculator.aug.md +5 -5
  153. package/examples/developer-workflow/logging/console.aug.md +2 -2
  154. package/examples/developer-workflow/logging/logger.aug.md +2 -2
  155. package/examples/developer-workflow/main.aug.md +2 -2
  156. package/examples/generic-di/.aug-spec/manifest.json +3 -3
  157. package/examples/generic-di/main.aug.md +2 -2
  158. package/examples/generic-di/types.aug.md +3 -3
  159. package/examples/hello/.aug-spec/manifest.json +3 -3
  160. package/examples/hello/app/greeter.aug.md +3 -3
  161. package/examples/hello/logging/console.aug.md +2 -2
  162. package/examples/hello/logging/logger.aug.md +2 -2
  163. package/examples/hello/main.aug.md +2 -2
  164. package/examples/interceptors/.aug-spec/manifest.json +3 -3
  165. package/examples/interceptors/app.aug.md +5 -5
  166. package/examples/interceptors/interceptors.aug.md +2 -2
  167. package/examples/interceptors/logging.aug.md +3 -3
  168. package/examples/interceptors/main.aug.md +2 -2
  169. package/examples/native-blake3/.aug-spec/manifest.json +16 -0
  170. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.1/native.abi.json +29 -0
  171. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/api.aug +14 -0
  172. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/api.aug.md +34 -0
  173. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.aug +4 -0
  174. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/contracts.aug.md +8 -0
  175. package/examples/native-blake3/.aug-spec/packages/@greenpandastudios/aug-blake3/0.1.3/native.abi.json +29 -0
  176. package/examples/native-blake3/AGENTS.md +5 -0
  177. package/examples/native-blake3/aug.lock.json +253 -0
  178. package/examples/native-blake3/hashing.aug +11 -0
  179. package/examples/native-blake3/hashing.aug.md +25 -0
  180. package/examples/native-blake3/main.aug +8 -0
  181. package/examples/native-blake3/main.aug.md +13 -0
  182. package/examples/native-pytorch/.aug-spec/manifest.json +18 -0
  183. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.1/native.abi.json +142 -0
  184. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.3/native.abi.json +142 -0
  185. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/api.aug +101 -0
  186. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/api.aug.md +160 -0
  187. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.aug +3 -0
  188. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/bindings.aug.md +8 -0
  189. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.aug +6 -0
  190. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/contracts.aug.md +13 -0
  191. package/examples/native-pytorch/.aug-spec/packages/@greenpandastudios/aug-pytorch/0.1.4/native.abi.json +142 -0
  192. package/examples/native-pytorch/AGENTS.md +5 -0
  193. package/examples/native-pytorch/aug.lock.json +309 -0
  194. package/examples/native-pytorch/main.aug +8 -0
  195. package/examples/native-pytorch/main.aug.md +13 -0
  196. package/examples/native-pytorch/tensors.aug +23 -0
  197. package/examples/native-pytorch/tensors.aug.md +35 -0
  198. package/examples/native-sqlite/.aug-spec/manifest.json +18 -0
  199. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.2/native.abi.json +100 -0
  200. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/api.aug +48 -0
  201. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/api.aug.md +91 -0
  202. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.aug +3 -0
  203. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/bindings.aug.md +8 -0
  204. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.aug +8 -0
  205. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/contracts.aug.md +22 -0
  206. package/examples/native-sqlite/.aug-spec/packages/@greenpandastudios/aug-sqlite/0.1.3/native.abi.json +100 -0
  207. package/examples/native-sqlite/AGENTS.md +5 -0
  208. package/examples/native-sqlite/aug.lock.json +236 -0
  209. package/examples/native-sqlite/database.aug +15 -0
  210. package/examples/native-sqlite/database.aug.md +27 -0
  211. package/examples/native-sqlite/main.aug +8 -0
  212. package/examples/native-sqlite/main.aug.md +13 -0
  213. package/examples/native-zlib/.aug-spec/manifest.json +16 -0
  214. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.1/native.abi.json +57 -0
  215. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/api.aug +29 -0
  216. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/api.aug.md +54 -0
  217. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.aug +4 -0
  218. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/contracts.aug.md +8 -0
  219. package/examples/native-zlib/.aug-spec/packages/@greenpandastudios/aug-zlib/0.1.3/native.abi.json +57 -0
  220. package/examples/native-zlib/AGENTS.md +5 -0
  221. package/examples/native-zlib/aug.lock.json +236 -0
  222. package/examples/native-zlib/compression.aug +15 -0
  223. package/examples/native-zlib/compression.aug.md +27 -0
  224. package/examples/native-zlib/main.aug +10 -0
  225. package/examples/native-zlib/main.aug.md +13 -0
  226. package/examples/new-syntax/.aug-spec/manifest.json +3 -3
  227. package/examples/new-syntax/console.aug.md +2 -2
  228. package/examples/new-syntax/greeter.aug.md +3 -3
  229. package/examples/new-syntax/logger.aug.md +2 -2
  230. package/examples/new-syntax/main.aug.md +2 -2
  231. package/examples/oidc-login/aug.lock.json +6 -6
  232. package/examples/ownership-transfer/.aug-spec/manifest.json +3 -3
  233. package/examples/ownership-transfer/main.aug.md +2 -2
  234. package/examples/ownership-transfer/resource.aug.md +2 -2
  235. package/examples/packages/math/aug-package.json +1 -1
  236. package/native/compiler-packs.json +43 -0
  237. package/package.json +3 -2
  238. package/runtime/aug_http.c +48 -21
  239. package/runtime/aug_http_ir.c +30 -0
  240. package/runtime/aug_http_ir.h +18 -0
  241. package/runtime/aug_ir.c +209 -0
  242. package/runtime/aug_ir.h +89 -0
  243. package/runtime/aug_json.c +6 -1
  244. package/runtime/aug_runtime.c +82 -16
  245. package/runtime/aug_runtime.h +16 -2
  246. package/runtime/aug_tasks.c +38 -7
  247. package/runtime/aug_values.c +12 -6
  248. package/scripts/bootstrap-native.mjs +4 -1
  249. package/src/ast.js +1 -1
  250. package/src/checker.js +110 -28
  251. package/src/cli.js +92 -14
  252. package/src/codegen.js +31 -6
  253. package/src/compiler-packs.js +66 -0
  254. package/src/config.js +2 -2
  255. package/src/editor.js +15 -6
  256. package/src/formatter.js +4 -2
  257. package/src/git-http.js +137 -0
  258. package/src/git-packages.js +9 -1
  259. package/src/help.js +10 -2
  260. package/src/ir-types.js +5 -0
  261. package/src/ir-verify.js +277 -0
  262. package/src/ir.js +962 -0
  263. package/src/llvm-debug.js +101 -0
  264. package/src/llvm-native.js +152 -0
  265. package/src/llvm-platform.js +20 -0
  266. package/src/llvm.js +781 -0
  267. package/src/native-artifacts.js +207 -0
  268. package/src/native-bindings.js +189 -0
  269. package/src/native-contracts.js +295 -0
  270. package/src/native-declarations.js +68 -0
  271. package/src/native-facts.js +63 -0
  272. package/src/package-locking.js +43 -0
  273. package/src/package-manager.js +23 -8
  274. package/src/parser.js +20 -2
  275. package/src/project.js +2 -2
  276. package/src/runtime-abi.js +23 -0
  277. package/src/runtime-adapters.js +18 -0
  278. package/src/schemas.js +24 -17
  279. package/src/semantic.js +8 -3
  280. package/src/snippets.js +1 -0
  281. package/src/spec.js +49 -8
  282. /package/examples/approved-design/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug +0 -0
  283. /package/examples/approved-design/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug.md +0 -0
  284. /package/examples/developer-workflow/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug +0 -0
  285. /package/examples/developer-workflow/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug.md +0 -0
  286. /package/examples/generic-di/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug +0 -0
  287. /package/examples/generic-di/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug.md +0 -0
  288. /package/examples/hello/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug +0 -0
  289. /package/examples/hello/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug.md +0 -0
  290. /package/examples/interceptors/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug +0 -0
  291. /package/examples/interceptors/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug.md +0 -0
  292. /package/examples/new-syntax/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug +0 -0
  293. /package/examples/new-syntax/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug.md +0 -0
  294. /package/examples/ownership-transfer/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug +0 -0
  295. /package/examples/ownership-transfer/.aug-spec/august/{0.20.1 → 0.21.0}/io/contracts.aug.md +0 -0
@@ -23,11 +23,17 @@ typedef struct {
23
23
  } AugHttpSession;
24
24
  struct AugHttpJob {
25
25
  struct lws *wsi; AugHttpSession *session; AugValue task;
26
- /* Request and loggers outlive transport session cleanup on a disconnect. */
27
- AugValue roots[2]; AugRetained retained;
28
- bool test, transport_complete, timed_out; int64_t started,deadline;
26
+ /* Request, loggers and the prepared HEAD response outlive transport cleanup. */
27
+ AugValue roots[3]; AugRetained retained;
28
+ bool test, transport_complete, timed_out, head_complete; int64_t started,deadline;
29
29
  };
30
30
  static const AugRoute *served_routes;
31
+ static AugValue route_call(const AugRoute *route,AugValue *args,int count) {
32
+ AugValue result=aug_null();
33
+ if(route->pointer_handler)route->pointer_handler(&result,NULL,args,count);
34
+ else result=route->handler(args,count);
35
+ return result;
36
+ }
31
37
  static size_t served_count;
32
38
  static size_t body_limit = 1024 * 1024;
33
39
  static size_t response_limit = 4 * 1024 * 1024;
@@ -93,6 +99,14 @@ AugValue aug_headers_with(AugValue headers, AugValue name, AugValue value) {
93
99
  header_add(result, name.as.object->text, name.as.object->text_length, value.as.object->text, value.as.object->text_length);
94
100
  aug_freeze(result); aug_release(&retained); aug_frame_leave(&frame); return result;
95
101
  }
102
+ static AugValue headers_with_name(AugValue headers, const char *name, AugValue value) {
103
+ /* Root the value before allocating the name: either allocation can collect. */
104
+ AugValue roots[3] = {headers, value, aug_null()};
105
+ AugFrame frame; aug_frame_enter(&frame, roots, 3);
106
+ roots[2] = aug_string(name);
107
+ AugValue result = aug_headers_with(roots[0], roots[2], roots[1]);
108
+ aug_frame_leave(&frame); return result;
109
+ }
96
110
  AugValue aug_headers_get(AugValue headers, AugValue name) {AugValue value = header_get(headers, aug_cstring(name), false); return value.tag == AUG_NULL ? aug_null() : value;}
97
111
  AugValue aug_headers_all(AugValue headers, AugValue name) {
98
112
  AugValue result = aug_list_new(NULL, 0); AugFrame frame; aug_frame_enter(&frame, &result, 1); AugValue entries = aug_field(headers, 0);
@@ -165,7 +179,7 @@ static const AugRoute *select_route(AugValue request, const AugRoute *routes, si
165
179
  for(size_t layer=0;layer<routes[i].policy_count;layer++)if(routes[i].policies[layer].kind==AUG_HTTP_POLICY_CORS){
166
180
  AugValue headers=aug_headers_new();AugFrame frame;aug_frame_enter(&frame,&headers,1);
167
181
  if(cors_apply(&routes[i].policies[layer],request,&headers,true)) {
168
- headers=aug_headers_with(headers,aug_string("access-control-allow-methods"),requested);
182
+ headers=headers_with_name(headers,"access-control-allow-methods",requested);
169
183
  *failure=aug_http_response_full(aug_null(),aug_int(204),headers);
170
184
  }else {int status=aug_has_error?aug_http_error_status():403;if(aug_has_error)aug_take_error();*failure=aug_http_problem(status);}
171
185
  aug_frame_leave(&frame);return NULL;
@@ -255,9 +269,9 @@ static bool cors_apply(const AugHttpPolicy *policy,AugValue request,AugValue *he
255
269
  AugValue origin=header_get(aug_field(request,2),"origin",true);if(aug_has_error)return false;if(origin.tag==AUG_NULL)return !preflight;
256
270
  const char *name=aug_cstring(origin);bool wildcard=listed(policy->origins,"*");
257
271
  if(!wildcard&&!listed(policy->origins,name)){request_error("HttpForbidden");return false;}
258
- *headers=aug_headers_with(*headers,aug_string("access-control-allow-origin"),wildcard?aug_string("*"):origin);
259
- *headers=aug_headers_with(*headers,aug_string("vary"),aug_string("Origin"));
260
- if(policy->credentials)*headers=aug_headers_with(*headers,aug_string("access-control-allow-credentials"),aug_string("true"));
272
+ *headers=headers_with_name(*headers,"access-control-allow-origin",wildcard?aug_string("*"):origin);
273
+ *headers=headers_with_name(*headers,"vary",aug_string("Origin"));
274
+ if(policy->credentials)*headers=headers_with_name(*headers,"access-control-allow-credentials",aug_string("true"));
261
275
  if(preflight) {
262
276
  AugValue asked=header_get(aug_field(request,2),"access-control-request-headers",true);if(aug_has_error)return false;
263
277
  if(asked.tag==AUG_STRING){char *copy=strdup(aug_cstring(asked));if(!copy)abort();char *save=NULL;
@@ -265,7 +279,7 @@ static bool cors_apply(const AugHttpPolicy *policy,AugValue request,AugValue *he
265
279
  bool found=false;const char *allowed=policy->headers;while(*allowed){const char *end=strchr(allowed,',');if(!end)end=allowed+strlen(allowed);if((size_t)(end-allowed)==size&&!strncasecmp(allowed,part,size))found=true;allowed=*end?end+1:end;while(*allowed==' ')allowed++;}
266
280
  if(!size||!found){free(copy);request_error("HttpForbidden");return false;}}
267
281
  free(copy);}
268
- *headers=aug_headers_with(*headers,aug_string("access-control-allow-headers"),aug_string(policy->headers));
282
+ *headers=headers_with_name(*headers,"access-control-allow-headers",aug_string(policy->headers));
269
283
  }
270
284
  return !aug_has_error;
271
285
  }
@@ -317,7 +331,7 @@ static AugValue policy_response(AugHttpSession *session,AugValue response) {
317
331
  if(session->roots[4].tag==AUG_NULL&&!session->compress)return response;
318
332
  AugValue roots[2]={response,aug_field(response,2)};AugFrame frame;aug_frame_enter(&frame,roots,2);
319
333
  if(session->roots[4].tag==AUG_OBJECT){AugValue entries=aug_field(session->roots[4],0);for(size_t i=0;i<entries.as.object->field_count;i++){AugValue pair=entries.as.object->fields[i];roots[1]=aug_headers_with(roots[1],aug_field(pair,0),aug_field(pair,1));}}
320
- if(session->compress){roots[1]=aug_headers_with(roots[1],aug_string("content-encoding"),aug_string("gzip"));roots[1]=aug_headers_with(roots[1],aug_string("vary"),aug_string("Accept-Encoding"));}
334
+ if(session->compress){roots[1]=headers_with_name(roots[1],"content-encoding",aug_string("gzip"));roots[1]=headers_with_name(roots[1],"vary",aug_string("Accept-Encoding"));}
321
335
  AugValue result=aug_http_response_full(aug_field(roots[0],0),aug_field(roots[0],1),roots[1]);aug_frame_leave(&frame);return result;
322
336
  }
323
337
  AugValue _aug_http_log(AugValue method,AugValue path,AugValue status,AugValue milliseconds) {
@@ -353,9 +367,9 @@ AugValue aug_httptestclient_request(AugValue client,AugValue method,AugValue tar
353
367
  if(aug_field(session.roots[0],3).as.object->text_length>body_limit){session.roots[1]=aug_http_problem(413);goto serialize;}
354
368
  aug_freeze(session.roots[0]);
355
369
  AugHttpJob job={.session=&session,.test=true,.roots={session.roots[0],aug_null()}};
356
- aug_retain(&job.retained,job.roots,2);
370
+ aug_retain(&job.retained,job.roots,3);
357
371
  void *previous=aug_execution_current()->http_job;bool previous_cancelled=aug_cancelled;aug_execution_current()->http_job=&job;
358
- session.roots[1]=session.route->handler(session.roots,1);aug_execution_current()->http_job=previous;aug_release(&job.retained);
372
+ session.roots[1]=route_call(session.route,session.roots,1);aug_execution_current()->http_job=previous;aug_release(&job.retained);
359
373
  if(job.timed_out)aug_cancelled=previous_cancelled;
360
374
  if(aug_has_error){aug_report_error();aug_take_error();session.roots[1]=aug_http_problem(500);}
361
375
  if(session.streaming&&aug_cint(aug_field(session.roots[1],1))>=400){aug_frame_leave(&frame);return request_error("HttpError");}
@@ -369,7 +383,7 @@ serialize:;
369
383
  if(session.compress&&!session.streaming)session.roots[2]=gzip_bytes(session.roots[2]);
370
384
  if(aug_has_error||session.roots[2].as.object->text_length>response_limit){if(aug_has_error)aug_take_error();session.roots[1]=aug_http_problem(500);status=500;session.roots[2]=aug_json_stringify(aug_field(session.roots[1],0));}
371
385
  session.roots[3]=aug_field(session.roots[1],2);
372
- if(header_get(session.roots[3],"content-type",false).tag==AUG_NULL)session.roots[3]=aug_headers_with(session.roots[3],aug_string("content-type"),aug_string(type));
386
+ if(header_get(session.roots[3],"content-type",false).tag==AUG_NULL)session.roots[3]=headers_with_name(session.roots[3],"content-type",aug_string(type));
373
387
  if(!strcmp(aug_cstring(method),"HEAD")||status==204||status==304)session.roots[2]=aug_bytes("",0,AUG_BYTES_KIND);
374
388
  session.roots[1]=aug_http_response_full(session.roots[2],aug_int(status),session.roots[3]);
375
389
  AugValue result=session.roots[1];aug_frame_leave(&frame);return result;
@@ -431,7 +445,7 @@ AugValue aug_http_bind(AugValue request, const char *source, const char *name, c
431
445
  bool known = false; for (size_t j = 0; j < schema->count; j++) if (!strcmp(aug_cstring(map.as.object->fields[i]), schema->names[j])) known = true;
432
446
  if (!known) request_error("HttpBadRequest");
433
447
  }
434
- AugValue result = aug_has_error ? aug_null() : schema->make(fields, (int)schema->count);
448
+ AugValue result = aug_has_error ? aug_null() : aug_schema_make(schema,fields,(int)schema->count);
435
449
  aug_frame_leave(&field_frame); free(fields); aug_frame_leave(&frame); return result;
436
450
  }
437
451
  if (!strcmp(source, "body")) {
@@ -484,7 +498,7 @@ static void cleanup(AugHttpSession *session) {
484
498
  free(session->body); memset(session, 0, sizeof(*session));
485
499
  }
486
500
  static AugValue request_task(AugValue self, AugValue *args, int count) {
487
- (void)self; (void)count; aug_execution_current()->http_job=(void *)(intptr_t)aug_cint(args[2]); size_t index = (size_t)aug_cint(args[1]); return served_routes[index].handler(args, 1);
501
+ (void)self; (void)count; aug_execution_current()->http_job=(void *)(intptr_t)aug_cint(args[2]); size_t index = (size_t)aug_cint(args[1]); return route_call(&served_routes[index],args,1);
488
502
  }
489
503
  AugValue aug_http_event(AugValue data, AugValue id, AugValue event, AugValue retry) {
490
504
  AugValue values[]={data,id,event,retry};
@@ -522,18 +536,26 @@ void aug_http_yield(AugValue value) {
522
536
  }
523
537
  session->roots[1]=policy_response(session,aug_http_response(aug_null(),session->route->status));session->roots[3]=encoded;session->streaming=true;session->stream_pending=true;session->sent=0;
524
538
  lws_callback_on_writable(job->wsi);
525
- if(session->head){session->stream_pending=false;aug_cancelled=true;goto finished;}
539
+ if(session->head){session->stream_pending=false;job->roots[2]=session->roots[1];job->head_complete=true;aug_cancelled=true;goto finished;}
526
540
  while(job->session&&job->session->stream_pending&&!aug_cancelled)aug_task_suspend();
527
541
  finished:
528
542
  aug_frame_leave(&frame);
529
543
  }
544
+ bool aug_http_head_response(AugValue *response) {
545
+ AugHttpJob *job=aug_execution_current()->http_job;
546
+ if(!aug_cancelled||aug_has_error||!job||!job->head_complete||job->timed_out||(!job->session&&!job->transport_complete))return false;
547
+ /* The first yield already established this response. Cancellation stops the
548
+ producer and its children; it is not an error or a client disconnect. */
549
+ *response=job->roots[2];return response->tag==AUG_OBJECT;
550
+ }
530
551
  AugValue aug_http_finish(AugValue response) {
531
552
  AugHttpJob *job=aug_execution_current()->http_job;if(!job)return response;
532
553
  AugHttpSession *session=job->session;AugValue roots[3]={response,job->roots[1],job->roots[0]};AugFrame frame;aug_frame_enter(&frame,roots,3);
533
554
  if(job->timed_out)roots[0]=aug_http_problem(504);
534
555
  else if(job->test&&job->deadline&&monotonic_ms()>=job->deadline)roots[0]=aug_http_problem(504);
535
556
  if(session) {
536
- roots[0]=policy_response(session,roots[0]);
557
+ bool prepared_head=job->head_complete&&roots[0].tag==AUG_OBJECT&&session->roots[1].tag==AUG_OBJECT&&roots[0].as.object==session->roots[1].as.object;
558
+ if(!prepared_head)roots[0]=policy_response(session,roots[0]);
537
559
  bool stream_success=session->route->stream&&aug_cint(aug_field(roots[0],1))<400;
538
560
  if(job->test&&stream_success&&!session->streaming) {
539
561
  session->roots[2]=aug_bytes("",0,AUG_BYTES_KIND);
@@ -548,10 +570,12 @@ AugValue aug_http_finish(AugValue response) {
548
570
  else session->streaming=false;
549
571
  lws_callback_on_writable(job->wsi);
550
572
  }
551
- while(job->session&&!job->transport_complete&&!aug_cancelled)aug_task_suspend();
573
+ while(job->session&&!job->transport_complete&&(!aug_cancelled||(job->head_complete&&!job->timed_out)))aug_task_suspend();
552
574
  }
553
575
  }
554
- int status=aug_cancelled&&!job->timed_out?499:(int)aug_cint(aug_field(roots[0],1));
576
+ /* A deadline may have fired while finish was suspended on transport. */
577
+ if(job->timed_out)roots[0]=aug_http_problem(504);
578
+ int status=aug_cancelled&&!job->timed_out&&(!job->head_complete||!job->transport_complete)?499:(int)aug_cint(aug_field(roots[0],1));
555
579
  bool cancelled=aug_cancelled;aug_cancelled=false;aug_execution_current()->http_job=NULL;
556
580
  if(roots[1].tag==AUG_OBJECT)for(size_t i=roots[1].as.object->field_count;i>0;i--){
557
581
  AugValue arguments[]={aug_field(roots[2],0),aug_field(roots[2],1),aug_int(status),aug_int(monotonic_ms()-job->started)};
@@ -582,7 +606,7 @@ static void dispatch(struct lws *wsi, AugHttpSession *session) {
582
606
  if (!session->route) {session->roots[1] = aug_http_problem(404); lws_callback_on_writable(wsi); return;}
583
607
  AugHttpJob *job = calloc(1, sizeof(*job)); if (!job) return;
584
608
  job->wsi = wsi; job->session = session; session->job = job;job->started=monotonic_ms();
585
- job->roots[0]=session->roots[0];aug_retain(&job->retained,job->roots,2);
609
+ job->roots[0]=session->roots[0];aug_retain(&job->retained,job->roots,3);
586
610
  AugValue arguments[3] = {session->roots[0], aug_int(session->route - served_routes),aug_int((int64_t)(intptr_t)job)};
587
611
  job->task = aug_task_spawn(request_task, aug_null(), arguments, 3, request_complete, job);
588
612
  }
@@ -660,8 +684,11 @@ static int callback_http(struct lws *wsi, enum lws_callback_reasons reason, void
660
684
  snprintf(name, sizeof(name), "%s:", label.as.object->text);
661
685
  if (lws_add_http_header_by_name(wsi, (unsigned char *)name, (unsigned char *)value.as.object->text, (int)value.as.object->text_length, &next, end)) return -1;
662
686
  }
663
- if (lws_finalize_write_http_header(wsi, start, &next, end)) return -1;
664
- session->headers_sent = true; lws_callback_on_writable(wsi); return 0;
687
+ enum lws_write_protocol flags=LWS_WRITE_HTTP_HEADERS|(session->head?LWS_WRITE_H2_STREAM_END:0);
688
+ if (lws_finalize_write_http_header_flags(wsi, start, &next, end, flags)) return -1;
689
+ session->headers_sent = true;
690
+ if(session->head){if(session->job)session->job->transport_complete=true;cleanup(session);return lws_http_transaction_completed(wsi)?-1:0;}
691
+ lws_callback_on_writable(wsi); return 0;
665
692
  }
666
693
  if(session->streaming&&!session->stream_pending&&!session->stream_done)return 0;
667
694
  AugValue encoded = session->streaming&&session->stream_pending?session->roots[3]:session->roots[2]; size_t remaining = session->head ? 0 : encoded.as.object->text_length - session->sent;
@@ -0,0 +1,30 @@
1
+ #include "aug_http_ir.h"
2
+ void aug_ir_http_operation(AugValue *out,int op,AugValue *a,int count,const char *text,int64_t number) {
3
+ (void)number;*out=aug_null();
4
+ switch(op){
5
+ case AUG_IR_HTTP_HEADERS:*out=aug_headers_new();break;
6
+ case AUG_IR_HTTP_HEADERS_WITH:*out=aug_headers_with(a[0],a[1],a[2]);break;
7
+ case AUG_IR_HTTP_HEADERS_GET:*out=aug_headers_get(a[0],a[1]);break;
8
+ case AUG_IR_HTTP_HEADERS_ALL:*out=aug_headers_all(a[0],a[1]);break;
9
+ case AUG_IR_HTTP_RESPONSE:*out=aug_http_response_full(a[0],a[1],a[2]);break;
10
+ case AUG_IR_HTTP_RESPONSE_STATUS:*out=aug_http_response(a[0],(int)aug_cint(a[1]));break;
11
+ case AUG_IR_HTTP_FINISH:*out=aug_http_finish(a[0]);break;
12
+ case AUG_IR_HTTP_EVENT:*out=aug_http_event(a[0],a[1],a[2],a[3]);break;
13
+ case AUG_IR_HTTP_YIELD:aug_http_yield(a[0]);break;
14
+ case AUG_IR_HTTP_CLIENT_REQUEST:*out=aug_httptestclient_request(a[0],a[1],a[2],a[3],a[4]);break;
15
+ case AUG_IR_HTTP_ACTION:*out=aug_http_action(text,a,(size_t)count);break;
16
+ default:aug_error_named("NativeContractError");break;
17
+ }
18
+ }
19
+ void aug_ir_http_bind(AugValue *out,const AugValue *request,const char *source,const char *name,const AugSchema *schema){*out=aug_http_bind(*request,source,name,schema);}
20
+ void aug_ir_http_form(AugValue *out,const AugValue *request,const AugSchema *schema){*out=aug_httprequest_form(*request,schema);}
21
+ void aug_ir_http_policy(const AugHttpPolicy *policy,AugValue *args){aug_http_policy(policy,args[0],args[1],args[2]);}
22
+ void aug_ir_http_failure(AugValue *out,const AugIrHttpError *errors,int count){
23
+ if(aug_http_head_response(out))return;
24
+ int status=aug_http_error_status();
25
+ for(int i=0;i<count;i++)if(aug_error_is(errors[i].type))status=errors[i].status;
26
+ if(status==500)aug_report_error();aug_take_error();*out=aug_http_problem(status);
27
+ }
28
+ void aug_ir_http_test_client(AugValue *out,const AugRoute *routes,int count){*out=aug_http_test_client(routes,(size_t)count);}
29
+ void aug_ir_http_serve(const AugRoute *routes,int count,const AugValue *port){aug_http_serve(routes,(size_t)count,aug_cint(*port));}
30
+ void aug_ir_html(AugValue *out,const char *tag,AugValue *attributes,int count,AugValue *children,int child_count){*out=aug_html_element(tag,attributes,(size_t)count,children,(size_t)child_count);}
@@ -0,0 +1,18 @@
1
+ #ifndef AUG_HTTP_IR_H
2
+ #define AUG_HTTP_IR_H
3
+ #include "aug_ir.h"
4
+ enum AugIrHttpOperation {
5
+ AUG_IR_HTTP_HEADERS=1,AUG_IR_HTTP_HEADERS_WITH,AUG_IR_HTTP_HEADERS_GET,AUG_IR_HTTP_HEADERS_ALL,
6
+ AUG_IR_HTTP_RESPONSE,AUG_IR_HTTP_RESPONSE_STATUS,AUG_IR_HTTP_FINISH,AUG_IR_HTTP_EVENT,
7
+ AUG_IR_HTTP_YIELD,AUG_IR_HTTP_CLIENT_REQUEST,AUG_IR_HTTP_ACTION
8
+ };
9
+ typedef struct {const char *type; int status;} AugIrHttpError;
10
+ void aug_ir_http_operation(AugValue *out,int op,AugValue *args,int count,const char *text,int64_t number);
11
+ void aug_ir_http_bind(AugValue *out,const AugValue *request,const char *source,const char *name,const AugSchema *schema);
12
+ void aug_ir_http_form(AugValue *out,const AugValue *request,const AugSchema *schema);
13
+ void aug_ir_http_policy(const AugHttpPolicy *policy,AugValue *args);
14
+ void aug_ir_http_failure(AugValue *out,const AugIrHttpError *errors,int count);
15
+ void aug_ir_http_test_client(AugValue *out,const AugRoute *routes,int count);
16
+ void aug_ir_http_serve(const AugRoute *routes,int count,const AugValue *port);
17
+ void aug_ir_html(AugValue *out,const char *tag,AugValue *attributes,int count,AugValue *children,int child_count);
18
+ #endif
@@ -0,0 +1,209 @@
1
+ #include "aug_ir.h"
2
+ #include <limits.h>
3
+ #include <stdlib.h>
4
+ #include <stdio.h>
5
+
6
+ _Static_assert(sizeof(AugValue)==16, "LLVM pack must record its actual AugValue layout");
7
+ _Static_assert(offsetof(AugValue,as)==8, "LLVM pack must record its actual payload offset");
8
+
9
+ void aug_ir_operation(AugValue *out,int op,AugValue *a,int count,const char *text,int64_t n) {
10
+ (void)count; *out=aug_null();
11
+ switch(op) {
12
+ case AUG_IR_PRINT: aug_print(a[0]); break;
13
+ case AUG_IR_BINARY: *out=aug_binary(text,a[0],a[1]); break;
14
+ case AUG_IR_UNARY: *out=aug_unary(text,a[0]); break;
15
+ case AUG_IR_FIELD: *out=aug_field(a[0],(size_t)n); break;
16
+ case AUG_IR_SET_FIELD: aug_set_field(a[0],(size_t)n,a[1]); break;
17
+ case AUG_IR_LIST: *out=aug_list_new(a,(size_t)count); break;
18
+ case AUG_IR_TUPLE: *out=aug_tuple_new(a,(size_t)count); break;
19
+ case AUG_IR_SET: *out=aug_set_new(a,(size_t)count); break;
20
+ case AUG_IR_MAP: *out=aug_map_new(); break;
21
+ case AUG_IR_MAP_SET: aug_map_set(a[0],a[1],a[2]); break;
22
+ case AUG_IR_LIST_LENGTH: *out=aug_int(aug_list_length(a[0])); break;
23
+ case AUG_IR_LIST_GET: *out=aug_list_get(a[0],aug_cint(a[1])); break;
24
+ case AUG_IR_LIST_AT: *out=aug_list_at(a[0],aug_cint(a[1])); break;
25
+ case AUG_IR_LIST_APPEND: aug_list_append(a[0],a[1]); break;
26
+ case AUG_IR_TUPLE_LENGTH: *out=aug_int(aug_tuple_length(a[0])); break;
27
+ case AUG_IR_TUPLE_GET: *out=aug_tuple_get(a[0],aug_cint(a[1])); break;
28
+ case AUG_IR_SET_LENGTH: *out=aug_int(aug_set_length(a[0])); break;
29
+ case AUG_IR_SET_ADD: aug_set_add(a[0],a[1]); break;
30
+ case AUG_IR_SET_CONTAINS: *out=aug_bool(aug_set_contains(a[0],a[1])); break;
31
+ case AUG_IR_MAP_LENGTH: *out=aug_int(aug_map_length(a[0])); break;
32
+ case AUG_IR_MAP_GET: *out=aug_map_get(a[0],a[1]); break;
33
+ case AUG_IR_MAP_TAKE: *out=aug_map_take(a[0],a[1]); break;
34
+ case AUG_IR_MAP_CONTAINS: *out=aug_bool(aug_map_contains(a[0],a[1])); break;
35
+ case AUG_IR_STRING_LENGTH: *out=aug_int(aug_string_length(a[0])); break;
36
+ case AUG_IR_STRING_BYTES: *out=aug_string_bytes(a[0]); break;
37
+ case AUG_IR_STRING_SPLIT: *out=aug_string_split(a[0],a[1]); break;
38
+ case AUG_IR_STRING_STARTS_WITH: *out=aug_bool(aug_string_starts_with(a[0],a[1])); break;
39
+ case AUG_IR_STRING_IS_TOKEN: *out=aug_bool(aug_string_is_token(a[0],aug_cint(a[1]),aug_cint(a[2]))); break;
40
+ case AUG_IR_BYTES_LENGTH: *out=aug_int(aug_bytes_length(a[0])); break;
41
+ case AUG_IR_BYTES_TEXT: *out=aug_bytes_text(a[0]); break;
42
+ case AUG_IR_BYTES_BASE64URL: *out=aug_bytes_base64url(a[0]); break;
43
+ case AUG_IR_BASE64URL_DECODE: *out=aug_base64url_decode(a[0]); break;
44
+ case AUG_IR_C_INT: *out=aug_to_c_int(a[0]); break;
45
+ case AUG_IR_READ_FILE: *out=aug_read_file(a[0]); break;
46
+ case AUG_IR_WRITE_FILE: *out=aug_write_file(a[0],a[1]); break;
47
+ case AUG_IR_ARGUMENTS: *out=aug_arguments(); break;
48
+ case AUG_IR_FREEZE: aug_freeze(a[0]); *out=a[0]; break;
49
+ case AUG_IR_ITER: *out=aug_iter_snapshot(a[0]); break;
50
+ case AUG_IR_MAP_ITER: *out=aug_map_entries_snapshot(a[0]); break;
51
+ case AUG_IR_IS_TYPE: *out=aug_bool(a[0].tag==AUG_OBJECT&&a[0].as.object&&!strcmp(a[0].as.object->type_name,text)); break;
52
+ case AUG_IR_SHARED: *out=aug_shared_new(a[0]); break;
53
+ case AUG_IR_SHARED_LOCK: *out=aug_shared_lock(a[0]); break;
54
+ case AUG_IR_JSON_WRAP: *out=aug_json_wrap(a[0]); break;
55
+ case AUG_IR_JSON_PARSE: *out=_aug_json_parse(a[0]); break;
56
+ case AUG_IR_JSON_STRINGIFY: *out=aug_json_stringify(a[0]); break;
57
+ case AUG_IR_JSON_GET: *out=aug_json_get(a[0],a[1]); break;
58
+ case AUG_IR_JSON_REQUIRE: *out=aug_json_require(a[0],a[1]); break;
59
+ case AUG_IR_JSON_STRING: *out=aug_json_string(a[0]); break;
60
+ case AUG_IR_JSON_INTEGER: *out=aug_int(aug_json_integer(a[0])); break;
61
+ case AUG_IR_JSON_BOOLEAN: *out=aug_bool(aug_json_boolean(a[0])); break;
62
+ case AUG_IR_JSON_ITEMS: *out=aug_json_items(a[0]); break;
63
+ case AUG_IR_TIME_NOW: *out=_aug_time_now(); break;
64
+ case AUG_IR_EXIT: {int64_t status=aug_cint(a[0]);aug_cancelled=true;aug_shutdown();exit(status>=0&&status<=255?(int)status:1);}
65
+ case AUG_IR_TEST_CASE: aug_test_assertions=0;break;
66
+ default: *out=aug_error_named("NativeContractError"); break;
67
+ }
68
+ }
69
+ void aug_ir_json_decode(AugValue *out,const AugValue *value,const AugSchema *schema){*out=aug_json_decode(*value,schema);}
70
+ void aug_ir_print(const AugValue *value){aug_print(*value);}
71
+ void aug_ir_binary(AugValue *out,const char *operation,const AugValue *left,const AugValue *right){*out=aug_binary(operation,*left,*right);}
72
+ void aug_ir_unary(AugValue *out,const char *operation,const AugValue *value){*out=aug_unary(operation,*value);}
73
+ void aug_ir_list_new(AugValue *out,AugValue *items,int count){*out=aug_list_new(items,(size_t)count);}
74
+ void aug_ir_tuple_new(AugValue *out,AugValue *items,int count){*out=aug_tuple_new(items,(size_t)count);}
75
+ void aug_ir_set_new(AugValue *out,AugValue *items,int count){*out=aug_set_new(items,(size_t)count);}
76
+ void aug_ir_map(AugValue *out){*out=aug_map_new();}
77
+ void aug_ir_iter(AugValue *out,const AugValue *value){*out=aug_iter_snapshot(*value);}
78
+ void aug_ir_map_iter(AugValue *out,const AugValue *value){*out=aug_map_entries_snapshot(*value);}
79
+ void aug_ir_list_append(const AugValue *list,const AugValue *value){aug_list_append(*list,*value);}
80
+ int64_t aug_ir_tuple_length(const AugValue *tuple){return aug_tuple_length(*tuple);}
81
+ void aug_ir_tuple_get(AugValue *out,const AugValue *tuple,const AugValue *index){*out=aug_tuple_get(*tuple,aug_cint(*index));}
82
+ int64_t aug_ir_string_length(const AugValue *value){return aug_string_length(*value);}
83
+ void aug_ir_string_bytes(AugValue *out,const AugValue *value){*out=aug_string_bytes(*value);}
84
+ void aug_ir_string_split(AugValue *out,const AugValue *value,const AugValue *separator){*out=aug_string_split(*value,*separator);}
85
+ void aug_ir_map_set(const AugValue *map,const AugValue *key,const AugValue *value){aug_map_set(*map,*key,*value);}
86
+ void aug_ir_set_add(const AugValue *set,const AugValue *value){aug_set_add(*set,*value);}
87
+ uint8_t aug_ir_set_contains(const AugValue *set,const AugValue *value){return aug_set_contains(*set,*value)?1:0;}
88
+ uint8_t aug_ir_map_contains(const AugValue *map,const AugValue *key){return aug_map_contains(*map,*key)?1:0;}
89
+ int64_t aug_ir_list_length(const AugValue *list){return (int64_t)aug_list_length(*list);}
90
+ int64_t aug_ir_set_length(const AugValue *set){return (int64_t)aug_set_length(*set);}
91
+ int64_t aug_ir_map_length(const AugValue *map){return (int64_t)aug_map_length(*map);}
92
+ void aug_ir_list_get(AugValue *out,const AugValue *list,const AugValue *index){*out=aug_list_get(*list,aug_cint(*index));}
93
+ void aug_ir_list_at(AugValue *out,const AugValue *list,const AugValue *index){*out=aug_list_at(*list,aug_cint(*index));}
94
+ void aug_ir_map_get(AugValue *out,const AugValue *map,const AugValue *key){*out=aug_map_get(*map,*key);}
95
+ void aug_ir_map_take(AugValue *out,const AugValue *map,const AugValue *key){*out=aug_map_take(*map,*key);}
96
+ void aug_ir_string(AugValue *out,const void *text,uint64_t count){*out=aug_string_n(text,(size_t)count);}
97
+ void aug_ir_assert(const AugValue *condition,const char *expression,const char *file,int line){aug_assert(*condition,expression,file,line);}
98
+ void aug_ir_drop(AugValue *value){aug_drop(*value);*value=aug_null();}
99
+ void aug_ir_failed_result(AugValue *value){if(aug_has_error){aug_drop_partial(*value);*value=aug_null();}}
100
+ void aug_ir_constructor_result(AugValue *value,const AugValue *result){aug_constructor_result_cleanup(*value,*result);*value=aug_null();}
101
+ void aug_ir_throw(const AugValue *value){aug_throw(*value);}
102
+ void aug_ir_take_error(AugValue *out){*out=aug_take_error();}
103
+ void aug_ir_save_error_state(AugValue *error,AugValue *cancelled){
104
+ *error=aug_has_error?aug_take_error():aug_null();*cancelled=aug_bool(aug_cancelled);aug_cancelled=false;
105
+ }
106
+ void aug_ir_restore_error_state(const AugValue *error,const AugValue *cancelled){
107
+ aug_cancelled=aug_truthy(*cancelled);if(!aug_has_error&&error->tag!=AUG_NULL)aug_throw(*error);
108
+ }
109
+ bool aug_ir_has_error(void){return aug_has_error;}
110
+ void aug_ir_task_wait(AugValue *out,AugValue *tasks,int count){*out=aug_task_wait(tasks,count);}
111
+ bool aug_ir_cancelled(void){return aug_cancelled;}
112
+ uint8_t aug_ir_state(void){
113
+ AugExecution *execution=aug_execution_current();
114
+ return execution->cancelled?1:execution->has_error?2:0;
115
+ }
116
+ bool aug_ir_is_null(const AugValue *value){return value->tag==AUG_NULL;}
117
+ bool aug_ir_truthy(const AugValue *value){return aug_truthy(*value);}
118
+ int64_t aug_ir_integer(const AugValue *value){return aug_cint(*value);}
119
+ double aug_ir_float(const AugValue *value){return aug_cfloat(*value);}
120
+ void aug_ir_frame_enter(AugFrame *frame,AugValue *values,uint64_t count){aug_frame_enter(frame,values,(size_t)count);}
121
+ void aug_ir_method(AugValue *out,const AugValue *self,const char *name,AugValue *args,int count){*out=aug_call_method(*self,name,args,count);}
122
+ void aug_ir_object(AugValue *out,const char *type,uint64_t fields,const unsigned char *owned,const AugMethodEntry *methods,uint64_t method_count,const char *const *names,bool record){
123
+ *out=aug_new_object(type,(size_t)fields,owned,methods,(size_t)method_count);
124
+ out->as.object->field_names=names;if(record)out->as.object->kind=AUG_RECORD_KIND;
125
+ }
126
+ void aug_ir_binding_get(AugValue *out,uint64_t index){*out=aug_binding_get((size_t)index);}
127
+ void aug_ir_binding_set(uint64_t index,const AugValue *value){aug_binding_set((size_t)index,*value);}
128
+ int aug_ir_exit_status(bool test){
129
+ if(aug_has_error){aug_report_error();return 1;}
130
+ if(test&&!aug_test_assertions){fputs("Test executed no assertions\n",stderr);return 1;}
131
+ return aug_test_failed?1:0;
132
+ }
133
+ void *aug_ir_resource_pointer(const AugValue *value,const char *type){
134
+ if(value->tag!=AUG_OBJECT||!value->as.object||value->as.object->kind!=AUG_NATIVE_RESOURCE_KIND||value->as.object->dropped||!value->as.object->native||strcmp(value->as.object->type_name,type)){
135
+ aug_error_named("NativeContractError");return NULL;
136
+ }
137
+ return value->as.object->native;
138
+ }
139
+ void aug_ir_resource(AugValue *out,void *pointer,const char *type,void(*release)(void *)){
140
+ if(!pointer||!release){*out=aug_null();aug_error_named("NativeContractError");return;}
141
+ *out=aug_new_object(type,0,NULL,NULL,0);out->as.object->kind=AUG_NATIVE_RESOURCE_KIND;
142
+ out->as.object->native=pointer;out->as.object->finalize=release;
143
+ }
144
+ void aug_ir_resource_move(AugValue *value){
145
+ if(value->tag==AUG_OBJECT&&value->as.object&&value->as.object->kind==AUG_NATIVE_RESOURCE_KIND){
146
+ value->as.object->native=NULL;value->as.object->finalize=NULL;value->as.object->dropped=true;
147
+ }
148
+ *value=aug_null();
149
+ }
150
+ void aug_ir_contract_error(AugValue *out){*out=aug_null();if(!aug_has_error)aug_error_named("NativeContractError");}
151
+ void aug_ir_native_error(AugValue *out,AugPointerMethod factory,int32_t code,const void *text,uint64_t length){
152
+ if(aug_has_error)return;
153
+ if(!factory){aug_ir_contract_error(out);return;}
154
+ if(length>512||!aug_valid_utf8(text,(size_t)length)){text="Native library returned an invalid error message";length=strlen(text);}
155
+ if(!length){text="Native call rejected its input or supplied no error message";length=strlen(text);}
156
+ AugValue roots[3]={0};AugFrame frame;aug_frame_enter(&frame,roots,3);
157
+ roots[0]=aug_int(code);roots[1]=aug_string_n(text,(size_t)length);
158
+ factory(&roots[2],NULL,roots,2);
159
+ if(!aug_has_error)aug_throw(roots[2]);aug_frame_leave(&frame);
160
+ }
161
+ bool aug_ir_data(const AugValue *v,const void **data,uint64_t *count){
162
+ *data=NULL;*count=0;
163
+ if((v->tag!=AUG_STRING&&v->tag!=AUG_OBJECT)||!v->as.object||v->as.object->dropped||(v->tag==AUG_OBJECT&&v->as.object->kind!=AUG_BYTES_KIND)){
164
+ aug_error_named("NativeContractError");return false;
165
+ }
166
+ *data=v->as.object->text;*count=v->as.object->text_length;return true;
167
+ }
168
+ bool aug_ir_floats(const AugValue *v,double **data,uint64_t *count){
169
+ *data=NULL;*count=0;
170
+ if(v->tag!=AUG_OBJECT||!v->as.object||v->as.object->kind!=AUG_LIST_KIND||v->as.object->dropped||v->as.object->field_count>SIZE_MAX/sizeof(double)){
171
+ aug_error_named("NativeContractError");return false;
172
+ }
173
+ size_t n=v->as.object->field_count;double *items=malloc((n?n:1)*sizeof(double));
174
+ if(!items){aug_error_named("NativeContractError");return false;}
175
+ for(size_t i=0;i<n;i++){
176
+ AugValue item=v->as.object->fields[i];if(item.tag!=AUG_FLOAT&&item.tag!=AUG_INT){free(items);aug_error_named("NativeContractError");return false;}
177
+ items[i]=item.tag==AUG_FLOAT?item.as.floating:(double)item.as.integer;
178
+ }
179
+ *data=items;*count=n;return true;
180
+ }
181
+ bool aug_ir_strings(const AugValue *v,const void ***data,uint64_t **lengths,uint64_t *count){
182
+ *data=NULL;*lengths=NULL;*count=0;
183
+ if(v->tag!=AUG_OBJECT||!v->as.object||v->as.object->kind!=AUG_LIST_KIND||v->as.object->dropped||v->as.object->field_count>SIZE_MAX/sizeof(uint64_t)){
184
+ aug_error_named("NativeContractError");return false;
185
+ }
186
+ size_t n=v->as.object->field_count;const void **items=calloc(n?n:1,sizeof(void *));uint64_t *sizes=calloc(n?n:1,sizeof(uint64_t));
187
+ if(!items||!sizes){free(items);free(sizes);aug_error_named("NativeContractError");return false;}
188
+ for(size_t i=0;i<n;i++){
189
+ AugValue item=v->as.object->fields[i];if(item.tag!=AUG_STRING||!item.as.object||item.as.object->dropped){free(items);free(sizes);aug_error_named("NativeContractError");return false;}
190
+ items[i]=item.as.object->text;sizes[i]=item.as.object->text_length;
191
+ }
192
+ *data=items;*lengths=sizes;*count=n;return true;
193
+ }
194
+ void aug_ir_free(void *memory){free(memory);}
195
+ void aug_ir_copy_bytes(AugValue *out,const void *bytes,uint64_t count){
196
+ if(count>SIZE_MAX-1||(!bytes&&count)){*out=aug_error_named("NativeContractError");return;}
197
+ *out=aug_bytes(bytes,(size_t)count,AUG_BYTES_KIND);
198
+ }
199
+ void aug_ir_copy_utf8(AugValue *out,const void *text,uint64_t count){
200
+ if(count>SIZE_MAX-1||!aug_valid_utf8(text,(size_t)count)){*out=aug_error_named("NativeContractError");return;}
201
+ *out=aug_string_n(text,(size_t)count);
202
+ }
203
+ void aug_ir_copy_bool(AugValue *out,uint8_t value){*out=value>1?aug_error_named("NativeContractError"):aug_bool(value!=0);}
204
+ void aug_ir_copy_floats(AugValue *out,const double *values,uint64_t count){
205
+ if(count>SIZE_MAX/sizeof(AugValue)||(!values&&count)){*out=aug_error_named("NativeContractError");return;}
206
+ AugValue *items=malloc((count?count:1)*sizeof(AugValue));if(!items){*out=aug_error_named("NativeContractError");return;}
207
+ for(uint64_t i=0;i<count;i++)items[i]=aug_float(values[i]);
208
+ *out=aug_list_new(items,(size_t)count);free(items);
209
+ }
@@ -0,0 +1,89 @@
1
+ #ifndef AUG_IR_H
2
+ #define AUG_IR_H
3
+ #include "aug_runtime.h"
4
+
5
+ /* Compiler-private pointer-call ABI. This is not the public native package ABI.
6
+ All target packs record these layouts; LLVM validates that record before use. */
7
+ enum AugIrOperation {
8
+ AUG_IR_PRINT=1, AUG_IR_BINARY, AUG_IR_UNARY, AUG_IR_FIELD, AUG_IR_SET_FIELD,
9
+ AUG_IR_LIST, AUG_IR_TUPLE, AUG_IR_SET, AUG_IR_MAP, AUG_IR_MAP_SET,
10
+ AUG_IR_LIST_LENGTH, AUG_IR_LIST_GET, AUG_IR_LIST_AT, AUG_IR_LIST_APPEND,
11
+ AUG_IR_TUPLE_LENGTH, AUG_IR_TUPLE_GET, AUG_IR_SET_LENGTH, AUG_IR_SET_ADD,
12
+ AUG_IR_SET_CONTAINS, AUG_IR_MAP_LENGTH, AUG_IR_MAP_GET, AUG_IR_MAP_TAKE,
13
+ AUG_IR_MAP_CONTAINS, AUG_IR_STRING_LENGTH, AUG_IR_STRING_BYTES,
14
+ AUG_IR_STRING_SPLIT, AUG_IR_STRING_STARTS_WITH, AUG_IR_STRING_IS_TOKEN,
15
+ AUG_IR_BYTES_LENGTH, AUG_IR_BYTES_TEXT, AUG_IR_BYTES_BASE64URL,
16
+ AUG_IR_BASE64URL_DECODE, AUG_IR_C_INT, AUG_IR_READ_FILE, AUG_IR_WRITE_FILE,
17
+ AUG_IR_ARGUMENTS, AUG_IR_FREEZE, AUG_IR_ITER, AUG_IR_MAP_ITER, AUG_IR_IS_TYPE,
18
+ AUG_IR_SHARED, AUG_IR_SHARED_LOCK, AUG_IR_JSON_WRAP, AUG_IR_JSON_PARSE,
19
+ AUG_IR_JSON_STRINGIFY, AUG_IR_JSON_GET, AUG_IR_JSON_REQUIRE, AUG_IR_JSON_STRING,
20
+ AUG_IR_JSON_INTEGER, AUG_IR_JSON_BOOLEAN, AUG_IR_JSON_ITEMS, AUG_IR_TIME_NOW, AUG_IR_EXIT, AUG_IR_TEST_CASE
21
+ };
22
+ void aug_ir_operation(AugValue *out, int operation, AugValue *args, int count, const char *text, int64_t number);
23
+ /* Specialized services keep managed inputs in the caller's rooted cells. */
24
+ void aug_ir_print(const AugValue *value);
25
+ void aug_ir_binary(AugValue *out,const char *operation,const AugValue *left,const AugValue *right);
26
+ void aug_ir_unary(AugValue *out,const char *operation,const AugValue *value);
27
+ void aug_ir_list_new(AugValue *out,AugValue *items,int count);
28
+ void aug_ir_tuple_new(AugValue *out,AugValue *items,int count);
29
+ void aug_ir_set_new(AugValue *out,AugValue *items,int count);
30
+ void aug_ir_map(AugValue *out);
31
+ void aug_ir_iter(AugValue *out,const AugValue *value);
32
+ void aug_ir_map_iter(AugValue *out,const AugValue *value);
33
+ void aug_ir_list_append(const AugValue *list,const AugValue *value);
34
+ int64_t aug_ir_tuple_length(const AugValue *tuple);
35
+ void aug_ir_tuple_get(AugValue *out,const AugValue *tuple,const AugValue *index);
36
+ int64_t aug_ir_string_length(const AugValue *value);
37
+ void aug_ir_string_bytes(AugValue *out,const AugValue *value);
38
+ void aug_ir_string_split(AugValue *out,const AugValue *value,const AugValue *separator);
39
+ void aug_ir_map_set(const AugValue *map,const AugValue *key,const AugValue *value);
40
+ void aug_ir_set_add(const AugValue *set,const AugValue *value);
41
+ uint8_t aug_ir_set_contains(const AugValue *set,const AugValue *value);
42
+ uint8_t aug_ir_map_contains(const AugValue *map,const AugValue *key);
43
+ int64_t aug_ir_list_length(const AugValue *list);
44
+ int64_t aug_ir_set_length(const AugValue *set);
45
+ int64_t aug_ir_map_length(const AugValue *map);
46
+ void aug_ir_list_get(AugValue *out,const AugValue *list,const AugValue *index);
47
+ void aug_ir_list_at(AugValue *out,const AugValue *list,const AugValue *index);
48
+ void aug_ir_map_get(AugValue *out,const AugValue *map,const AugValue *key);
49
+ void aug_ir_map_take(AugValue *out,const AugValue *map,const AugValue *key);
50
+ void aug_ir_json_decode(AugValue *out, const AugValue *value, const AugSchema *schema);
51
+ void aug_ir_string(AugValue *out, const void *text, uint64_t count);
52
+ void aug_ir_assert(const AugValue *condition, const char *expression, const char *file, int line);
53
+ void aug_ir_drop(AugValue *value);
54
+ void aug_ir_failed_result(AugValue *value);
55
+ void aug_ir_constructor_result(AugValue *value, const AugValue *result);
56
+ void aug_ir_throw(const AugValue *value);
57
+ void aug_ir_take_error(AugValue *out);
58
+ void aug_ir_save_error_state(AugValue *error,AugValue *cancelled);
59
+ void aug_ir_restore_error_state(const AugValue *error,const AugValue *cancelled);
60
+ void aug_ir_task_wait(AugValue *out, AugValue *tasks, int count);
61
+ bool aug_ir_has_error(void);
62
+ bool aug_ir_cancelled(void);
63
+ /* 0 = running, 1 = cancelled, 2 = checked error; cancellation wins. */
64
+ uint8_t aug_ir_state(void);
65
+ bool aug_ir_is_null(const AugValue *value);
66
+ bool aug_ir_truthy(const AugValue *value);
67
+ int64_t aug_ir_integer(const AugValue *value);
68
+ double aug_ir_float(const AugValue *value);
69
+ void aug_ir_frame_enter(AugFrame *frame, AugValue *values, uint64_t count);
70
+ void aug_ir_method(AugValue *out, const AugValue *self, const char *name, AugValue *args, int count);
71
+ void aug_ir_object(AugValue *out, const char *type, uint64_t fields, const unsigned char *owned,
72
+ const AugMethodEntry *methods, uint64_t method_count, const char *const *names, bool record);
73
+ void aug_ir_binding_get(AugValue *out, uint64_t index);
74
+ void aug_ir_binding_set(uint64_t index, const AugValue *value);
75
+ int aug_ir_exit_status(bool test);
76
+ void *aug_ir_resource_pointer(const AugValue *value, const char *type);
77
+ void aug_ir_resource(AugValue *out, void *pointer, const char *type, void (*release)(void *));
78
+ void aug_ir_resource_move(AugValue *value);
79
+ void aug_ir_contract_error(AugValue *out);
80
+ void aug_ir_native_error(AugValue *out, AugPointerMethod factory, int32_t code, const void *text, uint64_t length);
81
+ bool aug_ir_data(const AugValue *value, const void **data, uint64_t *count);
82
+ bool aug_ir_floats(const AugValue *value, double **data, uint64_t *count);
83
+ bool aug_ir_strings(const AugValue *value, const void ***data, uint64_t **lengths, uint64_t *count);
84
+ void aug_ir_free(void *memory);
85
+ void aug_ir_copy_bytes(AugValue *out, const void *bytes, uint64_t count);
86
+ void aug_ir_copy_utf8(AugValue *out, const void *text, uint64_t count);
87
+ void aug_ir_copy_bool(AugValue *out, uint8_t value);
88
+ void aug_ir_copy_floats(AugValue *out, const double *values, uint64_t count);
89
+ #endif
@@ -116,6 +116,11 @@ AugValue aug_json_items(AugValue value) {
116
116
  for (size_t i = 0; i < value.as.object->field_count; i++) aug_list_append(roots[1], aug_json_wrap(value.as.object->fields[i]));
117
117
  AugValue result = roots[1]; aug_frame_leave(&frame); return result;
118
118
  }
119
+ AugValue aug_schema_make(const AugSchema *schema, AugValue *fields, int count) {
120
+ if(schema->pointer_make){AugValue result=aug_null();schema->pointer_make(&result,NULL,fields,count);return result;}
121
+ if(schema->make)return schema->make(fields,count);
122
+ return invalid();
123
+ }
119
124
  static AugValue decode(AugValue value, const AugSchema *schema, size_t depth) {
120
125
  if (depth > 64) return invalid();
121
126
  if (value.tag == AUG_NULL && schema->nullable) return value;
@@ -152,7 +157,7 @@ static AugValue decode(AugValue value, const AugSchema *schema, size_t depth) {
152
157
  }
153
158
  AugValue result = aug_null();
154
159
  if (!aug_has_error) {
155
- if (schema->kind == AUG_SCHEMA_RECORD) result = schema->make(items, (int)count);
160
+ if (schema->kind == AUG_SCHEMA_RECORD) result = aug_schema_make(schema,items,(int)count);
156
161
  else if (schema->kind == AUG_SCHEMA_TUPLE) result = aug_tuple_new(items, count);
157
162
  else if (schema->kind == AUG_SCHEMA_SET) result = aug_set_new(items, count);
158
163
  else if (schema->kind == AUG_SCHEMA_MAP) { result = aug_map_new(); items[count] = result; for (size_t i = 0; i < count; i += 2) aug_map_set(result, items[i], items[i + 1]); }