@scriptc/compiler 0.2.5 → 0.2.6

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 (307) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +57 -30
  2. package/dist/backend/cycle-analysis.test.js +1 -1
  3. package/dist/backend/executable-features.js +1 -0
  4. package/dist/backend/executable-features.js.map +1 -1
  5. package/dist/backend/link-plan-core.d.ts +2 -0
  6. package/dist/backend/link-plan-core.js +1 -0
  7. package/dist/backend/link-plan-core.js.map +1 -1
  8. package/dist/backend/link-plan.d.ts +1 -0
  9. package/dist/backend/link-plan.js +3 -0
  10. package/dist/backend/link-plan.js.map +1 -1
  11. package/dist/backend/llvm/byte-numbers.js +32 -4
  12. package/dist/backend/llvm/byte-numbers.js.map +1 -1
  13. package/dist/backend/llvm/byte-windows.d.ts +31 -0
  14. package/dist/backend/llvm/byte-windows.js +334 -0
  15. package/dist/backend/llvm/byte-windows.js.map +1 -0
  16. package/dist/backend/llvm/byte-windows.test.d.ts +1 -0
  17. package/dist/backend/llvm/byte-windows.test.js +244 -0
  18. package/dist/backend/llvm/byte-windows.test.js.map +1 -0
  19. package/dist/backend/llvm/call-lifetimes.d.ts +2 -2
  20. package/dist/backend/llvm/call-lifetimes.js +17 -7
  21. package/dist/backend/llvm/call-lifetimes.js.map +1 -1
  22. package/dist/backend/llvm/classes.d.ts +14 -1
  23. package/dist/backend/llvm/classes.js +80 -9
  24. package/dist/backend/llvm/classes.js.map +1 -1
  25. package/dist/backend/llvm/classes.test.d.ts +1 -0
  26. package/dist/backend/llvm/classes.test.js +99 -0
  27. package/dist/backend/llvm/classes.test.js.map +1 -0
  28. package/dist/backend/llvm/constant-callbacks.d.ts +11 -0
  29. package/dist/backend/llvm/constant-callbacks.js +213 -0
  30. package/dist/backend/llvm/constant-callbacks.js.map +1 -0
  31. package/dist/backend/llvm/constant-callbacks.test.d.ts +1 -0
  32. package/dist/backend/llvm/constant-callbacks.test.js +124 -0
  33. package/dist/backend/llvm/constant-callbacks.test.js.map +1 -0
  34. package/dist/backend/llvm/dyn.d.ts +1 -1
  35. package/dist/backend/llvm/dyn.js +7 -34
  36. package/dist/backend/llvm/dyn.js.map +1 -1
  37. package/dist/backend/llvm/emitter.d.ts +19 -0
  38. package/dist/backend/llvm/emitter.js +274 -46
  39. package/dist/backend/llvm/emitter.js.map +1 -1
  40. package/dist/backend/llvm/emitter.test.js +17 -11
  41. package/dist/backend/llvm/emitter.test.js.map +1 -1
  42. package/dist/backend/llvm/expr-bytes.js +11 -0
  43. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  44. package/dist/backend/llvm/expr-calls.js +91 -23
  45. package/dist/backend/llvm/expr-calls.js.map +1 -1
  46. package/dist/backend/llvm/expr-containers.js +21 -9
  47. package/dist/backend/llvm/expr-containers.js.map +1 -1
  48. package/dist/backend/llvm/expr-dynamic.js +36 -3
  49. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  50. package/dist/backend/llvm/expr-primitives.js +7 -0
  51. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  52. package/dist/backend/llvm/expr-primitives.test.js +1 -1
  53. package/dist/backend/llvm/expr-stream-bridges.test.js +1 -1
  54. package/dist/backend/llvm/integer-remainder.d.ts +7 -0
  55. package/dist/backend/llvm/integer-remainder.js +26 -0
  56. package/dist/backend/llvm/integer-remainder.js.map +1 -0
  57. package/dist/backend/llvm/layouts.js +1 -1
  58. package/dist/backend/llvm/layouts.js.map +1 -1
  59. package/dist/backend/llvm/lib-abi.js +7 -0
  60. package/dist/backend/llvm/lib-abi.js.map +1 -1
  61. package/dist/backend/llvm/lib-dispatch.js +7 -22
  62. package/dist/backend/llvm/lib-dispatch.js.map +1 -1
  63. package/dist/backend/llvm/lib-shared.js +15 -0
  64. package/dist/backend/llvm/lib-shared.js.map +1 -1
  65. package/dist/backend/llvm/local-array-reads.d.ts +8 -2
  66. package/dist/backend/llvm/local-array-reads.js +89 -68
  67. package/dist/backend/llvm/local-array-reads.js.map +1 -1
  68. package/dist/backend/llvm/local-array-reads.test.js +28 -4
  69. package/dist/backend/llvm/local-array-reads.test.js.map +1 -1
  70. package/dist/backend/llvm/local-union-storage.test.js +1 -1
  71. package/dist/backend/llvm/loop-array-borrows.d.ts +11 -0
  72. package/dist/backend/llvm/loop-array-borrows.js +70 -0
  73. package/dist/backend/llvm/loop-array-borrows.js.map +1 -0
  74. package/dist/backend/llvm/loop-array-borrows.test.d.ts +1 -0
  75. package/dist/backend/llvm/loop-array-borrows.test.js +145 -0
  76. package/dist/backend/llvm/loop-array-borrows.test.js.map +1 -0
  77. package/dist/backend/llvm/map-read-lifetimes.d.ts +5 -0
  78. package/dist/backend/llvm/map-read-lifetimes.js +20 -5
  79. package/dist/backend/llvm/map-read-lifetimes.js.map +1 -1
  80. package/dist/backend/llvm/map-read-lifetimes.test.js +1 -1
  81. package/dist/backend/llvm/reference-effects.d.ts +2 -1
  82. package/dist/backend/llvm/reference-effects.js +7 -0
  83. package/dist/backend/llvm/reference-effects.js.map +1 -1
  84. package/dist/backend/llvm/shapes.d.ts +4 -1
  85. package/dist/backend/llvm/shapes.js +22 -7
  86. package/dist/backend/llvm/shapes.js.map +1 -1
  87. package/dist/backend/llvm/split-loops.d.ts +48 -0
  88. package/dist/backend/llvm/split-loops.js +183 -0
  89. package/dist/backend/llvm/split-loops.js.map +1 -0
  90. package/dist/backend/llvm/split.js +0 -7
  91. package/dist/backend/llvm/split.js.map +1 -1
  92. package/dist/backend/llvm/split.test.js +66 -2
  93. package/dist/backend/llvm/split.test.js.map +1 -1
  94. package/dist/backend/llvm/stack-callbacks.d.ts +14 -0
  95. package/dist/backend/llvm/stack-callbacks.js +73 -0
  96. package/dist/backend/llvm/stack-callbacks.js.map +1 -0
  97. package/dist/backend/llvm/stack-captures.d.ts +25 -0
  98. package/dist/backend/llvm/stack-captures.js +150 -0
  99. package/dist/backend/llvm/stack-captures.js.map +1 -0
  100. package/dist/backend/llvm/stack-unions.test.js +1 -1
  101. package/dist/backend/llvm/string-construction.test.js +1 -1
  102. package/dist/backend/llvm/string-lifetimes.test.js +8 -4
  103. package/dist/backend/llvm/string-lifetimes.test.js.map +1 -1
  104. package/dist/backend/llvm/string-slices.d.ts +20 -0
  105. package/dist/backend/llvm/string-slices.js +87 -0
  106. package/dist/backend/llvm/string-slices.js.map +1 -0
  107. package/dist/backend/llvm/string-slices.test.d.ts +1 -0
  108. package/dist/backend/llvm/string-slices.test.js +98 -0
  109. package/dist/backend/llvm/string-slices.test.js.map +1 -0
  110. package/dist/backend/llvm/switch-dispatch.test.js +1 -1
  111. package/dist/backend/llvm/walkers.d.ts +4 -14
  112. package/dist/backend/llvm/walkers.js +53 -311
  113. package/dist/backend/llvm/walkers.js.map +1 -1
  114. package/dist/backend/may-throw.js +1 -1
  115. package/dist/backend/may-throw.js.map +1 -1
  116. package/dist/backend/may-throw.test.js +1 -1
  117. package/dist/backend/native/contracts.d.ts +2 -0
  118. package/dist/backend/native/executable.js +12 -4
  119. package/dist/backend/native/executable.js.map +1 -1
  120. package/dist/backend/native/runtime-inputs.d.ts +1 -1
  121. package/dist/backend/native/runtime-inputs.js +2 -0
  122. package/dist/backend/native/runtime-inputs.js.map +1 -1
  123. package/dist/backend/native-codegen-core.d.ts +6 -0
  124. package/dist/backend/native-codegen-core.js +21 -0
  125. package/dist/backend/native-codegen-core.js.map +1 -1
  126. package/dist/backend/native-codegen.d.ts +4 -0
  127. package/dist/backend/native-codegen.js +34 -18
  128. package/dist/backend/native-codegen.js.map +1 -1
  129. package/dist/backend/native-codegen.test.js +47 -2
  130. package/dist/backend/native-codegen.test.js.map +1 -1
  131. package/dist/backend/native-link-info-core.d.ts +1 -0
  132. package/dist/backend/native-link-info-core.js.map +1 -1
  133. package/dist/backend/native-tools.d.ts +3 -1
  134. package/dist/backend/native-tools.js +6 -4
  135. package/dist/backend/native-tools.js.map +1 -1
  136. package/dist/backend/runtime-abi.d.ts +2 -2
  137. package/dist/backend/runtime-abi.js +2 -2
  138. package/dist/backend/runtime-pack-core.d.ts +1 -0
  139. package/dist/backend/runtime-pack-core.js +8 -1
  140. package/dist/backend/runtime-pack-core.js.map +1 -1
  141. package/dist/backend/runtime-pack-targets.test.js +41 -4
  142. package/dist/backend/runtime-pack-targets.test.js.map +1 -1
  143. package/dist/backend/runtime-pack.test.js +11 -1
  144. package/dist/backend/runtime-pack.test.js.map +1 -1
  145. package/dist/backend/target-diagnostics.test.js +1 -1
  146. package/dist/executable/executable-cache.d.ts +1 -0
  147. package/dist/executable/executable-cache.js +2 -1
  148. package/dist/executable/executable-cache.js.map +1 -1
  149. package/dist/executable/executable-cache.test.js +15 -0
  150. package/dist/executable/executable-cache.test.js.map +1 -1
  151. package/dist/frontend/fork-target.d.ts +5 -0
  152. package/dist/frontend/fork-target.js +40 -8
  153. package/dist/frontend/fork-target.js.map +1 -1
  154. package/dist/frontend/fork-target.test.d.ts +1 -0
  155. package/dist/frontend/fork-target.test.js +59 -0
  156. package/dist/frontend/fork-target.test.js.map +1 -0
  157. package/dist/frontend/lowering/binding-analysis.js +2 -2
  158. package/dist/frontend/lowering/binding-analysis.js.map +1 -1
  159. package/dist/frontend/lowering/builtins/atomics.d.ts +2 -11
  160. package/dist/frontend/lowering/builtins/atomics.js +64 -28
  161. package/dist/frontend/lowering/builtins/atomics.js.map +1 -1
  162. package/dist/frontend/lowering/builtins/filesystem-calls.d.ts +3 -0
  163. package/dist/frontend/lowering/builtins/filesystem-calls.js +51 -4
  164. package/dist/frontend/lowering/builtins/filesystem-calls.js.map +1 -1
  165. package/dist/frontend/lowering/builtins/module-calls.js +6 -1
  166. package/dist/frontend/lowering/builtins/module-calls.js.map +1 -1
  167. package/dist/frontend/lowering/builtins/workers.d.ts +5 -0
  168. package/dist/frontend/lowering/builtins/workers.js +65 -0
  169. package/dist/frontend/lowering/builtins/workers.js.map +1 -0
  170. package/dist/frontend/lowering/class-assertions.d.ts +7 -0
  171. package/dist/frontend/lowering/class-assertions.js +96 -0
  172. package/dist/frontend/lowering/class-assertions.js.map +1 -0
  173. package/dist/frontend/lowering/class-protocols.d.ts +17 -0
  174. package/dist/frontend/lowering/class-protocols.js +126 -0
  175. package/dist/frontend/lowering/class-protocols.js.map +1 -0
  176. package/dist/frontend/lowering/containers/array-callbacks.d.ts +7 -11
  177. package/dist/frontend/lowering/containers/array-callbacks.js +52 -87
  178. package/dist/frontend/lowering/containers/array-callbacks.js.map +1 -1
  179. package/dist/frontend/lowering/containers/bytes.js +12 -34
  180. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  181. package/dist/frontend/lowering/containers/string-and-regexp.js +22 -3
  182. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  183. package/dist/frontend/lowering/expressions/object-literals.js +2 -6
  184. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  185. package/dist/frontend/lowering/generic-functions.d.ts +2 -5
  186. package/dist/frontend/lowering/generic-functions.js +13 -10
  187. package/dist/frontend/lowering/generic-functions.js.map +1 -1
  188. package/dist/frontend/lowering/instantiation-path.d.ts +8 -0
  189. package/dist/frontend/lowering/instantiation-path.js +10 -0
  190. package/dist/frontend/lowering/instantiation-path.js.map +1 -0
  191. package/dist/frontend/lowering/instantiation-path.test.d.ts +1 -0
  192. package/dist/frontend/lowering/instantiation-path.test.js +23 -0
  193. package/dist/frontend/lowering/instantiation-path.test.js.map +1 -0
  194. package/dist/frontend/lowering/lower-builtin-values.js +11 -7
  195. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  196. package/dist/frontend/lowering/lower-calls.js +36 -3
  197. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  198. package/dist/frontend/lowering/lower-classes.d.ts +5 -0
  199. package/dist/frontend/lowering/lower-classes.js +121 -53
  200. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  201. package/dist/frontend/lowering/lower-event-emitter.js +1 -1
  202. package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
  203. package/dist/frontend/lowering/lower-exprs.js +31 -10
  204. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  205. package/dist/frontend/lowering/lower-functions.d.ts +1 -1
  206. package/dist/frontend/lowering/lower-functions.js +2 -2
  207. package/dist/frontend/lowering/lower-functions.js.map +1 -1
  208. package/dist/frontend/lowering/lower-island.js +1 -1
  209. package/dist/frontend/lowering/lower-island.js.map +1 -1
  210. package/dist/frontend/lowering/lower-modules.d.ts +1 -0
  211. package/dist/frontend/lowering/lower-modules.js +44 -9
  212. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  213. package/dist/frontend/lowering/lower-stmts.js +13 -11
  214. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  215. package/dist/frontend/lowering/lower-stream.js +1 -1
  216. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  217. package/dist/frontend/lowering/lowerer.d.ts +13 -1
  218. package/dist/frontend/lowering/lowerer.js +51 -9
  219. package/dist/frontend/lowering/lowerer.js.map +1 -1
  220. package/dist/frontend/lowering/sanitize-class-types.test.js +2 -2
  221. package/dist/frontend/lowering/split-consumers.d.ts +7 -0
  222. package/dist/frontend/lowering/split-consumers.js +64 -0
  223. package/dist/frontend/lowering/split-consumers.js.map +1 -0
  224. package/dist/frontend/lowering/surfaces.d.ts +3 -4
  225. package/dist/frontend/lowering/surfaces.js +35 -7
  226. package/dist/frontend/lowering/surfaces.js.map +1 -1
  227. package/dist/frontend/module-source-candidates.d.ts +10 -0
  228. package/dist/frontend/module-source-candidates.js +40 -0
  229. package/dist/frontend/module-source-candidates.js.map +1 -0
  230. package/dist/frontend/module-source-candidates.test.d.ts +1 -0
  231. package/dist/frontend/module-source-candidates.test.js +53 -0
  232. package/dist/frontend/module-source-candidates.test.js.map +1 -0
  233. package/dist/frontend/pipeline.js +2 -2
  234. package/dist/frontend/pipeline.js.map +1 -1
  235. package/dist/frontend/program-analysis.d.ts +2 -0
  236. package/dist/frontend/program-analysis.js +2 -0
  237. package/dist/frontend/program-analysis.js.map +1 -1
  238. package/dist/frontend/program.js +17 -29
  239. package/dist/frontend/program.js.map +1 -1
  240. package/dist/frontend/ts7/ast-node.js +6 -8
  241. package/dist/frontend/ts7/ast-node.js.map +1 -1
  242. package/dist/frontend/ts7/ast-node.test.js +42 -1
  243. package/dist/frontend/ts7/ast-node.test.js.map +1 -1
  244. package/dist/frontend/ts7/ast-wire.d.ts +4 -0
  245. package/dist/frontend/ts7/ast-wire.js +28 -0
  246. package/dist/frontend/ts7/ast-wire.js.map +1 -1
  247. package/dist/frontend/ts7/ast.d.ts +2 -1
  248. package/dist/frontend/ts7/ast.js +8 -4
  249. package/dist/frontend/ts7/ast.js.map +1 -1
  250. package/dist/frontend/ts7/checker.d.ts +8 -2
  251. package/dist/frontend/ts7/checker.js +41 -5
  252. package/dist/frontend/ts7/checker.js.map +1 -1
  253. package/dist/frontend/ts7/checker.test.js +42 -0
  254. package/dist/frontend/ts7/checker.test.js.map +1 -1
  255. package/dist/frontend/ts7/program-host.d.ts +7 -0
  256. package/dist/frontend/ts7/program-host.js +26 -2
  257. package/dist/frontend/ts7/program-host.js.map +1 -1
  258. package/dist/frontend/ts7/program-host.test.js +29 -0
  259. package/dist/frontend/ts7/program-host.test.js.map +1 -1
  260. package/dist/frontend/type-mapper.d.ts +3 -0
  261. package/dist/frontend/type-mapper.js +44 -2
  262. package/dist/frontend/type-mapper.js.map +1 -1
  263. package/dist/frontend/worker-target.d.ts +6 -0
  264. package/dist/frontend/worker-target.js +108 -0
  265. package/dist/frontend/worker-target.js.map +1 -0
  266. package/dist/frontend/worker-target.test.d.ts +1 -0
  267. package/dist/frontend/worker-target.test.js +71 -0
  268. package/dist/frontend/worker-target.test.js.map +1 -0
  269. package/dist/index.js +24 -7
  270. package/dist/index.js.map +1 -1
  271. package/dist/ir/builtin-effects.js +12 -0
  272. package/dist/ir/builtin-effects.js.map +1 -1
  273. package/dist/ir/builtin-signatures.d.ts +1 -1
  274. package/dist/ir/builtin-signatures.js +13 -12
  275. package/dist/ir/builtin-signatures.js.map +1 -1
  276. package/dist/ir/constant-tables.test.js +1 -1
  277. package/dist/ir/initializer-bindings.test.js +1 -1
  278. package/dist/ir/ir.d.ts +9 -10
  279. package/dist/ir/ir.js.map +1 -1
  280. package/dist/ir/numeric-call-specialization.d.ts +8 -0
  281. package/dist/ir/numeric-call-specialization.js +198 -0
  282. package/dist/ir/numeric-call-specialization.js.map +1 -0
  283. package/dist/ir/runtime-features.js +4 -3
  284. package/dist/ir/runtime-features.js.map +1 -1
  285. package/dist/ir/scalar-records.test.js +1 -1
  286. package/dist/ir/serialize.d.ts +1 -1
  287. package/dist/ir/serialize.js +3 -3
  288. package/dist/ir/serialize.js.map +1 -1
  289. package/dist/ir/validate.js +89 -23
  290. package/dist/ir/validate.js.map +1 -1
  291. package/dist/ir/validate.test.js +91 -4
  292. package/dist/ir/validate.test.js.map +1 -1
  293. package/dist/library/fence-eval.test.js +1 -1
  294. package/dist/library/int-infer.test.js +4 -4
  295. package/dist/library/ir-policy.js +2 -0
  296. package/dist/library/ir-policy.js.map +1 -1
  297. package/dist/library/library-cache.test.js +5 -5
  298. package/dist/native/compiler.js +24 -11
  299. package/dist/native/compiler.js.map +1 -1
  300. package/dist/native/compiler.test.js +7 -3
  301. package/dist/native/compiler.test.js.map +1 -1
  302. package/dist/native/prepare.js +2 -0
  303. package/dist/native/prepare.js.map +1 -1
  304. package/dist/native/sanitizer.test.js +1 -0
  305. package/dist/native/sanitizer.test.js.map +1 -1
  306. package/package.json +20 -20
  307. package/surface-manifest.json +30 -2
