@scriptc/compiler 0.0.32 → 0.0.33

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 (51) hide show
  1. package/dist/backend/cc-cache.test.js +308 -1
  2. package/dist/backend/cc-cache.test.js.map +1 -1
  3. package/dist/backend/cc.d.ts +6 -0
  4. package/dist/backend/cc.js +707 -68
  5. package/dist/backend/cc.js.map +1 -1
  6. package/dist/backend/emission/emit-exprs.js +53 -2
  7. package/dist/backend/emission/emit-exprs.js.map +1 -1
  8. package/dist/backend/emission/emitter.d.ts +12 -5
  9. package/dist/backend/emission/emitter.js +160 -22
  10. package/dist/backend/emission/emitter.js.map +1 -1
  11. package/dist/backend/emission/may-throw.js +7 -4
  12. package/dist/backend/emission/may-throw.js.map +1 -1
  13. package/dist/backend/ffi-callbacks.d.ts +38 -1
  14. package/dist/backend/ffi-callbacks.js +76 -3
  15. package/dist/backend/ffi-callbacks.js.map +1 -1
  16. package/dist/backend/llvm/emitter.js +243 -12
  17. package/dist/backend/llvm/emitter.js.map +1 -1
  18. package/dist/diagnostics/diagnostic.js +2 -0
  19. package/dist/diagnostics/diagnostic.js.map +1 -1
  20. package/dist/ffi/profile.d.ts +17 -5
  21. package/dist/ffi/profile.js +169 -22
  22. package/dist/ffi/profile.js.map +1 -1
  23. package/dist/frontend/lowering/lower-calls.d.ts +1 -0
  24. package/dist/frontend/lowering/lower-calls.js +89 -23
  25. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  26. package/dist/frontend/lowering/lower-containers.js +65 -19
  27. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  28. package/dist/frontend/lowering/lowerer.d.ts +12 -0
  29. package/dist/frontend/lowering/lowerer.js +20 -1
  30. package/dist/frontend/lowering/lowerer.js.map +1 -1
  31. package/dist/frontend/ts7/checker.d.ts +2 -0
  32. package/dist/frontend/ts7/checker.js +20 -3
  33. package/dist/frontend/ts7/checker.js.map +1 -1
  34. package/dist/frontend/types.d.ts +8 -0
  35. package/dist/frontend/types.js +33 -5
  36. package/dist/frontend/types.js.map +1 -1
  37. package/dist/index.js +35 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/ir/nodes.d.ts +22 -9
  40. package/dist/ir/nodes.js +7 -1
  41. package/dist/ir/nodes.js.map +1 -1
  42. package/dist/ir/serialize.d.ts +1 -1
  43. package/dist/ir/serialize.js +1 -1
  44. package/dist/ir/validate.js +74 -1
  45. package/dist/ir/validate.js.map +1 -1
  46. package/dist/library/int-infer.test.js +4 -4
  47. package/dist/library/profile.d.ts +3 -0
  48. package/dist/library/profile.js +9 -1
  49. package/dist/library/profile.js.map +1 -1
  50. package/package.json +2 -2
  51. package/surface-manifest.json +1 -1
@@ -1,8 +1,9 @@
1
- import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, islandPromisePayloadTag, isFfiCallbackParam, isFfiContextParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/nodes.js";
1
+ import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, DYN, F64, islandPromisePayloadTag, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/nodes.js";
2
2
  import { boxAccess, BYTES_NUM_KIND_C, BYTES_NUM_VAR_C, bytesElemKindC, cDecl, cFnPtrCast, cNumberLiteral, cStringLiteral, cType, DV_GET_KIND_C, DV_SET_KIND_C, elemAccess, mapKeyAccess, mapKeyKindC, mapValKindC, releaseCallC, retainCallC, vAdapters } from "./emit-types.js";
3
3
  import { mangleClassNew, mangleClassRetain, mangleClassStruct, mangleField, mangleFnClosure, mangleFunction, mangleGlobal, mangleLocal, mangleRecordNew, mangleRecordStruct, mangleVtStruct } from "../mangle.js";
4
4
  import { OVERFLOW_MEMBER } from "./emit-shapes.js";
5
5
  import { dynDestrCheckHelper, dynIterNHelper, dynKeyGetHelper } from "./emit-walkers.js";
6
+ import { collectFfiRetainedOps, parseFfiCallbackKey } from "../ffi-callbacks.js";
6
7
  import { genResultThunkFor } from "./emit-async.js";
