@scriptc/compiler 0.0.22 → 0.0.24

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 (93) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +139 -14
  2. package/dist/backend/cc.d.ts +13 -0
  3. package/dist/backend/cc.js +11 -0
  4. package/dist/backend/cc.js.map +1 -1
  5. package/dist/backend/emission/emit-async.d.ts +4 -0
  6. package/dist/backend/emission/emit-async.js +34 -2
  7. package/dist/backend/emission/emit-async.js.map +1 -1
  8. package/dist/backend/emission/emit-exprs.d.ts +10 -0
  9. package/dist/backend/emission/emit-exprs.js +272 -22
  10. package/dist/backend/emission/emit-exprs.js.map +1 -1
  11. package/dist/backend/emission/emit-shapes.js +1 -0
  12. package/dist/backend/emission/emit-shapes.js.map +1 -1
  13. package/dist/backend/emission/emit-stmts.js +36 -9
  14. package/dist/backend/emission/emit-stmts.js.map +1 -1
  15. package/dist/backend/emission/emit-types.js +14 -1
  16. package/dist/backend/emission/emit-types.js.map +1 -1
  17. package/dist/backend/emission/emitter.d.ts +19 -1
  18. package/dist/backend/emission/emitter.js +81 -2
  19. package/dist/backend/emission/emitter.js.map +1 -1
  20. package/dist/backend/llvm/emitter.js +578 -36
  21. package/dist/backend/llvm/emitter.js.map +1 -1
  22. package/dist/backend/llvm/shapes.js +12 -3
  23. package/dist/backend/llvm/shapes.js.map +1 -1
  24. package/dist/backend/mangle.d.ts +3 -0
  25. package/dist/backend/mangle.js +5 -0
  26. package/dist/backend/mangle.js.map +1 -1
  27. package/dist/compat/fetch-profile.d.ts +10 -0
  28. package/dist/compat/fetch-profile.js +55 -6
  29. package/dist/compat/fetch-profile.js.map +1 -1
  30. package/dist/coverage/surface-manifest.js +16 -1
  31. package/dist/coverage/surface-manifest.js.map +1 -1
  32. package/dist/diagnostics/diagnostic.d.ts +10 -0
  33. package/dist/diagnostics/diagnostic.js +27 -1
  34. package/dist/diagnostics/diagnostic.js.map +1 -1
  35. package/dist/frontend/lowering/lower-builtins.d.ts +17 -16
  36. package/dist/frontend/lowering/lower-builtins.js +817 -117
  37. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  38. package/dist/frontend/lowering/lower-calls.js +3 -1
  39. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  40. package/dist/frontend/lowering/lower-classes.js +28 -8
  41. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  42. package/dist/frontend/lowering/lower-containers.d.ts +2 -1
  43. package/dist/frontend/lowering/lower-containers.js +99 -32
  44. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  45. package/dist/frontend/lowering/lower-exprs.d.ts +1 -1
  46. package/dist/frontend/lowering/lower-exprs.js +78 -6
  47. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  48. package/dist/frontend/lowering/lower-generators.js +7 -1
  49. package/dist/frontend/lowering/lower-generators.js.map +1 -1
  50. package/dist/frontend/lowering/lower-inspect.js +59 -1
  51. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  52. package/dist/frontend/lowering/lower-island.d.ts +21 -0
  53. package/dist/frontend/lowering/lower-island.js +284 -10
  54. package/dist/frontend/lowering/lower-island.js.map +1 -1
  55. package/dist/frontend/lowering/lower-server.d.ts +5 -0
  56. package/dist/frontend/lowering/lower-server.js +1 -1
  57. package/dist/frontend/lowering/lower-server.js.map +1 -1
  58. package/dist/frontend/lowering/lower-stmts.d.ts +6 -2
  59. package/dist/frontend/lowering/lower-stmts.js +53 -14
  60. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  61. package/dist/frontend/lowering/lowerer.d.ts +3 -2
  62. package/dist/frontend/lowering/lowerer.js +17 -8
  63. package/dist/frontend/lowering/lowerer.js.map +1 -1
  64. package/dist/frontend/lowering/surfaces.js +108 -25
  65. package/dist/frontend/lowering/surfaces.js.map +1 -1
  66. package/dist/frontend/program.d.ts +4 -4
  67. package/dist/frontend/program.js +264 -46
  68. package/dist/frontend/program.js.map +1 -1
  69. package/dist/frontend/resolve.d.ts +10 -0
  70. package/dist/frontend/resolve.js +37 -0
  71. package/dist/frontend/resolve.js.map +1 -1
  72. package/dist/frontend/ts7/enums.d.ts +9 -0
  73. package/dist/frontend/ts7/enums.js +8 -6
  74. package/dist/frontend/ts7/enums.js.map +1 -1
  75. package/dist/frontend/ts7/program.js +4 -1
  76. package/dist/frontend/ts7/program.js.map +1 -1
  77. package/dist/frontend/types.d.ts +7 -4
  78. package/dist/frontend/types.js +103 -8
  79. package/dist/frontend/types.js.map +1 -1
  80. package/dist/index.js +8 -1
  81. package/dist/index.js.map +1 -1
  82. package/dist/ir/integer-loops.d.ts +23 -0
  83. package/dist/ir/integer-loops.js +82 -0
  84. package/dist/ir/integer-loops.js.map +1 -0
  85. package/dist/ir/nodes.d.ts +104 -28
  86. package/dist/ir/nodes.js +89 -1
  87. package/dist/ir/nodes.js.map +1 -1
  88. package/dist/ir/validate.js +136 -25
  89. package/dist/ir/validate.js.map +1 -1
  90. package/dist/library/fence-eval.js +4 -3
  91. package/dist/library/fence-eval.js.map +1 -1
  92. package/package.json +2 -2
  93. package/surface-manifest.json +186 -29