@@ -53,7 +53,20 @@ export function validateModule(mod) {
53
53
  const ffiByName = new Map();
54
54
  const ffiSymbols = new Set();
55
55
  const moduleLoc = { file: mod.sourceFile, start: 0, end: 0 };
56
+ if (mod.workers !== undefined && typeof mod.workers !== "boolean")
57
+ errors.push({ message: "worker execution mode must be a boolean", loc: moduleLoc });
58
+ if (mod.workers && (mod.lib !== undefined || mod.embedded !== undefined))
59
+ errors.push({
60
+ message: "worker execution requires a native static executable",
61
+ loc: moduleLoc,
62
+ });
56
63
  for (const entry of mod.ffiImports ?? []) {
64
+ if (mod.workers &&
65
+ entry.params.some((parameter) => isFfiCallbackParam(parameter) && parameter.callback.invoke === "foreign"))
66
+ errors.push({
67
+ message: "worker execution cannot install foreign-thread callbacks",
68
+ loc: moduleLoc,
69
+ });
57
70
  if (ffiByName.has(entry.name)) {
58
71
  errors.push({ message: `duplicate FFI binding "${entry.name}"`, loc: moduleLoc });
59
72
  }
@@ -473,8 +486,19 @@ export function validateModule(mod) {
473
486
  });
474
487
  }
