@scriptc/compiler 0.1.5 → 0.1.7

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 (139) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +0 -1
  2. package/ambient/scriptc.d.ts +13 -5
  3. package/dist/backend/c/c-emitter.d.ts +5 -0
  4. package/dist/backend/c/c-emitter.js +15 -0
  5. package/dist/backend/c/c-emitter.js.map +1 -1
  6. package/dist/backend/c/exprs.js +81 -9
  7. package/dist/backend/c/exprs.js.map +1 -1
  8. package/dist/backend/c/stmts.js +25 -1
  9. package/dist/backend/c/stmts.js.map +1 -1
  10. package/dist/backend/c/walkers.js +2 -3
  11. package/dist/backend/c/walkers.js.map +1 -1
  12. package/dist/backend/debug-symbols.d.ts +8 -0
  13. package/dist/backend/debug-symbols.js +52 -0
  14. package/dist/backend/debug-symbols.js.map +1 -0
  15. package/dist/backend/link-plan.d.ts +1 -0
  16. package/dist/backend/link-plan.js +2 -0
  17. package/dist/backend/link-plan.js.map +1 -1
  18. package/dist/backend/linker.js +8 -0
  19. package/dist/backend/linker.js.map +1 -1
  20. package/dist/backend/llvm/blocks.d.ts +2 -0
  21. package/dist/backend/llvm/blocks.js +18 -2
  22. package/dist/backend/llvm/blocks.js.map +1 -1
  23. package/dist/backend/llvm/debug-info.d.ts +32 -0
  24. package/dist/backend/llvm/debug-info.js +203 -0
  25. package/dist/backend/llvm/debug-info.js.map +1 -0
  26. package/dist/backend/llvm/dyn.js +4 -10
  27. package/dist/backend/llvm/dyn.js.map +1 -1
  28. package/dist/backend/llvm/emitter.d.ts +2 -0
  29. package/dist/backend/llvm/emitter.js +49 -4
  30. package/dist/backend/llvm/emitter.js.map +1 -1
  31. package/dist/backend/llvm/expr-containers.js +28 -2
  32. package/dist/backend/llvm/expr-containers.js.map +1 -1
  33. package/dist/backend/llvm/expr-dynamic.js +10 -0
  34. package/dist/backend/llvm/expr-dynamic.js.map +1 -1
  35. package/dist/backend/llvm/lib-filesystem.js +37 -0
  36. package/dist/backend/llvm/lib-filesystem.js.map +1 -1
  37. package/dist/backend/llvm/lib-process.js +4 -3
  38. package/dist/backend/llvm/lib-process.js.map +1 -1
  39. package/dist/backend/llvm/lib-shared.js +9 -0
  40. package/dist/backend/llvm/lib-shared.js.map +1 -1
  41. package/dist/backend/llvm/split.js +4 -1
  42. package/dist/backend/llvm/split.js.map +1 -1
  43. package/dist/backend/llvm/split.test.js +26 -1
  44. package/dist/backend/llvm/split.test.js.map +1 -1
  45. package/dist/backend/native-toolchain.js +58 -8
  46. package/dist/backend/native-toolchain.js.map +1 -1
  47. package/dist/backend/native-toolchain.test.js +10 -0
  48. package/dist/backend/native-toolchain.test.js.map +1 -1
  49. package/dist/backend/source-locations.d.ts +12 -0
  50. package/dist/backend/source-locations.js +32 -0
  51. package/dist/backend/source-locations.js.map +1 -0
  52. package/dist/backend/source-locations.test.d.ts +1 -0
  53. package/dist/backend/source-locations.test.js +16 -0
  54. package/dist/backend/source-locations.test.js.map +1 -0
  55. package/dist/coverage/surface-manifest.js +6 -1
  56. package/dist/coverage/surface-manifest.js.map +1 -1
  57. package/dist/diagnostics/diagnostic.d.ts +4 -0
  58. package/dist/diagnostics/diagnostic.js +12 -0
  59. package/dist/diagnostics/diagnostic.js.map +1 -1
  60. package/dist/executable/executable-cache.js +28 -4
  61. package/dist/executable/executable-cache.js.map +1 -1
  62. package/dist/executable/executable-cache.test.js +23 -0
  63. package/dist/executable/executable-cache.test.js.map +1 -1
  64. package/dist/frontend/arguments-usage.d.ts +6 -0
  65. package/dist/frontend/arguments-usage.js +40 -0
  66. package/dist/frontend/arguments-usage.js.map +1 -0
  67. package/dist/frontend/binding-source.d.ts +4 -0
  68. package/dist/frontend/binding-source.js +18 -0
  69. package/dist/frontend/binding-source.js.map +1 -0
  70. package/dist/frontend/lowering/array-indexed-mutation.d.ts +8 -0
  71. package/dist/frontend/lowering/array-indexed-mutation.js +176 -0
  72. package/dist/frontend/lowering/array-indexed-mutation.js.map +1 -0
  73. package/dist/frontend/lowering/containers/string-and-regexp.d.ts +7 -0
  74. package/dist/frontend/lowering/containers/string-and-regexp.js +190 -13
  75. package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
  76. package/dist/frontend/lowering/expressions/object-literals.js +13 -8
  77. package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
  78. package/dist/frontend/lowering/expressions/optional-chains.d.ts +5 -6
  79. package/dist/frontend/lowering/expressions/optional-chains.js +7 -6
  80. package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
  81. package/dist/frontend/lowering/indexed-comparison.d.ts +6 -0
  82. package/dist/frontend/lowering/indexed-comparison.js +30 -0
  83. package/dist/frontend/lowering/indexed-comparison.js.map +1 -0
  84. package/dist/frontend/lowering/lower-builtins.d.ts +1 -1
  85. package/dist/frontend/lowering/lower-builtins.js +21 -10
  86. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  87. package/dist/frontend/lowering/lower-calls.d.ts +2 -9
  88. package/dist/frontend/lowering/lower-calls.js +406 -40
  89. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  90. package/dist/frontend/lowering/lower-classes.js +3 -27
  91. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  92. package/dist/frontend/lowering/lower-containers.d.ts +8 -2
  93. package/dist/frontend/lowering/lower-containers.js +454 -104
  94. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  95. package/dist/frontend/lowering/lower-exprs.js +134 -18
  96. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  97. package/dist/frontend/lowering/lower-island.d.ts +1 -1
  98. package/dist/frontend/lowering/lower-island.js +1 -1
  99. package/dist/frontend/lowering/lower-modules.js +19 -8
  100. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  101. package/dist/frontend/lowering/lower-stmts.js +4 -37
  102. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  103. package/dist/frontend/lowering/lowerer.js +14 -3
  104. package/dist/frontend/lowering/lowerer.js.map +1 -1
  105. package/dist/frontend/lowering/surfaces.d.ts +3 -1
  106. package/dist/frontend/lowering/surfaces.js +50 -7
  107. package/dist/frontend/lowering/surfaces.js.map +1 -1
  108. package/dist/frontend/program.d.ts +5 -0
  109. package/dist/frontend/program.js +216 -32
  110. package/dist/frontend/program.js.map +1 -1
  111. package/dist/frontend/program.test.d.ts +1 -0
  112. package/dist/frontend/program.test.js +117 -0
  113. package/dist/frontend/program.test.js.map +1 -0
  114. package/dist/frontend/type-mapper.d.ts +4 -2
  115. package/dist/frontend/type-mapper.js +249 -186
  116. package/dist/frontend/type-mapper.js.map +1 -1
  117. package/dist/frontend/type-mapper.test.d.ts +1 -0
  118. package/dist/frontend/type-mapper.test.js +86 -0
  119. package/dist/frontend/type-mapper.test.js.map +1 -0
  120. package/dist/index.d.ts +2 -1
  121. package/dist/index.js +7 -2
  122. package/dist/index.js.map +1 -1
  123. package/dist/ir/analysis.js +4 -2
  124. package/dist/ir/analysis.js.map +1 -1
  125. package/dist/ir/ir.d.ts +33 -14
  126. package/dist/ir/ir.js +5 -1
  127. package/dist/ir/ir.js.map +1 -1
  128. package/dist/ir/validate.js +57 -31
  129. package/dist/ir/validate.js.map +1 -1
  130. package/dist/ir/validate.test.js +17 -0
  131. package/dist/ir/validate.test.js.map +1 -1
  132. package/dist/library/compiler-self-identity.d.ts +1 -1
  133. package/dist/library/compiler-self-identity.js +31 -15
  134. package/dist/library/compiler-self-identity.js.map +1 -1
  135. package/dist/library/compiler-self-identity.test.d.ts +1 -0
  136. package/dist/library/compiler-self-identity.test.js +93 -0
  137. package/dist/library/compiler-self-identity.test.js.map +1 -0
  138. package/package.json +17 -17
  139. package/surface-manifest.json +155 -4
