@scriptc/compiler 0.0.14 → 0.0.15

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 (36) hide show
  1. package/dist/backend/cc.d.ts +15 -0
  2. package/dist/backend/cc.js +32 -7
  3. package/dist/backend/cc.js.map +1 -1
  4. package/dist/backend/emission/emit-exprs.js +47 -0
  5. package/dist/backend/emission/emit-exprs.js.map +1 -1
  6. package/dist/backend/emission/emitter.d.ts +3 -1
  7. package/dist/backend/emission/emitter.js +32 -0
  8. package/dist/backend/emission/emitter.js.map +1 -1
  9. package/dist/backend/llvm/emitter.js +104 -0
  10. package/dist/backend/llvm/emitter.js.map +1 -1
  11. package/dist/diagnostics/diagnostic.d.ts +13 -0
  12. package/dist/diagnostics/diagnostic.js +44 -0
  13. package/dist/diagnostics/diagnostic.js.map +1 -1
  14. package/dist/ffi/profile.d.ts +29 -0
  15. package/dist/ffi/profile.js +191 -0
  16. package/dist/ffi/profile.js.map +1 -0
  17. package/dist/frontend/lowering/lower-calls.d.ts +17 -0
  18. package/dist/frontend/lowering/lower-calls.js +191 -2
  19. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  20. package/dist/frontend/lowering/lowerer.d.ts +16 -1
  21. package/dist/frontend/lowering/lowerer.js +44 -5
  22. package/dist/frontend/lowering/lowerer.js.map +1 -1
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.js +141 -80
  25. package/dist/index.js.map +1 -1
  26. package/dist/ir/nodes.d.ts +32 -1
  27. package/dist/ir/nodes.js.map +1 -1
  28. package/dist/ir/serialize.d.ts +1 -1
  29. package/dist/ir/serialize.js +1 -1
  30. package/dist/ir/validate.js +54 -2
  31. package/dist/ir/validate.js.map +1 -1
  32. package/dist/library/int-infer.js +1 -0
  33. package/dist/library/int-infer.js.map +1 -1
  34. package/dist/library/int-infer.test.js +1 -1
  35. package/package.json +2 -2
  36. package/surface-manifest.json +1 -1
@@ -1,7 +1,7 @@
1
1
  import * as ts from "../ts7/adapter.js";
2
2
  import type { ScrDiagnostic } from "../../diagnostics/diagnostic.js";
3
3
  import { UNSUPPORTED } from "../../diagnostics/diagnostic.js";
4
- import type { IrClassDef, IrExpr, IrFunction, IrGlobal, IrLocal, IrModule, IrParam, IrRecordShape, IrStmt, IrType, IrUnionDef, SrcLoc } from "../../ir/nodes.js";
4
+ import type { IrClassDef, IrExpr, IrFfiImport, IrFunction, IrGlobal, IrLocal, IrModule, IrParam, IrRecordShape, IrStmt, IrType, IrUnionDef, SrcLoc } from "../../ir/nodes.js";
5
5
  import { type DynamicImportResolution, type NpmBuiltinUse, type NpmLazyTrap } from "../npm.js";
6
6
  import { type StartupCrash } from "../program.js";
7
7
  import { ShapeRegistry, type TypeMapperCtx, UnionRegistry } from "../types.js";
@@ -210,6 +210,11 @@ export interface LowerOptions {
210
210
  * OUTSIDE the graph, so discovery seeds them alongside the init
211
211
  * bodies. Names are the entry file's unqualified declaration names. */
212
212
  libRoots?: readonly string[];
213
+ /** Outbound native FFI declarations from a validated format-1 manifest.
214
+ * Calls of their exact ambient TypeScript bindings lower to direct C ABI
215
+ * imports; without this option ambient declarations keep Node's ordinary
216
+ * ReferenceError behavior. */
217
+ ffiImports?: readonly IrFfiImport[];
213
218
  }
214
219
  /** The Lowerer's pass configuration (see lowerToIr). */
