@scriptc/compiler 0.1.4 → 0.1.6
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 +75 -11
- package/dist/backend/c/c-emitter.d.ts +5 -1
- package/dist/backend/c/c-emitter.js +22 -9
- 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 +298 -27
- 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 +8 -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 +1 -0
- package/dist/backend/link-plan.js +2 -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 +25 -9
- 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 +22 -17
- package/dist/backend/llvm/expr-bytes.js.map +1 -1
- package/dist/backend/llvm/expr-containers.d.ts +1 -0
- package/dist/backend/llvm/expr-containers.js +58 -4
- package/dist/backend/llvm/expr-containers.js.map +1 -1
- package/dist/backend/llvm/expr-context.d.ts +6 -2
- package/dist/backend/llvm/expr-primitives.js +22 -7
- package/dist/backend/llvm/expr-primitives.js.map +1 -1
- package/dist/backend/llvm/lib-filesystem.js +20 -0
- package/dist/backend/llvm/lib-filesystem.js.map +1 -1
- package/dist/backend/llvm/lib-network.js +53 -10
- package/dist/backend/llvm/lib-network.js.map +1 -1
- package/dist/backend/llvm/lib-process.js +4 -3
- package/dist/backend/llvm/lib-process.js.map +1 -1
- package/dist/backend/llvm/lib-shared.js +65 -0
- package/dist/backend/llvm/lib-shared.js.map +1 -1
- package/dist/backend/native-toolchain.d.ts +2 -0
- package/dist/backend/native-toolchain.js +2 -1
- package/dist/backend/native-toolchain.js.map +1 -1
- package/dist/backend/targets.d.ts +3 -0
- package/dist/backend/targets.js +13 -0
- package/dist/backend/targets.js.map +1 -1
- package/dist/coverage/surface-manifest.js +12 -5
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/executable/executable-cache.d.ts +2 -0
- package/dist/executable/executable-cache.js +3 -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/lowering/array-indexed-mutation.d.ts +8 -0
- package/dist/frontend/lowering/array-indexed-mutation.js +176 -0
- package/dist/frontend/lowering/array-indexed-mutation.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 +14 -6
- package/dist/frontend/lowering/containers/string-and-regexp.js +420 -34
- 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/indexed-comparison.d.ts +6 -0
- package/dist/frontend/lowering/indexed-comparison.js +30 -0
- package/dist/frontend/lowering/indexed-comparison.js.map +1 -0
- package/dist/frontend/lowering/lower-builtins.d.ts +5 -6
- package/dist/frontend/lowering/lower-builtins.js +24 -16
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +3 -2
- package/dist/frontend/lowering/lower-calls.js +522 -89
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +5 -29
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +15 -11
- package/dist/frontend/lowering/lower-containers.js +588 -146
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +12 -0
- package/dist/frontend/lowering/lower-exprs.js +145 -11
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-island.js +17 -6
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +2 -4
- package/dist/frontend/lowering/lower-server.js +288 -32
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.js +4 -4
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.js +37 -2
- 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 +10 -14
- package/dist/frontend/lowering/surfaces.js +50 -28
- package/dist/frontend/lowering/surfaces.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.js +7 -6
- package/dist/frontend/npm.js.map +1 -1
- package/dist/frontend/program.js +15 -4
- 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/type-mapper.js +16 -5
- package/dist/frontend/type-mapper.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +13 -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 +56 -35
- package/dist/ir/ir.js +9 -1
- package/dist/ir/ir.js.map +1 -1
- package/dist/ir/ir.test.js +6 -0
- 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/validate.js +135 -34
- package/dist/ir/validate.js.map +1 -1
- package/dist/ir/validate.test.d.ts +1 -0
- package/dist/ir/validate.test.js +48 -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/library-cache.js +0 -1
- package/dist/library/library-cache.js.map +1 -1
- package/dist/library/library-cache.test.js +3 -3
- package/dist/library/library-cache.test.js.map +1 -1
- package/package.json +17 -17
- package/surface-manifest.json +90 -45
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));
|
|
@@ -604,11 +604,36 @@ function emitLiteralExpr(emitter, e) {
|
|
|
604
604
|
}
|
|
605
605
|
}
|
|
606
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
|
+
}
|
|
607
626
|
function emitOperatorExpr(emitter, e) {
|
|
608
627
|
switch (e.kind) {
|
|
609
628
|
case "bin": {
|
|
610
629
|
const l = emitter.emitExpr(e.left);
|
|
611
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
|
+
}
|
|
612
637
|
switch (e.op) {
|
|
613
638
|
case "%":
|
|
614
639
|
return emitter.newTemp(e.type, `fmod(${l.name}, ${r.name})`);
|
|
@@ -639,7 +664,8 @@ function emitOperatorExpr(emitter, e) {
|
|
|
639
664
|
case "unary": {
|
|
640
665
|
const v = emitter.emitExpr(e.operand);
|
|
641
666
|
if (e.op === "~")
|
|
642
|
-
return emitter.
|
|
667
|
+
return emitter.integerRanges.get(e.operand)
|
|
668
|
+
? emitIntegerBits(emitter, e, v.name) : emitter.newTemp(e.type, `scr_bit_not(${v.name})`);
|
|
643
669
|
return emitter.newTemp(e.type, `${e.op}${v.name}`);
|
|
644
670
|
}
|
|
645
671
|
case "incDec": {
|
|
@@ -1233,9 +1259,13 @@ function emitStringExpr(emitter, e) {
|
|
|
1233
1259
|
}
|
|
1234
1260
|
return emitter.newTemp(e.type, `scr_str_includes(${r.name}, ${args[0].name})`);
|
|
1235
1261
|
case "startsWith":
|
|
1236
|
-
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})`);
|
|
1237
1265
|
case "endsWith":
|
|
1238
|
-
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})`);
|
|
1239
1269
|
case "slice":
|
|
1240
1270
|
return emitter.newTemp(e.type, `scr_str_slice(${r.name}, ${args[0]?.name ?? "0"}, ${args[1]?.name ?? "INFINITY"})`);
|
|
1241
1271
|
case "substring":
|
|
@@ -1447,7 +1477,11 @@ function emitContainerExpr(emitter, e) {
|
|
|
1447
1477
|
return emitter.newTemp(e.type, `scr_arr_state(${arr.name}, ${idx.name})`);
|
|
1448
1478
|
}
|
|
1449
1479
|
case "arrIntrinsic": {
|
|
1450
|
-
|
|
1480
|
+
// getNumber/indexEq produce scalars without invoking user code. A
|
|
1481
|
+
// stable binding can own its receiver until that lookup finishes.
|
|
1482
|
+
const r = e.method === "getNumber" || e.method === "indexEq"
|
|
1483
|
+
? emitStableReceiver(emitter, e.receiver, e.args)
|
|
1484
|
+
: emitter.emitExpr(e.receiver);
|
|
1451
1485
|
if (e.receiver.type.kind !== "array")
|
|
1452
1486
|
throw new InternalCompilerError("emitter bug: arrIntrinsic on non-array");
|
|
1453
1487
|
const acc = elemAccess(e.receiver.type.elem);
|
|
@@ -1455,10 +1489,21 @@ function emitContainerExpr(emitter, e) {
|
|
|
1455
1489
|
switch (method) {
|
|
1456
1490
|
case "length":
|
|
1457
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
|
+
}
|
|
1458
1497
|
case "nextPresent": {
|
|
1459
1498
|
const start = emitter.emitExpr(e.args[0]);
|
|
1460
1499
|
return emitter.newTemp(e.type, `scr_arr_next_present(${r.name}, ${start.name})`);
|
|
1461
1500
|
}
|
|
1501
|
+
case "indexEq": {
|
|
1502
|
+
const index = emitter.emitExpr(e.args[0]);
|
|
1503
|
+
const other = emitStableReceiver(emitter, e.args[1], [e.args[2]]);
|
|
1504
|
+
const otherIndex = emitter.emitExpr(e.args[2]);
|
|
1505
|
+
return emitter.newTemp(e.type, `scr_arr_index_eq(${r.name}, ${index.name}, ${other.name}, ${otherIndex.name})`);
|
|
1506
|
+
}
|
|
1462
1507
|
case "push": {
|
|
1463
1508
|
// Variadic like JS: every argument evaluates first (left to
|
|
1464
1509
|
// right — an argument reading the array sees the pre-push
|
|
@@ -1605,6 +1650,17 @@ function emitContainerExpr(emitter, e) {
|
|
|
1605
1650
|
const cnt = e.args[1] ? emitter.emitExpr(e.args[1]).name : "INFINITY";
|
|
1606
1651
|
return emitter.newTemp(e.type, `scr_arr_splice(${r.name}, ${start.name}, ${cnt})`);
|
|
1607
1652
|
}
|
|
1653
|
+
case "spliceInsert": {
|
|
1654
|
+
const start = emitter.emitExpr(e.args[0]);
|
|
1655
|
+
const count = emitter.emitExpr(e.args[1]);
|
|
1656
|
+
const items = emitter.emitExpr(e.args[2]);
|
|
1657
|
+
return emitter.newTemp(e.type, `scr_arr_splice_insert(${r.name}, ${start.name}, ${count.name}, ${items.name})`);
|
|
1658
|
+
}
|
|
1659
|
+
case "flatCopy":
|
|
1660
|
+
case "flatOne": {
|
|
1661
|
+
const out = emitter.emitExpr(e.args[0]);
|
|
1662
|
+
return emitter.newTemp(e.type, `scr_arr_flat_copy(${r.name}, ${out.name}, ${method === "flatOne" ? "true" : "false"})`);
|
|
1663
|
+
}
|
|
1608
1664
|
default: {
|
|
1609
1665
|
const _exhaustive = method;
|
|
1610
1666
|
void _exhaustive;
|
|
@@ -1677,7 +1733,7 @@ function emitContainerExpr(emitter, e) {
|
|
|
1677
1733
|
const method = e.method;
|
|
1678
1734
|
const directElementAccess = method === "length" || method === "byteLength" || method === "get";
|
|
1679
1735
|
const r = directElementAccess
|
|
1680
|
-
?
|
|
1736
|
+
? emitStableReceiver(emitter, e.receiver, e.args)
|
|
1681
1737
|
: emitter.emitExpr(e.receiver);
|
|
1682
1738
|
const integerIndex = method === "get" ? emitter.integerLoopIndex(e.args[0]) : null;
|
|
1683
1739
|
const args = integerIndex === null ? e.args.map((a) => emitter.emitExpr(a)) : [];
|
|
@@ -1688,7 +1744,7 @@ function emitContainerExpr(emitter, e) {
|
|
|
1688
1744
|
if (e.receiver.type.kind !== "bytes") {
|
|
1689
1745
|
throw new InternalCompilerError("emitter bug: bytesIntrinsic byteLength on non-bytes");
|
|
1690
1746
|
}
|
|
1691
|
-
return emitter.newTemp(e.type, `(double)(${r.name}->len * ${e.receiver.type.elem === "u8" ? "1" : "4"})`);
|
|
1747
|
+
return emitter.newTemp(e.type, `(double)(${r.name}->len * ${e.receiver.type.elem === "u8" ? "1" : e.receiver.type.elem === "f64" ? "8" : "4"})`);
|
|
1692
1748
|
case "get":
|
|
1693
1749
|
// Any invalid index traps (the array runtime's discipline).
|
|
1694
1750
|
if (e.receiver.type.kind !== "bytes") {
|
|
@@ -4010,6 +4066,8 @@ function emitDynamicLibCall(state) {
|
|
|
4010
4066
|
case "dyn.typeof":
|
|
4011
4067
|
// Bare typeof on a dyn value: the dyn kind's JS answer (+1).
|
|
4012
4068
|
return finish(`scr_dyn_typeof(${arg(0)})`);
|
|
4069
|
+
case "dyn.objectTag":
|
|
4070
|
+
return finish(`scr_dyn_object_tag(${arg(0)})`);
|
|
4013
4071
|
case "dyn.toString":
|
|
4014
4072
|
// Receiver-kind-dispatched toString (+1); throws Node's
|
|
4015
4073
|
// TypeError on undefined/null and the "is not a function"
|
|
@@ -4764,6 +4822,8 @@ function emitPrimitiveLibCall(state) {
|
|
|
4764
4822
|
return finish(`scr_math_max_arr(${arg(0)})`);
|
|
4765
4823
|
case "math.minArr":
|
|
4766
4824
|
return finish(`scr_math_min_arr(${arg(0)})`);
|
|
4825
|
+
case "math.hypotArr":
|
|
4826
|
+
return finish(`scr_math_hypot_arr(${arg(0)})`);
|
|
4767
4827
|
// Math.floor/trunc/ceil — the C functions ARE the JS operations
|
|
4768
4828
|
// (math.h is always included). Borrow nothing; no throw.
|
|
4769
4829
|
case "math.floor":
|
|
@@ -4772,6 +4832,38 @@ function emitPrimitiveLibCall(state) {
|
|
|
4772
4832
|
return finish(`trunc(${arg(0)})`);
|
|
4773
4833
|
case "math.ceil":
|
|
4774
4834
|
return finish(`ceil(${arg(0)})`);
|
|
4835
|
+
case "math.sin":
|
|
4836
|
+
return finish(`sin(${arg(0)})`);
|
|
4837
|
+
case "math.cos":
|
|
4838
|
+
return finish(`cos(${arg(0)})`);
|
|
4839
|
+
case "math.tan":
|
|
4840
|
+
return finish(`tan(${arg(0)})`);
|
|
4841
|
+
case "math.asin":
|
|
4842
|
+
return finish(`asin(${arg(0)})`);
|
|
4843
|
+
case "math.acos":
|
|
4844
|
+
return finish(`acos(${arg(0)})`);
|
|
4845
|
+
case "math.atan":
|
|
4846
|
+
return finish(`atan(${arg(0)})`);
|
|
4847
|
+
case "math.cbrt":
|
|
4848
|
+
return finish(`cbrt(${arg(0)})`);
|
|
4849
|
+
case "math.sign":
|
|
4850
|
+
// Each argument was evaluated into a temp. Returning that temp
|
|
4851
|
+
// for unordered/zero inputs preserves NaN and the sign of zero.
|
|
4852
|
+
return finish(`(${arg(0)} > 0.0 ? 1.0 : (${arg(0)} < 0.0 ? -1.0 : ${arg(0)}))`);
|
|
4853
|
+
case "math.exp":
|
|
4854
|
+
return finish(`exp(${arg(0)})`);
|
|
4855
|
+
case "math.sqrt":
|
|
4856
|
+
return finish(`sqrt(${arg(0)})`);
|
|
4857
|
+
case "math.log":
|
|
4858
|
+
return finish(`log(${arg(0)})`);
|
|
4859
|
+
case "math.log2":
|
|
4860
|
+
return finish(`log2(${arg(0)})`);
|
|
4861
|
+
case "math.log10":
|
|
4862
|
+
return finish(`log10(${arg(0)})`);
|
|
4863
|
+
case "math.atan2":
|
|
4864
|
+
return finish(`atan2(${arg(0)}, ${arg(1)})`);
|
|
4865
|
+
case "math.pow":
|
|
4866
|
+
return finish(`scr_math_pow(${arg(0)}, ${arg(1)})`);
|
|
4775
4867
|
// Math.abs — C fabs IS the JS operation. Math.round — the JS
|
|
4776
4868
|
// half-toward-+Infinity rule (scr_lib.c; C round() differs on
|
|
4777
4869
|
// halves and naive floor(x+0.5) drifts at the epsilon boundary).
|
|
@@ -5015,6 +5107,8 @@ function emitPrimitiveLibCall(state) {
|
|
|
5015
5107
|
: `scr_str_from_char_code(${arg(0)})`);
|
|
5016
5108
|
case "string.lastIndexOf":
|
|
5017
5109
|
return finish(`scr_str_last_index_of(${arg(0)}, ${arg(1)})`);
|
|
5110
|
+
case "string.lastIndexOfFrom":
|
|
5111
|
+
return finish(`scr_str_last_index_of_from(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
5018
5112
|
case "string.raw":
|
|
5019
5113
|
// Raw literals + pre-stringified substitutions; +1 string.
|
|
5020
5114
|
return finish(`scr_str_raw(${arg(0)}, ${arg(1)})`);
|
|
@@ -5521,6 +5615,8 @@ function emitNetworkLibCall(state) {
|
|
|
5521
5615
|
}
|
|
5522
5616
|
case "net.serverPort":
|
|
5523
5617
|
return finish(`scr_net_server_port(${arg(0)})`);
|
|
5618
|
+
case "net.serverListening":
|
|
5619
|
+
return finish(`scr_net_server_listening(${arg(0)})`);
|
|
5524
5620
|
case "net.serverAddress": {
|
|
5525
5621
|
// The AddressInfo record from the three runtime reads (the
|
|
5526
5622
|
// dgram.address materialization; none of these throw).
|
|
@@ -5598,9 +5694,7 @@ function emitNetworkLibCall(state) {
|
|
|
5598
5694
|
const cb = args[1];
|
|
5599
5695
|
emitter.moveTemp(cb);
|
|
5600
5696
|
const adapter = cbT.params.length === 0 ? "scr_net_conn_thunk0" : "scr_net_conn_thunk_sock";
|
|
5601
|
-
const entry = e.fn === "net.serverOnConnection"
|
|
5602
|
-
? "scr_net_server_on_connection"
|
|
5603
|
-
: "scr_net_server_on_secure_connection";
|
|
5697
|
+
const entry = e.fn === "net.serverOnConnection" ? "scr_net_server_on_connection" : "scr_net_server_on_secure_connection";
|
|
5604
5698
|
emitter.line(`${entry}(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
5605
5699
|
return { name: "", type: e.type };
|
|
5606
5700
|
}
|
|
@@ -6058,10 +6152,22 @@ function emitHttpLibCall(state) {
|
|
|
6058
6152
|
case "http.resSetHeader":
|
|
6059
6153
|
emitter.line(`scr_http_res_set_header(${arg(0)}, ${arg(1)}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
6060
6154
|
return { name: "", type: e.type };
|
|
6155
|
+
case "http.validateHeaderName":
|
|
6156
|
+
emitter.line(`scr_http_validate_header_name(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6157
|
+
return { name: "", type: e.type };
|
|
6158
|
+
case "http.validateHeaderValue":
|
|
6159
|
+
emitter.line(`scr_http_validate_header_value(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6160
|
+
return { name: "", type: e.type };
|
|
6061
6161
|
case "http.resWriteHead":
|
|
6062
6162
|
return finish(`scr_http_res_write_head(${arg(0)}, ${arg(1)})`);
|
|
6063
6163
|
case "http.resWriteHeadN":
|
|
6064
6164
|
return finish(`scr_http_res_write_head_n(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
|
|
6165
|
+
case "http.resWriteContinue":
|
|
6166
|
+
return finish(`scr_http_res_write_continue(${arg(0)})`);
|
|
6167
|
+
case "http.resWriteProcessing":
|
|
6168
|
+
return finish(`scr_http_res_write_processing(${arg(0)})`);
|
|
6169
|
+
case "http.resWriteEarlyHints":
|
|
6170
|
+
return finish(`scr_http_res_write_early_hints(${arg(0)}, ${arg(1)})`);
|
|
6065
6171
|
case "http.resWrite":
|
|
6066
6172
|
return finish(`scr_http_res_write_str(${arg(0)}, ${arg(1)})`);
|
|
6067
6173
|
case "http.resWriteBytes":
|
|
@@ -6078,6 +6184,8 @@ function emitHttpLibCall(state) {
|
|
|
6078
6184
|
return finish(`scr_http_res_end_dynv(${arg(0)}, ${arg(1)})`);
|
|
6079
6185
|
case "http.resHeadersSent":
|
|
6080
6186
|
return finish(`scr_http_res_headers_sent(${arg(0)})`);
|
|
6187
|
+
case "http.resWritableEnded":
|
|
6188
|
+
return finish(`scr_http_res_writable_ended(${arg(0)})`);
|
|
6081
6189
|
case "http.resFlushHeaders":
|
|
6082
6190
|
return finish(`scr_http_res_flush_headers(${arg(0)})`);
|
|
6083
6191
|
case "http.resAddTrailers":
|
|
@@ -6245,6 +6353,32 @@ function emitHttpLibCall(state) {
|
|
|
6245
6353
|
case "http.serverAllowMissingHostHeader":
|
|
6246
6354
|
emitter.line(`scr_http_server_allow_missing_host_header(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6247
6355
|
return { name: "", type: e.type };
|
|
6356
|
+
case "http.serverSetTimeout":
|
|
6357
|
+
emitter.line(`scr_net_server_set_timeout_plain(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6358
|
+
return { name: "", type: e.type };
|
|
6359
|
+
case "http.serverCloseAllConnections":
|
|
6360
|
+
case "http.serverCloseIdleConnections": {
|
|
6361
|
+
const entry = e.fn === "http.serverCloseAllConnections"
|
|
6362
|
+
? "scr_net_server_close_all_connections" : "scr_net_server_close_idle_connections";
|
|
6363
|
+
emitter.line(`${entry}(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6364
|
+
return { name: "", type: e.type };
|
|
6365
|
+
}
|
|
6366
|
+
case "http.serverOnTimeout":
|
|
6367
|
+
case "http.serverSetTimeoutCb": {
|
|
6368
|
+
const cbIndex = e.fn === "http.serverSetTimeoutCb" ? 2 : 1;
|
|
6369
|
+
const cbT = e.args[cbIndex].type;
|
|
6370
|
+
if (cbT.kind !== "func")
|
|
6371
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} callback not a func`);
|
|
6372
|
+
const cb = args[cbIndex];
|
|
6373
|
+
emitter.moveTemp(cb);
|
|
6374
|
+
const adapter = cbT.params.length === 0 ? "scr_net_conn_thunk0" : "scr_net_conn_thunk_sock";
|
|
6375
|
+
const entry = e.fn === "http.serverOnTimeout" ? "scr_net_server_on_timeout" : "scr_net_server_set_timeout_cb";
|
|
6376
|
+
const callArgs = e.fn === "http.serverOnTimeout"
|
|
6377
|
+
? `${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)}`
|
|
6378
|
+
: `${arg(0)}, ${arg(1)}, ${cb.name}, &${adapter}`;
|
|
6379
|
+
emitter.line(`${entry}(${callArgs});${emitter.srcComment(e.loc)}`);
|
|
6380
|
+
return { name: "", type: e.type };
|
|
6381
|
+
}
|
|
6248
6382
|
case "http.serverTimeoutGet":
|
|
6249
6383
|
return finish(`scr_net_server_timeout_get(${arg(0)}, ${arg(1)})`);
|
|
6250
6384
|
case "http.serverTimeoutSet":
|
|
@@ -6257,27 +6391,82 @@ function emitHttpLibCall(state) {
|
|
|
6257
6391
|
case "http.resStatusSet":
|
|
6258
6392
|
emitter.line(`scr_http_res_status_set(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6259
6393
|
return { name: "", type: e.type };
|
|
6260
|
-
case "http.resStatusMsgGet":
|
|
6261
|
-
|
|
6394
|
+
case "http.resStatusMsgGet": {
|
|
6395
|
+
if (e.type.kind !== "union")
|
|
6396
|
+
throw new InternalCompilerError("emitter bug: http.resStatusMsgGet result is not a union");
|
|
6397
|
+
const def = emitter.unionsById.get(e.type.unionId);
|
|
6398
|
+
const strTag = def ? def.arms.findIndex((a) => a.kind === "string") : -1;
|
|
6399
|
+
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
6400
|
+
if (strTag < 0 || undefTag < 0)
|
|
6401
|
+
throw new InternalCompilerError("emitter bug: http.resStatusMsgGet union lacks its arms");
|
|
6402
|
+
const msg = emitter.newTemp(STRING, `scr_http_res_status_msg_get(${arg(0)})`);
|
|
6403
|
+
emitter.moveTemp(msg);
|
|
6404
|
+
const present = `scr_union_new_ref(${strTag}, ${msg.name}, &scr_str_retain_v, &scr_str_release_v, NULL)`;
|
|
6405
|
+
return emitter.newTemp(e.type, `${msg.name} ? ${present} : ${emitter.unitInstanceRef(e.type.unionId, undefTag)}`);
|
|
6406
|
+
}
|
|
6262
6407
|
case "http.resStatusMsgSet":
|
|
6263
6408
|
emitter.line(`scr_http_res_status_msg_set(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6264
6409
|
return { name: "", type: e.type };
|
|
6265
|
-
case "http.
|
|
6410
|
+
case "http.resRequest":
|
|
6411
|
+
return finish(`scr_http_res_request(${arg(0)})`);
|
|
6412
|
+
case "http.resSocket": {
|
|
6413
|
+
if (e.type.kind !== "union")
|
|
6414
|
+
throw new InternalCompilerError("emitter bug: http.resSocket result is not a union");
|
|
6415
|
+
const def = emitter.unionsById.get(e.type.unionId);
|
|
6416
|
+
const socketTag = def ? def.arms.findIndex((a) => a.kind === "netSocket") : -1;
|
|
6417
|
+
const nullTag = def ? def.arms.findIndex((a) => a.kind === "nullT") : -1;
|
|
6418
|
+
if (socketTag < 0 || nullTag < 0)
|
|
6419
|
+
throw new InternalCompilerError("emitter bug: http.resSocket union lacks its arms");
|
|
6420
|
+
const sock = emitter.newTemp(NETSOCKET_T, `scr_http_res_socket(${arg(0)})`);
|
|
6421
|
+
emitter.moveTemp(sock);
|
|
6422
|
+
const present = `scr_union_new_ref(${socketTag}, ${sock.name}, &scr_net_sock_retain_v, &scr_net_sock_release_v, NULL)`;
|
|
6423
|
+
return emitter.newTemp(e.type, `${sock.name} ? ${present} : ${emitter.unitInstanceRef(e.type.unionId, nullTag)}`);
|
|
6424
|
+
}
|
|
6425
|
+
case "http.resWritableFinished":
|
|
6426
|
+
return finish(`scr_http_res_writable_finished(${arg(0)})`);
|
|
6427
|
+
case "http.resSendDateGet":
|
|
6428
|
+
return finish(`scr_http_res_send_date(${arg(0)})`);
|
|
6429
|
+
case "http.resSendDateSet":
|
|
6430
|
+
emitter.line(`scr_http_res_set_send_date(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6431
|
+
return { name: "", type: e.type };
|
|
6432
|
+
case "http.resStrictContentLengthGet":
|
|
6433
|
+
return finish(`scr_http_res_strict_content_length(${arg(0)})`);
|
|
6434
|
+
case "http.resStrictContentLengthSet":
|
|
6435
|
+
emitter.line(`scr_http_res_set_strict_content_length(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6436
|
+
return { name: "", type: e.type };
|
|
6437
|
+
case "http.resSetTimeout":
|
|
6438
|
+
emitter.line(`scr_http_res_set_timeout_plain(${arg(0)}, ${arg(1)});${emitter.srcComment(e.loc)}`);
|
|
6439
|
+
return { name: "", type: e.type };
|
|
6440
|
+
case "http.resSetTimeoutCb": {
|
|
6441
|
+
const cb = args[2];
|
|
6442
|
+
emitter.moveTemp(cb);
|
|
6443
|
+
emitter.line(`scr_http_res_set_timeout(${arg(0)}, ${arg(1)}, ${cb.name});${emitter.srcComment(e.loc)}`);
|
|
6444
|
+
return { name: "", type: e.type };
|
|
6445
|
+
}
|
|
6446
|
+
case "http.resGetHeader":
|
|
6447
|
+
case "http.clientGetHeader": {
|
|
6266
6448
|
// string|undefined, exactly the http.reqHeader emission.
|
|
6267
6449
|
if (e.type.kind !== "union")
|
|
6268
|
-
throw new InternalCompilerError(
|
|
6450
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} result is not a union`);
|
|
6269
6451
|
const def = emitter.unionsById.get(e.type.unionId);
|
|
6270
6452
|
const strTag = def ? def.arms.findIndex((a) => a.kind === "string") : -1;
|
|
6271
6453
|
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
6272
6454
|
if (strTag < 0 || undefTag < 0) {
|
|
6273
6455
|
throw new InternalCompilerError("emitter bug: http.resGetHeader union lacks its arms");
|
|
6274
6456
|
}
|
|
6275
|
-
const
|
|
6457
|
+
const entry = e.fn === "http.resGetHeader" ? "scr_http_res_get_header" : "scr_http_client_get_header";
|
|
6458
|
+
const s = emitter.newTemp(STRING, `${entry}(${arg(0)}, ${arg(1)})`);
|
|
6276
6459
|
emitter.moveTemp(s); // moves into the box when present; NULL otherwise
|
|
6277
6460
|
const present = `scr_union_new_ref(${strTag}, ${s.name}, &scr_str_retain_v, &scr_str_release_v, NULL)`;
|
|
6278
6461
|
const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
|
|
6279
6462
|
return emitter.newTemp(e.type, `${s.name} ? ${present} : ${absent}`);
|
|
6280
6463
|
}
|
|
6464
|
+
case "http.resGetHeaderNames":
|
|
6465
|
+
return finish(`scr_http_res_get_header_names(${arg(0)})`);
|
|
6466
|
+
case "http.resGetRawHeaderNames":
|
|
6467
|
+
return finish(`scr_http_res_get_raw_header_names(${arg(0)})`);
|
|
6468
|
+
case "http.resGetHeaders":
|
|
6469
|
+
return finish(`scr_http_res_get_headers(${arg(0)})`);
|
|
6281
6470
|
case "http.resHasHeader":
|
|
6282
6471
|
return finish(`scr_http_res_has_header_named(${arg(0)}, ${arg(1)})`);
|
|
6283
6472
|
case "http.resRemoveHeader":
|
|
@@ -6295,6 +6484,14 @@ function emitHttpLibCall(state) {
|
|
|
6295
6484
|
return finish(`scr_http_res_write_head_dyn(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6296
6485
|
case "http.reqSetEncoding":
|
|
6297
6486
|
return finish(`scr_http_req_set_encoding(${arg(0)}, ${arg(1)})`);
|
|
6487
|
+
case "http.reqSetTimeout":
|
|
6488
|
+
return finish(`scr_http_req_set_timeout_plain(${arg(0)}, ${arg(1)})`);
|
|
6489
|
+
case "http.reqSetTimeoutCb": {
|
|
6490
|
+
const cb = args[2];
|
|
6491
|
+
emitter.moveTemp(cb);
|
|
6492
|
+
emitter.line(`scr_http_req_set_timeout(${arg(0)}, ${arg(1)}, ${cb.name});${emitter.srcComment(e.loc)}`);
|
|
6493
|
+
return { name: "", type: e.type };
|
|
6494
|
+
}
|
|
6298
6495
|
// node:http, the client slice (scr_http.c over the net client).
|
|
6299
6496
|
case "http.request":
|
|
6300
6497
|
case "http.requestCb": {
|
|
@@ -6464,6 +6661,18 @@ function emitHttpLibCall(state) {
|
|
|
6464
6661
|
}
|
|
6465
6662
|
case "http.clientWrite":
|
|
6466
6663
|
return finish(`scr_http_client_write_str(${arg(0)}, ${arg(1)})`);
|
|
6664
|
+
case "http.clientSetHeader":
|
|
6665
|
+
return finish(`scr_http_client_set_header(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6666
|
+
case "http.clientHasHeader":
|
|
6667
|
+
return finish(`scr_http_client_has_header_named(${arg(0)}, ${arg(1)})`);
|
|
6668
|
+
case "http.clientRemoveHeader":
|
|
6669
|
+
return finish(`scr_http_client_remove_header(${arg(0)}, ${arg(1)})`);
|
|
6670
|
+
case "http.clientGetHeaderNames":
|
|
6671
|
+
return finish(`scr_http_client_get_header_names(${arg(0)})`);
|
|
6672
|
+
case "http.clientGetRawHeaderNames":
|
|
6673
|
+
return finish(`scr_http_client_get_raw_header_names(${arg(0)})`);
|
|
6674
|
+
case "http.clientGetHeaders":
|
|
6675
|
+
return finish(`scr_http_client_get_headers(${arg(0)})`);
|
|
6467
6676
|
case "http.clientWriteBytes":
|
|
6468
6677
|
return finish(`scr_http_client_write_bytes(${arg(0)}, ${arg(1)})`);
|
|
6469
6678
|
case "http.clientEnd":
|
|
@@ -6487,9 +6696,48 @@ function emitHttpLibCall(state) {
|
|
|
6487
6696
|
return finish(`scr_http_client_uncork(${arg(0)})`);
|
|
6488
6697
|
case "http.clientWritableCorked":
|
|
6489
6698
|
return finish(`scr_http_client_writable_corked(${arg(0)})`);
|
|
6699
|
+
case "http.clientMethod":
|
|
6700
|
+
return finish(`scr_http_client_method(${arg(0)})`);
|
|
6701
|
+
case "http.clientPath":
|
|
6702
|
+
return finish(`scr_http_client_path(${arg(0)})`);
|
|
6703
|
+
case "http.clientHost":
|
|
6704
|
+
return finish(`scr_http_client_host(${arg(0)})`);
|
|
6705
|
+
case "http.clientProtocol":
|
|
6706
|
+
return finish(`scr_http_client_protocol(${arg(0)})`);
|
|
6707
|
+
case "http.clientHeadersSent":
|
|
6708
|
+
return finish(`scr_http_client_headers_sent(${arg(0)})`);
|
|
6709
|
+
case "http.clientWritableEnded":
|
|
6710
|
+
return finish(`scr_http_client_writable_ended(${arg(0)})`);
|
|
6711
|
+
case "http.clientWritableFinished":
|
|
6712
|
+
return finish(`scr_http_client_writable_finished(${arg(0)})`);
|
|
6713
|
+
case "http.clientSocket":
|
|
6714
|
+
return finish(`scr_http_client_socket(${arg(0)})`);
|
|
6715
|
+
case "http.clientReusedSocket":
|
|
6716
|
+
return finish(`scr_http_client_reused_socket(${arg(0)})`);
|
|
6717
|
+
case "http.clientSetNoDelay":
|
|
6718
|
+
return finish(`scr_http_client_set_nodelay(${arg(0)}, ${arg(1)})`);
|
|
6719
|
+
case "http.clientSetSocketKeepAlive":
|
|
6720
|
+
return finish(`scr_http_client_set_socket_keepalive(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6721
|
+
case "http.clientSetTimeout":
|
|
6722
|
+
return finish(`scr_http_client_set_timeout(${arg(0)}, ${arg(1)})`);
|
|
6723
|
+
case "http.clientSetTimeoutCb": {
|
|
6724
|
+
const cb = args[2];
|
|
6725
|
+
emitter.moveTemp(cb);
|
|
6726
|
+
emitter.line(`scr_http_client_set_timeout_cb(${arg(0)}, ${arg(1)}, ${cb.name});${emitter.srcComment(e.loc)}`);
|
|
6727
|
+
return { name: "", type: e.type };
|
|
6728
|
+
}
|
|
6729
|
+
case "http.statusCodes":
|
|
6730
|
+
return finish("scr_http_status_codes()");
|
|
6731
|
+
case "http.methods":
|
|
6732
|
+
return finish("scr_http_methods()");
|
|
6490
6733
|
case "http.clientDestroy":
|
|
6491
6734
|
emitter.line(`scr_http_client_destroy(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6492
6735
|
return { name: "", type: e.type };
|
|
6736
|
+
case "http.clientAbort":
|
|
6737
|
+
emitter.line(`scr_http_client_abort(${arg(0)});${emitter.srcComment(e.loc)}`);
|
|
6738
|
+
return { name: "", type: e.type };
|
|
6739
|
+
case "http.clientAborted":
|
|
6740
|
+
return finish(`scr_http_client_aborted(${arg(0)})`);
|
|
6493
6741
|
case "http.clientDestroyed":
|
|
6494
6742
|
return finish(`scr_http_client_destroyed(${arg(0)})`);
|
|
6495
6743
|
case "http.clientOnResponse": {
|
|
@@ -6502,6 +6750,16 @@ function emitHttpLibCall(state) {
|
|
|
6502
6750
|
emitter.line(`scr_http_client_on_response(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
6503
6751
|
return { name: "", type: e.type };
|
|
6504
6752
|
}
|
|
6753
|
+
case "http.clientOnSocket": {
|
|
6754
|
+
const cbT = e.args[1].type;
|
|
6755
|
+
if (cbT.kind !== "func")
|
|
6756
|
+
throw new InternalCompilerError("emitter bug: http.clientOnSocket callback not a func");
|
|
6757
|
+
const cb = args[1];
|
|
6758
|
+
emitter.moveTemp(cb);
|
|
6759
|
+
const adapter = cbT.params.length === 0 ? "scr_net_conn_thunk0" : "scr_net_conn_thunk_sock";
|
|
6760
|
+
emitter.line(`scr_http_client_on_socket(${arg(0)}, ${cb.name}, &${adapter}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
6761
|
+
return { name: "", type: e.type };
|
|
6762
|
+
}
|
|
6505
6763
|
case "http.clientOnError": {
|
|
6506
6764
|
const cbT = e.args[1].type;
|
|
6507
6765
|
if (cbT.kind !== "func")
|
|
@@ -6513,10 +6771,14 @@ function emitHttpLibCall(state) {
|
|
|
6513
6771
|
return { name: "", type: e.type };
|
|
6514
6772
|
}
|
|
6515
6773
|
case "http.clientOnTimeout":
|
|
6516
|
-
case "http.clientOnClose":
|
|
6774
|
+
case "http.clientOnClose":
|
|
6775
|
+
case "http.clientOnFinish":
|
|
6776
|
+
case "http.clientOnAbort": {
|
|
6517
6777
|
const cb = args[1];
|
|
6518
6778
|
emitter.moveTemp(cb);
|
|
6519
|
-
const fn = e.fn === "http.clientOnTimeout" ? "scr_http_client_on_timeout"
|
|
6779
|
+
const fn = e.fn === "http.clientOnTimeout" ? "scr_http_client_on_timeout"
|
|
6780
|
+
: e.fn === "http.clientOnClose" ? "scr_http_client_on_close"
|
|
6781
|
+
: e.fn === "http.clientOnAbort" ? "scr_http_client_on_abort" : "scr_http_client_on_finish";
|
|
6520
6782
|
emitter.line(`${fn}(${arg(0)}, ${cb.name}, ${arg(2)});${emitter.srcComment(e.loc)}`);
|
|
6521
6783
|
return { name: "", type: e.type };
|
|
6522
6784
|
}
|
|
@@ -7438,22 +7700,23 @@ function emitProcessLibCall(state) {
|
|
|
7438
7700
|
return finish(`scr_stdin_next_chunk()`);
|
|
7439
7701
|
case "process.isTTY":
|
|
7440
7702
|
return finish(`scr_process_is_tty(${arg(0)})`);
|
|
7441
|
-
case "process.columns":
|
|
7442
|
-
|
|
7703
|
+
case "process.columns":
|
|
7704
|
+
case "process.rows": {
|
|
7705
|
+
// ioctl(TIOCGWINSZ): a non-negative dimension wraps the f64 arm;
|
|
7443
7706
|
// a non-TTY stream (or an ioctl refusal) comes back negative
|
|
7444
7707
|
// and yields the interned undefined-arm instance — Node's
|
|
7445
|
-
// missing
|
|
7708
|
+
// missing geometry. Type-directed union construction, like
|
|
7446
7709
|
// process.envGet.
|
|
7447
7710
|
if (e.type.kind !== "union") {
|
|
7448
|
-
throw new InternalCompilerError(
|
|
7711
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} result is not a union`);
|
|
7449
7712
|
}
|
|
7450
7713
|
const def = emitter.unionsById.get(e.type.unionId);
|
|
7451
7714
|
const f64Tag = def ? def.arms.findIndex((a) => a.kind === "f64") : -1;
|
|
7452
7715
|
const undefTag = undefinedArmTag(e.type, emitter.unionsById);
|
|
7453
7716
|
if (f64Tag < 0 || undefTag < 0) {
|
|
7454
|
-
throw new InternalCompilerError(
|
|
7717
|
+
throw new InternalCompilerError(`emitter bug: ${e.fn} union lacks its arms`);
|
|
7455
7718
|
}
|
|
7456
|
-
const w = emitter.newTemp(F64, `
|
|
7719
|
+
const w = emitter.newTemp(F64, `scr_process_${e.fn === "process.rows" ? "rows" : "columns"}(${arg(0)})`);
|
|
7457
7720
|
const present = `scr_union_new_f64(${f64Tag}, ${w.name})`;
|
|
7458
7721
|
const absent = emitter.unitInstanceRef(e.type.unionId, undefTag);
|
|
7459
7722
|
return emitter.newTemp(e.type, `${w.name} >= 0 ? ${present} : ${absent}`);
|
|
@@ -8291,6 +8554,14 @@ function emitIoLibCall(state) {
|
|
|
8291
8554
|
}
|
|
8292
8555
|
}
|
|
8293
8556
|
function emitLibCallExpr(emitter, e) {
|
|
8557
|
+
const packed = e.args[0];
|
|
8558
|
+
if (e.fn === "string.fromCharCode" && packed?.kind === "arrayLit" &&
|
|
8559
|
+
packed.elems.length === 1 && !packed.spreads?.length) {
|
|
8560
|
+
// The literal is only the variadic ABI pack, never an observable
|
|
8561
|
+
// array. Evaluate the scalar once before bypassing that allocation.
|
|
8562
|
+
const code = emitter.emitExpr(packed.elems[0]);
|
|
8563
|
+
return emitter.newTemp(e.type, `scr_str_from_char_code_one(${code.name})`);
|
|
8564
|
+
}
|
|
8294
8565
|
// Standard-library call. Args are BORROWED (owned temps of the
|
|
8295
8566
|
// current frame, released at statement end); refcounted results come
|
|
8296
8567
|
// back +1 (process.argv: +1 on the runtime's ONE interned array —
|