7
8
  function streamTypedRefCommitAdapter(E, t, snapshot, defs) {
8
9
  if (t.kind === "bytes") {
@@ -1885,7 +1886,34 @@ export function emitExpr(E, e) {
1885
1886
  sourceArgs.set(abiIndex, arg);
1886
1887
  if (isFfiCallbackParam(param))
1887
1888
  callbackArgs.set(param.callback.id, arg);
1889
+ if (isFfiReleaseParam(param))
1890
+ callbackArgs.set(param.callback.release, arg);
1888
1891
  });
1892
+ const { registrations: retainedRegistrations, releases: retainedReleases } = collectFfiRetainedOps(entry, callbackArgs, (binding, id) => E.ffiCallbackAdapter(binding, id));
1893
+ // Pin before registration. Raw retained descriptors are native
1894
+ // singletons: the incoming closure is pinned (and an EMPTY slot
1895
+ // armed) before the native set call, but a replaced registration
1896
+ // stays live and dispatching until the call returns — a native
1897
+ // setter may flush the outgoing callback one last time mid-replace.
1898
+ // scr_ffi_commit_slot below repoints the slot and retires the
1899
+ // superseded pins after the call.
1900
+ for (const registration of retainedRegistrations) {
1901
+ if (registration.global !== null) {
1902
+ E.line(`scr_ffi_retain_slot(&${registration.table}, &${registration.global}, ${registration.callback.name});`);
1903
+ }
1904
+ else if (registration.foreign) {
1905
+ E.line(`scr_ffi_retain_foreign(&${registration.table}, ${registration.callback.name});`);
1906
+ }
1907
+ else {
1908
+ E.line(`scr_ffi_retain(&${registration.table}, ${registration.callback.name});`);
1909
+ }
1910
+ }
1911
+ // Validate releases BEFORE the native removal call runs: a bogus
1912
+ // release traps without native code observing any side effect. The
1913
+ // registration itself is unpinned only after the call returns.
1914
+ for (const release of retainedReleases) {
1915
+ E.line(`scr_ffi_require${release.foreign ? "_foreign" : ""}(&${release.table}, ${release.callback.name});`);
1916
+ }
1889
1917
  // Raw C callback pointers carry no userdata. For the documented
1890
1918
  // call-scoped/same-thread policy, lend each one a distinct TLS
1891
1919
  // slot for the dynamic extent of this native call. Save/restore
@@ -1909,6 +1937,12 @@ export function emitExpr(E, e) {
1909
1937
  nativeArgs.push(`&${adapter.symbol}`);
1910
1938
  return;
1911
1939
  }
1940
+ if (isFfiReleaseParam(param)) {
1941
+ const { binding, id } = parseFfiCallbackKey(param.callback.release);
1942
+ const adapter = E.ffiCallbackAdapter(binding, id);
1943
+ nativeArgs.push(`&${adapter.symbol}`);
1944
+ return;
1945
+ }
1912
1946
  if (isFfiContextParam(param)) {
1913
1947
  const callback = callbackArgs.get(param.context);
1914
1948
  if (!callback)
@@ -1948,17 +1982,32 @@ export function emitExpr(E, e) {
1948
1982
  E.line(`${saved.tls} = ${saved.previous.name};`);
1949
1983
  }
1950
1984
  };
1951
- const callbacksMayThrow = callbackArgs.size > 0;
1985
+ const finishRetainedReleases = () => {
1986
+ // Commit raw replacements first (repoint the slot, retire the
1987
+ // superseded pins), then unpin explicit releases — the runtime
1988
+ // disarms the slot itself when the released closure holds it.
1989
+ for (const registration of retainedRegistrations) {
1990
+ if (registration.global !== null) {
1991
+ E.line(`scr_ffi_commit_slot(&${registration.table}, ${registration.callback.name});`);
1992
+ }
1993
+ }
1994
+ for (const release of retainedReleases) {
1995
+ E.line(`scr_ffi_release${release.foreign ? "_foreign" : ""}(&${release.table}, ${release.callback.name});`);
1996
+ }
1997
+ };
1998
+ const callbacksMayThrow = callbackArgs.size > 0 || E.ffiHasRetainedCallback;
1952
1999
  switch (entry.returns) {
1953
2000
  case "void":
1954
2001
  E.line(`${call};${E.srcComment(e.loc)}`);
1955
2002
  restoreRawContexts();
2003
+ finishRetainedReleases();
1956
2004
  if (callbacksMayThrow)
1957
2005
  E.emitPendingCheck();
1958
2006
  return { name: "", type: e.type };
1959
2007
  case "f64": {
1960
2008
  const result = E.newTemp(e.type, call);
1961
2009
  restoreRawContexts();
2010
+ finishRetainedReleases();
1962
2011
  if (callbacksMayThrow)
1963
2012
  E.emitPendingCheck();
1964
2013
  return result;
@@ -1966,6 +2015,7 @@ export function emitExpr(E, e) {
1966
2015
  case "bool": {
1967
2016
  const result = E.newTemp(e.type, `(${call} != 0)`);
1968
2017
  restoreRawContexts();
2018
+ finishRetainedReleases();
1969
2019
  if (callbacksMayThrow)
1970
2020
  E.emitPendingCheck();
1971
2021
  return result;
@@ -1975,6 +2025,7 @@ export function emitExpr(E, e) {
1975
2025
  case "i32": {
1976
2026
  const result = E.newTemp(e.type, `(double)${call}`);
1977
2027
  restoreRawContexts();
2028
+ finishRetainedReleases();
1978
2029
  if (callbacksMayThrow)
1979
2030
  E.emitPendingCheck();
1980
2031
  return result;