@scriptc/compiler 0.1.3 → 0.1.5
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 +275 -62
- package/dist/backend/c/async.d.ts +25 -0
- package/dist/backend/c/async.js +167 -0
- package/dist/backend/c/async.js.map +1 -1
- package/dist/backend/c/c-emitter.d.ts +15 -1
- package/dist/backend/c/c-emitter.js +36 -11
- package/dist/backend/c/c-emitter.js.map +1 -1
- package/dist/backend/c/exprs.d.ts +2 -2
- package/dist/backend/c/exprs.js +556 -71
- package/dist/backend/c/exprs.js.map +1 -1
- package/dist/backend/c/stmts.js +5 -3
- package/dist/backend/c/stmts.js.map +1 -1
- package/dist/backend/c/types.d.ts +2 -3
- package/dist/backend/c/types.js +10 -1
- package/dist/backend/c/types.js.map +1 -1
- package/dist/backend/c/walkers.js +1 -1
- package/dist/backend/c/walkers.js.map +1 -1
- package/dist/backend/link-plan.d.ts +3 -1
- package/dist/backend/link-plan.js +3 -1
- package/dist/backend/link-plan.js.map +1 -1
- package/dist/backend/llvm/dyn.js +1 -1
- package/dist/backend/llvm/dyn.js.map +1 -1
- package/dist/backend/llvm/emitter.js +42 -12
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/expr-bytes.d.ts +1 -2
- package/dist/backend/llvm/expr-bytes.js +28 -23
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-callbacks.d.ts +9 -0
- package/dist/backend/llvm/expr-callbacks.js +125 -0
- package/dist/backend/llvm/expr-callbacks.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -0
- package/dist/backend/llvm/expr-containers.js +32 -4
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +19 -3
- package/dist/backend/llvm/expr-dispatch.js +1 -0
- package/dist/backend/llvm/expr-dispatch.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.d.ts +1 -1
- package/dist/backend/llvm/expr-primitives.js +49 -13
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/expr-primitives.test.d.ts +1 -0
- package/dist/backend/llvm/expr-primitives.test.js +38 -0
- package/dist/backend/llvm/expr-primitives.test.js.map +1 -0
- package/dist/backend/llvm/expr-stream-callbacks.d.ts +3 -0
- package/dist/backend/llvm/expr-stream-callbacks.js +69 -0
- package/dist/backend/llvm/expr-stream-callbacks.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +80 -10
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +69 -10
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +156 -6
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +100 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/llvm/lib-stream.js +23 -0
- package/dist/backend/llvm/lib-stream.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +5 -0
- package/dist/backend/native-toolchain.js +4 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/runtime-pack.test.js +28 -10
- package/dist/backend/runtime-pack.test.js.map +1 -1
- package/dist/backend/targets.d.ts +7 -0
- package/dist/backend/targets.js +26 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/backend/targets.test.js +8 -1
- package/dist/backend/targets.test.js.map +1 -1
- package/dist/coverage/surface-manifest.js +14 -4
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.js +1 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +4 -0
- package/dist/executable/executable-cache.js +6 -1
- package/dist/executable/executable-cache.js.map +1 -1
- package/dist/executable/executable-cache.test.js +3 -3
- package/dist/executable/executable-cache.test.js.map +1 -1
- package/dist/frontend/fork-target.d.ts +17 -0
- package/dist/frontend/fork-target.js +256 -0
- package/dist/frontend/fork-target.js.map +1 -0
- package/dist/frontend/lowering/abstract-equality.d.ts +6 -0
- package/dist/frontend/lowering/abstract-equality.js +250 -0
- package/dist/frontend/lowering/abstract-equality.js.map +1 -0
- package/dist/frontend/lowering/containers/bytes.d.ts +1 -1
- package/dist/frontend/lowering/containers/bytes.js +6 -5
- package/dist/frontend/lowering/containers/bytes.js.map +1 -1
- package/dist/frontend/lowering/containers/string-and-regexp.d.ts +7 -6
- package/dist/frontend/lowering/containers/string-and-regexp.js +237 -28
- package/dist/frontend/lowering/containers/string-and-regexp.js.map +1 -1
- package/dist/frontend/lowering/expressions/object-literals.js +8 -0
- package/dist/frontend/lowering/expressions/object-literals.js.map +1 -1
- package/dist/frontend/lowering/lower-assert.js +71 -2
- package/dist/frontend/lowering/lower-assert.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +54 -28
- package/dist/frontend/lowering/lower-builtins.js +957 -116
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +32 -23
- package/dist/frontend/lowering/lower-calls.js +835 -206
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +41 -10
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +7 -9
- package/dist/frontend/lowering/lower-containers.js +293 -51
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-event-emitter.js +212 -21
- package/dist/frontend/lowering/lower-event-emitter.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +12 -0
- package/dist/frontend/lowering/lower-exprs.js +263 -93
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.d.ts +4 -0
- package/dist/frontend/lowering/lower-inspect.js +1 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +6 -3
- package/dist/frontend/lowering/lower-island.js +182 -12
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.d.ts +6 -0
- package/dist/frontend/lowering/lower-modules.js +184 -38
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-namespaces.js +7 -0
- package/dist/frontend/lowering/lower-namespaces.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +3 -5
- package/dist/frontend/lowering/lower-server.js +413 -54
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +122 -19
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lower-stream.d.ts +3 -0
- package/dist/frontend/lowering/lower-stream.js +7 -0
- package/dist/frontend/lowering/lower-stream.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +86 -9
- package/dist/frontend/lowering/lowerer.js +449 -74
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/optional-arguments.d.ts +9 -1
- package/dist/frontend/lowering/optional-arguments.js +67 -1
- package/dist/frontend/lowering/optional-arguments.js.map +1 -1
- package/dist/frontend/lowering/pairs-snapshot.d.ts +3 -1
- package/dist/frontend/lowering/pairs-snapshot.js +12 -4
- package/dist/frontend/lowering/pairs-snapshot.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +34 -14
- package/dist/frontend/lowering/surfaces.js +177 -104
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/npm-static-declarations.d.ts +4 -0
- package/dist/frontend/npm-static-declarations.js +56 -0
- package/dist/frontend/npm-static-declarations.js.map +1 -1
- package/dist/frontend/npm-static-declarations.test.js +23 -2
- package/dist/frontend/npm-static-declarations.test.js.map +1 -1
- package/dist/frontend/npm-static-prune.d.ts +6 -0
- package/dist/frontend/npm-static-prune.js +203 -0
- package/dist/frontend/npm-static-prune.js.map +1 -0
- package/dist/frontend/npm-static-prune.test.d.ts +1 -0
- package/dist/frontend/npm-static-prune.test.js +48 -0
- package/dist/frontend/npm-static-prune.test.js.map +1 -0
- package/dist/frontend/npm-static.js +6 -5
- package/dist/frontend/npm-static.js.map +1 -1
- package/dist/frontend/npm.d.ts +15 -3
- package/dist/frontend/npm.js +87 -14
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/npm.test.js +76 -9
- package/dist/frontend/npm.test.js.map +1 -1
- package/dist/frontend/program.js +107 -14
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/provenance.js +8 -3
- package/dist/frontend/provenance.js.map +1 -1
- package/dist/frontend/resolve.d.ts +6 -0
- package/dist/frontend/resolve.js +7 -4
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/type-mapper.d.ts +5 -0
- package/dist/frontend/type-mapper.js +80 -29
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +8 -3
- package/dist/index.js +34 -41
- package/dist/index.js.map +1 -1
- package/dist/ir/analysis.d.ts +5 -3
- package/dist/ir/analysis.js +25 -11
- package/dist/ir/analysis.js.map +1 -1
- package/dist/ir/analysis.test.js +50 -2
- package/dist/ir/analysis.test.js.map +1 -1
- package/dist/ir/constant-tables.d.ts +17 -0
- package/dist/ir/constant-tables.js +99 -0
- package/dist/ir/constant-tables.js.map +1 -0
- package/dist/ir/constant-tables.test.d.ts +1 -0
- package/dist/ir/constant-tables.test.js +78 -0
- package/dist/ir/constant-tables.test.js.map +1 -0
- package/dist/ir/integer-ranges.d.ts +13 -0
- package/dist/ir/integer-ranges.js +122 -0
- package/dist/ir/integer-ranges.js.map +1 -0
- package/dist/ir/integer-ranges.test.d.ts +1 -0
- package/dist/ir/integer-ranges.test.js +63 -0
- package/dist/ir/integer-ranges.test.js.map +1 -0
- package/dist/ir/ir.d.ts +130 -76
- package/dist/ir/ir.js +69 -4
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +20 -1
- package/dist/ir/ir.test.js.map +1 -1
- package/dist/ir/scalar-records.d.ts +8 -0
- package/dist/ir/scalar-records.js +216 -0
- package/dist/ir/scalar-records.js.map +1 -0
- package/dist/ir/scalar-records.test.d.ts +1 -0
- package/dist/ir/scalar-records.test.js +142 -0
- package/dist/ir/scalar-records.test.js.map +1 -0
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/serialize.js.map +1 -1
- package/dist/ir/validate.js +256 -20
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.d.ts +1 -0
- package/dist/ir/validate.test.js +31 -0
- package/dist/ir/validate.test.js.map +1 -0
- package/dist/library/cache-primitives.d.ts +1 -1
- package/dist/library/cache-primitives.js +3 -3
- package/dist/library/cache-primitives.js.map +1 -1
- package/dist/library/fence-eval.js +11 -4
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.test.js +4 -4
- package/dist/library/int-infer.test.js.map +1 -1
- package/dist/library/library-cache.js +0 -1
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +8 -8
- package/dist/library/library-cache.test.js.map +1 -1
- package/package.json +17 -17
- package/surface-manifest.json +186 -79
package/dist/backend/c/exprs.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { InternalCompilerError } from "../../errors.js";
|
|
2
|
-
import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, CHILDWRITER_T, DYN, F64, islandPromisePayloadTag, isClassOwnEnumerableFieldName, isDynTypedRefType, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/ir.js";
|
|
2
|
+
import { arrayOf, BOOL, BYTES_U8, bytesOf, canMarshalFuncIntoIsland, CHILDSTREAM_T, CHILDWRITER_T, DYN, F64, islandPromisePayloadTag, isClassOwnEnumerableFieldName, isDynTypedRefType, isFfiCallbackParam, isFfiContextParam, isFfiReleaseParam, isRefCounted, isUnitType, MAY_THROW_LIB_FNS, NETSOCKET_T, RUNTIME_ERROR_CLASSES, STRING, typeEquals, typeKey } from "../../ir/ir.js";
|
|
3
3
|
import { boxAccess, BYTES_NUM_KIND_C, BYTES_NUM_VAR_C, bytesElemKindC, cDecl, cFnPtrCast, cNumberLiteral, cStringLiteral, cType, DV_GET_KIND_C, DV_SET_KIND_C, elemAccess, mapKeyAccess, mapKeyKindC, mapValKindC, releaseCallC, retainCallC, vAdapters } from "./types.js";
|
|
4
4
|
import { mangleClassNew, mangleClassRetain, mangleClassStruct, mangleField, mangleFnClosure, mangleFunction, mangleGlobal, mangleLocal, mangleRecordClone, mangleRecordNew, mangleRecordStruct, mangleVtStruct } from "../mangle.js";
|
|
5
5
|
import { OVERFLOW_MEMBER } from "./shapes.js";
|
|
6
6
|
import { dynDestrCheckHelper, dynIterNHelper, dynKeyGetHelper } from "./walkers.js";
|
|
7
7
|
import { collectFfiRetainedOps, parseFfiCallbackKey } from "../ffi-callbacks.js";
|
|
8
8
|
import { genResultThunkFor } from "./async.js";
|
|
9
|
-
import {
|
|
9
|
+
import { isStableReceiverOperand, matchStringSelfConcat, newValueMayThrow, streamTypedRefEligible, undefinedArmTag } from "../../ir/analysis.js";
|
|
10
10
|
function streamTypedRefCommitAdapter(emitter, t, snapshot, defs) {
|
|
11
11
|
if (t.kind === "bytes") {
|
|
12
12
|
const commit = `${snapshot}_commit`;
|
|
@@ -385,13 +385,13 @@ function dynPromiseAdapter(emitter, inner) {
|
|
|
385
385
|
emitter.walkerDefs.push(`${sig} { /* checked-dynamic promise exit ${key} */`, ` ScrDyn *sc_d = (ScrDyn *)scr_promise_payload_ref(sc_src);`, ` ${cDecl(inner, "sc_v")} = ${emitter.dynCheckHelper(inner)}(sc_d, NULL);`, ` scr_dyn_release(sc_d);`, ` if (scr_exc_pending()) {`, ` scr_promise_reject_pending(sc_dst);`, ` return;`, ` }`, ` ${fulfill}`, `}`, ``);
|
|
386
386
|
return sym;
|
|
387
387
|
}
|
|
388
|
-
/** Evaluate a
|
|
388
|
+
/** Evaluate a receiver as a borrow when it is a direct, unboxed
|
|
389
389
|
* binding and all later operands are stable. The binding's scope/global
|
|
390
390
|
* owner then keeps the value alive, avoiding retain/release traffic around
|
|
391
391
|
* every indexed access. Any uncertain shape falls back to an owned temp. */
|
|
392
|
-
export function
|
|
392
|
+
export function emitStableReceiver(emitter, receiver, following) {
|
|
393
393
|
if (receiver.kind === "varRef" &&
|
|
394
|
-
following.every((operand) =>
|
|
394
|
+
following.every((operand) => isStableReceiverOperand(operand, receiver.localId))) {
|
|
395
395
|
const local = emitter.currentLocals.get(receiver.localId);
|
|
396
396
|
if (local && !local.boxed) {
|
|
397
397
|
return emitter.newBorrowedTemp(receiver.type, mangleLocal(receiver.localId));
|
|
@@ -547,6 +547,10 @@ function emitLiteralExpr(emitter, e) {
|
|
|
547
547
|
const sym = emitter.internLiteral(e.value);
|
|
548
548
|
return emitter.newTemp(e.type, retainCallC(e.type, `(ScrStr *)&${sym}`));
|
|
549
549
|
}
|
|
550
|
+
case "moduleNsRef": {
|
|
551
|
+
const sym = emitter.internLiteral(`module:${e.moduleId}`);
|
|
552
|
+
return emitter.newTemp(e.type, retainCallC(e.type, `(ScrStr *)&${sym}`));
|
|
553
|
+
}
|
|
550
554
|
case "unitLit":
|
|
551
555
|
// unitLits are consumed inline by the unionWrap case (a unit arm is
|
|
552
556
|
// tag-only); one reaching the generic dispatch escaped its wrap.
|
|
@@ -600,11 +604,36 @@ function emitLiteralExpr(emitter, e) {
|
|
|
600
604
|
}
|
|
601
605
|
}
|
|
602
606
|
}
|
|
607
|
+
/** Unsigned operations avoid signed overflow and implementation-defined
|
|
608
|
+
* right shifts/conversions. Reinterpret the final bits numerically. */
|
|
609
|
+
function emitIntegerBits(emitter, e, left, right) {
|
|
610
|
+
const a = `sc_bits_${emitter.tempCounter++}`;
|
|
611
|
+
const out = `sc_bits_${emitter.tempCounter++}`;
|
|
612
|
+
emitter.line(`uint32_t ${a} = (uint32_t)(int64_t)${left};`);
|
|
613
|
+
let operation;
|
|
614
|
+
if (e.kind === "unary")
|
|
615
|
+
operation = `~${a}`;
|
|
616
|
+
else {
|
|
617
|
+
const b = `sc_bits_${emitter.tempCounter++}`;
|
|
618
|
+
const shift = e.op === "<<" || e.op === ">>" || e.op === ">>>";
|
|
619
|
+
emitter.line(`uint32_t ${b} = (uint32_t)(int64_t)${right}${shift ? " & 31u" : ""};`);
|
|
620
|
+
operation = e.op === ">>" ? `(${a} >> ${b}) | ((${a} & 0x80000000u) ? ~(UINT32_MAX >> ${b}) : 0u)`
|
|
621
|
+
: `${a} ${e.op === ">>>" ? ">>" : e.op} ${b}`;
|
|
622
|
+
}
|
|
623
|
+
emitter.line(`uint32_t ${out} = ${operation};`);
|
|
624
|
+
return emitter.newTemp(e.type, e.op === ">>>" ? `(double)${out}` : `(double)${out} - ((${out} & 0x80000000u) ? 4294967296.0 : 0.0)`);
|
|
625
|
+
}
|
|
603
626
|
function emitOperatorExpr(emitter, e) {
|
|
604
627
|
switch (e.kind) {
|
|
605
628
|
case "bin": {
|
|
606
629
|
const l = emitter.emitExpr(e.left);
|
|
607
630
|
const r = emitter.emitExpr(e.right);
|
|
631
|
+
if ((e.op === "+" || e.op === "-") && emitter.integerRanges.get(e)) {
|
|
632
|
+
return emitter.newTemp(e.type, `(double)((int64_t)${l.name} ${e.op} (int64_t)${r.name})`);
|
|
633
|
+
}
|
|
634
|
+
if (["&", "|", "^", "<<", ">>", ">>>"].includes(e.op) && emitter.integerRanges.get(e.left) && emitter.integerRanges.get(e.right)) {
|
|
635
|
+
return emitIntegerBits(emitter, e, l.name, r.name);
|
|
636
|
+
}
|
|
608
637
|
switch (e.op) {
|
|
609
638
|
case "%":
|
|
610
639
|
return emitter.newTemp(e.type, `fmod(${l.name}, ${r.name})`);
|
|
@@ -635,7 +664,8 @@ function emitOperatorExpr(emitter, e) {
|
|
|
635
664
|
case "unary": {
|
|
636
665
|
const v = emitter.emitExpr(e.operand);
|
|
637
666
|
if (e.op === "~")
|
|
638
|
-
return emitter.
|
|
667
|
+
return emitter.integerRanges.get(e.operand)
|
|
668
|
+
? emitIntegerBits(emitter, e, v.name) : emitter.newTemp(e.type, `scr_bit_not(${v.name})`);
|
|
639
669
|
return emitter.newTemp(e.type, `${e.op}${v.name}`);
|
|
640
670
|
}
|
|
641
671
|
case "incDec": {
|
|
@@ -1229,9 +1259,13 @@ function emitStringExpr(emitter, e) {
|
|
|
1229
1259
|
}
|
|
1230
1260
|
return emitter.newTemp(e.type, `scr_str_includes(${r.name}, ${args[0].name})`);
|
|
1231
1261
|
case "startsWith":
|
|
1232
|
-
return emitter.newTemp(e.type,
|
|
1262
|
+
return emitter.newTemp(e.type, args[1]
|
|
1263
|
+
? `scr_str_starts_with_from(${r.name}, ${args[0].name}, ${args[1].name})`
|
|
1264
|
+
: `scr_str_starts_with(${r.name}, ${args[0].name})`);
|
|
1233
1265
|
case "endsWith":
|
|
1234
|
-
return emitter.newTemp(e.type,
|
|
1266
|
+
return emitter.newTemp(e.type, args[1]
|
|
1267
|
+
? `scr_str_ends_with_from(${r.name}, ${args[0].name}, ${args[1].name})`
|
|
1268
|
+
: `scr_str_ends_with(${r.name}, ${args[0].name})`);
|
|
1235
1269
|
case "slice":
|
|
1236
1270
|
return emitter.newTemp(e.type, `scr_str_slice(${r.name}, ${args[0]?.name ?? "0"}, ${args[1]?.name ?? "INFINITY"})`);
|
|
1237
1271
|
case "substring":
|
|
@@ -1443,7 +1477,11 @@ function emitContainerExpr(emitter, e) {
|
|
|
1443
1477
|
return emitter.newTemp(e.type, `scr_arr_state(${arr.name}, ${idx.name})`);
|
|
1444
1478
|
}
|
|
1445
1479
|
case "arrIntrinsic": {
|
|
1446
|
-
|
|
1480
|
+
// getNumber copies out a scalar without invoking user code. A
|
|
1481
|
+
// stable binding can own its receiver until that lookup finishes.
|
|
1482
|
+
const r = e.method === "getNumber"
|
|
1483
|
+
? emitStableReceiver(emitter, e.receiver, e.args)
|
|
1484
|
+
: emitter.emitExpr(e.receiver);
|
|
1447
1485
|
if (e.receiver.type.kind !== "array")
|
|
1448
1486
|
throw new InternalCompilerError("emitter bug: arrIntrinsic on non-array");
|
|
1449
1487
|
const acc = elemAccess(e.receiver.type.elem);
|
|
@@ -1451,6 +1489,11 @@ function emitContainerExpr(emitter, e) {
|
|
|
1451
1489
|
switch (method) {
|
|
1452
1490
|
case "length":
|
|
1453
1491
|
return emitter.newTemp(e.type, `scr_arr_len(${r.name})`);
|
|
1492
|
+
case "getNumber": {
|
|
1493
|
+
const index = emitter.emitExpr(e.args[0]);
|
|
1494
|
+
const table = e.receiver.kind === "varRef" ? emitter.constantNumericTables.get(e.receiver.localId) : undefined;
|
|
1495
|
+
return emitter.newTemp(e.type, `${table ? `${table.symbol}_get` : "scr_arr_get_number"}(${r.name}, ${index.name})`);
|
|
1496
|
+
}
|
|
1454
1497
|
case "nextPresent": {
|
|
1455
1498
|
const start = emitter.emitExpr(e.args[0]);
|
|
1456
1499
|
return emitter.newTemp(e.type, `scr_arr_next_present(${r.name}, ${start.name})`);
|
|
@@ -1673,7 +1716,7 @@ function emitContainerExpr(emitter, e) {
|
|
|
1673
1716
|
const method = e.method;
|
|
1674
1717
|
const directElementAccess = method === "length" || method === "byteLength" || method === "get";
|
|
1675
1718
|
const r = directElementAccess
|
|
1676
|
-
?
|
|
1719
|
+
? emitStableReceiver(emitter, e.receiver, e.args)
|
|
1677
1720
|
: emitter.emitExpr(e.receiver);
|
|
1678
1721
|
const integerIndex = method === "get" ? emitter.integerLoopIndex(e.args[0]) : null;
|
|
1679
1722
|
const args = integerIndex === null ? e.args.map((a) => emitter.emitExpr(a)) : [];
|
|
@@ -1684,7 +1727,7 @@ function emitContainerExpr(emitter, e) {
|
|
|
1684
1727
|
if (e.receiver.type.kind !== "bytes") {
|
|
1685
1728
|
throw new InternalCompilerError("emitter bug: bytesIntrinsic byteLength on non-bytes");
|
|
1686
1729
|
}
|
|
1687
|
-
return emitter.newTemp(e.type, `(double)(${r.name}->len * ${e.receiver.type.elem === "u8" ? "1" : "4"})`);
|
|
1730
|
+
return emitter.newTemp(e.type, `(double)(${r.name}->len * ${e.receiver.type.elem === "u8" ? "1" : e.receiver.type.elem === "f64" ? "8" : "4"})`);
|
|
1688
1731
|
case "get":
|
|
1689
1732
|
// Any invalid index traps (the array runtime's discipline).
|
|
1690
1733
|
if (e.receiver.type.kind !== "bytes") {
|
|
@@ -4016,6 +4059,11 @@ function emitDynamicLibCall(state) {
|
|
|
4016
4059
|
// +1 string or NULL with the exception pending (user
|
|
4017
4060
|
// toString/valueOf throws propagate). Borrows the dyn.
|
|
4018
4061
|
return finish(`scr_dyn_string_coerce_js(${arg(0)})`);
|
|
4062
|
+
case "dyn.toNumberCoerce":
|
|
4063
|
+
// JS ToNumber (number-hint valueOf/toString protocol). A
|
|
4064
|
+
// thrown hook leaves the exception pending; the may-throw
|
|
4065
|
+
// epilogue abandons the NaN dummy.
|
|
4066
|
+
return finish(`scr_dyn_number_coerce(${arg(0)})`);
|
|
4019
4067
|
case "global.undefRead":
|
|
4020
4068
|
// A declare-d const nothing defines: Node's catchable
|
|
4021
4069
|
// ReferenceError at the access (always throws — the typed
|
|
@@ -4103,22 +4151,28 @@ function emitFilesystemLibCall(state) {
|
|
|
4103
4151
|
return finish(`scr_fs_rmdir(${arg(0)})`);
|
|
4104
4152
|
case "fs.readdirSync":
|
|
4105
4153
|
return finish(`scr_fs_readdir(${arg(0)})`);
|
|
4106
|
-
case "fs.readdirTypesSync":
|
|
4154
|
+
case "fs.readdirTypesSync":
|
|
4155
|
+
case "fsp.readdirTypes": {
|
|
4107
4156
|
// Dirent rows assembled inline from one scandir snapshot
|
|
4108
4157
|
// (scr_lib.c) — the os.networkInterfaces pattern, flat. The
|
|
4109
4158
|
// frontend/validator pinned the shape ({%dtype, name,
|
|
4110
|
-
// parentPath}); lookups here only guard emitter bugs. The
|
|
4111
|
-
//
|
|
4112
|
-
//
|
|
4113
|
-
//
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
const
|
|
4159
|
+
// parentPath}); lookups here only guard emitter bugs. The sync
|
|
4160
|
+
// form checks the snapshot's scandir error immediately. The
|
|
4161
|
+
// promise form lets NULL flow through the null-tolerant count/
|
|
4162
|
+
// free accessors, builds an empty dummy array, and moves it to
|
|
4163
|
+
// settled_ref: the pending exception becomes the rejection and
|
|
4164
|
+
// settled_ref releases that dummy.
|
|
4165
|
+
const promiseForm = e.fn === "fsp.readdirTypes";
|
|
4166
|
+
const arrayT = promiseForm && e.type.kind === "promise" ? e.type.inner : e.type;
|
|
4167
|
+
if (arrayT.kind !== "array" || arrayT.elem.kind !== "record") {
|
|
4168
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} result is not a Dirent record array`);
|
|
4169
|
+
}
|
|
4170
|
+
const recT = arrayT.elem;
|
|
4118
4171
|
const snap = `sc_t${emitter.tempCounter++}`;
|
|
4119
4172
|
emitter.line(`ScrScandir *${snap} = scr_fs_scandir(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
4120
|
-
|
|
4121
|
-
|
|
4173
|
+
if (!promiseForm)
|
|
4174
|
+
emitter.emitPendingCheck();
|
|
4175
|
+
const out = emitter.newTemp(arrayT, emitter.arrNewC(recT, `scr_fs_scandir_count(${snap})`));
|
|
4122
4176
|
const i = `sc_t${emitter.tempCounter++}`;
|
|
4123
4177
|
const n = `sc_t${emitter.tempCounter++}`;
|
|
4124
4178
|
emitter.line(`for (size_t ${i} = 0, ${n} = scr_fs_scandir_count(${snap}); ${i} < ${n}; ${i}++) {`);
|
|
@@ -4132,6 +4186,11 @@ function emitFilesystemLibCall(state) {
|
|
|
4132
4186
|
emitter.indent--;
|
|
4133
4187
|
emitter.line(`}`);
|
|
4134
4188
|
emitter.line(`scr_fs_scandir_free(${snap});`);
|
|
4189
|
+
if (promiseForm) {
|
|
4190
|
+
const rc = vAdapters(arrayT);
|
|
4191
|
+
emitter.moveTemp(out); // promise fulfillment owns the result array
|
|
4192
|
+
return finish(`scr_promise_settled_ref(${out.name}, &${rc.retain}, &${rc.release}, ${emitter.traceArgC(arrayT)})`);
|
|
4193
|
+
}
|
|
4135
4194
|
return out;
|
|
4136
4195
|
}
|
|
4137
4196
|
// Stats (scr_lib.c): statSync throws like the other sync fs
|
|
@@ -4140,6 +4199,16 @@ function emitFilesystemLibCall(state) {
|
|
|
4140
4199
|
// Throws Node-shaped fs errors (may-throw seed set); the fd
|
|
4141
4200
|
// comes back as f64.
|
|
4142
4201
|
return finish(`scr_fs_open(${arg(0)}, ${arg(1)})`);
|
|
4202
|
+
case "fs.openNumericSync":
|
|
4203
|
+
return finish(`scr_fs_open_numeric(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
4204
|
+
case "fs.fstatSync":
|
|
4205
|
+
return finish(`scr_fs_fstat(${arg(0)})`);
|
|
4206
|
+
case "fs.fchmodSync":
|
|
4207
|
+
return finish(`scr_fs_fchmod(${arg(0)}, ${arg(1)})`);
|
|
4208
|
+
case "fs.fsyncSync":
|
|
4209
|
+
return finish(`scr_fs_fsync(${arg(0)})`);
|
|
4210
|
+
case "fs.linkSync":
|
|
4211
|
+
return finish(`scr_fs_link(${arg(0)}, ${arg(1)})`);
|
|
4143
4212
|
case "fs.readSync":
|
|
4144
4213
|
return finish(`scr_fs_read_sync(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
|
|
4145
4214
|
case "fs.writeSync":
|
|
@@ -4182,12 +4251,18 @@ function emitFilesystemLibCall(state) {
|
|
|
4182
4251
|
return finish(`scr_stats_atime_ms(${arg(0)})`);
|
|
4183
4252
|
case "stats.mtimeMs":
|
|
4184
4253
|
return finish(`scr_stats_mtime_ms(${arg(0)})`);
|
|
4254
|
+
case "stats.ctimeMs":
|
|
4255
|
+
return finish(`scr_stats_ctime_ms(${arg(0)})`);
|
|
4185
4256
|
case "stats.isFile":
|
|
4186
4257
|
return finish(`scr_stats_is_file(${arg(0)})`);
|
|
4187
4258
|
case "stats.isDirectory":
|
|
4188
4259
|
return finish(`scr_stats_is_dir(${arg(0)})`);
|
|
4189
4260
|
case "stats.size":
|
|
4190
4261
|
return finish(`scr_stats_size(${arg(0)})`);
|
|
4262
|
+
case "stats.dev":
|
|
4263
|
+
return finish(`scr_stats_dev(${arg(0)})`);
|
|
4264
|
+
case "stats.ino":
|
|
4265
|
+
return finish(`scr_stats_ino(${arg(0)})`);
|
|
4191
4266
|
case "fs.toUnixTimestamp":
|
|
4192
4267
|
return finish(`scr_fs_to_unix_timestamp(${arg(0)})`);
|
|
4193
4268
|
// The fs argument-validation ladders: the always-throw Chk
|
|
@@ -4246,6 +4321,43 @@ function emitFilesystemLibCall(state) {
|
|
|
4246
4321
|
return finish(`scr_zlib_deflate(${arg(0)})`);
|
|
4247
4322
|
case "zlib.inflateSync":
|
|
4248
4323
|
return finish(`scr_zlib_inflate(${arg(0)})`);
|
|
4324
|
+
case "zlib.deflateRawSync":
|
|
4325
|
+
return finish(`scr_zlib_deflate_mode(${arg(0)}, 1.0, -1.0)`);
|
|
4326
|
+
case "zlib.inflateRawSync":
|
|
4327
|
+
return finish(`scr_zlib_inflate_mode(${arg(0)}, 1.0)`);
|
|
4328
|
+
case "zlib.gzipSync":
|
|
4329
|
+
return finish(`scr_zlib_deflate_mode(${arg(0)}, 2.0, -1.0)`);
|
|
4330
|
+
case "zlib.gunzipSync":
|
|
4331
|
+
return finish(`scr_zlib_inflate_mode(${arg(0)}, 2.0)`);
|
|
4332
|
+
case "zlib.unzipSync":
|
|
4333
|
+
return finish(`scr_zlib_inflate_mode(${arg(0)}, 3.0)`);
|
|
4334
|
+
case "zlib.crc32":
|
|
4335
|
+
return finish(`scr_zlib_crc32(${arg(0)}, ${arg(1)})`);
|
|
4336
|
+
case "zlib.deflateCb":
|
|
4337
|
+
case "zlib.inflateCb":
|
|
4338
|
+
case "zlib.deflateRawCb":
|
|
4339
|
+
case "zlib.inflateRawCb":
|
|
4340
|
+
case "zlib.gzipCb":
|
|
4341
|
+
case "zlib.gunzipCb":
|
|
4342
|
+
case "zlib.unzipCb": {
|
|
4343
|
+
emitter.usesTimers = true;
|
|
4344
|
+
const cbT = e.args[1].type;
|
|
4345
|
+
if (cbT.kind !== "func")
|
|
4346
|
+
throw new InternalCompilerError("emitter bug: zlib callback not a func");
|
|
4347
|
+
const callback = args[1];
|
|
4348
|
+
emitter.moveTemp(callback);
|
|
4349
|
+
const adapter = emitter.zlibBytesThunkFor(cbT);
|
|
4350
|
+
const compressing = fn === "zlib.deflateCb" || fn === "zlib.deflateRawCb" || fn === "zlib.gzipCb";
|
|
4351
|
+
const mode = fn === "zlib.deflateRawCb" || fn === "zlib.inflateRawCb"
|
|
4352
|
+
? 1
|
|
4353
|
+
: fn === "zlib.gzipCb" || fn === "zlib.gunzipCb"
|
|
4354
|
+
? 2
|
|
4355
|
+
: fn === "zlib.unzipCb"
|
|
4356
|
+
? 3
|
|
4357
|
+
: 0;
|
|
4358
|
+
emitter.line(`scr_zlib_codec_async(${arg(0)}, ${mode}.0, ${compressing ? "true" : "false"}, ${callback.name}, &${adapter});${emitter.srcComment(e.loc)}`);
|
|
4359
|
+
return { name: "", type: e.type };
|
|
4360
|
+
}
|
|
4249
4361
|
case "fsp.readFile":
|
|
4250
4362
|
return finish(`scr_fsp_read_file(${arg(0)})`);
|
|
4251
4363
|
case "fsp.writeFile":
|
|
@@ -4272,6 +4384,10 @@ function emitFilesystemLibCall(state) {
|
|
|
4272
4384
|
return finish(`scr_fsp_rm(${arg(0)})`);
|
|
4273
4385
|
case "fsp.stat":
|
|
4274
4386
|
return finish(`scr_fsp_stat(${arg(0)})`);
|
|
4387
|
+
case "fsp.realpath":
|
|
4388
|
+
return finish(`scr_fsp_realpath(${arg(0)})`);
|
|
4389
|
+
case "fsp.lstat":
|
|
4390
|
+
return finish(`scr_fsp_lstat(${arg(0)})`);
|
|
4275
4391
|
case "fsp.open":
|
|
4276
4392
|
return finish(`scr_fsp_open(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
4277
4393
|
case "fileHandle.fd":
|
|
@@ -4535,10 +4651,18 @@ function emitPathUrlLibCall(state) {
|
|
|
4535
4651
|
return finish(`scr_url_new(${arg(0)})`);
|
|
4536
4652
|
case "url.protocol":
|
|
4537
4653
|
return finish(`scr_url_protocol(${arg(0)})`);
|
|
4654
|
+
case "url.origin":
|
|
4655
|
+
return finish(`scr_url_origin(${arg(0)})`);
|
|
4656
|
+
case "url.username":
|
|
4657
|
+
return finish(`scr_url_username(${arg(0)})`);
|
|
4658
|
+
case "url.password":
|
|
4659
|
+
return finish(`scr_url_password(${arg(0)})`);
|
|
4538
4660
|
case "url.host":
|
|
4539
4661
|
return finish(`scr_url_host(${arg(0)})`);
|
|
4540
4662
|
case "url.hostname":
|
|
4541
4663
|
return finish(`scr_url_hostname(${arg(0)})`);
|
|
4664
|
+
case "url.port":
|
|
4665
|
+
return finish(`scr_url_port(${arg(0)})`);
|
|
4542
4666
|
case "url.pathname":
|
|
4543
4667
|
return finish(`scr_url_pathname(${arg(0)})`);
|
|
4544
4668
|
case "url.href":
|
|
@@ -4572,6 +4696,8 @@ function emitPathUrlLibCall(state) {
|
|
|
4572
4696
|
return finish(`scr_url_search_params(${arg(0)})`);
|
|
4573
4697
|
case "url.search":
|
|
4574
4698
|
return finish(`scr_url_search(${arg(0)})`);
|
|
4699
|
+
case "url.hash":
|
|
4700
|
+
return finish(`scr_url_hash(${arg(0)})`);
|
|
4575
4701
|
case "sp.get": {
|
|
4576
4702
|
// `string | null` — the sym.desc pattern with a null arm: the
|
|
4577
4703
|
// runtime answers a +1 string or NULL.
|
|
@@ -4677,6 +4803,8 @@ function emitPrimitiveLibCall(state) {
|
|
|
4677
4803
|
return finish(`scr_math_max_arr(${arg(0)})`);
|
|
4678
4804
|
case "math.minArr":
|
|
4679
4805
|
return finish(`scr_math_min_arr(${arg(0)})`);
|
|
4806
|
+
case "math.hypotArr":
|
|
4807
|
+
return finish(`scr_math_hypot_arr(${arg(0)})`);
|
|
4680
4808
|
// Math.floor/trunc/ceil — the C functions ARE the JS operations
|
|
4681
4809
|
// (math.h is always included). Borrow nothing; no throw.
|
|
4682
4810
|
case "math.floor":
|
|
@@ -4685,6 +4813,38 @@ function emitPrimitiveLibCall(state) {
|
|
|
4685
4813
|
return finish(`trunc(${arg(0)})`);
|
|
4686
4814
|
case "math.ceil":
|
|
4687
4815
|
return finish(`ceil(${arg(0)})`);
|
|
4816
|
+
case "math.sin":
|
|
4817
|
+
return finish(`sin(${arg(0)})`);
|
|
4818
|
+
case "math.cos":
|
|
4819
|
+
return finish(`cos(${arg(0)})`);
|
|
4820
|
+
case "math.tan":
|
|
4821
|
+
return finish(`tan(${arg(0)})`);
|
|
4822
|
+
case "math.asin":
|
|
4823
|
+
return finish(`asin(${arg(0)})`);
|
|
4824
|
+
case "math.acos":
|
|
4825
|
+
return finish(`acos(${arg(0)})`);
|
|
4826
|
+
case "math.atan":
|
|
4827
|
+
return finish(`atan(${arg(0)})`);
|
|
4828
|
+
case "math.cbrt":
|
|
4829
|
+
return finish(`cbrt(${arg(0)})`);
|
|
4830
|
+
case "math.sign":
|
|
4831
|
+
// Each argument was evaluated into a temp. Returning that temp
|
|
4832
|
+
// for unordered/zero inputs preserves NaN and the sign of zero.
|
|
4833
|
+
return finish(`(${arg(0)} > 0.0 ? 1.0 : (${arg(0)} < 0.0 ? -1.0 : ${arg(0)}))`);
|
|
4834
|
+
case "math.exp":
|
|
4835
|
+
return finish(`exp(${arg(0)})`);
|
|
4836
|
+
case "math.sqrt":
|
|
4837
|
+
return finish(`sqrt(${arg(0)})`);
|
|
4838
|
+
case "math.log":
|
|
4839
|
+
return finish(`log(${arg(0)})`);
|
|
4840
|
+
case "math.log2":
|
|
4841
|
+
return finish(`log2(${arg(0)})`);
|
|
4842
|
+
case "math.log10":
|
|
4843
|
+
return finish(`log10(${arg(0)})`);
|
|
4844
|
+
case "math.atan2":
|
|
4845
|
+
return finish(`atan2(${arg(0)}, ${arg(1)})`);
|
|
4846
|
+
case "math.pow":
|
|
4847
|
+
return finish(`scr_math_pow(${arg(0)}, ${arg(1)})`);
|
|
4688
4848
|
// Math.abs — C fabs IS the JS operation. Math.round — the JS
|
|
4689
4849
|
// half-toward-+Infinity rule (scr_lib.c; C round() differs on
|
|
4690
4850
|
// halves and naive floor(x+0.5) drifts at the epsilon boundary).
|
|
@@ -4796,6 +4956,8 @@ function emitPrimitiveLibCall(state) {
|
|
|
4796
4956
|
return finish(`scr_bigint_shr(${arg(0)}, ${arg(1)})`);
|
|
4797
4957
|
case "bigint.eq":
|
|
4798
4958
|
return finish(`scr_bigint_eq(${arg(0)}, ${arg(1)})`);
|
|
4959
|
+
case "bigint.eqString":
|
|
4960
|
+
return finish(`scr_bigint_eq_string(${arg(0)}, ${arg(1)})`);
|
|
4799
4961
|
case "bigint.cmp":
|
|
4800
4962
|
return finish(`scr_bigint_cmp_f64(${arg(0)}, ${arg(1)})`);
|
|
4801
4963
|
case "bigint.cmpNumber":
|
|
@@ -4868,6 +5030,7 @@ function emitPrimitiveLibCall(state) {
|
|
|
4868
5030
|
// +1 string, or Node's "Invalid time value" RangeError
|
|
4869
5031
|
// (may-throw seed set).
|
|
4870
5032
|
return finish(`scr_date_to_iso(${arg(0)})`);
|
|
5033
|
+
case "date.parse":
|
|
4871
5034
|
case "date.parseGetTime":
|
|
4872
5035
|
// The bounded date-string parse (X509 validity + ECMA format);
|
|
4873
5036
|
// NaN elsewhere. Never throws.
|
|
@@ -4925,6 +5088,8 @@ function emitPrimitiveLibCall(state) {
|
|
|
4925
5088
|
: `scr_str_from_char_code(${arg(0)})`);
|
|
4926
5089
|
case "string.lastIndexOf":
|
|
4927
5090
|
return finish(`scr_str_last_index_of(${arg(0)}, ${arg(1)})`);
|
|
5091
|
+
case "string.lastIndexOfFrom":
|
|
5092
|
+
return finish(`scr_str_last_index_of_from(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
4928
5093
|
case "string.raw":
|
|
4929
5094
|
// Raw literals + pre-stringified substitutions; +1 string.
|
|
4930
5095
|
return finish(`scr_str_raw(${arg(0)}, ${arg(1)})`);
|
|
@@ -5244,20 +5409,37 @@ function emitChildProcessLibCall(state) {
|
|
|
5244
5409
|
case "cp.spawn":
|
|
5245
5410
|
emitter.usesTimers = true; // the loop must run to reap the child
|
|
5246
5411
|
return finish(`scr_spawn(${arg(0)}, ${arg(1)})`);
|
|
5412
|
+
case "cp.fork":
|
|
5413
|
+
emitter.usesTimers = true;
|
|
5414
|
+
return finish(`scr_fork(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)})`);
|
|
5247
5415
|
case "cp.spawnOpts":
|
|
5248
5416
|
// The options form: per-slot stdio (ignore/inherit/fd — the
|
|
5249
5417
|
// fds dup2 into the child), detached (setsid), env
|
|
5250
5418
|
// replacement, cwd. Same loop/reap story as cp.spawn.
|
|
5251
5419
|
emitter.usesTimers = true;
|
|
5252
|
-
return finish(`scr_spawn_opts(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${arg(8)}, ${arg(9)}, ${arg(10)})`);
|
|
5253
|
-
case "
|
|
5420
|
+
return finish(`scr_spawn_opts(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${arg(8)}, ${arg(9)}, ${arg(10)}, ${arg(11)})`);
|
|
5421
|
+
case "cp.execFile": {
|
|
5422
|
+
const callbackArg = e.args[2];
|
|
5423
|
+
const cb = args[2];
|
|
5424
|
+
if (!callbackArg || !cb)
|
|
5425
|
+
throw new InternalCompilerError("emitter bug: execFile callback missing");
|
|
5426
|
+
const cbT = callbackArg.type;
|
|
5427
|
+
if (cbT.kind !== "func")
|
|
5428
|
+
throw new InternalCompilerError("emitter bug: execFile callback not a func");
|
|
5429
|
+
emitter.moveTemp(cb);
|
|
5430
|
+
const adapter = emitter.execFileThunkFor(cbT);
|
|
5431
|
+
emitter.usesTimers = true;
|
|
5432
|
+
return finish(`scr_exec_file(${arg(0)}, ${arg(1)}, ${cb.name}, &${adapter})`);
|
|
5433
|
+
}
|
|
5434
|
+
case "child.onExit":
|
|
5435
|
+
case "child.onClose": {
|
|
5254
5436
|
// The callback MOVES into the child's registry; the third
|
|
5255
5437
|
// ingredient is the ADAPTER — emitted per callback shape,
|
|
5256
5438
|
// because the `number | null` union's tags are program data
|
|
5257
5439
|
// (a zero-param listener gets the runtime's ignoring thunk).
|
|
5258
5440
|
const cbT = e.args[1].type;
|
|
5259
5441
|
if (cbT.kind !== "func")
|
|
5260
|
-
throw new InternalCompilerError(
|
|
5442
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} callback not a func`);
|
|
5261
5443
|
const cb = args[1];
|
|
5262
5444
|
emitter.moveTemp(cb);
|
|
5263
5445
|
const adapter = cbT.params.length === 0
|
|
@@ -5265,7 +5447,7 @@ function emitChildProcessLibCall(state) {
|
|
|
5265
5447
|
: cbT.params.length === 1
|
|
5266
5448
|
? emitter.childExitThunkFor(cbT.params[0])
|
|
5267
5449
|
: emitter.childExitSignalThunkFor(cbT.params[0], cbT.params[1]);
|
|
5268
|
-
emitter.line(
|
|
5450
|
+
emitter.line(`${e.fn === "child.onClose" ? "scr_child_on_close" : "scr_child_on_exit"}(${arg(0)}, ${cb.name}, &${adapter});${emitter.srcComment(e.loc)}`);
|
|
5269
5451
|
return { name: "", type: e.type };
|
|
5270
5452
|
}
|
|
5271
5453
|
case "child.onError": {
|
|
@@ -5280,6 +5462,43 @@ function emitChildProcessLibCall(state) {
|
|
|
5280
5462
|
emitter.line(`scr_child_on_error(${arg(0)}, ${cb.name}, &${adapter});${emitter.srcComment(e.loc)}`);
|
|
5281
5463
|
return { name: "", type: e.type };
|
|
5282
5464
|
}
|
|
5465
|
+
case "child.connected":
|
|
5466
|
+
return finish(`scr_child_ipc_connected(${arg(0)})`);
|
|
5467
|
+
case "child.send":
|
|
5468
|
+
emitter.usesTimers = true;
|
|
5469
|
+
return finish(`scr_child_ipc_send(${arg(0)}, ${arg(1)})`);
|
|
5470
|
+
case "child.sendCb": {
|
|
5471
|
+
const cbT = e.args[2].type;
|
|
5472
|
+
if (cbT.kind !== "func")
|
|
5473
|
+
throw new InternalCompilerError("emitter bug: child.send callback not a func");
|
|
5474
|
+
const cb = args[2];
|
|
5475
|
+
emitter.moveTemp(cb);
|
|
5476
|
+
emitter.usesTimers = true;
|
|
5477
|
+
return finish(`scr_child_ipc_send_cb(${arg(0)}, ${arg(1)}, ${cb.name}, &${emitter.ipcSendThunkFor(cbT)})`);
|
|
5478
|
+
}
|
|
5479
|
+
case "child.disconnect":
|
|
5480
|
+
emitter.usesTimers = true;
|
|
5481
|
+
return finish(`scr_child_ipc_disconnect(${arg(0)})`);
|
|
5482
|
+
case "child.onMessage": {
|
|
5483
|
+
const cbT = e.args[1].type;
|
|
5484
|
+
if (cbT.kind !== "func")
|
|
5485
|
+
throw new InternalCompilerError("emitter bug: child message listener not a func");
|
|
5486
|
+
const cb = args[1];
|
|
5487
|
+
emitter.moveTemp(cb);
|
|
5488
|
+
emitter.usesTimers = true;
|
|
5489
|
+
emitter.line(`scr_child_ipc_on_message(${arg(0)}, ${cb.name}, &${emitter.ipcMessageThunkFor(cbT)}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
5490
|
+
return { name: "", type: e.type };
|
|
5491
|
+
}
|
|
5492
|
+
case "child.onDisconnect": {
|
|
5493
|
+
const cbT = e.args[1].type;
|
|
5494
|
+
if (cbT.kind !== "func")
|
|
5495
|
+
throw new InternalCompilerError("emitter bug: child disconnect listener not a func");
|
|
5496
|
+
const cb = args[1];
|
|
5497
|
+
emitter.moveTemp(cb);
|
|
5498
|
+
emitter.usesTimers = true;
|
|
5499
|
+
emitter.line(`scr_child_ipc_on_disconnect(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
5500
|
+
return { name: "", type: e.type };
|
|
5501
|
+
}
|
|
5283
5502
|
default:
|
|
5284
5503
|
throw new InternalCompilerError(`emitter bug: childProcess libCall dispatch for ${fn}`);
|
|
5285
5504
|
}
|
|
@@ -5377,6 +5596,8 @@ function emitNetworkLibCall(state) {
|
|
|
5377
5596
|
}
|
|
5378
5597
|
case "net.serverPort":
|
|
5379
5598
|
return finish(`scr_net_server_port(${arg(0)})`);
|
|
5599
|
+
case "net.serverListening":
|
|
5600
|
+
return finish(`scr_net_server_listening(${arg(0)})`);
|
|
5380
5601
|
case "net.serverAddress": {
|
|
5381
5602
|
// The AddressInfo record from the three runtime reads (the
|
|
5382
5603
|
// dgram.address materialization; none of these throw).
|
|
@@ -5454,9 +5675,7 @@ function emitNetworkLibCall(state) {
|
|
|
5454
5675
|
const cb = args[1];
|
|
5455
5676
|
emitter.moveTemp(cb);
|
|
5456
5677
|
const adapter = cbT.params.length === 0 ? "scr_net_conn_thunk0" : "scr_net_conn_thunk_sock";
|
|
5457
|
-
const entry = e.fn === "net.serverOnConnection"
|
|
5458
|
-
? "scr_net_server_on_connection"
|
|
5459
|
-
: "scr_net_server_on_secure_connection";
|
|
5678
|
+
const entry = e.fn === "net.serverOnConnection" ? "scr_net_server_on_connection" : "scr_net_server_on_secure_connection";
|
|
5460
5679
|
emitter.line(`${entry}(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
5461
5680
|
return { name: "", type: e.type };
|
|
5462
5681
|
}
|
|
@@ -5857,7 +6076,8 @@ function emitHttpLibCall(state) {
|
|
|
5857
6076
|
return finish(`scr_http_req_aborted_flag(${arg(0)})`);
|
|
5858
6077
|
case "http.reqComplete":
|
|
5859
6078
|
return finish(`scr_http_req_complete(${arg(0)})`);
|
|
5860
|
-
case "http.reqHeader":
|
|
6079
|
+
case "http.reqHeader":
|
|
6080
|
+
case "http.reqTrailer": {
|
|
5861
6081
|
// string|undefined, type-directed exactly like process.envGet:
|
|
5862
6082
|
// the runtime answers +1 or NULL; NULL takes the undefined arm.
|
|
5863
6083
|
if (e.type.kind !== "union")
|
|
@@ -5868,12 +6088,29 @@ function emitHttpLibCall(state) {
|
|
|
5868
6088
|
if (strTag < 0 || undefTag < 0) {
|
|
5869
6089
|
throw new InternalCompilerError("emitter bug: http.reqHeader union lacks its arms");
|
|
5870
6090
|
}
|
|
5871
|
-
const
|
|
6091
|
+
const entry = e.fn === "http.reqHeader" ? "scr_http_req_header" : "scr_http_req_trailer";
|
|
6092
|
+
const s = emitter.newTemp(STRING, `${entry}(${arg(0)}, ${arg(1)})`);
|
|
5872
6093
|
emitter.moveTemp(s); // moves into the box when present; NULL otherwise
|
|
5873
6094
|
const present = `scr_union_new_ref(${strTag}, ${s.name}, &scr_str_retain_v, &scr_str_release_v, NULL)`;
|
|
5874
6095
|
const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
|
|
5875
6096
|
return emitter.newTemp(e.type, `${s.name} ? ${present} : ${absent}`);
|
|
5876
6097
|
}
|
|
6098
|
+
case "http.reqHeaderValues":
|
|
6099
|
+
case "http.reqTrailerValues": {
|
|
6100
|
+
if (e.type.kind !== "union")
|
|
6101
|
+
throw new InternalCompilerError("emitter bug: distinct header result is not a union");
|
|
6102
|
+
const def = emitter.unionsById.get(e.type.unionId);
|
|
6103
|
+
const arrTag = def ? def.arms.findIndex((a) => a.kind === "array") : -1;
|
|
6104
|
+
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
6105
|
+
if (arrTag < 0 || undefTag < 0)
|
|
6106
|
+
throw new InternalCompilerError("emitter bug: distinct header union lacks its arms");
|
|
6107
|
+
const entry = e.fn === "http.reqHeaderValues" ? "scr_http_req_header_values" : "scr_http_req_trailer_values";
|
|
6108
|
+
const values = emitter.newTemp(arrayOf(STRING), `${entry}(${arg(0)}, ${arg(1)})`);
|
|
6109
|
+
emitter.moveTemp(values);
|
|
6110
|
+
const present = `scr_union_new_ref(${arrTag}, ${values.name}, &scr_arr_retain_v, &scr_arr_release_v, NULL)`;
|
|
6111
|
+
const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
|
|
6112
|
+
return emitter.newTemp(e.type, `${values.name} ? ${present} : ${absent}`);
|
|
6113
|
+
}
|
|
5877
6114
|
case "http.reqOnData": {
|
|
5878
6115
|
const cbT = e.args[1].type;
|
|
5879
6116
|
if (cbT.kind !== "func")
|
|
@@ -5896,35 +6133,51 @@ function emitHttpLibCall(state) {
|
|
|
5896
6133
|
case "http.resSetHeader":
|
|
5897
6134
|
emitter.line(`scr_http_res_set_header(${arg(0)}, ${arg(1)}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
5898
6135
|
return { name: "", type: e.type };
|
|
5899
|
-
case "http.
|
|
5900
|
-
emitter.line(`
|
|
6136
|
+
case "http.validateHeaderName":
|
|
6137
|
+
emitter.line(`scr_http_validate_header_name(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
5901
6138
|
return { name: "", type: e.type };
|
|
5902
|
-
case "http.
|
|
5903
|
-
emitter.line(`
|
|
6139
|
+
case "http.validateHeaderValue":
|
|
6140
|
+
emitter.line(`scr_http_validate_header_value(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
5904
6141
|
return { name: "", type: e.type };
|
|
6142
|
+
case "http.resWriteHead":
|
|
6143
|
+
return finish(`scr_http_res_write_head(${arg(0)}, ${arg(1)})`);
|
|
6144
|
+
case "http.resWriteHeadN":
|
|
6145
|
+
return finish(`scr_http_res_write_head_n(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
|
|
6146
|
+
case "http.resWriteContinue":
|
|
6147
|
+
return finish(`scr_http_res_write_continue(${arg(0)})`);
|
|
6148
|
+
case "http.resWriteProcessing":
|
|
6149
|
+
return finish(`scr_http_res_write_processing(${arg(0)})`);
|
|
6150
|
+
case "http.resWriteEarlyHints":
|
|
6151
|
+
return finish(`scr_http_res_write_early_hints(${arg(0)}, ${arg(1)})`);
|
|
5905
6152
|
case "http.resWrite":
|
|
5906
|
-
|
|
5907
|
-
return { name: "", type: e.type };
|
|
6153
|
+
return finish(`scr_http_res_write_str(${arg(0)}, ${arg(1)})`);
|
|
5908
6154
|
case "http.resWriteBytes":
|
|
5909
|
-
|
|
5910
|
-
return { name: "", type: e.type };
|
|
6155
|
+
return finish(`scr_http_res_write_bytes(${arg(0)}, ${arg(1)})`);
|
|
5911
6156
|
case "http.resEnd":
|
|
5912
|
-
|
|
5913
|
-
return { name: "", type: e.type };
|
|
6157
|
+
return finish(`scr_http_res_end(${arg(0)})`);
|
|
5914
6158
|
case "http.resEndStr":
|
|
5915
|
-
|
|
5916
|
-
return { name: "", type: e.type };
|
|
6159
|
+
return finish(`scr_http_res_end_str(${arg(0)}, ${arg(1)})`);
|
|
5917
6160
|
case "http.resEndBytes":
|
|
5918
|
-
|
|
5919
|
-
return { name: "", type: e.type };
|
|
6161
|
+
return finish(`scr_http_res_end_bytes(${arg(0)}, ${arg(1)})`);
|
|
5920
6162
|
case "http.resWriteDyn":
|
|
5921
|
-
|
|
5922
|
-
return { name: "", type: e.type };
|
|
6163
|
+
return finish(`scr_http_res_write_dynv(${arg(0)}, ${arg(1)})`);
|
|
5923
6164
|
case "http.resEndDyn":
|
|
5924
|
-
|
|
5925
|
-
return { name: "", type: e.type };
|
|
6165
|
+
return finish(`scr_http_res_end_dynv(${arg(0)}, ${arg(1)})`);
|
|
5926
6166
|
case "http.resHeadersSent":
|
|
5927
6167
|
return finish(`scr_http_res_headers_sent(${arg(0)})`);
|
|
6168
|
+
case "http.resWritableEnded":
|
|
6169
|
+
return finish(`scr_http_res_writable_ended(${arg(0)})`);
|
|
6170
|
+
case "http.resFlushHeaders":
|
|
6171
|
+
return finish(`scr_http_res_flush_headers(${arg(0)})`);
|
|
6172
|
+
case "http.resAddTrailers":
|
|
6173
|
+
return finish(`scr_http_res_add_trailers(${arg(0)}, ${arg(1)})`);
|
|
6174
|
+
case "http.resCork":
|
|
6175
|
+
emitter.line(`scr_http_res_cork(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6176
|
+
return { name: "", type: e.type };
|
|
6177
|
+
case "http.resUncork":
|
|
6178
|
+
return finish(`scr_http_res_uncork(${arg(0)})`);
|
|
6179
|
+
case "http.resWritableCorked":
|
|
6180
|
+
return finish(`scr_http_res_writable_corked(${arg(0)})`);
|
|
5928
6181
|
// The server-surface member follow-ups.
|
|
5929
6182
|
case "http.reqStatusCode": {
|
|
5930
6183
|
// number | undefined, type-directed like process.columns: the
|
|
@@ -5961,8 +6214,12 @@ function emitHttpLibCall(state) {
|
|
|
5961
6214
|
return finish(`scr_http_req_h2_stream_or_throw(${arg(0)}, ${arg(1)})`);
|
|
5962
6215
|
case "http.reqRawHeaders":
|
|
5963
6216
|
return finish(`scr_http_req_raw_headers(${arg(0)})`);
|
|
6217
|
+
case "http.reqRawTrailers":
|
|
6218
|
+
return finish(`scr_http_req_raw_trailers(${arg(0)})`);
|
|
5964
6219
|
case "http.reqHeaderPairs":
|
|
5965
6220
|
return finish(`scr_http_req_header_pairs(${arg(0)})`);
|
|
6221
|
+
case "http.reqTrailerPairs":
|
|
6222
|
+
return finish(`scr_http_req_trailer_pairs(${arg(0)})`);
|
|
5966
6223
|
case "http.reqStatusMessage": {
|
|
5967
6224
|
// string | undefined: a reason phrase on client responses,
|
|
5968
6225
|
// NULL (the undefined arm) on server requests — the
|
|
@@ -6074,6 +6331,35 @@ function emitHttpLibCall(state) {
|
|
|
6074
6331
|
case "http.serverJoinDupHeaders":
|
|
6075
6332
|
emitter.line(`scr_http_server_join_duplicate_headers(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6076
6333
|
return { name: "", type: e.type };
|
|
6334
|
+
case "http.serverAllowMissingHostHeader":
|
|
6335
|
+
emitter.line(`scr_http_server_allow_missing_host_header(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6336
|
+
return { name: "", type: e.type };
|
|
6337
|
+
case "http.serverSetTimeout":
|
|
6338
|
+
emitter.line(`scr_net_server_set_timeout_plain(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6339
|
+
return { name: "", type: e.type };
|
|
6340
|
+
case "http.serverCloseAllConnections":
|
|
6341
|
+
case "http.serverCloseIdleConnections": {
|
|
6342
|
+
const entry = e.fn === "http.serverCloseAllConnections"
|
|
6343
|
+
? "scr_net_server_close_all_connections" : "scr_net_server_close_idle_connections";
|
|
6344
|
+
emitter.line(`${entry}(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6345
|
+
return { name: "", type: e.type };
|
|
6346
|
+
}
|
|
6347
|
+
case "http.serverOnTimeout":
|
|
6348
|
+
case "http.serverSetTimeoutCb": {
|
|
6349
|
+
const cbIndex = e.fn === "http.serverSetTimeoutCb" ? 2 : 1;
|
|
6350
|
+
const cbT = e.args[cbIndex].type;
|
|
6351
|
+
if (cbT.kind !== "func")
|
|
6352
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} callback not a func`);
|
|
6353
|
+
const cb = args[cbIndex];
|
|
6354
|
+
emitter.moveTemp(cb);
|
|
6355
|
+
const adapter = cbT.params.length === 0 ? "scr_net_conn_thunk0" : "scr_net_conn_thunk_sock";
|
|
6356
|
+
const entry = e.fn === "http.serverOnTimeout" ? "scr_net_server_on_timeout" : "scr_net_server_set_timeout_cb";
|
|
6357
|
+
const callArgs = e.fn === "http.serverOnTimeout"
|
|
6358
|
+
? `${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)}`
|
|
6359
|
+
: `${arg(0)}, ${arg(1)}, ${cb.name}, &${adapter}`;
|
|
6360
|
+
emitter.line(`${entry}(${callArgs});${emitter.srcComment(e.loc)}`);
|
|
6361
|
+
return { name: "", type: e.type };
|
|
6362
|
+
}
|
|
6077
6363
|
case "http.serverTimeoutGet":
|
|
6078
6364
|
return finish(`scr_net_server_timeout_get(${arg(0)}, ${arg(1)})`);
|
|
6079
6365
|
case "http.serverTimeoutSet":
|
|
@@ -6086,27 +6372,82 @@ function emitHttpLibCall(state) {
|
|
|
6086
6372
|
case "http.resStatusSet":
|
|
6087
6373
|
emitter.line(`scr_http_res_status_set(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6088
6374
|
return { name: "", type: e.type };
|
|
6089
|
-
case "http.resStatusMsgGet":
|
|
6090
|
-
|
|
6375
|
+
case "http.resStatusMsgGet": {
|
|
6376
|
+
if (e.type.kind !== "union")
|
|
6377
|
+
throw new InternalCompilerError("emitter bug: http.resStatusMsgGet result is not a union");
|
|
6378
|
+
const def = emitter.unionsById.get(e.type.unionId);
|
|
6379
|
+
const strTag = def ? def.arms.findIndex((a) => a.kind === "string") : -1;
|
|
6380
|
+
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
6381
|
+
if (strTag < 0 || undefTag < 0)
|
|
6382
|
+
throw new InternalCompilerError("emitter bug: http.resStatusMsgGet union lacks its arms");
|
|
6383
|
+
const msg = emitter.newTemp(STRING, `scr_http_res_status_msg_get(${arg(0)})`);
|
|
6384
|
+
emitter.moveTemp(msg);
|
|
6385
|
+
const present = `scr_union_new_ref(${strTag}, ${msg.name}, &scr_str_retain_v, &scr_str_release_v, NULL)`;
|
|
6386
|
+
return emitter.newTemp(e.type, `${msg.name} ? ${present} : ${emitter.unitInstanceRef(e.type.unionId, undefTag)}`);
|
|
6387
|
+
}
|
|
6091
6388
|
case "http.resStatusMsgSet":
|
|
6092
6389
|
emitter.line(`scr_http_res_status_msg_set(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6093
6390
|
return { name: "", type: e.type };
|
|
6094
|
-
case "http.
|
|
6391
|
+
case "http.resRequest":
|
|
6392
|
+
return finish(`scr_http_res_request(${arg(0)})`);
|
|
6393
|
+
case "http.resSocket": {
|
|
6394
|
+
if (e.type.kind !== "union")
|
|
6395
|
+
throw new InternalCompilerError("emitter bug: http.resSocket result is not a union");
|
|
6396
|
+
const def = emitter.unionsById.get(e.type.unionId);
|
|
6397
|
+
const socketTag = def ? def.arms.findIndex((a) => a.kind === "netSocket") : -1;
|
|
6398
|
+
const nullTag = def ? def.arms.findIndex((a) => a.kind === "nullT") : -1;
|
|
6399
|
+
if (socketTag < 0 || nullTag < 0)
|
|
6400
|
+
throw new InternalCompilerError("emitter bug: http.resSocket union lacks its arms");
|
|
6401
|
+
const sock = emitter.newTemp(NETSOCKET_T, `scr_http_res_socket(${arg(0)})`);
|
|
6402
|
+
emitter.moveTemp(sock);
|
|
6403
|
+
const present = `scr_union_new_ref(${socketTag}, ${sock.name}, &scr_net_sock_retain_v, &scr_net_sock_release_v, NULL)`;
|
|
6404
|
+
return emitter.newTemp(e.type, `${sock.name} ? ${present} : ${emitter.unitInstanceRef(e.type.unionId, nullTag)}`);
|
|
6405
|
+
}
|
|
6406
|
+
case "http.resWritableFinished":
|
|
6407
|
+
return finish(`scr_http_res_writable_finished(${arg(0)})`);
|
|
6408
|
+
case "http.resSendDateGet":
|
|
6409
|
+
return finish(`scr_http_res_send_date(${arg(0)})`);
|
|
6410
|
+
case "http.resSendDateSet":
|
|
6411
|
+
emitter.line(`scr_http_res_set_send_date(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6412
|
+
return { name: "", type: e.type };
|
|
6413
|
+
case "http.resStrictContentLengthGet":
|
|
6414
|
+
return finish(`scr_http_res_strict_content_length(${arg(0)})`);
|
|
6415
|
+
case "http.resStrictContentLengthSet":
|
|
6416
|
+
emitter.line(`scr_http_res_set_strict_content_length(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6417
|
+
return { name: "", type: e.type };
|
|
6418
|
+
case "http.resSetTimeout":
|
|
6419
|
+
emitter.line(`scr_http_res_set_timeout_plain(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6420
|
+
return { name: "", type: e.type };
|
|
6421
|
+
case "http.resSetTimeoutCb": {
|
|
6422
|
+
const cb = args[2];
|
|
6423
|
+
emitter.moveTemp(cb);
|
|
6424
|
+
emitter.line(`scr_http_res_set_timeout(${arg(0)}, ${arg(1)}, ${cb.name});${emitter.srcComment(e.loc)}`);
|
|
6425
|
+
return { name: "", type: e.type };
|
|
6426
|
+
}
|
|
6427
|
+
case "http.resGetHeader":
|
|
6428
|
+
case "http.clientGetHeader": {
|
|
6095
6429
|
// string|undefined, exactly the http.reqHeader emission.
|
|
6096
6430
|
if (e.type.kind !== "union")
|
|
6097
|
-
throw new InternalCompilerError(
|
|
6431
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} result is not a union`);
|
|
6098
6432
|
const def = emitter.unionsById.get(e.type.unionId);
|
|
6099
6433
|
const strTag = def ? def.arms.findIndex((a) => a.kind === "string") : -1;
|
|
6100
6434
|
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
6101
6435
|
if (strTag < 0 || undefTag < 0) {
|
|
6102
6436
|
throw new InternalCompilerError("emitter bug: http.resGetHeader union lacks its arms");
|
|
6103
6437
|
}
|
|
6104
|
-
const
|
|
6438
|
+
const entry = e.fn === "http.resGetHeader" ? "scr_http_res_get_header" : "scr_http_client_get_header";
|
|
6439
|
+
const s = emitter.newTemp(STRING, `${entry}(${arg(0)}, ${arg(1)})`);
|
|
6105
6440
|
emitter.moveTemp(s); // moves into the box when present; NULL otherwise
|
|
6106
6441
|
const present = `scr_union_new_ref(${strTag}, ${s.name}, &scr_str_retain_v, &scr_str_release_v, NULL)`;
|
|
6107
6442
|
const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
|
|
6108
6443
|
return emitter.newTemp(e.type, `${s.name} ? ${present} : ${absent}`);
|
|
6109
6444
|
}
|
|
6445
|
+
case "http.resGetHeaderNames":
|
|
6446
|
+
return finish(`scr_http_res_get_header_names(${arg(0)})`);
|
|
6447
|
+
case "http.resGetRawHeaderNames":
|
|
6448
|
+
return finish(`scr_http_res_get_raw_header_names(${arg(0)})`);
|
|
6449
|
+
case "http.resGetHeaders":
|
|
6450
|
+
return finish(`scr_http_res_get_headers(${arg(0)})`);
|
|
6110
6451
|
case "http.resHasHeader":
|
|
6111
6452
|
return finish(`scr_http_res_has_header_named(${arg(0)}, ${arg(1)})`);
|
|
6112
6453
|
case "http.resRemoveHeader":
|
|
@@ -6119,12 +6460,19 @@ function emitHttpLibCall(state) {
|
|
|
6119
6460
|
return { name: "", type: e.type };
|
|
6120
6461
|
}
|
|
6121
6462
|
case "http.resWriteHeadPairs":
|
|
6122
|
-
|
|
6123
|
-
return { name: "", type: e.type };
|
|
6463
|
+
return finish(`scr_http_res_write_head_pairs(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6124
6464
|
case "http.resWriteHeadDyn":
|
|
6125
6465
|
return finish(`scr_http_res_write_head_dyn(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6126
6466
|
case "http.reqSetEncoding":
|
|
6127
6467
|
return finish(`scr_http_req_set_encoding(${arg(0)}, ${arg(1)})`);
|
|
6468
|
+
case "http.reqSetTimeout":
|
|
6469
|
+
return finish(`scr_http_req_set_timeout_plain(${arg(0)}, ${arg(1)})`);
|
|
6470
|
+
case "http.reqSetTimeoutCb": {
|
|
6471
|
+
const cb = args[2];
|
|
6472
|
+
emitter.moveTemp(cb);
|
|
6473
|
+
emitter.line(`scr_http_req_set_timeout(${arg(0)}, ${arg(1)}, ${cb.name});${emitter.srcComment(e.loc)}`);
|
|
6474
|
+
return { name: "", type: e.type };
|
|
6475
|
+
}
|
|
6128
6476
|
// node:http, the client slice (scr_http.c over the net client).
|
|
6129
6477
|
case "http.request":
|
|
6130
6478
|
case "http.requestCb": {
|
|
@@ -6293,29 +6641,84 @@ function emitHttpLibCall(state) {
|
|
|
6293
6641
|
return finish(`(${arg(0)} ? scr_https_request(${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${arg(8)}, (const char *)${arg(9)}->data, ${arg(9)}->len, ${cbExpr}, ${adapter}) : scr_http_request_ex(${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)}, ${arg(7)}, ${cbExpr}, ${adapter}, 80, NULL, NULL))`);
|
|
6294
6642
|
}
|
|
6295
6643
|
case "http.clientWrite":
|
|
6296
|
-
|
|
6297
|
-
|
|
6644
|
+
return finish(`scr_http_client_write_str(${arg(0)}, ${arg(1)})`);
|
|
6645
|
+
case "http.clientSetHeader":
|
|
6646
|
+
return finish(`scr_http_client_set_header(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6647
|
+
case "http.clientHasHeader":
|
|
6648
|
+
return finish(`scr_http_client_has_header_named(${arg(0)}, ${arg(1)})`);
|
|
6649
|
+
case "http.clientRemoveHeader":
|
|
6650
|
+
return finish(`scr_http_client_remove_header(${arg(0)}, ${arg(1)})`);
|
|
6651
|
+
case "http.clientGetHeaderNames":
|
|
6652
|
+
return finish(`scr_http_client_get_header_names(${arg(0)})`);
|
|
6653
|
+
case "http.clientGetRawHeaderNames":
|
|
6654
|
+
return finish(`scr_http_client_get_raw_header_names(${arg(0)})`);
|
|
6655
|
+
case "http.clientGetHeaders":
|
|
6656
|
+
return finish(`scr_http_client_get_headers(${arg(0)})`);
|
|
6298
6657
|
case "http.clientWriteBytes":
|
|
6299
|
-
|
|
6300
|
-
return { name: "", type: e.type };
|
|
6658
|
+
return finish(`scr_http_client_write_bytes(${arg(0)}, ${arg(1)})`);
|
|
6301
6659
|
case "http.clientEnd":
|
|
6302
|
-
|
|
6303
|
-
return { name: "", type: e.type };
|
|
6660
|
+
return finish(`scr_http_client_end(${arg(0)})`);
|
|
6304
6661
|
case "http.clientEndStr":
|
|
6305
|
-
|
|
6306
|
-
return { name: "", type: e.type };
|
|
6662
|
+
return finish(`scr_http_client_end_str(${arg(0)}, ${arg(1)})`);
|
|
6307
6663
|
case "http.clientEndBytes":
|
|
6308
|
-
|
|
6309
|
-
return { name: "", type: e.type };
|
|
6664
|
+
return finish(`scr_http_client_end_bytes(${arg(0)}, ${arg(1)})`);
|
|
6310
6665
|
case "http.clientWriteDyn":
|
|
6311
|
-
|
|
6312
|
-
return { name: "", type: e.type };
|
|
6666
|
+
return finish(`scr_http_client_write_dynv(${arg(0)}, ${arg(1)})`);
|
|
6313
6667
|
case "http.clientEndDyn":
|
|
6314
|
-
|
|
6668
|
+
return finish(`scr_http_client_end_dynv(${arg(0)}, ${arg(1)})`);
|
|
6669
|
+
case "http.clientFlushHeaders":
|
|
6670
|
+
return finish(`scr_http_client_flush_headers(${arg(0)})`);
|
|
6671
|
+
case "http.clientAddTrailers":
|
|
6672
|
+
return finish(`scr_http_client_add_trailers(${arg(0)}, ${arg(1)})`);
|
|
6673
|
+
case "http.clientCork":
|
|
6674
|
+
emitter.line(`scr_http_client_cork(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6675
|
+
return { name: "", type: e.type };
|
|
6676
|
+
case "http.clientUncork":
|
|
6677
|
+
return finish(`scr_http_client_uncork(${arg(0)})`);
|
|
6678
|
+
case "http.clientWritableCorked":
|
|
6679
|
+
return finish(`scr_http_client_writable_corked(${arg(0)})`);
|
|
6680
|
+
case "http.clientMethod":
|
|
6681
|
+
return finish(`scr_http_client_method(${arg(0)})`);
|
|
6682
|
+
case "http.clientPath":
|
|
6683
|
+
return finish(`scr_http_client_path(${arg(0)})`);
|
|
6684
|
+
case "http.clientHost":
|
|
6685
|
+
return finish(`scr_http_client_host(${arg(0)})`);
|
|
6686
|
+
case "http.clientProtocol":
|
|
6687
|
+
return finish(`scr_http_client_protocol(${arg(0)})`);
|
|
6688
|
+
case "http.clientHeadersSent":
|
|
6689
|
+
return finish(`scr_http_client_headers_sent(${arg(0)})`);
|
|
6690
|
+
case "http.clientWritableEnded":
|
|
6691
|
+
return finish(`scr_http_client_writable_ended(${arg(0)})`);
|
|
6692
|
+
case "http.clientWritableFinished":
|
|
6693
|
+
return finish(`scr_http_client_writable_finished(${arg(0)})`);
|
|
6694
|
+
case "http.clientSocket":
|
|
6695
|
+
return finish(`scr_http_client_socket(${arg(0)})`);
|
|
6696
|
+
case "http.clientReusedSocket":
|
|
6697
|
+
return finish(`scr_http_client_reused_socket(${arg(0)})`);
|
|
6698
|
+
case "http.clientSetNoDelay":
|
|
6699
|
+
return finish(`scr_http_client_set_nodelay(${arg(0)}, ${arg(1)})`);
|
|
6700
|
+
case "http.clientSetSocketKeepAlive":
|
|
6701
|
+
return finish(`scr_http_client_set_socket_keepalive(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6702
|
+
case "http.clientSetTimeout":
|
|
6703
|
+
return finish(`scr_http_client_set_timeout(${arg(0)}, ${arg(1)})`);
|
|
6704
|
+
case "http.clientSetTimeoutCb": {
|
|
6705
|
+
const cb = args[2];
|
|
6706
|
+
emitter.moveTemp(cb);
|
|
6707
|
+
emitter.line(`scr_http_client_set_timeout_cb(${arg(0)}, ${arg(1)}, ${cb.name});${emitter.srcComment(e.loc)}`);
|
|
6315
6708
|
return { name: "", type: e.type };
|
|
6709
|
+
}
|
|
6710
|
+
case "http.statusCodes":
|
|
6711
|
+
return finish("scr_http_status_codes()");
|
|
6712
|
+
case "http.methods":
|
|
6713
|
+
return finish("scr_http_methods()");
|
|
6316
6714
|
case "http.clientDestroy":
|
|
6317
6715
|
emitter.line(`scr_http_client_destroy(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6318
6716
|
return { name: "", type: e.type };
|
|
6717
|
+
case "http.clientAbort":
|
|
6718
|
+
emitter.line(`scr_http_client_abort(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6719
|
+
return { name: "", type: e.type };
|
|
6720
|
+
case "http.clientAborted":
|
|
6721
|
+
return finish(`scr_http_client_aborted(${arg(0)})`);
|
|
6319
6722
|
case "http.clientDestroyed":
|
|
6320
6723
|
return finish(`scr_http_client_destroyed(${arg(0)})`);
|
|
6321
6724
|
case "http.clientOnResponse": {
|
|
@@ -6328,6 +6731,16 @@ function emitHttpLibCall(state) {
|
|
|
6328
6731
|
emitter.line(`scr_http_client_on_response(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
6329
6732
|
return { name: "", type: e.type };
|
|
6330
6733
|
}
|
|
6734
|
+
case "http.clientOnSocket": {
|
|
6735
|
+
const cbT = e.args[1].type;
|
|
6736
|
+
if (cbT.kind !== "func")
|
|
6737
|
+
throw new InternalCompilerError("emitter bug: http.clientOnSocket callback not a func");
|
|
6738
|
+
const cb = args[1];
|
|
6739
|
+
emitter.moveTemp(cb);
|
|
6740
|
+
const adapter = cbT.params.length === 0 ? "scr_net_conn_thunk0" : "scr_net_conn_thunk_sock";
|
|
6741
|
+
emitter.line(`scr_http_client_on_socket(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
6742
|
+
return { name: "", type: e.type };
|
|
6743
|
+
}
|
|
6331
6744
|
case "http.clientOnError": {
|
|
6332
6745
|
const cbT = e.args[1].type;
|
|
6333
6746
|
if (cbT.kind !== "func")
|
|
@@ -6339,10 +6752,14 @@ function emitHttpLibCall(state) {
|
|
|
6339
6752
|
return { name: "", type: e.type };
|
|
6340
6753
|
}
|
|
6341
6754
|
case "http.clientOnTimeout":
|
|
6342
|
-
case "http.clientOnClose":
|
|
6755
|
+
case "http.clientOnClose":
|
|
6756
|
+
case "http.clientOnFinish":
|
|
6757
|
+
case "http.clientOnAbort": {
|
|
6343
6758
|
const cb = args[1];
|
|
6344
6759
|
emitter.moveTemp(cb);
|
|
6345
|
-
const fn = e.fn === "http.clientOnTimeout" ? "scr_http_client_on_timeout"
|
|
6760
|
+
const fn = e.fn === "http.clientOnTimeout" ? "scr_http_client_on_timeout"
|
|
6761
|
+
: e.fn === "http.clientOnClose" ? "scr_http_client_on_close"
|
|
6762
|
+
: e.fn === "http.clientOnAbort" ? "scr_http_client_on_abort" : "scr_http_client_on_finish";
|
|
6346
6763
|
emitter.line(`${fn}(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
6347
6764
|
return { name: "", type: e.type };
|
|
6348
6765
|
}
|
|
@@ -7126,6 +7543,45 @@ function emitProcessLibCall(state) {
|
|
|
7126
7543
|
return finish(`scr_process_getgid()`);
|
|
7127
7544
|
case "process.execPath":
|
|
7128
7545
|
return finish(`scr_process_exec_path()`);
|
|
7546
|
+
case "process.forkTarget":
|
|
7547
|
+
return finish(`scr_process_fork_target(${arg(0)})`);
|
|
7548
|
+
case "process.connected":
|
|
7549
|
+
return finish(`scr_process_ipc_connected()`);
|
|
7550
|
+
case "process.send":
|
|
7551
|
+
emitter.usesTimers = true;
|
|
7552
|
+
return finish(`scr_process_ipc_send(${arg(0)})`);
|
|
7553
|
+
case "process.sendCb": {
|
|
7554
|
+
const cbT = e.args[1].type;
|
|
7555
|
+
if (cbT.kind !== "func")
|
|
7556
|
+
throw new InternalCompilerError("emitter bug: process.send callback not a func");
|
|
7557
|
+
const cb = args[1];
|
|
7558
|
+
emitter.moveTemp(cb);
|
|
7559
|
+
emitter.usesTimers = true;
|
|
7560
|
+
return finish(`scr_process_ipc_send_cb(${arg(0)}, ${cb.name}, &${emitter.ipcSendThunkFor(cbT)})`);
|
|
7561
|
+
}
|
|
7562
|
+
case "process.disconnect":
|
|
7563
|
+
emitter.usesTimers = true;
|
|
7564
|
+
return finish(`scr_process_ipc_disconnect()`);
|
|
7565
|
+
case "process.onMessage": {
|
|
7566
|
+
const cbT = e.args[0].type;
|
|
7567
|
+
if (cbT.kind !== "func")
|
|
7568
|
+
throw new InternalCompilerError("emitter bug: process message listener not a func");
|
|
7569
|
+
const cb = args[0];
|
|
7570
|
+
emitter.moveTemp(cb);
|
|
7571
|
+
emitter.usesTimers = true;
|
|
7572
|
+
emitter.line(`scr_process_ipc_on_message(${cb.name}, &${emitter.ipcMessageThunkFor(cbT)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
7573
|
+
return { name: "", type: e.type };
|
|
7574
|
+
}
|
|
7575
|
+
case "process.onDisconnect": {
|
|
7576
|
+
const cbT = e.args[0].type;
|
|
7577
|
+
if (cbT.kind !== "func")
|
|
7578
|
+
throw new InternalCompilerError("emitter bug: process disconnect listener not a func");
|
|
7579
|
+
const cb = args[0];
|
|
7580
|
+
emitter.moveTemp(cb);
|
|
7581
|
+
emitter.usesTimers = true;
|
|
7582
|
+
emitter.line(`scr_process_ipc_on_disconnect(${cb.name}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
7583
|
+
return { name: "", type: e.type };
|
|
7584
|
+
}
|
|
7129
7585
|
case "process.arch":
|
|
7130
7586
|
return finish(`scr_process_arch()`);
|
|
7131
7587
|
case "process.versionsNode":
|
|
@@ -7149,6 +7605,10 @@ function emitProcessLibCall(state) {
|
|
|
7149
7605
|
// Flushes stdout and _Exit()s — never returns (exit handlers,
|
|
7150
7606
|
// including the RC audit, deliberately do not run).
|
|
7151
7607
|
return finish(`scr_process_exit(${arg(0)})`);
|
|
7608
|
+
case "process.setExitCode":
|
|
7609
|
+
return finish(`scr_process_set_exit_code(${arg(0)})`);
|
|
7610
|
+
case "process.currentExitCode":
|
|
7611
|
+
return finish(`scr_process_exit_code_or_zero()`);
|
|
7152
7612
|
case "process.nextTick": {
|
|
7153
7613
|
// The tick queue owns the callback until the drain fires it;
|
|
7154
7614
|
// ticks run before promise jobs at every loop checkpoint and
|
|
@@ -7362,6 +7822,8 @@ function emitErrorsEventsLibCall(state) {
|
|
|
7362
7822
|
const dynThunk = emitter.emitterInvokeThunkFor(adT);
|
|
7363
7823
|
return finish(`(${cType(e.type).trim()})scr_emitter_on_dyn((ScrEmitter *)${arg(0)}, ${arg(1)}, ${arg(2)}, ${adapter.name}, &${dynThunk}, ${arg(4)}, ${arg(5)})`);
|
|
7364
7824
|
}
|
|
7825
|
+
case "emitter.onFlex":
|
|
7826
|
+
return finish(`(${cType(e.type).trim()})scr_emitter_on_flex((ScrEmitter *)${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
|
|
7365
7827
|
case "emitter.onData": {
|
|
7366
7828
|
// The stream-'data' registration: same runtime entry as
|
|
7367
7829
|
// emitter.on, but the DATA invoke thunk (the two-slot payload
|
|
@@ -7401,6 +7863,13 @@ function emitErrorsEventsLibCall(state) {
|
|
|
7401
7863
|
// C variadic tail, every argument borrowed (the invoke
|
|
7402
7864
|
// adapters retain each callee's +1). May-throw (listeners).
|
|
7403
7865
|
return finish(`scr_emitter_emit((ScrEmitter *)${arg(0)}, ${arg(1)}${e.args.slice(2).map((_, i) => `, ${arg(i + 2)}`).join("")})`);
|
|
7866
|
+
case "emitter.emitFlex": {
|
|
7867
|
+
const count = e.args.length - 2;
|
|
7868
|
+
const payload = count === 0
|
|
7869
|
+
? "NULL"
|
|
7870
|
+
: `(ScrDyn *const[]){${e.args.slice(2).map((_, i) => arg(i + 2)).join(", ")}}`;
|
|
7871
|
+
return finish(`scr_emitter_emit_flex((ScrEmitter *)${arg(0)}, ${arg(1)}, ${payload}, ${count})`);
|
|
7872
|
+
}
|
|
7404
7873
|
case "emitter.emitError":
|
|
7405
7874
|
// emit('error', err): unhandled ⇒ the runtime throws the
|
|
7406
7875
|
// payload through the exception cell (may-throw seed).
|
|
@@ -7479,12 +7948,25 @@ function emitStreamLibCall(state) {
|
|
|
7479
7948
|
emitter.line(`scr_child_stream_on_data(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
7480
7949
|
return { name: "", type: e.type };
|
|
7481
7950
|
}
|
|
7951
|
+
case "stream.onDataStr": {
|
|
7952
|
+
emitter.usesTimers = true;
|
|
7953
|
+
const cbT = e.args[1].type;
|
|
7954
|
+
if (cbT.kind !== "func" || cbT.params[0]?.kind !== "string") {
|
|
7955
|
+
throw new InternalCompilerError("emitter bug: stream.onDataStr callback not a string func");
|
|
7956
|
+
}
|
|
7957
|
+
const cb = args[1];
|
|
7958
|
+
emitter.moveTemp(cb);
|
|
7959
|
+
emitter.line(`scr_child_stream_on_data_str(${arg(0)}, ${cb.name}, &scr_child_stream_thunk_str, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
7960
|
+
return { name: "", type: e.type };
|
|
7961
|
+
}
|
|
7482
7962
|
case "stream.onEnd": {
|
|
7483
7963
|
const cb = args[1];
|
|
7484
7964
|
emitter.moveTemp(cb);
|
|
7485
7965
|
emitter.line(`scr_child_stream_on_end(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
7486
7966
|
return { name: "", type: e.type };
|
|
7487
7967
|
}
|
|
7968
|
+
case "stream.childSetEncoding":
|
|
7969
|
+
return finish(`scr_child_stream_set_encoding(${arg(0)}, ${arg(1)})`);
|
|
7488
7970
|
// node:stream (scr_stream.c — linked exactly when these appear,
|
|
7489
7971
|
// moduleUsesStream). Receivers reinterpret to the shared
|
|
7490
7972
|
// ScrStream layout (the ScrEmitter prefix plus the stream-state
|
|
@@ -7895,6 +8377,8 @@ function emitAssertInspectLibCall(state) {
|
|
|
7895
8377
|
// The quartet over checked-dynamic operands: SameValue /
|
|
7896
8378
|
// dyn-walk deep equality, assertion_error.js messages.
|
|
7897
8379
|
return finish(`scr_assert_eq_dyn(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
|
|
8380
|
+
case "assert.looseResult":
|
|
8381
|
+
return finish(`scr_assert_loose_result(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`);
|
|
7898
8382
|
case "assert.deepResult":
|
|
7899
8383
|
return finish(`scr_assert_deep_result(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
|
|
7900
8384
|
case "assert.deqEnter":
|
|
@@ -8175,6 +8659,7 @@ export function emitExpr(emitter, e) {
|
|
|
8175
8659
|
case "numLit":
|
|
8176
8660
|
case "boolLit":
|
|
8177
8661
|
case "strLit":
|
|
8662
|
+
case "moduleNsRef":
|
|
8178
8663
|
case "unitLit":
|
|
8179
8664
|
case "varRef":
|
|
8180
8665
|
return emitLiteralExpr(emitter, e);
|