@scriptc/compiler 0.0.17 → 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 +40 -4
- 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 +199 -21
- package/dist/backend/llvm/emitter.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.js +17 -9
- 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.js +55 -7
- 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.js +4 -0
- package/dist/frontend/lowering/surfaces.js.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +1 -1
- package/dist/ir/nodes.d.ts +46 -12
- package/dist/ir/nodes.js +41 -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 +98 -39
- package/dist/ir/validate.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 +25 -1
|
@@ -564,7 +564,7 @@ const LIB_FN_SYMS = {
|
|
|
564
564
|
"dc.chanRunStores": "scr_dc_chan_run_stores",
|
|
565
565
|
// process warning/rejection events (scr_lib.c / scr_async_dyn.c):
|
|
566
566
|
// dyn listeners are borrowed (the runtime retains its copy);
|
|
567
|
-
// onUnhandledRejection marks the loop live (the
|
|
567
|
+
// onUnhandledRejection marks the loop live (the checkpoint report
|
|
568
568
|
// dispatches the listeners).
|
|
569
569
|
"process.onWarning": "scr_process_on_warning",
|
|
570
570
|
"process.offWarning": "scr_process_off_warning",
|
|
@@ -649,12 +649,12 @@ const USES_TIMERS_LIB_FNS = new Set([
|
|
|
649
649
|
"fs.existsChk",
|
|
650
650
|
"http.createServer", "http.createServerEmpty",
|
|
651
651
|
"http.request", "http.requestCb", "http.requestUrl", "http.requestUrlCb",
|
|
652
|
-
"https.requestUrl", "https.requestUrlCb",
|
|
652
|
+
"https.request", "https.requestCb", "https.requestUrl", "https.requestUrlCb",
|
|
653
653
|
"http.requestConn", "http.requestConnCb",
|
|
654
654
|
"http.agentNew", "http.requestAgent", "http.requestAgentCb",
|
|
655
655
|
// The dyn-async slice (emit-exprs.ts's markings): fiber parks, the
|
|
656
656
|
// microtask/immediate mints, the tracing-promise reaction fiber, and
|
|
657
|
-
// the
|
|
657
|
+
// the checkpoint unhandled-rejection report.
|
|
658
658
|
"async.hop", "async.awaitDyn",
|
|
659
659
|
"dc.tcTracePromise",
|
|
660
660
|
"process.onUnhandledRejection", "process.onRejectionHandled",
|
|
@@ -1068,6 +1068,7 @@ class LlEmitter {
|
|
|
1068
1068
|
];
|
|
1069
1069
|
};
|
|
1070
1070
|
const globalReleases = globalReleaseLines("g");
|
|
1071
|
+
const asyncEntry = this.fnByName.get(this.mod.entry)?.async === true;
|
|
1071
1072
|
const entryMayThrow = this.mayThrow.has(this.mod.entry);
|
|
1072
1073
|
// The event loop runs when timers appeared OR any async/generator
|
|
1073
1074
|
// function exists (the C main's hasAsync || hasGenerators ||
|
|
@@ -1077,17 +1078,26 @@ class LlEmitter {
|
|
|
1077
1078
|
// async loop-exhaustion story.
|
|
1078
1079
|
const runsLoop = this.usesTimers ||
|
|
1079
1080
|
this.mod.functions.some((f) => f.async === true || f.generator !== undefined);
|
|
1080
|
-
const uncaughtReleases = entryMayThrow ? globalReleaseLines("gu") : [];
|
|
1081
|
+
const uncaughtReleases = entryMayThrow && !asyncEntry ? globalReleaseLines("gu") : [];
|
|
1081
1082
|
const loopReleasesU = runsLoop ? globalReleaseLines("gl") : [];
|
|
1082
1083
|
const loopReleasesR = runsLoop ? globalReleaseLines("gr") : [];
|
|
1084
|
+
const topRejectReleases = asyncEntry ? globalReleaseLines("gt") : [];
|
|
1085
|
+
const topPendingReleases = asyncEntry ? globalReleaseLines("gp") : [];
|
|
1086
|
+
const loopReportedReleases = runsLoop ? globalReleaseLines("gq") : [];
|
|
1083
1087
|
// main's epilogues read the flag / the loop entry points — declared
|
|
1084
1088
|
// HERE, before the extern block flushes (a pending check usually
|
|
1085
1089
|
// declared the flag already; the Set dedupes).
|
|
1086
1090
|
if (entryMayThrow || runsLoop)
|
|
1087
1091
|
this.declare(`declare zeroext i1 @scr_exc_pending()`);
|
|
1088
1092
|
if (runsLoop) {
|
|
1089
|
-
this.declare(`declare
|
|
1093
|
+
this.declare(`declare zeroext i1 @scr_loop_run(ptr)`);
|
|
1090
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)`);
|
|
1091
1101
|
}
|
|
1092
1102
|
// LIBRARY mode: the runtime entry points the generated library
|
|
1093
1103
|
// symbols delegate to — declared before the extern block flushes.
|
|
@@ -1288,9 +1298,11 @@ class LlEmitter {
|
|
|
1288
1298
|
...(usesEvents ? [` call void @scr_events_install()`] : []),
|
|
1289
1299
|
// fs.watch programs fill the loop's watch hooks the same way —
|
|
1290
1300
|
// scr_watch.c links only when this line is emitted.
|
|
1291
|
-
...(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)}()`]),
|
|
1292
1304
|
// Uncaught exception from top-level code: Node exits 1.
|
|
1293
|
-
...(entryMayThrow
|
|
1305
|
+
...(entryMayThrow && !asyncEntry
|
|
1294
1306
|
? [
|
|
1295
1307
|
` %exc = call zeroext i1 @scr_exc_pending()`,
|
|
1296
1308
|
` br i1 %exc, label %uncaught, label %ok`,
|
|
@@ -1307,15 +1319,44 @@ class LlEmitter {
|
|
|
1307
1319
|
// both exit 1, like Node — the C main's loop block exactly.
|
|
1308
1320
|
...(runsLoop
|
|
1309
1321
|
? [
|
|
1310
|
-
` call
|
|
1322
|
+
` %loop_rejection = call zeroext i1 @scr_loop_run(ptr ${asyncEntry ? "%top" : "null"})`,
|
|
1311
1323
|
` %lexc = call zeroext i1 @scr_exc_pending()`,
|
|
1312
1324
|
` br i1 %lexc, label %luncaught, label %lok`,
|
|
1313
1325
|
`luncaught:`,
|
|
1314
1326
|
` call void @scr_exc_print_uncaught()`,
|
|
1327
|
+
...(asyncEntry ? [` call void @scr_promise_release(ptr %top)`] : []),
|
|
1315
1328
|
...exitListenerLines("xl"),
|
|
1316
1329
|
...loopReleasesU,
|
|
1317
1330
|
` ret i32 1`,
|
|
1318
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
|
+
: []),
|
|
1319
1360
|
` %rej = call zeroext i1 @scr_report_unhandled_rejections()`,
|
|
1320
1361
|
` br i1 %rej, label %lrej, label %lrok`,
|
|
1321
1362
|
`lrej:`,
|
|
@@ -1323,6 +1364,17 @@ class LlEmitter {
|
|
|
1323
1364
|
...loopReleasesR,
|
|
1324
1365
|
` ret i32 1`,
|
|
1325
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
|
+
: []),
|
|
1326
1378
|
]
|
|
1327
1379
|
: []), ...exitListenerLines("xn"), ...globalReleases, ` ret i32 0`, `}`, ``,
|
|
1328
1380
|
// sanitize_address is inert under the plain pipeline; the sanitized
|
|
@@ -1645,9 +1697,29 @@ class LlEmitter {
|
|
|
1645
1697
|
out.push(...tr);
|
|
1646
1698
|
// Spawn wrapper: pack the args (+1 moves in), spawn the fiber.
|
|
1647
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
|
+
}
|
|
1648
1709
|
const sp = [
|
|
1649
1710
|
`define internal ptr @${mangleAsyncSpawn(fn.name)}(${params.join(", ")}) ${FN_ATTRS} { ; spawn ${fn.name}`,
|
|
1650
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
|
+
: []),
|
|
1651
1723
|
` %ap = call ptr @malloc(i64 ${sizeOf})`,
|
|
1652
1724
|
` %isnull = icmp eq ptr %ap, null`,
|
|
1653
1725
|
` br i1 %isnull, label %oom, label %ok`,
|
|
@@ -1666,7 +1738,36 @@ class LlEmitter {
|
|
|
1666
1738
|
const src = lifted && i === 0 ? "%env" : `%a${i}`;
|
|
1667
1739
|
sp.push(` %sp${i} = getelementptr inbounds %${pack}, ptr %ap, i64 0, i32 ${i}`, ` store ${ty} ${src}, ptr %sp${i}`);
|
|
1668
1740
|
});
|
|
1669
|
-
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`, `}`, ``);
|
|
1670
1771
|
out.push(...sp);
|
|
1671
1772
|
}
|
|
1672
1773
|
out.push(...this.emitGenScaffolding());
|
|
@@ -3651,11 +3752,12 @@ class LlEmitter {
|
|
|
3651
3752
|
case "strCmp": {
|
|
3652
3753
|
const l = this.emitExpr(e.left);
|
|
3653
3754
|
const r = this.emitExpr(e.right);
|
|
3654
|
-
|
|
3755
|
+
const fn = e.utf16 === true ? "scr_str_cmp_u16" : "scr_str_cmp";
|
|
3756
|
+
this.declare(`declare i32 @${fn}(ptr, ptr)`);
|
|
3655
3757
|
const c = B.tmp();
|
|
3656
3758
|
const t = B.tmp();
|
|
3657
3759
|
const pred = { "<": "slt", "<=": "sle", ">": "sgt", ">=": "sge" }[e.op];
|
|
3658
|
-
B.line(`${c} = call i32
|
|
3760
|
+
B.line(`${c} = call i32 @${fn}(ptr ${l.name}, ptr ${r.name})`);
|
|
3659
3761
|
B.line(`${t} = icmp ${pred} i32 ${c}, 0`);
|
|
3660
3762
|
return { name: t, type: e.type };
|
|
3661
3763
|
}
|
|
@@ -5533,6 +5635,15 @@ class LlEmitter {
|
|
|
5533
5635
|
case "libCall":
|
|
5534
5636
|
return this.emitLibCall(e);
|
|
5535
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
|
+
}
|
|
5536
5647
|
if (e.name === "promise.all") {
|
|
5537
5648
|
// The runtime countdown combinator (emit-exprs.ts): a pre-sized
|
|
5538
5649
|
// values array filled per INPUT index as entries fulfill, plus
|
|
@@ -8052,6 +8163,33 @@ class LlEmitter {
|
|
|
8052
8163
|
B.line(`${t} = call ptr @scr_arr_slice(ptr ${r.name}, double ${start}, double ${end})`);
|
|
8053
8164
|
return this.own({ name: t, type: e.type });
|
|
8054
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
|
+
}
|
|
8055
8193
|
case "splice": {
|
|
8056
8194
|
// The removal splice: removed elements come back as a fresh +1
|
|
8057
8195
|
// array, ownership MOVED out of the receiver. An omitted count
|
|
@@ -8495,6 +8633,14 @@ class LlEmitter {
|
|
|
8495
8633
|
// A +1 VIEW aliasing the receiver's storage (subarray / Buffer's
|
|
8496
8634
|
// slice); same index defaults as slice.
|
|
8497
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);
|
|
8498
8644
|
case "setFrom":
|
|
8499
8645
|
// dst.set(src, offset?) — void; throws Node's RangeError on
|
|
8500
8646
|
// overflow.
|
|
@@ -10736,14 +10882,17 @@ class LlEmitter {
|
|
|
10736
10882
|
}
|
|
10737
10883
|
if (e.fn === "http.request" || e.fn === "http.requestCb" || e.fn === "http.requestUrl" || e.fn === "http.requestUrlCb" ||
|
|
10738
10884
|
e.fn === "http.requestAgent" || e.fn === "http.requestAgentCb" ||
|
|
10885
|
+
e.fn === "https.request" || e.fn === "https.requestCb" ||
|
|
10739
10886
|
e.fn === "https.requestUrl" || e.fn === "https.requestUrlCb") {
|
|
10740
10887
|
// The https URL row is the http one with the TLS entry point — same
|
|
10741
|
-
// three arguments, same response-callback adapter.
|
|
10742
|
-
//
|
|
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.
|
|
10743
10891
|
const isTls = e.fn.startsWith("https.");
|
|
10744
|
-
const isUrl =
|
|
10892
|
+
const isUrl = e.fn.includes("requestUrl");
|
|
10893
|
+
const isTlsOptions = isTls && !isUrl;
|
|
10745
10894
|
const isAgent = e.fn.startsWith("http.requestAgent");
|
|
10746
|
-
const cbIdx = isUrl ? 3 : isAgent ? 8 : 7;
|
|
10895
|
+
const cbIdx = isUrl ? 3 : isTlsOptions ? 9 : isAgent ? 8 : 7;
|
|
10747
10896
|
const hasCb = e.fn.endsWith("Cb");
|
|
10748
10897
|
const args = e.args.map((a) => this.emitExpr(a));
|
|
10749
10898
|
let cb = "null";
|
|
@@ -10759,13 +10908,42 @@ class LlEmitter {
|
|
|
10759
10908
|
adapter = `@${sym}`;
|
|
10760
10909
|
}
|
|
10761
10910
|
const head = args.slice(0, cbIdx);
|
|
10762
|
-
const
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
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
|
+
}
|
|
10767
10945
|
const t = B.tmp();
|
|
10768
|
-
B.line(`${t} = call ptr @${entry}(${[...
|
|
10946
|
+
B.line(`${t} = call ptr @${entry}(${[...callArgs, `ptr ${cb}`, `ptr ${adapter}`].join(", ")})`);
|
|
10769
10947
|
const out = this.own({ name: t, type: e.type });
|
|
10770
10948
|
if (MAY_THROW_LIB_FNS.has(e.fn))
|
|
10771
10949
|
this.emitPendingCheck();
|