@scriptc/compiler 0.0.36 → 0.1.2

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 (256) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +52 -22
  2. package/ambient/scriptc-overrides.d.ts +0 -7
  3. package/ambient/scriptc.d.ts +3 -2
  4. package/dist/backend/build-cache.js.map +1 -1
  5. package/dist/backend/c/async.js +24 -2
  6. package/dist/backend/c/async.js.map +1 -1
  7. package/dist/backend/c/c-emitter.d.ts +22 -10
  8. package/dist/backend/c/c-emitter.js +60 -15
  9. package/dist/backend/c/c-emitter.js.map +1 -1
  10. package/dist/backend/c/exprs.js +289 -55
  11. package/dist/backend/c/exprs.js.map +1 -1
  12. package/dist/backend/c/island.js.map +1 -1
  13. package/dist/backend/c/may-throw.js +3 -0
  14. package/dist/backend/c/may-throw.js.map +1 -1
  15. package/dist/backend/c/stmts.d.ts +3 -5
  16. package/dist/backend/c/stmts.js +76 -17
  17. package/dist/backend/c/stmts.js.map +1 -1
  18. package/dist/backend/c/types.js.map +1 -1
  19. package/dist/backend/c/walkers.js +36 -12
  20. package/dist/backend/c/walkers.js.map +1 -1
  21. package/dist/backend/external-c.d.ts +33 -0
  22. package/dist/backend/external-c.js +51 -0
  23. package/dist/backend/external-c.js.map +1 -0
  24. package/dist/backend/link-plan.d.ts +37 -0
  25. package/dist/backend/link-plan.js +26 -0
  26. package/dist/backend/link-plan.js.map +1 -0
  27. package/dist/backend/linker.d.ts +22 -0
  28. package/dist/backend/linker.js +236 -0
  29. package/dist/backend/linker.js.map +1 -0
  30. package/dist/backend/llvm/blocks.js.map +1 -1
  31. package/dist/backend/llvm/dyn.js +63 -3
  32. package/dist/backend/llvm/dyn.js.map +1 -1
  33. package/dist/backend/llvm/emitter.js +132 -26
  34. package/dist/backend/llvm/emitter.js.map +1 -1
  35. package/dist/backend/llvm/expr-async.js +85 -3
  36. package/dist/backend/llvm/expr-async.js.map +1 -1
  37. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  38. package/dist/backend/llvm/expr-calls.js.map +1 -1
  39. package/dist/backend/llvm/expr-containers.js +68 -54
  40. package/dist/backend/llvm/expr-containers.js.map +1 -1
  41. package/dist/backend/llvm/expr-context.d.ts +2 -1
  42. package/dist/backend/llvm/expr-control.js.map +1 -1
  43. package/dist/backend/llvm/expr-dispatch.js +2 -0
  44. package/dist/backend/llvm/expr-dispatch.js.map +1 -1
  45. package/dist/backend/llvm/expr-dynamic.js +6 -3
  46. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  47. package/dist/backend/llvm/expr-island.js.map +1 -1
  48. package/dist/backend/llvm/expr-primitives.d.ts +1 -1
  49. package/dist/backend/llvm/expr-primitives.js +20 -0
  50. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  51. package/dist/backend/llvm/expr-records.js.map +1 -1
  52. package/dist/backend/llvm/expr-stream-bridges.js +245 -10
  53. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  54. package/dist/backend/llvm/lib-dispatch.js +2 -0
  55. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  56. package/dist/backend/llvm/lib-shared.js +18 -0
  57. package/dist/backend/llvm/lib-shared.js.map +1 -1
  58. package/dist/backend/llvm/lib-stream.js +6 -3
  59. package/dist/backend/llvm/lib-stream.js.map +1 -1
  60. package/dist/backend/llvm/split.js.map +1 -1
  61. package/dist/backend/llvm/unsupported.js.map +1 -1
  62. package/dist/backend/llvm/walkers.js +31 -4
  63. package/dist/backend/llvm/walkers.js.map +1 -1
  64. package/dist/backend/native-codegen.d.ts +8 -1
  65. package/dist/backend/native-codegen.js +39 -25
  66. package/dist/backend/native-codegen.js.map +1 -1
  67. package/dist/backend/native-codegen.test.js +44 -4
  68. package/dist/backend/native-codegen.test.js.map +1 -1
  69. package/dist/backend/native-link-info.d.ts +1 -1
  70. package/dist/backend/native-link-info.js +42 -18
  71. package/dist/backend/native-link-info.js.map +1 -1
  72. package/dist/backend/native-toolchain.js.map +1 -1
  73. package/dist/backend/native-toolchain.test.js +5 -1
  74. package/dist/backend/native-toolchain.test.js.map +1 -1
  75. package/dist/backend/runtime-pack-targets.test.d.ts +1 -0
  76. package/dist/backend/runtime-pack-targets.test.js +54 -0
  77. package/dist/backend/runtime-pack-targets.test.js.map +1 -0
  78. package/dist/backend/runtime-pack.d.ts +5 -30
  79. package/dist/backend/runtime-pack.js +46 -141
  80. package/dist/backend/runtime-pack.js.map +1 -1
  81. package/dist/backend/runtime-pack.test.js +49 -14
  82. package/dist/backend/runtime-pack.test.js.map +1 -1
  83. package/dist/backend/targets.d.ts +63 -17
  84. package/dist/backend/targets.js +251 -35
  85. package/dist/backend/targets.js.map +1 -1
  86. package/dist/backend/targets.test.js +27 -5
  87. package/dist/backend/targets.test.js.map +1 -1
  88. package/dist/backend/vendor-archives.js.map +1 -1
  89. package/dist/compat/fetch-profile.js +4 -2
  90. package/dist/compat/fetch-profile.js.map +1 -1
  91. package/dist/coverage/report.js.map +1 -1
  92. package/dist/coverage/surface-manifest.js +22 -1
  93. package/dist/coverage/surface-manifest.js.map +1 -1
  94. package/dist/diagnostics/diagnostic.d.ts +6 -5
  95. package/dist/diagnostics/diagnostic.js +7 -6
  96. package/dist/diagnostics/diagnostic.js.map +1 -1
  97. package/dist/diagnostics/render.js.map +1 -1
  98. package/dist/ffi/ffi-manifest.js.map +1 -1
  99. package/dist/frontend/cjs-lexer.js.map +1 -1
  100. package/dist/frontend/dts-paths.js.map +1 -1
  101. package/dist/frontend/input-tracker.d.ts +10 -0
  102. package/dist/frontend/input-tracker.js +26 -3
  103. package/dist/frontend/input-tracker.js.map +1 -1
  104. package/dist/frontend/input-tracker.test.js +8 -1
  105. package/dist/frontend/input-tracker.test.js.map +1 -1
  106. package/dist/frontend/lib-contract.js.map +1 -1
  107. package/dist/frontend/lowering/array-values.d.ts +12 -0
  108. package/dist/frontend/lowering/array-values.js +76 -0
  109. package/dist/frontend/lowering/array-values.js.map +1 -0
  110. package/dist/frontend/lowering/callback-arg.js.map +1 -1
  111. package/dist/frontend/lowering/containers/bytes.d.ts +35 -0
  112. package/dist/frontend/lowering/containers/bytes.js +1021 -0
  113. package/dist/frontend/lowering/containers/bytes.js.map +1 -0
  114. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +17 -0
  115. package/dist/frontend/lowering/containers/string-and-regexp.js +345 -0
  116. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -0
  117. package/dist/frontend/lowering/expressions/evaluation-safety.d.ts +13 -0
  118. package/dist/frontend/lowering/expressions/evaluation-safety.js +76 -0
  119. package/dist/frontend/lowering/expressions/evaluation-safety.js.map +1 -0
  120. package/dist/frontend/lowering/expressions/object-literals.d.ts +44 -0
  121. package/dist/frontend/lowering/expressions/object-literals.js +1815 -0
  122. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -0
  123. package/dist/frontend/lowering/expressions/optional-chains.d.ts +31 -0
  124. package/dist/frontend/lowering/expressions/optional-chains.js +382 -0
  125. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -0
  126. package/dist/frontend/lowering/expressions/try-lower-expression.d.ts +7 -0
  127. package/dist/frontend/lowering/expressions/try-lower-expression.js +26 -0
  128. package/dist/frontend/lowering/expressions/try-lower-expression.js.map +1 -0
  129. package/dist/frontend/lowering/lib-boundary.js +7 -2
  130. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  131. package/dist/frontend/lowering/lower-array-sort.d.ts +22 -0
  132. package/dist/frontend/lowering/lower-array-sort.js +619 -0
  133. package/dist/frontend/lowering/lower-array-sort.js.map +1 -0
  134. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  135. package/dist/frontend/lowering/lower-async-iteration.d.ts +7 -0
  136. package/dist/frontend/lowering/lower-async-iteration.js +657 -0
  137. package/dist/frontend/lowering/lower-async-iteration.js.map +1 -0
  138. package/dist/frontend/lowering/lower-builtins.d.ts +18 -0
  139. package/dist/frontend/lowering/lower-builtins.js +379 -48
  140. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  141. package/dist/frontend/lowering/lower-calls.d.ts +16 -8
  142. package/dist/frontend/lowering/lower-calls.js +667 -91
  143. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  144. package/dist/frontend/lowering/lower-classes.d.ts +7 -13
  145. package/dist/frontend/lowering/lower-classes.js +128 -35
  146. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  147. package/dist/frontend/lowering/lower-comptime.js.map +1 -1
  148. package/dist/frontend/lowering/lower-containers.d.ts +1 -47
  149. package/dist/frontend/lowering/lower-containers.js +779 -2038
  150. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  151. package/dist/frontend/lowering/lower-event-emitter.js +51 -5
  152. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  153. package/dist/frontend/lowering/lower-exprs.d.ts +4 -78
  154. package/dist/frontend/lowering/lower-exprs.js +1128 -2409
  155. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  156. package/dist/frontend/lowering/lower-generators.d.ts +18 -3
  157. package/dist/frontend/lowering/lower-generators.js +145 -9
  158. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  159. package/dist/frontend/lowering/lower-inspect.js +50 -36
  160. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  161. package/dist/frontend/lowering/lower-island.d.ts +11 -4
  162. package/dist/frontend/lowering/lower-island.js +47 -10
  163. package/dist/frontend/lowering/lower-island.js.map +1 -1
  164. package/dist/frontend/lowering/lower-modules.js +52 -15
  165. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  166. package/dist/frontend/lowering/lower-node-module.d.ts +18 -0
  167. package/dist/frontend/lowering/lower-node-module.js +302 -0
  168. package/dist/frontend/lowering/lower-node-module.js.map +1 -0
  169. package/dist/frontend/lowering/lower-server.js +11 -1
  170. package/dist/frontend/lowering/lower-server.js.map +1 -1
  171. package/dist/frontend/lowering/lower-stmts.d.ts +5 -24
  172. package/dist/frontend/lowering/lower-stmts.js +811 -314
  173. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  174. package/dist/frontend/lowering/lower-stream.js +4 -4
  175. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  176. package/dist/frontend/lowering/lowerer.d.ts +109 -34
  177. package/dist/frontend/lowering/lowerer.js +1225 -62
  178. package/dist/frontend/lowering/lowerer.js.map +1 -1
  179. package/dist/frontend/lowering/optional-arguments.d.ts +9 -0
  180. package/dist/frontend/lowering/optional-arguments.js +57 -0
  181. package/dist/frontend/lowering/optional-arguments.js.map +1 -0
  182. package/dist/frontend/lowering/surfaces.d.ts +10 -2
  183. package/dist/frontend/lowering/surfaces.js +15 -3
  184. package/dist/frontend/lowering/surfaces.js.map +1 -1
  185. package/dist/frontend/npm-static-declarations.d.ts +35 -0
  186. package/dist/frontend/npm-static-declarations.js +506 -0
  187. package/dist/frontend/npm-static-declarations.js.map +1 -0
  188. package/dist/frontend/npm-static-declarations.test.d.ts +1 -0
  189. package/dist/frontend/npm-static-declarations.test.js +122 -0
  190. package/dist/frontend/npm-static-declarations.test.js.map +1 -0
  191. package/dist/frontend/npm-static.d.ts +2 -0
  192. package/dist/frontend/npm-static.js +26 -10
  193. package/dist/frontend/npm-static.js.map +1 -1
  194. package/dist/frontend/npm.d.ts +60 -0
  195. package/dist/frontend/npm.js +38 -4
  196. package/dist/frontend/npm.js.map +1 -1
  197. package/dist/frontend/npm.test.d.ts +1 -0
  198. package/dist/frontend/npm.test.js +50 -0
  199. package/dist/frontend/npm.test.js.map +1 -0
  200. package/dist/frontend/program.d.ts +3 -2
  201. package/dist/frontend/program.js +495 -68
  202. package/dist/frontend/program.js.map +1 -1
  203. package/dist/frontend/resolve.d.ts +10 -2
  204. package/dist/frontend/resolve.js +90 -14
  205. package/dist/frontend/resolve.js.map +1 -1
  206. package/dist/frontend/resolve.test.js +4 -1
  207. package/dist/frontend/resolve.test.js.map +1 -1
  208. package/dist/frontend/runtime-resolve.d.ts +22 -0
  209. package/dist/frontend/runtime-resolve.js +101 -0
  210. package/dist/frontend/runtime-resolve.js.map +1 -0
  211. package/dist/frontend/runtime-resolve.test.d.ts +1 -0
  212. package/dist/frontend/runtime-resolve.test.js +18 -0
  213. package/dist/frontend/runtime-resolve.test.js.map +1 -0
  214. package/dist/frontend/ts7/adapter.js +12 -13
  215. package/dist/frontend/ts7/adapter.js.map +1 -1
  216. package/dist/frontend/ts7/ast.js.map +1 -1
  217. package/dist/frontend/ts7/census-check.js +3 -3
  218. package/dist/frontend/ts7/census-check.js.map +1 -1
  219. package/dist/frontend/ts7/checker.d.ts +3 -0
  220. package/dist/frontend/ts7/checker.js +12 -3
  221. package/dist/frontend/ts7/checker.js.map +1 -1
  222. package/dist/frontend/ts7/enums.js.map +1 -1
  223. package/dist/frontend/ts7/program-adapter.js +42 -3
  224. package/dist/frontend/ts7/program-adapter.js.map +1 -1
  225. package/dist/frontend/type-mapper.js +120 -7
  226. package/dist/frontend/type-mapper.js.map +1 -1
  227. package/dist/index.d.ts +3 -3
  228. package/dist/index.js +50 -28
  229. package/dist/index.js.map +1 -1
  230. package/dist/ir/analysis.js.map +1 -1
  231. package/dist/ir/ir.d.ts +125 -41
  232. package/dist/ir/ir.js +82 -31
  233. package/dist/ir/ir.js.map +1 -1
  234. package/dist/ir/serialize.d.ts +1 -1
  235. package/dist/ir/serialize.js +1 -1
  236. package/dist/ir/validate.js +127 -95
  237. package/dist/ir/validate.js.map +1 -1
  238. package/dist/library/cache-primitives.js.map +1 -1
  239. package/dist/library/cache-reset.test.js.map +1 -1
  240. package/dist/library/compiler-self-identity.js.map +1 -1
  241. package/dist/library/fence-eval.js +3 -1
  242. package/dist/library/fence-eval.js.map +1 -1
  243. package/dist/library/int-infer.js +12 -1
  244. package/dist/library/int-infer.js.map +1 -1
  245. package/dist/library/int-infer.test.js +4 -4
  246. package/dist/library/int-infer.test.js.map +1 -1
  247. package/dist/library/library-cache.test.js +5 -5
  248. package/dist/library/library-profile.js.map +1 -1
  249. package/dist/library/sidecar-validate.js.map +1 -1
  250. package/dist/library/sidecar.js.map +1 -1
  251. package/dist/startup-cache.d.ts +9 -1
  252. package/dist/startup-cache.js +16 -1
  253. package/dist/startup-cache.js.map +1 -1
  254. package/dist/wasi-paths.js.map +1 -1
  255. package/package.json +18 -5
  256. package/surface-manifest.json +64 -8
