@scriptc/compiler 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +25 -15
  2. package/dist/backend/cycle-analysis.js +1 -0
  3. package/dist/backend/cycle-analysis.js.map +1 -1
  4. package/dist/backend/llvm/classes.js +21 -5
  5. package/dist/backend/llvm/classes.js.map +1 -1
  6. package/dist/backend/llvm/dyn.d.ts +5 -0
  7. package/dist/backend/llvm/dyn.js +166 -99
  8. package/dist/backend/llvm/dyn.js.map +1 -1
  9. package/dist/backend/llvm/emitter.d.ts +2 -2
  10. package/dist/backend/llvm/emitter.js +79 -20
  11. package/dist/backend/llvm/emitter.js.map +1 -1
  12. package/dist/backend/llvm/expr-bytes.d.ts +1 -1
  13. package/dist/backend/llvm/expr-bytes.js +28 -17
  14. package/dist/backend/llvm/expr-bytes.js.map +1 -1
  15. package/dist/backend/llvm/expr-control.js +1 -1
  16. package/dist/backend/llvm/expr-control.js.map +1 -1
  17. package/dist/backend/llvm/expr-dynamic.js +18 -9
  18. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  19. package/dist/backend/llvm/expr-primitives.js +11 -1
  20. package/dist/backend/llvm/expr-primitives.js.map +1 -1
  21. package/dist/backend/llvm/expr-records.js +11 -3
  22. package/dist/backend/llvm/expr-records.js.map +1 -1
  23. package/dist/backend/llvm/expr-stream-bridges.js +125 -17
  24. package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
  25. package/dist/backend/llvm/lib-process.js +23 -3
  26. package/dist/backend/llvm/lib-process.js.map +1 -1
  27. package/dist/backend/llvm/lib-shared.js +45 -2
  28. package/dist/backend/llvm/lib-shared.js.map +1 -1
  29. package/dist/backend/llvm/shapes.js +8 -2
  30. package/dist/backend/llvm/shapes.js.map +1 -1
  31. package/dist/backend/native-toolchain.d.ts +3 -6
  32. package/dist/backend/native-toolchain.js +53 -23
  33. package/dist/backend/native-toolchain.js.map +1 -1
  34. package/dist/backend/native-toolchain.test.js +72 -0
  35. package/dist/backend/native-toolchain.test.js.map +1 -1
  36. package/dist/backend/runtime-abi.d.ts +2 -2
  37. package/dist/backend/runtime-abi.js +2 -2
  38. package/dist/backend/runtime-pack-native.js +4 -1
  39. package/dist/backend/runtime-pack-native.js.map +1 -1
  40. package/dist/backend/runtime-pack-targets.test.js +1 -1
  41. package/dist/backend/runtime-pack.test.js +1 -1
  42. package/dist/backend/targets.js +10 -6
  43. package/dist/backend/targets.js.map +1 -1
  44. package/dist/backend/targets.test.js +7 -0
  45. package/dist/backend/targets.test.js.map +1 -1
  46. package/dist/compat/fetch-profile.js +34 -4
  47. package/dist/compat/fetch-profile.js.map +1 -1
  48. package/dist/diagnostics/diagnostic.js +2 -7
  49. package/dist/diagnostics/diagnostic.js.map +1 -1
  50. package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
  51. package/dist/frontend/lowering/class-callbacks.js +26 -15
  52. package/dist/frontend/lowering/class-callbacks.js.map +1 -1
  53. package/dist/frontend/lowering/class-construction.d.ts +12 -0
  54. package/dist/frontend/lowering/class-construction.js +156 -0
  55. package/dist/frontend/lowering/class-construction.js.map +1 -0
  56. package/dist/frontend/lowering/class-descriptors.d.ts +1 -0
  57. package/dist/frontend/lowering/class-descriptors.js +46 -5
  58. package/dist/frontend/lowering/class-descriptors.js.map +1 -1
  59. package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +11 -1
  60. package/dist/frontend/lowering/class-dynamic-dispatch.js +403 -48
  61. package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
  62. package/dist/frontend/lowering/class-dynamic-dispatch.test.js +2 -1
  63. package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
  64. package/dist/frontend/lowering/class-instance-constructor.js +4 -1
  65. package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
  66. package/dist/frontend/lowering/class-method-values.d.ts +4 -1
  67. package/dist/frontend/lowering/class-method-values.js +72 -7
  68. package/dist/frontend/lowering/class-method-values.js.map +1 -1
  69. package/dist/frontend/lowering/class-prototypes.d.ts +5 -2
  70. package/dist/frontend/lowering/class-prototypes.js +121 -13
  71. package/dist/frontend/lowering/class-prototypes.js.map +1 -1
  72. package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
  73. package/dist/frontend/lowering/class-runtime-statics.js +66 -0
  74. package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
  75. package/dist/frontend/lowering/class-static-data.js +2 -2
  76. package/dist/frontend/lowering/class-static-data.js.map +1 -1
  77. package/dist/frontend/lowering/containers/bytes.js +49 -13
  78. package/dist/frontend/lowering/containers/bytes.js.map +1 -1
  79. package/dist/frontend/lowering/containers/string-and-regexp.js +19 -47
  80. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  81. package/dist/frontend/lowering/error-methods.d.ts +4 -1
  82. package/dist/frontend/lowering/error-methods.js +100 -1
  83. package/dist/frontend/lowering/error-methods.js.map +1 -1
  84. package/dist/frontend/lowering/expressions/native-proxy.js +3 -1
  85. package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
  86. package/dist/frontend/lowering/expressions/nullish-assignment.js +19 -11
  87. package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
  88. package/dist/frontend/lowering/expressions/object-literals.js +38 -7
  89. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  90. package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
  91. package/dist/frontend/lowering/expressions/optional-chains.js +69 -17
  92. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  93. package/dist/frontend/lowering/function-context.d.ts +11 -3
  94. package/dist/frontend/lowering/function-context.js +11 -5
  95. package/dist/frontend/lowering/function-context.js.map +1 -1
  96. package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -0
  97. package/dist/frontend/lowering/generator-dynamic-dispatch.js +39 -1
  98. package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
  99. package/dist/frontend/lowering/lib-boundary.d.ts +2 -0
  100. package/dist/frontend/lowering/lib-boundary.js +54 -1
  101. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  102. package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -1
  103. package/dist/frontend/lowering/lower-builtin-values.js +113 -3
  104. package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
  105. package/dist/frontend/lowering/lower-builtins.d.ts +6 -5
  106. package/dist/frontend/lowering/lower-builtins.js +156 -41
  107. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  108. package/dist/frontend/lowering/lower-calls.d.ts +8 -5
  109. package/dist/frontend/lowering/lower-calls.js +448 -83
  110. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  111. package/dist/frontend/lowering/lower-classes.d.ts +13 -13
  112. package/dist/frontend/lowering/lower-classes.js +650 -176
  113. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  114. package/dist/frontend/lowering/lower-containers.d.ts +9 -0
  115. package/dist/frontend/lowering/lower-containers.js +135 -36
  116. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  117. package/dist/frontend/lowering/lower-dgram.js +3 -2
  118. package/dist/frontend/lowering/lower-dgram.js.map +1 -1
  119. package/dist/frontend/lowering/lower-exprs.d.ts +2 -2
  120. package/dist/frontend/lowering/lower-exprs.js +531 -126
  121. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  122. package/dist/frontend/lowering/lower-generators.js +12 -1
  123. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  124. package/dist/frontend/lowering/lower-island.d.ts +2 -0
  125. package/dist/frontend/lowering/lower-island.js +32 -10
  126. package/dist/frontend/lowering/lower-island.js.map +1 -1
  127. package/dist/frontend/lowering/lower-modules.js +220 -17
  128. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  129. package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
  130. package/dist/frontend/lowering/lower-modules.test.js +39 -0
  131. package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
  132. package/dist/frontend/lowering/lower-stmts.d.ts +7 -3
  133. package/dist/frontend/lowering/lower-stmts.js +135 -26
  134. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  135. package/dist/frontend/lowering/lower-stream.js +1 -1
  136. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  137. package/dist/frontend/lowering/lowerer.d.ts +27 -1
  138. package/dist/frontend/lowering/lowerer.js +172 -50
  139. package/dist/frontend/lowering/lowerer.js.map +1 -1
  140. package/dist/frontend/lowering/lowerer.test.js +149 -3
  141. package/dist/frontend/lowering/lowerer.test.js.map +1 -1
  142. package/dist/frontend/lowering/surfaces.d.ts +2 -0
  143. package/dist/frontend/lowering/surfaces.js +25 -8
  144. package/dist/frontend/lowering/surfaces.js.map +1 -1
  145. package/dist/frontend/lowering/text-decoder-encoding.d.ts +2 -0
  146. package/dist/frontend/lowering/text-decoder-encoding.js +5 -0
  147. package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
  148. package/dist/frontend/lowering/unregistered-class-types.test.js +3 -3
  149. package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
  150. package/dist/frontend/npm-static-prune.js +116 -34
  151. package/dist/frontend/npm-static-prune.js.map +1 -1
  152. package/dist/frontend/npm-static-prune.test.js +8 -0
  153. package/dist/frontend/npm-static-prune.test.js.map +1 -1
  154. package/dist/frontend/program.d.ts +1 -1
  155. package/dist/frontend/program.js +53 -24
  156. package/dist/frontend/program.js.map +1 -1
  157. package/dist/frontend/program.test.js +18 -0
  158. package/dist/frontend/program.test.js.map +1 -1
  159. package/dist/frontend/ts7/ast.js +4 -3
  160. package/dist/frontend/ts7/ast.js.map +1 -1
  161. package/dist/frontend/ts7/semantic-json.js +5 -10
  162. package/dist/frontend/ts7/semantic-json.js.map +1 -1
  163. package/dist/frontend/type-mapper.d.ts +9 -1
  164. package/dist/frontend/type-mapper.js +90 -13
  165. package/dist/frontend/type-mapper.js.map +1 -1
  166. package/dist/frontend/type-mapper.test.js +23 -0
  167. package/dist/frontend/type-mapper.test.js.map +1 -1
  168. package/dist/frontend/union-discriminants.d.ts +1 -1
  169. package/dist/frontend/union-discriminants.js +2 -2
  170. package/dist/frontend/union-discriminants.js.map +1 -1
  171. package/dist/ir/analysis.js +2 -0
  172. package/dist/ir/analysis.js.map +1 -1
  173. package/dist/ir/ir.d.ts +52 -33
  174. package/dist/ir/ir.js +142 -42
  175. package/dist/ir/ir.js.map +1 -1
  176. package/dist/ir/ir.test.js +35 -0
  177. package/dist/ir/ir.test.js.map +1 -1
  178. package/dist/ir/serialize.js +15 -3
  179. package/dist/ir/serialize.js.map +1 -1
  180. package/dist/ir/serialize.test.js +5 -1
  181. package/dist/ir/serialize.test.js.map +1 -1
  182. package/dist/ir/validate.js +80 -11
  183. package/dist/ir/validate.js.map +1 -1
  184. package/dist/ir/validate.test.js +61 -1
  185. package/dist/ir/validate.test.js.map +1 -1
  186. package/dist/native/sanitizer.js +3 -1
  187. package/dist/native/sanitizer.js.map +1 -1
  188. package/dist/native/toolchain.d.ts +1 -1
  189. package/dist/native/toolchain.js +26 -6
  190. package/dist/native/toolchain.js.map +1 -1
  191. package/dist/native/toolchain.test.js +53 -1
  192. package/dist/native/toolchain.test.js.map +1 -1
  193. package/package.json +20 -20
  194. package/surface-manifest.json +56 -81
