@scriptc/compiler 0.2.0 → 0.2.1
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 +25 -15
- package/dist/backend/cycle-analysis.js +1 -0
- package/dist/backend/cycle-analysis.js.map +1 -1
- package/dist/backend/llvm/classes.js +21 -5
- package/dist/backend/llvm/classes.js.map +1 -1
- package/dist/backend/llvm/dyn.d.ts +5 -0
- package/dist/backend/llvm/dyn.js +166 -99
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.d.ts +2 -2
- package/dist/backend/llvm/emitter.js +79 -20
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -1
- package/dist/backend/llvm/expr-bytes.js +28 -17
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-control.js +1 -1
- package/dist/backend/llvm/expr-control.js.map +1 -1
- package/dist/backend/llvm/expr-dynamic.js +18 -9
- package/dist/backend/llvm/expr-dynamic.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.js +11 -1
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-records.js +11 -3
- package/dist/backend/llvm/expr-records.js.map +1 -1
- package/dist/backend/llvm/expr-stream-bridges.js +125 -17
- package/dist/backend/llvm/expr-stream-bridges.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +23 -3
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +45 -2
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/shapes.js +8 -2
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +3 -6
- package/dist/backend/native-toolchain.js +53 -23
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/native-toolchain.test.js +72 -0
- package/dist/backend/native-toolchain.test.js.map +1 -1
- package/dist/backend/runtime-abi.d.ts +2 -2
- package/dist/backend/runtime-abi.js +2 -2
- package/dist/backend/runtime-pack-native.js +4 -1
- package/dist/backend/runtime-pack-native.js.map +1 -1
- package/dist/backend/runtime-pack-targets.test.js +1 -1
- package/dist/backend/runtime-pack.test.js +1 -1
- package/dist/backend/targets.js +10 -6
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +7 -0
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/compat/fetch-profile.js +34 -4
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +2 -7
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/class-callbacks.d.ts +3 -3
- package/dist/frontend/lowering/class-callbacks.js +26 -15
- package/dist/frontend/lowering/class-callbacks.js.map +1 -1
- package/dist/frontend/lowering/class-construction.d.ts +12 -0
- package/dist/frontend/lowering/class-construction.js +156 -0
- package/dist/frontend/lowering/class-construction.js.map +1 -0
- package/dist/frontend/lowering/class-descriptors.d.ts +1 -0
- package/dist/frontend/lowering/class-descriptors.js +46 -5
- package/dist/frontend/lowering/class-descriptors.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.d.ts +11 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.js +403 -48
- package/dist/frontend/lowering/class-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js +2 -1
- package/dist/frontend/lowering/class-dynamic-dispatch.test.js.map +1 -1
- package/dist/frontend/lowering/class-instance-constructor.js +4 -1
- package/dist/frontend/lowering/class-instance-constructor.js.map +1 -1
- package/dist/frontend/lowering/class-method-values.d.ts +4 -1
- package/dist/frontend/lowering/class-method-values.js +72 -7
- package/dist/frontend/lowering/class-method-values.js.map +1 -1
- package/dist/frontend/lowering/class-prototypes.d.ts +5 -2
- package/dist/frontend/lowering/class-prototypes.js +121 -13
- package/dist/frontend/lowering/class-prototypes.js.map +1 -1
- package/dist/frontend/lowering/class-runtime-statics.d.ts +8 -0
- package/dist/frontend/lowering/class-runtime-statics.js +66 -0
- package/dist/frontend/lowering/class-runtime-statics.js.map +1 -0
- package/dist/frontend/lowering/class-static-data.js +2 -2
- package/dist/frontend/lowering/class-static-data.js.map +1 -1
- package/dist/frontend/lowering/containers/bytes.js +49 -13
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.js +19 -47
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/error-methods.d.ts +4 -1
- package/dist/frontend/lowering/error-methods.js +100 -1
- package/dist/frontend/lowering/error-methods.js.map +1 -1
- package/dist/frontend/lowering/expressions/native-proxy.js +3 -1
- package/dist/frontend/lowering/expressions/native-proxy.js.map +1 -1
- package/dist/frontend/lowering/expressions/nullish-assignment.js +19 -11
- package/dist/frontend/lowering/expressions/nullish-assignment.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +38 -7
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/expressions/optional-chains.d.ts +3 -4
- package/dist/frontend/lowering/expressions/optional-chains.js +69 -17
- package/dist/frontend/lowering/expressions/optional-chains.js.map +1 -1
- package/dist/frontend/lowering/function-context.d.ts +11 -3
- package/dist/frontend/lowering/function-context.js +11 -5
- package/dist/frontend/lowering/function-context.js.map +1 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.d.ts +1 -0
- package/dist/frontend/lowering/generator-dynamic-dispatch.js +39 -1
- package/dist/frontend/lowering/generator-dynamic-dispatch.js.map +1 -1
- package/dist/frontend/lowering/lib-boundary.d.ts +2 -0
- package/dist/frontend/lowering/lib-boundary.js +54 -1
- package/dist/frontend/lowering/lib-boundary.js.map +1 -1
- package/dist/frontend/lowering/lower-builtin-values.d.ts +7 -1
- package/dist/frontend/lowering/lower-builtin-values.js +113 -3
- package/dist/frontend/lowering/lower-builtin-values.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +6 -5
- package/dist/frontend/lowering/lower-builtins.js +156 -41
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +8 -5
- package/dist/frontend/lowering/lower-calls.js +448 -83
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.d.ts +13 -13
- package/dist/frontend/lowering/lower-classes.js +650 -176
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +9 -0
- package/dist/frontend/lowering/lower-containers.js +135 -36
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-dgram.js +3 -2
- package/dist/frontend/lowering/lower-dgram.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +2 -2
- package/dist/frontend/lowering/lower-exprs.js +531 -126
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +12 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +2 -0
- package/dist/frontend/lowering/lower-island.js +32 -10
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +220 -17
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.test.d.ts +1 -0
- package/dist/frontend/lowering/lower-modules.test.js +39 -0
- package/dist/frontend/lowering/lower-modules.test.js.map +1 -0
- package/dist/frontend/lowering/lower-stmts.d.ts +7 -3
- package/dist/frontend/lowering/lower-stmts.js +135 -26
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.js +1 -1
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +27 -1
- package/dist/frontend/lowering/lowerer.js +172 -50
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/lowerer.test.js +149 -3
- package/dist/frontend/lowering/lowerer.test.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +2 -0
- package/dist/frontend/lowering/surfaces.js +25 -8
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/lowering/text-decoder-encoding.d.ts +2 -0
- package/dist/frontend/lowering/text-decoder-encoding.js +5 -0
- package/dist/frontend/lowering/text-decoder-encoding.js.map +1 -1
- package/dist/frontend/lowering/unregistered-class-types.test.js +3 -3
- package/dist/frontend/lowering/unregistered-class-types.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.js +116 -34
- package/dist/frontend/npm-static-prune.js.map +1 -1
- package/dist/frontend/npm-static-prune.test.js +8 -0
- package/dist/frontend/npm-static-prune.test.js.map +1 -1
- package/dist/frontend/program.d.ts +1 -1
- package/dist/frontend/program.js +53 -24
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/program.test.js +18 -0
- package/dist/frontend/program.test.js.map +1 -1
- package/dist/frontend/ts7/ast.js +4 -3
- package/dist/frontend/ts7/ast.js.map +1 -1
- package/dist/frontend/ts7/semantic-json.js +5 -10
- package/dist/frontend/ts7/semantic-json.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +9 -1
- package/dist/frontend/type-mapper.js +90 -13
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/frontend/type-mapper.test.js +23 -0
- package/dist/frontend/type-mapper.test.js.map +1 -1
- package/dist/frontend/union-discriminants.d.ts +1 -1
- package/dist/frontend/union-discriminants.js +2 -2
- package/dist/frontend/union-discriminants.js.map +1 -1
- package/dist/ir/analysis.js +2 -0
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/ir.d.ts +52 -33
- package/dist/ir/ir.js +142 -42
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +35 -0
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/serialize.js +15 -3
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/serialize.test.js +5 -1
- package/dist/ir/serialize.test.js.map +1 -1
- package/dist/ir/validate.js +80 -11
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.js +61 -1
- package/dist/ir/validate.test.js.map +1 -1
- package/dist/native/sanitizer.js +3 -1
- package/dist/native/sanitizer.js.map +1 -1
- package/dist/native/toolchain.d.ts +1 -1
- package/dist/native/toolchain.js +26 -6
- package/dist/native/toolchain.js.map +1 -1
- package/dist/native/toolchain.test.js +53 -1
- package/dist/native/toolchain.test.js.map +1 -1
- package/package.json +20 -20
- package/surface-manifest.json +56 -81
package/dist/ir/ir.js
CHANGED
|
@@ -959,7 +959,7 @@ export function canMarshalTypedFuncIntoIsland(t, getRecord, getUnion) {
|
|
|
959
959
|
* through a dyn value), properties ON function values, and params/results
|
|
960
960
|
* outside the conversion domains (Maps, class instances, ...). Promises
|
|
961
961
|
* CONVERT in (canConvertToDyn's promise arm — an async dyn-boxed closure's
|
|
962
|
-
* return)
|
|
962
|
+
* return); checking OUT preserves the boxed Promise<unknown> payload ABI.
|
|
963
963
|
*/
|
|
964
964
|
/** The runtime HANDLE kinds that cross the checked-dynamic boundary as
|
|
965
965
|
* the checked-dynamic tree's HANDLE kind (SCR_DYN_HANDLE): boxed by REFERENCE (identity —
|
|
@@ -1016,7 +1016,7 @@ export function classDynViewSupported(fields, getRecord, getUnion) {
|
|
|
1016
1016
|
* JSON-safe data, numeric typed arrays (retained views), identity-preserving class
|
|
1017
1017
|
* references, undefined-armed unions of those arms, boxable function types,
|
|
1018
1018
|
* and the runtime HANDLE kinds (boxed by reference — DYN_HANDLE_KINDS). */
|
|
1019
|
-
export function canConvertToDyn(t, getRecord, getUnion) {
|
|
1019
|
+
export function canConvertToDyn(t, getRecord, getUnion, visiting = new Set()) {
|
|
1020
1020
|
if (isJsonSafeType(t, getRecord, getUnion))
|
|
1021
1021
|
return true;
|
|
1022
1022
|
// numeric typed arrays and boxable functions are dyn kinds the walker boxes
|
|
@@ -1024,14 +1024,14 @@ export function canConvertToDyn(t, getRecord, getUnion) {
|
|
|
1024
1024
|
// in records/arrays/unions. isJsonSafeType rejects them, but dynFrom
|
|
1025
1025
|
// needs only that the walker can build the dyn value, so this composite
|
|
1026
1026
|
// fold extends the JSON-safe core.
|
|
1027
|
-
if (canBoxDynComposite(t, getRecord, getUnion))
|
|
1027
|
+
if (canBoxDynComposite(t, getRecord, getUnion, visiting))
|
|
1028
1028
|
return true;
|
|
1029
1029
|
if (t.kind === "bytes")
|
|
1030
1030
|
return true;
|
|
1031
|
-
//
|
|
1031
|
+
// Built-in errors convert as the checked-dynamic tree's error encoding ({%error, name, message,
|
|
1032
1032
|
// code?} — the caughtToDyn shape, scr_dyn_from_error): the dyn 'error'
|
|
1033
1033
|
// listener boundary (a mustCall-wrapped handler receiving the payload).
|
|
1034
|
-
if (t.kind === "object" && t.className
|
|
1034
|
+
if (t.kind === "object" && RUNTIME_ERROR_CLASSES.has(t.className))
|
|
1035
1035
|
return true;
|
|
1036
1036
|
if (isDynTypedRefType(t))
|
|
1037
1037
|
return true;
|
|
@@ -1040,7 +1040,7 @@ export function canConvertToDyn(t, getRecord, getUnion) {
|
|
|
1040
1040
|
if (t.kind === "classval")
|
|
1041
1041
|
return true;
|
|
1042
1042
|
if (t.kind === "func")
|
|
1043
|
-
return canBoxFuncIntoDyn(t, getRecord, getUnion);
|
|
1043
|
+
return canBoxFuncIntoDyn(t, getRecord, getUnion, visiting);
|
|
1044
1044
|
if (DYN_HANDLE_KINDS.has(t.kind))
|
|
1045
1045
|
return true;
|
|
1046
1046
|
// Promises box by REFERENCE (SCR_DYN_PROMISE): promise<dyn> carries its
|
|
@@ -1052,7 +1052,7 @@ export function canConvertToDyn(t, getRecord, getUnion) {
|
|
|
1052
1052
|
if (t.kind === "promise") {
|
|
1053
1053
|
return (t.inner.kind === "dyn" ||
|
|
1054
1054
|
t.inner.kind === "void" ||
|
|
1055
|
-
canConvertToDyn(t.inner, getRecord, getUnion));
|
|
1055
|
+
canConvertToDyn(t.inner, getRecord, getUnion, visiting));
|
|
1056
1056
|
}
|
|
1057
1057
|
if (t.kind === "union") {
|
|
1058
1058
|
const def = getUnion(t.unionId);
|
|
@@ -1062,18 +1062,29 @@ export function canConvertToDyn(t, getRecord, getUnion) {
|
|
|
1062
1062
|
// boundary exactly like a bare func dynFrom).
|
|
1063
1063
|
return !!def && def.arms.every((a) => a.kind === "undefinedT" || isJsonSafeType(a, getRecord, getUnion) ||
|
|
1064
1064
|
isDynTypedRefType(a) || a.kind === "classval" || DYN_HANDLE_KINDS.has(a.kind) ||
|
|
1065
|
-
(a.kind === "func" && canBoxFuncIntoDyn(a, getRecord, getUnion)) ||
|
|
1066
|
-
(a.kind === "promise" && canConvertToDyn(a, getRecord, getUnion)));
|
|
1065
|
+
(a.kind === "func" && canBoxFuncIntoDyn(a, getRecord, getUnion, visiting)) ||
|
|
1066
|
+
(a.kind === "promise" && canConvertToDyn(a, getRecord, getUnion, visiting)));
|
|
1067
1067
|
}
|
|
1068
1068
|
return false;
|
|
1069
1069
|
}
|
|
1070
1070
|
/** The composite extension of the dynFrom domain: JSON-safe scalars plus
|
|
1071
1071
|
* numeric typed arrays and boxable functions anywhere, recursing through records
|
|
1072
1072
|
* (fields + index value), arrays, and unit-armed unions — exactly the
|
|
1073
|
-
* sc_td_* walker's capability.
|
|
1074
|
-
*
|
|
1075
|
-
*
|
|
1073
|
+
* sc_td_* walker's capability. Map and Set payloads must also support
|
|
1074
|
+
* checked extraction back into native storage. Other unsupported nested
|
|
1075
|
+
* kinds retain their conversion fence. */
|
|
1076
1076
|
function canBoxDynComposite(t, getRecord, getUnion, visiting = new Set()) {
|
|
1077
|
+
const key = `boxed:${typeKey(t)}`;
|
|
1078
|
+
if (visiting.has(key))
|
|
1079
|
+
return true;
|
|
1080
|
+
const result = canBoxDynCompositeAt(t, getRecord, getUnion, visiting);
|
|
1081
|
+
if (result)
|
|
1082
|
+
visiting.add(key);
|
|
1083
|
+
else
|
|
1084
|
+
clearDynConversionResults(visiting);
|
|
1085
|
+
return result;
|
|
1086
|
+
}
|
|
1087
|
+
function canBoxDynCompositeAt(t, getRecord, getUnion, visiting) {
|
|
1077
1088
|
switch (t.kind) {
|
|
1078
1089
|
case "f64":
|
|
1079
1090
|
case "bigint":
|
|
@@ -1088,15 +1099,17 @@ function canBoxDynComposite(t, getRecord, getUnion, visiting = new Set()) {
|
|
|
1088
1099
|
case "bytes":
|
|
1089
1100
|
case "regex":
|
|
1090
1101
|
case "url":
|
|
1102
|
+
case "searchParams":
|
|
1091
1103
|
return true;
|
|
1092
1104
|
case "func":
|
|
1093
|
-
return canBoxFuncIntoDyn(t, getRecord, getUnion);
|
|
1105
|
+
return canBoxFuncIntoDyn(t, getRecord, getUnion, visiting);
|
|
1094
1106
|
case "set":
|
|
1095
|
-
return t.elem.
|
|
1107
|
+
return canConvertToDyn(t.elem, getRecord, getUnion, visiting) && canDynCheckTo(t.elem, getRecord, getUnion, visiting);
|
|
1096
1108
|
case "map":
|
|
1097
|
-
return t.key
|
|
1109
|
+
return canConvertToDyn(t.key, getRecord, getUnion, visiting) && canDynCheckTo(t.key, getRecord, getUnion, visiting) &&
|
|
1110
|
+
canConvertToDyn(t.value, getRecord, getUnion, visiting) && canDynCheckTo(t.value, getRecord, getUnion, visiting);
|
|
1098
1111
|
case "object":
|
|
1099
|
-
return t.className
|
|
1112
|
+
return RUNTIME_ERROR_CLASSES.has(t.className) || isDynTypedRefType(t);
|
|
1100
1113
|
case "array":
|
|
1101
1114
|
return canBoxDynComposite(t.elem, getRecord, getUnion, visiting);
|
|
1102
1115
|
case "record": {
|
|
@@ -1109,11 +1122,16 @@ function canBoxDynComposite(t, getRecord, getUnion, visiting = new Set()) {
|
|
|
1109
1122
|
if (visiting.has(t.shapeId))
|
|
1110
1123
|
return true;
|
|
1111
1124
|
visiting.add(t.shapeId);
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1125
|
+
try {
|
|
1126
|
+
for (const field of shape.fields) {
|
|
1127
|
+
if (!canBoxDynComposite(field.type, getRecord, getUnion, visiting))
|
|
1128
|
+
return false;
|
|
1129
|
+
}
|
|
1130
|
+
return !shape.indexValue || canBoxDynComposite(shape.indexValue, getRecord, getUnion, visiting);
|
|
1131
|
+
}
|
|
1132
|
+
finally {
|
|
1133
|
+
visiting.delete(t.shapeId);
|
|
1115
1134
|
}
|
|
1116
|
-
return !shape.indexValue || canBoxDynComposite(shape.indexValue, getRecord, getUnion, visiting);
|
|
1117
1135
|
}
|
|
1118
1136
|
case "union": {
|
|
1119
1137
|
const def = getUnion(t.unionId);
|
|
@@ -1122,11 +1140,16 @@ function canBoxDynComposite(t, getRecord, getUnion, visiting = new Set()) {
|
|
|
1122
1140
|
if (visiting.has(t.unionId))
|
|
1123
1141
|
return true;
|
|
1124
1142
|
visiting.add(t.unionId);
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1143
|
+
try {
|
|
1144
|
+
for (const arm of def.arms) {
|
|
1145
|
+
if (!canBoxDynComposite(arm, getRecord, getUnion, visiting))
|
|
1146
|
+
return false;
|
|
1147
|
+
}
|
|
1148
|
+
return true;
|
|
1149
|
+
}
|
|
1150
|
+
finally {
|
|
1151
|
+
visiting.delete(t.unionId);
|
|
1128
1152
|
}
|
|
1129
|
-
return true;
|
|
1130
1153
|
}
|
|
1131
1154
|
default:
|
|
1132
1155
|
return false;
|
|
@@ -1137,7 +1160,27 @@ function canBoxDynComposite(t, getRecord, getUnion, visiting = new Set()) {
|
|
|
1137
1160
|
* undefined-armed unions of JSON-safe arms, adaptable function types,
|
|
1138
1161
|
* and the runtime HANDLE kinds (a tag-checked reference unwrap —
|
|
1139
1162
|
* DYN_HANDLE_KINDS). */
|
|
1140
|
-
export function canDynCheckTo(t, getRecord, getUnion) {
|
|
1163
|
+
export function canDynCheckTo(t, getRecord, getUnion, visiting = new Set()) {
|
|
1164
|
+
const key = `checked:${typeKey(t)}`;
|
|
1165
|
+
if (visiting.has(key))
|
|
1166
|
+
return true;
|
|
1167
|
+
const result = canDynCheckToAt(t, getRecord, getUnion, visiting);
|
|
1168
|
+
if (result)
|
|
1169
|
+
visiting.add(key);
|
|
1170
|
+
else
|
|
1171
|
+
clearDynConversionResults(visiting);
|
|
1172
|
+
return result;
|
|
1173
|
+
}
|
|
1174
|
+
/** Reuse completed subgraphs within one conversion query. A failed branch
|
|
1175
|
+
* invalidates successes that may depend on a coinductive back-edge to it;
|
|
1176
|
+
* active recursion keys remain until their owning calls unwind. */
|
|
1177
|
+
function clearDynConversionResults(visiting) {
|
|
1178
|
+
for (const key of visiting) {
|
|
1179
|
+
if (key.startsWith("boxed:") || key.startsWith("checked:"))
|
|
1180
|
+
visiting.delete(key);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1183
|
+
function canDynCheckToAt(t, getRecord, getUnion, visiting) {
|
|
1141
1184
|
// Unknown fields keep an owned dyn subtree; checking the surrounding
|
|
1142
1185
|
// record/array still validates its layout. This is broader than the
|
|
1143
1186
|
// stringify/island JSON domain, which cannot assume opaque slots are
|
|
@@ -1145,26 +1188,48 @@ export function canDynCheckTo(t, getRecord, getUnion) {
|
|
|
1145
1188
|
// unknown record fields with the undefined value.
|
|
1146
1189
|
if (isJsonSafeAt(t, getRecord, getUnion, false, false, new Set(), true))
|
|
1147
1190
|
return true;
|
|
1148
|
-
if (t.kind === "bigint" || t.kind === "symbol" || t.kind === "
|
|
1149
|
-
return true;
|
|
1150
|
-
if (t.kind === "map" && t.key.kind === "dyn" && t.value.kind === "dyn")
|
|
1191
|
+
if (t.kind === "bigint" || t.kind === "symbol" || t.kind === "date" || t.kind === "searchParams")
|
|
1151
1192
|
return true;
|
|
1193
|
+
if (t.kind === "map" || t.kind === "set")
|
|
1194
|
+
return canBoxDynComposite(t, getRecord, getUnion, visiting);
|
|
1152
1195
|
if (t.kind === "bytes")
|
|
1153
1196
|
return true;
|
|
1154
1197
|
if (t.kind === "classval")
|
|
1155
1198
|
return true;
|
|
1156
1199
|
if (t.kind === "generator")
|
|
1157
1200
|
return true;
|
|
1201
|
+
if (t.kind === "promise")
|
|
1202
|
+
return t.inner.kind === "dyn" || t.inner.kind === "void" || canDynCheckToAt(t.inner, getRecord, getUnion, visiting);
|
|
1158
1203
|
if (t.kind === "object" && t.className === "%Error")
|
|
1159
1204
|
return true;
|
|
1160
1205
|
// Native class capsules already support checked extraction at ordinary
|
|
1161
1206
|
// boundaries. Callable adapters use the same identity/brand check.
|
|
1162
1207
|
if (isDynTypedRefType(t))
|
|
1163
1208
|
return true;
|
|
1164
|
-
if (t.kind === "array"
|
|
1165
|
-
|
|
1209
|
+
if (t.kind === "array") {
|
|
1210
|
+
const key = typeKey(t);
|
|
1211
|
+
if (visiting.has(key))
|
|
1212
|
+
return false;
|
|
1213
|
+
visiting.add(key);
|
|
1214
|
+
const result = canDynCheckTo(t.elem, getRecord, getUnion, visiting);
|
|
1215
|
+
visiting.delete(key);
|
|
1216
|
+
return result;
|
|
1217
|
+
}
|
|
1218
|
+
if (t.kind === "record") {
|
|
1219
|
+
const key = typeKey(t);
|
|
1220
|
+
if (visiting.has(key))
|
|
1221
|
+
return false;
|
|
1222
|
+
const shape = getRecord(t.shapeId);
|
|
1223
|
+
if (!shape || shapeHasAccessorSlots(shape))
|
|
1224
|
+
return false;
|
|
1225
|
+
visiting.add(key);
|
|
1226
|
+
const result = shape.fields.every((field) => canDynCheckTo(field.type, getRecord, getUnion, visiting)) &&
|
|
1227
|
+
(!shape.indexValue || canDynCheckTo(shape.indexValue, getRecord, getUnion, visiting));
|
|
1228
|
+
visiting.delete(key);
|
|
1229
|
+
return result;
|
|
1230
|
+
}
|
|
1166
1231
|
if (t.kind === "func")
|
|
1167
|
-
return canAdaptDynFuncTo(t, getRecord, getUnion);
|
|
1232
|
+
return canAdaptDynFuncTo(t, getRecord, getUnion, visiting);
|
|
1168
1233
|
if (DYN_HANDLE_KINDS.has(t.kind))
|
|
1169
1234
|
return true;
|
|
1170
1235
|
if (t.kind === "union") {
|
|
@@ -1172,7 +1237,7 @@ export function canDynCheckTo(t, getRecord, getUnion) {
|
|
|
1172
1237
|
// Optional native callbacks and handles retain the same checked
|
|
1173
1238
|
// conversion as their bare value. The union matcher selects the arm
|
|
1174
1239
|
// before its adapter/extractor runs.
|
|
1175
|
-
return !!def && def.arms.every((a) => isUnitType(a) || (a.kind !== "union" && canDynCheckTo(a, getRecord, getUnion)));
|
|
1240
|
+
return !!def && def.arms.every((a) => isUnitType(a) || (a.kind !== "union" && canDynCheckTo(a, getRecord, getUnion, visiting)));
|
|
1176
1241
|
}
|
|
1177
1242
|
return false;
|
|
1178
1243
|
}
|
|
@@ -1180,7 +1245,7 @@ export function canDynCheckTo(t, getRecord, getUnion) {
|
|
|
1180
1245
|
* every param dyn or dynCheckable (the thunk validates dyn arguments into
|
|
1181
1246
|
* them), return void, dyn, or dyn-convertible (the thunk converts it
|
|
1182
1247
|
* back). */
|
|
1183
|
-
export function canBoxFuncIntoDyn(t, getRecord, getUnion) {
|
|
1248
|
+
export function canBoxFuncIntoDyn(t, getRecord, getUnion, visiting = new Set()) {
|
|
1184
1249
|
return (t.kind === "func" &&
|
|
1185
1250
|
// Typed rest occupies the final native array parameter; its thunk
|
|
1186
1251
|
// checks a fresh array containing all remaining call arguments.
|
|
@@ -1191,23 +1256,23 @@ export function canBoxFuncIntoDyn(t, getRecord, getUnion) {
|
|
|
1191
1256
|
// thunk (wrapped cells unwrap by reference, dyn data deep-copies) —
|
|
1192
1257
|
// the checker-'any' callback params of the routed-dispatch lane
|
|
1193
1258
|
// (`bag.list.map((x) => ...)` with x typed any).
|
|
1194
|
-
t.params.every((p) => p.kind === "dyn" || p.kind === "jsval" || canDynCheckTo(p, getRecord, getUnion)) &&
|
|
1259
|
+
t.params.every((p) => p.kind === "dyn" || p.kind === "jsval" || canDynCheckTo(p, getRecord, getUnion, visiting)) &&
|
|
1195
1260
|
// A jsval return converts through the by-reference wrap
|
|
1196
1261
|
// (dynFromJsval — the thunk's result conversion), so engine-returning
|
|
1197
1262
|
// callbacks box too: the routed-dispatch lane's flatMap shape.
|
|
1198
|
-
(t.ret.kind === "void" || t.ret.kind === "dyn" || t.ret.kind === "jsval" || canConvertToDyn(t.ret, getRecord, getUnion)));
|
|
1263
|
+
(t.ret.kind === "void" || t.ret.kind === "dyn" || t.ret.kind === "jsval" || canConvertToDyn(t.ret, getRecord, getUnion, visiting)));
|
|
1199
1264
|
}
|
|
1200
1265
|
/** A closure type a dyn function value can ADAPT to (dynCheck): every
|
|
1201
1266
|
* param dyn or dyn-convertible (the adapter converts typed arguments into
|
|
1202
1267
|
* dyn), return void, dyn, or dynCheckable (the adapter validates the dyn
|
|
1203
1268
|
* result). */
|
|
1204
|
-
export function canAdaptDynFuncTo(t, getRecord, getUnion) {
|
|
1269
|
+
export function canAdaptDynFuncTo(t, getRecord, getUnion, visiting = new Set()) {
|
|
1205
1270
|
return (t.kind === "func" &&
|
|
1206
1271
|
// Checked rest and arguments packs retain all actual arguments. Typed
|
|
1207
1272
|
// and island rest ABIs still require their own conversion plan.
|
|
1208
1273
|
(t.rest !== true || t.restAbi === undefined) &&
|
|
1209
|
-
t.params.every((p) => p.kind === "dyn" || canConvertToDyn(p, getRecord, getUnion)) &&
|
|
1210
|
-
(t.ret.kind === "void" || t.ret.kind === "dyn" || canDynCheckTo(t.ret, getRecord, getUnion)));
|
|
1274
|
+
t.params.every((p) => p.kind === "dyn" || canConvertToDyn(p, getRecord, getUnion, visiting)) &&
|
|
1275
|
+
(t.ret.kind === "void" || t.ret.kind === "dyn" || canDynCheckTo(t.ret, getRecord, getUnion, visiting)));
|
|
1211
1276
|
}
|
|
1212
1277
|
/** The MARSHAL-direction boundary (jsMarshal): everything that can cross
|
|
1213
1278
|
* out and back (canCrossIslandBoundary) plus qualifying closures — those
|
|
@@ -1267,7 +1332,8 @@ export function canExitIslandToType(t, getRecord, getUnion) {
|
|
|
1267
1332
|
return false;
|
|
1268
1333
|
}
|
|
1269
1334
|
const DYN_ASYNC_LIB_FNS = new Set([
|
|
1270
|
-
"
|
|
1335
|
+
"fs.callbackValue", "fs.callbackCall",
|
|
1336
|
+
"async.awaitDyn", "timers.immediatePromise", "crypto.native",
|
|
1271
1337
|
"process.onUncaughtException", "process.offUncaughtException",
|
|
1272
1338
|
"process.onUnhandledRejection", "process.offUnhandledRejection",
|
|
1273
1339
|
"process.onRejectionHandled", "process.offRejectionHandled",
|
|
@@ -1287,7 +1353,9 @@ function scanRuntimeFeatures(mod, stopAt) {
|
|
|
1287
1353
|
processEvents: false, emitter: (mod.classes ?? []).some((c) => c.name === RUNTIME_EMITTER_CLASS),
|
|
1288
1354
|
stream: (mod.classes ?? []).some((c) => RUNTIME_STREAM_CLASSES.has(c.name)),
|
|
1289
1355
|
zlib: mod.embedded?.edges.some((e) => e.to === "node:zlib") ?? false,
|
|
1290
|
-
dc: false, assert: false, dynInvoke: false,
|
|
1356
|
+
dc: false, assert: false, dynInvoke: false,
|
|
1357
|
+
dynAsync: mod.functions.some((fn) => fn.async === true && fn.generator === undefined && fn.returnType.kind === "dyn"),
|
|
1358
|
+
inspect: false,
|
|
1291
1359
|
childProcess: false, net: false, symbol: false, bigint: false, searchParams: false,
|
|
1292
1360
|
qs: false, parseArgs: false, fsWatch: false, nodeTest: false, dgram: false,
|
|
1293
1361
|
http: false, http2: false, tls: false, tlsCa: false,
|
|
@@ -1298,7 +1366,7 @@ function scanRuntimeFeatures(mod, stopAt) {
|
|
|
1298
1366
|
const fn = node.fn;
|
|
1299
1367
|
if (fn === "regexp.escape" || fn === "dyn.nativeRegexIs")
|
|
1300
1368
|
features.regex = true;
|
|
1301
|
-
if (fn === "text.decodeLegacy")
|
|
1369
|
+
if (fn === "text.decodeLegacy" || fn === "text.decodeLegacyOptions" || fn === "text.decodeStream")
|
|
1302
1370
|
features.legacyTextDecoder = true;
|
|
1303
1371
|
if (fn.startsWith("fetch."))
|
|
1304
1372
|
features.fetch = true;
|
|
@@ -1317,7 +1385,7 @@ function scanRuntimeFeatures(mod, stopAt) {
|
|
|
1317
1385
|
features.dc = true;
|
|
1318
1386
|
if (fn.startsWith("assert."))
|
|
1319
1387
|
features.assert = true;
|
|
1320
|
-
if (fn === "dyn.defineProps" || fn === "dyn.defineProperty" || fn === "dyn.objCreateWithProperties" || fn === "dyn.arrayProtoCall" || fn === "dyn.arrayPrototype")
|
|
1388
|
+
if (fn === "dyn.defineProps" || fn === "dyn.defineProperty" || fn === "dyn.objCreateWithProperties" || fn === "dyn.arrayProtoCall" || fn === "dyn.arrayPrototype" || fn === "dyn.functionApply" || fn === "dyn.builtinMethod")
|
|
1321
1389
|
features.dynInvoke = true;
|
|
1322
1390
|
if (DYN_ASYNC_LIB_FNS.has(fn))
|
|
1323
1391
|
features.dynAsync = true;
|
|
@@ -1749,6 +1817,7 @@ const LIB_MODE_REFUSED_PREFIXES = [
|
|
|
1749
1817
|
// exclude — refuse the surface like the rest of the event-loop family.
|
|
1750
1818
|
["fs.existsChk", "the async fs callback surface (fs.exists)"],
|
|
1751
1819
|
["fs.renameCb", "the async fs callback surface (fs.rename)"],
|
|
1820
|
+
["fs.callback", "the async filesystem callback surface"],
|
|
1752
1821
|
["zlib.deflateCb", "the async node:zlib callback surface"],
|
|
1753
1822
|
["zlib.inflateCb", "the async node:zlib callback surface"],
|
|
1754
1823
|
["zlib.deflateRawCb", "the async node:zlib callback surface"],
|
|
@@ -1968,6 +2037,14 @@ export function moduleLibNondeterministicSurface(mod) {
|
|
|
1968
2037
|
* seed on `dynCheck` and `awaitExpr` nodes, which throw on validation
|
|
1969
2038
|
* failure / promise rejection). */
|
|
1970
2039
|
export const MAY_THROW_LIB_FNS = new Set([
|
|
2040
|
+
"cp.spawnDynamic",
|
|
2041
|
+
"child.onDyn",
|
|
2042
|
+
"text.decoderEncoding",
|
|
2043
|
+
"dyn.construct",
|
|
2044
|
+
"dyn.reflectApply",
|
|
2045
|
+
"text.decodeOptions",
|
|
2046
|
+
"text.decodeStream",
|
|
2047
|
+
"text.decodeLegacyOptions",
|
|
1971
2048
|
"dyn.nativeSetNew",
|
|
1972
2049
|
"ffi.argument",
|
|
1973
2050
|
"ffi.memoryModule",
|
|
@@ -1979,6 +2056,10 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
1979
2056
|
"weakMap.new",
|
|
1980
2057
|
"weakSet.new",
|
|
1981
2058
|
"dyn.fromEntries",
|
|
2059
|
+
"bytes.constructor",
|
|
2060
|
+
"bytes.instanceOf",
|
|
2061
|
+
"buffer.byteLenDyn",
|
|
2062
|
+
"bytes.construct",
|
|
1982
2063
|
"arrayBuffer.new",
|
|
1983
2064
|
"arrayBuffer.byteLengthGetter",
|
|
1984
2065
|
"arrayBuffer.viewU8C",
|
|
@@ -1991,6 +2072,8 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
1991
2072
|
"arrayBuffer.viewF32",
|
|
1992
2073
|
"arrayBuffer.viewF64",
|
|
1993
2074
|
"arrayBuffer.viewDV",
|
|
2075
|
+
"bytes.bufferSource",
|
|
2076
|
+
"text.decodeBufferSource",
|
|
1994
2077
|
"bigint.parse",
|
|
1995
2078
|
"bigint.fromF64",
|
|
1996
2079
|
"bigint.div",
|
|
@@ -2005,12 +2088,15 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2005
2088
|
"bigint.bufferWrite",
|
|
2006
2089
|
"bigint.dataViewGet",
|
|
2007
2090
|
"bigint.dataViewSet",
|
|
2091
|
+
"fetch.requestNew",
|
|
2092
|
+
"fetch.headersNew",
|
|
2008
2093
|
"fetch.responseNew",
|
|
2009
2094
|
"fetch.abortTimeout",
|
|
2010
2095
|
"fetch.abortAny",
|
|
2011
2096
|
"fetch.streamNew",
|
|
2012
2097
|
"fetch.streamFrom",
|
|
2013
2098
|
"num.toFixed",
|
|
2099
|
+
"num.toStringRadix",
|
|
2014
2100
|
"insp.jsonDyn",
|
|
2015
2101
|
// diagnostics_channel: publish runs subscribers synchronously (a throw
|
|
2016
2102
|
// propagates — the documented divergence from triggerUncaughtException);
|
|
@@ -2170,6 +2256,8 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2170
2256
|
"readable.unshift",
|
|
2171
2257
|
"readable.unshiftStr",
|
|
2172
2258
|
"readable.read",
|
|
2259
|
+
"readable.readDyn",
|
|
2260
|
+
"stream.onDyn",
|
|
2173
2261
|
"readable.resume",
|
|
2174
2262
|
"readable.pipe",
|
|
2175
2263
|
"readable.unpipe",
|
|
@@ -2217,18 +2305,23 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2217
2305
|
// Error messages use the same coercion protocol before installing cause.
|
|
2218
2306
|
"error.newOptions",
|
|
2219
2307
|
"error.ctorOptions",
|
|
2308
|
+
"error.toString",
|
|
2309
|
+
"error.stack",
|
|
2220
2310
|
"error.cause",
|
|
2221
2311
|
"error.setCause",
|
|
2222
2312
|
"error.deleteCause",
|
|
2223
2313
|
"dyn.objectTag",
|
|
2224
2314
|
// Numeric coercion runs user valueOf/toString — throws propagate.
|
|
2225
2315
|
"dyn.numberConstructor",
|
|
2316
|
+
"dyn.bigintConstructor",
|
|
2226
2317
|
"dyn.toNumberCoerce",
|
|
2227
2318
|
"dyn.add",
|
|
2228
2319
|
"dyn.arithmetic",
|
|
2320
|
+
"dyn.compare",
|
|
2229
2321
|
"dyn.bitwise",
|
|
2230
2322
|
"dyn.proxyNew",
|
|
2231
2323
|
"dyn.classBasePrototype",
|
|
2324
|
+
"dyn.classInherit",
|
|
2232
2325
|
"dyn.classSuper",
|
|
2233
2326
|
"dyn.hasKey",
|
|
2234
2327
|
"child.kill",
|
|
@@ -2274,6 +2367,7 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2274
2367
|
// decodeURIComponent throws the spec's URIError on bad hex/invalid
|
|
2275
2368
|
// UTF-8 octets (encodeURIComponent never throws — see the IrLibFn doc).
|
|
2276
2369
|
"str.decodeUriComponent",
|
|
2370
|
+
"str.decodeUri",
|
|
2277
2371
|
// The base64 globals: atob/btoa throw the catchable DOMException
|
|
2278
2372
|
// InvalidCharacterError on malformed input; the zero-argument form
|
|
2279
2373
|
// always throws Node's TypeError [ERR_MISSING_ARGS].
|
|
@@ -2298,6 +2392,7 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2298
2392
|
"dyn.propertyIsEnumerable",
|
|
2299
2393
|
"dyn.assign",
|
|
2300
2394
|
"dyn.copyDataProperties",
|
|
2395
|
+
"dyn.objectRest",
|
|
2301
2396
|
// variadic Object.assign: spread flattening throws V8's spread-call
|
|
2302
2397
|
// TypeErrors; the final copy throws ToObject on a nullish target
|
|
2303
2398
|
"dyn.packPushSpread",
|
|
@@ -2308,6 +2403,7 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2308
2403
|
"dyn.getPrototype",
|
|
2309
2404
|
"dyn.setPrototype",
|
|
2310
2405
|
"dyn.getOwnPropertyNames",
|
|
2406
|
+
"dyn.ownKeys",
|
|
2311
2407
|
"dyn.getOwnPropertySymbols",
|
|
2312
2408
|
"dyn.getOwnPropertyDescriptors",
|
|
2313
2409
|
"dyn.preventExtensions",
|
|
@@ -2320,12 +2416,15 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2320
2416
|
// new RegExp compiles the pattern eagerly: an invalid pattern or flag
|
|
2321
2417
|
// throws Node's catchable SyntaxError at construction.
|
|
2322
2418
|
"regex.new",
|
|
2419
|
+
"regex.resetLastIndex",
|
|
2323
2420
|
"regex.newChecked",
|
|
2324
2421
|
"dyn.keySet",
|
|
2325
2422
|
"dyn.keySetComputed",
|
|
2326
2423
|
"process.builtinId",
|
|
2327
2424
|
"process.builtinModule",
|
|
2328
2425
|
"process.builtinUnsupported",
|
|
2426
|
+
"fs.callbackValue",
|
|
2427
|
+
"fs.callbackCall",
|
|
2329
2428
|
"dyn.keyDelete",
|
|
2330
2429
|
"dyn.keyDeleteComputed",
|
|
2331
2430
|
"dyn.hasKeyComputed",
|
|
@@ -2372,6 +2471,7 @@ export const MAY_THROW_LIB_FNS = new Set([
|
|
|
2372
2471
|
// on a row that is not a [name, value] pair. The rest of the sp family
|
|
2373
2472
|
// never throws.
|
|
2374
2473
|
"sp.fromPairs",
|
|
2474
|
+
"sp.newChecked",
|
|
2375
2475
|
"fs.statSync",
|
|
2376
2476
|
"crypto.randomBytesToString",
|
|
2377
2477
|
"crypto.randomBytes",
|