@@ -1,6 +1,8 @@
1
1
  import type { IrModule } from "../../ir/ir.js";
2
2
  export { LlvmUnsupportedError } from "./unsupported.js";
3
3
  export interface LlvmTargetOptions {
4
+ /** Exact frontend sources for dev-build locations and variable metadata. */
5
+ debugSources?: ReadonlyMap<string, string>;
4
6
  /** Pointer width of the target C ABI. Native targets are 64-bit today. */
5
7
  pointerBits?: 32 | 64;
6
8
  /** Select the WASI libc entry-point convention. */
@@ -74,6 +74,7 @@ import { RUNTIME_ABI_MARKER } from "../runtime-abi.js";
74
74
  import { computeMayThrow } from "../c/may-throw.js";
75
75
  import { mangleArgPack, mangleAsyncSpawn, mangleClassObj, mangleFnClosure, mangleFunction, mangleGenDrop, mangleGenSpawn, mangleGlobal, mangleLocal, mangleRecordStruct, mangleTrampoline, mangleWrapper } from "../mangle.js";
76
76
  import { BlockBuilder } from "./blocks.js";
77
+ import { LlvmDebugInfo } from "./debug-info.js";
77
78
  import { f64Lit, ffiNativeTypeLl, llvmCommentText } from "./common.js";
78
79
  import { emitLiteralExpr, emitOperatorExpr, emitStringExpr, emitContainerExpr, emitRecordExpr } from "./expr-primitives.js";
79
80
  import { emitControlExpr } from "./expr-control.js";
@@ -114,7 +115,8 @@ function ffiCallbackDummyLl(callback) {
114
115
  }
115
116
  }
