@scriptc/compiler 0.0.11 → 0.0.12

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 (90) hide show
  1. package/ambient/scriptc-node-fallback.d.ts +12 -9
  2. package/ambient/scriptc.d.ts +2 -2
  3. package/dist/backend/cc.d.ts +2 -2
  4. package/dist/backend/emission/emit-async.js +1 -1
  5. package/dist/backend/emission/emit-exprs.js +97 -52
  6. package/dist/backend/emission/emit-exprs.js.map +1 -1
  7. package/dist/backend/emission/emit-island.js +1 -1
  8. package/dist/backend/emission/emit-shapes.js +1 -1
  9. package/dist/backend/emission/emit-walkers.d.ts +14 -14
  10. package/dist/backend/emission/emit-walkers.js +44 -44
  11. package/dist/backend/emission/emit-walkers.js.map +1 -1
  12. package/dist/backend/emission/emitter.d.ts +3 -3
  13. package/dist/backend/emission/emitter.js +8 -8
  14. package/dist/backend/emission/may-throw.js +1 -1
  15. package/dist/backend/llvm/dyn.d.ts +10 -10
  16. package/dist/backend/llvm/dyn.js +26 -26
  17. package/dist/backend/llvm/dyn.js.map +1 -1
  18. package/dist/backend/llvm/emitter.js +97 -43
  19. package/dist/backend/llvm/emitter.js.map +1 -1
  20. package/dist/backend/llvm/shapes.js +1 -1
  21. package/dist/backend/llvm/walkers.js +2 -2
  22. package/dist/backend/llvm/walkers.js.map +1 -1
  23. package/dist/diagnostics/diagnostic.d.ts +1 -1
  24. package/dist/diagnostics/diagnostic.js +4 -3
  25. package/dist/diagnostics/diagnostic.js.map +1 -1
  26. package/dist/frontend/lowering/lib-boundary.js +5 -5
  27. package/dist/frontend/lowering/lib-boundary.js.map +1 -1
  28. package/dist/frontend/lowering/lower-assert.js +12 -12
  29. package/dist/frontend/lowering/lower-assert.js.map +1 -1
  30. package/dist/frontend/lowering/lower-builtins.d.ts +7 -7
  31. package/dist/frontend/lowering/lower-builtins.js +92 -31
  32. package/dist/frontend/lowering/lower-builtins.js.map +1 -1
  33. package/dist/frontend/lowering/lower-calls.d.ts +4 -4
  34. package/dist/frontend/lowering/lower-calls.js +66 -66
  35. package/dist/frontend/lowering/lower-calls.js.map +1 -1
  36. package/dist/frontend/lowering/lower-classes.js +31 -5
  37. package/dist/frontend/lowering/lower-classes.js.map +1 -1
  38. package/dist/frontend/lowering/lower-containers.d.ts +5 -5
  39. package/dist/frontend/lowering/lower-containers.js +19 -19
  40. package/dist/frontend/lowering/lower-containers.js.map +1 -1
  41. package/dist/frontend/lowering/lower-emitter.js +2 -2
  42. package/dist/frontend/lowering/lower-emitter.js.map +1 -1
  43. package/dist/frontend/lowering/lower-exprs.d.ts +7 -7
  44. package/dist/frontend/lowering/lower-exprs.js +158 -112
  45. package/dist/frontend/lowering/lower-exprs.js.map +1 -1
  46. package/dist/frontend/lowering/lower-inspect.js +5 -5
  47. package/dist/frontend/lowering/lower-inspect.js.map +1 -1
  48. package/dist/frontend/lowering/lower-island.js +12 -3
  49. package/dist/frontend/lowering/lower-island.js.map +1 -1
  50. package/dist/frontend/lowering/lower-modules.js +16 -16
  51. package/dist/frontend/lowering/lower-modules.js.map +1 -1
  52. package/dist/frontend/lowering/lower-namespaces.d.ts +11 -1
  53. package/dist/frontend/lowering/lower-namespaces.js +41 -6
  54. package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
  55. package/dist/frontend/lowering/lower-server.js +11 -11
  56. package/dist/frontend/lowering/lower-server.js.map +1 -1
  57. package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
  58. package/dist/frontend/lowering/lower-stmts.js +191 -30
  59. package/dist/frontend/lowering/lower-stmts.js.map +1 -1
  60. package/dist/frontend/lowering/lower-stream.js +66 -22
  61. package/dist/frontend/lowering/lower-stream.js.map +1 -1
  62. package/dist/frontend/lowering/lowerer.d.ts +10 -10
  63. package/dist/frontend/lowering/lowerer.js +51 -37
  64. package/dist/frontend/lowering/lowerer.js.map +1 -1
  65. package/dist/frontend/lowering/surfaces.js +2 -2
  66. package/dist/frontend/lowering/surfaces.js.map +1 -1
  67. package/dist/frontend/program.js +1 -1
  68. package/dist/frontend/shared.js +7 -7
  69. package/dist/frontend/shared.js.map +1 -1
  70. package/dist/frontend/types.d.ts +2 -2
  71. package/dist/frontend/types.js +15 -15
  72. package/dist/frontend/types.js.map +1 -1
  73. package/dist/index.js +38 -7
  74. package/dist/index.js.map +1 -1
  75. package/dist/ir/nodes.d.ts +110 -98
  76. package/dist/ir/nodes.js +48 -21
  77. package/dist/ir/nodes.js.map +1 -1
  78. package/dist/ir/validate.js +44 -34
  79. package/dist/ir/validate.js.map +1 -1
  80. package/dist/library/int-infer.js +13 -0
  81. package/dist/library/int-infer.js.map +1 -1
  82. package/dist/library/profile.d.ts +8 -6
  83. package/dist/library/profile.js.map +1 -1
  84. package/dist/library/sidecar-validate.js +1 -1
  85. package/dist/library/sidecar-validate.js.map +1 -1
  86. package/dist/library/sidecar.d.ts +1 -1
  87. package/dist/library/sidecar.js +20 -7
  88. package/dist/library/sidecar.js.map +1 -1
  89. package/package.json +2 -2
  90. package/surface-manifest.json +4 -4