475
488
  }
476
- // Generic-class instantiations: the named FAMILY exists and is a proper
477
- // ancestor (the class object's interval is read off it — see IrClassDef).
489
+ // Family membership is nominal; an instance may have a separately
490
+ // specialized base. The family's inherited prefix must remain valid.
491
+ const physicalRoot = (cls) => {
492
+ const seen = new Set();
493
+ let current = cls;
494
+ while (current?.base !== undefined) {
495
+ if (seen.has(current.name))
496
+ return undefined;
497
+ seen.add(current.name);
498
+ current = classesByName.get(current.base);
499
+ }
500
+ return current;
501
+ };
478
502
  for (const cls of mod.classes ?? []) {
479
503
  if (cls.genericOf === undefined)
480
504
  continue;
@@ -484,20 +508,23 @@ export function validateModule(mod) {
484
508
  message: `class ${cls.name}: undeclared generic family "${cls.genericOf}"`,
485
509
  loc: cls.loc,
486
510
  });
487
- continue;
488
511
  }
489
- let ancestor = false;
490
- const seen = new Set();
491
- for (let c = cls.base !== undefined ? classesByName.get(cls.base) : undefined; c && !seen.has(c.name); c = c.base !== undefined ? classesByName.get(c.base) : undefined) {
492
- seen.add(c.name);
493
- if (c.name === cls.genericOf) {
494
- ancestor = true;
495
- break;
496
- }
512
+ else if (family === cls || family.genericOf !== undefined) {
513
+ errors.push({
514
+ message: `class ${cls.name}: generic family "${cls.genericOf}" must name an erased declaration`,
515
+ loc: cls.loc,
516
+ });
497
517
  }
498
- if (!ancestor) {
518
+ else if (physicalRoot(cls) !== physicalRoot(family)) {
499
519
  errors.push({
500
- message: `class ${cls.name}: generic family "${cls.genericOf}" is not an ancestor`,
520
+ message: `class ${cls.name}: generic family "${cls.genericOf}" has a different storage root`,
521
+ loc: cls.loc,
522
+ });
523
+ }
524
+ else if (family.fields.some((field, index) => cls.fields[index]?.name !== field.name ||
525
+ !typeEquals(cls.fields[index].type, field.type))) {
526
+ errors.push({
527
+ message: `class ${cls.name}: generic family "${cls.genericOf}" has an incompatible prefix`,
501
528
  loc: cls.loc,
502
529
  });
503
530
  }
@@ -831,11 +858,11 @@ export function validateModule(mod) {
831
858
  }
832
859
  }
833
860
  for (const fn of mod.functions) {
834
- validateFunction(fn, functionsByName, ffiByName, classesByName, recordsById, recordValidation, unionsById, globalsById, classValidation, errors);
861
+ validateFunction(fn, functionsByName, ffiByName, classesByName, recordsById, recordValidation, unionsById, globalsById, classValidation, errors, mod.workers === true);
835
862
  }
836
863
  return errors;
837
864
  }
