@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
@@ -28,6 +28,10 @@ static size_t next_collection = 1024;
28
28
  static bool collecting = false;
29
29
  static AugValue cli_args = {0};
30
30
  static bool equal(AugValue left, AugValue right);
31
+ /* Map-only metadata keeps ordinary object allocation sizes unchanged. The
32
+ first member permits the existing heap, roots and GC to use AugObject. */
33
+ typedef struct { AugObject object; size_t *field_buckets; } AugMapObject;
34
+ static size_t *map_field_buckets(AugObject *object) { return ((AugMapObject *)object)->field_buckets; }
31
35
  bool aug_test_failed = false;
32
36
  size_t aug_test_assertions = 0;
33
37
 
@@ -54,7 +58,7 @@ static AugObject *allocate(int kind, const char *type_name, size_t field_count,
54
58
  const unsigned char *owned_fields,
55
59
  const AugMethodEntry *methods, size_t method_count) {
56
60
  if (!collecting && object_count >= next_collection) aug_collect();
57
- AugObject *object = calloc(1, sizeof(AugObject));
61
+ AugObject *object = calloc(1, kind == AUG_MAP_KIND ? sizeof(AugMapObject) : sizeof(AugObject));
58
62
  if (!object) fail("out of memory");
59
63
  object->kind = kind;
60
64
  object->type_name = type_name;
@@ -79,7 +83,7 @@ AugValue aug_string_n(const void *value, size_t length) {
79
83
  AugObject *object = allocate(AUG_STRING, "string", 0, NULL, NULL, 0);
80
84
  object->text = malloc(length + 1);
81
85
  if (!object->text) fail("out of memory");
82
- memcpy(object->text, value, length);
86
+ if (length) memcpy(object->text, value, length);
83
87
  object->text[length] = 0;
84
88
  object->text_length = length;
85
89
  return (AugValue){ .tag = AUG_STRING, .as.object = object };
@@ -209,6 +213,18 @@ static size_t bucket_for(AugObject *object, AugValue key) { return bucket_for_ha
209
213
 
210
214
  static bool grow_table(AugObject *object, size_t stride) {
211
215
  size_t entries = object->field_count / stride;
216
+ if (object->field_count + stride > object->capacity) {
217
+ size_t capacity = object->capacity ? object->capacity * 2 : 8;
218
+ AugValue *fields = realloc(object->fields, capacity * sizeof(AugValue));
219
+ if (!fields) fail("out of memory");
220
+ object->fields = fields;
221
+ if (stride == 2) {
222
+ size_t *positions = realloc(map_field_buckets(object), (capacity / 2) * sizeof(size_t));
223
+ if (!positions) fail("out of memory");
224
+ ((AugMapObject *)object)->field_buckets = positions;
225
+ }
226
+ object->capacity = capacity;
227
+ }
212
228
  bool rehashed = !object->bucket_count || (entries + 1) * 10 > object->bucket_count * 7;
213
229
  if (rehashed) {
214
230
  size_t count = object->bucket_count ? object->bucket_count * 2 : 8;
@@ -217,15 +233,11 @@ static bool grow_table(AugObject *object, size_t stride) {
217
233
  free(object->buckets);
218
234
  object->buckets = buckets;
219
235
  object->bucket_count = count;
220
- for (size_t i = 0; i < object->field_count; i += stride)
221
- object->buckets[bucket_for(object, object->fields[i])] = i + 1;
222
- }
223
- if (object->field_count + stride > object->capacity) {
224
- size_t capacity = object->capacity ? object->capacity * 2 : 8;
225
- AugValue *fields = realloc(object->fields, capacity * sizeof(AugValue));
226
- if (!fields) fail("out of memory");
227
- object->fields = fields;
228
- object->capacity = capacity;
236
+ for (size_t i = 0; i < object->field_count; i += stride) {
237
+ size_t bucket = bucket_for(object, object->fields[i]);
238
+ object->buckets[bucket] = i + 1;
239
+ if (stride == 2) map_field_buckets(object)[i / 2] = bucket;
240
+ }
229
241
  }
230
242
  return rehashed;
231
243
  }
@@ -251,6 +263,7 @@ void aug_map_set(AugValue map, AugValue key, AugValue value) {
251
263
  if (field) { object->fields[field] = value; return; }
252
264
  }
253
265
  if (grow_table(object, 2)) bucket = bucket_for_hash(object, key, hash);
266
+ map_field_buckets(object)[object->field_count / 2] = bucket;
254
267
  object->buckets[bucket] = object->field_count + 1;
255
268
  object->fields[object->field_count++] = key;
256
269
  object->fields[object->field_count++] = value;
@@ -264,12 +277,29 @@ AugValue aug_map_get(AugValue map, AugValue key) {
264
277
  }
265
278
  AugValue aug_map_take(AugValue map, AugValue key) {
266
279
  AugObject *object = expect_map(map); if (object->frozen) fail("cannot mutate a frozen Map");
267
- if (!object->bucket_count) return aug_null(); size_t field = object->buckets[bucket_for(object, key)];
280
+ if (!object->bucket_count) return aug_null();
281
+ size_t bucket = bucket_for(object, key), field = object->buckets[bucket];
268
282
  if (!field) return aug_null(); AugValue result = object->fields[field]; size_t first = field - 1;
269
283
  memmove(object->fields + first, object->fields + first + 2, (object->field_count - first - 2) * sizeof(AugValue));
270
284
  object->field_count -= 2; object->fields[object->field_count] = aug_null(); object->fields[object->field_count + 1] = aug_null();
271
- memset(object->buckets, 0, object->bucket_count * sizeof(size_t));
272
- for (size_t i = 0; i < object->field_count; i += 2) object->buckets[bucket_for(object, object->fields[i])] = i + 1;
285
+ object->buckets[bucket] = 0;
286
+ /* Ordered fields remain dense. Adjust only moved entry offsets, then repair
287
+ the probe chain after the removed bucket. Neither step rehashes the map. */
288
+ size_t *positions = map_field_buckets(object);
289
+ for (size_t i = first / 2 + 1; i <= object->field_count / 2; i++)
290
+ object->buckets[positions[i]] -= 2;
291
+ memmove(positions + first / 2, positions + first / 2 + 1,
292
+ (object->field_count - first) / 2 * sizeof(size_t));
293
+ size_t mask = object->bucket_count - 1, hole = bucket;
294
+ for (size_t next = (hole + 1) & mask; object->buckets[next]; next = (next + 1) & mask) {
295
+ size_t home = (size_t)hash_value(object->fields[object->buckets[next] - 1]) & mask;
296
+ if (((next - home) & mask) >= ((next - hole) & mask)) {
297
+ object->buckets[hole] = object->buckets[next];
298
+ positions[(object->buckets[hole] - 1) / 2] = hole;
299
+ hole = next;
300
+ }
301
+ }
302
+ object->buckets[hole] = 0;
273
303
  return result;
274
304
  }
275
305
 
@@ -409,6 +439,10 @@ void aug_set_field(AugValue object, size_t index, AugValue value) {
409
439
  fail("invalid field assignment");
410
440
  if (object.as.object->dropped) fail("use of dropped object");
411
441
  if (object.as.object->frozen) fail("cannot assign a frozen field");
442
+ AugValue previous = object.as.object->fields[index];
443
+ if (object.as.object->owned_fields && object.as.object->owned_fields[index] &&
444
+ !(previous.tag == AUG_OBJECT && value.tag == AUG_OBJECT && previous.as.object == value.as.object))
445
+ aug_drop(previous);
412
446
  object.as.object->fields[index] = value;
413
447
  }
414
448
 
@@ -417,7 +451,10 @@ AugValue aug_call_method(AugValue object, const char *name, AugValue *args, int
417
451
  if (object.as.object->dropped) fail("use of dropped object");
418
452
  for (size_t i = 0; i < object.as.object->method_count; i++) {
419
453
  const AugMethodEntry *entry = &object.as.object->methods[i];
420
- if (strcmp(entry->name, name) == 0) return entry->function(object, args, count);
454
+ if (strcmp(entry->name, name) == 0) {
455
+ if(entry->pointer_function){AugValue result=aug_null();entry->pointer_function(&result,&object,args,count);return result;}
456
+ return entry->function(object, args, count);
457
+ }
421
458
  }
422
459
  fprintf(stderr, "AugScript runtime error: %s has no method %s\n",
423
460
  object.as.object->type_name, name);
@@ -736,6 +773,7 @@ void aug_collect(void) {
736
773
  free(object->text);
737
774
  free(object->fields);
738
775
  free(object->buckets);
776
+ if (object->kind == AUG_MAP_KIND) free(map_field_buckets(object));
739
777
  free(object);
740
778
  object_count--;
741
779
  }
@@ -748,20 +786,48 @@ void aug_drop(AugValue value) {
748
786
  if (value.tag != AUG_OBJECT && value.tag != AUG_STRING) return;
749
787
  AugObject *object = value.as.object;
750
788
  if (!object || object->dropped) return;
789
+ AugValue roots[2] = {value, aug_error}; AugFrame frame; aug_frame_enter(&frame, roots, 2);
790
+ bool failed = aug_has_error, cancelled = aug_cancelled;
791
+ aug_error = aug_null(); aug_has_error = false; aug_cancelled = false;
751
792
  if (object->kind == AUG_OBJECT) {
752
793
  if (getenv("AUG_TRACE_DROPS")) fprintf(stderr, "drop: %s\n", object->type_name);
753
794
  for (size_t i = 0; i < object->method_count; i++)
754
795
  if (strcmp(object->methods[i].name, "drop") == 0) {
755
- object->methods[i].function(value, NULL, 0);
796
+ if(object->methods[i].pointer_function){AugValue ignored=aug_null();object->methods[i].pointer_function(&ignored,&value,NULL,0);}
797
+ else object->methods[i].function(value, NULL, 0);
756
798
  break;
757
799
  }
758
800
  }
759
801
  object->dropped = true;
802
+ if(object->kind==AUG_NATIVE_RESOURCE_KIND&&object->finalize){
803
+ void *native=object->native;void(*release)(void *)=object->finalize;
804
+ object->native=NULL;object->finalize=NULL;
805
+ if(native)release(native);
806
+ }
760
807
  for (size_t i = 0; i < object->field_count; i++)
761
808
  if (object->owned_fields && object->owned_fields[i]) aug_drop(object->fields[i]);
809
+ if (failed) aug_throw(roots[1]); aug_cancelled = aug_cancelled || cancelled;
810
+ aug_frame_leave(&frame);
762
811
  }
763
812
 
764
813
  void aug_throw(AugValue value) { aug_error = value; aug_has_error = true; }
814
+ void aug_constructor_result_cleanup(AugValue value, AugValue result) {
815
+ if (value.tag != AUG_OBJECT || !value.as.object || value.as.object->dropped) return;
816
+ if (aug_has_error || aug_cancelled || result.tag != AUG_OBJECT || result.as.object != value.as.object)
817
+ aug_drop(value);
818
+ }
819
+ void aug_drop_partial(AugValue value) {
820
+ if(value.tag!=AUG_OBJECT||!value.as.object||value.as.object->dropped)return;
821
+ AugValue roots[2]={value,aug_error};AugFrame frame;aug_frame_enter(&frame,roots,2);
822
+ bool pending=aug_has_error,cancelled=aug_cancelled;
823
+ aug_error=aug_null();aug_has_error=false;aug_cancelled=false;
824
+ AugObject *object=value.as.object;object->dropped=true;
825
+ for(size_t i=0;i<object->field_count;i++)
826
+ if(object->owned_fields&&object->owned_fields[i])aug_drop(object->fields[i]);
827
+ /* A constructor's checked failure remains primary during implicit cleanup. */
828
+ if(pending)aug_throw(roots[1]);aug_cancelled=aug_cancelled||cancelled;
829
+ aug_frame_leave(&frame);
830
+ }
765
831
  AugValue aug_take_error(void) {
766
832
  AugValue value = aug_error;
767
833
  aug_error = aug_null();
@@ -9,9 +9,10 @@
9
9
  typedef struct AugObject AugObject;
10
10
  typedef struct AugValue AugValue;
11
11
  typedef AugValue (*AugMethod)(AugValue self, AugValue *args, int count);
12
+ typedef void (*AugPointerMethod)(AugValue *out, const AugValue *self, AugValue *args, int count);
12
13
 
13
14
  enum { AUG_NULL, AUG_INT, AUG_FLOAT, AUG_BOOL, AUG_STRING, AUG_OBJECT };
14
- enum { AUG_LIST_KIND = 6, AUG_MAP_KIND, AUG_SET_KIND, AUG_TUPLE_KIND, AUG_RECORD_KIND, AUG_BYTES_KIND, AUG_PRIVATE_KEY_KIND, AUG_PUBLIC_KEY_KIND, AUG_JSON_KIND, AUG_HTTP_REQUEST_KIND, AUG_HTTP_RESPONSE_KIND, AUG_HEADERS_KIND, AUG_HTML_KIND, AUG_TASK_KIND, AUG_HTTP_ACTION_KIND };
15
+ enum { AUG_LIST_KIND = 6, AUG_MAP_KIND, AUG_SET_KIND, AUG_TUPLE_KIND, AUG_RECORD_KIND, AUG_BYTES_KIND, AUG_PRIVATE_KEY_KIND, AUG_PUBLIC_KEY_KIND, AUG_JSON_KIND, AUG_HTTP_REQUEST_KIND, AUG_HTTP_RESPONSE_KIND, AUG_HEADERS_KIND, AUG_HTML_KIND, AUG_TASK_KIND, AUG_HTTP_ACTION_KIND, AUG_NATIVE_RESOURCE_KIND };
15
16
 
16
17
  struct AugValue {
17
18
  int tag;
@@ -21,6 +22,7 @@ struct AugValue {
21
22
  typedef struct {
22
23
  const char *name;
23
24
  AugMethod function;
25
+ AugPointerMethod pointer_function;
24
26
  } AugMethodEntry;
25
27
 
26
28
  struct AugObject {
@@ -85,7 +87,11 @@ extern void (*aug_mutex_wait_hook)(void);
85
87
  typedef struct AugTask AugTask;
86
88
  typedef void (*AugTaskCompletion)(AugValue task, void *data);
87
89
  AugValue aug_task_start(AugMethod function, AugValue receiver, AugValue *args, int count);
90
+ AugValue aug_task_start_owned(AugMethod function, AugValue receiver, AugValue *args, int count, const unsigned char *owned);
88
91
  AugValue aug_task_spawn(AugMethod function, AugValue receiver, AugValue *args, int count, AugTaskCompletion completion, void *data);
92
+ /* Compiler-private entry points; native package callbacks have a separate ABI. */
93
+ void aug_task_start_pointer(AugValue *out, AugPointerMethod function, const AugValue *receiver, AugValue *args, int count, const unsigned char *owned);
94
+ void aug_task_spawn_pointer(AugValue *out, AugPointerMethod function, const AugValue *receiver, AugValue *args, int count, AugTaskCompletion completion, void *data);
89
95
  AugValue aug_task_wait(AugValue *tasks, int count);
90
96
  AugTask *aug_task_current(void);
91
97
  bool aug_task_finished(AugValue task);
@@ -134,6 +140,7 @@ bool aug_string_starts_with(AugValue value, AugValue prefix);
134
140
  bool aug_string_is_token(AugValue value, int64_t minimum, int64_t maximum);
135
141
  int64_t aug_bytes_length(AugValue value);
136
142
  AugValue aug_bytes_text(AugValue value);
143
+ bool aug_valid_utf8(const void *text, size_t size);
137
144
  AugValue aug_bytes_base64url(AugValue value);
138
145
  AugValue aug_base64url_decode(AugValue value);
139
146
 
@@ -144,8 +151,10 @@ enum { AUG_SCHEMA_INT, AUG_SCHEMA_C_INT, AUG_SCHEMA_FLOAT, AUG_SCHEMA_BOOL, AUG_
144
151
  struct AugSchema {
145
152
  int kind; bool nullable; bool optional; size_t count;
146
153
  const AugSchema *const *fields; const char *const *names; AugFunction make;
154
+ AugPointerMethod pointer_make;
147
155
  };
148
156
  AugValue aug_json_decode(AugValue value, const AugSchema *schema);
157
+ AugValue aug_schema_make(const AugSchema *schema, AugValue *fields, int count);
149
158
  AugValue aug_json_stringify(AugValue value);
150
159
  AugValue aug_json_get(AugValue value, AugValue name);
151
160
  AugValue aug_json_require(AugValue value, AugValue name);
@@ -155,15 +164,17 @@ bool aug_json_boolean(AugValue value);
155
164
  AugValue aug_json_items(AugValue value);
156
165
  AugValue aug_json_wrap(AugValue value);
157
166
  AugValue _aug_json_parse(AugValue input);
167
+ AugValue _aug_time_now(void);
158
168
  typedef enum {
159
169
  AUG_HTTP_POLICY_REQUIRE_LOGIN=1, AUG_HTTP_POLICY_REQUIRE_PERMISSION,
160
170
  AUG_HTTP_POLICY_LOG_REQUEST, AUG_HTTP_POLICY_RATE_LIMIT, AUG_HTTP_POLICY_TIMEOUT,
161
171
  AUG_HTTP_POLICY_CORS, AUG_HTTP_POLICY_COMPRESS
162
172
  } AugHttpPolicyKind;
163
173
  typedef struct {AugHttpPolicyKind kind;const char *permission;int64_t amount,seconds;bool credentials;const char *origins,*headers;} AugHttpPolicy;
164
- typedef struct { const char *method; const char *path; AugFunction handler; int stream; int status; const AugHttpPolicy *policies;size_t policy_count; } AugRoute;
174
+ typedef struct { const char *method; const char *path; AugFunction handler; int stream; int status; const AugHttpPolicy *policies;size_t policy_count; AugPointerMethod pointer_handler; } AugRoute;
165
175
  void aug_http_policy(const AugHttpPolicy *policy, AugValue request, AugValue dependency, AugValue second);
166
176
  AugValue aug_http_finish(AugValue response);
177
+ bool aug_http_head_response(AugValue *response);
167
178
  AugValue aug_http_bind(AugValue request, const char *source, const char *name, const AugSchema *schema);
168
179
  AugValue aug_httprequest_form(AugValue request, const AugSchema *schema);
169
180
  AugValue aug_http_response(AugValue body, int status);
@@ -236,6 +247,9 @@ void aug_scope_restore(size_t depth);
236
247
  void aug_collect(void);
237
248
  void aug_freeze(AugValue value);
238
249
  void aug_drop(AugValue value);
250
+ /* Failed construction releases initialized ownership without invoking drop. */
251
+ void aug_drop_partial(AugValue value);
252
+ void aug_constructor_result_cleanup(AugValue value, AugValue result);
239
253
  void aug_throw(AugValue value);
240
254
  AugValue aug_take_error(void);
241
255
  bool aug_error_is(const char *name);
@@ -7,10 +7,11 @@
7
7
 
8
8
  /* C stack suspension preserves ordinary August calls and their precise GC frames. */
9
9
  struct AugTask {
10
- mco_coro *coroutine; AugExecution execution; AugMethod function;
10
+ mco_coro *coroutine; AugExecution execution; AugMethod function; AugPointerMethod pointer_function;
11
11
  AugValue value; AugRetained retained; bool retained_active, queued, complete, observed;
12
12
  size_t base_depth; struct AugTask *ready_next, *sibling; AugScope *owner;
13
13
  AugTaskCompletion completion; void *completion_data; unsigned ticks;
14
+ unsigned char *owned_inputs;
14
15
  };
15
16
  static AugTask *ready_first, *ready_last;
16
17
  void (*aug_scheduler_io)(bool wait);
@@ -32,7 +33,7 @@ void aug_task_wake(AugTask *task) {
32
33
  static void destroy_task(void *native) {
33
34
  AugTask *task = native;
34
35
  if (!task->complete) fatal("collected an unfinished task");
35
- mco_destroy(task->coroutine); free(task);
36
+ mco_destroy(task->coroutine); free(task->owned_inputs); free(task);
36
37
  }
37
38
  void aug_task_release(AugValue value) {
38
39
  AugTask *task = task_of(value);
@@ -52,8 +53,22 @@ static void run_task(mco_coro *coroutine) {
52
53
  AugTask *task = mco_get_user_data(coroutine);
53
54
  AugValue arguments = aug_field(task->value, 1);
54
55
  if (!aug_cancelled) {
55
- AugValue result = task->function(aug_field(task->value, 0), arguments.as.object->fields, (int)arguments.as.object->field_count);
56
- aug_set_field(task->value, 2, result);
56
+ AugValue roots[2] = {aug_field(task->value, 0), aug_null()};
57
+ AugFrame frame; aug_frame_enter(&frame, roots, 2);
58
+ if (task->pointer_function) task->pointer_function(&roots[1], &roots[0], arguments.as.object->fields, (int)arguments.as.object->field_count);
59
+ else roots[1] = task->function(roots[0], arguments.as.object->fields, (int)arguments.as.object->field_count);
60
+ aug_set_field(task->value, 2, roots[1]);
61
+ aug_frame_leave(&frame);
62
+ } else if (task->owned_inputs) {
63
+ /* Ownership crossed at start, even if a sibling cancels this child before
64
+ entry. No callee ran to release these captures. Cleanup must run with
65
+ cancellation suspended, just as an always block does. */
66
+ AugValue pending = aug_error; AugFrame frame; aug_frame_enter(&frame, &pending, 1);
67
+ bool failed = aug_has_error; aug_error = aug_null(); aug_has_error = false; aug_cancelled = false;
68
+ for (size_t i = 0; i < arguments.as.object->field_count; i++) if (task->owned_inputs[i]) {
69
+ aug_drop(aug_field(arguments, i)); aug_set_field(arguments, i, aug_null());
70
+ }
71
+ if (failed) aug_throw(pending); aug_cancelled = true; aug_frame_leave(&frame);
57
72
  }
58
73
  aug_scope_restore(task->base_depth);
59
74
  if (aug_has_error) { aug_set_field(task->value, 3, aug_take_error()); cancel_group(task); }
@@ -110,14 +125,15 @@ static void join_scope(AugScope *scope) {
110
125
  if (!aug_has_error && first_error.tag != AUG_NULL) aug_throw(first_error);
111
126
  aug_frame_leave(&frame);
112
127
  }
113
- AugValue aug_task_spawn(AugMethod function, AugValue receiver, AugValue *args, int count, AugTaskCompletion completion, void *data) {
128
+ static AugValue spawn_task(AugMethod function, AugPointerMethod pointer_function, AugValue receiver, AugValue *args, int count, const unsigned char *owned, AugTaskCompletion completion, void *data) {
114
129
  aug_scope_join_hook = join_scope;
115
130
  AugValue roots[3] = {receiver, aug_null(), aug_null()}; AugFrame frame; aug_frame_enter(&frame, roots, 3);
116
131
  roots[1] = aug_list_new(args, (size_t)count);
117
132
  roots[2] = aug_new_object("Task", 4, NULL, NULL, 0); roots[2].as.object->kind = AUG_TASK_KIND;
118
133
  aug_set_field(roots[2], 0, receiver); aug_set_field(roots[2], 1, roots[1]);
119
134
  AugTask *task = calloc(1, sizeof(*task)); if (!task) fatal("out of memory");
120
- task->function = function; task->value = roots[2]; task->completion = completion; task->completion_data = data;
135
+ task->function = function; task->pointer_function = pointer_function; task->value = roots[2]; task->completion = completion; task->completion_data = data;
136
+ if (owned && count) { task->owned_inputs = malloc((size_t)count); if (!task->owned_inputs) fatal("out of memory"); memcpy(task->owned_inputs, owned, (size_t)count); }
121
137
  aug_execution_init(&task->execution); task->execution.fiber = task;
122
138
  AugExecution *parent = aug_execution_current();
123
139
  task->execution.scope_stack = parent->scope_stack; task->execution.scope_depth = parent->scope_depth; task->base_depth = parent->scope_depth;
@@ -128,10 +144,25 @@ AugValue aug_task_spawn(AugMethod function, AugValue receiver, AugValue *args, i
128
144
  if (mco_create(&task->coroutine, &description) != MCO_SUCCESS) fatal("cannot allocate coroutine stack");
129
145
  aug_task_wake(task); AugValue result = roots[2]; aug_frame_leave(&frame); return result;
130
146
  }
147
+ AugValue aug_task_spawn(AugMethod function, AugValue receiver, AugValue *args, int count, AugTaskCompletion completion, void *data) {
148
+ return spawn_task(function, NULL, receiver, args, count, NULL, completion, data);
149
+ }
150
+ void aug_task_spawn_pointer(AugValue *out, AugPointerMethod function, const AugValue *receiver, AugValue *args, int count, AugTaskCompletion completion, void *data) {
151
+ *out = spawn_task(NULL, function, receiver ? *receiver : aug_null(), args, count, NULL, completion, data);
152
+ }
153
+ void aug_task_start_pointer(AugValue *out, AugPointerMethod function, const AugValue *receiver, AugValue *args, int count, const unsigned char *owned) {
154
+ AugScope *scope = aug_execution_current()->scope_stack;
155
+ if (!scope) { *out = aug_error_named("ConcurrencyError"); return; }
156
+ *out = spawn_task(NULL, function, receiver ? *receiver : aug_null(), args, count, owned, NULL, NULL);
157
+ AugTask *task = task_of(*out); task->owner = scope; task->sibling = scope->tasks; scope->tasks = task;
158
+ }
131
159
  AugValue aug_task_start(AugMethod function, AugValue receiver, AugValue *args, int count) {
160
+ return aug_task_start_owned(function, receiver, args, count, NULL);
161
+ }
162
+ AugValue aug_task_start_owned(AugMethod function, AugValue receiver, AugValue *args, int count, const unsigned char *owned) {
132
163
  AugScope *scope = aug_execution_current()->scope_stack;
133
164
  if (!scope) return aug_error_named("ConcurrencyError");
134
- AugValue value = aug_task_spawn(function, receiver, args, count, NULL, NULL); AugTask *task = task_of(value);
165
+ AugValue value = spawn_task(function, NULL, receiver, args, count, owned, NULL, NULL); AugTask *task = task_of(value);
135
166
  task->owner = scope; task->sibling = scope->tasks; scope->tasks = task; return value;
136
167
  }
137
168
  static AugValue wait_one(AugValue value) {
@@ -25,22 +25,28 @@ AugValue aug_string_split(AugValue value, AugValue separator) {
25
25
  AugValue result = roots[1]; aug_frame_leave(&frame); return result;
26
26
  }
27
27
  int64_t aug_bytes_length(AugValue value) { return (int64_t)value.as.object->text_length; }
28
- AugValue aug_bytes_text(AugValue value) {
29
- const unsigned char *text = (const unsigned char *)value.as.object->text;
30
- size_t size = value.as.object->text_length;
28
+ bool aug_valid_utf8(const void *data, size_t size) {
29
+ if (!data && size) return false;
30
+ const unsigned char *text = data;
31
31
  for (size_t i = 0; i < size;) {
32
32
  unsigned char first = text[i++];
33
33
  if (first < 0x80) continue;
34
34
  int extra = first >= 0xc2 && first <= 0xdf ? 1 : first >= 0xe0 && first <= 0xef ? 2 : first >= 0xf0 && first <= 0xf4 ? 3 : -1;
35
- if (extra < 0 || i + (size_t)extra > size) return aug_error_named("ConversionError");
35
+ if (extra < 0 || (size_t)extra > size - i) return false;
36
36
  uint32_t code = first & (extra == 1 ? 0x1f : extra == 2 ? 0x0f : 0x07);
37
37
  for (int j = 0; j < extra; j++) {
38
38
  unsigned char next = text[i++];
39
- if ((next & 0xc0) != 0x80) return aug_error_named("ConversionError");
39
+ if ((next & 0xc0) != 0x80) return false;
40
40
  code = (code << 6) | (next & 0x3f);
41
41
  }
42
- if (code < (extra == 1 ? 0x80u : extra == 2 ? 0x800u : 0x10000u) || code > 0x10ffff || (code >= 0xd800 && code <= 0xdfff)) return aug_error_named("ConversionError");
42
+ if (code < (extra == 1 ? 0x80u : extra == 2 ? 0x800u : 0x10000u) || code > 0x10ffff || (code >= 0xd800 && code <= 0xdfff)) return false;
43
43
  }
44
+ return true;
45
+ }
46
+ AugValue aug_bytes_text(AugValue value) {
47
+ const void *text = value.as.object->text;
48
+ size_t size = value.as.object->text_length;
49
+ if (!aug_valid_utf8(text, size)) return aug_error_named("ConversionError");
44
50
  return aug_string_n(text, size);
45
51
  }
46
52
 
@@ -91,6 +91,8 @@ async function setup() {
91
91
 
92
92
  const sdk = '/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk';
93
93
  const mac = process.platform === 'darwin';
94
+ const minimumOS = mac ? process.env.MACOSX_DEPLOYMENT_TARGET : undefined;
95
+ if (minimumOS && !/^\d+\.\d+(?:\.\d+)?$/.test(minimumOS)) throw new Error('MACOSX_DEPLOYMENT_TARGET must be an OS version such as 14.0.');
94
96
  const sysroot = mac && existsSync(sdk) ? ' -isysroot ' + sdk : '';
95
97
  const environment = { ...process.env, ...(mac && existsSync(sdk) && !process.env.SDKROOT ? { SDKROOT: sdk } : {}), CC: cc, CC_FOR_BUILD: cc, CXX: process.env.CXX ?? cc.replace(/clang$/, 'clang++').replace(/gcc$/, 'g++').replace(/^cc$/, 'c++'),
96
98
  CFLAGS: `-O2 -fPIC${sysroot}`,
@@ -140,6 +142,7 @@ async function setup() {
140
142
  run(cmake, ['-S', join(sources, 'libwebsockets'), '-B', build,
141
143
  '-DCMAKE_BUILD_TYPE=Release', '-DCMAKE_INSTALL_PREFIX=' + prefix, '-DCMAKE_INSTALL_LIBDIR=lib', '-DCMAKE_PREFIX_PATH=' + prefix,
142
144
  '-DCMAKE_C_COMPILER=' + cc, ...(mac && existsSync(sdk) && !process.env.SDKROOT ? ['-DCMAKE_OSX_SYSROOT=' + sdk] : []),
145
+ ...(minimumOS ? ['-DCMAKE_OSX_DEPLOYMENT_TARGET=' + minimumOS] : []),
143
146
  '-DLWS_GNUTLS_LIBRARIES=' + join(prefix, 'lib', mac ? 'libgnutls.dylib' : 'libgnutls.so'),
144
147
  '-DLWS_GNUTLS_INCLUDE_DIRS=' + join(prefix, 'include'),
145
148
  '-DLWS_WITH_GNUTLS=ON', '-DLWS_WITH_HTTP2=ON', '-DLWS_WITH_HTTP3=ON',
@@ -153,7 +156,7 @@ async function setup() {
153
156
  writeFileSync(webMarker, webChecksum + '\n');
154
157
  }
155
158
  }
156
- writeFileSync(join(prefix, 'aug-native-manifest.json'), JSON.stringify({ platform: process.platform, architecture: process.arch,
159
+ writeFileSync(join(prefix, 'aug-native-manifest.json'), JSON.stringify({ platform: process.platform, architecture: process.arch, ...(minimumOS ? {minimumOS} : {}),
157
160
  dependencies: lock.dependencies.filter(dependency => dependencyReady(directory, dependency)).map(({name, version, revision, sha256}) => ({name, version, revision, sha256})) }, null, 2) + '\n');
158
161
  process.stdout.write(`Native dependencies ready at ${prefix}\n`);
159
162
  } finally { release(); }
package/src/ast.js CHANGED
@@ -1,5 +1,5 @@
1
1
  export function isStatement(item) {
2
- return !['import', 'export', 'bind', 'composition', 'include', 'class', 'interface', 'interceptor', 'function', 'test'].includes(item.kind);
2
+ return !['import', 'export', 'bind', 'composition', 'include', 'class', 'interface', 'interceptor', 'resource', 'function', 'test'].includes(item.kind);
3
3
  }
4
4
  export function typeName(type) {
5
5
  return (type.optional || type.nullable ? 'optional ' : '') + type.name + (type.args.length ? `<${type.args.map(typeName).join(',')}>` : '');