@@ -1,4 +1,4 @@
1
- import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, isJsonSafeType, isRefCounted, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./nodes.js";
1
+ import { arrayOf, BOOL, BYTES_U8, bytesOf, canAdaptDynFuncTo, canConvertToDyn, canExitIslandToType, canMarshalIntoIsland, canMarshalTypedFuncIntoIsland, CHILD_T, CHILDSTREAM_T, DGRAMSOCK_T, DYN, DYN_HANDLE_KINDS, F64, FSWATCHER_T, HTTP2SESSION_T, HTTP2STREAM_T, HTTPCLIENTREQ_T, HTTPREQ_T, HTTPRES_T, islandPromisePayloadTag, isJsonSafeType, isRefCounted, isSupportedIndexValue, isSupportedMapKey, isSupportedMapValue, isSupportedSetElem, isUnitType, jsOpResultKind, JSVAL, NETSERVER_T, NETSOCKET_T, PROCSTREAM_T, REF_TRUTHY_KINDS, REGEX, RUNTIME_EMITTER_CLASS, RUNTIME_ERROR_CLASSES, RUNTIME_STREAM_CLASSES, SEARCH_PARAMS_T, SECURECTX_T, SPAWNRES_T, STATS_T, STRING, SYMBOL_T, TESTCTX_T, typeEquals, typeKey, unionFuncSetArmsOk, URL_T, VOID } from "./nodes.js";
2
2
  /** Per-method signature for strIntrinsic: `argTypes` lists every argument
3
3
  * position (optional ones included); `minArgs` is how many may be omitted
4
4
  * from the end (backends fill the documented defaults). Exported for the
@@ -63,6 +63,8 @@ export const LIB_FN_SIGS = {
63
63
  "json.parse": { argTypes: [STRING], result: DYN },
64
64
  "dyn.keySet": { argTypes: [DYN, STRING, DYN], result: VOID },
65
65
  "dyn.iterPack": { argTypes: [DYN, STRING], result: DYN },
66
+ "dyn.arrLen": { argTypes: [DYN], result: F64 },
67
+ "dyn.arrAt": { argTypes: [DYN, F64], result: DYN },
66
68
  "dyn.toString": { argTypes: [DYN, STRING, STRING], result: STRING },
67
69
  "dyn.defineProps": { argTypes: [DYN, DYN], result: DYN },
68
70
  "dyn.typeof": { argTypes: [DYN], result: STRING },
@@ -173,7 +175,7 @@ export const LIB_FN_SIGS = {
173
175
  "num.fromString": { argTypes: [STRING], result: F64 },
174
176
  "num.isNaN": { argTypes: [F64], result: BOOL },
175
177
  "str.encodeUriComponent": { argTypes: [STRING], result: STRING },
176
- // The base64 globals: the argument is a DOM value (WebIDL ToString
178
+ // The base64 globals: the argument is a dyn value (WebIDL ToString
177
179
  // runs in the runtime); the zero-argument form always throws.
178
180
  "str.atob": { argTypes: [DYN], result: STRING },
179
181
  "str.btoa": { argTypes: [DYN], result: STRING },
@@ -230,7 +232,7 @@ export const LIB_FN_SIGS = {
230
232
  // node:querystring. qs.parse's result is the call site's ParsedUrlQuery
231
233
  // dictionary record (VOID is the networkInterfaces sentinel — the
232
234
  // libCall case checks the structure); qs.stringify's object argument
233
- // is a DOM value (the frontend dynFroms typed records).
235
+ // is a dyn value (the frontend dynFroms typed records).
234
236
  "qs.parse": { argTypes: [STRING, STRING, STRING, F64], result: VOID },
235
237
  "qs.stringify": { argTypes: [DYN, STRING, STRING], result: STRING },
236
238
  "qs.escape": { argTypes: [STRING], result: STRING },
@@ -647,7 +649,7 @@ export const LIB_FN_SIGS = {
647
649
  "buffer.isEncoding": { argTypes: [STRING], result: BOOL },
648
650
  "buffer.concatLen": { argTypes: [arrayOf(BYTES_U8), F64], result: BYTES_U8 },
649
651
  // The checked-dynamic compare/equals validators (Node's argument
650
- // ladders over DOM-boxed invalid-input probes).
652
+ // ladders over dyn-boxed invalid-input probes).
651
653
  "buffer.compareChk": { argTypes: [DYN, DYN], result: F64 },
652
654
  "bytes.equalsChk": { argTypes: [BYTES_U8, DYN], result: BOOL },
653
655
  "bytes.compareChk": { argTypes: [BYTES_U8, DYN, DYN, DYN, DYN, DYN], result: F64 },
@@ -726,7 +728,7 @@ export const LIB_FN_SIGS = {
726
728
  // Receiver (any error-hierarchy object) and the program-dependent
727
729
  // `string | undefined` result are checked in the libCall case.
728
730
  "error.code": { argTypes: [null], result: VOID },
729
- // DOMException: construction takes the two DOM args (WebIDL's
731
+ // DOMException: construction takes the two dyn args (WebIDL's
730
732
  // resolution runs in the runtime); the %DOMException result is a
731
733
  // program-dependent object type, checked in the libCall case. The
732
734
  // read surface takes the %DOMException receiver (a null slot — the
@@ -877,7 +879,7 @@ export const LIB_FN_SIGS = {
877
879
  // Symbol strict equality (pointer identity; scr_symbol.c).
878
880
  "assert.eqSym": { argTypes: [{ kind: "symbol" }, { kind: "symbol" }, BOOL, BOOL, STRING, BOOL], result: VOID },
879
881
  // The equality quartet over checked-dynamic operands (the frontend
880
- // boxes a static side into the DOM first).
882
+ // boxes a static side into the checked-dynamic tree first).
881
883
  "assert.eqDyn": { argTypes: [DYN, DYN, BOOL, BOOL, STRING, BOOL], result: VOID },
882
884
  // The throws(fn, {shape}) accumulator: begin/slot calls never throw;
883
885
  // shapeEnd throws the Comparison diff. The error slot is the
@@ -1183,7 +1185,7 @@ export function validateModule(mod) {
1183
1185
  // Unit kinds (undefinedT/nullT) exist only as union arms — a BARE
1184
1186
  // unit field is as malformed as a void one. dyn fields are VALID
1185
1187
  // (`[string, unknown]` entries tuples, `{ v: unknown }` records):
1186
- // the slot holds a DOM value with the overflow map's plumbing.
1188
+ // the slot holds a dyn value with the overflow map's plumbing.
1187
1189
  if (f.type.kind === "void" || f.type.kind === "jsval" ||
1188
1190
  isUnitType(f.type)) {
1189
1191
  errors.push({ message: `record ${rec.id}: field "${f.name}" is ${f.type.kind}`, loc: noLoc });
@@ -1741,10 +1743,10 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1741
1743
  }
1742
1744
  break;
1743
1745
  }
1744
- // A dyn (DOM) chain (`rawName?.match(re)` on a JSON.parse result):
1746
+ // A dyn (dyn) chain (`rawName?.match(re)` on a JSON.parse result):
1745
1747
  // the nullish test reads the node's kind tag; the body is the
1746
1748
  // validated dynamic dispatch, its result converted back into the
1747
- // DOM (dynFrom) — so body and result are dyn, or void for
1749
+ // dyn (dynFrom) — so body and result are dyn, or void for
1748
1750
  // statement-position chains.
1749
1751
  if (e.receiver.type.kind === "dyn") {
1750
1752
  if (activeChains.has(e.id))
@@ -1789,7 +1791,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1789
1791
  break;
1790
1792
  }
1791
1793
  expectType(e.body, e.type, "optChain body");
1792
- // dyn results carry the unit path as the undefined DOM value; every
1794
+ // dyn results carry the unit path as the undefined dyn value; every
1793
1795
  // other value result needs an undefined arm to land on.
1794
1796
  if (e.type.kind !== "dyn") {
1795
1797
  const rdef = e.type.kind === "union" ? unions.get(e.type.unionId) : undefined;
@@ -1821,7 +1823,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
1821
1823
  }
1822
1824
  // The CHECKED-DYNAMIC form: the runtime kind decides (the
1823
1825
  // emitters' scr_dyn_is_nullish arm) — left, right, and result
1824
- // all live in the DOM.
1826
+ // all live in the checked-dynamic tree.
1825
1827
  if (e.left.type.kind === "dyn") {
1826
1828
  if (e.type.kind !== "dyn")
1827
1829
  err("dyn nullish must answer dyn", e.loc);
@@ -2398,7 +2400,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2398
2400
  }
2399
2401
  });
2400
2402
  // Result func type must match the target's signature. A VARIADIC
2401
- // (rest-marked) type hides one synthetic trailing DOM-array param
2403
+ // (rest-marked) type hides one synthetic trailing dyn-array param
2402
2404
  // in the lifted function (the thunk fills it) — the type's
2403
2405
  // declared params plus that one must match.
2404
2406
  if (e.type.kind === "func") {
@@ -2771,7 +2773,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2771
2773
  expectType(e.obj, { kind: "record", shapeId: e.shapeId }, "recordKeyGet receiver");
2772
2774
  expectType(e.key, STRING, "recordKeyGet key");
2773
2775
  // Every reachable value must SURFACE as the result type: identity,
2774
- // an arm of a union result, or (dyn results) a DOM conversion —
2776
+ // an arm of a union result, or (dyn results) a dyn conversion —
2775
2777
  // the frontend's recordKeyResultOk mirror. overflowOnly reads (a
2776
2778
  // literal key naming no declared field) skip the declared check
2777
2779
  // and require the overflow to exist.
@@ -2812,7 +2814,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2812
2814
  if (e.type.kind !== "dyn")
2813
2815
  err(`dynFrom must be dyn-typed, got ${e.type.kind}`, e.loc);
2814
2816
  // A bare unit literal is legal exactly here (like unionWrap): the
2815
- // DOM has first-class undefined/null values.
2817
+ // dyn has first-class undefined/null values.
2816
2818
  if (e.value.kind === "unitLit") {
2817
2819
  const want = e.value.unit === "undefined" ? "undefinedT" : "nullT";
2818
2820
  if (e.value.type.kind !== want) {
@@ -2821,19 +2823,19 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
2821
2823
  break;
2822
2824
  }
2823
2825
  checkExpr(e.value);
2824
- // Domain: JSON-safe, bytes<u8> (the DOM's bytes kind — payload
2826
+ // Domain: JSON-safe, bytes<u8> (the checked-dynamic tree's bytes kind — payload
2825
2827
  // copied), an undefined-armed union of JSON-safe arms (the
2826
- // undefined arm becomes the undefined DOM value), or a BOXABLE
2827
- // function type (the DOM's function kind — canConvertToDyn folds
2828
+ // undefined arm becomes the undefined dyn value), or a BOXABLE
2829
+ // function type (the checked-dynamic tree's function kind — canConvertToDyn folds
2828
2830
  // all four in).
2829
2831
  const vt = e.value.type;
2830
2832
  if (!canConvertToDyn(vt, (id) => records.get(id), (id) => unions.get(id))) {
2831
- err(`dynFrom of non-DOM-convertible type ${vt.kind}`, e.loc);
2833
+ err(`dynFrom of non-dyn-convertible type ${vt.kind}`, e.loc);
2832
2834
  }
2833
2835
  break;
2834
2836
  }
2835
2837
  case "dynFromJsval": {
2836
- // The jsval→DOM crossing: exactly a jsval operand into a dyn
2838
+ // The jsval→dyn crossing: exactly a jsval operand into a dyn
2837
2839
  // result (the by-reference island wrap; scalars normalize at
2838
2840
  // runtime).
2839
2841
  checkExpr(e.value);
@@ -3013,7 +3015,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
3013
3015
  break;
3014
3016
  }
3015
3017
  case "caughtToDyn": {
3016
- // The caught snapshot converting to a dyn DOM value (an unknown
3018
+ // The caught snapshot converting to a dyn value (an unknown
3017
3019
  // slot): operand caught, result dyn — the runtime dispatch handles
3018
3020
  // every payload kind, so nothing else constrains it.
3019
3021
  checkExpr(e.value);
@@ -4259,7 +4261,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4259
4261
  }
4260
4262
  // The value's STATIC type drives the emitted serializer — it must be
4261
4263
  // JSON-safe (the frontend rejects the rest with a specific message).
4262
- // A dyn ROOT is the one non-static shape allowed: the runtime's DOM
4264
+ // A dyn ROOT is the one non-static shape allowed: the runtime's dyn
4263
4265
  // walker serializes it (scr_dyn_format_j), no emitted serializer.
4264
4266
  if (e.value.type.kind !== "dyn" &&
4265
4267
  !isJsonSafeType(e.value.type, (id) => records.get(id), (id) => unions.get(id))) {
@@ -4272,24 +4274,24 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4272
4274
  expectType(e.value, DYN, "dynCheck operand");
4273
4275
  // The target drives the emitted validator/builder: non-dyn,
4274
4276
  // non-void, JSON-representable (closures/class instances can never
4275
- // be found inside a JSON DOM — the frontend rejects those casts).
4277
+ // be found inside a JSON dyn — the frontend rejects those casts).
4276
4278
  // Bare undefined-armed unions of JSON-safe arms are additionally
4277
- // valid: the DOM holds a first-class undefined value (overflow
4279
+ // valid: the checked-dynamic tree holds a first-class undefined value (overflow
4278
4280
  // reads), which matches exactly the undefined arm.
4279
4281
  const jsonOk = (t) => isJsonSafeType(t, (id) => records.get(id), (id) => unions.get(id));
4280
4282
  const undefArmedOk = e.type.kind === "union" &&
4281
4283
  (unions.get(e.type.unionId)?.arms.every((a) => a.kind === "undefinedT" || jsonOk(a)) ??
4282
4284
  false);
4283
- // bytes<u8> targets extract the DOM's bytes kind (a copy).
4285
+ // bytes<u8> targets extract the checked-dynamic tree's bytes kind (a copy).
4284
4286
  const bytesOk = e.type.kind === "bytes" && e.type.elem === "u8";
4285
- // The %Error root extracts the DOM's error encoding (the "%error"
4287
+ // The %Error root extracts the checked-dynamic tree's error encoding (the "%error"
4286
4288
  // marker object caughtToDyn builds) as a fresh runtime error.
4287
4289
  const errorOk = e.type.kind === "object" && e.type.className === "%Error";
4288
- // ADAPTABLE function targets unwrap or wrap the DOM's function
4290
+ // ADAPTABLE function targets unwrap or wrap the checked-dynamic tree's function
4289
4291
  // kind (the checked-dynamic function boundary, nodes.ts).
4290
4292
  const funcOk = e.type.kind === "func" &&
4291
4293
  canAdaptDynFuncTo(e.type, (id) => records.get(id), (id) => unions.get(id));
4292
- // Runtime HANDLE targets unwrap the DOM's handle kind by tag (a
4294
+ // Runtime HANDLE targets unwrap the checked-dynamic tree's handle kind by tag (a
4293
4295
  // retained reference, no copy — DYN_HANDLE_KINDS).
4294
4296
  const handleOk = DYN_HANDLE_KINDS.has(e.type.kind);
4295
4297
  if (!jsonOk(e.type) && !undefArmedOk && !bytesOk && !errorOk && !funcOk && !handleOk) {
@@ -4512,7 +4514,11 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4512
4514
  // exactly what it produces.
4513
4515
  if (src.kind !== "bytes" &&
4514
4516
  src.kind !== "url" &&
4515
- src.kind !== "dyn" && // DOM values deep-copy in (data kinds; the runtime throws on boxes)
4517
+ src.kind !== "dyn" && // dyn values deep-copy in (data kinds; the runtime throws on boxes)
4518
+ // A STATIC promise crosses as a real engine thenable when its
4519
+ // fulfillment is in the reverse bridge's payload domain
4520
+ // (scr_jsval_from_promise — the async-callback return bridge).
4521
+ !(src.kind === "promise" && islandPromisePayloadTag(src.inner) !== null) &&
4516
4522
  !canMarshalIntoIsland(src, (id) => records.get(id), (id) => unions.get(id)) &&
4517
4523
  !canMarshalTypedFuncIntoIsland(src, (id) => records.get(id), (id) => unions.get(id))) {
4518
4524
  err(`jsMarshal of unmarshalable type ${src.kind}`, e.loc);
@@ -4570,11 +4576,15 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4570
4576
  case "jsBridgePromise": {
4571
4577
  checkExpr(e.value);
4572
4578
  expectType(e.value, JSVAL, "jsBridgePromise operand");
4573
- // The settled engine value crosses as a HANDLE (or not at all):
4574
- // the bridge never converts payloads — typed uses exit later.
4579
+ // The settled engine value crosses as a HANDLE (or not at all) —
4580
+ // plus the ONE converting payload: an `any[]`-declared
4581
+ // fulfillment exits Array.isArray-gated by reference AT THE
4582
+ // SETTLE (SCR_ISLP_JSVAL_ARR); every other typed use exits later.
4575
4583
  if (e.type.kind !== "promise" ||
4576
- (e.type.inner.kind !== "jsval" && e.type.inner.kind !== "void")) {
4577
- err("jsBridgePromise must be a promise of jsval or void", e.loc);
4584
+ (e.type.inner.kind !== "jsval" &&
4585
+ e.type.inner.kind !== "void" &&
4586
+ !(e.type.inner.kind === "array" && e.type.inner.elem.kind === "jsval"))) {
4587
+ err("jsBridgePromise must be a promise of jsval, void, or jsval-element array", e.loc);
4578
4588
  }
4579
4589
  break;
4580
4590
  }
@@ -4863,8 +4873,8 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
4863
4873
  break;
4864
4874
  case "throw":
4865
4875
  checkExpr(s.value);
4866
- // dyn throws are allowed: the DOM node rides the REF cell arm by
4867
- // reference (the JS-lane `throw err` of a DOM argument).
4876
+ // dyn throws are allowed: the dyn node rides the REF cell arm by
4877
+ // reference (the JS-lane `throw err` of a dyn argument).
4868
4878
  if (s.value.type.kind === "void" || s.value.type.kind === "caught") {
4869
4879
  err(`throw of a ${s.value.type.kind} value`, s.loc);
4870
4880
  }