838
- function validateFunction(fn, functions, ffiByName, classes, records, recordValidation, unions, globals, classValidation, errors) {
865
+ function validateFunction(fn, functions, ffiByName, classes, records, recordValidation, unions, globals, classValidation, errors, workers) {
839
866
  const locals = new Map(fn.locals.map((l) => [l.id, l]));
840
867
  const err = (message, loc) => errors.push({ message: `in ${fn.name}: ${message}`, loc });
841
868
  const asyncCaches = [
@@ -868,13 +895,37 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
868
895
  if (fn.asyncCycleCacheGlobal !== undefined && fn.asyncCacheGlobal === undefined) {
869
896
  err("an asyncCycleCacheGlobal requires a module asyncCacheGlobal", fn.loc);
870
897
  }
871
- // The class graph's two questions (upcast/downcast/instanceOf/virtualCall
872
- // legality): strict-descendant tests over the base links, and hierarchy
873
- // membership (a class that extends or is extended).
898
+ // Virtual slots and constructor ABIs follow physical inheritance only.
899
+ // Erased family identity does not supply their specialized layout or ABI.
900
+ const isPhysicalSubclass = (sub, sup) => {
901
+ const seen = new Set([sub]);
902
+ for (let c = classes.get(sub)?.base; c !== undefined; c = classes.get(c)?.base) {
903
+ if (seen.has(c))
904
+ return false;
905
+ seen.add(c);
906
+ if (c === sup)
907
+ return true;
908
+ }
909
+ return false;
910
+ };
911
+ // Object casts may also recover an erased family. The module-level
912
+ // prefix check validates the fields exposed by that view.
874
913
  const isStrictSubclass = (sub, sup) => {
875
- for (let c = classes.get(sub); c?.base !== undefined; c = classes.get(c.base)) {
876
- if (c.base === sup)
914
+ const seen = new Set();
915
+ for (let c = classes.get(sub); c; c = c.base === undefined ? undefined : classes.get(c.base)) {
916
+ if (seen.has(c.name))
917
+ return false;
918
+ seen.add(c.name);
919
+ if (c.name !== sub && c.name === sup)
877
920
  return true;
921
+ const families = new Set();
922
+ for (let family = c.genericOf === undefined ? undefined : classes.get(c.genericOf); family; family = family.base === undefined ? undefined : classes.get(family.base)) {
923
+ if (families.has(family.name))
924
+ return false;
925
+ families.add(family.name);
926
+ if (family.name === sup)
927
+ return true;
928
+ }
878
929
  }
879
930
  return false;
880
931
  };
@@ -901,7 +952,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
901
952
  if (declared) {
902
953
  // Preserve class-table order when choosing an abstract slot's ABI.
903
954
  for (const c of classValidation.implementations.get(method) ?? []) {
904
- if (!isStrictSubclass(c.name, className))
955
+ if (!isPhysicalSubclass(c.name, className))
905
956
  continue;
906
957
  hasOverride = true;
907
958
  implementation ??= functions.get(`%${c.name}.${method}`);
@@ -2047,7 +2098,9 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
2047
2098
  ? { argTypes: [STRING], result: STRING }
2048
2099
  : e.method === "slice"
2049
2100
  ? { argTypes: [F64, F64], result: e.receiver.type }
2050
- : e.method === "toReversed"
2101
+ : e.method === "toReversed" ||
2102
+ e.method === "sortPrimitive" ||
2103
+ e.method === "toSortedPrimitive"
2051
2104
  ? { argTypes: [], result: e.receiver.type }
2052
2105
  : e.method === "reverse"
2053
2106
  ? { argTypes: [], result: e.receiver.type }
@@ -2072,6 +2125,12 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
2072
2125
  : e.method === "shift"
2073
2126
  ? { argTypes: [], result: e.type } // union-checked below
2074
2127
  : { argTypes: [], result: F64 }; // length
2128
+ if ((e.method === "sortPrimitive" || e.method === "toSortedPrimitive") &&
2129
+ elem.kind !== "string" &&
2130
+ elem.kind !== "f64" &&
2131
+ elem.kind !== "bool") {
2132
+ err(`arrIntrinsic ${e.method} requires primitive elements, got ${elem.kind}`, e.loc);
2133
+ }
2075
2134
  if (e.method === "getNumber" && elem.kind !== "f64") {
2076
2135
  err(`arrIntrinsic getNumber requires f64 elements, got ${elem.kind}`, e.loc);
2077
2136
  }
@@ -2505,7 +2564,7 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
2505
2564
  checkExpr(e.value);
2506
2565
  if (e.kind === "upcast" && e.type.kind === "classval" && e.value.type.kind === "classval") {
2507
2566
  const [sub, sup] = [e.value.type.className, e.type.className];
2508
- if (!isStrictSubclass(sub, sup)) {
2567
+ if (!isPhysicalSubclass(sub, sup)) {
2509
2568
  err(`upcast: "${sub}" does not extend "${sup}"`, e.loc);
2510
2569
  break;
2511
2570
  }
@@ -3365,6 +3424,13 @@ function validateFunction(fn, functions, ffiByName, classes, records, recordVali
3365
3424
  err(`${e.name} must be void`, e.loc);
3366
3425
  }
3367
3426
  function checkLibCall(e) {
3427
+ if (e.fn === "atomics.op" &&
3428
+ (e.args[0]?.type.kind !== "bytes" ||
3429
+ !["u8", "i8", "u16", "i16", "u32", "i32"].includes(e.args[0].type.elem))) {
3430
+ errors.push({ message: "integer Atomics require an integer typed array", loc: e.loc });
3431
+ }
3432
+ if (e.fn === "worker.new" && !workers)
3433
+ errors.push({ message: "Worker construction requires worker execution mode", loc: e.loc });
3368
3434
  const sig = LIB_FN_SIGS[e.fn];
3369
3435
  if (!sig) {
3370
3436
  err(`libCall of unknown library function "${e.fn}"`, e.loc);