@scriptc/compiler 0.1.7 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1043) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +98 -39
  2. package/ambient/scriptc-overrides.d.ts +10 -6
  3. package/ambient/scriptc.d.ts +15 -0
  4. package/dist/backend/build-cache.d.ts +1 -3
  5. package/dist/backend/build-cache.js +3 -22
  6. package/dist/backend/build-cache.js.map +1 -1
  7. package/dist/backend/cache-root.d.ts +3 -0
  8. package/dist/backend/cache-root.js +23 -0
  9. package/dist/backend/cache-root.js.map +1 -0
  10. package/dist/backend/cycle-analysis.d.ts +15 -0
  11. package/dist/backend/cycle-analysis.js +108 -0
  12. package/dist/backend/cycle-analysis.js.map +1 -0
  13. package/dist/backend/cycle-analysis.test.js +124 -0
  14. package/dist/backend/cycle-analysis.test.js.map +1 -0
  15. package/dist/backend/executable-features.d.ts +4 -0
  16. package/dist/backend/executable-features.js +42 -0
  17. package/dist/backend/executable-features.js.map +1 -0
  18. package/dist/backend/external-c.d.ts +5 -27
  19. package/dist/backend/external-c.js +5 -40
  20. package/dist/backend/external-c.js.map +1 -1
  21. package/dist/backend/ffi-callbacks.d.ts +2 -3
  22. package/dist/backend/ffi-callbacks.js +2 -3
  23. package/dist/backend/ffi-callbacks.js.map +1 -1
  24. package/dist/backend/library-identity-markers.d.ts +4 -9
  25. package/dist/backend/library-identity-markers.js +11 -49
  26. package/dist/backend/library-identity-markers.js.map +1 -1
  27. package/dist/backend/library-pack.d.ts +5 -0
  28. package/dist/backend/library-pack.js +123 -0
  29. package/dist/backend/library-pack.js.map +1 -0
  30. package/dist/backend/link-plan-core.d.ts +20 -0
  31. package/dist/backend/link-plan-core.js +18 -0
  32. package/dist/backend/link-plan-core.js.map +1 -0
  33. package/dist/backend/link-plan.d.ts +1 -1
  34. package/dist/backend/link-plan.js +16 -17
  35. package/dist/backend/link-plan.js.map +1 -1
  36. package/dist/backend/link-trace.d.ts +2 -0
  37. package/dist/backend/link-trace.js +24 -0
  38. package/dist/backend/link-trace.js.map +1 -0
  39. package/dist/backend/linker.js +1 -1
  40. package/dist/backend/linker.js.map +1 -1
  41. package/dist/backend/literals.d.ts +9 -0
  42. package/dist/backend/literals.js +35 -0
  43. package/dist/backend/literals.js.map +1 -0
  44. package/dist/backend/literals.test.d.ts +1 -0
  45. package/dist/backend/literals.test.js +53 -0
  46. package/dist/backend/literals.test.js.map +1 -0
  47. package/dist/backend/llvm/blocks.d.ts +2 -0
  48. package/dist/backend/llvm/blocks.js +9 -4
  49. package/dist/backend/llvm/blocks.js.map +1 -1
  50. package/dist/backend/llvm/blocks.test.d.ts +1 -0
  51. package/dist/backend/llvm/blocks.test.js +91 -0
  52. package/dist/backend/llvm/blocks.test.js.map +1 -0
  53. package/dist/backend/llvm/classes.d.ts +14 -8
  54. package/dist/backend/llvm/classes.js +88 -30
  55. package/dist/backend/llvm/classes.js.map +1 -1
  56. package/dist/backend/llvm/common.d.ts +5 -1
  57. package/dist/backend/llvm/common.js +45 -4
  58. package/dist/backend/llvm/common.js.map +1 -1
  59. package/dist/backend/llvm/debug-info.js +2 -7
  60. package/dist/backend/llvm/debug-info.js.map +1 -1
  61. package/dist/backend/llvm/debug-info.test.d.ts +1 -0
  62. package/dist/backend/llvm/debug-info.test.js +110 -0
  63. package/dist/backend/llvm/debug-info.test.js.map +1 -0
  64. package/dist/backend/llvm/dyn.d.ts +21 -2
  65. package/dist/backend/llvm/dyn.js +647 -251
  66. package/dist/backend/llvm/dyn.js.map +1 -1
  67. package/dist/backend/llvm/emitter.d.ts +596 -1
  68. package/dist/backend/llvm/emitter.js +769 -425
  69. package/dist/backend/llvm/emitter.js.map +1 -1
  70. package/dist/backend/llvm/emitter.test.d.ts +1 -0
  71. package/dist/backend/llvm/emitter.test.js +179 -0
  72. package/dist/backend/llvm/emitter.test.js.map +1 -0
  73. package/dist/backend/llvm/expr-async.js +23 -14
  74. package/dist/backend/llvm/expr-async.js.map +1 -1
  75. package/dist/backend/llvm/expr-bytes.d.ts +2 -2
  76. package/dist/backend/llvm/expr-bytes.js +60 -31
  77. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  78. package/dist/backend/llvm/expr-callbacks.d.ts +1 -1
  79. package/dist/backend/llvm/expr-callbacks.js +25 -22
  80. package/dist/backend/llvm/expr-callbacks.js.map +1 -1
  81. package/dist/backend/llvm/expr-calls.js +136 -35
  82. package/dist/backend/llvm/expr-calls.js.map +1 -1
  83. package/dist/backend/llvm/expr-containers.d.ts +1 -1
  84. package/dist/backend/llvm/expr-containers.js +43 -14
  85. package/dist/backend/llvm/expr-containers.js.map +1 -1
  86. package/dist/backend/llvm/expr-context.d.ts +5 -260
  87. package/dist/backend/llvm/expr-control.js +10 -6
  88. package/dist/backend/llvm/expr-control.js.map +1 -1
  89. package/dist/backend/llvm/expr-dispatch.d.ts +1 -1
  90. package/dist/backend/llvm/expr-dispatch.js +2 -0
  91. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  92. package/dist/backend/llvm/expr-dynamic.js +78 -81
  93. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  94. package/dist/backend/llvm/expr-island.d.ts +1 -1
  95. package/dist/backend/llvm/expr-island.js +11 -7
  96. package/dist/backend/llvm/expr-island.js.map +1 -1
  97. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  98. package/dist/backend/llvm/expr-primitives.js +62 -31
  99. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  100. package/dist/backend/llvm/expr-primitives.test.js +1 -1
  101. package/dist/backend/llvm/expr-records.d.ts +5 -1
  102. package/dist/backend/llvm/expr-records.js +54 -7
  103. package/dist/backend/llvm/expr-records.js.map +1 -1
  104. package/dist/backend/llvm/expr-stream-bridges.d.ts +4 -4
  105. package/dist/backend/llvm/expr-stream-bridges.js +220 -131
  106. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  107. package/dist/backend/llvm/expr-stream-bridges.test.d.ts +1 -0
  108. package/dist/backend/llvm/expr-stream-bridges.test.js +55 -0
  109. package/dist/backend/llvm/expr-stream-bridges.test.js.map +1 -0
  110. package/dist/backend/llvm/expr-stream-callbacks.d.ts +1 -1
  111. package/dist/backend/llvm/expr-stream-callbacks.js +12 -12
  112. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  113. package/dist/backend/llvm/layouts.d.ts +19 -0
  114. package/dist/backend/llvm/layouts.js +12 -0
  115. package/dist/backend/llvm/layouts.js.map +1 -0
  116. package/dist/backend/llvm/lib-abi.d.ts +19 -0
  117. package/dist/backend/llvm/lib-abi.js +82 -0
  118. package/dist/backend/llvm/lib-abi.js.map +1 -0
  119. package/dist/backend/llvm/lib-connect.d.ts +2 -0
  120. package/dist/backend/llvm/lib-connect.js +51 -0
  121. package/dist/backend/llvm/lib-connect.js.map +1 -0
  122. package/dist/backend/llvm/lib-datagram.d.ts +2 -0
  123. package/dist/backend/llvm/lib-datagram.js +135 -0
  124. package/dist/backend/llvm/lib-datagram.js.map +1 -0
  125. package/dist/backend/llvm/lib-dispatch.js +50 -6
  126. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  127. package/dist/backend/llvm/lib-filesystem.js +30 -18
  128. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  129. package/dist/backend/llvm/lib-http2.d.ts +2 -0
  130. package/dist/backend/llvm/lib-http2.js +215 -0
  131. package/dist/backend/llvm/lib-http2.js.map +1 -0
  132. package/dist/backend/llvm/lib-lookup.d.ts +2 -0
  133. package/dist/backend/llvm/lib-lookup.js +39 -0
  134. package/dist/backend/llvm/lib-lookup.js.map +1 -0
  135. package/dist/backend/llvm/lib-network.js +25 -2
  136. package/dist/backend/llvm/lib-network.js.map +1 -1
  137. package/dist/backend/llvm/lib-process.js +44 -19
  138. package/dist/backend/llvm/lib-process.js.map +1 -1
  139. package/dist/backend/llvm/lib-shared.js +162 -3
  140. package/dist/backend/llvm/lib-shared.js.map +1 -1
  141. package/dist/backend/llvm/lib-stream.js +3 -2
  142. package/dist/backend/llvm/lib-stream.js.map +1 -1
  143. package/dist/backend/llvm/lib-test.d.ts +2 -0
  144. package/dist/backend/llvm/lib-test.js +34 -0
  145. package/dist/backend/llvm/lib-test.js.map +1 -0
  146. package/dist/backend/llvm/lib-tls.d.ts +2 -0
  147. package/dist/backend/llvm/lib-tls.js +82 -0
  148. package/dist/backend/llvm/lib-tls.js.map +1 -0
  149. package/dist/backend/llvm/shapes.d.ts +10 -9
  150. package/dist/backend/llvm/shapes.js +42 -131
  151. package/dist/backend/llvm/shapes.js.map +1 -1
  152. package/dist/backend/llvm/unsupported.d.ts +1 -0
  153. package/dist/backend/llvm/unsupported.js +1 -2
  154. package/dist/backend/llvm/unsupported.js.map +1 -1
  155. package/dist/backend/llvm/walkers.js +1 -7
  156. package/dist/backend/llvm/walkers.js.map +1 -1
  157. package/dist/backend/mangle.d.ts +2 -2
  158. package/dist/backend/mangle.js +16 -5
  159. package/dist/backend/mangle.js.map +1 -1
  160. package/dist/backend/{c/may-throw.d.ts → may-throw.d.ts} +1 -1
  161. package/dist/backend/{c/may-throw.js → may-throw.js} +51 -46
  162. package/dist/backend/may-throw.js.map +1 -0
  163. package/dist/backend/may-throw.test.d.ts +1 -0
  164. package/dist/backend/may-throw.test.js +58 -0
  165. package/dist/backend/may-throw.test.js.map +1 -0
  166. package/dist/backend/native-codegen-core.d.ts +22 -0
  167. package/dist/backend/native-codegen-core.js +44 -0
  168. package/dist/backend/native-codegen-core.js.map +1 -0
  169. package/dist/backend/native-codegen.d.ts +3 -19
  170. package/dist/backend/native-codegen.js +5 -44
  171. package/dist/backend/native-codegen.js.map +1 -1
  172. package/dist/backend/native-codegen.test.js +2 -2
  173. package/dist/backend/native-codegen.test.js.map +1 -1
  174. package/dist/backend/native-link-info-core.d.ts +94 -0
  175. package/dist/backend/native-link-info-core.js +62 -0
  176. package/dist/backend/native-link-info-core.js.map +1 -0
  177. package/dist/backend/native-link-info.d.ts +3 -88
  178. package/dist/backend/native-link-info.js +12 -243
  179. package/dist/backend/native-link-info.js.map +1 -1
  180. package/dist/backend/native-link-info.test.js +41 -146
  181. package/dist/backend/native-link-info.test.js.map +1 -1
  182. package/dist/backend/native-toolchain.d.ts +12 -30
  183. package/dist/backend/native-toolchain.js +83 -233
  184. package/dist/backend/native-toolchain.js.map +1 -1
  185. package/dist/backend/native-toolchain.test.js +77 -5
  186. package/dist/backend/native-toolchain.test.js.map +1 -1
  187. package/dist/backend/native-tools.d.ts +24 -0
  188. package/dist/backend/native-tools.js +33 -0
  189. package/dist/backend/native-tools.js.map +1 -0
  190. package/dist/backend/object-localize.js +19 -8
  191. package/dist/backend/object-localize.js.map +1 -1
  192. package/dist/backend/object-localize.test.js +22 -0
  193. package/dist/backend/object-localize.test.js.map +1 -1
  194. package/dist/backend/runtime-abi.d.ts +2 -2
  195. package/dist/backend/runtime-abi.js +2 -2
  196. package/dist/backend/runtime-pack-core.d.ts +101 -0
  197. package/dist/backend/runtime-pack-core.js +172 -0
  198. package/dist/backend/runtime-pack-core.js.map +1 -0
  199. package/dist/backend/runtime-pack-native.d.ts +21 -0
  200. package/dist/backend/runtime-pack-native.js +73 -0
  201. package/dist/backend/runtime-pack-native.js.map +1 -0
  202. package/dist/backend/runtime-pack-targets.test.js +1 -1
  203. package/dist/backend/runtime-pack.d.ts +3 -83
  204. package/dist/backend/runtime-pack.js +8 -151
  205. package/dist/backend/runtime-pack.js.map +1 -1
  206. package/dist/backend/runtime-pack.test.js +24 -1
  207. package/dist/backend/runtime-pack.test.js.map +1 -1
  208. package/dist/backend/target-diagnostics.d.ts +22 -0
  209. package/dist/backend/target-diagnostics.js +108 -0
  210. package/dist/backend/target-diagnostics.js.map +1 -0
  211. package/dist/backend/target-platform.d.ts +15 -0
  212. package/dist/backend/target-platform.js +72 -0
  213. package/dist/backend/target-platform.js.map +1 -0
  214. package/dist/backend/targets.d.ts +13 -4
  215. package/dist/backend/targets.js +103 -34
  216. package/dist/backend/targets.js.map +1 -1
  217. package/dist/backend/targets.test.js +72 -4
  218. package/dist/backend/targets.test.js.map +1 -1
  219. package/dist/backend/toolchain-environment.d.ts +6 -0
  220. package/dist/backend/toolchain-environment.js +99 -0
  221. package/dist/backend/toolchain-environment.js.map +1 -0
  222. package/dist/backend/vendor-archives.d.ts +1 -9
  223. package/dist/backend/vendor-archives.js +2 -9
  224. package/dist/backend/vendor-archives.js.map +1 -1
  225. package/dist/backend/vendor-inputs.d.ts +9 -0
  226. package/dist/backend/vendor-inputs.js +10 -0
  227. package/dist/backend/vendor-inputs.js.map +1 -0
  228. package/dist/backend/warm-cache.d.ts +3 -0
  229. package/dist/backend/warm-cache.js +41 -0
  230. package/dist/backend/warm-cache.js.map +1 -0
  231. package/dist/cli/command.d.ts +3 -0
  232. package/dist/cli/command.js +328 -0
  233. package/dist/cli/command.js.map +1 -0
  234. package/dist/cli/host.d.ts +24 -0
  235. package/dist/cli/host.js +2 -0
  236. package/dist/cli/host.js.map +1 -0
  237. package/dist/cli/output-options.d.ts +26 -0
  238. package/dist/cli/output-options.js +60 -0
  239. package/dist/cli/output-options.js.map +1 -0
  240. package/dist/cli/paths.d.ts +12 -0
  241. package/dist/cli/paths.js +42 -0
  242. package/dist/cli/paths.js.map +1 -0
  243. package/dist/cli/usage.d.ts +74 -0
  244. package/dist/cli/usage.js +86 -0
  245. package/dist/cli/usage.js.map +1 -0
  246. package/dist/cli/wasi-paths.d.ts +8 -0
  247. package/dist/cli/wasi-paths.js +41 -0
  248. package/dist/cli/wasi-paths.js.map +1 -0
  249. package/dist/cli/wasi-runner.d.ts +2 -0
  250. package/dist/cli/wasi-runner.js +28 -0
  251. package/dist/cli/wasi-runner.js.map +1 -0
  252. package/dist/compat/fetch-profile.js +37 -7
  253. package/dist/compat/fetch-profile.js.map +1 -1
  254. package/dist/compile-types.d.ts +162 -0
  255. package/dist/compile-types.js +2 -0
  256. package/dist/compile-types.js.map +1 -0
  257. package/dist/coverage/report.js +11 -5
  258. package/dist/coverage/report.js.map +1 -1
  259. package/dist/coverage/surface-manifest.js +5 -2
  260. package/dist/coverage/surface-manifest.js.map +1 -1
  261. package/dist/diagnostics/diagnostic.js +5 -10
  262. package/dist/diagnostics/diagnostic.js.map +1 -1
  263. package/dist/executable/executable-cache.d.ts +3 -4
  264. package/dist/executable/executable-cache.js +5 -6
  265. package/dist/executable/executable-cache.js.map +1 -1
  266. package/dist/executable/executable-cache.test.js +16 -17
  267. package/dist/executable/executable-cache.test.js.map +1 -1
  268. package/dist/executable/prepare.d.ts +14 -0
  269. package/dist/executable/prepare.js +66 -0
  270. package/dist/executable/prepare.js.map +1 -0
  271. package/dist/ffi/ffi-manifest.d.ts +11 -4
  272. package/dist/ffi/ffi-manifest.js +170 -58
  273. package/dist/ffi/ffi-manifest.js.map +1 -1
  274. package/dist/ffi/ffi-manifest.test.d.ts +1 -0
  275. package/dist/ffi/ffi-manifest.test.js +111 -0
  276. package/dist/ffi/ffi-manifest.test.js.map +1 -0
  277. package/dist/format-integer.d.ts +3 -0
  278. package/dist/format-integer.js +14 -0
  279. package/dist/format-integer.js.map +1 -0
  280. package/dist/frontend/analysis.d.ts +5 -0
  281. package/dist/frontend/analysis.js +88 -0
  282. package/dist/frontend/analysis.js.map +1 -0
  283. package/dist/frontend/arguments-usage.d.ts +1 -3
  284. package/dist/frontend/arguments-usage.js.map +1 -1
  285. package/dist/frontend/builtin-modules.d.ts +1 -1
  286. package/dist/frontend/builtin-modules.js +1 -1
  287. package/dist/frontend/builtin-modules.js.map +1 -1
  288. package/dist/frontend/cjs-lexer.d.ts +4 -25
  289. package/dist/frontend/cjs-lexer.js +6 -806
  290. package/dist/frontend/cjs-lexer.js.map +1 -1
  291. package/dist/frontend/cjs-resolve.d.ts +5 -0
  292. package/dist/frontend/cjs-resolve.js +429 -0
  293. package/dist/frontend/cjs-resolve.js.map +1 -0
  294. package/dist/frontend/cjs-syntax.d.ts +26 -0
  295. package/dist/frontend/cjs-syntax.js +806 -0
  296. package/dist/frontend/cjs-syntax.js.map +1 -0
  297. package/dist/frontend/comptime-node.d.ts +4 -0
  298. package/dist/frontend/comptime-node.js +16 -0
  299. package/dist/frontend/comptime-node.js.map +1 -0
  300. package/dist/frontend/comptime-node.test.d.ts +1 -0
  301. package/dist/frontend/comptime-node.test.js +37 -0
  302. package/dist/frontend/comptime-node.test.js.map +1 -0
  303. package/dist/frontend/dts-paths.d.ts +3 -4
  304. package/dist/frontend/dts-paths.js +15 -8
  305. package/dist/frontend/dts-paths.js.map +1 -1
  306. package/dist/frontend/fork-target.js +2 -2
  307. package/dist/frontend/fork-target.js.map +1 -1
  308. package/dist/frontend/helper-tokens.d.ts +1 -0
  309. package/dist/frontend/helper-tokens.js +147 -0
  310. package/dist/frontend/helper-tokens.js.map +1 -0
  311. package/dist/frontend/helper-tokens.test.d.ts +1 -0
  312. package/dist/frontend/helper-tokens.test.js +35 -0
  313. package/dist/frontend/helper-tokens.test.js.map +1 -0
  314. package/dist/frontend/inferred-js-diagnostics.d.ts +5 -0
  315. package/dist/frontend/inferred-js-diagnostics.js +69 -0
  316. package/dist/frontend/inferred-js-diagnostics.js.map +1 -0
  317. package/dist/frontend/inferred-js-diagnostics.test.d.ts +1 -0
  318. package/dist/frontend/inferred-js-diagnostics.test.js +58 -0
  319. package/dist/frontend/inferred-js-diagnostics.test.js.map +1 -0
  320. package/dist/frontend/input-tracker.d.ts +5 -2
  321. package/dist/frontend/input-tracker.js +24 -3
  322. package/dist/frontend/input-tracker.js.map +1 -1
  323. package/dist/frontend/input-tracker.test.js +23 -0
  324. package/dist/frontend/input-tracker.test.js.map +1 -1
  325. package/dist/frontend/lib-contract.js +32 -24
  326. package/dist/frontend/lib-contract.js.map +1 -1
  327. package/dist/frontend/literal-values.d.ts +4 -0
  328. package/dist/frontend/literal-values.js +21 -0
  329. package/dist/frontend/literal-values.js.map +1 -0
  330. package/dist/frontend/literal-values.test.d.ts +1 -0
  331. package/dist/frontend/literal-values.test.js +91 -0
  332. package/dist/frontend/literal-values.test.js.map +1 -0
  333. package/dist/frontend/lowering/abstract-equality.d.ts +1 -1
  334. package/dist/frontend/lowering/abstract-equality.js +3 -0
  335. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  336. package/dist/frontend/lowering/array-indexed-mutation.js +11 -6
  337. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -1
  338. package/dist/frontend/lowering/array-values.d.ts +4 -1
  339. package/dist/frontend/lowering/array-values.js +43 -1
  340. package/dist/frontend/lowering/array-values.js.map +1 -1
  341. package/dist/frontend/lowering/callback-arg.js +1 -0
  342. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  343. package/dist/frontend/lowering/class-callbacks.d.ts +12 -0
  344. package/dist/frontend/lowering/class-callbacks.js +74 -0
  345. package/dist/frontend/lowering/class-callbacks.js.map +1 -0
  346. package/dist/frontend/lowering/class-construction.d.ts +12 -0
  347. package/dist/frontend/lowering/class-construction.js +156 -0
  348. package/dist/frontend/lowering/class-construction.js.map +1 -0
  349. package/dist/frontend/lowering/class-descriptors.d.ts +10 -0
  350. package/dist/frontend/lowering/class-descriptors.js +114 -0
  351. package/dist/frontend/lowering/class-descriptors.js.map +1 -0
  352. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +51 -0
  353. package/dist/frontend/lowering/class-dynamic-dispatch.js +1158 -0
  354. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -0
  355. package/dist/frontend/lowering/class-dynamic-dispatch.test.d.ts +1 -0
  356. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +93 -0
  357. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -0
  358. package/dist/frontend/lowering/class-instance-constructor.d.ts +7 -0
  359. package/dist/frontend/lowering/class-instance-constructor.js +67 -0
  360. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -0
  361. package/dist/frontend/lowering/class-method-values.d.ts +13 -0
  362. package/dist/frontend/lowering/class-method-values.js +235 -0
  363. package/dist/frontend/lowering/class-method-values.js.map +1 -0
  364. package/dist/frontend/lowering/class-prototypes.d.ts +19 -0
  365. package/dist/frontend/lowering/class-prototypes.js +242 -0
  366. package/dist/frontend/lowering/class-prototypes.js.map +1 -0
  367. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  368. package/dist/frontend/lowering/class-runtime-statics.js +66 -0
  369. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
  370. package/dist/frontend/lowering/class-static-data.d.ts +6 -0
  371. package/dist/frontend/lowering/class-static-data.js +56 -0
  372. package/dist/frontend/lowering/class-static-data.js.map +1 -0
  373. package/dist/frontend/lowering/containers/buffer-numeric-methods.d.ts +4 -0
  374. package/dist/frontend/lowering/containers/buffer-numeric-methods.js +26 -0
  375. package/dist/frontend/lowering/containers/buffer-numeric-methods.js.map +1 -0
  376. package/dist/frontend/lowering/containers/bytes.d.ts +11 -7
  377. package/dist/frontend/lowering/containers/bytes.js +208 -163
  378. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  379. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +2 -2
  380. package/dist/frontend/lowering/containers/string-and-regexp.js +58 -63
  381. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  382. package/dist/frontend/lowering/containers/string-replacement.d.ts +7 -0
  383. package/dist/frontend/lowering/containers/string-replacement.js +217 -0
  384. package/dist/frontend/lowering/containers/string-replacement.js.map +1 -0
  385. package/dist/frontend/lowering/error-methods.d.ts +14 -0
  386. package/dist/frontend/lowering/error-methods.js +177 -0
  387. package/dist/frontend/lowering/error-methods.js.map +1 -0
  388. package/dist/frontend/lowering/expressions/global-symbols.d.ts +6 -0
  389. package/dist/frontend/lowering/expressions/global-symbols.js +11 -0
  390. package/dist/frontend/lowering/expressions/global-symbols.js.map +1 -0
  391. package/dist/frontend/lowering/expressions/native-proxy.d.ts +7 -0
  392. package/dist/frontend/lowering/expressions/native-proxy.js +51 -0
  393. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -0
  394. package/dist/frontend/lowering/expressions/nullish-assignment.d.ts +6 -0
  395. package/dist/frontend/lowering/expressions/nullish-assignment.js +132 -0
  396. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -0
  397. package/dist/frontend/lowering/expressions/object-literals.d.ts +8 -8
  398. package/dist/frontend/lowering/expressions/object-literals.js +509 -183
  399. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  400. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
  401. package/dist/frontend/lowering/expressions/optional-chains.js +88 -24
  402. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  403. package/dist/frontend/lowering/expressions/try-lower-expression.js +1 -0
  404. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -1
  405. package/dist/frontend/lowering/expressions/union-field-write.d.ts +8 -0
  406. package/dist/frontend/lowering/expressions/union-field-write.js +71 -0
  407. package/dist/frontend/lowering/expressions/union-field-write.js.map +1 -0
  408. package/dist/frontend/lowering/function-context.d.ts +101 -0
  409. package/dist/frontend/lowering/function-context.js +109 -0
  410. package/dist/frontend/lowering/function-context.js.map +1 -0
  411. package/dist/frontend/lowering/generator-delegation.d.ts +7 -0
  412. package/dist/frontend/lowering/generator-delegation.js +85 -0
  413. package/dist/frontend/lowering/generator-delegation.js.map +1 -0
  414. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +11 -0
  415. package/dist/frontend/lowering/generator-dynamic-dispatch.js +143 -0
  416. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -0
  417. package/dist/frontend/lowering/lib-boundary.d.ts +4 -1
  418. package/dist/frontend/lowering/lib-boundary.js +112 -20
  419. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  420. package/dist/frontend/lowering/lib-boundary.test.d.ts +1 -0
  421. package/dist/frontend/lowering/lib-boundary.test.js +45 -0
  422. package/dist/frontend/lowering/lib-boundary.test.js.map +1 -0
  423. package/dist/frontend/lowering/lower-array-sort.d.ts +1 -1
  424. package/dist/frontend/lowering/lower-assert.d.ts +1 -1
  425. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  426. package/dist/frontend/lowering/lower-async-iteration.d.ts +1 -1
  427. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -1
  428. package/dist/frontend/lowering/lower-builtin-values.d.ts +18 -0
  429. package/dist/frontend/lowering/lower-builtin-values.js +249 -0
  430. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -0
  431. package/dist/frontend/lowering/lower-builtins.d.ts +33 -46
  432. package/dist/frontend/lowering/lower-builtins.js +676 -365
  433. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  434. package/dist/frontend/lowering/lower-calls.d.ts +28 -22
  435. package/dist/frontend/lowering/lower-calls.js +1660 -412
  436. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  437. package/dist/frontend/lowering/lower-classes.d.ts +95 -57
  438. package/dist/frontend/lowering/lower-classes.js +1491 -404
  439. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  440. package/dist/frontend/lowering/lower-comptime.d.ts +1 -1
  441. package/dist/frontend/lowering/lower-comptime.js +23 -32
  442. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  443. package/dist/frontend/lowering/lower-containers.d.ts +36 -32
  444. package/dist/frontend/lowering/lower-containers.js +925 -181
  445. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  446. package/dist/frontend/lowering/lower-dgram.d.ts +1 -1
  447. package/dist/frontend/lowering/lower-dgram.js +3 -2
  448. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  449. package/dist/frontend/lowering/lower-enums.d.ts +1 -1
  450. package/dist/frontend/lowering/lower-enums.js.map +1 -1
  451. package/dist/frontend/lowering/lower-event-emitter.d.ts +30 -1
  452. package/dist/frontend/lowering/lower-event-emitter.js +58 -26
  453. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  454. package/dist/frontend/lowering/lower-expando.d.ts +7 -1
  455. package/dist/frontend/lowering/lower-expando.js +14 -6
  456. package/dist/frontend/lowering/lower-expando.js.map +1 -1
  457. package/dist/frontend/lowering/lower-exprs.d.ts +37 -13
  458. package/dist/frontend/lowering/lower-exprs.js +2163 -863
  459. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  460. package/dist/frontend/lowering/lower-generators.d.ts +2 -5
  461. package/dist/frontend/lowering/lower-generators.js +88 -46
  462. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  463. package/dist/frontend/lowering/lower-global-value.d.ts +7 -0
  464. package/dist/frontend/lowering/lower-global-value.js +17 -0
  465. package/dist/frontend/lowering/lower-global-value.js.map +1 -0
  466. package/dist/frontend/lowering/lower-inspect.d.ts +1 -1
  467. package/dist/frontend/lowering/lower-inspect.js +17 -8
  468. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  469. package/dist/frontend/lowering/lower-island.d.ts +7 -8
  470. package/dist/frontend/lowering/lower-island.js +66 -33
  471. package/dist/frontend/lowering/lower-island.js.map +1 -1
  472. package/dist/frontend/lowering/lower-mixins.d.ts +2 -2
  473. package/dist/frontend/lowering/lower-mixins.js +5 -3
  474. package/dist/frontend/lowering/lower-mixins.js.map +1 -1
  475. package/dist/frontend/lowering/lower-modules.d.ts +1 -1
  476. package/dist/frontend/lowering/lower-modules.js +445 -39
  477. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  478. package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
  479. package/dist/frontend/lowering/lower-modules.test.js +39 -0
  480. package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
  481. package/dist/frontend/lowering/lower-namespaces.d.ts +1 -1
  482. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  483. package/dist/frontend/lowering/lower-node-module.d.ts +1 -1
  484. package/dist/frontend/lowering/lower-node-module.js +13 -10
  485. package/dist/frontend/lowering/lower-node-module.js.map +1 -1
  486. package/dist/frontend/lowering/lower-server.d.ts +1 -1
  487. package/dist/frontend/lowering/lower-server.js +6 -10
  488. package/dist/frontend/lowering/lower-server.js.map +1 -1
  489. package/dist/frontend/lowering/lower-stmts.d.ts +17 -17
  490. package/dist/frontend/lowering/lower-stmts.js +855 -514
  491. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  492. package/dist/frontend/lowering/lower-stream.d.ts +1 -1
  493. package/dist/frontend/lowering/lower-stream.js +20 -11
  494. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  495. package/dist/frontend/lowering/lower-test.d.ts +1 -1
  496. package/dist/frontend/lowering/lower-test.js.map +1 -1
  497. package/dist/frontend/lowering/lower-url.d.ts +6 -0
  498. package/dist/frontend/lowering/lower-url.js +77 -0
  499. package/dist/frontend/lowering/lower-url.js.map +1 -0
  500. package/dist/frontend/lowering/lowerer.d.ts +140 -190
  501. package/dist/frontend/lowering/lowerer.js +1193 -712
  502. package/dist/frontend/lowering/lowerer.js.map +1 -1
  503. package/dist/frontend/lowering/lowerer.test.d.ts +1 -0
  504. package/dist/frontend/lowering/lowerer.test.js +172 -0
  505. package/dist/frontend/lowering/lowerer.test.js.map +1 -0
  506. package/dist/frontend/lowering/native-ffi.d.ts +5 -0
  507. package/dist/frontend/lowering/native-ffi.js +40 -0
  508. package/dist/frontend/lowering/native-ffi.js.map +1 -0
  509. package/dist/frontend/lowering/object-enumeration-receiver.d.ts +7 -0
  510. package/dist/frontend/lowering/object-enumeration-receiver.js +33 -0
  511. package/dist/frontend/lowering/object-enumeration-receiver.js.map +1 -0
  512. package/dist/frontend/lowering/object-factory-new.d.ts +8 -0
  513. package/dist/frontend/lowering/object-factory-new.js +68 -0
  514. package/dist/frontend/lowering/object-factory-new.js.map +1 -0
  515. package/dist/frontend/lowering/optional-arguments.js +6 -1
  516. package/dist/frontend/lowering/optional-arguments.js.map +1 -1
  517. package/dist/frontend/lowering/pairs-snapshot.js +2 -1
  518. package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
  519. package/dist/frontend/lowering/runtime-optional-locals.d.ts +14 -0
  520. package/dist/frontend/lowering/runtime-optional-locals.js +41 -0
  521. package/dist/frontend/lowering/runtime-optional-locals.js.map +1 -0
  522. package/dist/frontend/lowering/runtime-optional-locals.test.d.ts +1 -0
  523. package/dist/frontend/lowering/runtime-optional-locals.test.js +85 -0
  524. package/dist/frontend/lowering/runtime-optional-locals.test.js.map +1 -0
  525. package/dist/frontend/lowering/sanitize-class-types.d.ts +8 -0
  526. package/dist/frontend/lowering/sanitize-class-types.js +79 -0
  527. package/dist/frontend/lowering/sanitize-class-types.js.map +1 -0
  528. package/dist/frontend/lowering/sanitize-class-types.test.d.ts +1 -0
  529. package/dist/frontend/lowering/sanitize-class-types.test.js +60 -0
  530. package/dist/frontend/lowering/sanitize-class-types.test.js.map +1 -0
  531. package/dist/frontend/lowering/static-this.d.ts +5 -1
  532. package/dist/frontend/lowering/static-this.js +28 -2
  533. package/dist/frontend/lowering/static-this.js.map +1 -1
  534. package/dist/frontend/lowering/string-index.d.ts +7 -0
  535. package/dist/frontend/lowering/string-index.js +39 -0
  536. package/dist/frontend/lowering/string-index.js.map +1 -0
  537. package/dist/frontend/lowering/surfaces.d.ts +10 -3
  538. package/dist/frontend/lowering/surfaces.js +86 -37
  539. package/dist/frontend/lowering/surfaces.js.map +1 -1
  540. package/dist/frontend/lowering/symbol-fields.d.ts +22 -0
  541. package/dist/frontend/lowering/symbol-fields.js +183 -0
  542. package/dist/frontend/lowering/symbol-fields.js.map +1 -0
  543. package/dist/frontend/lowering/symbol-methods.d.ts +7 -0
  544. package/dist/frontend/lowering/symbol-methods.js +30 -0
  545. package/dist/frontend/lowering/symbol-methods.js.map +1 -0
  546. package/dist/frontend/lowering/text-decoder-encoding.d.ts +12 -0
  547. package/dist/frontend/lowering/text-decoder-encoding.js +82 -0
  548. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -0
  549. package/dist/frontend/lowering/text-decoder-encoding.test.d.ts +1 -0
  550. package/dist/frontend/lowering/text-decoder-encoding.test.js +38 -0
  551. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -0
  552. package/dist/frontend/lowering/union-narrow.d.ts +9 -0
  553. package/dist/frontend/lowering/union-narrow.js +59 -0
  554. package/dist/frontend/lowering/union-narrow.js.map +1 -0
  555. package/dist/frontend/lowering/union-narrow.test.d.ts +1 -0
  556. package/dist/frontend/lowering/union-narrow.test.js +72 -0
  557. package/dist/frontend/lowering/union-narrow.test.js.map +1 -0
  558. package/dist/frontend/lowering/union-retag.d.ts +43 -0
  559. package/dist/frontend/lowering/union-retag.js +259 -0
  560. package/dist/frontend/lowering/union-retag.js.map +1 -0
  561. package/dist/frontend/lowering/union-retag.test.d.ts +1 -0
  562. package/dist/frontend/lowering/union-retag.test.js +405 -0
  563. package/dist/frontend/lowering/union-retag.test.js.map +1 -0
  564. package/dist/frontend/lowering/unregistered-class-types.d.ts +14 -0
  565. package/dist/frontend/lowering/unregistered-class-types.js +94 -0
  566. package/dist/frontend/lowering/unregistered-class-types.js.map +1 -0
  567. package/dist/frontend/lowering/unregistered-class-types.test.d.ts +1 -0
  568. package/dist/frontend/lowering/unregistered-class-types.test.js +65 -0
  569. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -0
  570. package/dist/frontend/lowering/width-lift.d.ts +40 -0
  571. package/dist/frontend/lowering/width-lift.js +2 -0
  572. package/dist/frontend/lowering/width-lift.js.map +1 -0
  573. package/dist/frontend/module-syntax.d.ts +58 -0
  574. package/dist/frontend/module-syntax.js +123 -0
  575. package/dist/frontend/module-syntax.js.map +1 -0
  576. package/dist/frontend/module-syntax.test.d.ts +1 -0
  577. package/dist/frontend/module-syntax.test.js +78 -0
  578. package/dist/frontend/module-syntax.test.js.map +1 -0
  579. package/dist/frontend/npm-fetch-analysis.d.ts +17 -0
  580. package/dist/frontend/npm-fetch-analysis.js +100 -0
  581. package/dist/frontend/npm-fetch-analysis.js.map +1 -0
  582. package/dist/frontend/npm-fetch-analysis.test.d.ts +1 -0
  583. package/dist/frontend/npm-fetch-analysis.test.js +107 -0
  584. package/dist/frontend/npm-fetch-analysis.test.js.map +1 -0
  585. package/dist/frontend/npm-fetch-node.d.ts +2 -0
  586. package/dist/frontend/npm-fetch-node.js +12 -0
  587. package/dist/frontend/npm-fetch-node.js.map +1 -0
  588. package/dist/frontend/npm-fetch-syntax.d.ts +6 -0
  589. package/dist/frontend/npm-fetch-syntax.js +207 -0
  590. package/dist/frontend/npm-fetch-syntax.js.map +1 -0
  591. package/dist/frontend/npm-node.d.ts +10 -0
  592. package/dist/frontend/npm-node.js +14 -0
  593. package/dist/frontend/npm-node.js.map +1 -0
  594. package/dist/frontend/npm-static-bundled-cjs.d.ts +8 -0
  595. package/dist/frontend/npm-static-bundled-cjs.js +236 -0
  596. package/dist/frontend/npm-static-bundled-cjs.js.map +1 -0
  597. package/dist/frontend/npm-static-bundled-cjs.test.d.ts +1 -0
  598. package/dist/frontend/npm-static-bundled-cjs.test.js +69 -0
  599. package/dist/frontend/npm-static-bundled-cjs.test.js.map +1 -0
  600. package/dist/frontend/npm-static-declaration-syntax.d.ts +57 -0
  601. package/dist/frontend/npm-static-declaration-syntax.js +944 -0
  602. package/dist/frontend/npm-static-declaration-syntax.js.map +1 -0
  603. package/dist/frontend/npm-static-declarations.d.ts +11 -39
  604. package/dist/frontend/npm-static-declarations.js +22 -561
  605. package/dist/frontend/npm-static-declarations.js.map +1 -1
  606. package/dist/frontend/npm-static-declarations.test.js +245 -6
  607. package/dist/frontend/npm-static-declarations.test.js.map +1 -1
  608. package/dist/frontend/npm-static-prune.d.ts +1 -1
  609. package/dist/frontend/npm-static-prune.js +121 -38
  610. package/dist/frontend/npm-static-prune.js.map +1 -1
  611. package/dist/frontend/npm-static-prune.test.js +9 -1
  612. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  613. package/dist/frontend/npm-static-rewrite-host.d.ts +4 -0
  614. package/dist/frontend/npm-static-rewrite-host.js +179 -0
  615. package/dist/frontend/npm-static-rewrite-host.js.map +1 -0
  616. package/dist/frontend/npm-static-rewrite-syntax.d.ts +16 -0
  617. package/dist/frontend/npm-static-rewrite-syntax.js +905 -0
  618. package/dist/frontend/npm-static-rewrite-syntax.js.map +1 -0
  619. package/dist/frontend/npm-static-rewrite.d.ts +0 -5
  620. package/dist/frontend/npm-static-rewrite.js +2 -1079
  621. package/dist/frontend/npm-static-rewrite.js.map +1 -1
  622. package/dist/frontend/npm-static-subtyping.d.ts +5 -0
  623. package/dist/frontend/npm-static-subtyping.js +55 -0
  624. package/dist/frontend/npm-static-subtyping.js.map +1 -0
  625. package/dist/frontend/npm-static-subtyping.test.d.ts +1 -0
  626. package/dist/frontend/npm-static-subtyping.test.js +58 -0
  627. package/dist/frontend/npm-static-subtyping.test.js.map +1 -0
  628. package/dist/frontend/npm-static.d.ts +7 -15
  629. package/dist/frontend/npm-static.js +19 -28
  630. package/dist/frontend/npm-static.js.map +1 -1
  631. package/dist/frontend/npm.d.ts +8 -69
  632. package/dist/frontend/npm.js +21 -361
  633. package/dist/frontend/npm.js.map +1 -1
  634. package/dist/frontend/npm.test.js +2 -2
  635. package/dist/frontend/npm.test.js.map +1 -1
  636. package/dist/frontend/pipeline-native.d.ts +6 -0
  637. package/dist/frontend/pipeline-native.js +32 -0
  638. package/dist/frontend/pipeline-native.js.map +1 -0
  639. package/dist/frontend/pipeline.d.ts +54 -0
  640. package/dist/frontend/pipeline.js +382 -0
  641. package/dist/frontend/pipeline.js.map +1 -0
  642. package/dist/frontend/pipeline.test.d.ts +1 -0
  643. package/dist/frontend/pipeline.test.js +77 -0
  644. package/dist/frontend/pipeline.test.js.map +1 -0
  645. package/dist/frontend/program-analysis.d.ts +10 -0
  646. package/dist/frontend/program-analysis.js +14 -0
  647. package/dist/frontend/program-analysis.js.map +1 -0
  648. package/dist/frontend/program-node.d.ts +9 -0
  649. package/dist/frontend/program-node.js +48 -0
  650. package/dist/frontend/program-node.js.map +1 -0
  651. package/dist/frontend/program.d.ts +39 -20
  652. package/dist/frontend/program.js +393 -189
  653. package/dist/frontend/program.js.map +1 -1
  654. package/dist/frontend/program.test.js +105 -2
  655. package/dist/frontend/program.test.js.map +1 -1
  656. package/dist/frontend/provenance-core.d.ts +9 -0
  657. package/dist/frontend/provenance-core.js +435 -0
  658. package/dist/frontend/provenance-core.js.map +1 -0
  659. package/dist/frontend/provenance.d.ts +0 -4
  660. package/dist/frontend/provenance.js +4 -459
  661. package/dist/frontend/provenance.js.map +1 -1
  662. package/dist/frontend/resolve.d.ts +3 -1
  663. package/dist/frontend/resolve.js +6 -3
  664. package/dist/frontend/resolve.js.map +1 -1
  665. package/dist/frontend/runtime-resolve.d.ts +4 -3
  666. package/dist/frontend/runtime-resolve.js +22 -18
  667. package/dist/frontend/runtime-resolve.js.map +1 -1
  668. package/dist/frontend/runtime-resolve.test.js +53 -0
  669. package/dist/frontend/runtime-resolve.test.js.map +1 -1
  670. package/dist/frontend/services-node.d.ts +5 -0
  671. package/dist/frontend/services-node.js +19 -0
  672. package/dist/frontend/services-node.js.map +1 -0
  673. package/dist/frontend/services-node.test.d.ts +1 -0
  674. package/dist/frontend/services-node.test.js +70 -0
  675. package/dist/frontend/services-node.test.js.map +1 -0
  676. package/dist/frontend/services.d.ts +44 -0
  677. package/dist/frontend/services.js +90 -0
  678. package/dist/frontend/services.js.map +1 -0
  679. package/dist/frontend/services.test.d.ts +1 -0
  680. package/dist/frontend/services.test.js +174 -0
  681. package/dist/frontend/services.test.js.map +1 -0
  682. package/dist/frontend/ts7/adapter.d.ts +3 -3
  683. package/dist/frontend/ts7/adapter.js +14 -31
  684. package/dist/frontend/ts7/adapter.js.map +1 -1
  685. package/dist/frontend/ts7/api.d.ts +16 -0
  686. package/dist/frontend/ts7/api.js +24 -0
  687. package/dist/frontend/ts7/api.js.map +1 -0
  688. package/dist/frontend/ts7/ast-bytes.d.ts +31 -0
  689. package/dist/frontend/ts7/ast-bytes.js +137 -0
  690. package/dist/frontend/ts7/ast-bytes.js.map +1 -0
  691. package/dist/frontend/ts7/ast-bytes.test.d.ts +1 -0
  692. package/dist/frontend/ts7/ast-bytes.test.js +73 -0
  693. package/dist/frontend/ts7/ast-bytes.test.js.map +1 -0
  694. package/dist/frontend/ts7/ast-guards.generated.d.ts +353 -0
  695. package/dist/frontend/ts7/ast-guards.generated.js +1951 -0
  696. package/dist/frontend/ts7/ast-guards.generated.js.map +1 -0
  697. package/dist/frontend/ts7/ast-guards.test.d.ts +1 -0
  698. package/dist/frontend/ts7/ast-guards.test.js +43 -0
  699. package/dist/frontend/ts7/ast-guards.test.js.map +1 -0
  700. package/dist/frontend/ts7/ast-node.d.ts +194 -0
  701. package/dist/frontend/ts7/ast-node.js +448 -0
  702. package/dist/frontend/ts7/ast-node.js.map +1 -0
  703. package/dist/frontend/ts7/ast-node.test.d.ts +1 -0
  704. package/dist/frontend/ts7/ast-node.test.js +266 -0
  705. package/dist/frontend/ts7/ast-node.test.js.map +1 -0
  706. package/dist/frontend/ts7/ast-schema.generated.d.ts +503 -0
  707. package/dist/frontend/ts7/ast-schema.generated.js +1446 -0
  708. package/dist/frontend/ts7/ast-schema.generated.js.map +1 -0
  709. package/dist/frontend/ts7/ast-text.d.ts +6 -0
  710. package/dist/frontend/ts7/ast-text.js +124 -0
  711. package/dist/frontend/ts7/ast-text.js.map +1 -0
  712. package/dist/frontend/ts7/ast-text.test.d.ts +1 -0
  713. package/dist/frontend/ts7/ast-text.test.js +38 -0
  714. package/dist/frontend/ts7/ast-text.test.js.map +1 -0
  715. package/dist/frontend/ts7/ast-tokens.generated.d.ts +2 -0
  716. package/dist/frontend/ts7/ast-tokens.generated.js +155 -0
  717. package/dist/frontend/ts7/ast-tokens.generated.js.map +1 -0
  718. package/dist/frontend/ts7/ast-types.d.ts +42 -0
  719. package/dist/frontend/ts7/ast-types.generated.d.ts +1615 -0
  720. package/dist/frontend/ts7/ast-types.generated.js +5 -0
  721. package/dist/frontend/ts7/ast-types.generated.js.map +1 -0
  722. package/dist/frontend/ts7/ast-types.js +3 -0
  723. package/dist/frontend/ts7/ast-types.js.map +1 -0
  724. package/dist/frontend/ts7/ast-wire.d.ts +58 -0
  725. package/dist/frontend/ts7/ast-wire.js +267 -0
  726. package/dist/frontend/ts7/ast-wire.js.map +1 -0
  727. package/dist/frontend/ts7/ast-wire.test.d.ts +1 -0
  728. package/dist/frontend/ts7/ast-wire.test.js +151 -0
  729. package/dist/frontend/ts7/ast-wire.test.js.map +1 -0
  730. package/dist/frontend/ts7/ast.d.ts +14 -14
  731. package/dist/frontend/ts7/ast.js +25 -18
  732. package/dist/frontend/ts7/ast.js.map +1 -1
  733. package/dist/frontend/ts7/census-check.js +1 -0
  734. package/dist/frontend/ts7/census-check.js.map +1 -1
  735. package/dist/frontend/ts7/checker-cache.d.ts +48 -0
  736. package/dist/frontend/ts7/checker-cache.js +92 -0
  737. package/dist/frontend/ts7/checker-cache.js.map +1 -0
  738. package/dist/frontend/ts7/checker.d.ts +19 -46
  739. package/dist/frontend/ts7/checker.js +231 -161
  740. package/dist/frontend/ts7/checker.js.map +1 -1
  741. package/dist/frontend/ts7/checker.test.d.ts +1 -0
  742. package/dist/frontend/ts7/checker.test.js +335 -0
  743. package/dist/frontend/ts7/checker.test.js.map +1 -0
  744. package/dist/frontend/ts7/enums.d.ts +4 -27
  745. package/dist/frontend/ts7/enums.generated.d.ts +878 -0
  746. package/dist/frontend/ts7/enums.generated.js +1313 -0
  747. package/dist/frontend/ts7/enums.generated.js.map +1 -0
  748. package/dist/frontend/ts7/enums.js +4 -45
  749. package/dist/frontend/ts7/enums.js.map +1 -1
  750. package/dist/frontend/ts7/enums.test.d.ts +1 -0
  751. package/dist/frontend/ts7/enums.test.js +48 -0
  752. package/dist/frontend/ts7/enums.test.js.map +1 -0
  753. package/dist/frontend/ts7/native-api.d.ts +10 -0
  754. package/dist/frontend/ts7/native-api.js +10 -0
  755. package/dist/frontend/ts7/native-api.js.map +1 -0
  756. package/dist/frontend/ts7/native-host.d.ts +2 -0
  757. package/dist/frontend/ts7/native-host.js +11 -0
  758. package/dist/frontend/ts7/native-host.js.map +1 -0
  759. package/dist/frontend/ts7/native-process.d.ts +14 -0
  760. package/dist/frontend/ts7/native-process.js +62 -0
  761. package/dist/frontend/ts7/native-process.js.map +1 -0
  762. package/dist/frontend/ts7/program-adapter.d.ts +10 -98
  763. package/dist/frontend/ts7/program-adapter.js +16 -310
  764. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  765. package/dist/frontend/ts7/program-host.d.ts +115 -0
  766. package/dist/frontend/ts7/program-host.js +347 -0
  767. package/dist/frontend/ts7/program-host.js.map +1 -0
  768. package/dist/frontend/ts7/program-host.test.d.ts +1 -0
  769. package/dist/frontend/ts7/program-host.test.js +207 -0
  770. package/dist/frontend/ts7/program-host.test.js.map +1 -0
  771. package/dist/frontend/ts7/rpc-api.d.ts +12 -0
  772. package/dist/frontend/ts7/rpc-api.js +23 -0
  773. package/dist/frontend/ts7/rpc-api.js.map +1 -0
  774. package/dist/frontend/ts7/rpc-client.d.ts +27 -0
  775. package/dist/frontend/ts7/rpc-client.js +102 -0
  776. package/dist/frontend/ts7/rpc-client.js.map +1 -0
  777. package/dist/frontend/ts7/rpc-client.test.d.ts +1 -0
  778. package/dist/frontend/ts7/rpc-client.test.js +133 -0
  779. package/dist/frontend/ts7/rpc-client.test.js.map +1 -0
  780. package/dist/frontend/ts7/rpc-filesystem.d.ts +16 -0
  781. package/dist/frontend/ts7/rpc-filesystem.js +42 -0
  782. package/dist/frontend/ts7/rpc-filesystem.js.map +1 -0
  783. package/dist/frontend/ts7/rpc-filesystem.test.d.ts +1 -0
  784. package/dist/frontend/ts7/rpc-filesystem.test.js +89 -0
  785. package/dist/frontend/ts7/rpc-filesystem.test.js.map +1 -0
  786. package/dist/frontend/ts7/rpc-process.d.ts +2 -0
  787. package/dist/frontend/ts7/rpc-process.js +148 -0
  788. package/dist/frontend/ts7/rpc-process.js.map +1 -0
  789. package/dist/frontend/ts7/rpc-process.test.d.ts +1 -0
  790. package/dist/frontend/ts7/rpc-process.test.js +29 -0
  791. package/dist/frontend/ts7/rpc-process.test.js.map +1 -0
  792. package/dist/frontend/ts7/rpc-wire.d.ts +46 -0
  793. package/dist/frontend/ts7/rpc-wire.js +195 -0
  794. package/dist/frontend/ts7/rpc-wire.js.map +1 -0
  795. package/dist/frontend/ts7/rpc-wire.test.d.ts +1 -0
  796. package/dist/frontend/ts7/rpc-wire.test.js +168 -0
  797. package/dist/frontend/ts7/rpc-wire.test.js.map +1 -0
  798. package/dist/frontend/ts7/semantic-checker.d.ts +137 -0
  799. package/dist/frontend/ts7/semantic-checker.js +221 -0
  800. package/dist/frontend/ts7/semantic-checker.js.map +1 -0
  801. package/dist/frontend/ts7/semantic-checker.test.d.ts +1 -0
  802. package/dist/frontend/ts7/semantic-checker.test.js +119 -0
  803. package/dist/frontend/ts7/semantic-checker.test.js.map +1 -0
  804. package/dist/frontend/ts7/semantic-json.d.ts +5 -0
  805. package/dist/frontend/ts7/semantic-json.js +47 -0
  806. package/dist/frontend/ts7/semantic-json.js.map +1 -0
  807. package/dist/frontend/ts7/semantic-json.test.d.ts +1 -0
  808. package/dist/frontend/ts7/semantic-json.test.js +42 -0
  809. package/dist/frontend/ts7/semantic-json.test.js.map +1 -0
  810. package/dist/frontend/ts7/semantic-model.d.ts +222 -0
  811. package/dist/frontend/ts7/semantic-model.js +423 -0
  812. package/dist/frontend/ts7/semantic-model.js.map +1 -0
  813. package/dist/frontend/ts7/semantic-model.test.d.ts +1 -0
  814. package/dist/frontend/ts7/semantic-model.test.js +322 -0
  815. package/dist/frontend/ts7/semantic-model.test.js.map +1 -0
  816. package/dist/frontend/ts7/semantic-schema.generated.d.ts +283 -0
  817. package/dist/frontend/ts7/semantic-schema.generated.js +222 -0
  818. package/dist/frontend/ts7/semantic-schema.generated.js.map +1 -0
  819. package/dist/frontend/ts7/semantic-types.d.ts +5 -0
  820. package/dist/frontend/ts7/semantic-types.js +2 -0
  821. package/dist/frontend/ts7/semantic-types.js.map +1 -0
  822. package/dist/frontend/ts7/session-cache.d.ts +17 -0
  823. package/dist/frontend/ts7/session-cache.js +97 -0
  824. package/dist/frontend/ts7/session-cache.js.map +1 -0
  825. package/dist/frontend/ts7/session-cache.test.d.ts +1 -0
  826. package/dist/frontend/ts7/session-cache.test.js +87 -0
  827. package/dist/frontend/ts7/session-cache.test.js.map +1 -0
  828. package/dist/frontend/ts7/session-path.d.ts +18 -0
  829. package/dist/frontend/ts7/session-path.js +203 -0
  830. package/dist/frontend/ts7/session-path.js.map +1 -0
  831. package/dist/frontend/ts7/session-path.test.d.ts +1 -0
  832. package/dist/frontend/ts7/session-path.test.js +34 -0
  833. package/dist/frontend/ts7/session-path.test.js.map +1 -0
  834. package/dist/frontend/ts7/session-schema.generated.d.ts +167 -0
  835. package/dist/frontend/ts7/session-schema.generated.js +5 -0
  836. package/dist/frontend/ts7/session-schema.generated.js.map +1 -0
  837. package/dist/frontend/ts7/session-timing.d.ts +50 -0
  838. package/dist/frontend/ts7/session-timing.js +61 -0
  839. package/dist/frontend/ts7/session-timing.js.map +1 -0
  840. package/dist/frontend/ts7/session-timing.test.d.ts +1 -0
  841. package/dist/frontend/ts7/session-timing.test.js +52 -0
  842. package/dist/frontend/ts7/session-timing.test.js.map +1 -0
  843. package/dist/frontend/ts7/session.d.ts +105 -0
  844. package/dist/frontend/ts7/session.js +233 -0
  845. package/dist/frontend/ts7/session.js.map +1 -0
  846. package/dist/frontend/ts7/session.test.d.ts +1 -0
  847. package/dist/frontend/ts7/session.test.js +215 -0
  848. package/dist/frontend/ts7/session.test.js.map +1 -0
  849. package/dist/frontend/ts7/source-parser-node.d.ts +6 -0
  850. package/dist/frontend/ts7/source-parser-node.js +15 -0
  851. package/dist/frontend/ts7/source-parser-node.js.map +1 -0
  852. package/dist/frontend/ts7/source-parser.d.ts +25 -0
  853. package/dist/frontend/ts7/source-parser.js +96 -0
  854. package/dist/frontend/ts7/source-parser.js.map +1 -0
  855. package/dist/frontend/ts7/source-parser.test.d.ts +1 -0
  856. package/dist/frontend/ts7/source-parser.test.js +151 -0
  857. package/dist/frontend/ts7/source-parser.test.js.map +1 -0
  858. package/dist/frontend/ts7/syntax.d.ts +3 -0
  859. package/dist/frontend/ts7/syntax.js +4 -0
  860. package/dist/frontend/ts7/syntax.js.map +1 -0
  861. package/dist/frontend/tsc-codes.js +3 -0
  862. package/dist/frontend/tsc-codes.js.map +1 -1
  863. package/dist/frontend/type-mapper.d.ts +34 -18
  864. package/dist/frontend/type-mapper.js +552 -131
  865. package/dist/frontend/type-mapper.js.map +1 -1
  866. package/dist/frontend/type-mapper.test.js +146 -2
  867. package/dist/frontend/type-mapper.test.js.map +1 -1
  868. package/dist/frontend/union-discriminants.d.ts +16 -0
  869. package/dist/frontend/union-discriminants.js +98 -0
  870. package/dist/frontend/union-discriminants.js.map +1 -0
  871. package/dist/frontend/union-discriminants.test.d.ts +1 -0
  872. package/dist/frontend/union-discriminants.test.js +182 -0
  873. package/dist/frontend/union-discriminants.test.js.map +1 -0
  874. package/dist/index.d.ts +7 -198
  875. package/dist/index.js +369 -1572
  876. package/dist/index.js.map +1 -1
  877. package/dist/ir/analysis.d.ts +16 -4
  878. package/dist/ir/analysis.js +23 -4
  879. package/dist/ir/analysis.js.map +1 -1
  880. package/dist/ir/analysis.test.js +15 -2
  881. package/dist/ir/analysis.test.js.map +1 -1
  882. package/dist/ir/constant-tables.js +67 -49
  883. package/dist/ir/constant-tables.js.map +1 -1
  884. package/dist/ir/constant-tables.test.js +1 -1
  885. package/dist/ir/control-flow.d.ts +6 -0
  886. package/dist/ir/control-flow.js +142 -0
  887. package/dist/ir/control-flow.js.map +1 -0
  888. package/dist/ir/control-flow.test.d.ts +1 -0
  889. package/dist/ir/control-flow.test.js +113 -0
  890. package/dist/ir/control-flow.test.js.map +1 -0
  891. package/dist/ir/integer-loops.js +7 -18
  892. package/dist/ir/integer-loops.js.map +1 -1
  893. package/dist/ir/integer-ranges.js +53 -27
  894. package/dist/ir/integer-ranges.js.map +1 -1
  895. package/dist/ir/ir.d.ts +334 -176
  896. package/dist/ir/ir.js +710 -903
  897. package/dist/ir/ir.js.map +1 -1
  898. package/dist/ir/ir.test.js +162 -1
  899. package/dist/ir/ir.test.js.map +1 -1
  900. package/dist/ir/scalar-records.js +165 -134
  901. package/dist/ir/scalar-records.js.map +1 -1
  902. package/dist/ir/scalar-records.test.js +1 -1
  903. package/dist/ir/serialize.d.ts +4 -2
  904. package/dist/ir/serialize.js +33 -14
  905. package/dist/ir/serialize.js.map +1 -1
  906. package/dist/ir/serialize.test.d.ts +1 -0
  907. package/dist/ir/serialize.test.js +57 -0
  908. package/dist/ir/serialize.test.js.map +1 -0
  909. package/dist/ir/traverse.d.ts +41 -0
  910. package/dist/ir/traverse.js +660 -0
  911. package/dist/ir/traverse.js.map +1 -0
  912. package/dist/ir/traverse.test.d.ts +1 -0
  913. package/dist/ir/traverse.test.js +242 -0
  914. package/dist/ir/traverse.test.js.map +1 -0
  915. package/dist/ir/validate.js +2018 -1498
  916. package/dist/ir/validate.js.map +1 -1
  917. package/dist/ir/validate.test.js +536 -2
  918. package/dist/ir/validate.test.js.map +1 -1
  919. package/dist/library/cache-primitives.d.ts +2 -3
  920. package/dist/library/cache-primitives.js +4 -6
  921. package/dist/library/cache-primitives.js.map +1 -1
  922. package/dist/library/fence-eval.js +2 -2
  923. package/dist/library/fence-eval.js.map +1 -1
  924. package/dist/library/int-infer.js +7 -6
  925. package/dist/library/int-infer.js.map +1 -1
  926. package/dist/library/int-infer.test.js +4 -4
  927. package/dist/library/library-cache.d.ts +3 -2
  928. package/dist/library/library-cache.js +5 -17
  929. package/dist/library/library-cache.js.map +1 -1
  930. package/dist/library/library-cache.test.js +54 -41
  931. package/dist/library/library-cache.test.js.map +1 -1
  932. package/dist/library/library-profile.d.ts +3 -1
  933. package/dist/library/library-profile.js +15 -6
  934. package/dist/library/library-profile.js.map +1 -1
  935. package/dist/library/prepare.d.ts +15 -0
  936. package/dist/library/prepare.js +584 -0
  937. package/dist/library/prepare.js.map +1 -0
  938. package/dist/library/semantic-source.d.ts +1 -1
  939. package/dist/library/semantic-source.js +8 -6
  940. package/dist/library/semantic-source.js.map +1 -1
  941. package/dist/library/sidecar-validate.js +4 -4
  942. package/dist/library/sidecar-validate.js.map +1 -1
  943. package/dist/library/sidecar.d.ts +2 -0
  944. package/dist/library/sidecar.js +10 -3
  945. package/dist/library/sidecar.js.map +1 -1
  946. package/dist/native/cache.d.ts +11 -0
  947. package/dist/native/cache.js +113 -0
  948. package/dist/native/cache.js.map +1 -0
  949. package/dist/native/cache.test.d.ts +1 -0
  950. package/dist/native/cache.test.js +66 -0
  951. package/dist/native/cache.test.js.map +1 -0
  952. package/dist/native/cli.d.ts +1 -0
  953. package/dist/native/cli.js +112 -0
  954. package/dist/native/cli.js.map +1 -0
  955. package/dist/native/compiler.d.ts +15 -0
  956. package/dist/native/compiler.js +336 -0
  957. package/dist/native/compiler.js.map +1 -0
  958. package/dist/native/compiler.test.d.ts +1 -0
  959. package/dist/native/compiler.test.js +174 -0
  960. package/dist/native/compiler.test.js.map +1 -0
  961. package/dist/native/comptime.d.ts +5 -0
  962. package/dist/native/comptime.js +73 -0
  963. package/dist/native/comptime.js.map +1 -0
  964. package/dist/native/comptime.test.d.ts +1 -0
  965. package/dist/native/comptime.test.js +65 -0
  966. package/dist/native/comptime.test.js.map +1 -0
  967. package/dist/native/executable-cache.d.ts +26 -0
  968. package/dist/native/executable-cache.js +228 -0
  969. package/dist/native/executable-cache.js.map +1 -0
  970. package/dist/native/executable-cache.test.d.ts +1 -0
  971. package/dist/native/executable-cache.test.js +151 -0
  972. package/dist/native/executable-cache.test.js.map +1 -0
  973. package/dist/native/file-identity.d.ts +4 -0
  974. package/dist/native/file-identity.js +14 -0
  975. package/dist/native/file-identity.js.map +1 -0
  976. package/dist/native/file-identity.test.d.ts +1 -0
  977. package/dist/native/file-identity.test.js +43 -0
  978. package/dist/native/file-identity.test.js.map +1 -0
  979. package/dist/native/library.d.ts +22 -0
  980. package/dist/native/library.js +83 -0
  981. package/dist/native/library.js.map +1 -0
  982. package/dist/native/prepare.d.ts +21 -0
  983. package/dist/native/prepare.js +174 -0
  984. package/dist/native/prepare.js.map +1 -0
  985. package/dist/native/prepare.test.d.ts +1 -0
  986. package/dist/native/prepare.test.js +70 -0
  987. package/dist/native/prepare.test.js.map +1 -0
  988. package/dist/native/sanitizer.d.ts +11 -0
  989. package/dist/native/sanitizer.js +137 -0
  990. package/dist/native/sanitizer.js.map +1 -0
  991. package/dist/native/sanitizer.test.d.ts +1 -0
  992. package/dist/native/sanitizer.test.js +58 -0
  993. package/dist/native/sanitizer.test.js.map +1 -0
  994. package/dist/native/task.d.ts +4 -0
  995. package/dist/native/task.js +16 -0
  996. package/dist/native/task.js.map +1 -0
  997. package/dist/native/task.test.d.ts +1 -0
  998. package/dist/native/task.test.js +17 -0
  999. package/dist/native/task.test.js.map +1 -0
  1000. package/dist/native/toolchain.d.ts +45 -0
  1001. package/dist/native/toolchain.js +94 -0
  1002. package/dist/native/toolchain.js.map +1 -0
  1003. package/dist/native/toolchain.test.d.ts +1 -0
  1004. package/dist/native/toolchain.test.js +85 -0
  1005. package/dist/native/toolchain.test.js.map +1 -0
  1006. package/dist/startup-cache.d.ts +1 -1
  1007. package/dist/startup-cache.js +2 -5
  1008. package/dist/startup-cache.js.map +1 -1
  1009. package/dist/timing.d.ts +4 -0
  1010. package/dist/timing.js +19 -0
  1011. package/dist/timing.js.map +1 -0
  1012. package/dist/wasi-paths.js +10 -7
  1013. package/dist/wasi-paths.js.map +1 -1
  1014. package/package.json +28 -19
  1015. package/surface-manifest.json +107 -98
  1016. package/dist/backend/c/async.d.ts +0 -171
  1017. package/dist/backend/c/async.js +0 -1317
  1018. package/dist/backend/c/async.js.map +0 -1
  1019. package/dist/backend/c/c-emitter.d.ts +0 -536
  1020. package/dist/backend/c/c-emitter.js +0 -1932
  1021. package/dist/backend/c/c-emitter.js.map +0 -1
  1022. package/dist/backend/c/exprs.d.ts +0 -15
  1023. package/dist/backend/c/exprs.js +0 -8847
  1024. package/dist/backend/c/exprs.js.map +0 -1
  1025. package/dist/backend/c/island.d.ts +0 -45
  1026. package/dist/backend/c/island.js +0 -281
  1027. package/dist/backend/c/island.js.map +0 -1
  1028. package/dist/backend/c/may-throw.js.map +0 -1
  1029. package/dist/backend/c/shapes.d.ts +0 -142
  1030. package/dist/backend/c/shapes.js +0 -603
  1031. package/dist/backend/c/shapes.js.map +0 -1
  1032. package/dist/backend/c/stmts.d.ts +0 -76
  1033. package/dist/backend/c/stmts.js +0 -1108
  1034. package/dist/backend/c/stmts.js.map +0 -1
  1035. package/dist/backend/c/types.d.ts +0 -71
  1036. package/dist/backend/c/types.js +0 -459
  1037. package/dist/backend/c/types.js.map +0 -1
  1038. package/dist/backend/c/types.test.js +0 -32
  1039. package/dist/backend/c/types.test.js.map +0 -1
  1040. package/dist/backend/c/walkers.d.ts +0 -134
  1041. package/dist/backend/c/walkers.js +0 -1772
  1042. package/dist/backend/c/walkers.js.map +0 -1
  1043. /package/dist/backend/{c/types.test.d.ts → cycle-analysis.test.d.ts} +0 -0