@@ -971,7 +971,7 @@ export function fenceUnsupportedFetchConstructorMember(L, access) {
971
971
  const member = members.find((candidate) => fetchInventoryStatus("Response", candidate, "static") === "unsupported");
972
972
  if (member === undefined)
973
973
  return null;
974
- L.noLowering(`Response.${member}`, access, "Response constructor-object operations have no compiler lowering in either tier");
974
+ L.noLowering(`Response.${member}`, access, "Response static constructor-object operations have no compiler lowering in either tier");
975
975
  }
976
976
  function hasLiveWebMutableArm(L, type) {
977
977
  if (type.kind === "record" ||
@@ -988,8 +988,8 @@ function hasLiveWebMutableArm(L, type) {
988
988
  * this capsule is deliberately limited to records/arrays/bytes (including
989
989
  * those selected at runtime from a union) that the live materializer can
990
990
  * snapshot and commit. */
991
- function lowerLiveWebValue(L, node) {
992
- const value = L.lowerExpr(node);
991
+ function lowerLiveWebValue(L, node, lowered) {
992
+ const value = lowered ?? L.lowerExpr(node);
993
993
  if (hasLiveWebMutableArm(L, value.type) &&
994
994
  canConvertToDyn(value.type, (id) => L.shapes.get(id), (id) => L.unions.get(id))) {
995
995
  return {
@@ -1069,6 +1069,22 @@ export function fenceStaticHeadersMember(L, access, use) {
1069
1069
  }
1070
1070
  L.noLowering(`Headers.${member} in a static build`, access, "the native static Headers surface is append/delete/get/getSetCookie/has/set/forEach; use keys()/values()/entries() or symbol-keyed iteration with --dynamic, while construction remains unsupported", sym);
1071
1071
  }
1072
+ /** The native AbortController handle dispatches `abort()` directly and
1073
+ * exposes `.signal` as data, but it has no first-class function value for
1074
+ * the prototype method. Fence method extraction before the checked-dynamic
1075
+ * keyed-read fallback can silently answer `undefined`. Dynamic builds use
1076
+ * the engine's real AbortController object and retain ordinary method reads. */
1077
+ export function fenceStaticAbortControllerMemberRead(L, access) {
1078
+ if (L.dynamic)
1079
+ return null;
1080
+ const symbol = isStdlibFetchInterface(L, access.expression, "AbortController");
1081
+ if (!symbol)
1082
+ return null;
1083
+ const members = fetchAccessMemberNames(L, access);
1084
+ if (members === null || !members.includes("abort"))
1085
+ return null;
1086
+ L.noLowering("AbortController.abort through method extraction in a static build", access, "call controller.abort(...) directly; the native AbortController handle does not expose abort as a first-class function value", symbol);
1087
+ }
1072
1088
  function isStdlibFetchInterface(L, node, owner) {
1073
1089
  const type = L.checker.getBaseTypeOfLiteralType(L.typeOf(node));
1074
1090
  for (const symbol of [type.getSymbol(), type.getAliasSymbol()]) {
@@ -1525,17 +1541,17 @@ export function fenceStaticReadableStreamMember(L, access, use) {
1525
1541
  * ambient globals have no first-class constructor-object representation;
1526
1542
  * claim the direct calls by declaration provenance before the general
1527
1543
  * member-call path tries to lower the receiver as a value. */
1528
- function staticCallWithSurplusArgs(L, call, first, result) {
1544
+ function staticFirstArgWithSurplusArgs(L, call, first) {
1529
1545
  const loc = locOf(call);
1530
- if (call.arguments.length === 1)
1531
- return result(first);
1546
+ if (call.arguments.length <= 1)
1547
+ return first;
1532
1548
  const firstLocal = L.declareHiddenLocal("%fetchArg", first.type);
1533
- const firstRef = () => ({
1549
+ const firstRef = {
1534
1550
  kind: "varRef",
1535
1551
  localId: firstLocal.id,
1536
1552
  type: first.type,
1537
1553
  loc,
1538
- });
1554
+ };
1539
1555
  const stmts = [
1540
1556
  { kind: "varDecl", localId: firstLocal.id, init: first, loc },
1541
1557
  ];
@@ -1551,8 +1567,16 @@ function staticCallWithSurplusArgs(L, call, first, result) {
1551
1567
  : L.lowerExpr(argument);
1552
1568
  stmts.push({ kind: "exprStmt", expr: discarded, loc: discarded.loc });
1553
1569
  }
1554
- const answer = result(firstRef());
1555
- return { kind: "seqExpr", stmts, result: answer, type: answer.type, loc };
1570
+ return {
1571
+ kind: "seqExpr",
1572
+ stmts,
1573
+ result: firstRef,
1574
+ type: first.type,
1575
+ loc,
1576
+ };
1577
+ }
1578
+ function staticCallWithSurplusArgs(L, call, first, result) {
1579
+ return result(staticFirstArgWithSurplusArgs(L, call, first));
1556
1580
  }
1557
1581
  export function lowerStaticFetchCompanionCall(L, call) {
1558
1582
  if (L.dynamic ||
@@ -1668,6 +1692,46 @@ export function lowerStaticFetchCompanionCall(L, call) {
1668
1692
  }
1669
1693
  return null;
1670
1694
  }
1695
+ /** `AbortController.abort(reason?)` mutates the native signal shared with
1696
+ * `.signal` and fetch. Preserve a mutable reason's identity just like
1697
+ * `AbortSignal.abort(reason)`; surplus arguments still evaluate in order and
1698
+ * are ignored by the runtime operation. */
1699
+ export function lowerStaticAbortControllerCall(L, call) {
1700
+ const access = call.expression;
1701
+ if (L.dynamic ||
1702
+ call.questionDotToken ||
1703
+ call.arguments.some((argument) => ts.isSpreadElement(argument)) ||
1704
+ (!ts.isPropertyAccessExpression(access) &&
1705
+ !ts.isElementAccessExpression(access)) ||
1706
+ access.questionDotToken ||
1707
+ staticResponseMemberName(L, access) !== "abort") {
1708
+ return null;
1709
+ }
1710
+ const receiverTs = L.checker.getBaseTypeOfLiteralType(L.typeOf(access.expression));
1711
+ const symbol = receiverTs.getAliasSymbol() ?? receiverTs.getSymbol();
1712
+ if (symbol?.name !== "AbortController" ||
1713
+ !L.checker.declarationsOf(symbol).some((d) => ts.isInterfaceDeclaration(d) &&
1714
+ L.isStdlibFile(d.getSourceFile()))) {
1715
+ return null;
1716
+ }
1717
+ const receiver = L.lowerExpr(access.expression);
1718
+ if (receiver.type.kind !== "dyn")
1719
+ return null;
1720
+ const loc = locOf(call);
1721
+ const first = call.arguments[0]
1722
+ ? lowerLiveWebValue(L, call.arguments[0])
1723
+ : dynUndefinedExpr(loc);
1724
+ const args = [staticFirstArgWithSurplusArgs(L, call, first)];
1725
+ return lowerStaticFixedFetchMethodCall(L, call, access, "abort", receiver, args, (receiverRef, argumentRefs) => ({
1726
+ kind: "dynInvoke",
1727
+ recv: receiverRef,
1728
+ method: "abort",
1729
+ calleeName: access.getText(),
1730
+ args: argumentRefs,
1731
+ type: DYN,
1732
+ loc,
1733
+ }));
1734
+ }
1671
1735
  /** Controller chunks and error reasons are dyn-handle calls, but unlike a
1672
1736
  * general checked-dynamic boundary the Web Streams contract preserves their
1673
1737
  * object identity for the reader/source callbacks that observe them. */
@@ -1792,6 +1856,60 @@ export function lowerStaticAbortSignalListenerCall(L, call) {
1792
1856
  loc,
1793
1857
  }));
1794
1858
  }
1859
+ /** `new AbortController()`. Static builds create a native controller handle
1860
+ * over the same signal state consumed by fetch; dynamic builds construct the
1861
+ * island Web object. JavaScript accepts surplus constructor arguments, so
1862
+ * both tiers evaluate them even though AbortController ignores their values. */
1863
+ export function lowerAbortControllerNew(L, expr) {
1864
+ if (!ts.isIdentifier(expr.expression) ||
1865
+ expr.expression.text !== "AbortController") {
1866
+ return null;
1867
+ }
1868
+ const symbol = L.resolveValueSymbol(expr.expression);
1869
+ if (!symbol || !L.isStdlibSymbol(symbol))
1870
+ return null;
1871
+ const args = expr.arguments ?? [];
1872
+ if (args.some((argument) => ts.isSpreadElement(argument)))
1873
+ return null;
1874
+ const loc = locOf(expr);
1875
+ if (L.dynamic) {
1876
+ const ctor = {
1877
+ kind: "jsOp",
1878
+ op: "globalGet",
1879
+ name: "AbortController",
1880
+ args: [],
1881
+ type: JSVAL,
1882
+ loc,
1883
+ };
1884
+ return {
1885
+ kind: "jsOp",
1886
+ op: "construct",
1887
+ args: [ctor, ...args.map((argument) => L.jsvalIn(L.lowerExpr(argument), argument))],
1888
+ type: JSVAL,
1889
+ loc,
1890
+ };
1891
+ }
1892
+ const result = {
1893
+ kind: "libCall",
1894
+ fn: "fetch.abortControllerNew",
1895
+ args: [],
1896
+ type: DYN,
1897
+ loc,
1898
+ };
1899
+ if (args.length === 0)
1900
+ return result;
1901
+ return {
1902
+ kind: "seqExpr",
1903
+ stmts: args.map((argument) => ({
1904
+ kind: "exprStmt",
1905
+ expr: L.lowerExpr(argument),
1906
+ loc: locOf(argument),
1907
+ })),
1908
+ result,
1909
+ type: DYN,
1910
+ loc,
1911
+ };
1912
+ }
1795
1913
  /** `new ReadableStream(source?)`. Static builds box the source record into
1796
1914
  * the checked-dynamic tree; dynamic builds construct the island's Web
1797
1915
  * stream directly so the returned handle composes with dynamic fetch. */
@@ -1842,6 +1960,162 @@ export function lowerStaticReadableStreamNew(L, expr) {
1842
1960
  loc,
1843
1961
  };
1844
1962
  }
1963
+ /** `new Response(body?, init?)`. Dynamic builds construct the island's
1964
+ * Web Response directly. Static builds hand a checked-dynamic BodyInit and
1965
+ * ResponseInit snapshot to the native fetch runtime, which returns the same
1966
+ * opaque Response handle as fetch(). */
1967
+ export function lowerResponseNew(L, expr) {
1968
+ if (!ts.isIdentifier(expr.expression) ||
1969
+ expr.expression.text !== "Response") {
1970
+ return null;
1971
+ }
1972
+ const symbol = L.resolveValueSymbol(expr.expression);
1973
+ if (!symbol || !L.isStdlibSymbol(symbol))
1974
+ return null;
1975
+ const args = expr.arguments ?? [];
1976
+ if (args.some(ts.isSpreadElement))
1977
+ return null;
1978
+ const loc = locOf(expr);
1979
+ if (L.dynamic) {
1980
+ const ctor = {
1981
+ kind: "jsOp",
1982
+ op: "globalGet",
1983
+ name: "Response",
1984
+ args: [],
1985
+ type: JSVAL,
1986
+ loc,
1987
+ };
1988
+ const lowered = args.map((arg) => ts.isObjectLiteralExpression(arg)
1989
+ ? lowerIslandObjectLiteral(L, arg)
1990
+ : L.jsvalIn(L.lowerExpr(arg), arg));
1991
+ return {
1992
+ kind: "jsOp",
1993
+ op: "construct",
1994
+ args: [ctor, ...lowered],
1995
+ type: JSVAL,
1996
+ loc,
1997
+ };
1998
+ }
1999
+ const toDyn = (node, value, what) => {
2000
+ if (node === undefined)
2001
+ return dynUndefinedExpr(loc);
2002
+ if (value.type.kind === "dyn")
2003
+ return value;
2004
+ /* A user class can satisfy ResponseInit structurally through plain
2005
+ * fields. Project just the declared dictionary members into a record,
2006
+ * then use the ordinary checked-dynamic copy. objRecordWidthHelper
2007
+ * deliberately declines accessors/methods, whose observable reads
2008
+ * cannot be moved into the runtime WebIDL conversion phase. */
2009
+ if (what === "an init value" && value.type.kind === "object") {
2010
+ const sourceType = L.typeOf(node);
2011
+ const fields = [];
2012
+ for (const name of ["headers", "status", "statusText"]) {
2013
+ const property = L.checker.getPropertyOfType(sourceType, name);
2014
+ if (!property)
2015
+ continue;
2016
+ const propertyType = L.checker.getTypeOfSymbolAtLocation(property, node);
2017
+ const mapped = L.mapTypeOf(propertyType);
2018
+ if (!mapped || mapped.kind === "void") {
2019
+ L.noLowering(`new Response with ${what} of type '${L.fmt(value.type)}'`, node, `the '${name}' field does not have a checked-dynamic representation`);
2020
+ }
2021
+ fields.push({ name, type: mapped });
2022
+ }
2023
+ const recordType = {
2024
+ kind: "record",
2025
+ shapeId: L.shapes.intern(fields, false, undefined, fields.map((field) => field.name)),
2026
+ };
2027
+ const projected = L.widthCoerce(value, recordType);
2028
+ if (projected && L.dynConvertible(projected.type)) {
2029
+ return {
2030
+ kind: "dynFrom",
2031
+ value: projected,
2032
+ liveRef: true,
2033
+ type: DYN,
2034
+ loc: value.loc,
2035
+ };
2036
+ }
2037
+ }
2038
+ if (value.kind === "unitLit" || L.dynConvertible(value.type)) {
2039
+ if (what === "an init value" &&
2040
+ hasLiveWebMutableArm(L, value.type)) {
2041
+ return {
2042
+ kind: "dynFrom",
2043
+ value,
2044
+ liveRef: true,
2045
+ type: DYN,
2046
+ loc: value.loc,
2047
+ };
2048
+ }
2049
+ return {
2050
+ kind: "dynFrom",
2051
+ value,
2052
+ type: DYN,
2053
+ loc: value.loc,
2054
+ };
2055
+ }
2056
+ L.noLowering(`new Response with ${what} of type '${L.fmt(value.type)}'`, node, "the static constructor accepts string, Uint8Array, ReadableStream, null, and the declared ResponseInit dictionary");
2057
+ };
2058
+ const bodyNode = args[0];
2059
+ const body = bodyNode === undefined
2060
+ ? { kind: "unitLit", unit: "undefined", type: { kind: "undefinedT" }, loc }
2061
+ : L.lowerExpr(bodyNode);
2062
+ const initNode = args[1];
2063
+ const init = initNode === undefined
2064
+ ? { kind: "unitLit", unit: "undefined", type: { kind: "undefinedT" }, loc }
2065
+ : ts.isObjectLiteralExpression(initNode)
2066
+ ? lowerDynObjectLiteral(L, initNode, (node, value) => lowerLiveWebValue(L, node, value))
2067
+ : L.lowerExpr(initNode);
2068
+ /* JavaScript evaluates every argument expression before WebIDL starts
2069
+ * converting either BodyInit or ResponseInit. Capture the raw values in
2070
+ * source order; only the final libCall boxes the body and gives typed init
2071
+ * values a live capsule for the runtime's later dictionary reads. This is
2072
+ * observable when argument evaluation or BodyInit coercion mutates a
2073
+ * Uint8Array body or a typed ResponseInit record. Unit-valued expressions
2074
+ * still execute, then contribute the corresponding undefined/null literal. */
2075
+ const stmts = [];
2076
+ const capture = (value, name) => {
2077
+ if (isUnitType(value.type) || value.type.kind === "void") {
2078
+ if (value.kind !== "unitLit") {
2079
+ stmts.push({ kind: "exprStmt", expr: value, loc: value.loc });
2080
+ }
2081
+ return value.type.kind === "nullT"
2082
+ ? { kind: "unitLit", unit: "null", type: value.type, loc: value.loc }
2083
+ : {
2084
+ kind: "unitLit",
2085
+ unit: "undefined",
2086
+ type: { kind: "undefinedT" },
2087
+ loc: value.loc,
2088
+ };
2089
+ }
2090
+ const local = L.declareHiddenLocal(name, value.type);
2091
+ stmts.push({ kind: "varDecl", localId: local.id, init: value, loc: value.loc });
2092
+ return {
2093
+ kind: "varRef",
2094
+ localId: local.id,
2095
+ type: local.type,
2096
+ loc: value.loc,
2097
+ };
2098
+ };
2099
+ const bodyRef = capture(body, "%responseBody");
2100
+ const initRef = capture(init, "%responseInit");
2101
+ for (const argument of args.slice(2)) {
2102
+ const discarded = ts.isVoidExpression(argument)
2103
+ ? L.lowerExpr(argument.expression)
2104
+ : L.lowerExpr(argument);
2105
+ stmts.push({ kind: "exprStmt", expr: discarded, loc: discarded.loc });
2106
+ }
2107
+ const result = {
2108
+ kind: "libCall",
2109
+ fn: "fetch.responseNew",
2110
+ args: [
2111
+ toDyn(bodyNode, bodyRef, "a body"),
2112
+ toDyn(initNode, initRef, "an init value"),
2113
+ ],
2114
+ type: DYN,
2115
+ loc,
2116
+ };
2117
+ return { kind: "seqExpr", stmts, result, type: DYN, loc };
2118
+ }
1845
2119
  /** A static default reader's read() exits the native checked-dynamic
1846
2120
  * transport into the checker's concrete chunk type. An exact chunk type
1847
2121
  * preserves ReadableStream.from(array)'s element identity; structural