@@ -1,4 +1,4 @@
1
- import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DATE_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, ffiClassType, ffiSourceParamTypes, FILEHANDLE_T, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, islandPromisePayloadTag, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isJsonSafeType, isRefCounted, isSupportedArrayElem, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, shapeHasAccessorSlots, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./ir.js";
1
+ import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DATE_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, ffiClassType, ffiSourceParamTypes, FILEHANDLE_T, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, islandPromisePayloadTag, isDynTypedRefType, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isJsonSafeType, isJsonStringifySafeType, isRefCounted, isSupportedArrayElem, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, shapeHasAccessorSlots, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./ir.js";
2
2
  /** Per-method signature for strIntrinsic: `argTypes` lists every argument
3
3
  * position (optional ones included); `minArgs` is how many may be omitted
4
4
  * from the end (backends fill the documented defaults). Exported for the
@@ -85,6 +85,22 @@ export const LIB_FN_SIGS = {
85
85
  "dyn.toString": { argTypes: [DYN, STRING, STRING], result: STRING },
86
86
  "dyn.defineProps": { argTypes: [DYN, DYN], result: DYN },
87
87
  "dyn.typeof": { argTypes: [DYN], result: STRING },
88
+ "module.registryInit": { argTypes: [F64], result: VOID },
89
+ "module.define": { argTypes: [F64, STRING, STRING, STRING, arrayOf(STRING), BOOL], result: VOID },
90
+ "module.enter": { argTypes: [F64], result: VOID },
91
+ "module.link": { argTypes: [F64, F64], result: VOID },
92
+ "module.finish": { argTypes: [F64], result: VOID },
93
+ "module.fail": { argTypes: [F64], result: VOID },
94
+ "module.filename": { argTypes: [F64], result: STRING },
95
+ "module.id": { argTypes: [F64], result: STRING },
96
+ "module.path": { argTypes: [F64], result: STRING },
97
+ "module.paths": { argTypes: [F64], result: arrayOf(STRING) },
98
+ "module.children": { argTypes: [F64], result: arrayOf(F64) },
99
+ "module.parent": { argTypes: [F64], result: F64 },
100
+ "module.loaded": { argTypes: [F64], result: BOOL },
101
+ "module.cacheGet": { argTypes: [STRING], result: F64 },
102
+ "module.cacheHas": { argTypes: [STRING], result: BOOL },
103
+ "module.cacheKeys": { argTypes: [], result: arrayOf(STRING) },
88
104
  "timers.setTimeout": { argTypes: [{ kind: "func", params: [], ret: VOID }, F64], result: VOID },
89
105
  "timers.setInterval": { argTypes: [{ kind: "func", params: [], ret: VOID }, F64], result: F64 },
90
106
  "timers.clearInterval": { argTypes: [F64], result: VOID },
@@ -937,6 +953,7 @@ export const LIB_FN_SIGS = {
937
953
  "writable.uncork": { argTypes: [null], result: VOID },
938
954
  "stream.destroy": { argTypes: [null], result: VOID },
939
955
  "stream.destroyErr": { argTypes: [null, null], result: VOID },
956
+ "stream.iteratorClose": { argTypes: [null], result: VOID },
940
957
  "stream.prop": { argTypes: [null, STRING], result: VOID },
941
958
  "stream.errored": { argTypes: [null], result: VOID },
942
959
  // node:assert: pass/negated/deep/hasMsg are frontend-computed bools; the
@@ -1118,6 +1135,9 @@ function isBuiltinErrorObject(t) {
1118
1135
  * TReturn channel, so call sites see the generator type. The one place
1119
1136
  * the body/call-site split is spelled out in the validator. */