116
117
  export function emitLlvmModule(mod, options = {}) {
117
- return new LlEmitter(scalarizeNumericRecords(mod), options).emit();
118
+ // Keep source storage intact for debugger inspection in dev builds.
119
+ return new LlEmitter(options.debugSources === undefined ? scalarizeNumericRecords(mod) : mod, options).emit();
118
120
  }
119
121
  /** LLVM c"..." payload for a UTF-8 literal, NUL-terminated like the C
120
122
  * emitter's flexible-array-member initializer. */
@@ -133,6 +135,8 @@ function llStrBytes(text) {
133
135
  }
134
136
  class LlEmitter {
135
137
  mod;
138
+ debug;
139
+ debugScope = null;
136
140
  sizeType;
137
141
  cycleColorOffset;
138
142
  wasi;
@@ -285,6 +289,7 @@ class LlEmitter {
285
289
  logArgSlots = 0;
286
290
  constructor(mod, options) {
287
291
  this.mod = mod;
292
+ this.debug = options.debugSources === undefined ? null : new LlvmDebugInfo(mod.sourceFile, options.debugSources, options.pointerBits, mod.unions);
288
293
  this.constantNumericTables = findConstantNumericTables(mod);
289
294
  this.sizeType = options.pointerBits === 32 ? "i32" : "i64";
290
295
  this.wasi = options.wasi === true;
@@ -1060,7 +1065,8 @@ class LlEmitter {
1060
1065
  for (const g of globals) {
1061
1066
  const ty = this.llType(g.type);
1062
1067
  const zero = ty === "double" ? f64Lit(0) : ty === "ptr" ? "null" : "false";
1063
- out.push(`@${mangleGlobal(g.id)} = internal ${tl}global ${ty} ${zero} ; ${g.name}`);
1068
+ const debug = this.debug?.global(g);
1069
+ out.push(`@${mangleGlobal(g.id)} = internal ${tl}global ${ty} ${zero}${debug ? `, !dbg ${debug}` : ""} ; ${g.name}`);
1064
1070
  }
1065
1071
  if (globals.length > 0)
1066
1072
  out.push(``);
@@ -1128,6 +1134,8 @@ class LlEmitter {
1128
1134
  if (hasNoInlineRecordClone)
1129
1135
  out.push(`attributes #2 = { noinline sanitize_address }`);
1130
1136
  out.push(``);
1137
+ if (this.debug !== null)
1138
+ out.push(this.debug.render());
1131
1139
  return out.join("\n");
1132
1140
  }
1133
1141
  out.push(`define i32 @${this.wasi ? "__main_argc_argv" : "main"}(i32 %argc, ptr %argv) ${FN_ATTRS} {`, `entry:`, ...(this.runtimeAbiMarker ? [` call void @${RUNTIME_ABI_MARKER}()`] : []), ` call void @scr_init()`, ...stamps,
@@ -1230,6 +1238,8 @@ class LlEmitter {
1230
1238
  // lane's -fsanitize=address link activates instrumentation over the
1231
1239
  // emitted functions too (the runtime TUs get theirs from clang).
1232
1240
  `attributes #0 = { sanitize_address }`, ...(this.wasi ? [`attributes #1 = { sanitize_address presplitcoroutine }`] : []), ...(hasNoInlineRecordClone ? [`attributes #2 = { noinline sanitize_address }`] : []), ``);
1241
+ if (this.debug !== null)
1242
+ out.push(this.debug.render());
1233
1243
  return out.join("\n");
1234
1244
  }
1235
1245
  /** LIBRARY mode: the profile-declared external definitions — the
@@ -2015,6 +2025,20 @@ class LlEmitter {
2015
2025
  this.declare(`declare void @scr_throw_obj(ptr, ptr, ptr, ptr)`);
2016
2026
  B.line(`call void @scr_throw_obj(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)})`);
2017
2027
  }
2028
+ else if (t.kind === "symbol" || t.kind === "bigint" || t.kind === "func" || t.kind === "classval") {
2029
+ const rc = vAdapters(this, t);
2030
+ this.declare(`declare void @scr_throw_primitive_ref(ptr, ptr, ptr, ptr)`);
2031
+ B.line(`call void @scr_throw_primitive_ref(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr null)`);
2032
+ }
2033
+ else if (t.kind === "dyn" || t.kind === "jsval") {
2034
+ const rc = vAdapters(this, t);
2035
+ const test = t.kind === "dyn" ? "scr_dyn_is_object" : "scr_jsval_is_object";
2036
+ this.declare(`declare zeroext i1 @${test}(ptr)`);
2037
+ this.declare(`declare void @scr_throw_ref_classified(ptr, ptr, ptr, ptr, i1 zeroext)`);
2038
+ const object = B.tmp();
2039
+ B.line(`${object} = call zeroext i1 @${test}(ptr ${v.name})`);
2040
+ B.line(`call void @scr_throw_ref_classified(ptr ${v.name}, ptr ${rc.retain}, ptr ${rc.release}, ptr ${traceArg(this, t)}, i1 zeroext ${object})`);
2041
+ }
2018
2042
  else {
2019
2043
  const rc = vAdapters(this, t);
2020
2044
  this.declare(`declare void @scr_throw_ref(ptr, ptr, ptr, ptr)`);
@@ -2341,6 +2365,13 @@ class LlEmitter {
2341
2365
  throw new InternalCompilerError(`llvm emitter bug: unknown binding ${id}`);
2342
2366
  return { kind: "global", slot: `@${mangleGlobal(id)}`, type: g };
2343
2367
  }
2368
+ emitDebugLocal(local, slot, arg = 0, captured = false) {
2369
+ const debug = this.debug?.local(local, this.debugScope, arg, captured);
2370
+ if (!debug)
2371
+ return;
2372
+ this.declare("declare void @llvm.dbg.declare(metadata, metadata, metadata)");
2373
+ this.B.entryAllocas.push(`call void @llvm.dbg.declare(metadata ptr ${slot}, metadata ${debug.variable}, metadata ${debug.expression}), !dbg ${debug.location}`);
2374
+ }
2344
2375
  /** Loads a boxed binding's box pointer out of its slot. */
2345
2376
  loadBox(slot) {
2346
2377
  const b = this.B.tmp();
@@ -2541,6 +2572,8 @@ class LlEmitter {
2541
2572
  emitFunction(fn) {
2542
2573
  const B = new BlockBuilder();
2543
2574
  this.B = B;
2575
+ this.debugScope = this.debug?.function(fn) ?? null;
2576
+ B.debugLocation = this.debug?.location(fn.loc, this.debugScope) ?? null;
2544
2577
  this.frames = [];
2545
2578
  this.scopes = [];
2546
2579
  this.jumpTargets = [];
@@ -2598,6 +2631,7 @@ class LlEmitter {
2598
2631
  ? "ptr"
2599
2632
  : this.llType(local.type);
2600
2633
  B.entryAllocas.push(`%${mangleLocal(local.id)} = alloca ${slotTy} ; ${local.name}`);
2634
+ this.emitDebugLocal(local, `%${mangleLocal(local.id)}`, fn.params.findIndex((p) => p.localId === local.id) + 1, this.captureIds.has(local.id));
2601
2635
  // Refcounted/boxed locals start NULL (the C prologue's `= NULL`):
2602
2636
  // scope-exit releases run whether or not an assign ever did.
2603
2637
  if (paramIds.has(local.id) || this.captureIds.has(local.id))
@@ -2697,7 +2731,8 @@ class LlEmitter {
2697
2731
  params.unshift("ptr %sc_env");
2698
2732
  const ret = this.llType(fn.returnType);
2699
2733
  const attrs = coro !== null ? "#1" : FN_ATTRS;
2700
- return `define internal ${ret} @${mangleFunction(fn.name)}(${params.join(", ")}) ${attrs} { ; ${fn.name}\n${B.render()}\n}`;
2734
+ const debug = this.debugScope === null ? "" : ` !dbg ${this.debugScope}`;
2735
+ return `define internal ${ret} @${mangleFunction(fn.name)}(${params.join(", ")}) ${attrs}${debug} { ; ${fn.name}\n${B.render()}\n}`;
2701
2736
  }
2702
2737
  // ── statements ──────────────────────────────────────────────────────────
2703
2738
  emitStmts(stmts) {
@@ -2726,6 +2761,16 @@ class LlEmitter {
2726
2761
  this.releaseScope(scope);
2727
2762
  }
2728
2763
  emitStmt(s) {
2764
+ const previous = this.B.debugLocation;
2765
+ this.B.debugLocation = this.debug?.location(s.loc, this.debugScope) ?? null;
2766
+ try {
2767
+ this.emitStmtBody(s);
2768
+ }
2769
+ finally {
2770
+ this.B.debugLocation = previous;
2771
+ }
2772
+ }
2773
+ emitStmtBody(s) {
2729
2774
  const B = this.B;
2730
2775
  this.frames.push([]);
2731
2776
  switch (s.kind) {
@@ -3123,7 +3168,7 @@ class LlEmitter {
3123
3168
  case "for": {
3124
3169
  // The init's scope wraps the whole loop (break/continue must NOT
3125
3170
  // release it — scopeDepth captured after the push, C parity).
3126
- const integerLoop = matchIntegerBytesForLoop(s, this.currentLocals);
3171
+ const integerLoop = this.debug === null ? matchIntegerBytesForLoop(s, this.currentLocals) : null;
3127
3172
  this.scopes.push([]);
3128
3173
  let integerSlot = null;
3129
3174
  if (integerLoop) {