@scriptc/compiler 0.2.1 → 0.2.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 (193) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +59 -4
  2. package/dist/backend/llvm/dyn.d.ts +3 -0
  3. package/dist/backend/llvm/dyn.js +84 -12
  4. package/dist/backend/llvm/dyn.js.map +1 -1
  5. package/dist/backend/llvm/emitter.d.ts +4 -1
  6. package/dist/backend/llvm/emitter.js +20 -5
  7. package/dist/backend/llvm/emitter.js.map +1 -1
  8. package/dist/backend/llvm/emitter.test.js +9 -1
  9. package/dist/backend/llvm/emitter.test.js.map +1 -1
  10. package/dist/backend/llvm/expr-containers.js +5 -0
  11. package/dist/backend/llvm/expr-containers.js.map +1 -1
  12. package/dist/backend/llvm/expr-dynamic.js +30 -5
  13. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  14. package/dist/backend/llvm/expr-stream-bridges.js +70 -9
  15. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  16. package/dist/backend/llvm/expr-stream-callbacks.d.ts +2 -2
  17. package/dist/backend/llvm/expr-stream-callbacks.js +7 -57
  18. package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
  19. package/dist/backend/llvm/lib-dispatch.js +41 -3
  20. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  21. package/dist/backend/llvm/lib-filesystem.js +12 -9
  22. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  23. package/dist/backend/llvm/lib-shared.js +35 -1
  24. package/dist/backend/llvm/lib-shared.js.map +1 -1
  25. package/dist/backend/may-throw.js +4 -0
  26. package/dist/backend/may-throw.js.map +1 -1
  27. package/dist/backend/native-codegen.d.ts +1 -1
  28. package/dist/backend/native-codegen.js +4 -3
  29. package/dist/backend/native-codegen.js.map +1 -1
  30. package/dist/backend/native-codegen.test.js +11 -0
  31. package/dist/backend/native-codegen.test.js.map +1 -1
  32. package/dist/backend/target-diagnostics.d.ts +5 -0
  33. package/dist/backend/target-diagnostics.js +72 -1
  34. package/dist/backend/target-diagnostics.js.map +1 -1
  35. package/dist/backend/target-diagnostics.test.d.ts +1 -0
  36. package/dist/backend/target-diagnostics.test.js +68 -0
  37. package/dist/backend/target-diagnostics.test.js.map +1 -0
  38. package/dist/coverage/surface-manifest.js +5 -3
  39. package/dist/coverage/surface-manifest.js.map +1 -1
  40. package/dist/executable/executable-cache.d.ts +7 -3
  41. package/dist/executable/executable-cache.js +47 -11
  42. package/dist/executable/executable-cache.js.map +1 -1
  43. package/dist/executable/executable-cache.test.js +109 -2
  44. package/dist/executable/executable-cache.test.js.map +1 -1
  45. package/dist/executable/prepare.js +2 -1
  46. package/dist/executable/prepare.js.map +1 -1
  47. package/dist/frontend/builtin-modules.d.ts +1 -1
  48. package/dist/frontend/builtin-modules.js +1 -1
  49. package/dist/frontend/builtin-modules.js.map +1 -1
  50. package/dist/frontend/function-completion.d.ts +6 -0
  51. package/dist/frontend/function-completion.js +50 -0
  52. package/dist/frontend/function-completion.js.map +1 -0
  53. package/dist/frontend/lowering/abstract-equality.js +5 -1
  54. package/dist/frontend/lowering/abstract-equality.js.map +1 -1
  55. package/dist/frontend/lowering/checked-iterable-spread.d.ts +4 -0
  56. package/dist/frontend/lowering/checked-iterable-spread.js +30 -0
  57. package/dist/frontend/lowering/checked-iterable-spread.js.map +1 -0
  58. package/dist/frontend/lowering/checked-promise-all.d.ts +5 -0
  59. package/dist/frontend/lowering/checked-promise-all.js +31 -0
  60. package/dist/frontend/lowering/checked-promise-all.js.map +1 -0
  61. package/dist/frontend/lowering/class-callbacks.d.ts +1 -1
  62. package/dist/frontend/lowering/class-callbacks.js +7 -6
  63. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  64. package/dist/frontend/lowering/class-construction.d.ts +2 -0
  65. package/dist/frontend/lowering/class-construction.js +34 -5
  66. package/dist/frontend/lowering/class-construction.js.map +1 -1
  67. package/dist/frontend/lowering/class-descriptors.d.ts +1 -1
  68. package/dist/frontend/lowering/class-descriptors.js +12 -5
  69. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  70. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +25 -0
  71. package/dist/frontend/lowering/class-dynamic-dispatch.js +597 -78
  72. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  73. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +64 -2
  74. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  75. package/dist/frontend/lowering/class-instance-constructor.d.ts +1 -1
  76. package/dist/frontend/lowering/class-instance-constructor.js +11 -41
  77. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  78. package/dist/frontend/lowering/class-method-values.d.ts +16 -0
  79. package/dist/frontend/lowering/class-method-values.js +60 -29
  80. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  81. package/dist/frontend/lowering/class-prototypes.d.ts +5 -1
  82. package/dist/frontend/lowering/class-prototypes.js +69 -10
  83. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  84. package/dist/frontend/lowering/class-runtime-statics.d.ts +4 -4
  85. package/dist/frontend/lowering/class-runtime-statics.js +26 -8
  86. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -1
  87. package/dist/frontend/lowering/class-static-data.d.ts +1 -0
  88. package/dist/frontend/lowering/class-static-data.js +4 -2
  89. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  90. package/dist/frontend/lowering/containers/bytes.js +17 -4
  91. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  92. package/dist/frontend/lowering/containers/string-and-regexp.js +6 -1
  93. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  94. package/dist/frontend/lowering/deferred-module-initializers.d.ts +13 -0
  95. package/dist/frontend/lowering/deferred-module-initializers.js +410 -0
  96. package/dist/frontend/lowering/deferred-module-initializers.js.map +1 -0
  97. package/dist/frontend/lowering/deferred-module-initializers.test.d.ts +1 -0
  98. package/dist/frontend/lowering/deferred-module-initializers.test.js +92 -0
  99. package/dist/frontend/lowering/deferred-module-initializers.test.js.map +1 -0
  100. package/dist/frontend/lowering/expressions/object-literals.js +31 -1
  101. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  102. package/dist/frontend/lowering/expressions/optional-chains.js +3 -3
  103. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  104. package/dist/frontend/lowering/lower-builtins.d.ts +4 -9
  105. package/dist/frontend/lowering/lower-builtins.js +291 -51
  106. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  107. package/dist/frontend/lowering/lower-calls.js +283 -73
  108. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  109. package/dist/frontend/lowering/lower-classes.d.ts +5 -0
  110. package/dist/frontend/lowering/lower-classes.js +439 -25
  111. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  112. package/dist/frontend/lowering/lower-containers.d.ts +1 -1
  113. package/dist/frontend/lowering/lower-containers.js +39 -17
  114. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  115. package/dist/frontend/lowering/lower-exprs.d.ts +10 -6
  116. package/dist/frontend/lowering/lower-exprs.js +294 -129
  117. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  118. package/dist/frontend/lowering/lower-generators.js +5 -1
  119. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  120. package/dist/frontend/lowering/lower-inspect.js +15 -1
  121. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  122. package/dist/frontend/lowering/lower-island.js +4 -0
  123. package/dist/frontend/lowering/lower-island.js.map +1 -1
  124. package/dist/frontend/lowering/lower-island.test.d.ts +1 -0
  125. package/dist/frontend/lowering/lower-island.test.js +51 -0
  126. package/dist/frontend/lowering/lower-island.test.js.map +1 -0
  127. package/dist/frontend/lowering/lower-modules.d.ts +1 -3
  128. package/dist/frontend/lowering/lower-modules.js +186 -82
  129. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  130. package/dist/frontend/lowering/lower-modules.test.js +69 -1
  131. package/dist/frontend/lowering/lower-modules.test.js.map +1 -1
  132. package/dist/frontend/lowering/lower-stmts.js +100 -35
  133. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  134. package/dist/frontend/lowering/lower-stmts.test.d.ts +1 -0
  135. package/dist/frontend/lowering/lower-stmts.test.js +77 -0
  136. package/dist/frontend/lowering/lower-stmts.test.js.map +1 -0
  137. package/dist/frontend/lowering/lower-stream.js +2 -0
  138. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  139. package/dist/frontend/lowering/lower-url.d.ts +2 -1
  140. package/dist/frontend/lowering/lower-url.js +32 -9
  141. package/dist/frontend/lowering/lower-url.js.map +1 -1
  142. package/dist/frontend/lowering/lowerer.d.ts +26 -9
  143. package/dist/frontend/lowering/lowerer.js +218 -27
  144. package/dist/frontend/lowering/lowerer.js.map +1 -1
  145. package/dist/frontend/lowering/lowerer.test.js +38 -0
  146. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  147. package/dist/frontend/lowering/module-namespace-elements.d.ts +7 -0
  148. package/dist/frontend/lowering/module-namespace-elements.js +54 -0
  149. package/dist/frontend/lowering/module-namespace-elements.js.map +1 -0
  150. package/dist/frontend/lowering/object-factory-new.d.ts +4 -3
  151. package/dist/frontend/lowering/object-factory-new.js +27 -14
  152. package/dist/frontend/lowering/object-factory-new.js.map +1 -1
  153. package/dist/frontend/lowering/surfaces.d.ts +1 -0
  154. package/dist/frontend/lowering/surfaces.js +24 -12
  155. package/dist/frontend/lowering/surfaces.js.map +1 -1
  156. package/dist/frontend/lowering/text-decoder-encoding.js +3 -0
  157. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  158. package/dist/frontend/lowering/text-decoder-encoding.test.js +2 -1
  159. package/dist/frontend/lowering/text-decoder-encoding.test.js.map +1 -1
  160. package/dist/frontend/program.js +4 -2
  161. package/dist/frontend/program.js.map +1 -1
  162. package/dist/frontend/type-mapper.js +83 -14
  163. package/dist/frontend/type-mapper.js.map +1 -1
  164. package/dist/frontend/union-discriminants.js +22 -7
  165. package/dist/frontend/union-discriminants.js.map +1 -1
  166. package/dist/index.js +16 -10
  167. package/dist/index.js.map +1 -1
  168. package/dist/ir/ir.d.ts +27 -13
  169. package/dist/ir/ir.js +26 -2
  170. package/dist/ir/ir.js.map +1 -1
  171. package/dist/ir/serialize.js +21 -1
  172. package/dist/ir/serialize.js.map +1 -1
  173. package/dist/ir/serialize.test.js +21 -0
  174. package/dist/ir/serialize.test.js.map +1 -1
  175. package/dist/ir/traverse.d.ts +0 -3
  176. package/dist/ir/traverse.js +33 -20
  177. package/dist/ir/traverse.js.map +1 -1
  178. package/dist/ir/validate.js +56 -5
  179. package/dist/ir/validate.js.map +1 -1
  180. package/dist/ir/validate.test.js +17 -1
  181. package/dist/ir/validate.test.js.map +1 -1
  182. package/dist/library/compiler-self-identity.js +1 -1
  183. package/dist/library/compiler-self-identity.test.js +2 -2
  184. package/dist/library/compiler-self-identity.test.js.map +1 -1
  185. package/dist/library/int-infer.d.ts +2 -2
  186. package/dist/library/int-infer.js +10 -7
  187. package/dist/library/int-infer.js.map +1 -1
  188. package/dist/library/int-infer.test.js +44 -0
  189. package/dist/library/int-infer.test.js.map +1 -1
  190. package/dist/library/prepare.js +2 -1
  191. package/dist/library/prepare.js.map +1 -1
  192. package/package.json +20 -20
  193. package/surface-manifest.json +115 -13
