@scriptc/compiler 0.0.22 → 0.0.24
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 +139 -14
- package/dist/backend/cc.d.ts +13 -0
- package/dist/backend/cc.js +11 -0
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-async.d.ts +4 -0
- package/dist/backend/emission/emit-async.js +34 -2
- package/dist/backend/emission/emit-async.js.map +1 -1
- package/dist/backend/emission/emit-exprs.d.ts +10 -0
- package/dist/backend/emission/emit-exprs.js +272 -22
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emit-shapes.js +1 -0
- package/dist/backend/emission/emit-shapes.js.map +1 -1
- package/dist/backend/emission/emit-stmts.js +36 -9
- package/dist/backend/emission/emit-stmts.js.map +1 -1
- package/dist/backend/emission/emit-types.js +14 -1
- package/dist/backend/emission/emit-types.js.map +1 -1
- package/dist/backend/emission/emitter.d.ts +19 -1
- package/dist/backend/emission/emitter.js +81 -2
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/llvm/emitter.js +578 -36
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/backend/llvm/shapes.js +12 -3
- package/dist/backend/llvm/shapes.js.map +1 -1
- package/dist/backend/mangle.d.ts +3 -0
- package/dist/backend/mangle.js +5 -0
- package/dist/backend/mangle.js.map +1 -1
- package/dist/compat/fetch-profile.d.ts +10 -0
- package/dist/compat/fetch-profile.js +55 -6
- package/dist/compat/fetch-profile.js.map +1 -1
- package/dist/coverage/surface-manifest.js +16 -1
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/diagnostics/diagnostic.d.ts +10 -0
- package/dist/diagnostics/diagnostic.js +27 -1
- package/dist/diagnostics/diagnostic.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.d.ts +17 -16
- package/dist/frontend/lowering/lower-builtins.js +817 -117
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.js +3 -1
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-classes.js +28 -8
- package/dist/frontend/lowering/lower-classes.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +2 -1
- package/dist/frontend/lowering/lower-containers.js +99 -32
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.d.ts +1 -1
- package/dist/frontend/lowering/lower-exprs.js +78 -6
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-generators.js +7 -1
- package/dist/frontend/lowering/lower-generators.js.map +1 -1
- package/dist/frontend/lowering/lower-inspect.js +59 -1
- package/dist/frontend/lowering/lower-inspect.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +21 -0
- package/dist/frontend/lowering/lower-island.js +284 -10
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-server.d.ts +5 -0
- package/dist/frontend/lowering/lower-server.js +1 -1
- package/dist/frontend/lowering/lower-server.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +6 -2
- package/dist/frontend/lowering/lower-stmts.js +53 -14
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +3 -2
- package/dist/frontend/lowering/lowerer.js +17 -8
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.js +108 -25
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/program.d.ts +4 -4
- package/dist/frontend/program.js +264 -46
- package/dist/frontend/program.js.map +1 -1
- package/dist/frontend/resolve.d.ts +10 -0
- package/dist/frontend/resolve.js +37 -0
- package/dist/frontend/resolve.js.map +1 -1
- package/dist/frontend/ts7/enums.d.ts +9 -0
- package/dist/frontend/ts7/enums.js +8 -6
- package/dist/frontend/ts7/enums.js.map +1 -1
- package/dist/frontend/ts7/program.js +4 -1
- package/dist/frontend/ts7/program.js.map +1 -1
- package/dist/frontend/types.d.ts +7 -4
- package/dist/frontend/types.js +103 -8
- package/dist/frontend/types.js.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/ir/integer-loops.d.ts +23 -0
- package/dist/ir/integer-loops.js +82 -0
- package/dist/ir/integer-loops.js.map +1 -0
- package/dist/ir/nodes.d.ts +104 -28
- package/dist/ir/nodes.js +89 -1
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/validate.js +136 -25
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/fence-eval.js +4 -3
- package/dist/library/fence-eval.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +186 -29
|
@@ -287,6 +287,59 @@ function dynPromiseAdapter(E, inner) {
|
|
|
287
287
|
E.walkerDefs.push(`${sig} { /* checked-dynamic promise exit ${key} */`, ` ScrDyn *sc_d = (ScrDyn *)scr_promise_payload_ref(sc_src);`, ` ${cDecl(inner, "sc_v")} = ${E.dynCheckHelper(inner)}(sc_d, NULL);`, ` scr_dyn_release(sc_d);`, ` if (scr_exc_pending()) {`, ` scr_promise_reject_pending(sc_dst);`, ` return;`, ` }`, ` ${fulfill}`, `}`, ``);
|
|
288
288
|
return sym;
|
|
289
289
|
}
|
|
290
|
+
/** True when evaluating an index/value expression cannot overwrite the bytes
|
|
291
|
+
* receiver binding. This deliberately small whitelist enables borrowed
|
|
292
|
+
* receivers in typed-array hot loops while side-effecting/calling shapes
|
|
293
|
+
* retain the full snapshot ownership required by JS evaluation order. */
|
|
294
|
+
export function isStableBytesOperand(e, receiverLocalId) {
|
|
295
|
+
switch (e.kind) {
|
|
296
|
+
case "numLit":
|
|
297
|
+
case "boolLit":
|
|
298
|
+
case "varRef":
|
|
299
|
+
case "incDec":
|
|
300
|
+
return true;
|
|
301
|
+
case "assignExpr":
|
|
302
|
+
// An assignment nested under truthiness/ternary can still produce the
|
|
303
|
+
// numeric index/value while overwriting the bytes-typed receiver.
|
|
304
|
+
return e.localId !== receiverLocalId && isStableBytesOperand(e.value, receiverLocalId);
|
|
305
|
+
case "bin":
|
|
306
|
+
return (isStableBytesOperand(e.left, receiverLocalId) &&
|
|
307
|
+
isStableBytesOperand(e.right, receiverLocalId));
|
|
308
|
+
case "unary":
|
|
309
|
+
case "toBool":
|
|
310
|
+
return isStableBytesOperand(e.operand, receiverLocalId);
|
|
311
|
+
case "logical":
|
|
312
|
+
return (isStableBytesOperand(e.left, receiverLocalId) &&
|
|
313
|
+
isStableBytesOperand(e.right, receiverLocalId));
|
|
314
|
+
case "ternary":
|
|
315
|
+
return (isStableBytesOperand(e.cond, receiverLocalId) &&
|
|
316
|
+
isStableBytesOperand(e.then, receiverLocalId) &&
|
|
317
|
+
isStableBytesOperand(e.else_, receiverLocalId));
|
|
318
|
+
case "bytesIntrinsic":
|
|
319
|
+
return ((e.method === "get" || e.method === "length" || e.method === "byteLength") &&
|
|
320
|
+
e.receiver.kind === "varRef" &&
|
|
321
|
+
e.args.every((arg) => isStableBytesOperand(arg, receiverLocalId)));
|
|
322
|
+
default:
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/** Evaluate a bytes receiver as a borrow when it is a direct, unboxed
|
|
327
|
+
* binding and all later operands are stable. The binding's scope/global
|
|
328
|
+
* owner then keeps the value alive, avoiding retain/release traffic around
|
|
329
|
+
* every indexed access. Any uncertain shape falls back to an owned temp. */
|
|
330
|
+
export function emitBytesReceiver(E, receiver, following) {
|
|
331
|
+
if (receiver.kind === "varRef" &&
|
|
332
|
+
following.every((operand) => isStableBytesOperand(operand, receiver.localId))) {
|
|
333
|
+
const local = E.currentLocals.get(receiver.localId);
|
|
334
|
+
if (local && !local.boxed) {
|
|
335
|
+
return E.newBorrowedTemp(receiver.type, mangleLocal(receiver.localId));
|
|
336
|
+
}
|
|
337
|
+
if (!local && E.globalsById.has(receiver.localId)) {
|
|
338
|
+
return E.newBorrowedTemp(receiver.type, mangleGlobal(receiver.localId));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return E.emitExpr(receiver);
|
|
342
|
+
}
|
|
290
343
|
export function emitExpr(E, e) {
|
|
291
344
|
switch (e.kind) {
|
|
292
345
|
case "numLit":
|
|
@@ -302,6 +355,9 @@ export function emitExpr(E, e) {
|
|
|
302
355
|
// tag-only); one reaching the generic dispatch escaped its wrap.
|
|
303
356
|
throw new Error(`emitter bug: bare unitLit '${e.unit}'`);
|
|
304
357
|
case "varRef": {
|
|
358
|
+
const integerLoopIndex = E.integerLoopIndex(e);
|
|
359
|
+
if (integerLoopIndex !== null)
|
|
360
|
+
return E.newTemp(e.type, `(double)${integerLoopIndex}`);
|
|
305
361
|
const local = E.currentLocals.get(e.localId);
|
|
306
362
|
if (!local && E.globalsById.has(e.localId)) {
|
|
307
363
|
const gname = mangleGlobal(e.localId);
|
|
@@ -932,7 +988,7 @@ export function emitExpr(E, e) {
|
|
|
932
988
|
case "trimEnd":
|
|
933
989
|
return E.newTemp(e.type, `scr_str_trim_end(${r.name})`);
|
|
934
990
|
case "split":
|
|
935
|
-
return E.newTemp(e.type, `
|
|
991
|
+
return E.newTemp(e.type, `scr_str_split_limit(${r.name}, ${args[0].name}, ${args[1].name})`);
|
|
936
992
|
case "padStart":
|
|
937
993
|
return E.newTemp(e.type, `scr_str_pad_start(${r.name}, ${args[0].name}, ${args[1].name})`);
|
|
938
994
|
case "padEnd":
|
|
@@ -1035,7 +1091,7 @@ export function emitExpr(E, e) {
|
|
|
1035
1091
|
case "replaceAll":
|
|
1036
1092
|
return E.fallibleTemp(e.type, `scr_regex_replace_all(${r.name}, ${args[0].name}, ${args[1].name})`);
|
|
1037
1093
|
case "split":
|
|
1038
|
-
return E.fallibleTemp(e.type, `
|
|
1094
|
+
return E.fallibleTemp(e.type, `scr_regex_split_limit(${r.name}, ${args[0].name}, ${args[1].name})`);
|
|
1039
1095
|
default: {
|
|
1040
1096
|
const _exhaustive = method;
|
|
1041
1097
|
void _exhaustive;
|
|
@@ -1152,6 +1208,25 @@ export function emitExpr(E, e) {
|
|
|
1152
1208
|
E.line(`}`);
|
|
1153
1209
|
return E.newTemp(e.type, `scr_arr_len(${r.name})`);
|
|
1154
1210
|
}
|
|
1211
|
+
case "unshift": {
|
|
1212
|
+
// Like push, every argument evaluates before mutation. Apply
|
|
1213
|
+
// them from right to left so their final front order remains
|
|
1214
|
+
// the source order. Ref ownership moves into the array.
|
|
1215
|
+
const vs = e.args.map((a) => E.emitExpr(a));
|
|
1216
|
+
if (acc === "ref")
|
|
1217
|
+
vs.forEach((v) => E.moveTemp(v));
|
|
1218
|
+
let last;
|
|
1219
|
+
for (let i = vs.length - 1; i >= 0; i--) {
|
|
1220
|
+
last = E.newTemp(e.type, `scr_arr_unshift_${acc}(${r.name}, ${vs[i].name})`);
|
|
1221
|
+
}
|
|
1222
|
+
return last ?? E.newTemp(e.type, `scr_arr_len(${r.name})`);
|
|
1223
|
+
}
|
|
1224
|
+
case "unshiftSpread": {
|
|
1225
|
+
// The runtime snapshots and retains the borrowed source,
|
|
1226
|
+
// including the aliasing `a.unshift(...a)` case.
|
|
1227
|
+
const src = E.emitExpr(e.args[0]);
|
|
1228
|
+
return E.newTemp(e.type, `scr_arr_unshift_spread(${r.name}, ${src.name})`);
|
|
1229
|
+
}
|
|
1155
1230
|
case "pop":
|
|
1156
1231
|
// Ownership of a refcounted element moves OUT of the array to
|
|
1157
1232
|
// this temp (+1 to us, the runtime does not release it).
|
|
@@ -1188,6 +1263,10 @@ export function emitExpr(E, e) {
|
|
|
1188
1263
|
}
|
|
1189
1264
|
case "toReversed":
|
|
1190
1265
|
return E.newTemp(e.type, `scr_arr_to_reversed(${r.name})`);
|
|
1266
|
+
case "reverse":
|
|
1267
|
+
// Mutates in place and returns a retained reference to the
|
|
1268
|
+
// receiver, preserving Array.prototype.reverse identity.
|
|
1269
|
+
return E.newTemp(e.type, `scr_arr_reverse(${r.name})`);
|
|
1191
1270
|
case "toSpliced": {
|
|
1192
1271
|
const start = E.emitExpr(e.args[0]);
|
|
1193
1272
|
const count = E.emitExpr(e.args[1]);
|
|
@@ -1303,17 +1382,27 @@ export function emitExpr(E, e) {
|
|
|
1303
1382
|
E.emitPendingCheck();
|
|
1304
1383
|
return t;
|
|
1305
1384
|
}
|
|
1306
|
-
const r = E.emitExpr(e.receiver);
|
|
1307
|
-
const args = e.args.map((a) => E.emitExpr(a));
|
|
1308
1385
|
const method = e.method;
|
|
1386
|
+
const directElementAccess = method === "length" || method === "byteLength" || method === "get";
|
|
1387
|
+
const r = directElementAccess
|
|
1388
|
+
? emitBytesReceiver(E, e.receiver, e.args)
|
|
1389
|
+
: E.emitExpr(e.receiver);
|
|
1390
|
+
const integerIndex = method === "get" ? E.integerLoopIndex(e.args[0]) : null;
|
|
1391
|
+
const args = integerIndex === null ? e.args.map((a) => E.emitExpr(a)) : [];
|
|
1309
1392
|
switch (method) {
|
|
1310
1393
|
case "length":
|
|
1311
|
-
return E.newTemp(e.type, `
|
|
1394
|
+
return E.newTemp(e.type, `(double)${r.name}->len`);
|
|
1312
1395
|
case "byteLength":
|
|
1313
|
-
|
|
1396
|
+
if (e.receiver.type.kind !== "bytes") {
|
|
1397
|
+
throw new Error("emitter bug: bytesIntrinsic byteLength on non-bytes");
|
|
1398
|
+
}
|
|
1399
|
+
return E.newTemp(e.type, `(double)(${r.name}->len * ${e.receiver.type.elem === "u8" ? "1" : "4"})`);
|
|
1314
1400
|
case "get":
|
|
1315
1401
|
// Any invalid index traps (the array runtime's discipline).
|
|
1316
|
-
|
|
1402
|
+
if (e.receiver.type.kind !== "bytes") {
|
|
1403
|
+
throw new Error("emitter bug: bytesIntrinsic get on non-bytes");
|
|
1404
|
+
}
|
|
1405
|
+
return E.newTemp(e.type, `${E.bytesElementHelper("get", e.receiver.type.elem, integerIndex !== null)}(${r.name}, ${integerIndex ?? args[0].name})`);
|
|
1317
1406
|
case "slice":
|
|
1318
1407
|
// Omitted relative indices default like string slice: start 0,
|
|
1319
1408
|
// end +Infinity (math.h is always included). Fresh copy, +1.
|
|
@@ -1341,18 +1430,30 @@ export function emitExpr(E, e) {
|
|
|
1341
1430
|
return { name: "", type: e.type };
|
|
1342
1431
|
}
|
|
1343
1432
|
case "toString":
|
|
1433
|
+
case "toStringVar": {
|
|
1344
1434
|
// The encoding arg is always present (the frontend completes
|
|
1345
|
-
// an omitted one to "utf8").
|
|
1346
|
-
//
|
|
1347
|
-
//
|
|
1348
|
-
//
|
|
1435
|
+
// an omitted one to "utf8"). The literal path is already
|
|
1436
|
+
// canonical and cannot throw; toStringVar validates a runtime
|
|
1437
|
+
// encoding and may throw ERR_UNKNOWN_ENCODING. Both return a
|
|
1438
|
+
// +1 string. Range forms: [enc, start] decodes to the buffer's
|
|
1439
|
+
// end; [enc, start, end] clamps the explicit end (negatives
|
|
1440
|
+
// empty, Node's slice-then-decode).
|
|
1441
|
+
const checked = method === "toStringVar";
|
|
1442
|
+
const stem = checked ? "scr_bytes_to_str_checked" : "scr_bytes_to_str";
|
|
1443
|
+
let out;
|
|
1349
1444
|
if (args.length === 3) {
|
|
1350
|
-
|
|
1445
|
+
out = E.newTemp(e.type, `${stem}_range(${r.name}, ${args[0].name}, ${args[1].name}, ${args[2].name})`);
|
|
1351
1446
|
}
|
|
1352
|
-
if (args.length === 2) {
|
|
1353
|
-
|
|
1447
|
+
else if (args.length === 2) {
|
|
1448
|
+
out = E.newTemp(e.type, `${stem}_range(${r.name}, ${args[0].name}, ${args[1].name}, (double)${r.name}->len)`);
|
|
1354
1449
|
}
|
|
1355
|
-
|
|
1450
|
+
else {
|
|
1451
|
+
out = E.newTemp(e.type, `${stem}(${r.name}, ${args[0].name})`);
|
|
1452
|
+
}
|
|
1453
|
+
if (checked)
|
|
1454
|
+
E.emitPendingCheck();
|
|
1455
|
+
return out;
|
|
1456
|
+
}
|
|
1356
1457
|
case "equals":
|
|
1357
1458
|
return E.newTemp(e.type, `scr_bytes_equals(${r.name}, ${args[0].name})`);
|
|
1358
1459
|
case "compareBuf": {
|
|
@@ -2503,6 +2604,7 @@ export function emitExpr(E, e) {
|
|
|
2503
2604
|
const t = e.args[0].type;
|
|
2504
2605
|
switch (t.kind) {
|
|
2505
2606
|
case "f64":
|
|
2607
|
+
case "date":
|
|
2506
2608
|
E.line(`scr_promise_fulfill_f64(${p.name}, ${v.name});${E.srcComment(e.loc)}`);
|
|
2507
2609
|
break;
|
|
2508
2610
|
case "bool":
|
|
@@ -2588,6 +2690,8 @@ export function emitExpr(E, e) {
|
|
|
2588
2690
|
case "fetch.start":
|
|
2589
2691
|
E.usesTimers = true;
|
|
2590
2692
|
return finish(`scr_fetch_static(${arg(0)}, ${arg(1)})`);
|
|
2693
|
+
case "fetch.responseNew":
|
|
2694
|
+
return finish(`scr_fetch_response_new(${arg(0)}, ${arg(1)})`);
|
|
2591
2695
|
case "fetch.responseJson":
|
|
2592
2696
|
return finish(`scr_fetch_response_json(${arg(0)})`);
|
|
2593
2697
|
case "fetch.responseText":
|
|
@@ -2604,6 +2708,8 @@ export function emitExpr(E, e) {
|
|
|
2604
2708
|
E.line(`scr_promise_race_add(${result.name}, ${source.name}, &${adapter});${E.srcComment(e.loc)}`);
|
|
2605
2709
|
return result;
|
|
2606
2710
|
}
|
|
2711
|
+
case "fetch.abortControllerNew":
|
|
2712
|
+
return finish(`scr_fetch_abort_controller_new()`);
|
|
2607
2713
|
case "fetch.abortTimeout":
|
|
2608
2714
|
E.usesTimers = true;
|
|
2609
2715
|
return finish(`scr_fetch_abort_timeout(${arg(0)})`);
|
|
@@ -3157,6 +3263,10 @@ export function emitExpr(E, e) {
|
|
|
3157
3263
|
E.line(`scr_qs_parse_into(${dict.name}->${OVERFLOW_MEMBER}, ${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${strTag}, ${arrTag});${E.srcComment(e.loc)}`);
|
|
3158
3264
|
return dict;
|
|
3159
3265
|
}
|
|
3266
|
+
// node:util.parseArgs (scr_util.c): checked-dynamic config in,
|
|
3267
|
+
// checked-dynamic result out; may throw a coded TypeError.
|
|
3268
|
+
case "util.parseArgs":
|
|
3269
|
+
return finish(`scr_util_parse_args(${arg(0)})`);
|
|
3160
3270
|
// Stats (scr_lib.c): statSync throws like the other sync fs
|
|
3161
3271
|
// calls; the getters are pure reads.
|
|
3162
3272
|
case "fs.openSync":
|
|
@@ -3164,7 +3274,11 @@ export function emitExpr(E, e) {
|
|
|
3164
3274
|
// comes back as f64.
|
|
3165
3275
|
return finish(`scr_fs_open(${arg(0)}, ${arg(1)})`);
|
|
3166
3276
|
case "fs.readSync":
|
|
3167
|
-
return finish(`scr_fs_read_sync(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
|
|
3277
|
+
return finish(`scr_fs_read_sync(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
|
|
3278
|
+
case "fs.writeSync":
|
|
3279
|
+
return finish(`scr_fs_write_sync(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)})`);
|
|
3280
|
+
case "fs.writeStrSync":
|
|
3281
|
+
return finish(`scr_fs_write_str_sync(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`);
|
|
3168
3282
|
case "fs.closeSync":
|
|
3169
3283
|
return finish(`scr_fs_close(${arg(0)})`);
|
|
3170
3284
|
case "fs.watch":
|
|
@@ -3208,6 +3322,12 @@ export function emitExpr(E, e) {
|
|
|
3208
3322
|
return finish(`scr_fs_stat(${arg(0)})`);
|
|
3209
3323
|
case "stats.isSymbolicLink":
|
|
3210
3324
|
return finish(`scr_stats_is_symlink(${arg(0)})`);
|
|
3325
|
+
case "stats.blocks":
|
|
3326
|
+
return finish(`scr_stats_blocks(${arg(0)})`);
|
|
3327
|
+
case "stats.nlink":
|
|
3328
|
+
return finish(`scr_stats_nlink(${arg(0)})`);
|
|
3329
|
+
case "stats.atimeMs":
|
|
3330
|
+
return finish(`scr_stats_atime_ms(${arg(0)})`);
|
|
3211
3331
|
case "stats.mtimeMs":
|
|
3212
3332
|
return finish(`scr_stats_mtime_ms(${arg(0)})`);
|
|
3213
3333
|
case "stats.isFile":
|
|
@@ -4926,6 +5046,20 @@ export function emitExpr(E, e) {
|
|
|
4926
5046
|
case "fs.existsChk":
|
|
4927
5047
|
E.usesTimers = true; // the scheduled answer holds the loop open
|
|
4928
5048
|
return finish(`scr_fs_exists_async(${arg(0)}, ${arg(1)})`);
|
|
5049
|
+
case "fs.renameCb": {
|
|
5050
|
+
// The callback MOVES into the scheduled operation. Its
|
|
5051
|
+
// adapter constructs the program-specific Error | null union
|
|
5052
|
+
// (or dyn error/null for the JS lane) when the timer fires.
|
|
5053
|
+
E.usesTimers = true;
|
|
5054
|
+
const cbT = e.args[2].type;
|
|
5055
|
+
if (cbT.kind !== "func")
|
|
5056
|
+
throw new Error("emitter bug: fs.rename callback not a func");
|
|
5057
|
+
const cb = args[2];
|
|
5058
|
+
E.moveTemp(cb);
|
|
5059
|
+
const adapter = E.fsRenameThunkFor(cbT);
|
|
5060
|
+
E.line(`scr_fs_rename_async(${arg(0)}, ${arg(1)}, ${cb.name}, &${adapter});${E.srcComment(e.loc)}`);
|
|
5061
|
+
return { name: "", type: e.type };
|
|
5062
|
+
}
|
|
4929
5063
|
case "fs.mkdtempChk":
|
|
4930
5064
|
return finish(`(scr_fs_mkdtemp_chk(${arg(0)}, ${arg(1)}, ${arg(2)}), ${isRefCounted(e.type) ? `(${cType(e.type).trim()})NULL` : "0"})`);
|
|
4931
5065
|
case "fs.mkdtempSyncChk":
|
|
@@ -4970,9 +5104,28 @@ export function emitExpr(E, e) {
|
|
|
4970
5104
|
case "zlib.inflateSync":
|
|
4971
5105
|
return finish(`scr_zlib_inflate(${arg(0)})`);
|
|
4972
5106
|
case "process.stdoutWriteBytes":
|
|
4973
|
-
return finish(`scr_process_stdout_write_bytes(${arg(0)})`);
|
|
5107
|
+
return finish(`scr_process_stdout_write_bytes(${arg(0)}, ${arg(1)})`);
|
|
4974
5108
|
case "process.stderrWriteBytes":
|
|
4975
|
-
return finish(`scr_process_stderr_write_bytes(${arg(0)})`);
|
|
5109
|
+
return finish(`scr_process_stderr_write_bytes(${arg(0)}, ${arg(1)})`);
|
|
5110
|
+
case "process.stdoutWriteBytesCb":
|
|
5111
|
+
case "process.stderrWriteBytesCb": {
|
|
5112
|
+
// Submit the bytes only after every call argument evaluated,
|
|
5113
|
+
// then move the completion callback onto the next-tick queue.
|
|
5114
|
+
// The shared error-first adapter materializes success `null`.
|
|
5115
|
+
E.usesTimers = true;
|
|
5116
|
+
const cbT = e.args[2].type;
|
|
5117
|
+
if (cbT.kind !== "func")
|
|
5118
|
+
throw new Error("emitter bug: process write callback not a func");
|
|
5119
|
+
const cb = args[2];
|
|
5120
|
+
E.moveTemp(cb);
|
|
5121
|
+
const adapter = E.fsRenameThunkFor(cbT);
|
|
5122
|
+
const write = e.fn === "process.stdoutWriteBytesCb"
|
|
5123
|
+
? "scr_process_stdout_write_bytes"
|
|
5124
|
+
: "scr_process_stderr_write_bytes";
|
|
5125
|
+
const out = E.newTemp(e.type, `${write}(${arg(0)}, ${arg(1)})`);
|
|
5126
|
+
E.line(`scr_process_write_callback(${cb.name}, &${adapter});${E.srcComment(e.loc)}`);
|
|
5127
|
+
return out;
|
|
5128
|
+
}
|
|
4976
5129
|
case "tp.setTimeout":
|
|
4977
5130
|
return finish(`scr_tp_set_timeout(${arg(0)})`);
|
|
4978
5131
|
case "tp.setImmediate":
|
|
@@ -5072,6 +5225,8 @@ export function emitExpr(E, e) {
|
|
|
5072
5225
|
return finish(`scr_fsp_read_file(${arg(0)})`);
|
|
5073
5226
|
case "fsp.writeFile":
|
|
5074
5227
|
return finish(`scr_fsp_write_file(${arg(0)}, ${arg(1)})`);
|
|
5228
|
+
case "fsp.writeFileMode":
|
|
5229
|
+
return finish(`scr_fsp_write_file_mode(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
5075
5230
|
case "fsp.mkdir":
|
|
5076
5231
|
return finish(`scr_fsp_mkdir(${arg(0)})`);
|
|
5077
5232
|
case "fsp.mkdirMode":
|
|
@@ -5084,12 +5239,51 @@ export function emitExpr(E, e) {
|
|
|
5084
5239
|
return finish(`scr_fsp_unlink(${arg(0)})`);
|
|
5085
5240
|
case "fsp.chmod":
|
|
5086
5241
|
return finish(`scr_fsp_chmod(${arg(0)}, ${arg(1)})`);
|
|
5242
|
+
case "fsp.rename":
|
|
5243
|
+
return finish(`scr_fsp_rename(${arg(0)}, ${arg(1)})`);
|
|
5087
5244
|
case "fsp.readdir":
|
|
5088
5245
|
return finish(`scr_fsp_readdir(${arg(0)})`);
|
|
5089
5246
|
case "fsp.rm":
|
|
5090
5247
|
return finish(`scr_fsp_rm(${arg(0)})`);
|
|
5091
5248
|
case "fsp.stat":
|
|
5092
5249
|
return finish(`scr_fsp_stat(${arg(0)})`);
|
|
5250
|
+
case "fsp.open":
|
|
5251
|
+
return finish(`scr_fsp_open(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
5252
|
+
case "fileHandle.fd":
|
|
5253
|
+
return finish(`scr_file_handle_fd(${arg(0)})`);
|
|
5254
|
+
case "fileHandle.close":
|
|
5255
|
+
return finish(`scr_file_handle_close_promise(${arg(0)})`);
|
|
5256
|
+
case "fileHandle.readFile":
|
|
5257
|
+
return finish(`scr_file_handle_read_file_promise(${arg(0)}, ${arg(1)})`);
|
|
5258
|
+
case "fileHandle.readFileBytes":
|
|
5259
|
+
return finish(`scr_file_handle_read_file_bytes_promise(${arg(0)}, ${arg(1)})`);
|
|
5260
|
+
case "fileHandle.writeFile":
|
|
5261
|
+
return finish(`scr_file_handle_write_file_promise(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
5262
|
+
case "fileHandle.writeFileBytes":
|
|
5263
|
+
return finish(`scr_file_handle_write_file_bytes_promise(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
5264
|
+
case "fileHandle.stat":
|
|
5265
|
+
return finish(`scr_file_handle_stat_promise(${arg(0)})`);
|
|
5266
|
+
case "fileHandle.read":
|
|
5267
|
+
case "fileHandle.writeBytes":
|
|
5268
|
+
case "fileHandle.writeStr": {
|
|
5269
|
+
if (e.type.kind !== "promise" || e.type.inner.kind !== "record") {
|
|
5270
|
+
throw new Error(`emitter bug: ${e.fn} result`);
|
|
5271
|
+
}
|
|
5272
|
+
const inner = e.type.inner;
|
|
5273
|
+
const countFn = e.fn === "fileHandle.read"
|
|
5274
|
+
? `scr_file_handle_read(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`
|
|
5275
|
+
: e.fn === "fileHandle.writeBytes"
|
|
5276
|
+
? `scr_file_handle_write_bytes(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)})`
|
|
5277
|
+
: `scr_file_handle_write_str(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)})`;
|
|
5278
|
+
const count = E.newTemp(F64, countFn);
|
|
5279
|
+
const row = E.newTemp(inner, `${mangleRecordNew(inner.shapeId)}()`);
|
|
5280
|
+
const countField = e.fn === "fileHandle.read" ? "bytesRead" : "bytesWritten";
|
|
5281
|
+
E.line(`${row.name}->${mangleField(countField)} = ${count.name};`);
|
|
5282
|
+
E.line(`${row.name}->${mangleField("buffer")} = ${retainCallC(e.args[1].type, arg(1))};`);
|
|
5283
|
+
const rc = vAdapters(inner);
|
|
5284
|
+
E.moveTemp(row); // promise fulfillment owns the result record
|
|
5285
|
+
return finish(`scr_promise_settled_ref(${row.name}, &${rc.retain}, &${rc.release}, ${E.traceArgC(inner)})`);
|
|
5286
|
+
}
|
|
5093
5287
|
case "process.argv":
|
|
5094
5288
|
return finish(`scr_process_argv()`);
|
|
5095
5289
|
case "process.platform":
|
|
@@ -6132,7 +6326,17 @@ export function emitExpr(E, e) {
|
|
|
6132
6326
|
case "date.now":
|
|
6133
6327
|
// Node's integer milliseconds since epoch. Never throws.
|
|
6134
6328
|
return finish(`scr_date_now()`);
|
|
6329
|
+
case "date.newNow":
|
|
6330
|
+
return finish(`scr_date_now()`);
|
|
6331
|
+
case "date.newMs":
|
|
6332
|
+
return finish(`scr_date_new_ms(${arg(0)})`);
|
|
6333
|
+
case "date.newString":
|
|
6334
|
+
return finish(`scr_date_parse_get_time(${arg(0)})`);
|
|
6335
|
+
case "date.getTime":
|
|
6336
|
+
case "date.valueOf":
|
|
6337
|
+
return finish(`${arg(0)}`);
|
|
6135
6338
|
case "date.toISOString":
|
|
6339
|
+
case "date.toISOStringValue":
|
|
6136
6340
|
// +1 string, or Node's "Invalid time value" RangeError
|
|
6137
6341
|
// (may-throw seed set).
|
|
6138
6342
|
return finish(`scr_date_to_iso(${arg(0)})`);
|
|
@@ -6144,10 +6348,47 @@ export function emitExpr(E, e) {
|
|
|
6144
6348
|
// MakeDay/MakeTime/TimeClip over seven completed number
|
|
6145
6349
|
// arguments; NaN outside the time range. Never throws.
|
|
6146
6350
|
return finish(`scr_date_utc(${arg(0)}, ${arg(1)}, ${arg(2)}, ${arg(3)}, ${arg(4)}, ${arg(5)}, ${arg(6)})`);
|
|
6351
|
+
case "date.getFullYear":
|
|
6352
|
+
return finish(`scr_date_get_full_year(${arg(0)}, false)`);
|
|
6353
|
+
case "date.getUTCFullYear":
|
|
6354
|
+
return finish(`scr_date_get_full_year(${arg(0)}, true)`);
|
|
6355
|
+
case "date.getMonth":
|
|
6356
|
+
return finish(`scr_date_get_month(${arg(0)}, false)`);
|
|
6357
|
+
case "date.getUTCMonth":
|
|
6358
|
+
return finish(`scr_date_get_month(${arg(0)}, true)`);
|
|
6359
|
+
case "date.getDate":
|
|
6360
|
+
return finish(`scr_date_get_date(${arg(0)}, false)`);
|
|
6361
|
+
case "date.getUTCDate":
|
|
6362
|
+
return finish(`scr_date_get_date(${arg(0)}, true)`);
|
|
6363
|
+
case "date.getDay":
|
|
6364
|
+
return finish(`scr_date_get_day(${arg(0)}, false)`);
|
|
6365
|
+
case "date.getUTCDay":
|
|
6366
|
+
return finish(`scr_date_get_day(${arg(0)}, true)`);
|
|
6367
|
+
case "date.getHours":
|
|
6368
|
+
return finish(`scr_date_get_hours(${arg(0)}, false)`);
|
|
6369
|
+
case "date.getUTCHours":
|
|
6370
|
+
return finish(`scr_date_get_hours(${arg(0)}, true)`);
|
|
6371
|
+
case "date.getMinutes":
|
|
6372
|
+
return finish(`scr_date_get_minutes(${arg(0)}, false)`);
|
|
6373
|
+
case "date.getUTCMinutes":
|
|
6374
|
+
return finish(`scr_date_get_minutes(${arg(0)}, true)`);
|
|
6375
|
+
case "date.getSeconds":
|
|
6376
|
+
return finish(`scr_date_get_seconds(${arg(0)}, false)`);
|
|
6377
|
+
case "date.getUTCSeconds":
|
|
6378
|
+
return finish(`scr_date_get_seconds(${arg(0)}, true)`);
|
|
6379
|
+
case "date.getMilliseconds":
|
|
6380
|
+
case "date.getUTCMilliseconds":
|
|
6381
|
+
return finish(`scr_date_get_milliseconds(${arg(0)})`);
|
|
6382
|
+
case "date.getTimezoneOffset":
|
|
6383
|
+
return finish(`scr_date_get_timezone_offset(${arg(0)})`);
|
|
6147
6384
|
case "text.decode":
|
|
6148
6385
|
// WHATWG utf-8 decode with the leading BOM stripped
|
|
6149
6386
|
// (scr_bytes.c). Borrowed bytes; +1 string; never throws.
|
|
6150
6387
|
return finish(`scr_text_decode(${arg(0)})`);
|
|
6388
|
+
case "text.decodeLegacy":
|
|
6389
|
+
// Compile-time-labeled WHATWG legacy decode (scr_bytes.c).
|
|
6390
|
+
// Borrowed bytes + numeric encoding id; +1 string.
|
|
6391
|
+
return finish(`scr_text_decode_legacy(${arg(0)}, ${arg(1)})`);
|
|
6151
6392
|
// The fs option forms (scr_lib.c) — all in the may-throw seed,
|
|
6152
6393
|
// like the rest of sync fs.
|
|
6153
6394
|
case "fs.mkdirRecursiveSync":
|
|
@@ -6170,6 +6411,8 @@ export function emitExpr(E, e) {
|
|
|
6170
6411
|
return finish(`scr_fs_chown(${arg(0)}, ${arg(1)}, ${arg(2)})`);
|
|
6171
6412
|
case "fs.copyFileSync":
|
|
6172
6413
|
return finish(`scr_fs_copyfile(${arg(0)}, ${arg(1)})`);
|
|
6414
|
+
case "fs.renameSync":
|
|
6415
|
+
return finish(`scr_fs_rename(${arg(0)}, ${arg(1)})`);
|
|
6173
6416
|
case "fs.lstatSync":
|
|
6174
6417
|
return finish(`scr_fs_lstat(${arg(0)})`);
|
|
6175
6418
|
case "fs.writeFileModeSync":
|
|
@@ -6302,7 +6545,7 @@ export function emitExpr(E, e) {
|
|
|
6302
6545
|
throw new Error("emitter bug: yieldExpr with no operand (frontend fills undefined)");
|
|
6303
6546
|
const v = E.emitExpr(e.value);
|
|
6304
6547
|
const yt = e.value.type;
|
|
6305
|
-
if (yt.kind === "f64") {
|
|
6548
|
+
if (yt.kind === "f64" || yt.kind === "date") {
|
|
6306
6549
|
E.line(`scr_gen_yield_f64(${v.name});${E.srcComment(e.loc)}`);
|
|
6307
6550
|
}
|
|
6308
6551
|
else if (yt.kind === "bool") {
|
|
@@ -6319,6 +6562,7 @@ export function emitExpr(E, e) {
|
|
|
6319
6562
|
// fences value-position yields on this channel).
|
|
6320
6563
|
return { name: "", type: e.type };
|
|
6321
6564
|
case "f64":
|
|
6565
|
+
case "date":
|
|
6322
6566
|
return E.newTemp(e.type, `scr_gen_take_in_f64()`);
|
|
6323
6567
|
case "bool":
|
|
6324
6568
|
return E.newTemp(e.type, `scr_gen_take_in_bool()`);
|
|
@@ -6356,7 +6600,7 @@ export function emitExpr(E, e) {
|
|
|
6356
6600
|
}
|
|
6357
6601
|
else {
|
|
6358
6602
|
const nt = e.arg.type;
|
|
6359
|
-
sendArg((a) => nt.kind === "f64" ? `scr_gen_in_f64(${g.name}, ${a.name});${E.srcComment(e.loc)}`
|
|
6603
|
+
sendArg((a) => nt.kind === "f64" || nt.kind === "date" ? `scr_gen_in_f64(${g.name}, ${a.name});${E.srcComment(e.loc)}`
|
|
6360
6604
|
: nt.kind === "bool" ? `scr_gen_in_bool(${g.name}, ${a.name});${E.srcComment(e.loc)}`
|
|
6361
6605
|
: `scr_gen_in_ref(${g.name}, ${a.name}, ${vAdapters(nt).release});${E.srcComment(e.loc)}`);
|
|
6362
6606
|
}
|
|
@@ -6368,7 +6612,7 @@ export function emitExpr(E, e) {
|
|
|
6368
6612
|
}
|
|
6369
6613
|
else {
|
|
6370
6614
|
const rt = e.arg.type;
|
|
6371
|
-
sendArg((a) => rt.kind === "f64" ? `scr_gen_ret_f64(${g.name}, ${a.name});${E.srcComment(e.loc)}`
|
|
6615
|
+
sendArg((a) => rt.kind === "f64" || rt.kind === "date" ? `scr_gen_ret_f64(${g.name}, ${a.name});${E.srcComment(e.loc)}`
|
|
6372
6616
|
: rt.kind === "bool" ? `scr_gen_ret_bool(${g.name}, ${a.name});${E.srcComment(e.loc)}`
|
|
6373
6617
|
: `scr_gen_ret_ref(${g.name}, ${a.name}, ${vAdapters(rt).release});${E.srcComment(e.loc)}`);
|
|
6374
6618
|
}
|
|
@@ -6385,7 +6629,10 @@ export function emitExpr(E, e) {
|
|
|
6385
6629
|
const t = e.arg.type;
|
|
6386
6630
|
if (isRefCounted(t))
|
|
6387
6631
|
E.moveTemp(a); // the cell takes ownership
|
|
6388
|
-
if (t.kind === "
|
|
6632
|
+
if (t.kind === "date") {
|
|
6633
|
+
throw new Error("emitter bug: Date generator throw reached backend");
|
|
6634
|
+
}
|
|
6635
|
+
else if (t.kind === "f64") {
|
|
6389
6636
|
E.line(`scr_throw_f64(${a.name});${E.srcComment(e.loc)}`);
|
|
6390
6637
|
}
|
|
6391
6638
|
else if (t.kind === "bool") {
|
|
@@ -6418,6 +6665,7 @@ export function emitExpr(E, e) {
|
|
|
6418
6665
|
let read;
|
|
6419
6666
|
switch (e.type.kind) {
|
|
6420
6667
|
case "f64":
|
|
6668
|
+
case "date":
|
|
6421
6669
|
read = `scr_await_f64(${pr.name})`;
|
|
6422
6670
|
break;
|
|
6423
6671
|
case "bool":
|
|
@@ -6540,6 +6788,7 @@ export function emitExpr(E, e) {
|
|
|
6540
6788
|
let mk;
|
|
6541
6789
|
switch (inner.kind) {
|
|
6542
6790
|
case "f64":
|
|
6791
|
+
case "date":
|
|
6543
6792
|
mk = `scr_make_resolve(${p.name}, 0)`;
|
|
6544
6793
|
break;
|
|
6545
6794
|
case "bool":
|
|
@@ -6594,6 +6843,7 @@ export function emitExpr(E, e) {
|
|
|
6594
6843
|
let mk;
|
|
6595
6844
|
switch (inner.kind) {
|
|
6596
6845
|
case "f64":
|
|
6846
|
+
case "date":
|
|
6597
6847
|
mk = `scr_make_resolve(${p.name}, 0)`;
|
|
6598
6848
|
break;
|
|
6599
6849
|
case "bool":
|