1120
1137
  function callSiteReturnType(fn) {
1138
+ if (fn.async && fn.generator !== undefined) {
1139
+ return { kind: "generator", async: true, yieldT: fn.generator.yieldT, retT: fn.returnType, nextT: fn.generator.nextT };
1140
+ }
1121
1141
  if (fn.async)
1122
1142
  return { kind: "promise", inner: fn.returnType };
1123
1143
  if (fn.generator !== undefined) {
@@ -1132,9 +1152,6 @@ export function validateModule(mod) {
1132
1152
  if (functionsByName.has(fn.name)) {
1133
1153
  errors.push({ message: `duplicate function "${fn.name}"`, loc: fn.loc });
1134
1154
  }
1135
- if (fn.async && fn.generator !== undefined) {
1136
- errors.push({ message: `function "${fn.name}" is both async and a generator (async generators are fenced)`, loc: fn.loc });
1137
- }
1138
1155
  functionsByName.set(fn.name, fn);
1139
1156
  }
1140
1157
  const ffiByName = new Map();
@@ -1716,7 +1733,8 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
1716
1733
  const liveDynRefEligible = (type, seen = new Set()) => {
1717
1734
  if (type.kind === "record" ||
1718
1735
  type.kind === "array" ||
1719
- type.kind === "bytes") {
1736
+ type.kind === "bytes" ||
1737
+ isDynTypedRefType(type)) {
1720
1738
  return true;
1721
1739
  }
1722
1740
  if (type.kind !== "union" || seen.has(type.unionId))
@@ -1883,9 +1901,11 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
1883
1901
  break;
1884
1902
  }
1885
1903
  case "seqExpr": {
1886
- // Statements in an expression: straight-line writes only — no
1887
- // control flow, no jumps (the C emission point is mid-expression).
1888
- const allowed = new Set(["varDecl", "assign", "exprStmt", "fieldSet", "recordSet", "recordKeySet", "arraySet", "bytesSet", "block"]);
1904
+ // Statements in an expression cannot jump out of the expression,
1905
+ // but a local state branch is valid: optional array stores must
1906
+ // choose ARRAY_VALUE versus ARRAY_UNDEFINED before the final result
1907
+ // is evaluated. Nested blocks/ifs are checked recursively below.
1908
+ const allowed = new Set(["varDecl", "assign", "exprStmt", "fieldSet", "recordSet", "recordKeySet", "arraySet", "arraySetLength", "arraySetUndefined", "arrayDelete", "bytesSet", "block", "if"]);
1889
1909
  const flat = (ss) => {
1890
1910
  for (const s of ss) {
1891
1911
  if (!allowed.has(s.kind)) {
@@ -1896,6 +1916,13 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
1896
1916
  flat(s.body);
1897
1917
  continue;
1898
1918
  }
1919
+ if (s.kind === "if") {
1920
+ flat(s.then);
1921
+ if (s.else_)
1922
+ flat(s.else_);
1923
+ checkExpr(s.cond);
1924
+ continue;
1925
+ }
1899
1926
  checkStmt(s);
1900
1927
  }
1901
1928
  };
@@ -2320,6 +2347,27 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
2320
2347
  }
2321
2348
  break;
2322
2349
  }
2350
+ case "arrayHas": {
2351
+ checkExpr(e.arr);
2352
+ checkExpr(e.index);
2353
+ expectType(e.index, F64, "arrayHas index");
2354
+ if (!typeEquals(e.type, BOOL))
2355
+ err(`arrayHas result ${e.type.kind} != bool`, e.loc);
2356
+ if (e.arr.type.kind !== "array") {
2357
+ err(`arrayHas on non-array ${e.arr.type.kind}`, e.loc);
2358
+ }
2359
+ break;
2360
+ }
2361
+ case "arrayState": {
2362
+ checkExpr(e.arr);
2363
+ checkExpr(e.index);
2364
+ expectType(e.index, F64, "arrayState index");
2365
+ if (!typeEquals(e.type, F64))
2366
+ err(`arrayState result ${e.type.kind} != f64`, e.loc);
2367
+ if (e.arr.type.kind !== "array")
2368
+ err(`arrayState on non-array ${e.arr.type.kind}`, e.loc);
2369
+ break;
2370
+ }
2323
2371
  case "bytesNew": {
2324
2372
  if (e.type.kind !== "bytes") {
2325
2373
  err(`bytesNew of non-bytes type ${e.type.kind}`, e.loc);
@@ -2468,31 +2516,35 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
2468
2516
  const elem = e.receiver.type.elem;
2469
2517
  const sig = e.method === "push" || e.method === "unshift"
2470
2518
  ? { argTypes: e.args.map(() => elem), result: F64 }
2471
- : e.method === "pushSpread" || e.method === "unshiftSpread"
2519
+ : e.method === "pushSpread" || e.method === "concatSpread" || e.method === "unshiftSpread"
2472
2520
  ? { argTypes: [e.receiver.type], result: F64 }
2473
- : e.method === "pop"
2474
- ? { argTypes: [], result: elem }
2475
- : e.method === "indexOf"
2476
- ? { argTypes: [elem], result: F64 }
2477
- : e.method === "includes"
2478
- ? { argTypes: [elem], result: BOOL }
2479
- : e.method === "join"
2480
- ? { argTypes: [STRING], result: STRING }
2481
- : e.method === "slice"
2482
- ? { argTypes: [F64, F64], result: e.receiver.type }
2483
- : e.method === "toReversed"
2484
- ? { argTypes: [], result: e.receiver.type }
2485
- : e.method === "reverse"
2521
+ : e.method === "nextPresent"
2522
+ ? { argTypes: [F64], result: F64 }
2523
+ : e.method === "pop"
2524
+ ? { argTypes: [], result: e.type } // union-checked below
2525
+ : e.method === "indexOf"
2526
+ ? { argTypes: [elem], result: F64 }
2527
+ : e.method === "includes"
2528
+ ? { argTypes: [elem], result: BOOL }
2529
+ : e.method === "join"
2530
+ ? { argTypes: [STRING], result: STRING }
2531
+ : e.method === "slice"
2532
+ ? { argTypes: [F64, F64], result: e.receiver.type }
2533
+ : e.method === "toReversed"
2486
2534
  ? { argTypes: [], result: e.receiver.type }
2487
- : e.method === "toSpliced"
2488
- ? { argTypes: [F64, F64, e.receiver.type], result: e.receiver.type }
2489
- : e.method === "with"
2490
- ? { argTypes: [F64, elem], result: e.receiver.type }
2491
- : e.method === "splice"
2492
- ? { argTypes: [F64, F64], result: e.receiver.type }
2493
- : e.method === "shift"
2494
- ? { argTypes: [], result: e.type } // union-checked below
2495
- : { argTypes: [], result: F64 }; // length
2535
+ : e.method === "reverse"
2536
+ ? { argTypes: [], result: e.receiver.type }
2537
+ : e.method === "toSpliced"
2538
+ ? { argTypes: [F64, F64, e.receiver.type], result: e.receiver.type }
2539
+ : e.method === "with"
2540
+ ? { argTypes: [F64, elem], result: e.receiver.type }
2541
+ : e.method === "withUndefined"
2542
+ ? { argTypes: [F64], result: e.receiver.type }
2543
+ : e.method === "splice"
2544
+ ? { argTypes: [F64, F64], result: e.receiver.type }
2545
+ : e.method === "shift"
2546
+ ? { argTypes: [], result: e.type } // union-checked below
2547
+ : { argTypes: [], result: F64 }; // length
2496
2548
  if (e.method === "join" &&
2497
2549
  elem.kind !== "f64" && elem.kind !== "string" && elem.kind !== "bool" &&
2498
2550
  !(elem.kind === "union" &&
@@ -2507,17 +2559,12 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
2507
2559
  // misjudge JS ===; the frontend fences these.
2508
2560
  err(`arrIntrinsic ${e.method} on union elements (frontend must reject)`, e.loc);
2509
2561
  }
2510
- if (e.method === "shift") {
2511
- // The result is the interned `elem | undefined` union (union
2512
- // elements are frontend-fenced, so the arms never collide).
2513
- if (elem.kind === "union") {
2514
- err("arrIntrinsic shift on union elements (frontend must reject)", e.loc);
2515
- }
2562
+ if (e.method === "shift" || e.method === "pop") {
2516
2563
  const rdef = e.type.kind === "union" ? unions.get(e.type.unionId) : undefined;
2517
2564
  if (!rdef ||
2518
- !rdef.arms.some((a) => a.kind === "undefinedT") ||
2519
- !rdef.arms.some((a) => typeEquals(a, elem))) {
2520
- err("arrIntrinsic shift result must be the elem|undefined union", e.loc);
2565
+ !rdef.arms.some((arm) => arm.kind === "undefinedT") ||
2566
+ !(elem.kind === "union" ? typeEquals(elem, e.type) : rdef.arms.some((arm) => typeEquals(arm, elem)))) {
2567
+ err(`arrIntrinsic ${e.method} result must be the elem|undefined union`, e.loc);
2521
2568
  }
2522
2569
  }
2523
2570
  // slice's indices and splice's count are optional (omitted args
@@ -4498,7 +4545,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
4498
4545
  if (e.fn.startsWith("readable.") || e.fn.startsWith("writable.") ||
4499
4546
  e.fn.startsWith("duplex.") || e.fn.startsWith("transform.") ||
4500
4547
  e.fn.startsWith("passthrough.") || e.fn === "stream.destroy" ||
4501
- e.fn === "stream.destroyErr" || e.fn === "stream.prop" ||
4548
+ e.fn === "stream.destroyErr" || e.fn === "stream.iteratorClose" || e.fn === "stream.prop" ||
4502
4549
  e.fn === "stream.errored" || e.fn === "stream.finished" ||
4503
4550
  e.fn === "stream.finishedDyn" || e.fn === "stream.pipeline" ||
4504
4551
  e.fn === "stream.pipelineDyn") {
@@ -4606,7 +4653,8 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
4606
4653
  if (e.fn === "readable.pause" || e.fn === "readable.resume" ||
4607
4654
  e.fn === "readable.unpipe" || e.fn === "writable.end" ||
4608
4655
  e.fn === "readable.setEncoding" || e.fn === "readable.pushEncoding" ||
4609
- e.fn === "stream.destroy" || e.fn === "stream.destroyErr") {
4656
+ e.fn === "stream.destroy" || e.fn === "stream.destroyErr" ||
4657
+ e.fn === "stream.iteratorClose") {
4610
4658
  if (!typeEquals(e.type, e.args[0].type)) {
4611
4659
  err(`libCall ${e.fn} must return its receiver's type (the chaining 'this')`, e.loc);
4612
4660
  }
@@ -4750,7 +4798,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
4750
4798
  // A dyn ROOT is the one non-static shape allowed: the runtime's dyn
4751
4799
  // walker serializes it (scr_dyn_format_j), no emitted serializer.
4752
4800
  if (e.value.type.kind !== "dyn" &&
4753
- !isJsonSafeType(e.value.type, (id) => records.get(id), (id) => unions.get(id))) {
4801
+ !isJsonStringifySafeType(e.value.type, (id) => records.get(id), (id) => unions.get(id))) {
4754
4802
  err(`jsonStringify of non-JSON-safe type ${e.value.type.kind}`, e.loc);
4755
4803
  }
4756
4804
  break;
@@ -4766,13 +4814,17 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
4766
4814
  // reads), which matches exactly the undefined arm.
4767
4815
  const jsonOk = (t) => isJsonSafeType(t, (id) => records.get(id), (id) => unions.get(id));
4768
4816
  const undefArmedOk = e.type.kind === "union" &&
4769
- (unions.get(e.type.unionId)?.arms.every((a) => a.kind === "undefinedT" || jsonOk(a)) ??
4817
+ (unions.get(e.type.unionId)?.arms.every((a) => a.kind === "undefinedT" ||
4818
+ jsonOk(a) ||
4819
+ isDynTypedRefType(a) ||
4820
+ DYN_HANDLE_KINDS.has(a.kind)) ??
4770
4821
  false);
4771
4822
  // bytes<u8> targets extract the checked-dynamic tree's bytes kind (a copy).
4772
4823
  const bytesOk = e.type.kind === "bytes" && e.type.elem === "u8";
4773
4824
  // The %Error root extracts the checked-dynamic tree's error encoding (the "%error"
4774
4825
  // marker object caughtToDyn builds) as a fresh runtime error.
4775
4826
  const errorOk = e.type.kind === "object" && e.type.className === "%Error";
4827
+ const classOk = isDynTypedRefType(e.type);
4776
4828
  // ADAPTABLE function targets unwrap or wrap the checked-dynamic tree's function
4777
4829
  // kind (the checked-dynamic function boundary, ir.ts).
4778
4830
  const funcOk = e.type.kind === "func" &&
@@ -4780,7 +4832,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
4780
4832
  // Runtime HANDLE targets unwrap the checked-dynamic tree's handle kind by tag (a
4781
4833
  // retained reference, no copy — DYN_HANDLE_KINDS).
4782
4834
  const handleOk = DYN_HANDLE_KINDS.has(e.type.kind);
4783
- if (!jsonOk(e.type) && !undefArmedOk && !bytesOk && !errorOk && !funcOk && !handleOk) {
4835
+ if (!jsonOk(e.type) && !undefArmedOk && !bytesOk && !errorOk && !classOk && !funcOk && !handleOk) {
4784
4836
  err(`dynCheck against non-JSON-representable type ${e.type.kind}`, e.loc);
4785
4837
  }
4786
4838
  break;
@@ -4859,17 +4911,19 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
4859
4911
  err(`genResume throw of a ${e.arg.type.kind} value`, e.loc);
4860
4912
  }
4861
4913
  }
4862
- // The result is the IteratorResult record { done: bool, value: V }
4914
+ // Sync resumes return IteratorResult directly; async resumes return
4915
+ // Promise<IteratorResult>. The record is { done: bool, value: V }
4863
4916
  // with V dyn (the any/unknown channel) or an undefined-armed union.
4864
- if (e.type.kind !== "record") {
4865
- err(`genResume result is ${e.type.kind}, not a record`, e.loc);
4917
+ const resultT = genT.async ? (e.type.kind === "promise" ? e.type.inner : null) : e.type;
4918
+ if (resultT?.kind !== "record") {
4919
+ err(`genResume result is ${typeKey(e.type)}, not ${genT.async ? "a promise of " : ""}a record`, e.loc);
4866
4920
  break;
4867
4921
  }
4868
- const rec = records.get(e.type.shapeId);
4922
+ const rec = records.get(resultT.shapeId);
4869
4923
  const doneF = rec?.fields.find((f) => f.name === "done");
4870
4924
  const valueF = rec?.fields.find((f) => f.name === "value");
4871
4925
  if (!rec || rec.fields.length !== 2 || doneF?.type.kind !== "bool" || valueF === undefined) {
4872
- err(`genResume result record ${e.type.shapeId} is not { done: bool, value: V }`, e.loc);
4926
+ err(`genResume result record ${resultT.shapeId} is not { done: bool, value: V }`, e.loc);
4873
4927
  break;
4874
4928
  }
4875
4929
  if (valueF.type.kind === "dyn")
@@ -5093,19 +5147,8 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
5093
5147
  let breakableDepth = 0;
5094
5148
  // Labeled jump targets, innermost last: every loop/switch/labeled-block
5095
5149
  // enters with its labels (possibly none) so `break lbl`/`continue lbl`
5096
- // can resolve to an enclosing entry — and so the finally backstop can
5097
- // compare the TARGET's position, not just the innermost depth.
5150
+ // can resolve to an enclosing entry.
5098
5151
  const labelTargets = [];
5099
- // Active try-with-finally regions: break/continue may not cross one, and
5100
- // NO jump may leave a finally BODY (the frontend fences both; this is the
5101
- // backstop). `return` crossing a region is modeled now (the backend's
5102
- // pending-return path), so returns are legal in tryBody/catchBody but
5103
- // still rejected inside finallyBody (they would replace a pending
5104
- // completion). Each entry records the loop/switch depths (and the label
5105
- // stack length) at region entry: a break whose target is at or below
5106
- // them would cross the finally.
5107
- const finallyRegions = [];
5108
- let finallyBlockDepth = 0;
5109
5152
  function checkStmts(stmts) {
5110
5153
  for (const s of stmts)
5111
5154
  checkStmt(s);
@@ -5119,12 +5162,11 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
5119
5162
  breakableDepth--;
5120
5163
  loopDepth--;
5121
5164
  }
5122
- /** The innermost enclosing target carrying `label`, or null — plus its
5123
- * index for the finally-region crossing check. */
5165
+ /** The innermost enclosing target carrying `label`, or null. */
5124
5166
  function labelTargetOf(label) {
5125
5167
  for (let i = labelTargets.length - 1; i >= 0; i--) {
5126
5168
  if (labelTargets[i].labels.includes(label))
5127
- return { entry: labelTargets[i], index: i };
5169
+ return labelTargets[i];
5128
5170
  }
5129
5171
  return null;
5130
5172
  }
@@ -5243,6 +5285,24 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
5243
5285
  }
5244
5286
  break;
5245
5287
  }
5288
+ case "arraySetLength": {
5289
+ checkExpr(s.arr);
5290
+ checkExpr(s.length);
5291
+ expectType(s.length, F64, "arraySetLength length");
5292
+ if (s.arr.type.kind !== "array") {
5293
+ err(`arraySetLength on non-array ${s.arr.type.kind}`, s.loc);
5294
+ }
5295
+ break;
5296
+ }
5297
+ case "arraySetUndefined":
5298
+ case "arrayDelete": {
5299
+ checkExpr(s.arr);
5300
+ checkExpr(s.index);
5301
+ expectType(s.index, F64, `${s.kind} index`);
5302
+ if (s.arr.type.kind !== "array")
5303
+ err(`${s.kind} on non-array ${s.arr.type.kind}`, s.loc);
5304
+ break;
5305
+ }
5246
5306
  case "bytesSet": {
5247
5307
  checkExpr(s.arr);
5248
5308
  checkExpr(s.index);
@@ -5403,67 +5463,39 @@ function validateFunction(fn, functions, ffiByName, classes, records, unions, gl
5403
5463
  err(`tryCatch catch binding without a catch body`, s.loc);
5404
5464
  }
5405
5465
  }
5406
- const guarded = s.finallyBody !== null;
5407
- if (guarded)
5408
- finallyRegions.push({ loopDepth, breakableDepth, labelLen: labelTargets.length });
5409
5466
  checkStmts(s.tryBody);
5410
5467
  if (s.catchBody)
5411
5468
  checkStmts(s.catchBody);
5412
- if (s.finallyBody) {
5413
- finallyBlockDepth++;
5469
+ if (s.finallyBody)
5414
5470
  checkStmts(s.finallyBody);
5415
- finallyBlockDepth--;
5416
- }
5417
- if (guarded)
5418
- finallyRegions.pop();
5419
5471
  break;
5420
5472
  }
5421
5473
  case "break": {
5422
- const region = finallyRegions[finallyRegions.length - 1];
5423
5474
  if (s.label !== undefined) {
5424
5475
  const target = labelTargetOf(s.label);
5425
5476
  if (!target)
5426
5477
  err(`break to unknown label "${s.label}"`, s.loc);
5427
- else if (region && target.index < region.labelLen) {
5428
- err(`labeled break crossing a finally block (frontend must reject)`, s.loc);
5429
- }
5430
5478
  break;
5431
5479
  }
5432
5480
  if (breakableDepth === 0)
5433
5481
  err(`break outside a loop or switch`, s.loc);
5434
- if (region && breakableDepth <= region.breakableDepth) {
5435
- err(`break crossing a finally block (frontend must reject)`, s.loc);
5436
- }
5437
5482
  break;
5438
5483
  }
5439
5484
  case "continue": {
5440
- const region = finallyRegions[finallyRegions.length - 1];
5441
5485
  if (s.label !== undefined) {
5442
5486
  const target = labelTargetOf(s.label);
5443
5487
  if (!target)
5444
5488
  err(`continue to unknown label "${s.label}"`, s.loc);
5445
- else if (target.entry.kind !== "loop") {
5489
+ else if (target.kind !== "loop") {
5446
5490
  err(`continue to non-loop label "${s.label}"`, s.loc);
5447
5491
  }
5448
- else if (region && target.index < region.labelLen) {
5449
- err(`labeled continue crossing a finally block (frontend must reject)`, s.loc);
5450
- }
5451
5492
  break;
5452
5493
  }
5453
5494
  if (loopDepth === 0)
5454
5495
  err(`continue outside a loop`, s.loc);
5455
- if (region && loopDepth <= region.loopDepth) {
5456
- err(`continue crossing a finally block (frontend must reject)`, s.loc);
5457
- }
5458
5496
  break;
5459
5497
  }
5460
5498
  case "return":
5461
- // Crossing OUT of a try/catch body guarded by a finally is modeled
5462
- // (the backend's pending-return path); a return inside the finally
5463
- // BODY itself is not (it would replace a pending completion).
5464
- if (finallyBlockDepth > 0) {
5465
- err(`return inside a finally body (frontend must reject)`, s.loc);
5466
- }
5467
5499
  if (s.value) {
5468
5500
  checkExpr(s.value);
5469
5501
  expectType(s.value, fn.returnType, "return value");