@scriptc/compiler 0.0.16 → 0.0.18
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 +4 -4
- package/dist/backend/cc.d.ts +5 -0
- package/dist/backend/cc.js +2 -0
- package/dist/backend/cc.js.map +1 -1
- package/dist/backend/emission/emit-async.js +35 -2
- package/dist/backend/emission/emit-async.js.map +1 -1
- package/dist/backend/emission/emit-exprs.js +44 -6
- package/dist/backend/emission/emit-exprs.js.map +1 -1
- package/dist/backend/emission/emitter.js +69 -11
- package/dist/backend/emission/emitter.js.map +1 -1
- package/dist/backend/emission/may-throw.d.ts +3 -3
- package/dist/backend/emission/may-throw.js +15 -4
- package/dist/backend/emission/may-throw.js.map +1 -1
- package/dist/backend/llvm/emitter.js +200 -21
- package/dist/backend/llvm/emitter.js.map +1 -1
- package/dist/coverage/surface-manifest.js +27 -9
- package/dist/coverage/surface-manifest.js.map +1 -1
- package/dist/frontend/lowering/lower-builtins.js +4 -7
- package/dist/frontend/lowering/lower-builtins.js.map +1 -1
- package/dist/frontend/lowering/lower-calls.d.ts +4 -4
- package/dist/frontend/lowering/lower-calls.js +44 -11
- package/dist/frontend/lowering/lower-calls.js.map +1 -1
- package/dist/frontend/lowering/lower-containers.d.ts +22 -17
- package/dist/frontend/lowering/lower-containers.js +628 -51
- package/dist/frontend/lowering/lower-containers.js.map +1 -1
- package/dist/frontend/lowering/lower-exprs.js +19 -1
- package/dist/frontend/lowering/lower-exprs.js.map +1 -1
- package/dist/frontend/lowering/lower-island.d.ts +2 -2
- package/dist/frontend/lowering/lower-island.js +57 -9
- package/dist/frontend/lowering/lower-island.js.map +1 -1
- package/dist/frontend/lowering/lower-modules.js +144 -10
- package/dist/frontend/lowering/lower-modules.js.map +1 -1
- package/dist/frontend/lowering/lower-stmts.d.ts +8 -0
- package/dist/frontend/lowering/lower-stmts.js +408 -21
- package/dist/frontend/lowering/lower-stmts.js.map +1 -1
- package/dist/frontend/lowering/lowerer.d.ts +38 -0
- package/dist/frontend/lowering/lowerer.js +149 -2
- package/dist/frontend/lowering/lowerer.js.map +1 -1
- package/dist/frontend/lowering/surfaces.d.ts +8 -0
- package/dist/frontend/lowering/surfaces.js +10 -0
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/frontend/shared.d.ts +4 -0
- package/dist/frontend/shared.js +9 -3
- package/dist/frontend/shared.js.map +1 -1
- package/dist/frontend/ts7/program.js +5 -4
- package/dist/frontend/ts7/program.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -3
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +53 -22
- package/dist/ir/nodes.js +42 -0
- package/dist/ir/nodes.js.map +1 -1
- package/dist/ir/serialize.d.ts +1 -1
- package/dist/ir/serialize.js +1 -1
- package/dist/ir/validate.js +99 -39
- package/dist/ir/validate.js.map +1 -1
- package/dist/library/fence-eval.js +9 -1
- package/dist/library/fence-eval.js.map +1 -1
- package/dist/library/int-infer.js +191 -25
- package/dist/library/int-infer.js.map +1 -1
- package/dist/library/int-infer.test.js +206 -1
- package/dist/library/int-infer.test.js.map +1 -1
- package/package.json +2 -2
- package/surface-manifest.json +27 -3
|
@@ -60,6 +60,7 @@ const LIB_FN_SYMS = {
|
|
|
60
60
|
"dyn.errInstanceof": "scr_dyn_err_instanceof",
|
|
61
61
|
"num.toExponential": "scr_num_to_exponential",
|
|
62
62
|
"num.toFixed0": "scr_num_to_fixed0",
|
|
63
|
+
"num.toFixed": "scr_num_to_fixed",
|
|
63
64
|
"num.sameValue": "scr_num_same_value",
|
|
64
65
|
"intl.numFormatEnUs": "scr_intl_num_format_en_us",
|
|
65
66
|
"number.isFinite": "scr_num_is_finite",
|
|
@@ -563,7 +564,7 @@ const LIB_FN_SYMS = {
|
|
|
563
564
|
"dc.chanRunStores": "scr_dc_chan_run_stores",
|
|
564
565
|
// process warning/rejection events (scr_lib.c / scr_async_dyn.c):
|
|
565
566
|
// dyn listeners are borrowed (the runtime retains its copy);
|
|
566
|
-
// onUnhandledRejection marks the loop live (the
|
|
567
|
+
// onUnhandledRejection marks the loop live (the checkpoint report
|
|
567
568
|
// dispatches the listeners).
|
|
568
569
|
"process.onWarning": "scr_process_on_warning",
|
|
569
570
|
"process.offWarning": "scr_process_off_warning",
|
|
@@ -648,12 +649,12 @@ const USES_TIMERS_LIB_FNS = new Set([
|
|
|
648
649
|
"fs.existsChk",
|
|
649
650
|
"http.createServer", "http.createServerEmpty",
|
|
650
651
|
"http.request", "http.requestCb", "http.requestUrl", "http.requestUrlCb",
|
|
651
|
-
"https.requestUrl", "https.requestUrlCb",
|
|
652
|
+
"https.request", "https.requestCb", "https.requestUrl", "https.requestUrlCb",
|
|
652
653
|
"http.requestConn", "http.requestConnCb",
|
|
653
654
|
"http.agentNew", "http.requestAgent", "http.requestAgentCb",
|
|
654
655
|
// The dyn-async slice (emit-exprs.ts's markings): fiber parks, the
|
|
655
656
|
// microtask/immediate mints, the tracing-promise reaction fiber, and
|
|
656
|
-
// the
|
|
657
|
+
// the checkpoint unhandled-rejection report.
|
|
657
658
|
"async.hop", "async.awaitDyn",
|
|
658
659
|
"dc.tcTracePromise",
|
|
659
660
|
"process.onUnhandledRejection", "process.onRejectionHandled",
|
|
@@ -1067,6 +1068,7 @@ class LlEmitter {
|
|
|
1067
1068
|
];
|
|
1068
1069
|
};
|
|
1069
1070
|
const globalReleases = globalReleaseLines("g");
|
|
1071
|
+
const asyncEntry = this.fnByName.get(this.mod.entry)?.async === true;
|
|
1070
1072
|
const entryMayThrow = this.mayThrow.has(this.mod.entry);
|
|
1071
1073
|
// The event loop runs when timers appeared OR any async/generator
|
|
1072
1074
|
// function exists (the C main's hasAsync || hasGenerators ||
|
|
@@ -1076,17 +1078,26 @@ class LlEmitter {
|
|
|
1076
1078
|
// async loop-exhaustion story.
|
|
1077
1079
|
const runsLoop = this.usesTimers ||
|
|
1078
1080
|
this.mod.functions.some((f) => f.async === true || f.generator !== undefined);
|
|
1079
|
-
const uncaughtReleases = entryMayThrow ? globalReleaseLines("gu") : [];
|
|
1081
|
+
const uncaughtReleases = entryMayThrow && !asyncEntry ? globalReleaseLines("gu") : [];
|
|
1080
1082
|
const loopReleasesU = runsLoop ? globalReleaseLines("gl") : [];
|
|
1081
1083
|
const loopReleasesR = runsLoop ? globalReleaseLines("gr") : [];
|
|
1084
|
+
const topRejectReleases = asyncEntry ? globalReleaseLines("gt") : [];
|
|
1085
|
+
const topPendingReleases = asyncEntry ? globalReleaseLines("gp") : [];
|
|
1086
|
+
const loopReportedReleases = runsLoop ? globalReleaseLines("gq") : [];
|
|
1082
1087
|
// main's epilogues read the flag / the loop entry points — declared
|
|
1083
1088
|
// HERE, before the extern block flushes (a pending check usually
|
|
1084
1089
|
// declared the flag already; the Set dedupes).
|
|
1085
1090
|
if (entryMayThrow || runsLoop)
|
|
1086
1091
|
this.declare(`declare zeroext i1 @scr_exc_pending()`);
|
|
1087
1092
|
if (runsLoop) {
|
|
1088
|
-
this.declare(`declare
|
|
1093
|
+
this.declare(`declare zeroext i1 @scr_loop_run(ptr)`);
|
|
1089
1094
|
this.declare(`declare zeroext i1 @scr_report_unhandled_rejections()`);
|
|
1095
|
+
this.declare(`declare void @scr_discard_unhandled_rejections()`);
|
|
1096
|
+
}
|
|
1097
|
+
if (asyncEntry) {
|
|
1098
|
+
this.declare(`declare i32 @scr_promise_finish_top_level(ptr)`);
|
|
1099
|
+
this.declare(`declare void @scr_promise_rethrow_top_level(ptr)`);
|
|
1100
|
+
this.declare(`declare void @scr_promise_release(ptr)`);
|
|
1090
1101
|
}
|
|
1091
1102
|
// LIBRARY mode: the runtime entry points the generated library
|
|
1092
1103
|
// symbols delegate to — declared before the extern block flushes.
|
|
@@ -1287,9 +1298,11 @@ class LlEmitter {
|
|
|
1287
1298
|
...(usesEvents ? [` call void @scr_events_install()`] : []),
|
|
1288
1299
|
// fs.watch programs fill the loop's watch hooks the same way —
|
|
1289
1300
|
// scr_watch.c links only when this line is emitted.
|
|
1290
|
-
...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`,
|
|
1301
|
+
...(usesFsWatch ? [` call void @scr_watch_install()`] : []), ...(usesFetch ? [` call void @scr_fetch_install()`] : []), ...(usesNet ? [` call void @scr_net_install()`, ` call void @scr_net_dyn_install()`] : []), ...(usesHttp ? [` call void @scr_http_dyn_install()`] : []), ...(usesStream ? [` call void @scr_stream_install()`] : []), ` call void @scr_lib_init(i32 %argc, ptr %argv)`, ...(asyncEntry
|
|
1302
|
+
? [` %top = call ptr @${mangleAsyncSpawn(this.mod.entry)}()`]
|
|
1303
|
+
: [` call void @${mangleFunction(this.mod.entry)}()`]),
|
|
1291
1304
|
// Uncaught exception from top-level code: Node exits 1.
|
|
1292
|
-
...(entryMayThrow
|
|
1305
|
+
...(entryMayThrow && !asyncEntry
|
|
1293
1306
|
? [
|
|
1294
1307
|
` %exc = call zeroext i1 @scr_exc_pending()`,
|
|
1295
1308
|
` br i1 %exc, label %uncaught, label %ok`,
|
|
@@ -1306,15 +1319,44 @@ class LlEmitter {
|
|
|
1306
1319
|
// both exit 1, like Node — the C main's loop block exactly.
|
|
1307
1320
|
...(runsLoop
|
|
1308
1321
|
? [
|
|
1309
|
-
` call
|
|
1322
|
+
` %loop_rejection = call zeroext i1 @scr_loop_run(ptr ${asyncEntry ? "%top" : "null"})`,
|
|
1310
1323
|
` %lexc = call zeroext i1 @scr_exc_pending()`,
|
|
1311
1324
|
` br i1 %lexc, label %luncaught, label %lok`,
|
|
1312
1325
|
`luncaught:`,
|
|
1313
1326
|
` call void @scr_exc_print_uncaught()`,
|
|
1327
|
+
...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
|
|
1314
1328
|
...exitListenerLines("xl"),
|
|
1315
1329
|
...loopReleasesU,
|
|
1316
1330
|
` ret i32 1`,
|
|
1317
1331
|
`lok:`,
|
|
1332
|
+
` br i1 %loop_rejection, label %lreported, label %lclean`,
|
|
1333
|
+
`lreported:`,
|
|
1334
|
+
` call void @scr_discard_unhandled_rejections()`,
|
|
1335
|
+
...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
|
|
1336
|
+
...exitListenerLines("xq"),
|
|
1337
|
+
...loopReportedReleases,
|
|
1338
|
+
` ret i32 1`,
|
|
1339
|
+
`lclean:`,
|
|
1340
|
+
...(asyncEntry
|
|
1341
|
+
? [
|
|
1342
|
+
` %tla_status = call i32 @scr_promise_finish_top_level(ptr %top)`,
|
|
1343
|
+
` %tla_rejected = icmp eq i32 %tla_status, 1`,
|
|
1344
|
+
` br i1 %tla_rejected, label %tla_fail, label %tla_not_rejected`,
|
|
1345
|
+
`tla_fail:`,
|
|
1346
|
+
// The loop already delivered every earlier-checkpoint
|
|
1347
|
+
// rejection. Drop same-checkpoint competitors before
|
|
1348
|
+
// surfacing the fatal module verdict.
|
|
1349
|
+
` call void @scr_discard_unhandled_rejections()`,
|
|
1350
|
+
` call void @scr_promise_rethrow_top_level(ptr %top)`,
|
|
1351
|
+
` call void @scr_promise_release(ptr %top)`,
|
|
1352
|
+
` call void @scr_exc_print_uncaught()`,
|
|
1353
|
+
...exitListenerLines("xt"),
|
|
1354
|
+
...topRejectReleases,
|
|
1355
|
+
` ret i32 1`,
|
|
1356
|
+
`tla_not_rejected:`,
|
|
1357
|
+
` call void @scr_promise_release(ptr %top)`,
|
|
1358
|
+
]
|
|
1359
|
+
: []),
|
|
1318
1360
|
` %rej = call zeroext i1 @scr_report_unhandled_rejections()`,
|
|
1319
1361
|
` br i1 %rej, label %lrej, label %lrok`,
|
|
1320
1362
|
`lrej:`,
|
|
@@ -1322,6 +1364,17 @@ class LlEmitter {
|
|
|
1322
1364
|
...loopReleasesR,
|
|
1323
1365
|
` ret i32 1`,
|
|
1324
1366
|
`lrok:`,
|
|
1367
|
+
...(asyncEntry
|
|
1368
|
+
? [
|
|
1369
|
+
` %tla_pending = icmp eq i32 %tla_status, 13`,
|
|
1370
|
+
` br i1 %tla_pending, label %tla_stuck, label %tla_ok`,
|
|
1371
|
+
`tla_stuck:`,
|
|
1372
|
+
...exitListenerLines("xp"),
|
|
1373
|
+
...topPendingReleases,
|
|
1374
|
+
` ret i32 13`,
|
|
1375
|
+
`tla_ok:`,
|
|
1376
|
+
]
|
|
1377
|
+
: []),
|
|
1325
1378
|
]
|
|
1326
1379
|
: []), ...exitListenerLines("xn"), ...globalReleases, ` ret i32 0`, `}`, ``,
|
|
1327
1380
|
// sanitize_address is inert under the plain pipeline; the sanitized
|
|
@@ -1644,9 +1697,29 @@ class LlEmitter {
|
|
|
1644
1697
|
out.push(...tr);
|
|
1645
1698
|
// Spawn wrapper: pack the args (+1 moves in), spawn the fiber.
|
|
1646
1699
|
const params = fieldTys.map((ty, i) => `${ty} %a${i}`);
|
|
1700
|
+
const cache = fn.asyncCacheGlobal !== undefined ? mangleGlobal(fn.asyncCacheGlobal) : null;
|
|
1701
|
+
const cycleCache = fn.asyncCycleCacheGlobal !== undefined ? mangleGlobal(fn.asyncCycleCacheGlobal) : null;
|
|
1702
|
+
if (cache !== null || cycleCache !== null) {
|
|
1703
|
+
this.declare(`declare ptr @scr_promise_retain_v(ptr)`);
|
|
1704
|
+
this.declare(`declare void @scr_promise_release(ptr)`);
|
|
1705
|
+
}
|
|
1706
|
+
if (cache !== null) {
|
|
1707
|
+
this.declare(`declare void @scr_promise_mark_handled(ptr)`);
|
|
1708
|
+
}
|
|
1647
1709
|
const sp = [
|
|
1648
1710
|
`define internal ptr @${mangleAsyncSpawn(fn.name)}(${params.join(", ")}) ${FN_ATTRS} { ; spawn ${fn.name}`,
|
|
1649
1711
|
`entry:`,
|
|
1712
|
+
...(cache !== null
|
|
1713
|
+
? [
|
|
1714
|
+
` %cached = load ptr, ptr @${cache}`,
|
|
1715
|
+
` %cache_hit = icmp ne ptr %cached, null`,
|
|
1716
|
+
` br i1 %cache_hit, label %cached_return, label %cache_miss`,
|
|
1717
|
+
`cached_return:`,
|
|
1718
|
+
` %cached_owned = call ptr @scr_promise_retain_v(ptr %cached)`,
|
|
1719
|
+
` ret ptr %cached_owned`,
|
|
1720
|
+
`cache_miss:`,
|
|
1721
|
+
]
|
|
1722
|
+
: []),
|
|
1650
1723
|
` %ap = call ptr @malloc(i64 ${sizeOf})`,
|
|
1651
1724
|
` %isnull = icmp eq ptr %ap, null`,
|
|
1652
1725
|
` br i1 %isnull, label %oom, label %ok`,
|
|
@@ -1665,7 +1738,36 @@ class LlEmitter {
|
|
|
1665
1738
|
const src = lifted && i === 0 ? "%env" : `%a${i}`;
|
|
1666
1739
|
sp.push(` %sp${i} = getelementptr inbounds %${pack}, ptr %ap, i64 0, i32 ${i}`, ` store ${ty} ${src}, ptr %sp${i}`);
|
|
1667
1740
|
});
|
|
1668
|
-
sp.push(` %p = call ptr @scr_async_spawn(ptr @${mangleTrampoline(fn.name)}, ptr %ap)`,
|
|
1741
|
+
sp.push(` %p = call ptr @scr_async_spawn(ptr @${mangleTrampoline(fn.name)}, ptr %ap)`, ...(cache !== null
|
|
1742
|
+
? [
|
|
1743
|
+
// The module loader owns this evaluation promise
|
|
1744
|
+
// immediately. A later sibling can throw before the
|
|
1745
|
+
// aggregate dependency wait is built, but this rejection
|
|
1746
|
+
// must never become an unrelated unhandled rejection.
|
|
1747
|
+
` call void @scr_promise_mark_handled(ptr %p)`,
|
|
1748
|
+
]
|
|
1749
|
+
: []), ...(cache !== null
|
|
1750
|
+
? [
|
|
1751
|
+
` %cache_owned = call ptr @scr_promise_retain_v(ptr %p)`,
|
|
1752
|
+
// The eager spawn may have re-entered this guarded module
|
|
1753
|
+
// through an admitted async cycle and installed a temporary
|
|
1754
|
+
// cache entry. Drop that owned slot before replacing it
|
|
1755
|
+
// with the outer evaluation promise.
|
|
1756
|
+
` %replaced_cache = load ptr, ptr @${cache}`,
|
|
1757
|
+
` call void @scr_promise_release(ptr %replaced_cache)`,
|
|
1758
|
+
` store ptr %cache_owned, ptr @${cache}`,
|
|
1759
|
+
]
|
|
1760
|
+
: []), ...(cycleCache !== null
|
|
1761
|
+
? [
|
|
1762
|
+
// Eager recursive spawns publish from the inside out. The
|
|
1763
|
+
// runtime-requested outermost member writes last and is the
|
|
1764
|
+
// SCC's actual evaluation root.
|
|
1765
|
+
` %cycle_cache_owned = call ptr @scr_promise_retain_v(ptr %p)`,
|
|
1766
|
+
` %replaced_cycle_cache = load ptr, ptr @${cycleCache}`,
|
|
1767
|
+
` call void @scr_promise_release(ptr %replaced_cycle_cache)`,
|
|
1768
|
+
` store ptr %cycle_cache_owned, ptr @${cycleCache}`,
|
|
1769
|
+
]
|
|
1770
|
+
: []), ` ret ptr %p`, `}`, ``);
|
|
1669
1771
|
out.push(...sp);
|
|
1670
1772
|
}
|
|
1671
1773
|
out.push(...this.emitGenScaffolding());
|
|
@@ -3650,11 +3752,12 @@ class LlEmitter {
|
|
|
3650
3752
|
case "strCmp": {
|
|
3651
3753
|
const l = this.emitExpr(e.left);
|
|
3652
3754
|
const r = this.emitExpr(e.right);
|
|
3653
|
-
|
|
3755
|
+
const fn = e.utf16 === true ? "scr_str_cmp_u16" : "scr_str_cmp";
|
|
3756
|
+
this.declare(`declare i32 @${fn}(ptr, ptr)`);
|
|
3654
3757
|
const c = B.tmp();
|
|
3655
3758
|
const t = B.tmp();
|
|
3656
3759
|
const pred = { "<": "slt", "<=": "sle", ">": "sgt", ">=": "sge" }[e.op];
|
|
3657
|
-
B.line(`${c} = call i32
|
|
3760
|
+
B.line(`${c} = call i32 @${fn}(ptr ${l.name}, ptr ${r.name})`);
|
|
3658
3761
|
B.line(`${t} = icmp ${pred} i32 ${c}, 0`);
|
|
3659
3762
|
return { name: t, type: e.type };
|
|
3660
3763
|
}
|
|
@@ -5532,6 +5635,15 @@ class LlEmitter {
|
|
|
5532
5635
|
case "libCall":
|
|
5533
5636
|
return this.emitLibCall(e);
|
|
5534
5637
|
case "intrinsic": {
|
|
5638
|
+
if (e.name === "module.await") {
|
|
5639
|
+
// Internal ESM dependency wait: pending promises park the module
|
|
5640
|
+
// fiber, while settled ones continue synchronously.
|
|
5641
|
+
const p = this.emitExpr(e.args[0]);
|
|
5642
|
+
this.declare(`declare void @scr_module_await(ptr)`);
|
|
5643
|
+
B.line(`call void @scr_module_await(ptr ${p.name})`);
|
|
5644
|
+
this.emitPendingCheck();
|
|
5645
|
+
return { name: "", type: e.type };
|
|
5646
|
+
}
|
|
5535
5647
|
if (e.name === "promise.all") {
|
|
5536
5648
|
// The runtime countdown combinator (emit-exprs.ts): a pre-sized
|
|
5537
5649
|
// values array filled per INPUT index as entries fulfill, plus
|
|
@@ -8051,6 +8163,33 @@ class LlEmitter {
|
|
|
8051
8163
|
B.line(`${t} = call ptr @scr_arr_slice(ptr ${r.name}, double ${start}, double ${end})`);
|
|
8052
8164
|
return this.own({ name: t, type: e.type });
|
|
8053
8165
|
}
|
|
8166
|
+
case "toReversed": {
|
|
8167
|
+
this.declare(`declare ptr @scr_arr_to_reversed(ptr)`);
|
|
8168
|
+
const t = B.tmp();
|
|
8169
|
+
B.line(`${t} = call ptr @scr_arr_to_reversed(ptr ${r.name})`);
|
|
8170
|
+
return this.own({ name: t, type: e.type });
|
|
8171
|
+
}
|
|
8172
|
+
case "toSpliced": {
|
|
8173
|
+
const start = this.emitExpr(e.args[0]);
|
|
8174
|
+
const count = this.emitExpr(e.args[1]);
|
|
8175
|
+
const items = this.emitExpr(e.args[2]);
|
|
8176
|
+
this.declare(`declare ptr @scr_arr_to_spliced(ptr, double, double, ptr)`);
|
|
8177
|
+
const t = B.tmp();
|
|
8178
|
+
B.line(`${t} = call ptr @scr_arr_to_spliced(ptr ${r.name}, double ${start.name}, ` +
|
|
8179
|
+
`double ${count.name}, ptr ${items.name})`);
|
|
8180
|
+
return this.own({ name: t, type: e.type });
|
|
8181
|
+
}
|
|
8182
|
+
case "with": {
|
|
8183
|
+
const index = this.emitExpr(e.args[0]);
|
|
8184
|
+
const value = this.emitExpr(e.args[1]);
|
|
8185
|
+
this.declare(`declare ptr @scr_arr_with_${acc}(ptr, double, ${accArg})`);
|
|
8186
|
+
const t = B.tmp();
|
|
8187
|
+
B.line(`${t} = call ptr @scr_arr_with_${acc}(ptr ${r.name}, double ${index.name}, ` +
|
|
8188
|
+
`${accTy} ${value.name})`);
|
|
8189
|
+
const out = this.own({ name: t, type: e.type });
|
|
8190
|
+
this.emitPendingCheck();
|
|
8191
|
+
return out;
|
|
8192
|
+
}
|
|
8054
8193
|
case "splice": {
|
|
8055
8194
|
// The removal splice: removed elements come back as a fresh +1
|
|
8056
8195
|
// array, ownership MOVED out of the receiver. An omitted count
|
|
@@ -8494,6 +8633,14 @@ class LlEmitter {
|
|
|
8494
8633
|
// A +1 VIEW aliasing the receiver's storage (subarray / Buffer's
|
|
8495
8634
|
// slice); same index defaults as slice.
|
|
8496
8635
|
return call("scr_bytes_subarray", "ptr (ptr, double, double)", `ptr ${r.name}, double ${args[0]?.name ?? f64Lit(0)}, double ${args[1]?.name ?? F64_INF}`, true, false);
|
|
8636
|
+
case "toReversed":
|
|
8637
|
+
return call("scr_bytes_to_reversed", "ptr (ptr)", `ptr ${r.name}`, true, false);
|
|
8638
|
+
case "with":
|
|
8639
|
+
return call("scr_bytes_with", "ptr (ptr, double, double)", `ptr ${r.name}, double ${args[0].name}, double ${args[1].name}`, true, true);
|
|
8640
|
+
case "join":
|
|
8641
|
+
return call("scr_bytes_join", "ptr (ptr, ptr)", `ptr ${r.name}, ptr ${args[0].name}`, true, false);
|
|
8642
|
+
case "toArray":
|
|
8643
|
+
return call("scr_bytes_to_arr", "ptr (ptr)", `ptr ${r.name}`, true, false);
|
|
8497
8644
|
case "setFrom":
|
|
8498
8645
|
// dst.set(src, offset?) — void; throws Node's RangeError on
|
|
8499
8646
|
// overflow.
|
|
@@ -10735,14 +10882,17 @@ class LlEmitter {
|
|
|
10735
10882
|
}
|
|
10736
10883
|
if (e.fn === "http.request" || e.fn === "http.requestCb" || e.fn === "http.requestUrl" || e.fn === "http.requestUrlCb" ||
|
|
10737
10884
|
e.fn === "http.requestAgent" || e.fn === "http.requestAgentCb" ||
|
|
10885
|
+
e.fn === "https.request" || e.fn === "https.requestCb" ||
|
|
10738
10886
|
e.fn === "https.requestUrl" || e.fn === "https.requestUrlCb") {
|
|
10739
10887
|
// The https URL row is the http one with the TLS entry point — same
|
|
10740
|
-
// three arguments, same response-callback adapter.
|
|
10741
|
-
//
|
|
10888
|
+
// three arguments, same response-callback adapter. The https options
|
|
10889
|
+
// row is wider: rejectUnauthorized stays an i1, while its ScrStr or
|
|
10890
|
+
// ScrBytes CA value expands to the runtime's raw pointer + length.
|
|
10742
10891
|
const isTls = e.fn.startsWith("https.");
|
|
10743
|
-
const isUrl =
|
|
10892
|
+
const isUrl = e.fn.includes("requestUrl");
|
|
10893
|
+
const isTlsOptions = isTls && !isUrl;
|
|
10744
10894
|
const isAgent = e.fn.startsWith("http.requestAgent");
|
|
10745
|
-
const cbIdx = isUrl ? 3 : isAgent ? 8 : 7;
|
|
10895
|
+
const cbIdx = isUrl ? 3 : isTlsOptions ? 9 : isAgent ? 8 : 7;
|
|
10746
10896
|
const hasCb = e.fn.endsWith("Cb");
|
|
10747
10897
|
const args = e.args.map((a) => this.emitExpr(a));
|
|
10748
10898
|
let cb = "null";
|
|
@@ -10758,13 +10908,42 @@ class LlEmitter {
|
|
|
10758
10908
|
adapter = `@${sym}`;
|
|
10759
10909
|
}
|
|
10760
10910
|
const head = args.slice(0, cbIdx);
|
|
10761
|
-
const
|
|
10762
|
-
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10911
|
+
const entry = isTlsOptions ? "scr_https_request"
|
|
10912
|
+
: isTls ? "scr_https_request_url"
|
|
10913
|
+
: isUrl ? "scr_http_request_url"
|
|
10914
|
+
: isAgent ? "scr_http_request_agent" : "scr_http_request";
|
|
10915
|
+
let callArgs = head.map((a) => `${this.llType(a.type)} ${a.name}`);
|
|
10916
|
+
if (isTlsOptions) {
|
|
10917
|
+
const ca = args[8];
|
|
10918
|
+
const caLenPtr = B.tmp();
|
|
10919
|
+
const caLen = B.tmp();
|
|
10920
|
+
let caData;
|
|
10921
|
+
if (ca.type.kind === "string") {
|
|
10922
|
+
caData = B.tmp();
|
|
10923
|
+
B.line(`${caLenPtr} = getelementptr inbounds %ScrStr, ptr ${ca.name}, i64 0, i32 1`);
|
|
10924
|
+
B.line(`${caLen} = load i64, ptr ${caLenPtr}`);
|
|
10925
|
+
B.line(`${caData} = getelementptr inbounds i8, ptr ${ca.name}, i64 24`);
|
|
10926
|
+
}
|
|
10927
|
+
else if (ca.type.kind === "bytes" && ca.type.elem === "u8") {
|
|
10928
|
+
const caDataPtr = B.tmp();
|
|
10929
|
+
caData = B.tmp();
|
|
10930
|
+
B.line(`${caLenPtr} = getelementptr inbounds i8, ptr ${ca.name}, i64 8`);
|
|
10931
|
+
B.line(`${caLen} = load i64, ptr ${caLenPtr}`);
|
|
10932
|
+
B.line(`${caDataPtr} = getelementptr inbounds i8, ptr ${ca.name}, i64 24`);
|
|
10933
|
+
B.line(`${caData} = load ptr, ptr ${caDataPtr}`);
|
|
10934
|
+
}
|
|
10935
|
+
else {
|
|
10936
|
+
throw new Error(`llvm emitter bug: ${e.fn} CA is not a string or Buffer`);
|
|
10937
|
+
}
|
|
10938
|
+
callArgs = [...callArgs.slice(0, 8), `ptr ${caData}`, `i64 ${caLen}`];
|
|
10939
|
+
this.declare(`declare ptr @scr_https_request(ptr, double, ptr, ptr, double, ptr, i1 zeroext, i1 zeroext, ptr, i64, ptr, ptr)`);
|
|
10940
|
+
}
|
|
10941
|
+
else {
|
|
10942
|
+
const decls = head.map((a) => (this.llType(a.type) === "i1" ? "i1 zeroext" : this.llType(a.type)));
|
|
10943
|
+
this.declare(`declare ptr @${entry}(${[...decls, "ptr", "ptr"].join(", ")})`);
|
|
10944
|
+
}
|
|
10766
10945
|
const t = B.tmp();
|
|
10767
|
-
B.line(`${t} = call ptr @${entry}(${[...
|
|
10946
|
+
B.line(`${t} = call ptr @${entry}(${[...callArgs, `ptr ${cb}`, `ptr ${adapter}`].join(", ")})`);
|
|
10768
10947
|
const out = this.own({ name: t, type: e.type });
|
|
10769
10948
|
if (MAY_THROW_LIB_FNS.has(e.fn))
|
|
10770
10949
|
this.emitPendingCheck();
|