@@ -201,6 +201,7 @@ declare var process: {
201
201
  umask(mask?: number): number;
202
202
  /* chdir(2) — failures throw Node's fs-shaped catchable error. */
203
203
  chdir(directory: string): void;
204
+ loadEnvFile(path?: string | URL | Uint8Array): void;
204
205
  /* The extra CLI arguments Node itself consumed (--expose-internals,
205
206
  * ...): a compiled binary consumed none, so this is always []. */
206
207
  readonly execArgv: string[];
@@ -1172,6 +1173,10 @@ declare module "node:fs" {
1172
1173
  export function openSync(path: string, flags: string): number;
1173
1174
  export function openSync(path: string, flags: number, mode?: number): number;
1174
1175
  export function closeSync(fd: number): void;
1176
+ export function fdatasyncSync(fd: number): void;
1177
+ export function ftruncateSync(fd: number, len?: number): void;
1178
+ export function readvSync(fd: number, buffers: Uint8Array[], position?: number | null): number;
1179
+ export function writevSync(fd: number, buffers: Uint8Array[], position?: number | null): number;
1175
1180
  /* Read into a caller buffer from the fd's current position when position
1176
1181
  * is omitted/null, or from a numeric byte position without advancing the
1177
1182
  * fd. Answers the byte count, 0 at EOF. */
@@ -1265,9 +1270,31 @@ declare module "fs/promises" {
1265
1270
  bytesWritten: number;
1266
1271
  buffer: T;
1267
1272
  }
1273
+ export interface FileReadvResult<T extends Uint8Array[]> {
1274
+ bytesRead: number;
1275
+ buffers: T;
1276
+ }
1277
+ export interface FileWritevResult<T extends Uint8Array[]> {
1278
+ bytesWritten: number;
1279
+ buffers: T;
1280
+ }
1281
+ export interface FileReadOptions<T extends Uint8Array = Buffer> {
1282
+ buffer?: T;
1283
+ offset?: number | null;
1284
+ length?: number | null;
1285
+ position?: number | null;
1286
+ }
1268
1287
  export interface FileHandle extends AsyncDisposable {
1269
1288
  readonly fd: number;
1270
1289
  close(): Promise<void>;
1290
+ sync(): Promise<void>;
1291
+ datasync(): Promise<void>;
1292
+ truncate(len?: number): Promise<void>;
1293
+ chmod(mode: number): Promise<void>;
1294
+ readv<T extends Uint8Array[]>(buffers: T, position?: number | null): Promise<FileReadvResult<T>>;
1295
+ writev<T extends Uint8Array[]>(buffers: T, position?: number | null): Promise<FileWritevResult<T>>;
1296
+ read<T extends Uint8Array = Buffer>(options?: FileReadOptions<T> | null): Promise<FileReadResult<T>>;
1297
+ read<T extends Uint8Array>(buffer: T, options: Omit<FileReadOptions<T>, "buffer">): Promise<FileReadResult<T>>;
1271
1298
  read<T extends Uint8Array>(
1272
1299
  buffer: T,
1273
1300
  offset?: number | null,
@@ -1280,6 +1307,7 @@ declare module "fs/promises" {
1280
1307
  length?: number | null,
1281
1308
  position?: number | null,
1282
1309
  ): Promise<FileWriteResult<T>>;
1310
+ write<T extends Uint8Array>(buffer: T, options: Omit<FileReadOptions<T>, "buffer">): Promise<FileWriteResult<T>>;
1283
1311
  write(data: string, position?: number | null, encoding?: "utf8" | "utf-8" | null): Promise<FileWriteResult<string>>;
1284
1312
  readFile(options?: null): Promise<Buffer>;
1285
1313
  readFile(encoding: "utf8" | "utf-8"): Promise<string>;
@@ -1438,12 +1466,13 @@ declare module "node:os" {
1438
1466
  }
1439
1467
 
1440
1468
  /* The WHATWG URL class (a Node global; the es2023 lib doesn't declare it),
1441
- * typed as exactly the supported surface: construction from ONE absolute-
1442
- * URL string (invalid input throws a catchable TypeError, like Node), the
1469
+ * typed as exactly the supported surface: construction from an input and
1470
+ * optional base (invalid input throws a catchable TypeError, like Node), the
1443
1471
  * protocol/origin/username/pathname/href/host/hostname/port/search/hash getters, searchParams (the
1444
1472
  * LIVE query view — mutations through it re-serialize into the URL, so
1445
1473
  * href reflects immediately; every read answers the same object, Node's
1446
- * caching), and toString() (the href serialization).
1474
+ * caching), toString()/toJSON() (href serialization), and the non-throwing
1475
+ * canParse()/parse() factories (conversion errors still propagate).
1447
1476
  * URL values have no SETTERS — the component fields are read-only (the
1448
1477
  * one supported mutation path is searchParams) — and participate in
1449
1478
  * unions (URL | undefined). The parser covers the common CLI schemes
@@ -1464,9 +1493,12 @@ interface URL {
1464
1493
  readonly hash: string;
1465
1494
  readonly searchParams: URLSearchParams;
1466
1495
  toString(): string;
1496
+ toJSON(): string;
1467
1497
  }
1468
1498
  declare var URL: {
1469
1499
  new (input: string | { toString: () => string }, base?: string | URL): URL;
1500
+ canParse(input: string | URL, base?: string | URL): boolean;
1501
+ parse(input: string | URL, base?: string | URL): URL | null;
1470
1502
  };
1471
1503
 
1472
1504
  /* URLSearchParams — the WHATWG application/x-www-form-urlencoded list.
@@ -1499,6 +1531,10 @@ declare var URLSearchParams: {
1499
1531
  * slashes, non-empty host); pathToFileURL resolves the path and percent-
1500
1532
  * encodes it into a file: URL. */
1501
1533
  declare module "url" {
1534
+ export type URL = globalThis.URL;
1535
+ export type URLSearchParams = globalThis.URLSearchParams;
1536
+ export const URL: typeof globalThis.URL;
1537
+ export const URLSearchParams: typeof globalThis.URLSearchParams;
1502
1538
  export function fileURLToPath(url: string | URL): string;
1503
1539
  export function pathToFileURL(path: string, options?: { windows?: boolean }): URL;
1504
1540
  }
@@ -1506,7 +1542,7 @@ declare module "node:url" {
1506
1542
  export * from "url";
1507
1543
  }
1508
1544
 
1509
- /* node:crypto: the static hashing/MAC/random/PBKDF2 utility slice. */
1545
+ /* node:crypto: the static hashing/MAC/random/key-derivation utility slice. */
1510
1546
  declare module "crypto" {
1511
1547
  export function randomUUID(): string;
1512
1548
  export function randomBytes(size: number): Buffer;
@@ -1531,6 +1567,21 @@ declare module "crypto" {
1531
1567
  export function pbkdf2Sync(password: string | Uint8Array, salt: string | Uint8Array, iterations: number, keylen: number, digest: string): Buffer;
1532
1568
  export function pbkdf2(password: string | Uint8Array, salt: string | Uint8Array, iterations: number, keylen: number, digest: string, callback: (error: Error | null, derivedKey: Buffer) => void): void;
1533
1569
  export function randomBytes(size: number, callback: (error: Error | null, buffer: Buffer) => void): void;
1570
+ export type BinaryLike = string | ArrayBuffer | ArrayBufferView;
1571
+ export interface ScryptOptions {
1572
+ N?: number;
1573
+ r?: number;
1574
+ p?: number;
1575
+ cost?: number;
1576
+ blockSize?: number;
1577
+ parallelization?: number;
1578
+ maxmem?: number;
1579
+ }
1580
+ export function scryptSync(password: BinaryLike, salt: BinaryLike, keylen: number, options?: ScryptOptions): Buffer;
1581
+ export function scrypt(password: BinaryLike, salt: BinaryLike, keylen: number, callback: (error: Error | null, derivedKey: Buffer) => void): void;
1582
+ export function scrypt(password: BinaryLike, salt: BinaryLike, keylen: number, options: ScryptOptions, callback: (error: Error | null, derivedKey: Buffer) => void): void;
1583
+ export function hkdfSync(digest: string, ikm: BinaryLike, salt: BinaryLike, info: BinaryLike, keylen: number): ArrayBuffer;
1584
+ export function hkdf(digest: string, ikm: BinaryLike, salt: BinaryLike, info: BinaryLike, keylen: number, callback: (error: Error | null, derivedKey: ArrayBuffer) => void): void;
1534
1585
  /* The lowered X509Certificate surface is the data-record slice:
1535
1586
  * fingerprint (the SHA-1 of the DER, uppercase colon-separated) and
1536
1587
  * the validFrom/validTo validity window (Node's ASN1_TIME_print
@@ -1832,6 +1883,7 @@ declare module "node:child_process" {
1832
1883
  * the latter resolves the callback's data argument. Other targets and bare
1833
1884
  * promisify values fence per site. */
1834
1885
  declare module "util" {
1886
+ export function parseEnv(content: string): { [key: string]: string | undefined };
1835
1887
  export type TextEncoder = globalThis.TextEncoder;
1836
1888
  export type TextDecoder = globalThis.TextDecoder;
1837
1889
  export var TextEncoder: typeof globalThis.TextEncoder;
@@ -3397,6 +3449,9 @@ declare module "node:worker_threads" {
3397
3449
  * third-party .d.ts files that `import { Buffer } from "node:buffer"` —
3398
3450
  * file-entry-cache in a typed-JS source graph — typecheck). */
3399
3451
  declare module "buffer" {
3452
+ export function isAscii(input: ArrayBuffer | ArrayBufferView): boolean;
3453
+ export function isUtf8(input: ArrayBuffer | ArrayBufferView): boolean;
3454
+ export function transcode(source: Uint8Array, fromEncoding: string, toEncoding: string): Buffer;
3400
3455
  export function atob(data: string): string;
3401
3456
  export function btoa(data: string): string;
3402
3457
  export const kMaxLength: number;
@@ -26,6 +26,9 @@ export interface DynHost extends WalkerHost {
26
26
  snapshot: string;
27
27
  commit: string;
28
28
  };
29
+ liveDynUnionRefAdapter(t: IrType & {
30
+ kind: "union";
31
+ }): string;
29
32
  dynPromiseAdapter(t: IrType): string;
30
33
  isErrorClass(className: string): boolean;
31
34
  classSubtypes(className: string): readonly string[];
@@ -2,7 +2,7 @@ import { typedRefConstructor } from "./shapes.js";
2
2
  import { BYTES_ELEM_NUM, f64Lit } from "./common.js";
3
3
  import { InternalCompilerError } from "../../errors.js";
4
4
  import { DYN_HANDLE_KINDS, isDynTypedRefType, isRefCounted, typeKey } from "../../ir/ir.js";
5
- import { dynDesc } from "../../ir/analysis.js";
5
+ import { dynDesc, streamTypedRefEligible } from "../../ir/analysis.js";
6
6
  import { mangleRecordNew, mangleRecordStruct } from "../mangle.js";
7
7
  import { BlockBuilder } from "./blocks.js";
8
8
  import { llvmCommentText } from "./common.js";
@@ -108,9 +108,25 @@ export class LlDyn {
108
108
  const ty = this.valTy(type);
109
109
  const unpack = ty === "double" ? "bitcast i64 %slot to double" : ty === "i1" ? "trunc i64 %slot to i1" : "inttoptr i64 %slot to ptr";
110
110
  const pack = ty === "double" ? "bitcast double %value to i64" : ty === "i1" ? "zext i1 %value to i64" : "ptrtoint ptr %value to i64";
111
- const box = this.toDynHelper(type);
111
+ // Collection reads expose the original mutable element, including
112
+ // records/arrays inside unions, rather than a detached dyn snapshot.
113
+ const B = new BlockBuilder();
114
+ B.line(`%value = ${unpack}`);
115
+ if (type.kind === "union" && this.host.unionsById.get(type.unionId)?.arms.some(streamTypedRefEligible)) {
116
+ B.line(`%result = call ptr @${this.host.liveDynUnionRefAdapter(type)}(ptr %value)`);
117
+ }
118
+ else if (type.kind === "record" || type.kind === "array") {
119
+ const adapter = this.host.liveDynRefAdapter(type);
120
+ const rc = vAdapters(this.host, type);
121
+ const typeId = typeKey(type);
122
+ B.line(`%result = call ptr ${typedRefConstructor(this.host, type)}(ptr %value, ptr ${rc.retain}, ptr ${rc.release}, ptr ${this.host.cstr(typeId)}, ${this.S} ${Buffer.byteLength(typeId, "utf8")}, ptr @${adapter.snapshot}, ptr ${adapter.commit})`);
123
+ }
124
+ else {
125
+ B.line(`%result = call ptr @${this.toDynHelper(type)}(${ty} %value)`);
126
+ }
127
+ B.terminate("ret ptr %result");
112
128
  const unbox = this.dynCheckHelper(type);
113
- this.defs.push(`define internal ptr @${name}_${role}_box(i64 %slot) ${FN_ATTRS} {`, ` %value = ${unpack}`, ` %result = call ptr @${box}(${ty} %value)`, ` ret ptr %result`, `}`, "", `define internal i64 @${name}_${role}_unbox(ptr %d) ${FN_ATTRS} {`, ` %value = call ${ty === "i1" ? "zeroext i1" : ty} @${unbox}(ptr %d, ptr null)`, ` %result = ${pack}`, ` ret i64 %result`, `}`, "");
129
+ this.defs.push(`define internal ptr @${name}_${role}_box(i64 %slot) ${FN_ATTRS} {`, B.render(), `}`, "", `define internal i64 @${name}_${role}_unbox(ptr %d) ${FN_ATTRS} {`, ` %value = call ${ty === "i1" ? "zeroext i1" : ty} @${unbox}(ptr %d, ptr null)`, ` %result = ${pack}`, ` ret i64 %result`, `}`, "");
114
130
  };
115
131
  emitSlot(keyType, "key");
116
132
  emitSlot(valueType, "value");
@@ -436,7 +452,12 @@ export class LlDyn {
436
452
  break;
437
453
  }
438
454
  case "func":
439
- kindIs(DYN_KIND.FUNC);
455
+ this.host.declare(`declare zeroext i1 @scr_dyn_is_callable(ptr)`);
456
+ {
457
+ const matched = B.tmp();
458
+ B.line(`${matched} = call zeroext i1 @scr_dyn_is_callable(ptr %d)`);
459
+ B.terminate(`ret i1 ${matched}`);
460
+ }
440
461
  break;
441
462
  case "classval": {
442
463
  this.host.declare(`declare zeroext i1 @scr_dyn_class_is(ptr, ptr)`);
@@ -584,7 +605,16 @@ export class LlDyn {
584
605
  B.startBlock(l0);
585
606
  const n = this.lenOf(B, "%d");
586
607
  const items = this.itemsOf(B, "%d");
587
- this.i64Loop(B, "dm.el", n, (i) => {
608
+ this.i64Loop(B, "dm.el", n, (i, brNext) => {
609
+ this.host.declare(`declare zeroext i1 @scr_dyn_arr_has_index(ptr, ${this.S})`);
610
+ const present = B.tmp();
611
+ B.line(`${present} = call zeroext i1 @scr_dyn_arr_has_index(ptr %d, ${this.S} ${i})`);
612
+ const valueLabel = B.newLabel("dm.present");
613
+ const holeLabel = B.newLabel("dm.hole");
614
+ B.condBr(present, valueLabel, holeLabel);
615
+ B.startBlock(holeLabel);
616
+ brNext();
617
+ B.startBlock(valueLabel);
588
618
  const e = this.itemAt(B, items, i);
589
619
  const ok = B.tmp();
590
620
  B.line(`${ok} = call zeroext i1 @${m}(ptr ${e})`);
@@ -1170,6 +1200,22 @@ export class LlDyn {
1170
1200
  const accTy = acc === "f64" ? "double" : acc === "bool" ? "i1" : "ptr";
1171
1201
  host.declare(`declare double @scr_arr_push_${acc}(ptr, ${acc === "bool" ? "i1 zeroext" : accTy})`);
1172
1202
  this.i64Loop(B, "dca", n, (i) => {
1203
+ host.declare(`declare zeroext i1 @scr_dyn_arr_has_index(ptr, ${this.S})`);
1204
+ const present = B.tmp();
1205
+ B.line(`${present} = call zeroext i1 @scr_dyn_arr_has_index(ptr %d, ${this.S} ${i})`);
1206
+ const valueLabel = B.newLabel("dca.present");
1207
+ const holeLabel = B.newLabel("dca.hole");
1208
+ const doneLabel = B.newLabel("dca.done");
1209
+ B.condBr(present, valueLabel, holeLabel);
1210
+ B.startBlock(holeLabel);
1211
+ host.declare(`declare void @scr_arr_set_len(ptr, double)`);
1212
+ const index = B.tmp();
1213
+ const length = B.tmp();
1214
+ B.line(`${index} = uitofp ${this.S} ${i} to double`);
1215
+ B.line(`${length} = fadd double ${index}, 1.0`);
1216
+ B.line(`call void @scr_arr_set_len(ptr ${a}, double ${length})`);
1217
+ B.br(doneLabel);
1218
+ B.startBlock(valueLabel);
1173
1219
  const pp = B.tmp();
1174
1220
  const kp = B.tmp();
1175
1221
  const ip = B.tmp();
@@ -1188,6 +1234,8 @@ export class LlDyn {
1188
1234
  }, "ptr null");
1189
1235
  const pushed = B.tmp();
1190
1236
  B.line(`${pushed} = call double @scr_arr_push_${acc}(ptr ${a}, ${accTy} ${v})`);
1237
+ B.br(doneLabel);
1238
+ B.startBlock(doneLabel);
1191
1239
  });
1192
1240
  B.terminate(`ret ptr ${a}`);
1193
1241
  break;
@@ -1316,7 +1364,22 @@ export class LlDyn {
1316
1364
  // caps[0] obj-box owns the dyn value (untraced).
1317
1365
  const adapter = this.dynFuncAdapterHelper(t);
1318
1366
  const sigLit = host.cstr(key);
1319
- requireKind(DYN_KIND.FUNC, "dcf");
1367
+ const lWrap = B.newLabel("dcf.w");
1368
+ host.declare(`declare zeroext i1 @scr_dyn_is_callable(ptr)`);
1369
+ const callable = B.tmp();
1370
+ const valid = B.newLabel("dcf.k");
1371
+ const invalid = B.newLabel("dcf.f");
1372
+ B.line(`${callable} = call zeroext i1 @scr_dyn_is_callable(ptr %d)`);
1373
+ B.condBr(callable, valid, invalid);
1374
+ B.startBlock(invalid);
1375
+ B.line(`call void @scr_dyn_check_fail(ptr %path, ptr ${want}, ptr %d)`);
1376
+ B.terminate(`ret ${dummy}`);
1377
+ B.startBlock(valid);
1378
+ const direct = B.tmp();
1379
+ const lSignature = B.newLabel("dcf.signature");
1380
+ B.line(`${direct} = icmp eq i32 ${this.kindOf(B, "%d")}, ${DYN_KIND.FUNC}`);
1381
+ B.condBr(direct, lSignature, lWrap);
1382
+ B.startBlock(lSignature);
1320
1383
  host.declare(`declare i32 @strcmp(ptr, ptr)`);
1321
1384
  const sigp = B.tmp();
1322
1385
  const sig = B.tmp();
@@ -1327,7 +1390,6 @@ export class LlDyn {
1327
1390
  B.line(`${cmp} = call i32 @strcmp(ptr ${sig}, ptr ${sigLit})`);
1328
1391
  B.line(`${same} = icmp eq i32 ${cmp}, 0`);
1329
1392
  const lSame = B.newLabel("dcf.s");
1330
- const lWrap = B.newLabel("dcf.w");
1331
1393
  B.condBr(same, lSame, lWrap);
1332
1394
  B.startBlock(lSame);
1333
1395
  host.declare(`declare ptr @scr_closure_retain_v(ptr)`);
@@ -1347,14 +1409,14 @@ export class LlDyn {
1347
1409
  host.declare(`declare void @scr_dyn_release_v(ptr)`);
1348
1410
  const a = B.tmp();
1349
1411
  B.line(`${a} = call ptr @scr_closure_new(ptr @${adapter}, ${host.sizeType} 1)`);
1350
- const sourceClosure = this.payloadOf(B, "%d", "ptr");
1351
- const sourceKind = B.tmp();
1412
+ host.declare(`declare i32 @scr_dyn_function_kind(ptr)`);
1352
1413
  const functionKind = B.tmp();
1353
1414
  const targetKind = B.tmp();
1354
- B.line(`${sourceKind} = getelementptr inbounds %ScrClosure, ptr ${sourceClosure}, i64 0, i32 4`);
1355
- B.line(`${functionKind} = load i32, ptr ${sourceKind}`);
1415
+ B.line(`${functionKind} = call i32 @scr_dyn_function_kind(ptr %d)`);
1356
1416
  B.line(`${targetKind} = getelementptr inbounds %ScrClosure, ptr ${a}, i64 0, i32 4`);
1357
- B.line(`store i32 ${functionKind}, ptr ${targetKind}`);
1417
+ const adapterKind = B.tmp();
1418
+ B.line(`${adapterKind} = or i32 ${functionKind}, 8 ; preserves the checked callable in caps[0]`);
1419
+ B.line(`store i32 ${adapterKind}, ptr ${targetKind}`);
1358
1420
  const box = B.tmp();
1359
1421
  B.line(`${box} = call ptr @scr_box_new_obj(ptr @scr_dyn_retain_v, ptr @scr_dyn_release_v, ptr @scr_dyn_trace_v)`);
1360
1422
  const capp = B.tmp();
@@ -1690,9 +1752,19 @@ export class LlDyn {
1690
1752
  const state = B.tmp();
1691
1753
  const undefinedState = B.tmp();
1692
1754
  const undefinedLabel = B.newLabel("tda.undefined");
1755
+ const holeLabel = B.newLabel("tda.hole");
1756
+ const presentLabel = B.newLabel("tda.present");
1693
1757
  const valueLabel = B.newLabel("tda.value");
1694
1758
  const doneLabel = B.newLabel("tda.done");
1695
1759
  B.line(`${state} = call double @scr_arr_state(ptr %v, double ${i})`);
1760
+ const hole = B.tmp();
1761
+ B.line(`${hole} = fcmp oeq double ${state}, 0.0`); // SCR_ARR_HOLE
1762
+ B.condBr(hole, holeLabel, presentLabel);
1763
+ B.startBlock(holeLabel);
1764
+ host.declare(`declare void @scr_dyn_arr_push_hole(ptr)`);
1765
+ B.line(`call void @scr_dyn_arr_push_hole(ptr ${d})`);
1766
+ B.br(doneLabel);
1767
+ B.startBlock(presentLabel);
1696
1768
  B.line(`${undefinedState} = fcmp oeq double ${state}, 2.0`); // SCR_ARR_UNDEFINED
1697
1769
  B.terminate(`br i1 ${undefinedState}, label %${undefinedLabel}, label %${valueLabel}`);
1698
1770
  B.startBlock(undefinedLabel);