@@ -42,8 +42,8 @@ export declare class LlEmitter {
42
42
  * immortal (rc == SIZE_MAX) static per (union, unit tag).
43
43
  * RC entry points and the collector skip immortals. */
44
44
  private readonly unitInstances;
45
- /** Interned regex literals: "<flags>/<pattern>" → { symbol, interned
46
- * source/flags literal refs } — one immortal ScrRegex per distinct
45
+ /** Regex literal templates: "<flags>/<pattern>" → { symbol, interned
46
+ * source/flags literal refs } — one immortal ScrRegex template per distinct
47
47
  * (pattern, flags) pair; the bytecode slot starts null and the runtime
48
48
  * compiles it lazily on first use. The source/flags strings intern at
49
49
  * REGISTRATION (bodies emit before the literal table flushes). */
@@ -30,7 +30,7 @@ import { findConstantNumericTables } from "../../ir/constant-tables.js";
30
30
  import { allocateFfiCallbackAdapters, hasForeignFfiCallback, hasRetainedFfiCallback } from "../ffi-callbacks.js";
31
31
  import { RUNTIME_ABI_MARKER } from "../runtime-abi.js";
32
32
  import { computeMayThrow } from "../may-throw.js";
33
- import { mangleArgPack, mangleAsyncSpawn, mangleClassObj, mangleClassStruct, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordStruct, mangleTrampoline, mangleWrapper } from "../mangle.js";
33
+ import { mangleArgPack, mangleAsyncSpawn, mangleClassObj, mangleClassStruct, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordStruct, mangleTrampoline, mangleWrapper, mangleVtInstance } from "../mangle.js";
34
34
  import { BlockBuilder } from "./blocks.js";
35
35
  import { LlvmDebugInfo } from "./debug-info.js";
36
36
  import { f64Lit, ffiNativeTypeLl, ffiNativeParamLl, ffiNativeReturnLl, llvmCommentText } from "./common.js";
@@ -57,7 +57,7 @@ import { buildClassGraph, classEnvironmentIndex, classFieldIndex, classStructSym
57
57
  import { LlDyn } from "./dyn.js";
58
58
  import { LlvmUnsupportedError } from "./unsupported.js";
59
59
  import { LlWalkers } from "./walkers.js";
60
- import { arrNewCall, boxAccess, boxNewCall, computeTraced, elemAccess, FN_ATTRS, llFieldType, releaseSym, retainSym, traceArg, vAdapters, } from "./shapes.js";
60
+ import { arrNewCall, boxAccess, boxNewCall, computeTraced, elemAccess, FN_ATTRS, llFieldType, releaseSym, retainSym, traceArg, typedRefConstructor, vAdapters, } from "./shapes.js";
61
61
  export { LlvmUnsupportedError } from "./unsupported.js";
62
62
  function ffiCallbackDummyLl(callback) {
63
63
  switch (callback.returns) {
@@ -108,8 +108,8 @@ export class LlEmitter {
108
108
  * immortal (rc == SIZE_MAX) static per (union, unit tag).
109
109
  * RC entry points and the collector skip immortals. */
110
110
  unitInstances = new Map();
111
- /** Interned regex literals: "<flags>/<pattern>" → { symbol, interned
112
- * source/flags literal refs } — one immortal ScrRegex per distinct
111
+ /** Regex literal templates: "<flags>/<pattern>" → { symbol, interned
112
+ * source/flags literal refs } — one immortal ScrRegex template per distinct
113
113
  * (pattern, flags) pair; the bytecode slot starts null and the runtime
114
114
  * compiles it lazily on first use. The source/flags strings intern at
115
115
  * REGISTRATION (bodies emit before the literal table flushes). */
@@ -310,6 +310,7 @@ export class LlEmitter {
310
310
  cstr: (text) => this.cstr(text),
311
311
  unitInstanceRef: (unionId, tag) => this.unitInstanceRef(unionId, tag),
312
312
  liveDynRefAdapter: (type) => this.liveDynRefAdapter(type),
313
+ dynPromiseAdapter: (type) => this.dynPromiseAdapter(type),
313
314
  isErrorClass: (name) => this.classMeta.get(name)?.root.def.name === "%Error",
314
315
  classSubtypes: (name) => {
315
316
  const target = this.classMetaOf(name);
@@ -675,6 +676,24 @@ export class LlEmitter {
675
676
  const fnDefs = [];
676
677
  for (const fn of this.mod.functions)
677
678
  fnDefs.push(this.emitFunction(fn));
679
+ const errorViews = [];
680
+ for (const property of ["name", "message"])
681
+ if (this.mod.functions.some((fn) => fn.name === `%error.${property}.read`)) {
682
+ this.declare(`declare void @scr_error_install_${property}_reader(ptr)`);
683
+ errorViews.push(` call void @scr_error_install_${property}_reader(ptr @${mangleFunction(`%error.${property}.read`)})`);
684
+ }
685
+ for (const meta of this.classMeta.values()) {
686
+ if (meta.def.runtime || meta.root.def.name !== "%Error")
687
+ continue;
688
+ const type = { kind: "object", className: meta.def.name };
689
+ const adapter = this.liveDynRefAdapter(type);
690
+ const rc = vAdapters(this.shapeHost, type);
691
+ const key = typeKey(type);
692
+ const name = `sc_error_view_${errorViews.length}`;
693
+ this.resolveThunkDefs.push(`define internal ptr @${name}(ptr %v) ${FN_ATTRS} {`, `entry:`, ` %d = call ptr ${typedRefConstructor(this.shapeHost, type)}(ptr %v, ptr ${rc.retain}, ptr ${rc.release}, ptr ${this.cstr(key)}, ${this.sizeType} ${Buffer.byteLength(key, "utf8")}, ptr @${adapter.snapshot}, ptr ${adapter.commit})`, ` ret ptr %d`, `}`, ``);
694
+ this.declare(`declare void @scr_error_register_dyn(ptr, ptr)`);
695
+ errorViews.push(` call void @scr_error_register_dyn(ptr @${mangleVtInstance(meta.def.name)}, ptr @${name})`);
696
+ }
678
697
  const layouts = emitLlvmLayouts(this.shapeHost, this.mod, this.classMeta, this.classObjs, this.fnByName, (t) => this.llType(t));
679
698
  const shapes = layouts.records;
680
699
  const classShapes = layouts.classes;
@@ -723,9 +742,11 @@ export class LlEmitter {
723
742
  // sc_release_globals tail). Only when the dispatch unit is even
724
743
  // linked (defineProps is the only writer).
725
744
  const runtimeFeatures = moduleRuntimeFeatures(this.mod);
726
- const fnValueProps = runtimeFeatures.dynInvoke ? [...this.fnValues] : [];
745
+ const fnValueProps = [...this.fnValues];
727
746
  if (fnValueProps.length > 0)
728
747
  this.declare(`declare void @scr_box_release(ptr)`);
748
+ if (this.classObjs.size > 0)
749
+ this.declare(`declare void @scr_classobj_clear_properties(ptr)`);
729
750
  const globalReleaseLines = (prefix) => {
730
751
  const lines = [];
731
752
  globals.forEach((g, i) => {
@@ -738,6 +759,8 @@ export class LlEmitter {
738
759
  // cleared so a second release path stays idempotent.
739
760
  lines.push(` %${prefix}fp${i} = load ptr, ptr getelementptr inbounds (%ScrClosure, ptr @${mangleFnClosure(name)}, i64 0, i32 3)`, ` call void @scr_box_release(ptr %${prefix}fp${i}) ; ${name}.props`, ` store ptr null, ptr getelementptr inbounds (%ScrClosure, ptr @${mangleFnClosure(name)}, i64 0, i32 3)`);
740
761
  });
762
+ for (const name of this.classObjs.keys())
763
+ lines.push(` call void @scr_classobj_clear_properties(ptr @${mangleClassObj(name)})`);
741
764
  return lines;
742
765
  };
743
766
  // Exit listeners can read MODULE GLOBALS directly, so they must run
@@ -781,6 +804,15 @@ export class LlEmitter {
781
804
  this.declare(`declare void @scr_events_install()`);
782
805
  if (usesChildProcess)
783
806
  this.declare(`declare void @scr_child_dyn_install()`);
807
+ const childStreamBoxes = usesChildProcess && usesStream &&
808
+ this.classMeta.has("%Readable") && this.classMeta.has("%Writable")
809
+ ? [this.dyn.toDynHelper({ kind: "object", className: "%Readable" }),
810
+ this.dyn.toDynHelper({ kind: "object", className: "%Writable" })]
811
+ : null;
812
+ if (childStreamBoxes) {
813
+ this.declare(`@scr_stream_child_ops = external constant { ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }`);
814
+ this.declare(`declare void @scr_child_dyn_streams_install(ptr, ptr, ptr)`);
815
+ }
784
816
  if (usesFsWatch)
785
817
  this.declare(`declare void @scr_watch_install()`);
786
818
  if (this.ffiHasForeignCallback)
@@ -970,16 +1002,16 @@ export class LlEmitter {
970
1002
  `%ScrUnion = type { ${this.sizeType}, i32, ptr, ptr, ptr, i64 }`,
971
1003
  `%ScrClosure = type { ${this.sizeType}, ptr, ${this.sizeType}, ptr, i32 }`,
972
1004
  `%ScrFfiTable = type { ptr, ${this.sizeType}, ${this.sizeType}, ptr, i8, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
973
- `%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr }`,
1005
+ `%ScrRegex = type { ${this.sizeType}, ptr, ptr, ptr, double, ptr }`,
974
1006
  // ScrArr mirrors scr_runtime.h field-for-field. Live dynamic stream
975
1007
  // commits swap its mutable dense, sparse, presence, and property
976
1008
  // storage while preserving the target object's identity.
977
- `%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType} }`,
1009
+ `%ScrArr = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, i32, ptr, ptr, ptr, ptr, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ${this.sizeType}, ${this.sizeType}, ptr }`,
978
1010
  // The runtime error prefix { rc, vt, name, message, code, cause } and the
979
1011
  // class-object shape { rc, pre, post, ctor, name } — field reads on
980
1012
  // builtin errors and classval loads GEP through these.
981
- `%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr, ptr }`,
982
- `%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr }`,
1013
+ `%ScrError = type { ${this.sizeType}, ptr, ptr, ptr, ptr, ptr, i8, i8, i8, i8, i8, ptr, ptr }`,
1014
+ `%ScrClassObj = type { ${this.sizeType}, ${this.sizeType}, ${this.sizeType}, ptr, ptr, ${this.sizeType}, ${this.sizeType}, ptr, ptr }`,
983
1015
  // The runtime emitter prefix { rc, vt, reg, cls } — user subclasses
984
1016
  // embed it (classes.ts), and bare-emitter GEPs address through it.
985
1017
  `%ScrEmitter = type { ${this.sizeType}, ptr, ptr, ptr }`,
@@ -1054,7 +1086,7 @@ export class LlEmitter {
1054
1086
  // One immortal ScrRegex per (pattern, flags) literal, pointing at
1055
1087
  // the interned source/flags strings. The bc slot starts null (lazy
1056
1088
  // compile, cached by the runtime) — a mutable global, not constant.
1057
- out.push(`@${re.sym} = internal ${tl}global %ScrRegex { ${this.sizeType} -1, ptr ${re.src}, ptr ${re.fl}, ptr null } ; ${key.replace(/\n/g, "\\n")}`);
1089
+ out.push(`@${re.sym} = internal ${tl}global %ScrRegex { ${this.sizeType} -1, ptr ${re.src}, ptr ${re.fl}, ptr null, double 0.0, ptr null } ; ${key.replace(/\n/g, "\\n")}`);
1058
1090
  }
1059
1091
  if (this.regexInstances.size > 0)
1060
1092
  out.push(``);
@@ -1068,7 +1100,7 @@ export class LlEmitter {
1068
1100
  const present = n === 0
1069
1101
  ? "zeroinitializer"
1070
1102
  : `[ ${inst.slots.map(() => "i8 1").join(", ")} ]`;
1071
- out.push(`@${inst.sym}_data = internal constant [${n} x ptr] [ ${inst.slots.map((s) => `ptr ${s}`).join(", ")} ]`, `@${inst.sym}_present = internal constant [${n} x i8] ${present}`, `@${inst.sym} = internal global %ScrArr { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null, ${this.sizeType} 0, ${this.sizeType} 0 }`);
1103
+ out.push(`@${inst.sym}_data = internal constant [${n} x ptr] [ ${inst.slots.map((s) => `ptr ${s}`).join(", ")} ]`, `@${inst.sym}_present = internal constant [${n} x i8] ${present}`, `@${inst.sym} = internal global %ScrArr { ${this.sizeType} -1, ${this.sizeType} ${n}, ${this.sizeType} ${n}, i32 2, ptr null, ptr null, ptr null, ptr @${inst.sym}_data, ptr @${inst.sym}_present, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null, ${this.sizeType} 0, ${this.sizeType} 0, ptr null }`);
1072
1104
  }
1073
1105
  if (this.templateStringsInstances.size > 0)
1074
1106
  out.push(``);
@@ -1150,7 +1182,7 @@ export class LlEmitter {
1150
1182
  // scr_lib_init(argc, argv), then the entry function. An uncaught
1151
1183
  // exception escaping top-level code prints and exits 1 (Node).
1152
1184
  // The exception epilogue is emitted when the entry may throw.
1153
- const stamps = [];
1185
+ const stamps = [...errorViews];
1154
1186
  for (const iv of this.errorIntervals) {
1155
1187
  const fields = [[0, iv.pre], [1, iv.post]];
1156
1188
  for (const [field, value] of fields) {
@@ -1208,7 +1240,7 @@ export class LlEmitter {
1208
1240
  // Event-surface programs (signal/exit listeners) fill the loop's
1209
1241
  // nullable event hooks before %main — scr_events.c links only when
1210
1242
  // this line is emitted (native-toolchain.ts gates on the same predicate).
1211
- ...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []),
1243
+ ...(usesEvents ? [` call void @scr_events_install()`] : []), ...(usesChildProcess ? [` call void @scr_child_dyn_install()`] : []), ...(childStreamBoxes ? [` call void @scr_child_dyn_streams_install(ptr @scr_stream_child_ops, ptr @${childStreamBoxes[0]}, ptr @${childStreamBoxes[1]})`] : []),
1212
1244
  // fs.watch programs fill the loop's watch hooks the same way —
1213
1245
  // scr_watch.c links only when this line is emitted.
1214
1246
  ...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(this.ffiHasForeignCallback ? [` call void @scr_ffi_install()`] : []), ...(snapshotsTlsCa ? [` call void @scr_tls_ca_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(embedsZlib ? [` call void @scr_zlib_island_install()`] : []), ...(embedsNet ? [` call void @scr_net_island_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesDgram ? [` call void @scr_dgram_install()`] : []), ...(usesHttp2 ? [` call void @scr_http2_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`, ...(usesIsland
@@ -1682,6 +1714,10 @@ export class LlEmitter {
1682
1714
  this.declare(`declare void @scr_promise_fulfill_str(ptr, ptr)`);
1683
1715
  tr.push(` call void @scr_promise_fulfill_str(ptr %pr, ptr %r) ; moves in`);
1684
1716
  break;
1717
+ case "dyn":
1718
+ this.declare(`declare void @scr_promise_resolve_dyn(ptr, ptr)`);
1719
+ tr.push(` call void @scr_promise_resolve_dyn(ptr %pr, ptr %r) ; moves in`);
1720
+ break;
1685
1721
  default: {
1686
1722
  const v = vAdapters(this.shapeHost, ret);
1687
1723
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
@@ -2784,6 +2820,10 @@ export class LlEmitter {
2784
2820
  this.declare(`declare void @scr_promise_fulfill_str(ptr, ptr)`);
2785
2821
  this.B.line(`call void @scr_promise_fulfill_str(ptr ${pr}, ptr ${v.name}) ; moves in`);
2786
2822
  break;
2823
+ case "dyn":
2824
+ this.declare(`declare void @scr_promise_resolve_dyn(ptr, ptr)`);
2825
+ this.B.line(`call void @scr_promise_resolve_dyn(ptr ${pr}, ptr ${v.name}) ; moves in`);
2826
+ break;
2787
2827
  default: {
2788
2828
  const rc = vAdapters(this.shapeHost, ret);
2789
2829
  this.declare(`declare void @scr_promise_fulfill_ref(ptr, ptr, ptr, ptr, ptr)`);
@@ -3151,8 +3191,8 @@ export class LlEmitter {
3151
3191
  case "bytesSet": {
3152
3192
  // Typed-array element write: same evaluation order as arraySet;
3153
3193
  // the value is a scalar (the kind-specific inline path coerces
3154
- // JS-exactly), so no ownership moves. Any invalid index traps — no
3155
- // append. IrBytesElem is static, so never rediscover it through the
3194
+ // JS-exactly), so no ownership moves. Invalid writes are ignored.
3195
+ // IrBytesElem is static, so never rediscover it through the
3156
3196
  // generic runtime switch in a hot loop.
3157
3197
  const arr = this.emitStableReceiver(s.arr, [s.index, s.value]);
3158
3198
  const integerIndex = this.emitIntegerLoopIndex(s.index);
@@ -3185,6 +3225,17 @@ export class LlEmitter {
3185
3225
  else {
3186
3226
  this.storeField(ptr, type, v.name);
3187
3227
  }
3228
+ if (s.kind === "fieldSet" && s.field === "name" && this.classMeta.get(s.className)?.root.def.name === "%Error") {
3229
+ const present = this.classFieldPtr(obj.name, s.className, "%namePresent").ptr;
3230
+ const enumerable = this.classFieldPtr(obj.name, s.className, "%nameEnumerable").ptr;
3231
+ const wasPresent = B.tmp(), wasEnumerable = B.tmp(), isPresent = B.tmp(), nextEnumerable = B.tmp();
3232
+ B.line(`${wasPresent} = load i8, ptr ${present}`);
3233
+ B.line(`${wasEnumerable} = load i8, ptr ${enumerable}`);
3234
+ B.line(`${isPresent} = icmp ne i8 ${wasPresent}, 0`);
3235
+ B.line(`${nextEnumerable} = select i1 ${isPresent}, i8 ${wasEnumerable}, i8 1`);
3236
+ B.line(`store i8 1, ptr ${present}`);
3237
+ B.line(`store i8 ${nextEnumerable}, ptr ${enumerable}`);
3238
+ }
3188
3239
  break;
3189
3240
  }
3190
3241
  case "recordKeyDelete": {
@@ -3709,10 +3760,9 @@ export class LlEmitter {
3709
3760
  case "rethrow": {
3710
3761
  // Re-raise the saved snapshot (payload retained — the binding
3711
3762
  // local releases with its scope) and unwind like `throw`.
3712
- const c = B.tmp();
3713
- B.line(`${c} = load ptr, ptr %${mangleLocal(s.localId)}`);
3763
+ const c = this.emitExpr({ kind: "varRef", localId: s.localId, type: CAUGHT, loc: s.loc });
3714
3764
  this.declare(`declare void @scr_rethrow(ptr)`);
3715
- B.line(`call void @scr_rethrow(ptr ${c})`);
3765
+ B.line(`call void @scr_rethrow(ptr ${c.name})`);
3716
3766
  this.emitUnwind();
3717
3767
  break;
3718
3768
  }
@@ -3830,8 +3880,17 @@ export class LlEmitter {
3830
3880
  this.emitBlock(s.catchBody, (scope) => {
3831
3881
  const c = B.tmp();
3832
3882
  B.line(`${c} = call ptr @scr_exc_take() ; catch binding`);
3833
- B.line(`store ptr ${c}, ptr ${slot}`);
3834
- scope.push({ slot, type: CAUGHT });
3883
+ if (this.currentLocals.get(s.catchLocalId)?.boxed) {
3884
+ const box = B.tmp();
3885
+ B.line(`${box} = ${boxNewCall(this.shapeHost, CAUGHT)} ; captured exception`);
3886
+ this.boxSet(box, CAUGHT, c);
3887
+ B.line(`store ptr ${box}, ptr ${slot}`);
3888
+ scope.push({ slot, type: CAUGHT, boxed: true });
3889
+ }
3890
+ else {
3891
+ B.line(`store ptr ${c}, ptr ${slot}`);
3892
+ scope.push({ slot, type: CAUGHT });
3893
+ }
3835
3894
  });
3836
3895
  }
3837
3896
  else {