@scriptc/compiler 0.0.11 → 0.0.13
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.
- package/ambient/scriptc-node-fallback.d.ts +153 -24
- package/ambient/scriptc.d.ts +2 -2
- package/dist/backend/cc.d.ts +10 -2
- package/dist/backend/cc.js +12 -0
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-async.js +1 -1
- package/dist/backend/emission/emit-exprs.js +235 -64
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-island.js +1 -1
- package/dist/backend/emission/emit-shapes.js +1 -1
- package/dist/backend/emission/emit-walkers.d.ts +14 -14
- package/dist/backend/emission/emit-walkers.js +44 -44
- package/dist/backend/emission/emit-walkers.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +3 -3
- package/dist/backend/emission/emitter.js +8 -8
- package/dist/backend/emission/may-throw.js +1 -1
- package/dist/backend/llvm/dyn.d.ts +10 -10
- package/dist/backend/llvm/dyn.js +26 -26
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +140 -49
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +1 -1
- package/dist/backend/llvm/walkers.js +2 -2
- package/dist/backend/llvm/walkers.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +1 -1
- package/dist/diagnostics/diagnostic.js +4 -3
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/crypto-tables.d.ts +7 -0
- package/dist/frontend/lowering/crypto-tables.js +139 -0
- package/dist/frontend/lowering/crypto-tables.js.map +1 -0
- package/dist/frontend/lowering/lib-boundary.js +5 -5
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +12 -12
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +45 -27
- package/dist/frontend/lowering/lower-builtins.js +203 -70
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +4 -4
- package/dist/frontend/lowering/lower-calls.js +74 -66
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +41 -7
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +5 -5
- package/dist/frontend/lowering/lower-containers.js +19 -19
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-emitter.js +2 -2
- package/dist/frontend/lowering/lower-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +7 -7
- package/dist/frontend/lowering/lower-exprs.js +227 -119
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +5 -5
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +12 -3
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +17 -17
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.d.ts +11 -1
- package/dist/frontend/lowering/lower-namespaces.js +41 -6
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +21 -0
- package/dist/frontend/lowering/lower-server.js +278 -23
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +1 -1
- package/dist/frontend/lowering/lower-stmts.js +195 -34
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +67 -23
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +31 -13
- package/dist/frontend/lowering/lowerer.js +99 -45
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +6 -0
- package/dist/frontend/lowering/surfaces.js +78 -2
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/program.js +1 -1
- package/dist/frontend/shared.js +7 -7
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/types.d.ts +2 -2
- package/dist/frontend/types.js +27 -15
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.js +44 -8
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +208 -106
- package/dist/ir/nodes.js +100 -22
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +96 -38
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/int-infer.js +13 -0
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/profile.d.ts +8 -6
- package/dist/library/profile.js.map +1 -1
- package/dist/library/sidecar-validate.js +1 -1
- package/dist/library/sidecar-validate.js.map +1 -1
- package/dist/library/sidecar.d.ts +1 -1
- package/dist/library/sidecar.js +20 -7
- package/dist/library/sidecar.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +289 -4
package/dist/ir/validate.js
CHANGED
|
@@ -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,9 @@ 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 },
|
|
68
|
+
"dyn.hasKey": { argTypes: [DYN, STRING], result: BOOL },
|
|
66
69
|
"dyn.toString": { argTypes: [DYN, STRING, STRING], result: STRING },
|
|
67
70
|
"dyn.defineProps": { argTypes: [DYN, DYN], result: DYN },
|
|
68
71
|
"dyn.typeof": { argTypes: [DYN], result: STRING },
|
|
@@ -173,7 +176,7 @@ export const LIB_FN_SIGS = {
|
|
|
173
176
|
"num.fromString": { argTypes: [STRING], result: F64 },
|
|
174
177
|
"num.isNaN": { argTypes: [F64], result: BOOL },
|
|
175
178
|
"str.encodeUriComponent": { argTypes: [STRING], result: STRING },
|
|
176
|
-
// The base64 globals: the argument is a
|
|
179
|
+
// The base64 globals: the argument is a dyn value (WebIDL ToString
|
|
177
180
|
// runs in the runtime); the zero-argument form always throws.
|
|
178
181
|
"str.atob": { argTypes: [DYN], result: STRING },
|
|
179
182
|
"str.btoa": { argTypes: [DYN], result: STRING },
|
|
@@ -230,7 +233,7 @@ export const LIB_FN_SIGS = {
|
|
|
230
233
|
// node:querystring. qs.parse's result is the call site's ParsedUrlQuery
|
|
231
234
|
// dictionary record (VOID is the networkInterfaces sentinel — the
|
|
232
235
|
// libCall case checks the structure); qs.stringify's object argument
|
|
233
|
-
// is a
|
|
236
|
+
// is a dyn value (the frontend dynFroms typed records).
|
|
234
237
|
"qs.parse": { argTypes: [STRING, STRING, STRING, F64], result: VOID },
|
|
235
238
|
"qs.stringify": { argTypes: [DYN, STRING, STRING], result: STRING },
|
|
236
239
|
"qs.escape": { argTypes: [STRING], result: STRING },
|
|
@@ -438,6 +441,9 @@ export const LIB_FN_SIGS = {
|
|
|
438
441
|
// program-dependent (checked below); header pairs arrive flat.
|
|
439
442
|
"http.request": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL], result: HTTPCLIENTREQ_T },
|
|
440
443
|
"http.requestCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, null], result: HTTPCLIENTREQ_T },
|
|
444
|
+
"http.agentNew": { argTypes: [BOOL, BOOL, F64, F64, F64, F64, F64], result: DYN },
|
|
445
|
+
"http.requestAgent": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, DYN], result: HTTPCLIENTREQ_T },
|
|
446
|
+
"http.requestAgentCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, DYN, null], result: HTTPCLIENTREQ_T },
|
|
441
447
|
"http.requestUrl": { argTypes: [STRING, STRING, BOOL], result: HTTPCLIENTREQ_T },
|
|
442
448
|
"http.requestUrlCb": { argTypes: [STRING, STRING, BOOL, null], result: HTTPCLIENTREQ_T },
|
|
443
449
|
"net.sockOnReadable": { argTypes: [NETSOCKET_T, null, BOOL], result: VOID },
|
|
@@ -446,6 +452,13 @@ export const LIB_FN_SIGS = {
|
|
|
446
452
|
// placeholder the special case overrides).
|
|
447
453
|
"net.sockRead": { argTypes: [NETSOCKET_T, F64], result: VOID },
|
|
448
454
|
"net.sockUnshift": { argTypes: [NETSOCKET_T, BYTES_U8], result: VOID },
|
|
455
|
+
"net.sockPause": { argTypes: [NETSOCKET_T], result: NETSOCKET_T },
|
|
456
|
+
"net.sockResume": { argTypes: [NETSOCKET_T], result: NETSOCKET_T },
|
|
457
|
+
"net.sockSetNoDelay": { argTypes: [NETSOCKET_T, BOOL], result: NETSOCKET_T },
|
|
458
|
+
"net.sockDestroySoon": { argTypes: [NETSOCKET_T], result: VOID },
|
|
459
|
+
"net.sockBytesWritten": { argTypes: [NETSOCKET_T], result: F64 },
|
|
460
|
+
"net.sockReadable": { argTypes: [NETSOCKET_T], result: BOOL },
|
|
461
|
+
"net.sockOnFinish": { argTypes: [NETSOCKET_T, { kind: "func", params: [], ret: VOID }], result: VOID },
|
|
449
462
|
"net.serverEmitConnection": { argTypes: [NETSERVER_T, NETSOCKET_T], result: VOID },
|
|
450
463
|
// tls/https: cert/key/ca PEM arguments are strings OR Buffers (null =
|
|
451
464
|
// both accepted; the emitter passes data+len either way).
|
|
@@ -459,6 +472,10 @@ export const LIB_FN_SIGS = {
|
|
|
459
472
|
"tls.createServerDynCb": { argTypes: [DYN, null], result: NETSERVER_T },
|
|
460
473
|
"https.createServerDyn": { argTypes: [DYN], result: NETSERVER_T },
|
|
461
474
|
"https.createServerDynCb": { argTypes: [DYN, null], result: NETSERVER_T },
|
|
475
|
+
"http2.createSecureServerReq": { argTypes: [null, null, null], result: NETSERVER_T },
|
|
476
|
+
"http2.createSecureServerH2Req": { argTypes: [null, null, null], result: NETSERVER_T },
|
|
477
|
+
"http2.createSecureServerDyn": { argTypes: [DYN], result: NETSERVER_T },
|
|
478
|
+
"http2.createSecureServerDynCb": { argTypes: [DYN, null], result: NETSERVER_T },
|
|
462
479
|
// tls.connect(port, host, opts[, cb]) — port -1 / host "" read the
|
|
463
480
|
// options record; the callback fires post-handshake (secureConnect).
|
|
464
481
|
"tls.connect": { argTypes: [F64, STRING, DYN], result: NETSOCKET_T },
|
|
@@ -473,6 +490,11 @@ export const LIB_FN_SIGS = {
|
|
|
473
490
|
"tls.createSecureContext": { argTypes: [null, null], result: SECURECTX_T },
|
|
474
491
|
"tls.createSecureContextDyn": { argTypes: [DYN], result: SECURECTX_T },
|
|
475
492
|
"tls.caCertsChk": { argTypes: [DYN, STRING], result: VOID },
|
|
493
|
+
// The CA-store introspection unit (scr_tls_ca.c): per-type cached PEM
|
|
494
|
+
// string arrays and the default-set replacement.
|
|
495
|
+
"tlsca.get": { argTypes: [STRING], result: arrayOf(STRING) },
|
|
496
|
+
"tlsca.root": { argTypes: [], result: arrayOf(STRING) },
|
|
497
|
+
"tlsca.set": { argTypes: [arrayOf(STRING)], result: VOID },
|
|
476
498
|
"https.createServer": { argTypes: [null, null, null], result: NETSERVER_T },
|
|
477
499
|
// http2's allowHTTP1 compatibility server (divergence 57): cert/key
|
|
478
500
|
// like tls.createServer; the 'request' handler arrives separately via
|
|
@@ -560,6 +582,8 @@ export const LIB_FN_SIGS = {
|
|
|
560
582
|
"http.requestConnCb": { argTypes: [null, STRING, STRING, F64, arrayOf(STRING), BOOL, null], result: HTTPCLIENTREQ_T },
|
|
561
583
|
"https.request": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null], result: HTTPCLIENTREQ_T },
|
|
562
584
|
"https.requestCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null, null], result: HTTPCLIENTREQ_T },
|
|
585
|
+
"https.requestAgent": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null, DYN], result: HTTPCLIENTREQ_T },
|
|
586
|
+
"https.requestAgentCb": { argTypes: [STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null, DYN, null], result: HTTPCLIENTREQ_T },
|
|
563
587
|
// The requestFn binding's runtime-secure rows: https.request's shape
|
|
564
588
|
// with the leading `secure` bool.
|
|
565
589
|
"https.requestFn": { argTypes: [BOOL, STRING, F64, STRING, STRING, F64, arrayOf(STRING), BOOL, BOOL, null], result: HTTPCLIENTREQ_T },
|
|
@@ -647,7 +671,7 @@ export const LIB_FN_SIGS = {
|
|
|
647
671
|
"buffer.isEncoding": { argTypes: [STRING], result: BOOL },
|
|
648
672
|
"buffer.concatLen": { argTypes: [arrayOf(BYTES_U8), F64], result: BYTES_U8 },
|
|
649
673
|
// The checked-dynamic compare/equals validators (Node's argument
|
|
650
|
-
// ladders over
|
|
674
|
+
// ladders over dyn-boxed invalid-input probes).
|
|
651
675
|
"buffer.compareChk": { argTypes: [DYN, DYN], result: F64 },
|
|
652
676
|
"bytes.equalsChk": { argTypes: [BYTES_U8, DYN], result: BOOL },
|
|
653
677
|
"bytes.compareChk": { argTypes: [BYTES_U8, DYN, DYN, DYN, DYN, DYN], result: F64 },
|
|
@@ -726,7 +750,7 @@ export const LIB_FN_SIGS = {
|
|
|
726
750
|
// Receiver (any error-hierarchy object) and the program-dependent
|
|
727
751
|
// `string | undefined` result are checked in the libCall case.
|
|
728
752
|
"error.code": { argTypes: [null], result: VOID },
|
|
729
|
-
// DOMException: construction takes the two
|
|
753
|
+
// DOMException: construction takes the two dyn args (WebIDL's
|
|
730
754
|
// resolution runs in the runtime); the %DOMException result is a
|
|
731
755
|
// program-dependent object type, checked in the libCall case. The
|
|
732
756
|
// read surface takes the %DOMException receiver (a null slot — the
|
|
@@ -877,7 +901,7 @@ export const LIB_FN_SIGS = {
|
|
|
877
901
|
// Symbol strict equality (pointer identity; scr_symbol.c).
|
|
878
902
|
"assert.eqSym": { argTypes: [{ kind: "symbol" }, { kind: "symbol" }, BOOL, BOOL, STRING, BOOL], result: VOID },
|
|
879
903
|
// The equality quartet over checked-dynamic operands (the frontend
|
|
880
|
-
// boxes a static side into the
|
|
904
|
+
// boxes a static side into the checked-dynamic tree first).
|
|
881
905
|
"assert.eqDyn": { argTypes: [DYN, DYN, BOOL, BOOL, STRING, BOOL], result: VOID },
|
|
882
906
|
// The throws(fn, {shape}) accumulator: begin/slot calls never throw;
|
|
883
907
|
// shapeEnd throws the Comparison diff. The error slot is the
|
|
@@ -957,7 +981,10 @@ export const LIB_FN_SIGS = {
|
|
|
957
981
|
"dc.tcTraceSync": { argTypes: [F64, DYN, DYN, DYN, DYN], result: DYN },
|
|
958
982
|
"dc.tcTraceCallback": { argTypes: [F64, DYN, F64, DYN, DYN, DYN], result: DYN },
|
|
959
983
|
"dc.tcTracePromise": { argTypes: [F64, DYN, DYN, DYN, DYN], result: { kind: "promise", inner: DYN } },
|
|
960
|
-
"process.onUnhandledRejection": { argTypes: [DYN], result: VOID },
|
|
984
|
+
"process.onUnhandledRejection": { argTypes: [DYN, BOOL], result: VOID },
|
|
985
|
+
"process.offUnhandledRejection": { argTypes: [DYN], result: VOID },
|
|
986
|
+
"process.onRejectionHandled": { argTypes: [DYN, BOOL], result: VOID },
|
|
987
|
+
"process.offRejectionHandled": { argTypes: [DYN], result: VOID },
|
|
961
988
|
"process.onWarning": { argTypes: [DYN], result: VOID },
|
|
962
989
|
"process.offWarning": { argTypes: [DYN], result: VOID },
|
|
963
990
|
"process.emitWarning": { argTypes: [DYN], result: VOID },
|
|
@@ -1183,7 +1210,7 @@ export function validateModule(mod) {
|
|
|
1183
1210
|
// Unit kinds (undefinedT/nullT) exist only as union arms — a BARE
|
|
1184
1211
|
// unit field is as malformed as a void one. dyn fields are VALID
|
|
1185
1212
|
// (`[string, unknown]` entries tuples, `{ v: unknown }` records):
|
|
1186
|
-
// the slot holds a
|
|
1213
|
+
// the slot holds a dyn value with the overflow map's plumbing.
|
|
1187
1214
|
if (f.type.kind === "void" || f.type.kind === "jsval" ||
|
|
1188
1215
|
isUnitType(f.type)) {
|
|
1189
1216
|
errors.push({ message: `record ${rec.id}: field "${f.name}" is ${f.type.kind}`, loc: noLoc });
|
|
@@ -1525,7 +1552,10 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
1525
1552
|
// Symbol identity IS pointer identity (the frontend's rule).
|
|
1526
1553
|
e.left.type.kind === "symbol" ||
|
|
1527
1554
|
e.left.type.kind === "bytes" ||
|
|
1528
|
-
e.left.type.kind === "promise"
|
|
1555
|
+
e.left.type.kind === "promise" ||
|
|
1556
|
+
// Runtime handles are objects to === (one handle per socket/
|
|
1557
|
+
// request — pointer identity is JS's object equality).
|
|
1558
|
+
DYN_HANDLE_KINDS.has(e.left.type.kind))) {
|
|
1529
1559
|
// Reference identity: both operands must be the same ref type.
|
|
1530
1560
|
if (!typeEquals(e.left.type, e.right.type)) {
|
|
1531
1561
|
err(`bin ${e.op} on references: operand types differ`, e.loc);
|
|
@@ -1741,10 +1771,10 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
1741
1771
|
}
|
|
1742
1772
|
break;
|
|
1743
1773
|
}
|
|
1744
|
-
// A dyn (
|
|
1774
|
+
// A dyn (dyn) chain (`rawName?.match(re)` on a JSON.parse result):
|
|
1745
1775
|
// the nullish test reads the node's kind tag; the body is the
|
|
1746
1776
|
// validated dynamic dispatch, its result converted back into the
|
|
1747
|
-
//
|
|
1777
|
+
// dyn (dynFrom) — so body and result are dyn, or void for
|
|
1748
1778
|
// statement-position chains.
|
|
1749
1779
|
if (e.receiver.type.kind === "dyn") {
|
|
1750
1780
|
if (activeChains.has(e.id))
|
|
@@ -1789,7 +1819,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
1789
1819
|
break;
|
|
1790
1820
|
}
|
|
1791
1821
|
expectType(e.body, e.type, "optChain body");
|
|
1792
|
-
// dyn results carry the unit path as the undefined
|
|
1822
|
+
// dyn results carry the unit path as the undefined dyn value; every
|
|
1793
1823
|
// other value result needs an undefined arm to land on.
|
|
1794
1824
|
if (e.type.kind !== "dyn") {
|
|
1795
1825
|
const rdef = e.type.kind === "union" ? unions.get(e.type.unionId) : undefined;
|
|
@@ -1821,7 +1851,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
1821
1851
|
}
|
|
1822
1852
|
// The CHECKED-DYNAMIC form: the runtime kind decides (the
|
|
1823
1853
|
// emitters' scr_dyn_is_nullish arm) — left, right, and result
|
|
1824
|
-
// all live in the
|
|
1854
|
+
// all live in the checked-dynamic tree.
|
|
1825
1855
|
if (e.left.type.kind === "dyn") {
|
|
1826
1856
|
if (e.type.kind !== "dyn")
|
|
1827
1857
|
err("dyn nullish must answer dyn", e.loc);
|
|
@@ -1862,6 +1892,21 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
1862
1892
|
err(`orDefault left references unknown union ${e.left.type.unionId}`, e.loc);
|
|
1863
1893
|
break;
|
|
1864
1894
|
}
|
|
1895
|
+
// Retagged shape: the truthy side is a call to the named helper, so
|
|
1896
|
+
// the arm count is free and the type rule is the helper's signature.
|
|
1897
|
+
if (e.retag !== undefined) {
|
|
1898
|
+
const helper = functions.get(e.retag);
|
|
1899
|
+
if (!helper) {
|
|
1900
|
+
err(`orDefault retag calls undeclared function "${e.retag}"`, e.loc);
|
|
1901
|
+
}
|
|
1902
|
+
else if (helper.params.length !== 1 || !typeEquals(helper.params[0].type, e.left.type)) {
|
|
1903
|
+
err(`orDefault retag ${e.retag} must take exactly the left union`, e.loc);
|
|
1904
|
+
}
|
|
1905
|
+
else if (!typeEquals(callSiteReturnType(helper), e.type)) {
|
|
1906
|
+
err(`orDefault retag ${e.retag} must return the node's type`, e.loc);
|
|
1907
|
+
}
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1865
1910
|
const rest = def.arms.filter((a) => !isUnitType(a));
|
|
1866
1911
|
if (rest.length !== 1 || !typeEquals(e.type, rest[0])) {
|
|
1867
1912
|
err("orDefault type must be the left union's single non-unit arm", e.loc);
|
|
@@ -2398,7 +2443,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
2398
2443
|
}
|
|
2399
2444
|
});
|
|
2400
2445
|
// Result func type must match the target's signature. A VARIADIC
|
|
2401
|
-
// (rest-marked) type hides one synthetic trailing
|
|
2446
|
+
// (rest-marked) type hides one synthetic trailing dyn-array param
|
|
2402
2447
|
// in the lifted function (the thunk fills it) — the type's
|
|
2403
2448
|
// declared params plus that one must match.
|
|
2404
2449
|
if (e.type.kind === "func") {
|
|
@@ -2771,7 +2816,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
2771
2816
|
expectType(e.obj, { kind: "record", shapeId: e.shapeId }, "recordKeyGet receiver");
|
|
2772
2817
|
expectType(e.key, STRING, "recordKeyGet key");
|
|
2773
2818
|
// Every reachable value must SURFACE as the result type: identity,
|
|
2774
|
-
// an arm of a union result, or (dyn results) a
|
|
2819
|
+
// an arm of a union result, or (dyn results) a dyn conversion —
|
|
2775
2820
|
// the frontend's recordKeyResultOk mirror. overflowOnly reads (a
|
|
2776
2821
|
// literal key naming no declared field) skip the declared check
|
|
2777
2822
|
// and require the overflow to exist.
|
|
@@ -2812,7 +2857,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
2812
2857
|
if (e.type.kind !== "dyn")
|
|
2813
2858
|
err(`dynFrom must be dyn-typed, got ${e.type.kind}`, e.loc);
|
|
2814
2859
|
// A bare unit literal is legal exactly here (like unionWrap): the
|
|
2815
|
-
//
|
|
2860
|
+
// dyn has first-class undefined/null values.
|
|
2816
2861
|
if (e.value.kind === "unitLit") {
|
|
2817
2862
|
const want = e.value.unit === "undefined" ? "undefinedT" : "nullT";
|
|
2818
2863
|
if (e.value.type.kind !== want) {
|
|
@@ -2821,19 +2866,19 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
2821
2866
|
break;
|
|
2822
2867
|
}
|
|
2823
2868
|
checkExpr(e.value);
|
|
2824
|
-
// Domain: JSON-safe, bytes<u8> (the
|
|
2869
|
+
// Domain: JSON-safe, bytes<u8> (the checked-dynamic tree's bytes kind — payload
|
|
2825
2870
|
// copied), an undefined-armed union of JSON-safe arms (the
|
|
2826
|
-
// undefined arm becomes the undefined
|
|
2827
|
-
// function type (the
|
|
2871
|
+
// undefined arm becomes the undefined dyn value), or a BOXABLE
|
|
2872
|
+
// function type (the checked-dynamic tree's function kind — canConvertToDyn folds
|
|
2828
2873
|
// all four in).
|
|
2829
2874
|
const vt = e.value.type;
|
|
2830
2875
|
if (!canConvertToDyn(vt, (id) => records.get(id), (id) => unions.get(id))) {
|
|
2831
|
-
err(`dynFrom of non-
|
|
2876
|
+
err(`dynFrom of non-dyn-convertible type ${vt.kind}`, e.loc);
|
|
2832
2877
|
}
|
|
2833
2878
|
break;
|
|
2834
2879
|
}
|
|
2835
2880
|
case "dynFromJsval": {
|
|
2836
|
-
// The jsval→
|
|
2881
|
+
// The jsval→dyn crossing: exactly a jsval operand into a dyn
|
|
2837
2882
|
// result (the by-reference island wrap; scalars normalize at
|
|
2838
2883
|
// runtime).
|
|
2839
2884
|
checkExpr(e.value);
|
|
@@ -3013,7 +3058,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
3013
3058
|
break;
|
|
3014
3059
|
}
|
|
3015
3060
|
case "caughtToDyn": {
|
|
3016
|
-
// The caught snapshot converting to a dyn
|
|
3061
|
+
// The caught snapshot converting to a dyn value (an unknown
|
|
3017
3062
|
// slot): operand caught, result dyn — the runtime dispatch handles
|
|
3018
3063
|
// every payload kind, so nothing else constrains it.
|
|
3019
3064
|
checkExpr(e.value);
|
|
@@ -3428,9 +3473,14 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
3428
3473
|
}
|
|
3429
3474
|
break;
|
|
3430
3475
|
}
|
|
3431
|
-
if (e.fn === "http.requestCb" || e.fn === "http.requestUrlCb" || e.fn === "http.clientOnResponse"
|
|
3476
|
+
if (e.fn === "http.requestCb" || e.fn === "http.requestUrlCb" || e.fn === "http.clientOnResponse" ||
|
|
3477
|
+
e.fn === "http.requestAgentCb" || e.fn === "https.requestAgentCb") {
|
|
3432
3478
|
// The response listener: void, no params or exactly (res: httpReq).
|
|
3433
|
-
const cbT = e.args[e.fn === "http.requestCb" ? 7
|
|
3479
|
+
const cbT = e.args[e.fn === "http.requestCb" ? 7
|
|
3480
|
+
: e.fn === "http.requestUrlCb" ? 3
|
|
3481
|
+
: e.fn === "http.requestAgentCb" ? 8
|
|
3482
|
+
: e.fn === "https.requestAgentCb" ? 10
|
|
3483
|
+
: 1]?.type;
|
|
3434
3484
|
let ok = cbT?.kind === "func" && cbT.ret.kind === "void" && cbT.params.length <= 1;
|
|
3435
3485
|
if (ok && cbT?.kind === "func" && cbT.params.length === 1) {
|
|
3436
3486
|
ok = cbT.params[0].kind === "httpReq";
|
|
@@ -4259,7 +4309,7 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
4259
4309
|
}
|
|
4260
4310
|
// The value's STATIC type drives the emitted serializer — it must be
|
|
4261
4311
|
// 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
|
|
4312
|
+
// A dyn ROOT is the one non-static shape allowed: the runtime's dyn
|
|
4263
4313
|
// walker serializes it (scr_dyn_format_j), no emitted serializer.
|
|
4264
4314
|
if (e.value.type.kind !== "dyn" &&
|
|
4265
4315
|
!isJsonSafeType(e.value.type, (id) => records.get(id), (id) => unions.get(id))) {
|
|
@@ -4272,24 +4322,24 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
4272
4322
|
expectType(e.value, DYN, "dynCheck operand");
|
|
4273
4323
|
// The target drives the emitted validator/builder: non-dyn,
|
|
4274
4324
|
// non-void, JSON-representable (closures/class instances can never
|
|
4275
|
-
// be found inside a JSON
|
|
4325
|
+
// be found inside a JSON dyn — the frontend rejects those casts).
|
|
4276
4326
|
// Bare undefined-armed unions of JSON-safe arms are additionally
|
|
4277
|
-
// valid: the
|
|
4327
|
+
// valid: the checked-dynamic tree holds a first-class undefined value (overflow
|
|
4278
4328
|
// reads), which matches exactly the undefined arm.
|
|
4279
4329
|
const jsonOk = (t) => isJsonSafeType(t, (id) => records.get(id), (id) => unions.get(id));
|
|
4280
4330
|
const undefArmedOk = e.type.kind === "union" &&
|
|
4281
4331
|
(unions.get(e.type.unionId)?.arms.every((a) => a.kind === "undefinedT" || jsonOk(a)) ??
|
|
4282
4332
|
false);
|
|
4283
|
-
// bytes<u8> targets extract the
|
|
4333
|
+
// bytes<u8> targets extract the checked-dynamic tree's bytes kind (a copy).
|
|
4284
4334
|
const bytesOk = e.type.kind === "bytes" && e.type.elem === "u8";
|
|
4285
|
-
// The %Error root extracts the
|
|
4335
|
+
// The %Error root extracts the checked-dynamic tree's error encoding (the "%error"
|
|
4286
4336
|
// marker object caughtToDyn builds) as a fresh runtime error.
|
|
4287
4337
|
const errorOk = e.type.kind === "object" && e.type.className === "%Error";
|
|
4288
|
-
// ADAPTABLE function targets unwrap or wrap the
|
|
4338
|
+
// ADAPTABLE function targets unwrap or wrap the checked-dynamic tree's function
|
|
4289
4339
|
// kind (the checked-dynamic function boundary, nodes.ts).
|
|
4290
4340
|
const funcOk = e.type.kind === "func" &&
|
|
4291
4341
|
canAdaptDynFuncTo(e.type, (id) => records.get(id), (id) => unions.get(id));
|
|
4292
|
-
// Runtime HANDLE targets unwrap the
|
|
4342
|
+
// Runtime HANDLE targets unwrap the checked-dynamic tree's handle kind by tag (a
|
|
4293
4343
|
// retained reference, no copy — DYN_HANDLE_KINDS).
|
|
4294
4344
|
const handleOk = DYN_HANDLE_KINDS.has(e.type.kind);
|
|
4295
4345
|
if (!jsonOk(e.type) && !undefArmedOk && !bytesOk && !errorOk && !funcOk && !handleOk) {
|
|
@@ -4512,7 +4562,11 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
4512
4562
|
// exactly what it produces.
|
|
4513
4563
|
if (src.kind !== "bytes" &&
|
|
4514
4564
|
src.kind !== "url" &&
|
|
4515
|
-
src.kind !== "dyn" && //
|
|
4565
|
+
src.kind !== "dyn" && // dyn values deep-copy in (data kinds; the runtime throws on boxes)
|
|
4566
|
+
// A STATIC promise crosses as a real engine thenable when its
|
|
4567
|
+
// fulfillment is in the reverse bridge's payload domain
|
|
4568
|
+
// (scr_jsval_from_promise — the async-callback return bridge).
|
|
4569
|
+
!(src.kind === "promise" && islandPromisePayloadTag(src.inner) !== null) &&
|
|
4516
4570
|
!canMarshalIntoIsland(src, (id) => records.get(id), (id) => unions.get(id)) &&
|
|
4517
4571
|
!canMarshalTypedFuncIntoIsland(src, (id) => records.get(id), (id) => unions.get(id))) {
|
|
4518
4572
|
err(`jsMarshal of unmarshalable type ${src.kind}`, e.loc);
|
|
@@ -4570,11 +4624,15 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
4570
4624
|
case "jsBridgePromise": {
|
|
4571
4625
|
checkExpr(e.value);
|
|
4572
4626
|
expectType(e.value, JSVAL, "jsBridgePromise operand");
|
|
4573
|
-
// The settled engine value crosses as a HANDLE (or not at all)
|
|
4574
|
-
// the
|
|
4627
|
+
// The settled engine value crosses as a HANDLE (or not at all) —
|
|
4628
|
+
// plus the ONE converting payload: an `any[]`-declared
|
|
4629
|
+
// fulfillment exits Array.isArray-gated by reference AT THE
|
|
4630
|
+
// SETTLE (SCR_ISLP_JSVAL_ARR); every other typed use exits later.
|
|
4575
4631
|
if (e.type.kind !== "promise" ||
|
|
4576
|
-
(e.type.inner.kind !== "jsval" &&
|
|
4577
|
-
|
|
4632
|
+
(e.type.inner.kind !== "jsval" &&
|
|
4633
|
+
e.type.inner.kind !== "void" &&
|
|
4634
|
+
!(e.type.inner.kind === "array" && e.type.inner.elem.kind === "jsval"))) {
|
|
4635
|
+
err("jsBridgePromise must be a promise of jsval, void, or jsval-element array", e.loc);
|
|
4578
4636
|
}
|
|
4579
4637
|
break;
|
|
4580
4638
|
}
|
|
@@ -4863,8 +4921,8 @@ function validateFunction(fn, functions, classes, records, unions, globals, erro
|
|
|
4863
4921
|
break;
|
|
4864
4922
|
case "throw":
|
|
4865
4923
|
checkExpr(s.value);
|
|
4866
|
-
// dyn throws are allowed: the
|
|
4867
|
-
// reference (the JS-lane `throw err` of a
|
|
4924
|
+
// dyn throws are allowed: the dyn node rides the REF cell arm by
|
|
4925
|
+
// reference (the JS-lane `throw err` of a dyn argument).
|
|
4868
4926
|
if (s.value.type.kind === "void" || s.value.type.kind === "caught") {
|
|
4869
4927
|
err(`throw of a ${s.value.type.kind} value`, s.loc);
|
|
4870
4928
|
}
|