215
220
  export interface LowererMode {
@@ -230,6 +235,11 @@ export interface LowererMode {
230
235
  * module init — Node refuses the whole graph before anything evaluates,
231
236
  * so nothing runs. */
232
237
  startupCrash?: StartupCrash | null;
238
+ /** The build's outbound native FFI declarations. */
239
+ ffiImports?: readonly IrFfiImport[];
240
+ /** Program-validated ambient declaration symbols for each FFI name.
241
+ * Undefined in discovery's legacy call-local validation path. */
242
+ ffiBindingSymbols?: ReadonlyMap<string, ReadonlySet<ts.Symbol>>;
233
243
  }
234
244
  /** Build lowering runs in two passes over the same ts.Program:
235
245
  *
@@ -699,6 +709,11 @@ export declare class Lowerer {
699
709
  readonly targetPlatform: string;
700
710
  /** LowererMode.startupCrash — buildMain opens %main with the throw. */
701
711
  readonly startupCrash: StartupCrash | null;
712
+ /** Outbound native bindings by their source-level ambient name. */
713
+ readonly ffiImports: readonly IrFfiImport[];
714
+ readonly ffiImportsByName: ReadonlyMap<string, IrFfiImport>;
715
+ /** Non-null after whole-program FFI declaration validation. */
716
+ readonly ffiBindingSymbols: ReadonlyMap<string, ReadonlySet<ts.Symbol>> | null;
702
717
  /** Symbols a POISONED declaration statement would have bound: the
703
718
  * declaration's own diagnostic is already recorded, and no local/global
704
719
  * registered, so later references fall through every resolution step —
@@ -23,7 +23,7 @@ import { boundaryIntoIslandMsg, boundaryOutOfIslandMsg, builtinConstLit, builtin
23
23
  import { splitFiles, collectProgram, collectNpmImports, collectJsonImports, moduleArtifacts, collectGlobals, declSymbolOf, defaultExportSymbolOf, lowerFileInit, lowerDefaultExport, buildMain, appendDynamicImportModules } from "./lower-modules.js";
24
24
  import { registerBuiltinErrorClasses, registerBuiltinEmitterClass, registerBuiltinStreamClasses, builtinErrorInfoOf, builtinEmitterInfoOf, builtinStreamInfoOf, analyzeClassDecoration, classIteratorDrainCall, classIteratorNextCall, classIteratorOf, classIteratorOpenCall, classIteratorRestDrainCall, classMemberNameOf, classValueRef, collectClassShape, exactClassOfReceiver, collectClassShapeInner, ctorAbiEquals, findMethodOn, findStaticOn, findGenericMethodOn, findGenericStaticOn, genericClassInstanceType, isSubclassOf, inHierarchy, overrideBelow, staticShadowBelow, upcastTo, lowerClassMembers, lowerClassCtor, lowerClassExpression, lowerClassExpressionInfo, lowerClassMethodMember, lowerClassValueProperty, lowerStaticMethod, throwingSetterFn, fieldInitStmts, lowerStaticFieldInits, lowerStaticFieldRead, lowerDerivedCtorBody, superCallStmt, lowerSuperMethodCall, superThisRef, lowerSuperAccessorRead, lowerSuperAccessorWrite, inheritsBuiltinErrorCtor, inheritsBuiltinEmitterCtor, errorMessageArg, lowerNew, accessorCall } from "./lower-classes.js";
25
25
  import { mixinCallClassInfoOf, mixinIntersectionInstanceType } from "./lower-mixins.js";
26
- import { bindingNeverReassigned, bodyReadsArguments, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, completeArgs, wrappedUndefined, undefinedArgFor, requireExactArityValue, bodyReturnType, declaredReturnType, collectSignature, collectSignatureInner, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, lowerCall, lowerTimersMemberCall, lowerPromiseMethodCall, lowerFilterNarrowCall, isTopLevelFnSymbol, lowerNestedFunctionDecl, lambdaSignature, lowerLambda, lowerFunction } from "./lower-calls.js";
26
+ import { bindingNeverReassigned, bodyReadsArguments, isThisParameter, paramShape, paramShapes, checkDefaultParamBodyType, completeArgs, wrappedUndefined, undefinedArgFor, requireExactArityValue, bodyReturnType, declaredReturnType, collectSignature, collectSignatureInner, collectGenericSignature, genericFnOf, lowerGenericCall, lowerGenericFnValue, inferTypeParamBindings, lowerGenericInstance, lowerCall, lowerFfiCall, lowerTimersMemberCall, lowerPromiseMethodCall, lowerFilterNarrowCall, isTopLevelFnSymbol, lowerNestedFunctionDecl, lambdaSignature, lowerLambda, lowerFunction, validateFfiImports } from "./lower-calls.js";
27
27
  import { lowerArrayMethodCall, lowerBufferStaticCall, lowerBytesMethodCall, lowerBytesNew, lowerMapMethodCall, lowerMapForEachCall, buildMapForEachFn, lowerRecordOvfCaptureHelper, lowerEnvToPairsHelper, lowerSetMethodCall, lowerSetForEachCall, buildSetForEachFn, lowerRegexMethodCall, lowerStringMethodCall } from "./lower-containers.js";
28
28
  import { lowerStreamModuleCall } from "./lower-stream.js";
29
29
  import { lowerEmitOverrideSpec } from "./lower-emitter.js";
@@ -163,10 +163,37 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
163
163
  dynamicCycleDiags.push(unsupportedDiag("SC1016", { file: entry.fileName, start: 0, end: 0 }, `circular imports (${cycle}; ${reason})`));
164
164
  });
165
165
  }
166
- const reachable = new Lowerer(program, entry, moduleOrder, dynamic, { targetPlatform }).discover(options.libRoots);
167
- const emit = new Lowerer(program, entry, moduleOrder, dynamic, { reachable, targetPlatform, startupCrash });
166
+ const ffiImports = options.ffiImports ?? [];
167
+ const validation = new Lowerer(program, entry, moduleOrder, dynamic, {
168
+ targetPlatform,
169
+ ffiImports,
170
+ });
171
+ const ffiValidation = validateFfiImports(validation);
172
+ // Discovery must use the same exact-symbol ownership as emit. Otherwise a
173
+ // local function shadowing a configured ambient name is mistaken for FFI
174
+ // while computing reachability, even though emit would correctly lower it
175
+ // as ordinary TypeScript. FFI-free builds reuse the validation lowerer
176
+ // (validation is an immediate no-op there), retaining the historical
177
+ // two-pass construction cost.
178
+ const discovery = ffiImports.length === 0
179
+ ? validation
180
+ : new Lowerer(program, entry, moduleOrder, dynamic, {
181
+ targetPlatform,
182
+ ffiImports,
183
+ ffiBindingSymbols: ffiValidation.symbolsByName,
184
+ });
185
+ const reachable = discovery.discover(options.libRoots);
186
+ const emit = new Lowerer(program, entry, moduleOrder, dynamic, {
187
+ reachable,
188
+ targetPlatform,
189
+ startupCrash,
190
+ ffiImports,
191
+ ffiBindingSymbols: ffiValidation.symbolsByName,
192
+ });
168
193
  for (const d of dynamicCycleDiags)
169
194
  emit.pushDiag(d);
195
+ for (const d of ffiValidation.diagnostics)
196
+ emit.pushDiag(d);
170
197
  const result = emit.run();
171
198
  if (options.coverage !== true)
172
199
  return result;
@@ -175,6 +202,8 @@ export function lowerToIr(program, entry, moduleOrder, options = {}) {
175
202
  remainder: true,
176
203
  alreadyFlushed: emit.flushedSymbols,
177
204
  targetPlatform,
205
+ ffiImports,
206
+ ffiBindingSymbols: ffiValidation.symbolsByName,
178
207
  });
179
208
  const rem = remainder.run();
180
209
  return { ...result, unreached: { diagnostics: rem.diagnostics, stats: rem.stats } };
@@ -852,6 +881,11 @@ export class Lowerer {
852
881
  targetPlatform;
853
882
  /** LowererMode.startupCrash — buildMain opens %main with the throw. */
854
883
  startupCrash;
884
+ /** Outbound native bindings by their source-level ambient name. */
885
+ ffiImports;
886
+ ffiImportsByName;
887
+ /** Non-null after whole-program FFI declaration validation. */
888
+ ffiBindingSymbols;
855
889
  /** Symbols a POISONED declaration statement would have bound: the
856
890
  * declaration's own diagnostic is already recorded, and no local/global
857
891
  * registered, so later references fall through every resolution step —
@@ -902,6 +936,9 @@ export class Lowerer {
902
936
  this.alreadyFlushed = mode.alreadyFlushed ?? new Set();
903
937
  this.targetPlatform = mode.targetPlatform ?? process.platform;
904
938
  this.startupCrash = mode.startupCrash ?? null;
939
+ this.ffiImports = mode.ffiImports ?? [];
940
+ this.ffiImportsByName = new Map(this.ffiImports.map((entry) => [entry.name, entry]));
941
+ this.ffiBindingSymbols = mode.ffiBindingSymbols ?? null;
905
942
  this.checker = program.getTypeChecker();
906
943
  this.typeCtx = {
907
944
  checker: this.checker,
@@ -1588,7 +1625,7 @@ export class Lowerer {
1588
1625
  const module = this.diags.length > 0
1589
1626
  ? null
1590
1627
  : {
1591
- irVersion: 1,
1628
+ irVersion: 2,
1592
1629
  sourceFile: this.entry.fileName,
1593
1630
  functions,
1594
1631
  classes: artifacts.classes,
@@ -1597,6 +1634,7 @@ export class Lowerer {
1597
1634
  globals: this.globalsList,
1598
1635
  ...(this.npmEmbedded ? { embedded: this.npmEmbedded } : {}),
1599
1636
  entry: ENTRY_NAME,
1637
+ ...(this.ffiImports.length > 0 ? { ffiImports: [...this.ffiImports] } : {}),
1600
1638
  };
1601
1639
  return {
1602
1640
  module,
@@ -6614,7 +6652,8 @@ export class Lowerer {
6614
6652
  // calls before the general dispatch (the general identifier-call paths
6615
6653
  // have no lowering for a promise-returning ambient global, and
6616
6654
  // `import` is a keyword callee no identifier path matches).
6617
- return (lowerFetchCall(this, expr) ??
6655
+ return (lowerFfiCall(this, expr) ??
6656
+ lowerFetchCall(this, expr) ??
6618
6657
  lowerDynamicImportCall(this, expr) ??
6619
6658
  lowerCall(this, expr));
6620
6659
  }