@@ -1,1772 +0,0 @@
1
- import { InternalCompilerError } from "../../errors.js";
2
- import { DYN_HANDLE_KINDS, isDynTypedRefType, isRefCounted, typeEquals, typeKey } from "../../ir/ir.js";
3
- import { dynDesc, undefinedArmTag } from "../../ir/analysis.js";
4
- import { cCommentText, cDecl, cStringLiteral, cType, elemAccess, releaseCallC, retainCallC, vAdapters } from "./types.js";
5
- import { mangleField, mangleRecordNew, mangleRecordStruct } from "../mangle.js";
6
- import { jsonObjectKeyLabel } from "../json-literal.js";
7
- import { OVERFLOW_MEMBER } from "./shapes.js";
8
- /** The per-union ToBoolean helper (interned per unionId): switch on the
9
- * runtime tag — unit arms false, f64 arms 0/NaN-falsy, string arms
10
- * empty-falsy, bool arms by payload, ref arms always true (JS objects),
11
- * jsval arms answered by the engine. Borrows the operand. */
12
- export function unionTruthyHelper(emitter, unionId) {
13
- const existing = emitter.unionTruthyFns.get(unionId);
14
- if (existing)
15
- return existing;
16
- const def = emitter.unionsById.get(unionId);
17
- if (!def)
18
- throw new InternalCompilerError(`emitter bug: truthiness of unknown union ${unionId}`);
19
- const name = `sc_ut_${emitter.unionTruthyFns.size}`;
20
- emitter.unionTruthyFns.set(unionId, name);
21
- const sig = `static bool ${name}(ScrUnion *v)`;
22
- emitter.walkerProtos.push(`${sig}; /* ToBoolean ${unionId} */`);
23
- const d = [`${sig} { /* ToBoolean ${unionId} */`, ` switch (v->tag) {`];
24
- def.arms.forEach((arm, i) => {
25
- switch (arm.kind) {
26
- case "undefinedT":
27
- case "nullT":
28
- d.push(` case ${i}: return false;`);
29
- break;
30
- case "f64":
31
- d.push(` case ${i}: { double x = scr_union_get_f64(v); return x == x && x != 0; }`);
32
- break;
33
- case "bool":
34
- d.push(` case ${i}: return scr_union_get_bool(v);`);
35
- break;
36
- case "string":
37
- d.push(` case ${i}: return ((ScrStr *)scr_union_peek(v))->len != 0;`);
38
- break;
39
- case "bigint":
40
- d.push(` case ${i}: return scr_bigint_truthy((ScrBigInt *)scr_union_peek(v));`);
41
- break;
42
- case "jsval":
43
- d.push(` case ${i}: return scr_jsval_truthy((ScrJsval *)scr_union_peek(v)) != 0;`);
44
- break;
45
- default:
46
- // Arrays, maps, sets, records, objects, functions, promises,
47
- // regexes, ...: JS objects are always truthy — [] and {} included.
48
- d.push(` case ${i}: return true; /* ${arm.kind} */`);
49
- }
50
- });
51
- d.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`, ` }`, `}`, ``);
52
- emitter.walkerDefs.push(...d);
53
- return name;
54
- }
55
- /** The per-union strict-equality helper (interned per unionId, with a
56
- * separate SameValue variant per unionId when Object.is reaches it):
57
- * different tags are never equal; equal tags compare the arm values —
58
- * unit arms equal, f64 with C == (NaN !== NaN, +0 === -0) or SameValue
59
- * (NaN equals NaN, +0 differs from -0) under the sameValue flag,
60
- * strings by bytes, bools by value, ref arms by POINTER identity (JS
61
- * object equality). Borrows both operands. */
62
- export function unionEqHelper(emitter, unionId, sameValue) {
63
- const key = sameValue ? `sv:${unionId}` : unionId;
64
- const existing = emitter.unionEqFns.get(key);
65
- if (existing)
66
- return existing;
67
- const def = emitter.unionsById.get(unionId);
68
- if (!def)
69
- throw new InternalCompilerError(`emitter bug: equality of unknown union ${unionId}`);
70
- const name = `sc_ue_${emitter.unionEqFns.size}`;
71
- emitter.unionEqFns.set(key, name);
72
- const what = sameValue ? "SameValue" : "strict equality";
73
- const sig = `static bool ${name}(ScrUnion *a, ScrUnion *b)`;
74
- emitter.walkerProtos.push(`${sig}; /* ${what} ${unionId} */`);
75
- const d = [
76
- `${sig} { /* ${what} ${unionId} */`,
77
- ` if (a->tag != b->tag) return false;`,
78
- ` switch (a->tag) {`,
79
- ];
80
- def.arms.forEach((arm, i) => {
81
- switch (arm.kind) {
82
- case "undefinedT":
83
- case "nullT":
84
- d.push(` case ${i}: return true;`);
85
- break;
86
- case "f64":
87
- d.push(sameValue
88
- ? ` case ${i}: return scr_num_same_value(scr_union_get_f64(a), scr_union_get_f64(b));`
89
- : ` case ${i}: return scr_union_get_f64(a) == scr_union_get_f64(b);`);
90
- break;
91
- case "bool":
92
- d.push(` case ${i}: return scr_union_get_bool(a) == scr_union_get_bool(b);`);
93
- break;
94
- case "string":
95
- d.push(` case ${i}: return scr_str_eq((ScrStr *)scr_union_peek(a), (ScrStr *)scr_union_peek(b));`);
96
- break;
97
- case "bigint":
98
- d.push(` case ${i}: return scr_bigint_eq((ScrBigInt *)scr_union_peek(a), (ScrBigInt *)scr_union_peek(b));`);
99
- break;
100
- default:
101
- // Ref arms: pointer identity, exactly JS object equality.
102
- d.push(` case ${i}: return scr_union_peek(a) == scr_union_peek(b); /* ${arm.kind} */`);
103
- }
104
- });
105
- d.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`, ` }`, `}`, ``);
106
- emitter.walkerDefs.push(...d);
107
- return name;
108
- }
109
- /** The per-union ToString helper (interned per unionId): switch on the
110
- * runtime tag — unit arms return the interned "undefined"/"null" texts,
111
- * string arms retain the payload, f64/bool arms go through the JS-exact
112
- * formatters (String(x) semantics). Ref arms never arrive (the frontend
113
- * fences unions with object arms from string conversion — JS would print
114
- * "[object Object]"). Borrows the operand; the result is owned (+1). */
115
- export function unionToStrHelper(emitter, unionId) {
116
- const existing = emitter.unionToStrFns.get(unionId);
117
- if (existing)
118
- return existing;
119
- const def = emitter.unionsById.get(unionId);
120
- if (!def)
121
- throw new InternalCompilerError(`emitter bug: ToString of unknown union ${unionId}`);
122
- const name = `sc_us_${emitter.unionToStrFns.size}`;
123
- emitter.unionToStrFns.set(unionId, name);
124
- const sig = `static ScrStr *${name}(ScrUnion *v)`;
125
- emitter.walkerProtos.push(`${sig}; /* ToString ${unionId} */`);
126
- const d = [`${sig} { /* ToString ${unionId} */`, ` switch (v->tag) {`];
127
- def.arms.forEach((arm, i) => {
128
- switch (arm.kind) {
129
- case "undefinedT":
130
- case "nullT": {
131
- const lit = emitter.internLiteral(arm.kind === "undefinedT" ? "undefined" : "null");
132
- d.push(` case ${i}: return scr_str_retain((ScrStr *)&${lit});`);
133
- break;
134
- }
135
- case "string":
136
- d.push(` case ${i}: return scr_str_retain((ScrStr *)scr_union_peek(v));`);
137
- break;
138
- case "f64":
139
- d.push(` case ${i}: return scr_f64_to_scrstr(scr_union_get_f64(v));`);
140
- break;
141
- case "bool":
142
- d.push(` case ${i}: return scr_bool_to_scrstr(scr_union_get_bool(v));`);
143
- break;
144
- case "bigint":
145
- d.push(` case ${i}: return scr_bigint_to_string((ScrBigInt *)scr_union_peek(v), 10);`);
146
- break;
147
- case "bytes": {
148
- // Buffer.toString() IS the utf8 decode (Node's default
149
- // encoding) — the `Buffer | string` chunk idiom.
150
- const enc = emitter.internLiteral("utf8");
151
- d.push(` case ${i}: return scr_bytes_to_str((ScrBytes *)scr_union_peek(v), (ScrStr *)&${enc});`);
152
- break;
153
- }
154
- default:
155
- throw new InternalCompilerError(`emitter bug: ToString of union with a ${arm.kind} arm (frontend fences these)`);
156
- }
157
- });
158
- d.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`, ` }`, `}`, ``);
159
- emitter.walkerDefs.push(...d);
160
- return name;
161
- }
162
- /** The per-union array-join helper (interned per unionId): Array.prototype
163
- * .join over union elements — undefined/null arms print EMPTY (exactly
164
- * JS's join, which silences only the nullish elements), every other arm
165
- * goes through the per-union ToString walker (string arms verbatim,
166
- * f64/bool via the JS-exact formatters). The frontend admits only unions
167
- * of f64/string/bool/unit arms here. Borrows the array and separator;
168
- * the result is owned (+1). */
169
- export function unionJoinHelper(emitter, unionId) {
170
- const existing = emitter.unionJoinFns.get(unionId);
171
- if (existing)
172
- return existing;
173
- const def = emitter.unionsById.get(unionId);
174
- if (!def)
175
- throw new InternalCompilerError(`emitter bug: join of unknown union ${unionId}`);
176
- const name = `sc_uj_${emitter.unionJoinFns.size}`;
177
- emitter.unionJoinFns.set(unionId, name);
178
- const toStr = unionToStrHelper(emitter, unionId);
179
- const unitTags = def.arms.flatMap((a, i) => a.kind === "undefinedT" || a.kind === "nullT" ? [i] : []);
180
- const sig = `static ScrStr *${name}(ScrArr *a, ScrStr *sep)`;
181
- emitter.walkerProtos.push(`${sig}; /* join ${unionId} */`);
182
- emitter.walkerDefs.push(`${sig} { /* Array#join over ${unionId}: nullish arms print empty */`, ` ScrJsonBuf b;`, ` scr_jb_init(&b);`, ` size_t n = (size_t)scr_arr_len(a);`, ` for (size_t i = 0; i < n; i++) {`, ` if (i) for (size_t j = 0; j < sep->len; j++) scr_jb_putc(&b, sep->data[j]);`, ` /* Holes and payload-free present undefined both stringify empty. */`, ` if (scr_arr_state(a, (double)i) != SCR_ARR_VALUE) continue;`, ` ScrUnion *u = (ScrUnion *)scr_arr_get_ref(a, (double)i);`, ...(unitTags.length > 0
183
- ? [` if (${unitTags.map((t) => `u->tag == ${t}`).join(" || ")}) { scr_union_release(u); continue; }`]
184
- : []), ` ScrStr *s = ${toStr}(u);`, ` for (size_t j = 0; j < s->len; j++) scr_jb_putc(&b, s->data[j]);`, ` scr_str_release(s);`, ` scr_union_release(u);`, ` }`, ` return scr_jb_finish(&b);`, `}`, ``);
185
- return name;
186
- }
187
- /** The dyn ToString helper pair (interned once, type-independent):
188
- * Node's String() over a dyn value — "undefined"/"null" texts, bools,
189
- * JS-exact number formatting (NaN/Infinity spelled out — NOT the JSON
190
- * null), strings verbatim, arrays via Array.prototype.toString (join
191
- * with ","; null/undefined ELEMENTS print empty, nested arrays flatten
192
- * through the recursion — JS-exact), plain objects as
193
- * "[object Object]". The operand is borrowed; the result is owned (+1). */
194
- export function dynToStrHelper(emitter) {
195
- if (emitter.dynToStrFn)
196
- return emitter.dynToStrFn;
197
- const name = "sc_ds";
198
- emitter.dynToStrFn = name;
199
- emitter.walkerProtos.push(`static void ${name}_buf(ScrJsonBuf *b, const ScrDyn *d); /* String(unknown) walker */`, `static ScrStr *${name}(const ScrDyn *d); /* String(unknown) */`);
200
- emitter.walkerDefs.push(`static void ${name}_buf(ScrJsonBuf *b, const ScrDyn *d) { /* String(unknown), recursive */`, ` switch (d->kind) {`, ` case SCR_DYN_UNDEF: scr_jb_puts(b, "undefined"); break;`, ` case SCR_DYN_NULL: scr_jb_puts(b, "null"); break;`, ` case SCR_DYN_BOOL: scr_jb_puts(b, d->v.b ? "true" : "false"); break;`, ` case SCR_DYN_NUM: {`, ` ScrStr *s = scr_f64_to_scrstr(d->v.num); /* String(n): NaN/Infinity spelled out, not JSON null */`, ` for (size_t i = 0; i < s->len; i++) scr_jb_putc(b, s->data[i]);`, ` scr_str_release(s);`, ` break;`, ` }`, ` case SCR_DYN_STR:`, ` for (size_t i = 0; i < d->v.str->len; i++) scr_jb_putc(b, d->v.str->data[i]);`, ` break;`, ` case SCR_DYN_ARR:`, ` /* Array.prototype.toString: join(",") — null/undefined ELEMENTS`, ` * print empty (unlike top level), nested arrays flatten. */`, ` for (size_t i = 0; i < d->v.arr.len; i++) {`, ` if (i > 0) scr_jb_putc(b, ',');`, ` const ScrDyn *e = d->v.arr.items[i];`, ` if (e->kind == SCR_DYN_UNDEF || e->kind == SCR_DYN_NULL) continue;`, ` ${name}_buf(b, e);`, ` }`, ` break;`, ` case SCR_DYN_OBJ:`, ` if (scr_dyn_obj_get(d, "%error", 6)) {`, ` /* The checked-dynamic tree's error encoding (caughtToDyn): Error.prototype`, ` * .toString over the encoded name/message — Node's String(err),`, ` * which carries no stack either. */`, ` const ScrDyn *en = scr_dyn_obj_get(d, "name", 4);`, ` const ScrDyn *em = scr_dyn_obj_get(d, "message", 7);`, ` const ScrStr *ens = (en && en->kind == SCR_DYN_STR) ? en->v.str : NULL;`, ` const ScrStr *ems = (em && em->kind == SCR_DYN_STR) ? em->v.str : NULL;`, ` if (ens) for (size_t i = 0; i < ens->len; i++) scr_jb_putc(b, ens->data[i]);`, ` if (ens && ens->len && ems && ems->len) scr_jb_puts(b, ": ");`, ` if (ems) for (size_t i = 0; i < ems->len; i++) scr_jb_putc(b, ems->data[i]);`, ` break;`, ` }`, ` scr_jb_puts(b, "[object Object]");`, ` break;`, ` case SCR_DYN_BYTES: {`, ` /* Buffer-flavored values (stream chunks) coerce utf8 (Node's`, ` * Buffer.toString); plain Uint8Array joins its elements. */`, ` if (d->buffer) {`, ` ScrStr *enc = scr_str_new("utf8", 4);`, ` ScrStr *txt = scr_bytes_to_str(d->v.bytes, enc);`, ` scr_str_release(enc);`, ` for (size_t i = 0; i < txt->len; i++) scr_jb_putc(b, txt->data[i]);`, ` scr_str_release(txt);`, ` break;`, ` }`, ` for (size_t i = 0; i < d->v.bytes->len; i++) {`, ` if (i > 0) scr_jb_putc(b, ',');`, ` char n[16];`, ` snprintf(n, sizeof n, "%u", (unsigned)d->v.bytes->data[i]);`, ` scr_jb_puts(b, n);`, ` }`, ` break;`, ` }`, ` case SCR_DYN_FUNC:`, ` /* Function.prototype.toString: the SOURCE is gone in a compiled`, ` * program, so the native-code form — exactly what JS engines`, ` * print for their own non-JS functions. */`, ` scr_jb_puts(b, "function ");`, ` if (d->v.fn.name) scr_jb_puts(b, d->v.fn.name);`, ` scr_jb_puts(b, "() { [native code] }");`, ` break;`, ` case SCR_DYN_HANDLE:`, ` /* Object.prototype.toString — Node's String() over these`, ` * classes (IncomingMessage/ServerResponse/Socket). */`, ` scr_jb_puts(b, "[object Object]");`, ` break;`, ` case SCR_DYN_PROMISE:`, ` /* Object.prototype.toString with the Promise @@toStringTag. */`, ` scr_jb_puts(b, "[object Promise]");`, ` break;`, ` case SCR_DYN_JSVAL:`, ` /* Island-held: the engine's own ToString (a bridged failure`, ` * leaves the exception pending and appends nothing). */`, ` scr_dyn_isl_tostr_buf(b, d);`, ` break;`, ` case SCR_DYN_TYPED_REF: {`, ` ScrDyn *sc_materialized = scr_dyn_typed_ref_materialize(d);`, ` ${name}_buf(b, sc_materialized);`, ` scr_dyn_release(sc_materialized);`, ` break;`, ` }`, ` }`, `}`, `static ScrStr *${name}(const ScrDyn *d) { /* String(unknown) -> owned (+1) */`, ` if (d->kind == SCR_DYN_STR) return scr_str_retain(d->v.str);`, ` ScrJsonBuf b;`, ` scr_jb_init(&b);`, ` ${name}_buf(&b, d);`, ` return scr_jb_finish(&b);`, `}`, ``);
201
- return name;
202
- }
203
- /** The caught→dyn converter (interned once, type-independent): a catch
204
- * binding flowing into an `unknown` slot — the typed→unknown deep-copy
205
- * stance over the exception snapshot's runtime kind. Scalar payloads
206
- * convert exactly; an Error-family OBJ payload becomes the checked-dynamic tree's error
207
- * encoding — the reserved "%error" marker plus name/message (and code
208
- * when stamped), so `instanceof Error`, the %Error extraction, and
209
- * String() answer like Node; every other payload (REF — records, arrays,
210
- * closures, unions — and non-Error hierarchy objects, type-erased at
211
- * runtime) becomes an EMPTY dyn object (SEMANTICS.md 67). Borrows the
212
- * snapshot; the result is a fresh tree (+1). Never throws. */
213
- export function caughtToDynHelper(emitter) {
214
- if (emitter.caughtToDynFn)
215
- return emitter.caughtToDynFn;
216
- const name = "sc_cd";
217
- emitter.caughtToDynFn = name;
218
- const sig = `static ScrDyn *${name}(const ScrCaught *c)`;
219
- emitter.walkerProtos.push(`${sig}; /* caught -> unknown */`);
220
- emitter.walkerDefs.push(`${sig} { /* caught -> unknown (+1, fresh tree) */`, ` switch (c->kind) {`, ` case SCR_EXC_F64: return scr_dyn_new_num(c->f64);`, ` case SCR_EXC_BOOL: return scr_dyn_new_bool(c->b);`, ` case SCR_EXC_STR: return scr_dyn_new_str((ScrStr *)c->payload); /* _new_str retains */`, ` case SCR_EXC_OBJ:`, ` if (scr_error_is(c->payload)) {`, ` /* The identity-cached crossing (scr_json.c): the SAME error`, ` * instance boxes to ONE dyn node however it crosses, so a`, ` * caught dyn compares reference-equal to the thrown error's`, ` * other boxings, like Node. */`, ` return scr_dyn_from_error((const ScrError *)c->payload);`, ` }`, ` /* FALLTHROUGH: a non-Error hierarchy object is type-erased */`, ` case SCR_EXC_REF:`, ` case SCR_EXC_PRIMITIVE_REF:`, ` /* A thrown dyn value passes back BY REFERENCE (identity with`, ` * every other holder of the node — the traced-throw shape). */`, ` if (c->retain_fn == scr_dyn_retain_v) return scr_dyn_retain((ScrDyn *)c->payload);`, ` /* FALLTHROUGH */`, ` default:`, ` /* non-dyn REF and non-Error objects: the "[object Object]"`, ` * approximation — truthy, typeof "object", fields unreadable. */`, ` return scr_dyn_new_obj();`, ` }`, `}`, ``);
221
- return name;
222
- }
223
- /** The pretty-print re-indenter (interned once, type-independent):
224
- * `JSON.stringify(v, null, space)` output as a REWRITE of the compact
225
- * serializer text — Node's gap algorithm exactly. Structural '{'/'[' open
226
- * a newline + one-deeper indent (unless immediately closed: `{}` and `[]`
227
- * stay inline, like Node), '}'/']' close onto their own line at the outer
228
- * depth, ',' breaks the line at the current depth, and the key ':' gains
229
- * one space. String state (with escape skipping) keeps literal braces,
230
- * commas, and colons inside JSON strings untouched. Compact input is
231
- * BORROWED; the result is a fresh string (+1). An empty indent (space 0,
232
- * "", null) never reaches here — the frontend drops the property. */
233
- export function jsonIndentHelper(emitter) {
234
- if (emitter.jsonIndentFn)
235
- return emitter.jsonIndentFn;
236
- const name = "sc_ji";
237
- emitter.jsonIndentFn = name;
238
- const sig = `static ScrStr *${name}(ScrStr *compact, const char *indent, size_t ilen)`;
239
- emitter.walkerProtos.push(`${sig}; /* stringify space re-indent */`);
240
- emitter.walkerDefs.push(`${sig} { /* stringify space re-indent (Node's gap algorithm) */`, ` ScrJsonBuf b;`, ` scr_jb_init(&b);`, ` const char *s = compact->data;`, ` size_t n = compact->len;`, ` size_t depth = 0;`, ` bool instr = false;`, `#define SCR_JI_INDENT() do { \\`, ` scr_jb_putc(&b, '\\n'); \\`, ` for (size_t td = 0; td < depth; td++) \\`, ` for (size_t tk = 0; tk < ilen; tk++) scr_jb_putc(&b, indent[tk]); \\`, ` } while (0)`, ` for (size_t i = 0; i < n; i++) {`, ` char c = s[i];`, ` if (instr) {`, ` scr_jb_putc(&b, c);`, ` if (c == '\\\\' && i + 1 < n) { scr_jb_putc(&b, s[++i]); }`, ` else if (c == '"') instr = false;`, ` continue;`, ` }`, ` switch (c) {`, ` case '"': instr = true; scr_jb_putc(&b, c); break;`, ` case '{': case '[':`, ` scr_jb_putc(&b, c);`, ` if (i + 1 < n && s[i + 1] == (c == '{' ? '}' : ']')) {`, ` scr_jb_putc(&b, s[++i]); /* empty {} / [] stay inline, like Node */`, ` break;`, ` }`, ` depth++;`, ` SCR_JI_INDENT();`, ` break;`, ` case '}': case ']':`, ` depth--;`, ` SCR_JI_INDENT();`, ` scr_jb_putc(&b, c);`, ` break;`, ` case ',':`, ` scr_jb_putc(&b, ',');`, ` SCR_JI_INDENT();`, ` break;`, ` case ':':`, ` scr_jb_putc(&b, ':');`, ` scr_jb_putc(&b, ' ');`, ` break;`, ` default:`, ` scr_jb_putc(&b, c);`, ` }`, ` }`, `#undef SCR_JI_INDENT`, ` return scr_jb_finish(&b);`, `}`, ``);
241
- return name;
242
- }
243
- export function jsonWriteHelper(emitter, t) {
244
- const key = typeKey(t);
245
- const existing = emitter.jsonWriters.get(key);
246
- if (existing)
247
- return existing;
248
- const name = `sc_jw_${emitter.jsonWriters.size}`;
249
- emitter.jsonWriters.set(key, name);
250
- const sig = `static void ${name}(ScrJsonBuf *b, ${cDecl(t, "v")})`;
251
- emitter.walkerProtos.push(`${sig}; /* stringify ${key} */`);
252
- const d = [`${sig} { /* stringify ${key} */`];
253
- switch (t.kind) {
254
- case "f64":
255
- d.push(` scr_jb_put_f64(b, v); /* NaN/Infinity -> null, -0 -> 0, like JS */`);
256
- break;
257
- case "bool":
258
- d.push(` scr_jb_puts(b, v ? "true" : "false");`);
259
- break;
260
- case "string":
261
- d.push(` scr_jb_put_json_str(b, v);`);
262
- break;
263
- case "record": {
264
- const shape = emitter.recordsById.get(t.shapeId);
265
- if (!shape)
266
- throw new InternalCompilerError(`emitter bug: jsonStringify of unknown shape ${t.shapeId}`);
267
- // CYCLE-CAPABLE shapes (recursive record types — the collector-
268
- // fixpoint set) bracket the walk with the circular-detection
269
- // stack: a value already being serialized above throws V8's exact
270
- // circular-structure TypeError (scr_jb_enter). Edge labels stamp
271
- // only before members whose walk can re-enter (cycle-capable
272
- // types); acyclic shapes pay nothing.
273
- const cyclic = emitter.traceAdapterC(t) !== null;
274
- const edgeable = (ft) => cyclic && emitter.traceAdapterC(ft) !== null;
275
- if (cyclic)
276
- d.push(` if (!scr_jb_enter(b, v, ${shape.tuple ? "true" : "false"})) return; /* circular: pending TypeError */`);
277
- // A tuple serializes as a JSON ARRAY in index order — JS-exact
278
- // (JSON.stringify(["a", 1]) is `["a",1]`). Every position is
279
- // required, so labels/commas are static like all-required records.
280
- if (shape.tuple) {
281
- const byIndex = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
282
- d.push(` scr_jb_putc(b, '[');`);
283
- byIndex.forEach((f, i) => {
284
- if (i > 0)
285
- d.push(` scr_jb_putc(b, ',');`);
286
- if (edgeable(f.type))
287
- d.push(` scr_jb_edge_idx(b, ${i});`);
288
- d.push(` ${emitter.jsonWriteHelper(f.type)}(b, v->${mangleField(f.name)});`);
289
- });
290
- d.push(` scr_jb_putc(b, ']');`);
291
- if (cyclic)
292
- d.push(` scr_jb_leave(b);`);
293
- break;
294
- }
295
- // Fields serialize in DECLARED order — JS insertion order, exactly
296
- // Node for objects constructed in declaration order (SEMANTICS.md
297
- // 36 documents the divergence when they are not) — never the
298
- // canonical (sorted) struct order. declaredOrder may omit internal
299
- // '%'-fields (Dirent's %dtype): those are hidden from JSON exactly
300
- // like every other key-order surface. Shapes interned WITHOUT an
301
- // order (the CJS export-table literal, accessor-narrowed JS
302
- // shapes) keep the canonical order — their construction paths
303
- // document the divergence.
304
- const order = shape.declaredOrder ?? shape.fields.map((f) => f.name);
305
- const inOrder = new Set(order);
306
- if (shape.fields.some((f) => !inOrder.has(f.name) && !f.name.startsWith("%"))) {
307
- throw new InternalCompilerError(`emitter bug: declaredOrder of shape ${t.shapeId} omits a non-internal field`);
308
- }
309
- const byName = new Map(shape.fields.map((f) => [f.name, f]));
310
- const emitFields = order.map((n) => byName.get(n)).filter((f) => f !== undefined);
311
- // Optional-flavored fields (undefined-armed unions) DROP from the
312
- // output while they hold the undefined arm — exactly Node — so as
313
- // soon as one exists, comma placement turns dynamic (a `first`
314
- // flag); all-required shapes keep the static prefix labels. An
315
- // overflow portion forces the dynamic path too (entry count is
316
- // runtime state).
317
- const droppable = emitFields.some((f) => undefinedArmTag(f.type, emitter.unionsById) >= 0) || !!shape.indexValue;
318
- d.push(` scr_jb_putc(b, '{');`);
319
- if (!droppable) {
320
- emitFields.forEach((f, i) => {
321
- const label = cStringLiteral(Buffer.from(`${i > 0 ? "," : ""}${jsonObjectKeyLabel(f.name)}`, "utf8"));
322
- d.push(` scr_jb_puts(b, ${label});`);
323
- if (edgeable(f.type))
324
- d.push(` scr_jb_edge_prop(b, ${cStringLiteral(Buffer.from(f.name, "utf8"))});`);
325
- // Refcounted fields are BORROWED straight off the struct (the
326
- // record itself is borrowed for the whole call).
327
- d.push(` ${emitter.jsonWriteHelper(f.type)}(b, v->${mangleField(f.name)});`);
328
- });
329
- }
330
- else {
331
- d.push(` bool first = true;`);
332
- for (const f of emitFields) {
333
- const label = cStringLiteral(Buffer.from(jsonObjectKeyLabel(f.name), "utf8"));
334
- const utag = undefinedArmTag(f.type, emitter.unionsById);
335
- const pad = utag >= 0 ? " " : " ";
336
- if (utag >= 0) {
337
- d.push(` if (v->${mangleField(f.name)}->tag != ${utag}) { /* undefined-valued field: dropped, like Node */`);
338
- }
339
- d.push(`${pad}if (!first) scr_jb_putc(b, ',');`);
340
- d.push(`${pad}first = false;`);
341
- d.push(`${pad}scr_jb_puts(b, ${label});`);
342
- if (edgeable(f.type))
343
- d.push(`${pad}scr_jb_edge_prop(b, ${cStringLiteral(Buffer.from(f.name, "utf8"))});`);
344
- d.push(`${pad}${emitter.jsonWriteHelper(f.type)}(b, v->${mangleField(f.name)});`);
345
- if (utag >= 0)
346
- d.push(` }`);
347
- }
348
- // Overflow entries follow the declared fields, themselves in JS
349
- // OWN-KEY order — integer-like keys ascending first, then the
350
- // rest in insertion order (scr_map_keys_js_order, the same
351
- // enumeration Object.keys answers; number-keyed signatures make
352
- // integer-like overflow keys ordinary). SEMANTICS.md documents
353
- // the declared-canonical-then-overflow divergence from JS's one
354
- // interleaved key order. Keys escape like any JSON string;
355
- // undefined-valued entries drop, exactly the optional-field rule.
356
- if (shape.indexValue) {
357
- const iv = shape.indexValue;
358
- const m = `v->${OVERFLOW_MEMBER}`;
359
- d.push(` {`);
360
- d.push(` ScrArr *ks = scr_map_keys_js_order(${m});`);
361
- d.push(` for (size_t i = 0; i < ks->len; i++) {`);
362
- d.push(` ScrStr *k = (ScrStr *)scr_arr_get_ref(ks, (double)i);`);
363
- if (iv.kind === "f64" || iv.kind === "bool") {
364
- d.push(` ${cDecl(iv, "e")} = 0;`);
365
- d.push(` scr_map_get_str_${iv.kind === "f64" ? "f64" : "bool"}(${m}, k, &e);`);
366
- }
367
- else {
368
- d.push(` ${cDecl(iv, "e")} = (${cType(iv).trim()})scr_map_get_str_ref(${m}, k);`);
369
- }
370
- const skipUndef = iv.kind === "dyn"
371
- ? `e->kind == SCR_DYN_UNDEF`
372
- : undefinedArmTag(iv, emitter.unionsById) >= 0
373
- ? `e->tag == ${undefinedArmTag(iv, emitter.unionsById)}`
374
- : null;
375
- if (skipUndef) {
376
- d.push(` if (${skipUndef}) { /* undefined-valued entry: dropped, like Node */`);
377
- d.push(` ${releaseCallC(iv, "e")};`);
378
- d.push(` scr_str_release(k);`);
379
- d.push(` continue;`);
380
- d.push(` }`);
381
- }
382
- d.push(` if (!first) scr_jb_putc(b, ',');`);
383
- d.push(` first = false;`);
384
- d.push(` scr_jb_put_json_str(b, k);`);
385
- d.push(` scr_jb_putc(b, ':');`);
386
- if (edgeable(iv))
387
- d.push(` scr_jb_edge_key(b, k);`);
388
- d.push(` ${emitter.jsonWriteHelper(iv)}(b, e);`);
389
- d.push(` scr_str_release(k);`);
390
- if (isRefCounted(iv))
391
- d.push(` ${releaseCallC(iv, "e")};`);
392
- d.push(` }`);
393
- d.push(` scr_arr_release(ks);`);
394
- d.push(` }`);
395
- }
396
- }
397
- d.push(` scr_jb_putc(b, '}');`);
398
- if (cyclic)
399
- d.push(` scr_jb_leave(b);`);
400
- break;
401
- }
402
- case "dyn":
403
- // Overflow values under an `unknown` index signature: the checked-dynamic tree
404
- // serializes itself (runtime walker) — object members holding
405
- // undefined drop, array slots holding undefined print null,
406
- // exactly Node. Bare JSON.stringify of dyn stays frontend-fenced;
407
- // this writer is reachable only through overflow entries.
408
- d.push(` scr_jb_put_dyn(b, v);`);
409
- break;
410
- case "array": {
411
- const elem = t.elem;
412
- const w = emitter.jsonWriteHelper(elem);
413
- // A cycle-capable array (elements can point back at it) joins the
414
- // circular-detection stack exactly like a cycle-capable record.
415
- const cyclic = emitter.traceAdapterC(t) !== null;
416
- if (cyclic)
417
- d.push(` if (!scr_jb_enter(b, v, true)) return; /* circular: pending TypeError */`);
418
- d.push(` scr_jb_putc(b, '[');`);
419
- d.push(` for (size_t i = 0; i < v->len; i++) {`);
420
- d.push(` if (i > 0) scr_jb_putc(b, ',');`);
421
- d.push(` if (scr_arr_state(v, (double)i) != SCR_ARR_VALUE) { scr_jb_puts(b, "null"); continue; }`);
422
- if (cyclic)
423
- d.push(` scr_jb_edge_idx(b, i);`);
424
- if (elem.kind === "f64") {
425
- d.push(` ${w}(b, scr_arr_get_f64(v, (double)i));`);
426
- }
427
- else if (elem.kind === "bool") {
428
- d.push(` ${w}(b, scr_arr_get_bool(v, (double)i));`);
429
- }
430
- else {
431
- // _get_ref returns +1; release after writing.
432
- d.push(` ${cDecl(elem, "e")} = (${cType(elem).trim()})scr_arr_get_ref(v, (double)i);`);
433
- d.push(` ${w}(b, e);`);
434
- d.push(` ${releaseCallC(elem, "e")};`);
435
- }
436
- d.push(` }`);
437
- d.push(` scr_jb_putc(b, ']');`);
438
- if (cyclic)
439
- d.push(` scr_jb_leave(b);`);
440
- break;
441
- }
442
- case "union": {
443
- const def = emitter.unionsById.get(t.unionId);
444
- if (!def)
445
- throw new InternalCompilerError(`emitter bug: jsonStringify of unknown union ${t.unionId}`);
446
- d.push(` switch (v->tag) {`);
447
- def.arms.forEach((arm, i) => {
448
- if (arm.kind === "nullT") {
449
- // Payload-less arm: JSON.stringify(null) is the text `null`,
450
- // exactly like Node.
451
- d.push(` case ${i}: scr_jb_puts(b, "null"); break;`);
452
- return;
453
- }
454
- if (arm.kind === "undefinedT") {
455
- // Array and tuple slots stringify undefined as null. Ordinary
456
- // record fields drop the key before invoking this writer.
457
- d.push(` case ${i}: scr_jb_puts(b, "null"); break;`);
458
- return;
459
- }
460
- const w = emitter.jsonWriteHelper(arm);
461
- if (arm.kind === "f64") {
462
- d.push(` case ${i}: ${w}(b, scr_union_get_f64(v)); break;`);
463
- }
464
- else if (arm.kind === "bool") {
465
- d.push(` case ${i}: ${w}(b, scr_union_get_bool(v)); break;`);
466
- }
467
- else {
468
- // Payload is BORROWED out of the box for the write.
469
- d.push(` case ${i}: ${w}(b, (${cType(arm).trim()})scr_union_peek(v)); break;`);
470
- }
471
- });
472
- d.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`);
473
- d.push(` }`);
474
- break;
475
- }
476
- default:
477
- throw new InternalCompilerError(`emitter bug: jsonStringify of non-JSON type ${t.kind}`);
478
- }
479
- d.push(`}`, ``);
480
- emitter.walkerDefs.push(...d);
481
- return name;
482
- }
483
- /** The emitted match predicate for one dynCheck target type:
484
- * `static bool sc_dm_<n>(const ScrDyn *d)` — does this dyn fit T?
485
- * Never throws, builds nothing; union builders use it to try arms in
486
- * canonical order (first FULL match wins). Records are width-tolerant
487
- * here too: extra keys are ignored, only declared fields are examined. */
488
- export function dynMatchHelper(emitter, t) {
489
- const key = typeKey(t);
490
- const existing = emitter.dynMatchers.get(key);
491
- if (existing)
492
- return existing;
493
- const name = `sc_dm_${emitter.dynMatchers.size}`;
494
- emitter.dynMatchers.set(key, name);
495
- const sig = `static bool ${name}(const ScrDyn *d)`;
496
- emitter.walkerProtos.push(`${sig}; /* matches ${key} */`);
497
- const d = [`${sig} { /* matches ${key} */`];
498
- if (isRefCounted(t) && t.kind !== "dyn") {
499
- const keyLit = cStringLiteral(Buffer.from(key, "utf8"));
500
- d.push(` if (scr_dyn_typed_ref_is(d, ${keyLit}, ${Buffer.byteLength(key, "utf8")})) return true;`);
501
- }
502
- if (t.kind !== "dyn") {
503
- d.push(` if (d && d->kind == SCR_DYN_TYPED_REF) {`, ` ScrDyn *sc_materialized = scr_dyn_typed_ref_materialize(d);`, ` bool sc_out = ${name}(sc_materialized);`, ` scr_dyn_release(sc_materialized);`, ` return sc_out;`, ` }`);
504
- }
505
- switch (t.kind) {
506
- case "f64":
507
- d.push(` return d->kind == SCR_DYN_NUM;`);
508
- break;
509
- case "string":
510
- d.push(` return d->kind == SCR_DYN_STR;`);
511
- break;
512
- case "bool":
513
- d.push(` return d->kind == SCR_DYN_BOOL;`);
514
- break;
515
- case "nullT":
516
- // JSON null matches exactly the nullT arm (reachable only as a
517
- // union-arm matcher — bare null is not a valid dynCheck target).
518
- d.push(` return d->kind == SCR_DYN_NULL;`);
519
- break;
520
- case "undefinedT":
521
- // JSON text never parses to undefined, but the checked-dynamic tree can HOLD it now
522
- // (overflow reads/conversions under `unknown` index signatures):
523
- // the undefined dyn value matches exactly the undefined arm.
524
- d.push(` return d->kind == SCR_DYN_UNDEF;`);
525
- break;
526
- case "dyn":
527
- // An `unknown` target: every dyn value fits, undefined included.
528
- d.push(` (void)d;`);
529
- d.push(` return true;`);
530
- break;
531
- case "bytes":
532
- // A Uint8Array target (the checked-dynamic tree carries u8 payloads only).
533
- if (t.elem !== "u8")
534
- throw new InternalCompilerError(`emitter bug: dynMatch of bytes<${t.elem}>`);
535
- d.push(` return d->kind == SCR_DYN_BYTES;`);
536
- break;
537
- case "func":
538
- d.push(` return d->kind == SCR_DYN_FUNC;`);
539
- break;
540
- case "object":
541
- if (t.className === "%Error") {
542
- d.push(` return d->kind == SCR_DYN_OBJ && scr_dyn_obj_get(d, "%error", 6) != NULL;`);
543
- }
544
- else {
545
- // Non-error classes match only the exact typed-reference fast
546
- // path above. A plain object (including JSON input) must never
547
- // acquire a class identity structurally.
548
- d.push(` (void)d; return false;`);
549
- }
550
- break;
551
- case "record": {
552
- const shape = emitter.recordsById.get(t.shapeId);
553
- if (!shape)
554
- throw new InternalCompilerError(`emitter bug: dynCheck of unknown shape ${t.shapeId}`);
555
- // A tuple matches a JSON ARRAY of EXACTLY its arity whose elements
556
- // match positionally (arity is part of the type — width tolerance
557
- // is an object-key concept and does not apply).
558
- if (shape.tuple) {
559
- const byIndex = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
560
- d.push(` if (d->kind != SCR_DYN_ARR || d->v.arr.len != ${byIndex.length}) return false;`);
561
- byIndex.forEach((f, i) => {
562
- d.push(` if (!${emitter.dynMatchHelper(f.type)}(d->v.arr.items[${i}])) return false;`);
563
- });
564
- d.push(` return true;`);
565
- break;
566
- }
567
- d.push(` if (d->kind != SCR_DYN_OBJ) return false;`);
568
- // dyn ('unknown') fields match ANY value, present or missing (a
569
- // missing key builds the undefined dyn value) — no test to emit.
570
- if (shape.fields.some((f) => f.type.kind !== "dyn"))
571
- d.push(` const ScrDyn *m;`);
572
- for (const f of shape.fields) {
573
- if (f.type.kind === "dyn")
574
- continue;
575
- const keyLit = cStringLiteral(Buffer.from(f.name, "utf8"));
576
- const keyLen = Buffer.byteLength(f.name, "utf8");
577
- d.push(` m = scr_dyn_obj_get(d, ${keyLit}, ${keyLen});`);
578
- if (undefinedArmTag(f.type, emitter.unionsById) >= 0) {
579
- // Optional-flavored field: a MISSING key is the undefined arm
580
- // (a match); a PRESENT key must fit the union as usual.
581
- d.push(` if (m && !${emitter.dynMatchHelper(f.type)}(m)) return false;`);
582
- }
583
- else {
584
- d.push(` if (!m || !${emitter.dynMatchHelper(f.type)}(m)) return false;`);
585
- }
586
- }
587
- // Index-signature shapes: UNDECLARED keys must fit the overflow
588
- // value type (the builder CAPTURES them — width tolerance became
589
- // width capture). A dyn value type accepts anything; concrete
590
- // types check every extra entry.
591
- if (shape.indexValue && shape.indexValue.kind !== "dyn") {
592
- const skip = shape.fields
593
- .map((f) => {
594
- const keyLit = cStringLiteral(Buffer.from(f.name, "utf8"));
595
- const keyLen = Buffer.byteLength(f.name, "utf8");
596
- return `(e->key_len == ${keyLen} && memcmp(e->key, ${keyLit}, ${keyLen}) == 0)`;
597
- })
598
- .join(" || ");
599
- d.push(` for (size_t i = 0; i < d->v.obj.len; i++) {`);
600
- d.push(` const ScrDynEntry *e = &d->v.obj.entries[i];`);
601
- if (shape.fields.length > 0)
602
- d.push(` if (${skip}) continue;`);
603
- d.push(` if (!${emitter.dynMatchHelper(shape.indexValue)}(e->value)) return false;`);
604
- d.push(` }`);
605
- }
606
- d.push(` return true;`);
607
- break;
608
- }
609
- case "array": {
610
- const m = emitter.dynMatchHelper(t.elem);
611
- d.push(` if (d->kind != SCR_DYN_ARR) return false;`);
612
- d.push(` for (size_t i = 0; i < d->v.arr.len; i++) {`);
613
- d.push(` if (!${m}(d->v.arr.items[i])) return false;`);
614
- d.push(` }`);
615
- d.push(` return true;`);
616
- break;
617
- }
618
- case "union": {
619
- const def = emitter.unionsById.get(t.unionId);
620
- if (!def)
621
- throw new InternalCompilerError(`emitter bug: dynCheck of unknown union ${t.unionId}`);
622
- // The undefined arm participates: parsed JSON never contains
623
- // undefined (a MISSING record key was the arm's only source), but
624
- // the checked-dynamic tree can hold the undefined value now — overflow entries
625
- // under `unknown` index signatures — and it matches exactly the
626
- // undefined arm.
627
- const arms = def.arms.map((a) => `${emitter.dynMatchHelper(a)}(d)`);
628
- d.push(` return ${arms.join(" || ")};`);
629
- break;
630
- }
631
- default: {
632
- const h = DYN_HANDLE_KINDS.get(t.kind);
633
- if (h) {
634
- d.push(` return d->kind == SCR_DYN_HANDLE && d->v.handle.tag == ${h.tag};`);
635
- break;
636
- }
637
- throw new InternalCompilerError(`emitter bug: dynMatch of non-JSON type ${t.kind}`);
638
- }
639
- }
640
- d.push(`}`, ``);
641
- emitter.walkerDefs.push(...d);
642
- return name;
643
- }
644
- /** The emitted keyed read on a dyn value:
645
- * `static ScrDyn *sc_dyn_key_get(ScrDyn *d, ScrStr *k, bool opt)` —
646
- * OBJ answers the member (+1) or the undefined singleton (own-property
647
- * answer); ARR answers `length` and canonical in-range indices, STR
648
- * answers `length` (UTF-16-exact via scr_str_utf16_len), both
649
- * undefined otherwise; NUM/BOOL/BYTES answer undefined. undefined/null
650
- * receivers THROW the catchable Node-shaped TypeError, or answer the
651
- * undefined singleton when `opt` is set (a `?.` step). Borrows d and k;
652
- * the result is +1. Interned once (the memo key can never collide with
653
- * a typeKey — no IR type spells "%"). */
654
- /** RequireObjectCoercible with V8's destructuring TypeError (the
655
- * dynDestrCheck node): nullish throws "Cannot destructure 'SPELL' as it
656
- * is undefined." (or "…null."), the property form "Cannot destructure
657
- * property 'PROP' of 'SPELL' …" when firstProp is non-NULL — V8's exact
658
- * strings, source spelling included. Non-nullish values pass silently. */
659
- export function dynDestrCheckHelper(emitter) {
660
- const memoKey = "%dynDestrCheck";
661
- const existing = emitter.dynBuilders.get(memoKey);
662
- if (existing)
663
- return existing;
664
- const name = "sc_dyn_destr_check";
665
- emitter.dynBuilders.set(memoKey, name);
666
- const sig = `static void ${name}(const ScrDyn *d, const char *spell, const char *firstProp)`;
667
- emitter.walkerProtos.push(`${sig}; /* destructuring RequireObjectCoercible */`);
668
- emitter.walkerDefs.push(`${sig} { /* destructuring RequireObjectCoercible */`, ` if (d->kind != SCR_DYN_UNDEF && d->kind != SCR_DYN_NULL) return;`, ` ScrJsonBuf b;`, ` scr_jb_init(&b);`, ` if (firstProp) {`, ` scr_jb_puts(&b, "Cannot destructure property '");`, ` scr_jb_puts(&b, firstProp);`, ` scr_jb_puts(&b, "' of '");`, ` scr_jb_puts(&b, spell);`, ` scr_jb_puts(&b, "' as it is ");`, ` } else {`, ` scr_jb_puts(&b, "Cannot destructure '");`, ` scr_jb_puts(&b, spell);`, ` scr_jb_puts(&b, "' as it is ");`, ` }`, ` scr_jb_puts(&b, d->kind == SCR_DYN_UNDEF ? "undefined." : "null.");`, ` scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&b));`, `}`, ``);
669
- return name;
670
- }
671
- /** GetIterator + first-N steps over a dyn value (the dynIterN node), as
672
- * array destructuring sees it: arrays step by index, strings by CODE
673
- * POINT (the string iterator — astral chars arrive unsplit), Buffers by
674
- * byte; everything else throws V8's exact not-iterable TypeError
675
- * ("undefined is not iterable …", "object null is not iterable …",
676
- * "number 1 is not iterable …", "boolean true …", "object …",
677
- * "function …" — each with the "(cannot read property
678
- * Symbol(Symbol.iterator))" tail). Returns a fresh +1 dyn array of
679
- * exactly n elements, undefined-padded past the end. */
680
- export function dynIterNHelper(emitter) {
681
- const memoKey = "%dynIterN";
682
- const existing = emitter.dynBuilders.get(memoKey);
683
- if (existing)
684
- return existing;
685
- const name = "sc_dyn_iter_n";
686
- emitter.dynBuilders.set(memoKey, name);
687
- const sig = `static ScrDyn *${name}(const ScrDyn *d, size_t n)`;
688
- emitter.walkerProtos.push(`${sig}; /* destructuring GetIterator + N steps */`);
689
- emitter.walkerDefs.push(`${sig} { /* destructuring GetIterator + N steps */`, ` if (d->kind == SCR_DYN_TYPED_REF) {`, ` ScrDyn *sc_materialized = scr_dyn_typed_ref_materialize(d);`, ` ScrDyn *sc_out = ${name}(sc_materialized, n);`, ` scr_dyn_release(sc_materialized);`, ` return sc_out;`, ` }`, ` if (d->kind == SCR_DYN_JSVAL) {`, ` /* An engine array IS iterable — the not-iterable TypeError below`, ` * would be a wrong claim. Loud fence (lane dyn-routing-ops). */`, ` scr_dyn_isl_fence(d, "iteration");`, ` return NULL;`, ` }`, ` if (d->kind != SCR_DYN_ARR && d->kind != SCR_DYN_STR && d->kind != SCR_DYN_BYTES) {`, ` ScrJsonBuf b;`, ` scr_jb_init(&b);`, ` switch (d->kind) {`, ` case SCR_DYN_UNDEF: scr_jb_puts(&b, "undefined"); break;`, ` case SCR_DYN_NULL: scr_jb_puts(&b, "object null"); break;`, ` case SCR_DYN_BOOL: scr_jb_puts(&b, d->v.b ? "boolean true" : "boolean false"); break;`, ` case SCR_DYN_NUM: {`, ` scr_jb_puts(&b, "number ");`, ` ScrStr *s = scr_f64_to_scrstr(d->v.num);`, ` for (size_t i = 0; i < s->len; i++) scr_jb_putc(&b, s->data[i]);`, ` scr_str_release(s);`, ` break;`, ` }`, ` case SCR_DYN_FUNC: scr_jb_puts(&b, "function"); break;`, ` default: scr_jb_puts(&b, "object"); break;`, ` }`, ` scr_jb_puts(&b, " is not iterable (cannot read property Symbol(Symbol.iterator))");`, ` scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&b));`, ` return NULL;`, ` }`, ` ScrDyn *out = scr_dyn_new_arr();`, ` for (size_t i = 0; i < n; i++) {`, ` ScrDyn *item = NULL;`, ` if (d->kind == SCR_DYN_ARR) {`, ` item = i < d->v.arr.len ? scr_dyn_retain(d->v.arr.items[i]) : scr_dyn_retain(scr_dyn_undefined());`, ` } else if (d->kind == SCR_DYN_BYTES) {`, ` item = i < d->v.bytes->len ? scr_dyn_new_num((double)d->v.bytes->data[i]) : scr_dyn_retain(scr_dyn_undefined());`, ` } else {`, ` /* String iteration: whole code POINTS (astral chars arrive`, ` * unsplit — the string iterator, not charAt). */`, ` double len = scr_str_utf16_len(d->v.str);`, ` double at = 0;`, ` for (size_t step = 0; step < i && at < len; step++) {`, ` ScrStr *cp = scr_str_cp_at(d->v.str, at);`, ` at += scr_str_utf16_len(cp);`, ` scr_str_release(cp);`, ` }`, ` if (at < len) {`, ` ScrStr *cp = scr_str_cp_at(d->v.str, at);`, ` item = scr_dyn_new_str(cp);`, ` scr_str_release(cp);`, ` } else {`, ` item = scr_dyn_retain(scr_dyn_undefined());`, ` }`, ` }`, ` scr_dyn_arr_push(out, item); /* push takes ownership */`, ` }`, ` return out;`, `}`, ``);
690
- return name;
691
- }
692
- export function dynKeyGetHelper(emitter) {
693
- const memoKey = "%dynKeyGet";
694
- const existing = emitter.dynBuilders.get(memoKey);
695
- if (existing)
696
- return existing;
697
- const name = "sc_dyn_key_get";
698
- emitter.dynBuilders.set(memoKey, name);
699
- const sig = `static ScrDyn *${name}(ScrDyn *d, ScrStr *k, bool opt)`;
700
- emitter.walkerProtos.push(`${sig}; /* d[k] on dyn */`);
701
- const d = [`${sig} { /* d[k] on dyn */`];
702
- d.push(` if (d->kind == SCR_DYN_UNDEF || d->kind == SCR_DYN_NULL) {`);
703
- d.push(` if (opt) return scr_dyn_retain(scr_dyn_undefined());`);
704
- d.push(` const char *base = d->kind == SCR_DYN_UNDEF`);
705
- d.push(` ? "Cannot read properties of undefined (reading '"`);
706
- d.push(` : "Cannot read properties of null (reading '";`);
707
- d.push(` ScrStr *head = scr_str_new(base, strlen(base));`);
708
- d.push(` ScrStr *withKey = scr_str_concat(head, k);`);
709
- d.push(` scr_str_release(head);`);
710
- d.push(` ScrStr *tail = scr_str_new("')", 2);`);
711
- d.push(` ScrStr *msg = scr_str_concat(withKey, tail);`);
712
- d.push(` scr_str_release(withKey);`);
713
- d.push(` scr_str_release(tail);`);
714
- d.push(` scr_throw_error(SCR_ERR_TYPE, msg); /* takes ownership */`);
715
- d.push(` return NULL;`);
716
- d.push(` }`);
717
- d.push(` if (d->kind == SCR_DYN_TYPED_REF) {`);
718
- d.push(` ScrDyn *sc_materialized = scr_dyn_typed_ref_materialize(d);`);
719
- d.push(` ScrDyn *sc_out = ${name}(sc_materialized, k, opt);`);
720
- d.push(` scr_dyn_release(sc_materialized);`);
721
- d.push(` return sc_out;`);
722
- d.push(` }`);
723
- d.push(` if (d->kind == SCR_DYN_OBJ) {`);
724
- d.push(` return scr_dyn_obj_read(d, k->data, k->len);`);
725
- d.push(` }`);
726
- d.push(` if (d->kind == SCR_DYN_JSVAL) {`);
727
- d.push(` /* Island-held: o[k] reads the REAL engine property (getters`);
728
- d.push(` * included, throws bridged catchably) and the result wraps`);
729
- d.push(` * back scalar-normalized — the routed keyed read that retired`);
730
- d.push(` * the fence (and before it, the fence box's .length -> 0). */`);
731
- d.push(` return scr_dyn_isl_key_get(d, k);`);
732
- d.push(` }`);
733
- d.push(` if (d->kind == SCR_DYN_HANDLE) {`);
734
- d.push(` /* Native handles: the tag's modeled properties (req.url,`);
735
- d.push(` * res.statusCode, ...) answer boxed values through the`);
736
- d.push(` * installed ops; the rest is the undefined singleton or the`);
737
- d.push(` * loud not-supported ladder (scr_json.c). */`);
738
- d.push(` return scr_dyn_handle_key_get(d, k);`);
739
- d.push(` }`);
740
- d.push(` if (d->kind == SCR_DYN_BYTES) {`);
741
- d.push(` /* Buffer-shaped dyn (a stream's 'data' chunk in the JS lane):`);
742
- d.push(` * .length and canonical-index byte reads answer like Node. */`);
743
- d.push(` if (k->len == 6 && memcmp(k->data, "length", 6) == 0) {`);
744
- d.push(` return scr_dyn_new_num((double)d->v.bytes->len);`);
745
- d.push(` }`);
746
- d.push(` if (k->len > 0 && !(k->len > 1 && k->data[0] == '0')) {`);
747
- d.push(` size_t idx = 0; bool digits = true;`);
748
- d.push(` for (size_t i = 0; i < k->len; i++) {`);
749
- d.push(` if (k->data[i] < '0' || k->data[i] > '9' || idx > (SIZE_MAX - 9) / 10) { digits = false; break; }`);
750
- d.push(` idx = idx * 10 + (size_t)(k->data[i] - '0');`);
751
- d.push(` }`);
752
- d.push(` if (digits && idx < d->v.bytes->len) return scr_dyn_new_num((double)d->v.bytes->data[idx]);`);
753
- d.push(` }`);
754
- d.push(` }`);
755
- d.push(` if (d->kind == SCR_DYN_FUNC) {`);
756
- d.push(` /* own props (defineProperties writes), then name/length —`);
757
- d.push(` * the function-instance members test/common copies. */`);
758
- d.push(` ScrDyn *m = scr_dyn_fn_get(d, k->data, k->len);`);
759
- d.push(` if (m) return m;`);
760
- d.push(` }`);
761
- d.push(` if (d->kind == SCR_DYN_ARR || d->kind == SCR_DYN_STR) {`);
762
- d.push(` if (k->len == 6 && memcmp(k->data, "length", 6) == 0) {`);
763
- d.push(` return scr_dyn_new_num(d->kind == SCR_DYN_ARR ? (double)d->v.arr.len : scr_str_utf16_len(d->v.str));`);
764
- d.push(` }`);
765
- d.push(` if (k->len > 0 && !(k->len > 1 && k->data[0] == '0')) {`);
766
- d.push(` /* canonical index: digits only, no leading zero — array`);
767
- d.push(` * elements, and the string's 1-code-unit char ("abc"[1] is`);
768
- d.push(` * "b" in JS; out of range reads as an absent key). */`);
769
- d.push(` size_t idx = 0; bool digits = true;`);
770
- d.push(` for (size_t i = 0; i < k->len; i++) {`);
771
- d.push(` if (k->data[i] < '0' || k->data[i] > '9' || idx > (SIZE_MAX - 9) / 10) { digits = false; break; }`);
772
- d.push(` idx = idx * 10 + (size_t)(k->data[i] - '0');`);
773
- d.push(` }`);
774
- d.push(` if (digits && d->kind == SCR_DYN_ARR && idx < d->v.arr.len) return scr_dyn_retain(d->v.arr.items[idx]);`);
775
- d.push(` if (digits && d->kind == SCR_DYN_STR && (double)idx < scr_str_utf16_len(d->v.str)) {`);
776
- d.push(` ScrStr *c = scr_str_char_at(d->v.str, (double)idx);`);
777
- d.push(` ScrDyn *r = scr_dyn_new_str(c);`);
778
- d.push(` scr_str_release(c);`);
779
- d.push(` return r;`);
780
- d.push(` }`);
781
- d.push(` }`);
782
- d.push(` }`);
783
- d.push(` return scr_dyn_retain(scr_dyn_undefined());`);
784
- d.push(`}`, ``);
785
- emitter.walkerDefs.push(...d);
786
- return name;
787
- }
788
- /** The emitted checked builder for one dynCheck target type:
789
- * `static T sc_dc_<n>(const ScrDyn *d, const ScrDynPath *path)` —
790
- * validate the checked-dynamic tree against T and BUILD the typed value (+1), or throw a
791
- * catchable, path-annotated TypeError-shaped string through the exception
792
- * cell and return a dummy (0/false/NULL) with the pending flag set.
793
- * Recursive calls propagate a pending exception by releasing the
794
- * partially-built value and returning — the same pending-check discipline
795
- * emitted function bodies follow. */
796
- export function dynCheckHelper(emitter, t) {
797
- const key = typeKey(t);
798
- const existing = emitter.dynBuilders.get(key);
799
- if (existing)
800
- return existing;
801
- const name = `sc_dc_${emitter.dynBuilders.size}`;
802
- emitter.dynBuilders.set(key, name);
803
- const sig = `static ${cType(t)}${cType(t).endsWith("*") ? "" : " "}${name}(const ScrDyn *d, const ScrDynPath *path)`;
804
- emitter.walkerProtos.push(`${sig}; /* check ${key} */`);
805
- const want = cStringLiteral(Buffer.from(dynDesc(t, emitter.recordsById, emitter.unionsById), "utf8"));
806
- const d = [`${sig} { /* check ${key} */`];
807
- if (isRefCounted(t) && t.kind !== "dyn") {
808
- const keyLit = cStringLiteral(Buffer.from(key, "utf8"));
809
- const keyLen = Buffer.byteLength(key, "utf8");
810
- d.push(` if (scr_dyn_typed_ref_is(d, ${keyLit}, ${keyLen})) {`, ` return (${cType(t).trim()})scr_dyn_typed_ref_unbox(d);`, ` }`);
811
- if (t.kind !== "union") {
812
- const rc = vAdapters(t);
813
- d.push(` if (d && d->kind == SCR_DYN_TYPED_REF) {`, ` ${cDecl(t, "sc_cached")} = (${cType(t).trim()})scr_dyn_typed_ref_cached_cast(d, ${keyLit}, ${keyLen});`);
814
- if (t.kind !== "record" && t.kind !== "array") {
815
- d.push(` if (sc_cached) return sc_cached;`);
816
- }
817
- d.push(` ScrDyn *sc_materialized = scr_dyn_typed_ref_materialize(d);`, ` ${cDecl(t, "sc_out")} = ${name}(sc_materialized, path);`, ` scr_dyn_release(sc_materialized);`);
818
- if (t.kind === "record") {
819
- const shape = emitter.recordsById.get(t.shapeId);
820
- if (!shape) {
821
- throw new InternalCompilerError(`emitter bug: cached typed-ref cast of unknown shape ${t.shapeId}`);
822
- }
823
- d.push(` if (sc_out && sc_cached) {`);
824
- for (const field of shape.fields) {
825
- const member = mangleField(field.name);
826
- d.push(` {`, ` ${cDecl(field.type, "sc_old")} = sc_cached->${member};`, ` sc_cached->${member} = sc_out->${member};`, ` sc_out->${member} = sc_old;`, ` }`);
827
- }
828
- if (shape.indexValue) {
829
- d.push(` ScrMap *sc_old = sc_cached->${OVERFLOW_MEMBER};`, ` sc_cached->${OVERFLOW_MEMBER} = sc_out->${OVERFLOW_MEMBER};`, ` sc_out->${OVERFLOW_MEMBER} = sc_old;`);
830
- }
831
- d.push(` ${releaseCallC(t, "sc_out")};`, ` return sc_cached;`, ` }`, ` if (sc_cached) ${releaseCallC(t, "sc_cached")};`);
832
- }
833
- else if (t.kind === "array") {
834
- d.push(` if (sc_out && sc_cached) {`, ` size_t sc_old_len = sc_cached->len;`, ` size_t sc_old_cap = sc_cached->cap;`, ` uint64_t *sc_old_data = sc_cached->data;`, ` sc_cached->len = sc_out->len;`, ` sc_cached->cap = sc_out->cap;`, ` sc_cached->data = sc_out->data;`, ` sc_out->len = sc_old_len;`, ` sc_out->cap = sc_old_cap;`, ` sc_out->data = sc_old_data;`, ` scr_arr_release(sc_out);`, ` return sc_cached;`, ` }`, ` if (sc_cached) scr_arr_release(sc_cached);`);
835
- }
836
- d.push(` if (sc_out) {`, ` scr_dyn_typed_ref_cache_cast((ScrDyn *)d, ${keyLit}, ${keyLen}, sc_out, &${rc.retain}, &${rc.release});`, ` }`, ` return sc_out;`, ` }`);
837
- }
838
- }
839
- switch (t.kind) {
840
- case "f64":
841
- d.push(` if (d->kind != SCR_DYN_NUM) { scr_dyn_check_fail(path, ${want}, d); return 0; }`);
842
- d.push(` return d->v.num;`);
843
- break;
844
- case "bool":
845
- d.push(` if (d->kind != SCR_DYN_BOOL) { scr_dyn_check_fail(path, ${want}, d); return false; }`);
846
- d.push(` return d->v.b;`);
847
- break;
848
- case "string":
849
- d.push(` if (d->kind != SCR_DYN_STR) { scr_dyn_check_fail(path, ${want}, d); return NULL; }`);
850
- d.push(` return scr_str_retain(d->v.str);`);
851
- break;
852
- case "dyn":
853
- // An `unknown` slot passes through as-is. Typed Web-stream transit
854
- // capsules stay wrapped so repeated references keep identity;
855
- // generic operations materialize their one cached detached view.
856
- d.push(` (void)path;`);
857
- d.push(` return scr_dyn_retain((ScrDyn *)d);`);
858
- break;
859
- case "bytes":
860
- // `u as Uint8Array`: kind check, then a fresh COPY out (the
861
- // boundary's aliasing stance in both directions).
862
- if (t.elem !== "u8")
863
- throw new InternalCompilerError(`emitter bug: dynCheck of bytes<${t.elem}>`);
864
- d.push(` if (d->kind != SCR_DYN_BYTES) { scr_dyn_check_fail(path, ${want}, d); return NULL; }`);
865
- d.push(` return scr_dyn_bytes_copy_out(d);`);
866
- break;
867
- case "object":
868
- // The %Error extraction (an instanceof-Error narrow on unknown):
869
- // validate the checked-dynamic tree's error encoding — the reserved "%error" marker
870
- // caughtToDyn builds — and extract through the runtime's IDENTITY
871
- // CACHE (scr_error_from_dyn): a dyn error that came from a runtime
872
- // ScrError answers that very instance, so out-and-back crossings
873
- // compare reference-equal (the tracing suite's shape); alien
874
- // %error objects rebuild once and cache the pair.
875
- if (t.className === "%Error") {
876
- d.push(` if (d->kind != SCR_DYN_OBJ || !scr_dyn_obj_get(d, "%error", 6)) { scr_dyn_check_fail(path, ${want}, d); return NULL; }`);
877
- d.push(` return scr_error_from_dyn(d);`);
878
- }
879
- else {
880
- // Exact typed references returned before this switch. Plain dyn
881
- // objects do not carry a class brand, so fail instead of
882
- // manufacturing an instance from matching fields.
883
- d.push(` scr_dyn_check_fail(path, ${want}, d);`);
884
- d.push(` return NULL;`);
885
- }
886
- break;
887
- case "record": {
888
- const shape = emitter.recordsById.get(t.shapeId);
889
- if (!shape)
890
- throw new InternalCompilerError(`emitter bug: dynCheck of unknown shape ${t.shapeId}`);
891
- const rel = (v) => releaseCallC(t, v);
892
- // Tuple targets: a JSON ARRAY of exactly the arity, validated and
893
- // extracted positionally with index paths ("$.pairs[3][1]").
894
- if (shape.tuple) {
895
- const byIndex = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
896
- const arityWant = cStringLiteral(Buffer.from(`array of length ${byIndex.length}`, "utf8"));
897
- d.push(` if (d->kind != SCR_DYN_ARR) { scr_dyn_check_fail(path, ${want}, d); return NULL; }`);
898
- d.push(` if (d->v.arr.len != ${byIndex.length}) { scr_dyn_check_fail(path, ${arityWant}, d); return NULL; }`);
899
- d.push(` ${cDecl(t, "r")} = ${mangleRecordNew(t.shapeId)}();`);
900
- byIndex.forEach((f, i) => {
901
- d.push(` {`);
902
- d.push(` ScrDynPath p = { path, NULL, ${i} };`);
903
- d.push(` r->${mangleField(f.name)} = ${emitter.dynCheckHelper(f.type)}(d->v.arr.items[${i}], &p);`);
904
- d.push(` if (scr_exc_pending()) { ${rel("r")}; return NULL; }`);
905
- d.push(` }`);
906
- });
907
- d.push(` return r;`);
908
- break;
909
- }
910
- d.push(` if (d->kind != SCR_DYN_OBJ) { scr_dyn_check_fail(path, ${want}, d); return NULL; }`);
911
- d.push(` ${cDecl(t, "r")} = ${mangleRecordNew(t.shapeId)}();`);
912
- for (const f of shape.fields) {
913
- const keyLit = cStringLiteral(Buffer.from(f.name, "utf8"));
914
- const keyLen = Buffer.byteLength(f.name, "utf8");
915
- const fieldWant = cStringLiteral(Buffer.from(dynDesc(f.type, emitter.recordsById, emitter.unionsById), "utf8"));
916
- // Width tolerance: only declared fields are looked up — extra JSON
917
- // keys are simply never examined (check-and-extract, not shape
918
- // equality). A missing field fails as "got undefined" — except
919
- // optional-flavored fields (undefined-armed unions), where the
920
- // missing key IS the undefined arm: the interned immortal
921
- // instance, no retain owed (rc == SIZE_MAX).
922
- const utag = f.type.kind === "union" ? undefinedArmTag(f.type, emitter.unionsById) : -1;
923
- d.push(` {`);
924
- d.push(` ScrDynPath p = { path, ${keyLit}, 0 };`);
925
- d.push(` const ScrDyn *m = scr_dyn_obj_get(d, ${keyLit}, ${keyLen});`);
926
- if (f.type.kind === "dyn") {
927
- // An `unknown` field: a present key passes through, a missing
928
- // one IS the undefined dyn value (JS's missing-property read).
929
- // Go through the dyn builder so a Web-stream typed-ref capsule
930
- // cannot escape inside a checked record field.
931
- d.push(` r->${mangleField(f.name)} = ${emitter.dynCheckHelper(f.type)}(m ? m : scr_dyn_undefined(), &p);`);
932
- }
933
- else if (utag >= 0 && f.type.kind === "union") {
934
- const unit = emitter.unitInstanceRef(f.type.unionId, utag);
935
- d.push(` if (!m) {`);
936
- d.push(` r->${mangleField(f.name)} = ${unit}; /* absent key -> the undefined arm */`);
937
- d.push(` } else {`);
938
- d.push(` r->${mangleField(f.name)} = ${emitter.dynCheckHelper(f.type)}(m, &p);`);
939
- d.push(` if (scr_exc_pending()) { ${rel("r")}; return NULL; }`);
940
- d.push(` }`);
941
- }
942
- else {
943
- d.push(` if (!m) { scr_dyn_check_fail(&p, ${fieldWant}, NULL); ${rel("r")}; return NULL; }`);
944
- d.push(` r->${mangleField(f.name)} = ${emitter.dynCheckHelper(f.type)}(m, &p);`);
945
- d.push(` if (scr_exc_pending()) { ${rel("r")}; return NULL; }`);
946
- }
947
- d.push(` }`);
948
- }
949
- // Index-signature shapes CAPTURE undeclared keys into the overflow
950
- // map (width tolerance became width capture — plain shapes above
951
- // keep ignoring extras). dyn value types retain the checked-dynamic tree subtree
952
- // as-is; concrete types validate each entry with its key path.
953
- if (shape.indexValue) {
954
- const iv = shape.indexValue;
955
- const skip = shape.fields
956
- .map((f) => {
957
- const keyLit = cStringLiteral(Buffer.from(f.name, "utf8"));
958
- const keyLen = Buffer.byteLength(f.name, "utf8");
959
- return `(e->key_len == ${keyLen} && memcmp(e->key, ${keyLit}, ${keyLen}) == 0)`;
960
- })
961
- .join(" || ");
962
- d.push(` for (size_t i = 0; i < d->v.obj.len; i++) {`);
963
- d.push(` const ScrDynEntry *e = &d->v.obj.entries[i];`);
964
- if (shape.fields.length > 0)
965
- d.push(` if (${skip}) continue;`);
966
- if (iv.kind === "dyn") {
967
- d.push(` ${cDecl(iv, "ev")} = scr_dyn_retain(e->value);`);
968
- }
969
- else {
970
- d.push(` ScrDynPath p = { path, e->key, 0 };`);
971
- d.push(` ${cDecl(iv, "ev")} = ${emitter.dynCheckHelper(iv)}(e->value, &p);`);
972
- d.push(` if (scr_exc_pending()) { ${rel("r")}; return NULL; }`);
973
- }
974
- d.push(` ScrStr *ek = scr_str_new(e->key, e->key_len);`);
975
- if (iv.kind === "f64" || iv.kind === "bool") {
976
- d.push(` scr_map_set_str_${iv.kind === "f64" ? "f64" : "bool"}(r->${OVERFLOW_MEMBER}, ek, ev);`);
977
- }
978
- else {
979
- d.push(` scr_map_set_str_ref(r->${OVERFLOW_MEMBER}, ek, ev);`);
980
- }
981
- d.push(` scr_str_release(ek);`);
982
- d.push(` }`);
983
- }
984
- d.push(` return r;`);
985
- break;
986
- }
987
- case "array": {
988
- const elem = t.elem;
989
- const c = emitter.dynCheckHelper(elem);
990
- d.push(` if (d->kind != SCR_DYN_ARR) { scr_dyn_check_fail(path, ${want}, d); return NULL; }`);
991
- d.push(` ScrArr *a = ${emitter.arrNewC(elem, "d->v.arr.len")};`);
992
- d.push(` for (size_t i = 0; i < d->v.arr.len; i++) {`);
993
- d.push(` ScrDynPath p = { path, NULL, i };`);
994
- d.push(` ${cDecl(elem, "e")} = ${c}(d->v.arr.items[i], &p);`);
995
- d.push(` if (scr_exc_pending()) { scr_arr_release(a); return NULL; }`);
996
- d.push(` scr_arr_push_${elemAccess(elem)}(a, e);`);
997
- d.push(` }`);
998
- d.push(` return a;`);
999
- break;
1000
- }
1001
- case "union": {
1002
- const def = emitter.unionsById.get(t.unionId);
1003
- if (!def)
1004
- throw new InternalCompilerError(`emitter bug: dynCheck of unknown union ${t.unionId}`);
1005
- // Arms in CANONICAL order, first FULL match wins (discriminated
1006
- // unions disambiguate naturally: the arm whose declared fields all
1007
- // fit). The matched arm's builder can no longer fail.
1008
- def.arms.forEach((arm, i) => {
1009
- const m = emitter.dynMatchHelper(arm);
1010
- if (arm.kind === "undefinedT") {
1011
- // Parsed JSON never matches here (no undefined in JSON text —
1012
- // a MISSING record key builds this arm in the record builder
1013
- // above), but the undefined dyn value can arrive from
1014
- // `unknown` index-signature overflows and builds the interned
1015
- // unit instance exactly like null.
1016
- d.push(` if (${m}(d)) {`);
1017
- d.push(` return ${emitter.unitInstanceRef(t.unionId, i)};`);
1018
- d.push(` }`);
1019
- return;
1020
- }
1021
- if (arm.kind === "nullT") {
1022
- // A matched unit arm builds nothing: the result is THE interned
1023
- // immortal instance (rc == SIZE_MAX — RC entry points and the
1024
- // collector both skip it, so no retain is owed).
1025
- d.push(` if (${m}(d)) {`);
1026
- d.push(` return ${emitter.unitInstanceRef(t.unionId, i)};`);
1027
- d.push(` }`);
1028
- return;
1029
- }
1030
- const c = emitter.dynCheckHelper(arm);
1031
- d.push(` if (${m}(d)) {`);
1032
- if (arm.kind === "f64") {
1033
- d.push(` return scr_union_new_f64(${i}, ${c}(d, path));`);
1034
- }
1035
- else if (arm.kind === "bool") {
1036
- d.push(` return scr_union_new_bool(${i}, ${c}(d, path));`);
1037
- }
1038
- else {
1039
- const rc = vAdapters(arm);
1040
- d.push(` return scr_union_new_ref(${i}, ${c}(d, path), &${rc.retain}, &${rc.release}, ${emitter.traceArgC(arm)});`);
1041
- }
1042
- d.push(` }`);
1043
- });
1044
- // A typed stream capsule may fit one arm EXACTLY; those probes run
1045
- // first so the matching arm can preserve object identity. Only when
1046
- // no arm matches the producer tag do we snapshot and retry the
1047
- // ordinary copy-based structural union check (the compiler's width
1048
- // coercion stance, rather than a live narrowed alias).
1049
- d.push(` if (d && d->kind == SCR_DYN_TYPED_REF) {`);
1050
- {
1051
- const keyLit = cStringLiteral(Buffer.from(key, "utf8"));
1052
- const keyLen = Buffer.byteLength(key, "utf8");
1053
- const rc = vAdapters(t);
1054
- d.push(` ${cDecl(t, "sc_cached")} = (${cType(t).trim()})scr_dyn_typed_ref_cached_cast(d, ${keyLit}, ${keyLen});`);
1055
- d.push(` ScrDyn *sc_materialized = scr_dyn_typed_ref_materialize(d);`);
1056
- d.push(` ${cDecl(t, "sc_out")} = ${name}(sc_materialized, path);`);
1057
- d.push(` scr_dyn_release(sc_materialized);`);
1058
- d.push(` if (sc_out && sc_cached) {`);
1059
- d.push(` size_t sc_cached_rc = sc_cached->rc;`);
1060
- d.push(` size_t sc_out_rc = sc_out->rc;`);
1061
- d.push(` ScrUnion sc_old = *sc_cached;`);
1062
- d.push(` *sc_cached = *sc_out;`);
1063
- d.push(` sc_cached->rc = sc_cached_rc;`);
1064
- d.push(` *sc_out = sc_old;`);
1065
- d.push(` sc_out->rc = sc_out_rc;`);
1066
- d.push(` scr_union_release(sc_out);`);
1067
- d.push(` return sc_cached;`);
1068
- d.push(` }`);
1069
- d.push(` if (sc_cached) scr_union_release(sc_cached);`);
1070
- d.push(` if (sc_out) {`);
1071
- d.push(` scr_dyn_typed_ref_cache_cast((ScrDyn *)d, ${keyLit}, ${keyLen}, sc_out, &${rc.retain}, &${rc.release});`);
1072
- d.push(` }`);
1073
- d.push(` return sc_out;`);
1074
- }
1075
- d.push(` }`);
1076
- d.push(` scr_dyn_check_fail(path, ${want}, d);`);
1077
- d.push(` return NULL;`);
1078
- break;
1079
- }
1080
- case "func": {
1081
- // The checked-dynamic function boundary, OUT direction: a
1082
- // non-function kind fails like any dynCheck; an IDENTICAL boxed
1083
- // signature (the interned typeKey — same key ⇔ same IR type ⇔
1084
- // same ABI) unwraps the closure directly (identity preserved:
1085
- // `mustCall(fn)` handed back to a slot of fn's own type IS fn's
1086
- // wrapper, retained); anything else wraps in the per-target
1087
- // adapter closure, whose caps[0] obj-box owns the dyn value
1088
- // (untraced — cycles through dyn never collect, SEMANTICS.md).
1089
- const adapter = dynFuncAdapterHelper(emitter, t);
1090
- const sigLit = cStringLiteral(Buffer.from(key, "utf8"));
1091
- d.push(` if (d->kind != SCR_DYN_FUNC) { scr_dyn_check_fail(path, ${want}, d); return NULL; }`);
1092
- d.push(` if (strcmp(d->v.fn.sig, ${sigLit}) == 0) return scr_closure_retain(d->v.fn.clo);`);
1093
- d.push(` {`);
1094
- d.push(` ScrClosure *a = scr_closure_new((void *)&${adapter}, 1);`);
1095
- d.push(` a->caps[0] = scr_box_new_obj(&scr_dyn_retain_v, &scr_dyn_release_v, NULL);`);
1096
- d.push(` scr_box_set_ref(a->caps[0], scr_dyn_retain((ScrDyn *)d));`);
1097
- d.push(` return a;`);
1098
- d.push(` }`);
1099
- break;
1100
- }
1101
- default: {
1102
- // Runtime HANDLE targets: a tag-checked reference unwrap (+1 —
1103
- // identity, no copy; the runtime throws the path-annotated
1104
- // TypeError on any other kind or tag).
1105
- const h = DYN_HANDLE_KINDS.get(t.kind);
1106
- if (h) {
1107
- d.push(` return (${cType(t).trim()})scr_dyn_handle_unbox(d, ${h.tag}, path, ${want});`);
1108
- break;
1109
- }
1110
- throw new InternalCompilerError(`emitter bug: dynCheck of non-JSON type ${t.kind}`);
1111
- }
1112
- }
1113
- d.push(`}`, ``);
1114
- emitter.walkerDefs.push(...d);
1115
- return name;
1116
- }
1117
- /** The emitted static→dyn converter for one type:
1118
- * `static ScrDyn *sc_td_<n>(<T> v)` — build a fresh dyn value from a
1119
- * static one (+1), DEEP-COPYING composites (a dyn value never aliases
1120
- * static storage — the jsMarshal stance). Domain: the JSON-safe kinds
1121
- * plus undefined-armed unions (the undefined arm becomes the undefined
1122
- * dyn singleton) and index-signature records (whose overflow entries
1123
- * copy over). The operand is borrowed. Never throws. */
1124
- export function toDynHelper(emitter, t) {
1125
- const key = typeKey(t);
1126
- const existing = emitter.toDynFns.get(key);
1127
- if (existing)
1128
- return existing;
1129
- const name = `sc_td_${emitter.toDynFns.size}`;
1130
- emitter.toDynFns.set(key, name);
1131
- const sig = `static ScrDyn *${name}(${cDecl(t, "v")})`;
1132
- emitter.walkerProtos.push(`${sig}; /* to-dyn ${key} */`);
1133
- const d = [`${sig} { /* to-dyn ${key} */`];
1134
- let sourceAccessor = null;
1135
- switch (t.kind) {
1136
- case "f64":
1137
- d.push(` return scr_dyn_new_num(v);`);
1138
- break;
1139
- case "bool":
1140
- d.push(` return scr_dyn_new_bool(v);`);
1141
- break;
1142
- case "string":
1143
- d.push(` return scr_dyn_new_str(v); /* retains v */`);
1144
- break;
1145
- case "undefinedT":
1146
- // A bare unit field (`x: undefined` in a record — the tls
1147
- // options-record's explicit-absent member): the dyn unit value.
1148
- d.push(` (void)v; return scr_dyn_retain(scr_dyn_undefined());`);
1149
- break;
1150
- case "nullT":
1151
- d.push(` (void)v; return scr_dyn_new_null();`);
1152
- break;
1153
- case "object": {
1154
- const className = t.className;
1155
- if (className === "%Error") {
1156
- d.push(` return scr_dyn_from_error(v);`);
1157
- break;
1158
- }
1159
- if (!isDynTypedRefType(t)) {
1160
- throw new InternalCompilerError(`emitter bug: to-dyn of runtime class ${className}`);
1161
- }
1162
- {
1163
- const adapter = emitter.liveDynRefAdapter(t);
1164
- const rc = vAdapters(t);
1165
- const key = typeKey(t);
1166
- const keyLit = cStringLiteral(Buffer.from(key, "utf8"));
1167
- d.push(` return scr_dyn_new_typed_ref(v, &${rc.retain}, &${rc.release}, ${keyLit}, ${Buffer.byteLength(key, "utf8")}, &${adapter.snapshot}, ${adapter.commit});`);
1168
- }
1169
- break;
1170
- }
1171
- case "dyn":
1172
- // A dyn member of a converting composite (a dyn record field): the
1173
- // dyn value passes through by reference — already a dyn, already
1174
- // immutable-through-copies.
1175
- d.push(` return scr_dyn_retain(v);`);
1176
- break;
1177
- case "func":
1178
- // Function-valued record/array fields (EventListenerObject's
1179
- // handleEvent method) box through the same identity-preserving
1180
- // closure bridge as a bare dynFrom function.
1181
- d.push(` return ${dynFuncBoxHelper(emitter, t)}(v, NULL);`);
1182
- break;
1183
- case "bytes":
1184
- // bytes<u8> → the checked-dynamic tree's bytes kind, payload COPIED (the boundary
1185
- // stance; stdin chunks into unknown-typed helpers).
1186
- if (t.elem !== "u8")
1187
- throw new InternalCompilerError(`emitter bug: to-dyn of bytes<${t.elem}>`);
1188
- d.push(` return scr_dyn_new_bytes_copy(v);`);
1189
- break;
1190
- case "record": {
1191
- const shape = emitter.recordsById.get(t.shapeId);
1192
- if (!shape)
1193
- throw new InternalCompilerError(`emitter bug: to-dyn of unknown shape ${t.shapeId}`);
1194
- // CYCLE-CAPABLE shapes guard the deep copy: a cyclic value has no
1195
- // finite dyn copy, so enter TRAPS on re-entry (SEMANTICS.md — Node
1196
- // shares the reference instead of copying).
1197
- const cyclicRec = emitter.traceAdapterC(t) !== null;
1198
- if (cyclicRec)
1199
- d.push(` scr_dyn_from_enter(v);`);
1200
- if (shape.tuple) {
1201
- // A tuple converts as the JSON ARRAY it is everywhere else.
1202
- const byIndex = [...shape.fields].sort((a, b) => Number(a.name) - Number(b.name));
1203
- d.push(` ScrDyn *d = scr_dyn_new_arr();`);
1204
- for (const f of byIndex) {
1205
- d.push(` scr_dyn_arr_push(d, ${emitter.toDynHelper(f.type)}(v->${mangleField(f.name)}));`);
1206
- }
1207
- if (cyclicRec)
1208
- d.push(` scr_dyn_from_leave();`);
1209
- d.push(` return d;`);
1210
- break;
1211
- }
1212
- const carriesListenerIdentity = shape.fields.some((f) => f.name === "handleEvent" && f.type.kind === "func");
1213
- if (carriesListenerIdentity) {
1214
- const rc = vAdapters(t);
1215
- sourceAccessor = {
1216
- name: `${name}_source_access`,
1217
- release: rc.release,
1218
- };
1219
- emitter.walkerProtos.push(`static ScrDyn *${sourceAccessor.name}(void *v, bool materialize); /* live listener source ${key} */`);
1220
- d.push(` ScrDyn *d = scr_dyn_new_obj_with_identity(v, &${rc.retain}, &${sourceAccessor.name});`);
1221
- }
1222
- else {
1223
- d.push(` ScrDyn *d = scr_dyn_new_obj();`);
1224
- }
1225
- // Keys insert in DECLARED order — the dyn object's insertion order
1226
- // is observable (Object.keys/for-in over checked-dynamic values,
1227
- // dyn JSON), so it must be JS's (SEMANTICS.md 36's stance, same as
1228
- // the JSON writer above). Internal '%'-fields declaredOrder omits
1229
- // still enter the checked-dynamic tree (after the visible keys) so a
1230
- // record→dyn→record round trip keeps their data.
1231
- {
1232
- const byName = new Map(shape.fields.map((f) => [f.name, f]));
1233
- const order = shape.declaredOrder ?? shape.fields.map((f) => f.name);
1234
- const inOrder = new Set(order);
1235
- const dynFields = [
1236
- ...order.map((n) => byName.get(n)).filter((f) => f !== undefined),
1237
- ...shape.fields.filter((f) => !inOrder.has(f.name)),
1238
- ];
1239
- for (const f of dynFields) {
1240
- const keyLit = cStringLiteral(Buffer.from(f.name, "utf8"));
1241
- const keyLen = Buffer.byteLength(f.name, "utf8");
1242
- d.push(` scr_dyn_obj_set(d, ${keyLit}, ${keyLen}, ${emitter.toDynHelper(f.type)}(v->${mangleField(f.name)}));`);
1243
- }
1244
- }
1245
- if (shape.indexValue) {
1246
- const iv = shape.indexValue;
1247
- const m = `v->${OVERFLOW_MEMBER}`;
1248
- // JS OWN-KEY order (integer-like keys ascending first) — the same
1249
- // enumeration Object.keys and the JSON writer answer.
1250
- d.push(` {`);
1251
- d.push(` ScrArr *ks = scr_map_keys_js_order(${m});`);
1252
- d.push(` for (size_t i = 0; i < ks->len; i++) {`);
1253
- d.push(` ScrStr *k = (ScrStr *)scr_arr_get_ref(ks, (double)i);`);
1254
- if (iv.kind === "f64" || iv.kind === "bool") {
1255
- d.push(` ${cDecl(iv, "sv")} = 0;`);
1256
- d.push(` scr_map_get_str_${iv.kind === "f64" ? "f64" : "bool"}(${m}, k, &sv);`);
1257
- d.push(` scr_dyn_obj_set(d, k->data, k->len, scr_dyn_new_${iv.kind === "f64" ? "num" : "bool"}(sv));`);
1258
- }
1259
- else if (iv.kind === "dyn") {
1260
- // get_str_ref returns +1 — exactly the ownership obj_set takes.
1261
- d.push(` scr_dyn_obj_set(d, k->data, k->len, (ScrDyn *)scr_map_get_str_ref(${m}, k));`);
1262
- }
1263
- else {
1264
- d.push(` ${cDecl(iv, "e")} = (${cType(iv).trim()})scr_map_get_str_ref(${m}, k);`);
1265
- d.push(` scr_dyn_obj_set(d, k->data, k->len, ${emitter.toDynHelper(iv)}(e));`);
1266
- d.push(` ${releaseCallC(iv, "e")};`);
1267
- }
1268
- d.push(` scr_str_release(k);`);
1269
- d.push(` }`);
1270
- d.push(` scr_arr_release(ks);`);
1271
- d.push(` }`);
1272
- }
1273
- if (cyclicRec)
1274
- d.push(` scr_dyn_from_leave();`);
1275
- d.push(` return d;`);
1276
- break;
1277
- }
1278
- case "array": {
1279
- const elem = t.elem;
1280
- // Cycle-capable arrays guard the deep copy like records above.
1281
- const cyclicArr = emitter.traceAdapterC(t) !== null;
1282
- if (cyclicArr)
1283
- d.push(` scr_dyn_from_enter(v);`);
1284
- d.push(` ScrDyn *d = scr_dyn_new_arr();`);
1285
- d.push(` for (size_t i = 0; i < v->len; i++) {`);
1286
- if (elem.kind === "f64") {
1287
- d.push(` scr_dyn_arr_push(d, scr_dyn_new_num(scr_arr_get_f64(v, (double)i)));`);
1288
- }
1289
- else if (elem.kind === "bool") {
1290
- d.push(` scr_dyn_arr_push(d, scr_dyn_new_bool(scr_arr_get_bool(v, (double)i)));`);
1291
- }
1292
- else {
1293
- d.push(` ${cDecl(elem, "e")} = (${cType(elem).trim()})scr_arr_get_ref(v, (double)i);`);
1294
- d.push(` scr_dyn_arr_push(d, ${emitter.toDynHelper(elem)}(e));`);
1295
- d.push(` ${releaseCallC(elem, "e")};`);
1296
- }
1297
- d.push(` }`);
1298
- if (cyclicArr)
1299
- d.push(` scr_dyn_from_leave();`);
1300
- d.push(` return d;`);
1301
- break;
1302
- }
1303
- case "union": {
1304
- const def = emitter.unionsById.get(t.unionId);
1305
- if (!def)
1306
- throw new InternalCompilerError(`emitter bug: to-dyn of unknown union ${t.unionId}`);
1307
- d.push(` switch (v->tag) {`);
1308
- def.arms.forEach((arm, i) => {
1309
- if (arm.kind === "undefinedT") {
1310
- d.push(` case ${i}: return scr_dyn_retain(scr_dyn_undefined());`);
1311
- }
1312
- else if (arm.kind === "nullT") {
1313
- d.push(` case ${i}: return scr_dyn_new_null();`);
1314
- }
1315
- else if (arm.kind === "f64") {
1316
- d.push(` case ${i}: return scr_dyn_new_num(scr_union_get_f64(v));`);
1317
- }
1318
- else if (arm.kind === "bool") {
1319
- d.push(` case ${i}: return scr_dyn_new_bool(scr_union_get_bool(v));`);
1320
- }
1321
- else if (arm.kind === "func") {
1322
- // A boxable function arm crosses through the checked-dynamic
1323
- // function boundary (the dynFrom func special case, sans name).
1324
- d.push(` case ${i}: return ${dynFuncBoxHelper(emitter, arm)}((ScrClosure *)scr_union_peek(v), NULL);`);
1325
- }
1326
- else {
1327
- d.push(` case ${i}: return ${emitter.toDynHelper(arm)}((${cType(arm).trim()})scr_union_peek(v));`);
1328
- }
1329
- });
1330
- d.push(` default: scr_trap("scriptc: internal error: invalid union tag\\n");`);
1331
- d.push(` }`);
1332
- break;
1333
- }
1334
- case "promise": {
1335
- // Promises box by REFERENCE (SCR_DYN_PROMISE — identity is the
1336
- // promise): promise<dyn> carries its ScrPromise directly (the
1337
- // payload is already a dyn value); any other inner boxes an
1338
- // ADAPTER promise whose settle callback converts the payload
1339
- // (rejections copy raw inside the runtime's cb-waiter machinery).
1340
- if (t.inner.kind === "dyn") {
1341
- d.push(` return scr_dyn_new_promise(v);`);
1342
- break;
1343
- }
1344
- d.push(` return scr_dyn_new_promise_adapting(v, &${promiseDynAdapterHelper(emitter, t.inner)});`);
1345
- break;
1346
- }
1347
- default: {
1348
- // Runtime HANDLE kinds box by REFERENCE (identity — no copy):
1349
- // scr_dyn_new_handle retains the borrowed operand through the
1350
- // tag's installed ops.
1351
- const h = DYN_HANDLE_KINDS.get(t.kind);
1352
- if (h) {
1353
- d.push(` return scr_dyn_new_handle(v, ${h.tag});`);
1354
- break;
1355
- }
1356
- throw new InternalCompilerError(`emitter bug: to-dyn of unsupported type ${t.kind}`);
1357
- }
1358
- }
1359
- d.push(`}`, ``);
1360
- emitter.walkerDefs.push(...d);
1361
- if (sourceAccessor) {
1362
- emitter.walkerDefs.push(`static ScrDyn *${sourceAccessor.name}(void *v, bool materialize) {`, ` if (materialize) return ${name}((${cType(t).trim()})v);`, ` ${sourceAccessor.release}(v);`, ` return NULL;`, `}`, ``);
1363
- }
1364
- return name;
1365
- }
1366
- /** The checked-dynamic tree-promise settle adapter for one fulfillment payload type:
1367
- * `static void sc_pda_<n>(ScrPromise *dst, ScrPromise *src)` — read
1368
- * src's fulfilled payload by its compile-time kind, convert it to a dyn
1369
- * value, and fulfill dst with it (scr_dyn_new_promise_adapting's
1370
- * callback; rejections never reach an adapter — the runtime copies them
1371
- * raw). Interned per inner typeKey. */
1372
- function promiseDynAdapterHelper(emitter, inner) {
1373
- const key = typeKey(inner);
1374
- const existing = emitter.promiseDynAdapters.get(key);
1375
- if (existing)
1376
- return existing;
1377
- const name = `sc_pda_${emitter.promiseDynAdapters.size}`;
1378
- emitter.promiseDynAdapters.set(key, name);
1379
- const sig = `static void ${name}(ScrPromise *dst, ScrPromise *src)`;
1380
- emitter.walkerProtos.push(`${sig}; /* dyn-box settle adapter for promise<${key}> */`);
1381
- const d = [`${sig} { /* dyn-box settle adapter for promise<${key}> */`];
1382
- const fulfill = (expr) => ` scr_promise_fulfill_ref(dst, ${expr}, scr_dyn_retain_v, scr_dyn_release_v, NULL);`;
1383
- switch (inner.kind) {
1384
- case "void":
1385
- case "undefinedT":
1386
- d.push(` (void)src;`);
1387
- d.push(fulfill(`scr_dyn_retain(scr_dyn_undefined())`));
1388
- break;
1389
- case "nullT":
1390
- d.push(` (void)src;`);
1391
- d.push(fulfill(`scr_dyn_new_null()`));
1392
- break;
1393
- case "f64":
1394
- d.push(fulfill(`scr_dyn_new_num(scr_promise_payload_f64(src))`));
1395
- break;
1396
- case "bool":
1397
- d.push(fulfill(`scr_dyn_new_bool(scr_promise_payload_bool(src))`));
1398
- break;
1399
- case "string":
1400
- d.push(` ScrStr *s = scr_promise_payload_str(src);`);
1401
- d.push(` ScrDyn *dv = scr_dyn_new_str(s); /* retains s */`);
1402
- d.push(` scr_str_release(s);`);
1403
- d.push(fulfill(`dv`));
1404
- break;
1405
- default: {
1406
- // Ref-payload inners (records, arrays, bytes, %Error, unions,
1407
- // nested promises, handles): extract (+1 via the stored retain),
1408
- // convert through the shared to-dyn spelling, release the extract.
1409
- d.push(` ${cDecl(inner, "pv")} = (${cType(inner).trim()})scr_promise_payload_ref(src);`);
1410
- d.push(` ScrDyn *dv = ${toDynExprC(emitter, inner, "pv")};`);
1411
- if (isRefCounted(inner))
1412
- d.push(` ${releaseCallC(inner, "pv")};`);
1413
- d.push(fulfill(`dv`));
1414
- break;
1415
- }
1416
- }
1417
- d.push(`}`, ``);
1418
- emitter.walkerDefs.push(...d);
1419
- return name;
1420
- }
1421
- /* ── the checked-dynamic function boundary (ir.ts) ─────────────────
1422
- * Three interned per-signature helpers:
1423
- *
1424
- * sc_dfk_<n> — the CALL THUNK a dyn-boxed closure carries: validate
1425
- * each dyn argument into the declared param type (JS arity: extras
1426
- * ignored, missing args are the undefined dyn value — a param type
1427
- * the undefined value fails checks throws the path-annotated
1428
- * TypeError), call through the closure, convert the result back to a
1429
- * dyn value (+1).
1430
- *
1431
- * sc_dfb_<n> — the BOX builder dynFrom emits: a fresh SCR_DYN_FUNC
1432
- * node carrying the retained closure, the thunk, the arity, the
1433
- * interned signature key (typeKey — dynCheck's exact-unwrap fast
1434
- * path), and the best-effort name.
1435
- *
1436
- * sc_dfa_<n> — the ADAPTER a func-targeted dynCheck wraps a
1437
- * NON-identical boxed signature in: a closure of the TARGET type
1438
- * whose body converts each typed argument INTO dyn, calls the boxed
1439
- * thunk, and validates the dyn result into the target's return type.
1440
- */
1441
- /** The dyn argument spelling of one static value (thunk results, adapter
1442
- * arguments): dyn passes through (+1 via retain — callers own the
1443
- * result uniformly), funcs box (anonymous — the static name is gone by
1444
- * the time a value flows through an adapter; SEMANTICS.md), everything
1445
- * else rides the toDyn converter. `expr` is BORROWED in every arm. */
1446
- function toDynExprC(emitter, t, expr) {
1447
- if (t.kind === "dyn")
1448
- return `scr_dyn_retain(${expr})`;
1449
- if (t.kind === "func")
1450
- return `${emitter.dynFuncBoxHelper(t)}(${expr}, NULL)`;
1451
- // An island value wraps by reference (scalar-normalizing) — the
1452
- // jsval-returning callback shape of the routed-dispatch lane.
1453
- if (t.kind === "jsval")
1454
- return `scr_dyn_from_jsval(${expr})`;
1455
- return `${emitter.toDynHelper(t)}(${expr})`;
1456
- }
1457
- /** The call thunk for one closure signature (see the block comment). */
1458
- function dynFuncThunkHelper(emitter, t) {
1459
- const key = typeKey(t);
1460
- const existing = emitter.dynFuncThunks.get(key);
1461
- if (existing)
1462
- return existing;
1463
- const name = `sc_dfk_${emitter.dynFuncThunks.size}`;
1464
- emitter.dynFuncThunks.set(key, name);
1465
- const sig = `static ScrDyn *${name}(ScrClosure *c, ScrDyn *const *args, size_t argc)`;
1466
- emitter.walkerProtos.push(`${sig}; /* dyn call thunk for ${key} */`);
1467
- const d = [`${sig} { /* dyn call thunk for ${key} */`];
1468
- if (t.params.length === 0)
1469
- d.push(` (void)args;`);
1470
- d.push(` (void)argc;`);
1471
- t.params.forEach((p, i) => {
1472
- // JS arity: a missing argument IS the undefined dyn value; the
1473
- // param's own check decides whether that flies (dyn params take
1474
- // anything; a number param throws the catchable TypeError).
1475
- d.push(` ${cDecl(p, `a${i}`)};`);
1476
- d.push(` {`);
1477
- d.push(` const ScrDyn *ad = ${i} < argc ? args[${i}] : scr_dyn_undefined();`);
1478
- if (p.kind === "dyn") {
1479
- d.push(` a${i} = scr_dyn_retain((ScrDyn *)ad);`);
1480
- }
1481
- else if (p.kind === "jsval") {
1482
- // A checker-'any' param: the dyn argument enters the island —
1483
- // wrapped cells unwrap by reference, data deep-copies, boxed
1484
- // functions cross through the host shim; a kind with no crossing
1485
- // throws the catchable TypeError (NULL + pending).
1486
- d.push(` a${i} = scr_jsval_from_dyn(ad);`);
1487
- const undo = t.params
1488
- .slice(0, i)
1489
- .flatMap((q, j) => (isRefCounted(q) ? [`${releaseCallC(q, `a${j}`)};`] : []));
1490
- d.push(` if (!a${i}) { ${undo.join(" ")}${undo.length > 0 ? " " : ""}return NULL; }`);
1491
- }
1492
- else {
1493
- d.push(` ScrDynPath pp = { NULL, NULL, ${i} };`);
1494
- d.push(` a${i} = ${emitter.dynCheckHelper(p)}(ad, &pp);`);
1495
- const undo = t.params
1496
- .slice(0, i)
1497
- .flatMap((q, j) => (isRefCounted(q) ? [`${releaseCallC(q, `a${j}`)};`] : []));
1498
- d.push(` if (scr_exc_pending()) { ${undo.join(" ")}${undo.length > 0 ? " " : ""}return NULL; }`);
1499
- }
1500
- d.push(` }`);
1501
- });
1502
- // VARIADIC (rest-marked) signatures: one extra trailing dyn-array
1503
- // param carries the call's arguments from index params.length on —
1504
- // the mustCall wrapper's `arguments`, a JS `...args`. Built fresh per
1505
- // call (+1, moved into the callee like every param).
1506
- if (t.rest) {
1507
- d.push(` ScrDyn *rest = scr_dyn_new_arr();`);
1508
- d.push(` for (size_t ri = ${t.argumentsAll ? 0 : t.params.length}; ri < argc; ri++) {`);
1509
- d.push(` scr_dyn_arr_push(rest, scr_dyn_retain((ScrDyn *)args[ri]));`);
1510
- d.push(` }`);
1511
- }
1512
- // The closure CONSUMES its params (+1 each moved in — exactly what the
1513
- // builders above returned).
1514
- const castParams = ["ScrClosure *", ...t.params.map((p) => cType(p).trim()), ...(t.rest ? ["ScrDyn *"] : [])].join(", ");
1515
- const call = `((${cType(t.ret).trim()} (*)(${castParams}))c->fn)(${["c", ...t.params.map((_, i) => `a${i}`), ...(t.rest ? ["rest"] : [])].join(", ")})`;
1516
- if (t.ret.kind === "void") {
1517
- d.push(` ${call};`);
1518
- d.push(` if (scr_exc_pending()) return NULL;`);
1519
- d.push(` return scr_dyn_retain(scr_dyn_undefined());`);
1520
- }
1521
- else if (t.ret.kind === "dyn") {
1522
- d.push(` ScrDyn *r = ${call};`);
1523
- d.push(` if (scr_exc_pending()) return NULL;`);
1524
- d.push(` return r;`);
1525
- }
1526
- else {
1527
- d.push(` ${cDecl(t.ret, "r")} = ${call};`);
1528
- d.push(` if (scr_exc_pending()) return NULL;`);
1529
- d.push(` ScrDyn *out = ${toDynExprC(emitter, t.ret, "r")};`);
1530
- if (isRefCounted(t.ret))
1531
- d.push(` ${releaseCallC(t.ret, "r")};`);
1532
- d.push(` return out;`);
1533
- }
1534
- d.push(`}`, ``);
1535
- emitter.walkerDefs.push(...d);
1536
- return name;
1537
- }
1538
- /** The box builder dynFrom emits for one closure signature. */
1539
- export function dynFuncBoxHelper(emitter, t) {
1540
- const key = typeKey(t);
1541
- const existing = emitter.dynFuncBoxes.get(key);
1542
- if (existing)
1543
- return existing;
1544
- const name = `sc_dfb_${emitter.dynFuncBoxes.size}`;
1545
- emitter.dynFuncBoxes.set(key, name);
1546
- const sig = `static ScrDyn *${name}(ScrClosure *v, const char *fname)`;
1547
- emitter.walkerProtos.push(`${sig}; /* box ${key} into dyn */`);
1548
- const thunk = dynFuncThunkHelper(emitter, t);
1549
- const sigLit = cStringLiteral(Buffer.from(key, "utf8"));
1550
- emitter.walkerDefs.push(`${sig} { /* box ${key} into dyn */`, ` return scr_dyn_new_func(scr_closure_retain(v), &${thunk}, ${t.params.length}, ${sigLit}, fname);`, `}`, ``);
1551
- return name;
1552
- }
1553
- /** The adapter closure body for one TARGET signature: the emitted C
1554
- * function a func-targeted dynCheck wraps a non-identical boxed
1555
- * signature in. caps[0] is an untraced obj-box owning the dyn function
1556
- * value. */
1557
- function dynFuncAdapterHelper(emitter, t) {
1558
- const key = typeKey(t);
1559
- const existing = emitter.dynFuncAdapters.get(key);
1560
- if (existing)
1561
- return existing;
1562
- const name = `sc_dfa_${emitter.dynFuncAdapters.size}`;
1563
- emitter.dynFuncAdapters.set(key, name);
1564
- const params = ["ScrClosure *sc_env", ...t.params.map((p, i) => cDecl(p, `a${i}`))].join(", ");
1565
- const sig = `static ${cType(t.ret)}${cType(t.ret).endsWith("*") ? "" : " "}${name}(${params})`;
1566
- emitter.walkerProtos.push(`${sig}; /* dyn fn adapter to ${key} */`);
1567
- const dummy = t.ret.kind === "void" ? "" : t.ret.kind === "f64" ? "0" : t.ret.kind === "bool" ? "false" : "NULL";
1568
- const d = [`${sig} { /* dyn fn adapter to ${key} */`];
1569
- d.push(` ScrDyn *sc_fn = (ScrDyn *)scr_box_get_ref(sc_env->caps[0]); /* +1 */`);
1570
- // The adapter OWNS its params (closure ABI); each converts to a dyn
1571
- // argument (toDynExprC borrows) and releases.
1572
- if (t.params.length > 0) {
1573
- d.push(` ScrDyn *sc_args[${t.params.length}];`);
1574
- t.params.forEach((p, i) => {
1575
- d.push(` sc_args[${i}] = ${toDynExprC(emitter, p, `a${i}`)};`);
1576
- if (isRefCounted(p))
1577
- d.push(` ${releaseCallC(p, `a${i}`)};`);
1578
- });
1579
- }
1580
- // The kind is FUNC by construction (the dynCheck that built this
1581
- // adapter tested it), so `what` is unreachable — spelled anyway.
1582
- d.push(` ScrDyn *sc_r = scr_dyn_call(sc_fn, ${t.params.length > 0 ? "sc_args" : "NULL"}, ${t.params.length}, "value");`);
1583
- d.push(` scr_dyn_release(sc_fn);`);
1584
- t.params.forEach((_, i) => d.push(` scr_dyn_release(sc_args[${i}]);`));
1585
- d.push(` if (scr_exc_pending()) return ${dummy};`.replace("return ;", "return;"));
1586
- if (t.ret.kind === "void") {
1587
- d.push(` scr_dyn_release(sc_r);`);
1588
- d.push(` return;`);
1589
- }
1590
- else if (t.ret.kind === "dyn") {
1591
- d.push(` return sc_r;`);
1592
- }
1593
- else {
1594
- // Validate the dyn result into the target's return type — a lying
1595
- // wrapper throws the catchable TypeError here (path "$"), exactly
1596
- // the dynCheck stance; the dummy result rides the pending unwind.
1597
- d.push(` ${cDecl(t.ret, "out")} = ${emitter.dynCheckHelper(t.ret)}(sc_r, NULL);`);
1598
- d.push(` scr_dyn_release(sc_r);`);
1599
- d.push(` return out;`);
1600
- }
1601
- d.push(`}`, ``);
1602
- emitter.walkerDefs.push(...d);
1603
- return name;
1604
- }
1605
- /** The emitted dynamic-keyed READ helper for one (shape, result type):
1606
- * `static <T> sc_rkg_<n>(<struct> *r, ScrStr *k)` — declared fields
1607
- * answer first (string comparisons in canonical order; the frontend
1608
- * proved each surfaces as T: identity, a to-dyn conversion, or an
1609
- * arm-into-union wrap), then the overflow map on index-signature shapes.
1610
- * A MISSING key yields the undefined dyn value (T dyn), the undefined
1611
- * arm (T undefined-armed union), or TRAPS with the key text (the array
1612
- * OOB policy — the checker claimed T and no undefined is representable).
1613
- * Borrows both; refcounted results are owned (+1). */
1614
- export function recordKeyGetHelper(emitter, shapeId, t, overflowOnly = false) {
1615
- const key = `${shapeId}|${typeKey(t)}${overflowOnly ? "|ovf" : ""}`;
1616
- const existing = emitter.recordKeyGetFns.get(key);
1617
- if (existing)
1618
- return existing;
1619
- const shape = emitter.recordsById.get(shapeId);
1620
- if (!shape)
1621
- throw new InternalCompilerError(`emitter bug: keyed read of unknown shape ${shapeId}`);
1622
- const name = `sc_rkg_${emitter.recordKeyGetFns.size}`;
1623
- emitter.recordKeyGetFns.set(key, name);
1624
- const struct = mangleRecordStruct(shapeId);
1625
- const sig = `static ${cType(t)}${cType(t).endsWith("*") ? "" : " "}${name}(${struct} *r, ScrStr *k)`;
1626
- emitter.walkerProtos.push(`${sig}; /* r[k] on ${shapeId} as ${typeKey(t)} */`);
1627
- const d = [`${sig} { /* r[k] on ${shapeId} as ${typeKey(t)} */`];
1628
- // How a value of type `vt` (a field, or the overflow hit) surfaces as T.
1629
- const surface = (vt, expr, owned) => {
1630
- if (typeEquals(vt, t)) {
1631
- return owned || !isRefCounted(vt) ? expr : retainCallC(vt, expr);
1632
- }
1633
- if (t.kind === "dyn") {
1634
- // toDyn borrows — an owned operand would leak; callers pass borrowed.
1635
- return `${emitter.toDynHelper(vt)}(${expr})`;
1636
- }
1637
- if (t.kind === "union") {
1638
- const def = emitter.unionsById.get(t.unionId);
1639
- const tag = def?.arms.findIndex((a) => typeEquals(a, vt)) ?? -1;
1640
- if (tag < 0)
1641
- throw new InternalCompilerError(`emitter bug: keyed read arm for ${typeKey(vt)} in ${typeKey(t)}`);
1642
- if (vt.kind === "f64")
1643
- return `scr_union_new_f64(${tag}, ${expr})`;
1644
- if (vt.kind === "bool")
1645
- return `scr_union_new_bool(${tag}, ${expr})`;
1646
- const rc = vAdapters(vt);
1647
- const payload = owned ? expr : retainCallC(vt, expr);
1648
- return `scr_union_new_ref(${tag}, ${payload}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(vt)})`;
1649
- }
1650
- throw new InternalCompilerError(`emitter bug: keyed read cannot surface ${typeKey(vt)} as ${typeKey(t)}`);
1651
- };
1652
- // overflowOnly (a literal key naming no declared field): the declared
1653
- // switch can never hit — only the overflow answers.
1654
- for (const f of overflowOnly ? [] : shape.fields) {
1655
- const lit = emitter.internLiteral(f.name);
1656
- d.push(` if (scr_str_eq(k, (ScrStr *)&${lit})) { /* ${cCommentText(f.name)} */`);
1657
- d.push(` return ${surface(f.type, `r->${mangleField(f.name)}`, false)};`);
1658
- d.push(` }`);
1659
- }
1660
- const iv = shape.indexValue;
1661
- if (iv) {
1662
- const m = `r->${OVERFLOW_MEMBER}`;
1663
- if (iv.kind === "f64" || iv.kind === "bool") {
1664
- const acc = iv.kind === "f64" ? "f64" : "bool";
1665
- d.push(` ${cDecl(iv, "hit")};`);
1666
- d.push(` if (scr_map_get_str_${acc}(${m}, k, &hit)) {`);
1667
- d.push(` return ${surface(iv, "hit", true)};`);
1668
- d.push(` }`);
1669
- }
1670
- else {
1671
- d.push(` ${cDecl(iv, "hit")} = (${cType(iv).trim()})scr_map_get_str_ref(${m}, k);`);
1672
- d.push(` if (hit) {`);
1673
- if (typeEquals(iv, t)) {
1674
- d.push(` return hit; /* get returned +1 */`);
1675
- }
1676
- else if (t.kind === "union") {
1677
- d.push(` return ${surface(iv, "hit", true)};`);
1678
- }
1679
- else {
1680
- throw new InternalCompilerError(`emitter bug: keyed read overflow ${typeKey(iv)} as ${typeKey(t)}`);
1681
- }
1682
- d.push(` }`);
1683
- }
1684
- }
1685
- // The miss path.
1686
- if (t.kind === "dyn") {
1687
- d.push(` return scr_dyn_retain(scr_dyn_undefined());`);
1688
- }
1689
- else if (t.kind === "union" && undefinedArmTag(t, emitter.unionsById) >= 0) {
1690
- d.push(` return ${emitter.unitInstanceRef(t.unionId, undefinedArmTag(t, emitter.unionsById))};`);
1691
- }
1692
- else {
1693
- // JS would answer undefined; T has no way to say it (the checker
1694
- // claimed T without noUncheckedIndexedAccess) — trap like an array
1695
- // OOB read instead of corrupting a typed slot (SEMANTICS.md).
1696
- d.push(` scr_trap_fmt("scriptc: TypeError: record has no key '%.*s' (typed '${dynDesc(t, emitter.recordsById, emitter.unionsById)}' — no undefined is representable)\\n", (int)k->len, k->data);`);
1697
- }
1698
- d.push(`}`, ``);
1699
- emitter.walkerDefs.push(...d);
1700
- return name;
1701
- }
1702
- /** The emitted dynamic-keyed WRITE helper for one index-signature shape:
1703
- * `static void sc_rks_<n>(<struct> *r, ScrStr *k, <V> v)` — a declared
1704
- * key writes THROUGH to the struct slot (dyn values validate against the
1705
- * field's type first via the dynCheck walker: a mismatch throws the
1706
- * catchable TypeError and leaves the field untouched — JS would store
1707
- * anything, the documented divergence; typed values store directly),
1708
- * an undeclared key inserts/replaces in the overflow map. Borrows r and
1709
- * k; OWNS v (+1 moves in — released on the validation-failure path). */
1710
- export function recordKeySetHelper(emitter, shapeId) {
1711
- const existing = emitter.recordKeySetFns.get(shapeId);
1712
- if (existing)
1713
- return existing;
1714
- const shape = emitter.recordsById.get(shapeId);
1715
- // Signature-free shapes dispatch over their (one-typed) declared
1716
- // fields and TRAP on a miss (scr_record_key_miss — JS would add the
1717
- // property, which a monomorphic struct cannot); overflow shapes keep
1718
- // the map insert tail.
1719
- const iv = shape?.indexValue ?? shape?.fields[0]?.type;
1720
- if (!shape || !iv)
1721
- throw new InternalCompilerError(`emitter bug: keyed write on field-free non-overflow shape ${shapeId}`);
1722
- const name = `sc_rks_${emitter.recordKeySetFns.size}`;
1723
- emitter.recordKeySetFns.set(shapeId, name);
1724
- const struct = mangleRecordStruct(shapeId);
1725
- const sig = `static void ${name}(${struct} *r, ScrStr *k, ${cDecl(iv, "v")})`;
1726
- emitter.walkerProtos.push(`${sig}; /* r[k] = v on ${shapeId} */`);
1727
- const d = [`${sig} { /* r[k] = v on ${shapeId} */`];
1728
- for (const f of shape.fields) {
1729
- const lit = emitter.internLiteral(f.name);
1730
- const member = `r->${mangleField(f.name)}`;
1731
- d.push(` if (scr_str_eq(k, (ScrStr *)&${lit})) { /* ${cCommentText(f.name)} */`);
1732
- if (iv.kind === "dyn" && shape.indexValue) {
1733
- const keyLit = cStringLiteral(Buffer.from(f.name, "utf8"));
1734
- d.push(` ScrDynPath p = { NULL, ${keyLit}, 0 };`);
1735
- d.push(` ${cDecl(f.type, "nv")} = ${emitter.dynCheckHelper(f.type)}(v, &p);`);
1736
- d.push(` scr_dyn_release(v);`);
1737
- d.push(` if (scr_exc_pending()) return; /* mismatched write: TypeError, field untouched */`);
1738
- d.push(` ${isRefCounted(f.type) ? `if (${member}) ${releaseCallC(f.type, member)};` : `(void)0;`}`);
1739
- d.push(` ${member} = nv;`);
1740
- }
1741
- else {
1742
- // typeEquals(f.type, iv) — the frontend fences everything else.
1743
- if (isRefCounted(f.type)) {
1744
- d.push(` if (${member}) ${releaseCallC(f.type, member)};`);
1745
- }
1746
- d.push(` ${member} = v;`);
1747
- }
1748
- d.push(` return;`);
1749
- d.push(` }`);
1750
- }
1751
- if (!shape.indexValue) {
1752
- // The MISS on a fixed shape: release the moved-in value, throw the
1753
- // catchable TypeError naming the key (JS would add the property —
1754
- // the documented monomorphic-struct divergence).
1755
- if (isRefCounted(iv))
1756
- d.push(` if (v) ${releaseCallC(iv, "v")};`);
1757
- d.push(` scr_record_key_miss(k);`);
1758
- }
1759
- else {
1760
- const m = `r->${OVERFLOW_MEMBER}`;
1761
- if (iv.kind === "f64" || iv.kind === "bool") {
1762
- d.push(` scr_map_set_str_${iv.kind === "f64" ? "f64" : "bool"}(${m}, k, v);`);
1763
- }
1764
- else {
1765
- d.push(` scr_map_set_str_ref(${m}, k, v); /* v moves in */`);
1766
- }
1767
- }
1768
- d.push(`}`, ``);
1769
- emitter.walkerDefs.push(...d);
1770
- return name;
1771
- }
1772
- //# sourceMappingURL=walkers.js.map