visaljs 0.0.10 โ 0.0.11
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/README.md +12 -4
- package/THIRD_PARTY_LICENSES +31 -1
- package/cli.js +962 -68
- package/node/include/js_node.h +11 -1
- package/node/prelude/_http_common.js +29 -0
- package/node/prelude/async_hooks.js +50 -11
- package/node/prelude/child_process.js +31 -4
- package/node/prelude/console.js +311 -143
- package/node/prelude/crypto.js +6 -4
- package/node/prelude/dgram.js +1169 -0
- package/node/prelude/diagnostics_channel.js +3 -1
- package/node/prelude/dns.js +250 -45
- package/node/prelude/dns_promises.js +8 -2
- package/node/prelude/fs_promises.js +9 -1
- package/node/prelude/http.js +395 -86
- package/node/prelude/https.js +13 -4
- package/node/prelude/internal/console_class.js +7 -0
- package/node/prelude/internal/console_global.js +25 -0
- package/node/prelude/internal/crypto/key_encryption.js +217 -0
- package/node/prelude/internal/crypto/keys.js +161 -26
- package/node/prelude/internal/crypto/random.js +24 -0
- package/node/prelude/internal/crypto/util.js +2 -1
- package/node/prelude/internal/crypto_x509.js +161 -0
- package/node/prelude/internal/dns_classes.js +6 -0
- package/node/prelude/internal/dns_resolver.js +371 -0
- package/node/prelude/internal/errors.js +9 -0
- package/node/prelude/internal/events_on.js +82 -37
- package/node/prelude/internal/features.js +8 -4
- package/node/prelude/internal/fs_filehandle.js +10 -4
- package/node/prelude/internal/perf_histogram.js +1 -1
- package/node/prelude/internal/process_more.js +32 -17
- package/node/prelude/internal/process_signals.js +8 -2
- package/node/prelude/internal/punycode.ts +163 -0
- package/node/prelude/internal/readline.js +648 -274
- package/node/prelude/internal/readline_editor.js +1240 -0
- package/node/prelude/internal/string_width.js +43 -0
- package/node/prelude/internal/tls/common.js +145 -33
- package/node/prelude/internal/tls/wrap.js +182 -49
- package/node/prelude/internal/tls/x509.js +4 -1
- package/node/prelude/internal/udp.js +177 -0
- package/node/prelude/net.js +13 -1
- package/node/prelude/os.js +24 -6
- package/node/prelude/perf_hooks.js +37 -2
- package/node/prelude/punycode.js +2 -130
- package/node/prelude/readline.js +113 -4
- package/node/prelude/readline_promises.js +56 -32
- package/node/prelude/tls.js +21 -4
- package/node/prelude/util.js +3 -16
- package/node/src/host_dns.c +623 -0
- package/node/src/host_http.c +12 -0
- package/node/src/host_net.c +46 -0
- package/node/src/host_os.c +1 -6
- package/node/src/host_sys.c +70 -0
- package/node/src/host_udp.c +418 -0
- package/node/third_party/c-ares/LICENSE.md +24 -0
- package/node/third_party/c-ares/config/darwin/ares_config.h +573 -0
- package/node/third_party/c-ares/config/freebsd/ares_config.h +573 -0
- package/node/third_party/c-ares/config/linux/ares_config.h +573 -0
- package/node/third_party/c-ares/config/openbsd/ares_config.h +583 -0
- package/node/third_party/c-ares/include/ares.h +1237 -0
- package/node/third_party/c-ares/include/ares_build.h +202 -0
- package/node/third_party/c-ares/include/ares_dns.h +127 -0
- package/node/third_party/c-ares/include/ares_dns_record.h +1119 -0
- package/node/third_party/c-ares/include/ares_nameser.h +510 -0
- package/node/third_party/c-ares/include/ares_version.h +47 -0
- package/node/third_party/c-ares/src/lib/ares_addrinfo2hostent.c +305 -0
- package/node/third_party/c-ares/src/lib/ares_addrinfo_localhost.c +245 -0
- package/node/third_party/c-ares/src/lib/ares_android.c +496 -0
- package/node/third_party/c-ares/src/lib/ares_android.h +38 -0
- package/node/third_party/c-ares/src/lib/ares_cancel.c +87 -0
- package/node/third_party/c-ares/src/lib/ares_close_sockets.c +137 -0
- package/node/third_party/c-ares/src/lib/ares_conn.c +511 -0
- package/node/third_party/c-ares/src/lib/ares_conn.h +202 -0
- package/node/third_party/c-ares/src/lib/ares_cookie.c +461 -0
- package/node/third_party/c-ares/src/lib/ares_data.c +168 -0
- package/node/third_party/c-ares/src/lib/ares_data.h +92 -0
- package/node/third_party/c-ares/src/lib/ares_destroy.c +159 -0
- package/node/third_party/c-ares/src/lib/ares_free_hostent.c +54 -0
- package/node/third_party/c-ares/src/lib/ares_free_string.c +33 -0
- package/node/third_party/c-ares/src/lib/ares_freeaddrinfo.c +67 -0
- package/node/third_party/c-ares/src/lib/ares_getaddrinfo.c +806 -0
- package/node/third_party/c-ares/src/lib/ares_getenv.c +38 -0
- package/node/third_party/c-ares/src/lib/ares_getenv.h +34 -0
- package/node/third_party/c-ares/src/lib/ares_gethostbyaddr.c +229 -0
- package/node/third_party/c-ares/src/lib/ares_gethostbyname.c +341 -0
- package/node/third_party/c-ares/src/lib/ares_getnameinfo.c +437 -0
- package/node/third_party/c-ares/src/lib/ares_hosts_file.c +960 -0
- package/node/third_party/c-ares/src/lib/ares_inet_net_pton.h +31 -0
- package/node/third_party/c-ares/src/lib/ares_init.c +631 -0
- package/node/third_party/c-ares/src/lib/ares_ipv6.h +115 -0
- package/node/third_party/c-ares/src/lib/ares_library_init.c +190 -0
- package/node/third_party/c-ares/src/lib/ares_metrics.c +261 -0
- package/node/third_party/c-ares/src/lib/ares_options.c +492 -0
- package/node/third_party/c-ares/src/lib/ares_parse_into_addrinfo.c +179 -0
- package/node/third_party/c-ares/src/lib/ares_private.h +648 -0
- package/node/third_party/c-ares/src/lib/ares_process.c +1649 -0
- package/node/third_party/c-ares/src/lib/ares_qcache.c +442 -0
- package/node/third_party/c-ares/src/lib/ares_query.c +151 -0
- package/node/third_party/c-ares/src/lib/ares_search.c +623 -0
- package/node/third_party/c-ares/src/lib/ares_send.c +300 -0
- package/node/third_party/c-ares/src/lib/ares_set_socket_functions.c +590 -0
- package/node/third_party/c-ares/src/lib/ares_setup.h +224 -0
- package/node/third_party/c-ares/src/lib/ares_socket.c +427 -0
- package/node/third_party/c-ares/src/lib/ares_socket.h +163 -0
- package/node/third_party/c-ares/src/lib/ares_sortaddrinfo.c +447 -0
- package/node/third_party/c-ares/src/lib/ares_strerror.c +91 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig.c +642 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_files.c +851 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_mac.c +373 -0
- package/node/third_party/c-ares/src/lib/ares_sysconfig_win.c +673 -0
- package/node/third_party/c-ares/src/lib/ares_timeout.c +162 -0
- package/node/third_party/c-ares/src/lib/ares_update_servers.c +1376 -0
- package/node/third_party/c-ares/src/lib/ares_version.c +36 -0
- package/node/third_party/c-ares/src/lib/config-dos.h +114 -0
- package/node/third_party/c-ares/src/lib/config-win32.h +396 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_array.c +409 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable.c +451 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable.h +174 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_asvp.c +224 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_dict.c +230 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_strvp.c +210 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_szvp.c +188 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpstr.c +186 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_htable_vpvp.c +194 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_llist.c +385 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_slist.c +479 -0
- package/node/third_party/c-ares/src/lib/dsa/ares_slist.h +207 -0
- package/node/third_party/c-ares/src/lib/event/ares_event.h +191 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_configchg.c +746 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_epoll.c +192 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_kqueue.c +248 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_poll.c +140 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_select.c +159 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_thread.c +575 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_wake_pipe.c +172 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_win32.c +981 -0
- package/node/third_party/c-ares/src/lib/event/ares_event_win32.h +161 -0
- package/node/third_party/c-ares/src/lib/include/ares_array.h +276 -0
- package/node/third_party/c-ares/src/lib/include/ares_buf.h +732 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_asvp.h +130 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_dict.h +123 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_strvp.h +130 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_szvp.h +118 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_vpstr.h +111 -0
- package/node/third_party/c-ares/src/lib/include/ares_htable_vpvp.h +128 -0
- package/node/third_party/c-ares/src/lib/include/ares_llist.h +239 -0
- package/node/third_party/c-ares/src/lib/include/ares_mem.h +41 -0
- package/node/third_party/c-ares/src/lib/include/ares_str.h +261 -0
- package/node/third_party/c-ares/src/lib/inet_net_pton.c +451 -0
- package/node/third_party/c-ares/src/lib/inet_ntop.c +219 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_create_query.c +78 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_expand_name.c +99 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_expand_string.c +107 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_fds.c +80 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_getsock.c +85 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_a_reply.c +107 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_aaaa_reply.c +109 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_caa_reply.c +137 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_mx_reply.c +110 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_naptr_reply.c +132 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_ns_reply.c +154 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_ptr_reply.c +213 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_soa_reply.c +115 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_srv_reply.c +114 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_txt_reply.c +144 -0
- package/node/third_party/c-ares/src/lib/legacy/ares_parse_uri_reply.c +113 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_mapping.c +982 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.c +309 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_multistring.h +72 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_name.c +736 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_parse.c +1360 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_private.h +273 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_record.c +1701 -0
- package/node/third_party/c-ares/src/lib/record/ares_dns_write.c +1229 -0
- package/node/third_party/c-ares/src/lib/str/ares_buf.c +1510 -0
- package/node/third_party/c-ares/src/lib/str/ares_str.c +562 -0
- package/node/third_party/c-ares/src/lib/str/ares_strsplit.c +90 -0
- package/node/third_party/c-ares/src/lib/str/ares_strsplit.h +51 -0
- package/node/third_party/c-ares/src/lib/thirdparty/apple/dnsinfo.h +122 -0
- package/node/third_party/c-ares/src/lib/util/ares_iface_ips.c +640 -0
- package/node/third_party/c-ares/src/lib/util/ares_iface_ips.h +140 -0
- package/node/third_party/c-ares/src/lib/util/ares_math.c +167 -0
- package/node/third_party/c-ares/src/lib/util/ares_math.h +58 -0
- package/node/third_party/c-ares/src/lib/util/ares_rand.c +389 -0
- package/node/third_party/c-ares/src/lib/util/ares_rand.h +36 -0
- package/node/third_party/c-ares/src/lib/util/ares_threads.c +613 -0
- package/node/third_party/c-ares/src/lib/util/ares_threads.h +60 -0
- package/node/third_party/c-ares/src/lib/util/ares_time.h +49 -0
- package/node/third_party/c-ares/src/lib/util/ares_timeval.c +95 -0
- package/node/third_party/c-ares/src/lib/util/ares_uri.c +1627 -0
- package/node/third_party/c-ares/src/lib/util/ares_uri.h +252 -0
- package/node/third_party/c-ares/src/lib/windows_port.c +29 -0
- package/package.json +1 -1
- package/prebuilt/darwin-arm64/cares-a6286c65ca9374a3.a +0 -0
- package/prebuilt/darwin-x64/cares-a6286c65ca9374a3.a +0 -0
- package/prebuilt/linux-arm64/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-arm64-musl/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-x64/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/linux-x64-musl/cares-4ba05ac8e948af8e.a +0 -0
- package/prebuilt/win32-x64/boringssl-ce573858472b7fc9.a +0 -0
- package/prebuilt/win32-x64/brotli-20d86a61f30baeb3.a +0 -0
- package/prebuilt/win32-x64/cares-49c9ec95162b912d.a +0 -0
- package/prebuilt/win32-x64/uv-b11bae65d7fced82.a +0 -0
- package/prebuilt/win32-x64/zlib-4ce2317a4c3f5fb5.a +0 -0
- package/prebuilt/win32-x64/zstd-015315ac7c784c73.a +0 -0
- package/runtime/include/js_builtins.h +5 -0
- package/runtime/include/js_crypto.h +11 -0
- package/runtime/include/js_gc.h +13 -10
- package/runtime/include/js_jobs.h +2 -0
- package/runtime/include/js_object.h +58 -0
- package/runtime/include/jscontext.h +1 -0
- package/runtime/src/crypto_internal.h +1 -0
- package/runtime/src/crypto_subtle.c +66 -7
- package/runtime/src/crypto_tls.c +265 -19
- package/runtime/src/gc.c +73 -92
- package/runtime/src/inspect.c +18 -1
- package/runtime/src/jobs.c +37 -22
- package/runtime/src/object.c +49 -2
- package/runtime/src/os.c +16 -6
- package/runtime/src/os.h +2 -0
- package/runtime/src/process.c +97 -10
package/cli.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { createRequire, isBuiltin } from "node:module";
|
|
3
3
|
import { Worker, isMainThread, parentPort, workerData } from "node:worker_threads";
|
|
4
|
-
import {
|
|
4
|
+
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
5
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
5
6
|
import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, relative, resolve, sep } from "node:path";
|
|
6
7
|
import { parseArgs, promisify } from "node:util";
|
|
7
8
|
import { getHeapStatistics } from "node:v8";
|
|
8
9
|
import ts from "typescript";
|
|
9
10
|
import { RolldownMagicString, rolldown } from "rolldown";
|
|
10
|
-
import { execFile, execFileSync, spawn, spawnSync } from "node:child_process";
|
|
11
11
|
import { createHash } from "node:crypto";
|
|
12
12
|
import { availableParallelism, homedir, tmpdir } from "node:os";
|
|
13
13
|
//#region \0rolldown/runtime.js
|
|
@@ -1359,6 +1359,8 @@ var Converter = class {
|
|
|
1359
1359
|
};
|
|
1360
1360
|
}
|
|
1361
1361
|
const object = this.expression(node.expression);
|
|
1362
|
+
const element = this.unit?.arrayElement(node.expression);
|
|
1363
|
+
const elem = element ? { elem: element } : {};
|
|
1362
1364
|
if (ts.isPropertyAccessExpression(node)) {
|
|
1363
1365
|
if (ts.isPrivateIdentifier(node.name)) return {
|
|
1364
1366
|
type: "MemberExpression",
|
|
@@ -1377,7 +1379,8 @@ var Converter = class {
|
|
|
1377
1379
|
loc,
|
|
1378
1380
|
object,
|
|
1379
1381
|
property: this.identifier(node.name),
|
|
1380
|
-
computed: false
|
|
1382
|
+
computed: false,
|
|
1383
|
+
...elem
|
|
1381
1384
|
};
|
|
1382
1385
|
}
|
|
1383
1386
|
return {
|
|
@@ -1385,7 +1388,8 @@ var Converter = class {
|
|
|
1385
1388
|
loc,
|
|
1386
1389
|
object,
|
|
1387
1390
|
property: this.expression(node.argumentExpression),
|
|
1388
|
-
computed: true
|
|
1391
|
+
computed: true,
|
|
1392
|
+
...elem
|
|
1389
1393
|
};
|
|
1390
1394
|
}
|
|
1391
1395
|
/** A property name: an identifier or literal naming the key, or a computed expression. */
|
|
@@ -2901,6 +2905,21 @@ const STATIC_TYPES = {
|
|
|
2901
2905
|
words: "null"
|
|
2902
2906
|
}
|
|
2903
2907
|
};
|
|
2908
|
+
/** Each kind's elements' type, and its kind in C (JS_SARRAY_*). */
|
|
2909
|
+
const ARRAY_ELEMS = {
|
|
2910
|
+
number: {
|
|
2911
|
+
type: T.Int32 | T.Double,
|
|
2912
|
+
c: "JS_SARRAY_NUMBER"
|
|
2913
|
+
},
|
|
2914
|
+
string: {
|
|
2915
|
+
type: T.String,
|
|
2916
|
+
c: "JS_SARRAY_STRING"
|
|
2917
|
+
},
|
|
2918
|
+
boolean: {
|
|
2919
|
+
type: T.Boolean,
|
|
2920
|
+
c: "JS_SARRAY_BOOLEAN"
|
|
2921
|
+
}
|
|
2922
|
+
};
|
|
2904
2923
|
/** A declared parameter's type as ERR_INVALID_ARG_TYPE words it: "of type string or undefined",
|
|
2905
2924
|
* "an instance of Float64Array". */
|
|
2906
2925
|
function expectedText(t, view) {
|
|
@@ -3106,6 +3125,23 @@ const OPS = {
|
|
|
3106
3125
|
allocates: true
|
|
3107
3126
|
},
|
|
3108
3127
|
math: pure(1),
|
|
3128
|
+
from_char_code: {
|
|
3129
|
+
...pure(1),
|
|
3130
|
+
allocates: true
|
|
3131
|
+
},
|
|
3132
|
+
array_get: generic(2),
|
|
3133
|
+
array_set: {
|
|
3134
|
+
...generic(3),
|
|
3135
|
+
result: false
|
|
3136
|
+
},
|
|
3137
|
+
array_length: {
|
|
3138
|
+
...generic(1),
|
|
3139
|
+
callsUser: false
|
|
3140
|
+
},
|
|
3141
|
+
array_push: {
|
|
3142
|
+
...generic(2),
|
|
3143
|
+
callsUser: false
|
|
3144
|
+
},
|
|
3109
3145
|
int_add: pure(2),
|
|
3110
3146
|
int_sub: pure(2),
|
|
3111
3147
|
int_mul: pure(2),
|
|
@@ -3463,6 +3499,10 @@ function isExceptionalEdge(from, to) {
|
|
|
3463
3499
|
}
|
|
3464
3500
|
//#endregion
|
|
3465
3501
|
//#region ir/src/builder.ts
|
|
3502
|
+
/** A literal's type. */
|
|
3503
|
+
function literalType(value) {
|
|
3504
|
+
return value === void 0 ? T.Undefined : value === null ? T.Null : typeof value === "boolean" ? T.Boolean : typeof value === "string" ? T.String : Number.isInteger(value) && Math.abs(value) <= 2147483647 && !Object.is(value, -0) ? T.Int32 : T.Double;
|
|
3505
|
+
}
|
|
3466
3506
|
var FunctionBuilder = class {
|
|
3467
3507
|
fn;
|
|
3468
3508
|
current;
|
|
@@ -3579,10 +3619,9 @@ var FunctionBuilder = class {
|
|
|
3579
3619
|
return instr;
|
|
3580
3620
|
}
|
|
3581
3621
|
const(value) {
|
|
3582
|
-
const type = value === void 0 ? T.Undefined : value === null ? T.Null : typeof value === "boolean" ? T.Boolean : typeof value === "string" ? T.String : Number.isInteger(value) && Math.abs(value) <= 2147483647 && !Object.is(value, -0) ? T.Int32 : T.Double;
|
|
3583
3622
|
return this.emit("const", [], {
|
|
3584
3623
|
lit: { value },
|
|
3585
|
-
type
|
|
3624
|
+
type: literalType(value)
|
|
3586
3625
|
});
|
|
3587
3626
|
}
|
|
3588
3627
|
writeVariable(key, value, block = this.current) {
|
|
@@ -3798,6 +3837,10 @@ function printFunction(fn) {
|
|
|
3798
3837
|
case "bigint": return `bigint ${i.bigint}n`;
|
|
3799
3838
|
case "switch_string": return `switch_string ${name(i.operands[0])}, ${JSON.stringify(i.cases)}`;
|
|
3800
3839
|
case "regexp": return `regexp /${i.regexp.pattern}/${i.regexp.flags}`;
|
|
3840
|
+
case "array_get":
|
|
3841
|
+
case "array_set":
|
|
3842
|
+
case "array_length":
|
|
3843
|
+
case "array_push": return `${i.op} ${i.elem}[] ${args}`;
|
|
3801
3844
|
case "template_object": return `template_object ${JSON.stringify(i.template.cooked)}, slot ${i.index}`;
|
|
3802
3845
|
case "import_meta": return `import_meta ${JSON.stringify(i.target)}, slot ${i.index}`;
|
|
3803
3846
|
case "dynamic_import": return `dynamic_import ${args}, from ${JSON.stringify(i.target)}`;
|
|
@@ -4052,6 +4095,12 @@ function calleeText(e) {
|
|
|
4052
4095
|
default: return "(intermediate value)";
|
|
4053
4096
|
}
|
|
4054
4097
|
}
|
|
4098
|
+
/** `a.push(v)` of a static array: one argument, no spread. */
|
|
4099
|
+
function isArrayPush(callee, e) {
|
|
4100
|
+
return callee.elem !== void 0 && !callee.computed && callee.property.name === "push" && e.arguments.length === 1 && e.arguments[0].type !== "SpreadElement";
|
|
4101
|
+
}
|
|
4102
|
+
/** A static array's element kind in the IR: an i32[]'s elements are Numbers its code converts. */
|
|
4103
|
+
const irElem = (elem) => elem === "i32" ? "number" : elem;
|
|
4055
4104
|
function isConst(key) {
|
|
4056
4105
|
return !("op" in key);
|
|
4057
4106
|
}
|
|
@@ -4824,6 +4873,7 @@ var FunctionLowering = class {
|
|
|
4824
4873
|
case "UpdateExpression": return this.isInt(e.argument);
|
|
4825
4874
|
case "BinaryExpression": return INT_OPERATORS.has(e.operator) && this.isInt(e.left) && this.isInt(e.right);
|
|
4826
4875
|
case "AssignmentExpression": return e.target.type === "Identifier" && this.isInt(e.target);
|
|
4876
|
+
case "MemberExpression": return e.computed && e.elem === "i32";
|
|
4827
4877
|
case "ConditionalExpression": return this.isInt(e.consequent) && this.isInt(e.alternate);
|
|
4828
4878
|
case "CallExpression": return e.callee.type === "Identifier" && declared(e.callee)?.returnsInt !== void 0;
|
|
4829
4879
|
default: return false;
|
|
@@ -5754,9 +5804,10 @@ var FunctionLowering = class {
|
|
|
5754
5804
|
};
|
|
5755
5805
|
}
|
|
5756
5806
|
const p = e.property;
|
|
5807
|
+
const elem = e.type === "MemberExpression" && e.elem && !(e.computed && p.type === "Literal" && typeof p.value === "string") ? { elem: e.elem } : {};
|
|
5757
5808
|
let key;
|
|
5758
5809
|
if (!e.computed) key = propKey(p.name);
|
|
5759
|
-
else if (p.type === "Literal" && (typeof p.value === "string" || typeof p.value === "number")) key = propKey(p.value);
|
|
5810
|
+
else if (p.type === "Literal" && (typeof p.value === "string" || typeof p.value === "number") && !elem.elem) key = propKey(p.value);
|
|
5760
5811
|
else key = this.expression(p);
|
|
5761
5812
|
return superCallee ? {
|
|
5762
5813
|
obj,
|
|
@@ -5764,7 +5815,8 @@ var FunctionLowering = class {
|
|
|
5764
5815
|
superCallee
|
|
5765
5816
|
} : {
|
|
5766
5817
|
obj,
|
|
5767
|
-
key
|
|
5818
|
+
key,
|
|
5819
|
+
...elem
|
|
5768
5820
|
};
|
|
5769
5821
|
}
|
|
5770
5822
|
getMember(ref) {
|
|
@@ -5777,6 +5829,11 @@ var FunctionLowering = class {
|
|
|
5777
5829
|
ref.key
|
|
5778
5830
|
]);
|
|
5779
5831
|
}
|
|
5832
|
+
if (ref.elem && !isConst(ref.key)) {
|
|
5833
|
+
const v = this.b.emit("array_get", [ref.obj, ref.key], { elem: irElem(ref.elem) });
|
|
5834
|
+
return ref.elem === "i32" ? this.toInt(v, "i32") : v;
|
|
5835
|
+
}
|
|
5836
|
+
if (ref.elem && "name" in ref.key && ref.key.name === "length") return this.b.emit("array_length", [ref.obj], { elem: irElem(ref.elem) });
|
|
5780
5837
|
if (isConst(ref.key)) return this.b.emit("get_prop", [ref.obj], { key: ref.key });
|
|
5781
5838
|
return this.b.emit("get_elem", [ref.obj, ref.key]);
|
|
5782
5839
|
}
|
|
@@ -5803,7 +5860,12 @@ var FunctionLowering = class {
|
|
|
5803
5860
|
]);
|
|
5804
5861
|
return;
|
|
5805
5862
|
}
|
|
5806
|
-
if (isConst(ref.key)) this.b.emit("
|
|
5863
|
+
if (ref.elem && !isConst(ref.key)) this.b.emit("array_set", [
|
|
5864
|
+
ref.obj,
|
|
5865
|
+
ref.key,
|
|
5866
|
+
ref.elem === "i32" ? this.toInt(value, "i32") : value
|
|
5867
|
+
], { elem: irElem(ref.elem) });
|
|
5868
|
+
else if (isConst(ref.key)) this.b.emit("set_prop", [ref.obj, value], { key: ref.key });
|
|
5807
5869
|
else this.b.emit("set_elem", [
|
|
5808
5870
|
ref.obj,
|
|
5809
5871
|
ref.key,
|
|
@@ -6046,6 +6108,12 @@ var FunctionLowering = class {
|
|
|
6046
6108
|
call(e) {
|
|
6047
6109
|
const b = this.b;
|
|
6048
6110
|
const callee = e.callee;
|
|
6111
|
+
if (callee.type === "MemberExpression" && isArrayPush(callee, e)) {
|
|
6112
|
+
const obj = this.expression(callee.object);
|
|
6113
|
+
const v = this.expression(e.arguments[0]);
|
|
6114
|
+
b.loc = e.loc;
|
|
6115
|
+
return b.emit("array_push", [obj, callee.elem === "i32" ? this.toInt(v, "i32") : v], { elem: irElem(callee.elem) });
|
|
6116
|
+
}
|
|
6049
6117
|
if (callee.type === "MemberExpression" || callee.type === "SuperMember") {
|
|
6050
6118
|
const ref = this.memberRef(callee);
|
|
6051
6119
|
b.loc = callee.loc;
|
|
@@ -7040,6 +7108,13 @@ var FunctionEmitter = class {
|
|
|
7040
7108
|
const value = i.operands[2];
|
|
7041
7109
|
return i.taView === "f64" && value.repr === "f64" ? `js_tav_put_f64${suffix}(ctx, ${view}, ${args[0]}, ${k}, ${this.as(value, "f64")}, ${strict})` : `js_tav_set_${i.taView}${suffix}(ctx, ${view}, ${args[0]}, ${k}, ${args[2]}, ${strict})`;
|
|
7042
7110
|
}
|
|
7111
|
+
/** A static array's index, an int64_t: -1 for a Number that isn't an index. */
|
|
7112
|
+
arrayIndex(key) {
|
|
7113
|
+
if (key.op === "const" && Number.isSafeInteger(key.lit.value) && key.lit.value >= 0) return this.as(key, "i64");
|
|
7114
|
+
if (key.repr === "i32" || key.repr === "i64") return `(int64_t)${this.as(key, key.repr)}`;
|
|
7115
|
+
if (key.repr === "f64") return `js_sarray_index_f64(${this.as(key, "f64")})`;
|
|
7116
|
+
return `js_sarray_index(${this.v(key)})`;
|
|
7117
|
+
}
|
|
7043
7118
|
/** A double read of a Float64Array's view: false from the access is an exception. */
|
|
7044
7119
|
readDouble(i, args) {
|
|
7045
7120
|
this.lines.push(` { double d; if (JS_UNLIKELY(!${this.viewAccess(i, args)})) { ${this.onException(i.block)} }`, this.hasVar(i) ? ` ${this.name(i)} = ${convert("d", "f64", i.repr)}; }` : " }");
|
|
@@ -7415,6 +7490,23 @@ var FunctionEmitter = class {
|
|
|
7415
7490
|
case "construct_direct":
|
|
7416
7491
|
this.constructDirect(i, args);
|
|
7417
7492
|
return;
|
|
7493
|
+
case "from_char_code": {
|
|
7494
|
+
const c = i.operands[0];
|
|
7495
|
+
expr = `js_from_char_code_unit(ctx, (uint16_t)${c.repr === "i32" || c.repr === "i64" ? this.as(c, c.repr) : `js_f64_to_int32(${this.as(c, "f64")})`})`;
|
|
7496
|
+
break;
|
|
7497
|
+
}
|
|
7498
|
+
case "array_get":
|
|
7499
|
+
expr = `js_sarray_get(ctx, ${args[0]}, ${this.arrayIndex(i.operands[1])}, ${ARRAY_ELEMS[i.elem].c})`;
|
|
7500
|
+
break;
|
|
7501
|
+
case "array_set":
|
|
7502
|
+
status = `js_sarray_set(ctx, ${args[0]}, ${this.arrayIndex(i.operands[1])}, ${args[2]}, ${ARRAY_ELEMS[i.elem].c})`;
|
|
7503
|
+
break;
|
|
7504
|
+
case "array_length":
|
|
7505
|
+
expr = `js_sarray_length(ctx, ${args[0]})`;
|
|
7506
|
+
break;
|
|
7507
|
+
case "array_push":
|
|
7508
|
+
expr = `js_sarray_push(ctx, ${args[0]}, ${args[1]}, ${ARRAY_ELEMS[i.elem].c})`;
|
|
7509
|
+
break;
|
|
7418
7510
|
case "math": {
|
|
7419
7511
|
const f = {
|
|
7420
7512
|
sqrt: "sqrt",
|
|
@@ -8589,6 +8681,7 @@ const REMOVABLE = /* @__PURE__ */ new Set([
|
|
|
8589
8681
|
"construct_result",
|
|
8590
8682
|
"char_code_at",
|
|
8591
8683
|
"math",
|
|
8684
|
+
"from_char_code",
|
|
8592
8685
|
"int_add",
|
|
8593
8686
|
"int_sub",
|
|
8594
8687
|
"int_mul",
|
|
@@ -8781,13 +8874,13 @@ function inlineBuiltin(i) {
|
|
|
8781
8874
|
return null;
|
|
8782
8875
|
}
|
|
8783
8876
|
/** What typed code ("use static", which trusts the built-ins to be the standard ones) makes of a
|
|
8784
|
-
* built-in call: s.charCodeAt(i) of a string, or Math's sqrt/abs/floor/ceil/trunc
|
|
8785
|
-
* the C helper's suffix; null for anything else. `type`: the values' types. */
|
|
8877
|
+
* built-in call: s.charCodeAt(i) of a string, or Math's sqrt/abs/floor/ceil/trunc or
|
|
8878
|
+
* String.fromCharCode of a Number, the C helper's suffix; null for anything else. `type`: the values' types. */
|
|
8786
8879
|
function trustedBuiltin(i, type) {
|
|
8787
8880
|
if (!isStatic(i.block.fn)) return null;
|
|
8788
8881
|
const name = inlineBuiltin(i);
|
|
8789
8882
|
if (name === "char_code_at") return isSubtype(type(i.operands[1]), T.String) ? name : null;
|
|
8790
|
-
if (name?.startsWith("math_")) return isSubtype(type(i.operands[2]), Number_) ? name : null;
|
|
8883
|
+
if (name?.startsWith("math_") || name === "from_char_code") return isSubtype(type(i.operands[2]), Number_) ? name : null;
|
|
8791
8884
|
return null;
|
|
8792
8885
|
}
|
|
8793
8886
|
/** The bitwise operators: ToInt32 (ToUint32) of their operands first. */
|
|
@@ -8922,6 +9015,9 @@ const specialize = {
|
|
|
8922
9015
|
if (trusted === "char_code_at") {
|
|
8923
9016
|
i.op = "char_code_at";
|
|
8924
9017
|
i.operands = [i.operands[1], i.operands[2]];
|
|
9018
|
+
} else if (trusted === "from_char_code") {
|
|
9019
|
+
i.op = "from_char_code";
|
|
9020
|
+
i.operands = [i.operands[2]];
|
|
8925
9021
|
} else {
|
|
8926
9022
|
i.op = "math";
|
|
8927
9023
|
i.target = trusted.slice(5);
|
|
@@ -9276,6 +9372,10 @@ function transfer(i, type, sig, bound = null) {
|
|
|
9276
9372
|
if (readsDouble(i)) return T.Int32 | T.Double;
|
|
9277
9373
|
if (i.taView && isStatic(i.block.fn)) return T.Int32 | T.Undefined;
|
|
9278
9374
|
return Unknown;
|
|
9375
|
+
case "array_get": return ARRAY_ELEMS[i.elem].type;
|
|
9376
|
+
case "array_length":
|
|
9377
|
+
case "array_push": return T.Int32;
|
|
9378
|
+
case "from_char_code": return T.String;
|
|
9279
9379
|
case "char_code_at":
|
|
9280
9380
|
case "math": return Number_;
|
|
9281
9381
|
case "int_add":
|
|
@@ -9668,6 +9768,7 @@ function constructorSlots(fn) {
|
|
|
9668
9768
|
const promoteGlobals = {
|
|
9669
9769
|
name: "promote-globals",
|
|
9670
9770
|
run(m, count) {
|
|
9771
|
+
if (isStatic(m.main)) count("folded", "constant", foldConstants(m));
|
|
9671
9772
|
const shared = /* @__PURE__ */ new Set();
|
|
9672
9773
|
for (const fn of functionsOf(m)) for (const b of fn.blocks) for (const i of b.instrs) if ((i.op === "load_global" || i.op === "store_global") && fn !== m.main || i.op === "template_object" || i.op === "import_meta") shared.add(i.index);
|
|
9673
9774
|
const slots = /* @__PURE__ */ new Set();
|
|
@@ -9766,6 +9867,44 @@ function promote(fn, slots, m) {
|
|
|
9766
9867
|
removeInstrs(fn, dead);
|
|
9767
9868
|
return slots.size;
|
|
9768
9869
|
}
|
|
9870
|
+
/** A stored value that is a literal: a const, or an integer literal an int (i32) binding converts
|
|
9871
|
+
* to itself. */
|
|
9872
|
+
function literal(v) {
|
|
9873
|
+
if (v.op === "const") return v.lit.value;
|
|
9874
|
+
const c = v.operands[0];
|
|
9875
|
+
if (c?.op !== "const" || typeof c.lit.value !== "number") return NOT_LITERAL;
|
|
9876
|
+
const n = c.lit.value;
|
|
9877
|
+
if (v.op === "to_i64" && Number.isSafeInteger(n)) return n;
|
|
9878
|
+
if (v.op === "to_i32" && (n | 0) === n) return n;
|
|
9879
|
+
return NOT_LITERAL;
|
|
9880
|
+
}
|
|
9881
|
+
const NOT_LITERAL = Symbol("not a literal");
|
|
9882
|
+
/** Static code's constant module bindings, as literals in the functions that read them. */
|
|
9883
|
+
function foldConstants(m) {
|
|
9884
|
+
const stores = /* @__PURE__ */ new Map();
|
|
9885
|
+
for (const fn of functionsOf(m)) for (const b of fn.blocks) for (const i of b.instrs) if (i.op === "store_global" && i.operands[0].op !== "empty") stores.set(i.index, (stores.get(i.index) ?? 0) + 1);
|
|
9886
|
+
const constants = /* @__PURE__ */ new Map();
|
|
9887
|
+
for (const i of m.main.blocks[0].instrs) {
|
|
9888
|
+
if (OPS[i.op].callsUser) break;
|
|
9889
|
+
if (i.op !== "store_global" || stores.get(i.index) !== 1) continue;
|
|
9890
|
+
const value = literal(i.operands[0]);
|
|
9891
|
+
if (value !== NOT_LITERAL) constants.set(i.index, value);
|
|
9892
|
+
}
|
|
9893
|
+
let folded = 0;
|
|
9894
|
+
for (const fn of m.functions) for (const b of fn.blocks) for (const i of b.instrs) {
|
|
9895
|
+
if (i.op !== "load_global" || !constants.has(i.index)) continue;
|
|
9896
|
+
const value = constants.get(i.index);
|
|
9897
|
+
Object.assign(i, {
|
|
9898
|
+
op: "const",
|
|
9899
|
+
operands: [],
|
|
9900
|
+
lit: { value },
|
|
9901
|
+
type: literalType(value),
|
|
9902
|
+
index: void 0
|
|
9903
|
+
});
|
|
9904
|
+
folded++;
|
|
9905
|
+
}
|
|
9906
|
+
return folded;
|
|
9907
|
+
}
|
|
9769
9908
|
//#endregion
|
|
9770
9909
|
//#region optimizer/src/simplify.ts
|
|
9771
9910
|
const NUMERIC = /* @__PURE__ */ new Set([
|
|
@@ -10883,6 +11022,7 @@ const LLHTTP = join(DIR, "third_party", "llhttp");
|
|
|
10883
11022
|
const ZLIB = join(DIR, "third_party", "zlib");
|
|
10884
11023
|
const BROTLI = join(DIR, "third_party", "brotli");
|
|
10885
11024
|
const ZSTD = join(DIR, "third_party", "zstd");
|
|
11025
|
+
const CARES = join(DIR, "third_party", "c-ares");
|
|
10886
11026
|
const INCLUDE = join(DIR, "include");
|
|
10887
11027
|
const files$1 = (dir, ext) => readdirSync(dir).filter((f) => f.endsWith(ext)).map((f) => join(dir, f));
|
|
10888
11028
|
/** Prelude modules may import "visaljs:host". */
|
|
@@ -10911,6 +11051,7 @@ const modules = {
|
|
|
10911
11051
|
inspector: join(preludeDir, "inspector.js"),
|
|
10912
11052
|
"inspector/promises": join(preludeDir, "inspector_promises.js"),
|
|
10913
11053
|
module: join(preludeDir, "module.js"),
|
|
11054
|
+
dgram: join(preludeDir, "dgram.js"),
|
|
10914
11055
|
net: join(preludeDir, "net.js"),
|
|
10915
11056
|
os: join(preludeDir, "os.js"),
|
|
10916
11057
|
path: join(preludeDir, "path.js"),
|
|
@@ -10926,6 +11067,7 @@ const modules = {
|
|
|
10926
11067
|
sea: join(preludeDir, "sea.js"),
|
|
10927
11068
|
stream: join(preludeDir, "stream.js"),
|
|
10928
11069
|
_http_agent: join(preludeDir, "_http_agent.js"),
|
|
11070
|
+
_http_common: join(preludeDir, "_http_common.js"),
|
|
10929
11071
|
_http_server: join(preludeDir, "_http_server.js"),
|
|
10930
11072
|
_stream_duplex: join(preludeDir, "_stream_duplex.js"),
|
|
10931
11073
|
_stream_passthrough: join(preludeDir, "_stream_passthrough.js"),
|
|
@@ -10968,6 +11110,14 @@ const implicitModules = [
|
|
|
10968
11110
|
file: join(preludeDir, "internal", "process_stdio.js"),
|
|
10969
11111
|
reached: (_code, program) => /\b(?:stdout|stderr)\b/.test(program) && STDIO_STREAM_USE.test(program)
|
|
10970
11112
|
},
|
|
11113
|
+
{
|
|
11114
|
+
file: join(preludeDir, "internal", "console_global.js"),
|
|
11115
|
+
reached: (_code, program) => STDIO_WRITE_REPLACED.test(program)
|
|
11116
|
+
},
|
|
11117
|
+
{
|
|
11118
|
+
file: join(preludeDir, "internal", "console_class.js"),
|
|
11119
|
+
reached: (_code, program) => /\bConsole\b/.test(program)
|
|
11120
|
+
},
|
|
10971
11121
|
{
|
|
10972
11122
|
file: join(preludeDir, "internal", "process_stdin.js"),
|
|
10973
11123
|
reached: (_code, program) => /\bstdin\b/.test(program)
|
|
@@ -11014,7 +11164,7 @@ const implicitModules = [
|
|
|
11014
11164
|
},
|
|
11015
11165
|
{
|
|
11016
11166
|
file: join(preludeDir, "internal", "events_on.js"),
|
|
11017
|
-
reached: (_code, program) => EVENTS_ON.test(program)
|
|
11167
|
+
reached: (_code, program) => EVENTS_ON.test(program) || /readline|readLines|createInterface/i.test(program) && /\bfor\s+await\b|\basyncIterator\b/.test(program)
|
|
11018
11168
|
},
|
|
11019
11169
|
{
|
|
11020
11170
|
file: join(preludeDir, "internal", "stream_compose.js"),
|
|
@@ -11104,6 +11254,18 @@ const implicitModules = [
|
|
|
11104
11254
|
file: join(preludeDir, "internal", "fs_filehandle.js"),
|
|
11105
11255
|
reached: (_code, program) => FS_OPEN.test(program) || /\bFileHandle\b/.test(program) || /\bpromises\b/.test(program) && /\.\s*open\s*\(/.test(program)
|
|
11106
11256
|
},
|
|
11257
|
+
{
|
|
11258
|
+
file: join(preludeDir, "internal", "readline_editor.js"),
|
|
11259
|
+
reached: (_code, program) => READLINE_EDITOR.test(program) || /readline|createInterface/i.test(program) && /\b(?:stdin|terminal)\b/.test(program)
|
|
11260
|
+
},
|
|
11261
|
+
{
|
|
11262
|
+
file: join(preludeDir, "internal", "dns_resolver.js"),
|
|
11263
|
+
reached: (_code, program) => DNS_RESOLVER.test(program) || DNS_RESOLVE_RRTYPE.test(program) || DNS_MODULE_RESOLVE.test(program)
|
|
11264
|
+
},
|
|
11265
|
+
{
|
|
11266
|
+
file: join(preludeDir, "internal", "crypto_x509.js"),
|
|
11267
|
+
reached: (_code, program) => /\b(?:X509Certificate|get(?:Peer)?X509Certificate)\b/.test(program)
|
|
11268
|
+
},
|
|
11107
11269
|
{
|
|
11108
11270
|
file: join(preludeDir, "internal", "process_more.js"),
|
|
11109
11271
|
reached: (_code, program) => PROCESS_MORE.test(program)
|
|
@@ -11147,6 +11309,11 @@ const implicitModules = [
|
|
|
11147
11309
|
];
|
|
11148
11310
|
const FETCH = /(?<![.\w$#])fetch\s*\(|[=(,]\s*fetch\s*[;,)\n]|\btypeof\s+fetch\b|\b(?:globalThis|global|self)\s*(?:\.\s*fetch\b|\[\s*["'`]fetch["'`])/;
|
|
11149
11311
|
const STREAM_OPERATORS = /\.\s*(?:flatMap|toArray|drop|take|asIndexedPairs)\s*\(|\bReadable\b[\s\S]*\.\s*(?:map|filter|forEach|reduce|some|every|find)\s*\(/;
|
|
11312
|
+
const DNS_RESOLVER = /\b(?:Resolver|resolve(?:4|6|Any|Caa|Cname|Mx|Naptr|Ns|Ptr|Soa|Srv|Tlsa|Txt)|getServers|setServers|setLocalAddress)\b/;
|
|
11313
|
+
const READLINE_EDITOR = /\b(?:emitKeypressEvents|setRawMode|keypress|completer)\b/;
|
|
11314
|
+
const DNS_MODULE_RESOLVE = /\b(?:dns|dns_default|require_dns\(\))\s*\.\s*(?:promises\s*\.\s*)?(?:resolve|reverse)\b/;
|
|
11315
|
+
const DNS_RESOLVE_RRTYPE = /\.\s*resolve\s*\([^,()]+,\s*["'`](?:A|AAAA|ANY|CAA|CNAME|MX|NAPTR|NS|PTR|SOA|SRV|TLSA|TXT)["'`]/;
|
|
11316
|
+
const STDIO_WRITE_REPLACED = /\b(?:stdout|stderr|stream)\s*\.\s*write\s*=(?![=>])|\b_std(?:out|err)\s*=(?!=)|\b(?:channel|subscribe)\s*\(\s*["'`]console\.(?:log|info|debug|warn|error)["'`]/;
|
|
11150
11317
|
const STDIO_STREAM_USE = /\.\s*(?:pipe|on|once|end|cork|uncork|destroy|removeListener|addListener|prependListener)\s*\(|\b(?:pipeline|finished)\b|\bwritable(?:Length|HighWaterMark|NeedDrain|Ended|Finished)\b/;
|
|
11151
11318
|
const PROCESS_DISTINCT = "chdir|umask|uptime|cpuUsage|threadCpuUsage|resourceUsage|availableMemory|constrainedMemory|setuid|setgid|seteuid|setegid|getgroups|setgroups|initgroups|reallyExit|execve|getBuiltinModule|loadEnvFile|hasUncaughtExceptionCaptureCallback|setUncaughtExceptionCaptureCallback|allowedNodeEnvironmentFlags|setSourceMapsEnabled|sourceMapsEnabled|getActiveResourcesInfo|moduleLoadList|openStdin|debugPort|dlopen";
|
|
11152
11319
|
const PROCESS_COMMON = "title|ppid|release|config|ref|unref|abort|report|domain|assert|binding|finalization";
|
|
@@ -11423,10 +11590,6 @@ const primitives = {
|
|
|
11423
11590
|
c: "js_host_os_homedir",
|
|
11424
11591
|
length: 0
|
|
11425
11592
|
},
|
|
11426
|
-
osTmpdir: {
|
|
11427
|
-
c: "js_host_os_tmpdir",
|
|
11428
|
-
length: 0
|
|
11429
|
-
},
|
|
11430
11593
|
osMemory: {
|
|
11431
11594
|
c: "js_host_os_memory",
|
|
11432
11595
|
length: 0
|
|
@@ -11495,6 +11658,10 @@ const primitives = {
|
|
|
11495
11658
|
c: "js_util_inspect",
|
|
11496
11659
|
length: 2
|
|
11497
11660
|
},
|
|
11661
|
+
previewEntries: {
|
|
11662
|
+
c: "js_host_preview_entries",
|
|
11663
|
+
length: 2
|
|
11664
|
+
},
|
|
11498
11665
|
utilFormat: {
|
|
11499
11666
|
c: "js_util_format",
|
|
11500
11667
|
length: 0
|
|
@@ -11715,6 +11882,26 @@ const primitives = {
|
|
|
11715
11882
|
c: "js_tls_context_set_key",
|
|
11716
11883
|
length: 2
|
|
11717
11884
|
},
|
|
11885
|
+
tlsContextAddCredential: {
|
|
11886
|
+
c: "js_tls_context_add_credential",
|
|
11887
|
+
length: 3
|
|
11888
|
+
},
|
|
11889
|
+
tlsContextAllowPartialChain: {
|
|
11890
|
+
c: "js_tls_context_allow_partial_chain",
|
|
11891
|
+
length: 1
|
|
11892
|
+
},
|
|
11893
|
+
tlsContextTicketKeys: {
|
|
11894
|
+
c: "js_tls_context_ticket_keys",
|
|
11895
|
+
length: 2
|
|
11896
|
+
},
|
|
11897
|
+
tlsContextSetSessions: {
|
|
11898
|
+
c: "js_tls_context_set_sessions",
|
|
11899
|
+
length: 3
|
|
11900
|
+
},
|
|
11901
|
+
tlsPkcs12: {
|
|
11902
|
+
c: "js_tls_pkcs12",
|
|
11903
|
+
length: 2
|
|
11904
|
+
},
|
|
11718
11905
|
tlsRootCertificates: {
|
|
11719
11906
|
c: "js_tls_root_certificates",
|
|
11720
11907
|
length: 0
|
|
@@ -11723,6 +11910,18 @@ const primitives = {
|
|
|
11723
11910
|
c: "js_tls_ciphers",
|
|
11724
11911
|
length: 0
|
|
11725
11912
|
},
|
|
11913
|
+
x509Check: {
|
|
11914
|
+
c: "js_x509_check",
|
|
11915
|
+
length: 4
|
|
11916
|
+
},
|
|
11917
|
+
x509CheckIssued: {
|
|
11918
|
+
c: "js_x509_check_issued",
|
|
11919
|
+
length: 2
|
|
11920
|
+
},
|
|
11921
|
+
x509CheckKey: {
|
|
11922
|
+
c: "js_x509_check_key",
|
|
11923
|
+
length: 2
|
|
11924
|
+
},
|
|
11726
11925
|
tlsNew: {
|
|
11727
11926
|
c: "js_tls_new",
|
|
11728
11927
|
length: 7
|
|
@@ -11751,6 +11950,10 @@ const primitives = {
|
|
|
11751
11950
|
c: "js_tls_session",
|
|
11752
11951
|
length: 1
|
|
11753
11952
|
},
|
|
11953
|
+
tlsTicket: {
|
|
11954
|
+
c: "js_tls_ticket",
|
|
11955
|
+
length: 1
|
|
11956
|
+
},
|
|
11754
11957
|
tlsExportKeyingMaterial: {
|
|
11755
11958
|
c: "js_tls_export_keying_material",
|
|
11756
11959
|
length: 4
|
|
@@ -11759,6 +11962,14 @@ const primitives = {
|
|
|
11759
11962
|
c: "js_tls_set_no_renegotiation",
|
|
11760
11963
|
length: 1
|
|
11761
11964
|
},
|
|
11965
|
+
tlsEnableKeylog: {
|
|
11966
|
+
c: "js_tls_enable_keylog",
|
|
11967
|
+
length: 1
|
|
11968
|
+
},
|
|
11969
|
+
tlsSetMaxSendFragment: {
|
|
11970
|
+
c: "js_tls_set_max_send_fragment",
|
|
11971
|
+
length: 2
|
|
11972
|
+
},
|
|
11762
11973
|
tlsFinished: {
|
|
11763
11974
|
c: "js_tls_finished",
|
|
11764
11975
|
length: 2
|
|
@@ -11787,6 +11998,10 @@ const primitives = {
|
|
|
11787
11998
|
c: "js_host_http_pending",
|
|
11788
11999
|
length: 1
|
|
11789
12000
|
},
|
|
12001
|
+
httpWritten: {
|
|
12002
|
+
c: "js_host_http_written",
|
|
12003
|
+
length: 1
|
|
12004
|
+
},
|
|
11790
12005
|
httpWatchDrain: {
|
|
11791
12006
|
c: "js_host_http_watch_drain",
|
|
11792
12007
|
length: 1
|
|
@@ -11819,6 +12034,94 @@ const primitives = {
|
|
|
11819
12034
|
c: "js_host_http_date",
|
|
11820
12035
|
length: 0
|
|
11821
12036
|
},
|
|
12037
|
+
udpOpen: {
|
|
12038
|
+
c: "js_host_udp_open",
|
|
12039
|
+
length: 1
|
|
12040
|
+
},
|
|
12041
|
+
udpOpenFd: {
|
|
12042
|
+
c: "js_host_udp_open_fd",
|
|
12043
|
+
length: 2
|
|
12044
|
+
},
|
|
12045
|
+
udpFd: {
|
|
12046
|
+
c: "js_host_udp_fd",
|
|
12047
|
+
length: 1
|
|
12048
|
+
},
|
|
12049
|
+
udpBind: {
|
|
12050
|
+
c: "js_host_udp_bind",
|
|
12051
|
+
length: 4
|
|
12052
|
+
},
|
|
12053
|
+
udpConnect: {
|
|
12054
|
+
c: "js_host_udp_connect",
|
|
12055
|
+
length: 3
|
|
12056
|
+
},
|
|
12057
|
+
udpDisconnect: {
|
|
12058
|
+
c: "js_host_udp_disconnect",
|
|
12059
|
+
length: 1
|
|
12060
|
+
},
|
|
12061
|
+
udpSend: {
|
|
12062
|
+
c: "js_host_udp_send",
|
|
12063
|
+
length: 4
|
|
12064
|
+
},
|
|
12065
|
+
udpSendQueue: {
|
|
12066
|
+
c: "js_host_udp_send_queue",
|
|
12067
|
+
length: 2
|
|
12068
|
+
},
|
|
12069
|
+
udpRecvStart: {
|
|
12070
|
+
c: "js_host_udp_recv_start",
|
|
12071
|
+
length: 1
|
|
12072
|
+
},
|
|
12073
|
+
udpRecvStop: {
|
|
12074
|
+
c: "js_host_udp_recv_stop",
|
|
12075
|
+
length: 1
|
|
12076
|
+
},
|
|
12077
|
+
udpAddress: {
|
|
12078
|
+
c: "js_host_udp_address",
|
|
12079
|
+
length: 2
|
|
12080
|
+
},
|
|
12081
|
+
udpSetBroadcast: {
|
|
12082
|
+
c: "js_host_udp_set_broadcast",
|
|
12083
|
+
length: 2
|
|
12084
|
+
},
|
|
12085
|
+
udpSetTTL: {
|
|
12086
|
+
c: "js_host_udp_set_ttl",
|
|
12087
|
+
length: 2
|
|
12088
|
+
},
|
|
12089
|
+
udpSetMulticastTTL: {
|
|
12090
|
+
c: "js_host_udp_set_multicast_ttl",
|
|
12091
|
+
length: 2
|
|
12092
|
+
},
|
|
12093
|
+
udpSetMulticastLoopback: {
|
|
12094
|
+
c: "js_host_udp_set_multicast_loopback",
|
|
12095
|
+
length: 2
|
|
12096
|
+
},
|
|
12097
|
+
udpSetMulticastInterface: {
|
|
12098
|
+
c: "js_host_udp_set_multicast_interface",
|
|
12099
|
+
length: 2
|
|
12100
|
+
},
|
|
12101
|
+
udpMembership: {
|
|
12102
|
+
c: "js_host_udp_membership",
|
|
12103
|
+
length: 4
|
|
12104
|
+
},
|
|
12105
|
+
udpSourceMembership: {
|
|
12106
|
+
c: "js_host_udp_source_membership",
|
|
12107
|
+
length: 5
|
|
12108
|
+
},
|
|
12109
|
+
udpBufferSize: {
|
|
12110
|
+
c: "js_host_udp_buffer_size",
|
|
12111
|
+
length: 3
|
|
12112
|
+
},
|
|
12113
|
+
udpClose: {
|
|
12114
|
+
c: "js_host_udp_close",
|
|
12115
|
+
length: 1
|
|
12116
|
+
},
|
|
12117
|
+
udpRef: {
|
|
12118
|
+
c: "js_host_udp_ref",
|
|
12119
|
+
length: 2
|
|
12120
|
+
},
|
|
12121
|
+
udpHasRef: {
|
|
12122
|
+
c: "js_host_udp_has_ref",
|
|
12123
|
+
length: 1
|
|
12124
|
+
},
|
|
11822
12125
|
netOpen: {
|
|
11823
12126
|
c: "js_host_net_open",
|
|
11824
12127
|
length: 2
|
|
@@ -11911,6 +12214,46 @@ const primitives = {
|
|
|
11911
12214
|
c: "js_host_dns_lookup",
|
|
11912
12215
|
length: 3
|
|
11913
12216
|
},
|
|
12217
|
+
dnsLookupService: {
|
|
12218
|
+
c: "js_host_dns_lookup_service",
|
|
12219
|
+
length: 3
|
|
12220
|
+
},
|
|
12221
|
+
dnsChannel: {
|
|
12222
|
+
c: "js_host_dns_channel",
|
|
12223
|
+
length: 3
|
|
12224
|
+
},
|
|
12225
|
+
dnsQuery: {
|
|
12226
|
+
c: "js_host_dns_query",
|
|
12227
|
+
length: 4
|
|
12228
|
+
},
|
|
12229
|
+
dnsReverse: {
|
|
12230
|
+
c: "js_host_dns_reverse",
|
|
12231
|
+
length: 3
|
|
12232
|
+
},
|
|
12233
|
+
dnsParse: {
|
|
12234
|
+
c: "js_host_dns_parse",
|
|
12235
|
+
length: 2
|
|
12236
|
+
},
|
|
12237
|
+
dnsGetServers: {
|
|
12238
|
+
c: "js_host_dns_get_servers",
|
|
12239
|
+
length: 1
|
|
12240
|
+
},
|
|
12241
|
+
dnsSetServers: {
|
|
12242
|
+
c: "js_host_dns_set_servers",
|
|
12243
|
+
length: 2
|
|
12244
|
+
},
|
|
12245
|
+
dnsSetLocalAddress: {
|
|
12246
|
+
c: "js_host_dns_set_local_address",
|
|
12247
|
+
length: 3
|
|
12248
|
+
},
|
|
12249
|
+
dnsCancel: {
|
|
12250
|
+
c: "js_host_dns_cancel",
|
|
12251
|
+
length: 1
|
|
12252
|
+
},
|
|
12253
|
+
dnsStrerror: {
|
|
12254
|
+
c: "js_host_dns_strerror",
|
|
12255
|
+
length: 1
|
|
12256
|
+
},
|
|
11914
12257
|
zlibNew: {
|
|
11915
12258
|
c: "js_host_zlib_new",
|
|
11916
12259
|
length: 1
|
|
@@ -12082,6 +12425,21 @@ const UV_PLATFORM = {
|
|
|
12082
12425
|
]
|
|
12083
12426
|
}
|
|
12084
12427
|
};
|
|
12428
|
+
const CARES_DIRS = [
|
|
12429
|
+
"",
|
|
12430
|
+
"dsa",
|
|
12431
|
+
"event",
|
|
12432
|
+
"legacy",
|
|
12433
|
+
"record",
|
|
12434
|
+
"str",
|
|
12435
|
+
"util"
|
|
12436
|
+
].map((d) => join(CARES, "src", "lib", d));
|
|
12437
|
+
const CARES_CONFIG = {
|
|
12438
|
+
linux: "linux",
|
|
12439
|
+
darwin: "darwin",
|
|
12440
|
+
freebsd: "freebsd",
|
|
12441
|
+
openbsd: "openbsd"
|
|
12442
|
+
};
|
|
12085
12443
|
const BROTLI_OS = {
|
|
12086
12444
|
linux: "OS_LINUX",
|
|
12087
12445
|
darwin: "OS_MACOSX",
|
|
@@ -12105,6 +12463,13 @@ function libraries(runtimeInclude, platform = process.platform) {
|
|
|
12105
12463
|
"compress",
|
|
12106
12464
|
"decompress"
|
|
12107
12465
|
].flatMap((d) => files$1(join(ZSTD, d), ".h"));
|
|
12466
|
+
const caresHeaders = [
|
|
12467
|
+
...files$1(join(CARES, "include"), ".h"),
|
|
12468
|
+
...CARES_DIRS.flatMap((d) => files$1(d, ".h")),
|
|
12469
|
+
...files$1(join(CARES, "src", "lib", "include"), ".h"),
|
|
12470
|
+
...files$1(join(CARES, "src", "lib", "thirdparty", "apple"), ".h"),
|
|
12471
|
+
...CARES_CONFIG[platform] ? files$1(join(CARES, "config", CARES_CONFIG[platform]), ".h") : []
|
|
12472
|
+
];
|
|
12108
12473
|
const uvHeaders = [
|
|
12109
12474
|
join(UV, "include"),
|
|
12110
12475
|
join(UV, "include", "uv"),
|
|
@@ -12123,7 +12488,8 @@ function libraries(runtimeInclude, platform = process.platform) {
|
|
|
12123
12488
|
...uvHeaders,
|
|
12124
12489
|
...zlibHeaders,
|
|
12125
12490
|
...brotliHeaders,
|
|
12126
|
-
...zstdHeaders
|
|
12491
|
+
...zstdHeaders,
|
|
12492
|
+
...caresHeaders
|
|
12127
12493
|
],
|
|
12128
12494
|
flags: [
|
|
12129
12495
|
`-I${INCLUDE}`,
|
|
@@ -12132,7 +12498,10 @@ function libraries(runtimeInclude, platform = process.platform) {
|
|
|
12132
12498
|
`-I${join(UV, "include")}`,
|
|
12133
12499
|
`-I${ZLIB}`,
|
|
12134
12500
|
`-I${join(BROTLI, "include")}`,
|
|
12135
|
-
`-I${ZSTD}
|
|
12501
|
+
`-I${ZSTD}`,
|
|
12502
|
+
`-I${join(CARES, "include")}`,
|
|
12503
|
+
"-DCARES_STATICLIB",
|
|
12504
|
+
"-DCARES_NO_DEPRECATED"
|
|
12136
12505
|
]
|
|
12137
12506
|
},
|
|
12138
12507
|
{
|
|
@@ -12176,6 +12545,32 @@ function libraries(runtimeInclude, platform = process.platform) {
|
|
|
12176
12545
|
`-I${ZSTD}`
|
|
12177
12546
|
]
|
|
12178
12547
|
},
|
|
12548
|
+
{
|
|
12549
|
+
name: "cares",
|
|
12550
|
+
sources: CARES_DIRS.flatMap((d) => files$1(d, ".c")),
|
|
12551
|
+
headers: caresHeaders,
|
|
12552
|
+
flags: [
|
|
12553
|
+
"-std=gnu11",
|
|
12554
|
+
"-w",
|
|
12555
|
+
"-DCARES_STATICLIB",
|
|
12556
|
+
"-D_LARGEFILE_SOURCE",
|
|
12557
|
+
"-D_FILE_OFFSET_BITS=64",
|
|
12558
|
+
...platform === "win32" ? ["-DCARES_PULL_WS2TCPIP_H=1", "-D_WINSOCK_DEPRECATED_NO_WARNINGS"] : [
|
|
12559
|
+
"-DHAVE_CONFIG_H",
|
|
12560
|
+
"-D_GNU_SOURCE",
|
|
12561
|
+
"-D_DARWIN_USE_64_BIT_INODE=1"
|
|
12562
|
+
],
|
|
12563
|
+
...CARES_CONFIG[platform] ? [`-I${join(CARES, "config", CARES_CONFIG[platform])}`] : [],
|
|
12564
|
+
`-I${join(CARES, "include")}`,
|
|
12565
|
+
`-I${join(CARES, "src", "lib")}`,
|
|
12566
|
+
`-I${join(CARES, "src", "lib", "include")}`
|
|
12567
|
+
],
|
|
12568
|
+
link: platform === "win32" ? [
|
|
12569
|
+
"ws2_32",
|
|
12570
|
+
"iphlpapi",
|
|
12571
|
+
"advapi32"
|
|
12572
|
+
] : []
|
|
12573
|
+
},
|
|
12179
12574
|
{
|
|
12180
12575
|
name: "uv",
|
|
12181
12576
|
sources: uvSources,
|
|
@@ -12233,6 +12628,12 @@ const notices$1 = [
|
|
|
12233
12628
|
license: "BSD-3-Clause",
|
|
12234
12629
|
files: [join(ZSTD, "LICENSE")]
|
|
12235
12630
|
},
|
|
12631
|
+
{
|
|
12632
|
+
name: "c-ares",
|
|
12633
|
+
what: "dns.Resolver's DNS queries",
|
|
12634
|
+
license: "MIT",
|
|
12635
|
+
files: [join(CARES, "LICENSE.md")]
|
|
12636
|
+
},
|
|
12236
12637
|
{
|
|
12237
12638
|
name: "punycode.js",
|
|
12238
12639
|
what: "node:punycode",
|
|
@@ -12290,10 +12691,15 @@ const INT_PARAMETERS = {
|
|
|
12290
12691
|
function declaredSignatures(checker, sf, out) {
|
|
12291
12692
|
for (const st of sf.statements) {
|
|
12292
12693
|
if (!ts.isFunctionDeclaration(st) || !st.name) continue;
|
|
12694
|
+
const arrays = [];
|
|
12293
12695
|
const types = st.parameters.map((p) => {
|
|
12294
12696
|
const kind = intKind(checker, p.type);
|
|
12295
12697
|
if (kind) return INT_PARAMETERS[kind];
|
|
12296
12698
|
const type = checker.getTypeAtLocation(p);
|
|
12699
|
+
if (checker.isArrayType(type)) {
|
|
12700
|
+
arrays.push(p);
|
|
12701
|
+
return T.Object;
|
|
12702
|
+
}
|
|
12297
12703
|
const t = irType(type);
|
|
12298
12704
|
if (t === null) throw compileError(p, `parameter '${p.name.getText(sf)}' of '${st.name.text}': ${checker.typeToString(type)} isn't a static type yet`);
|
|
12299
12705
|
return t;
|
|
@@ -12301,7 +12707,8 @@ function declaredSignatures(checker, sf, out) {
|
|
|
12301
12707
|
const views = st.parameters.map((p) => viewOf(checker.getTypeAtLocation(p).getSymbol()?.name ?? ""));
|
|
12302
12708
|
out.set(locKey(st), {
|
|
12303
12709
|
types,
|
|
12304
|
-
views
|
|
12710
|
+
views,
|
|
12711
|
+
arrays
|
|
12305
12712
|
});
|
|
12306
12713
|
}
|
|
12307
12714
|
}
|
|
@@ -12328,6 +12735,56 @@ function irType(t) {
|
|
|
12328
12735
|
if (name) return STATIC_TYPES[name].type;
|
|
12329
12736
|
return viewOf(t.getSymbol()?.name ?? "") ? T.Object : null;
|
|
12330
12737
|
}
|
|
12738
|
+
/** The primitive every part of a type is (its literals too), by the name an array's element kind has. */
|
|
12739
|
+
function primitiveOf(t) {
|
|
12740
|
+
const parts = t.isUnion() ? t.types : [t];
|
|
12741
|
+
for (const [flags, name] of [
|
|
12742
|
+
[ts.TypeFlags.NumberLike, "number"],
|
|
12743
|
+
[ts.TypeFlags.StringLike, "string"],
|
|
12744
|
+
[ts.TypeFlags.BooleanLike, "boolean"]
|
|
12745
|
+
]) if (parts.every((p) => p.flags & flags)) return name;
|
|
12746
|
+
}
|
|
12747
|
+
/** The element type an array type annotation writes (T[], Array<T>, readonly T[], an alias of one). */
|
|
12748
|
+
function elementNode(checker, node) {
|
|
12749
|
+
if (!node) return void 0;
|
|
12750
|
+
if (ts.isArrayTypeNode(node)) return node.elementType;
|
|
12751
|
+
if (ts.isTypeOperatorNode(node) || ts.isParenthesizedTypeNode(node)) return elementNode(checker, node.type);
|
|
12752
|
+
if (!ts.isTypeReferenceNode(node)) return void 0;
|
|
12753
|
+
const name = node.typeName.getText();
|
|
12754
|
+
if ((name === "Array" || name === "ReadonlyArray") && node.typeArguments?.length === 1) return node.typeArguments[0];
|
|
12755
|
+
let symbol = checker.getSymbolAtLocation(node.typeName);
|
|
12756
|
+
if (symbol && symbol.flags & ts.SymbolFlags.Alias) symbol = checker.getAliasedSymbol(symbol);
|
|
12757
|
+
const declaration = symbol?.declarations?.[0];
|
|
12758
|
+
return declaration && ts.isTypeAliasDeclaration(declaration) ? elementNode(checker, declaration.type) : void 0;
|
|
12759
|
+
}
|
|
12760
|
+
/** The array type annotation an expression's value was declared with, if one says: a variable's
|
|
12761
|
+
* or parameter's (or its initializer's), a call's declared return type, a cast's. */
|
|
12762
|
+
function declaredArrayType(checker, node) {
|
|
12763
|
+
if (ts.isParenthesizedExpression(node) || ts.isNonNullExpression(node)) return declaredArrayType(checker, node.expression);
|
|
12764
|
+
if (ts.isAsExpression(node) || ts.isSatisfiesExpression(node)) return node.type;
|
|
12765
|
+
if (ts.isCallExpression(node)) {
|
|
12766
|
+
const declaration = checker.getResolvedSignature(node)?.getDeclaration();
|
|
12767
|
+
return declaration && !ts.isJSDocSignature(declaration) ? declaration.type : void 0;
|
|
12768
|
+
}
|
|
12769
|
+
if (!ts.isIdentifier(node)) return void 0;
|
|
12770
|
+
const declaration = checker.getSymbolAtLocation(node)?.valueDeclaration;
|
|
12771
|
+
if (!declaration || !(ts.isVariableDeclaration(declaration) || ts.isParameter(declaration))) return void 0;
|
|
12772
|
+
if (declaration.type) return declaration.type;
|
|
12773
|
+
return declaration.initializer ? declaredArrayType(checker, declaration.initializer) : void 0;
|
|
12774
|
+
}
|
|
12775
|
+
/** The element kind of the array `node` is, if it is one: number, i32 (the annotation names it:
|
|
12776
|
+
* tsc erases it to number), string, boolean; an array of anything else is an error. */
|
|
12777
|
+
function arrayElement(checker, node) {
|
|
12778
|
+
const type = checker.getTypeAtLocation(node);
|
|
12779
|
+
if (!checker.isArrayType(type)) return void 0;
|
|
12780
|
+
const element = checker.getTypeArguments(type)[0];
|
|
12781
|
+
const kind = primitiveOf(element);
|
|
12782
|
+
if (!kind) throw compileError(node, `static code doesn't have arrays of ${checker.typeToString(element)} yet`);
|
|
12783
|
+
if (kind !== "number") return kind;
|
|
12784
|
+
const int = intKind(checker, elementNode(checker, declaredArrayType(checker, node)));
|
|
12785
|
+
if (int === "i64") throw compileError(node, "static code doesn't have int[] yet: an i32[], or a number[]");
|
|
12786
|
+
return int ?? "number";
|
|
12787
|
+
}
|
|
12331
12788
|
//#endregion
|
|
12332
12789
|
//#region cli/src/static/link.ts
|
|
12333
12790
|
/** A file's name in locations, as the program's: relative to the working directory. */
|
|
@@ -12420,7 +12877,8 @@ function linkUnit(program, files, hostPrimitives) {
|
|
|
12420
12877
|
},
|
|
12421
12878
|
linked: (node) => importedFile(checker, node, fileSet) !== void 0,
|
|
12422
12879
|
fileName,
|
|
12423
|
-
intKind: (type) => intKind(checker, type)
|
|
12880
|
+
intKind: (type) => intKind(checker, type),
|
|
12881
|
+
arrayElement: (node) => arrayElement(checker, node)
|
|
12424
12882
|
};
|
|
12425
12883
|
const exports = /* @__PURE__ */ new Map();
|
|
12426
12884
|
const exportedFrom = /* @__PURE__ */ new Map();
|
|
@@ -12892,7 +13350,7 @@ function findCompilers() {
|
|
|
12892
13350
|
"gcc",
|
|
12893
13351
|
"zig cc"
|
|
12894
13352
|
]) {
|
|
12895
|
-
const path = onPath(
|
|
13353
|
+
const path = onPath(compilerCommand(cc)[0]);
|
|
12896
13354
|
if (path && !found.has(path) && compilerVersion(cc)) found.set(path, cc);
|
|
12897
13355
|
}
|
|
12898
13356
|
if (found.size === 0) throw new Error("no C compiler found (set CC)");
|
|
@@ -12915,24 +13373,29 @@ const COMMON = [
|
|
|
12915
13373
|
];
|
|
12916
13374
|
const LINK = process.platform === "darwin" ? ["-Wl,-dead_strip"] : ["-Wl,--gc-sections"];
|
|
12917
13375
|
const STRIP = process.platform === "darwin" ? ["-Wl,-S,-x"] : ["-s"];
|
|
12918
|
-
/**
|
|
12919
|
-
|
|
13376
|
+
/** The link's flags that write its map to `file`: ld64's, the format size.ts reads. */
|
|
13377
|
+
const linkMapFlags = (file) => [`-Wl,-map,${file}`];
|
|
13378
|
+
/** A compiler's command line, split like make splits $(CC): "zig cc", "ccache gcc". Zig gets
|
|
13379
|
+
* -mcpu=baseline unless $(CC) names a CPU: its default is this machine's CPU, so what it builds
|
|
13380
|
+
* (a cached library, a program shipped elsewhere) would crash on an older one. */
|
|
13381
|
+
function compilerCommand(cc) {
|
|
12920
13382
|
const [program = cc, ...args] = cc.trim().split(/\s+/);
|
|
13383
|
+
if (/^zig(\.exe)?$/i.test(basename(program)) && !args.some((a) => /^-m(cpu|arch)=/.test(a))) args.push("-mcpu=baseline");
|
|
12921
13384
|
return [program, ...args];
|
|
12922
13385
|
}
|
|
12923
13386
|
function runCompiler(cc, args, options) {
|
|
12924
|
-
const [program, ...prefix] =
|
|
13387
|
+
const [program, ...prefix] = compilerCommand(cc);
|
|
12925
13388
|
return execFileSync(program, [...prefix, ...args], options);
|
|
12926
13389
|
}
|
|
12927
13390
|
/** Zig compiles C with its clang, and archives with its own ar: a machine without a C
|
|
12928
13391
|
* toolchain usually lacks binutils' ar too. */
|
|
12929
13392
|
function isZig(cc) {
|
|
12930
|
-
return /^zig(\.exe)?$/i.test(basename(
|
|
13393
|
+
return /^zig(\.exe)?$/i.test(basename(compilerCommand(cc)[0]));
|
|
12931
13394
|
}
|
|
12932
13395
|
/** "GCC 13.3.0", "clang 18.1.3", "Zig 0.16.0": the compiler's name and version, else its command. */
|
|
12933
13396
|
function describeCompiler(cc) {
|
|
12934
13397
|
if (isZig(cc)) try {
|
|
12935
|
-
return `Zig ${execFileSync(
|
|
13398
|
+
return `Zig ${execFileSync(compilerCommand(cc)[0], ["version"], { encoding: "utf8" }).trim()}`;
|
|
12936
13399
|
} catch {
|
|
12937
13400
|
return cc;
|
|
12938
13401
|
}
|
|
@@ -12964,7 +13427,7 @@ function libraryArchive(tc, lib, building) {
|
|
|
12964
13427
|
const prebuilt = prebuiltArchive(tc, lib);
|
|
12965
13428
|
if (prebuilt) return prebuilt;
|
|
12966
13429
|
const hash = createHash("sha256");
|
|
12967
|
-
hash.update(`${tc.cc}\n${compilerVersion(tc.cc)}\n${[
|
|
13430
|
+
hash.update(`${compilerCommand(tc.cc).join(" ")}\n${compilerVersion(tc.cc)}\n${[
|
|
12968
13431
|
...COMMON,
|
|
12969
13432
|
...CXX,
|
|
12970
13433
|
...tc.opt,
|
|
@@ -13010,7 +13473,7 @@ function buildArchive(cc, lib, archive, { common = COMMON, flags = [], arFlags =
|
|
|
13010
13473
|
"-o",
|
|
13011
13474
|
join(objects, outputs[i])
|
|
13012
13475
|
]));
|
|
13013
|
-
const [ar, ...arPrefix] = isZig(cc) ? [
|
|
13476
|
+
const [ar, ...arPrefix] = isZig(cc) ? [compilerCommand(cc)[0], "ar"] : ["ar"];
|
|
13014
13477
|
execFileSync(ar, [
|
|
13015
13478
|
...arPrefix,
|
|
13016
13479
|
...arFlags,
|
|
@@ -13038,8 +13501,8 @@ const cxx = (common) => [
|
|
|
13038
13501
|
];
|
|
13039
13502
|
const CXX = cxx(COMMON);
|
|
13040
13503
|
function compileCommand(cc, src, common) {
|
|
13041
|
-
if (!src.endsWith(".cc")) return [...
|
|
13042
|
-
const cmd =
|
|
13504
|
+
if (!src.endsWith(".cc")) return [...compilerCommand(cc), ...common];
|
|
13505
|
+
const cmd = compilerCommand(cc);
|
|
13043
13506
|
if (isZig(cc)) return [...cmd.map((w) => w === "cc" ? "c++" : w), ...cxx(common)];
|
|
13044
13507
|
return [
|
|
13045
13508
|
...cmd,
|
|
@@ -13131,7 +13594,7 @@ function regexpCompiler(cc) {
|
|
|
13131
13594
|
join(RUNTIME_DIR, "src", "regexp_anchor.h"),
|
|
13132
13595
|
...readdirSync(regexp).filter((f) => f.endsWith(".h")).map((f) => join(regexp, f))
|
|
13133
13596
|
];
|
|
13134
|
-
const hash = createHash("sha256").update(`${cc}\n`);
|
|
13597
|
+
const hash = createHash("sha256").update(`${compilerCommand(cc).join(" ")}\n`);
|
|
13135
13598
|
for (const f of [...sources, ...headers]) hash.update(f.slice(RUNTIME_DIR.length)).update(readFileSync(f));
|
|
13136
13599
|
const tool = join(cacheRoot(), `regexp-compile-${hash.digest("hex").slice(0, 16)}${process.platform === "win32" ? ".exe" : ""}`);
|
|
13137
13600
|
if (existsSync(tool)) return tool;
|
|
@@ -13156,14 +13619,18 @@ function regexpCompiler(cc) {
|
|
|
13156
13619
|
/** A program's archives, in link order: the host packages' libraries, then libjsrt (which they
|
|
13157
13620
|
* use), then the system libraries they need (-lโฆ). Each is built the first time; `building`
|
|
13158
13621
|
* hears about it. */
|
|
13622
|
+
function programLibraries(hosts) {
|
|
13623
|
+
return [...hosts.flatMap((h) => h.libraries(RUNTIME_INCLUDE)).filter((l) => l.sources.length), ...runtimeLibraries()];
|
|
13624
|
+
}
|
|
13159
13625
|
function programArchives(tc, hosts, building) {
|
|
13160
|
-
const libraries =
|
|
13626
|
+
const libraries = programLibraries(hosts);
|
|
13161
13627
|
return [...libraries.map((l) => libraryArchive(tc, l, building)), ...libraries.flatMap((l) => l.link ?? []).map((l) => `-l${l}`)];
|
|
13162
13628
|
}
|
|
13163
13629
|
/** Compiles the program's C files and links them with `archives` (programArchives), stripping at
|
|
13164
13630
|
* this link when asked. A split program's files compile `jobs` at once; `compiled` hears as each
|
|
13165
|
-
* is done.
|
|
13166
|
-
|
|
13631
|
+
* is done. `mapFile`: the link writes its map there (linkMapFlags), and each C file's object stays
|
|
13632
|
+
* beside it, for the debug info. Asynchronous, so the build's report keeps drawing. */
|
|
13633
|
+
async function compileProgram(tc, cFiles, output, archives, { extraFlags = [], jobs = compileJobs(), compiled, mapFile } = {}) {
|
|
13167
13634
|
const flags = [
|
|
13168
13635
|
...COMMON,
|
|
13169
13636
|
...tc.opt,
|
|
@@ -13171,20 +13638,17 @@ async function compileProgram(tc, cFiles, output, archives, { extraFlags = [], j
|
|
|
13171
13638
|
...extraFlags
|
|
13172
13639
|
];
|
|
13173
13640
|
const link = [
|
|
13174
|
-
...archives,
|
|
13641
|
+
...archives.map((a) => a.startsWith("-l") ? a : resolve(a)),
|
|
13175
13642
|
"-lm",
|
|
13176
13643
|
...LINK,
|
|
13177
13644
|
...tc.strip ? STRIP : [],
|
|
13645
|
+
...mapFile ? linkMapFlags(resolve(mapFile)) : [],
|
|
13178
13646
|
"-o",
|
|
13179
|
-
output
|
|
13647
|
+
resolve(output)
|
|
13180
13648
|
];
|
|
13181
|
-
|
|
13182
|
-
|
|
13183
|
-
|
|
13184
|
-
cFiles[0],
|
|
13185
|
-
...link
|
|
13186
|
-
]);
|
|
13187
|
-
const objects = cFiles.map((f) => f.replace(/\.c$/, ".o"));
|
|
13649
|
+
const cwd = dirname(resolve(cFiles[0]));
|
|
13650
|
+
const sources = cFiles.map((f) => relative(cwd, resolve(f)));
|
|
13651
|
+
const objects = sources.map((f) => f.replace(/\.c$/, ".o"));
|
|
13188
13652
|
const order = cFiles.map((_, i) => i).sort((a, b) => statSync(cFiles[b]).size - statSync(cFiles[a]).size);
|
|
13189
13653
|
let next = 0, done = 0;
|
|
13190
13654
|
const worker = async () => {
|
|
@@ -13195,10 +13659,10 @@ async function compileProgram(tc, cFiles, output, archives, { extraFlags = [], j
|
|
|
13195
13659
|
...flags,
|
|
13196
13660
|
`-I${RUNTIME_INCLUDE}`,
|
|
13197
13661
|
"-c",
|
|
13198
|
-
|
|
13662
|
+
sources[i],
|
|
13199
13663
|
"-o",
|
|
13200
13664
|
objects[i]
|
|
13201
|
-
]);
|
|
13665
|
+
], cwd);
|
|
13202
13666
|
} catch (e) {
|
|
13203
13667
|
next = order.length;
|
|
13204
13668
|
throw e;
|
|
@@ -13212,7 +13676,7 @@ async function compileProgram(tc, cFiles, output, archives, { extraFlags = [], j
|
|
|
13212
13676
|
...flags,
|
|
13213
13677
|
...objects,
|
|
13214
13678
|
...link
|
|
13215
|
-
]);
|
|
13679
|
+
], cwd);
|
|
13216
13680
|
}
|
|
13217
13681
|
/** How many of a split program's files compile at once: one per processor and per `perJob` bytes
|
|
13218
13682
|
* of available memory (a cgroup's limit counts). A file needs up to about 1.1 GB at -O2 with
|
|
@@ -13222,15 +13686,18 @@ function compileJobs(perJob = 15e8) {
|
|
|
13222
13686
|
}
|
|
13223
13687
|
/** Runs the compiler; its stderr passes through (but for notes the program can't act on), and its
|
|
13224
13688
|
* tail is kept to recognize a broken toolchain. Rejects when it fails. */
|
|
13225
|
-
function runCompilerAsync(cc, args) {
|
|
13689
|
+
function runCompilerAsync(cc, args, cwd) {
|
|
13226
13690
|
return new Promise((resolve, reject) => {
|
|
13227
13691
|
let errors = "";
|
|
13228
|
-
const [program, ...prefix] =
|
|
13229
|
-
const child = spawn(program, [...prefix, ...args], {
|
|
13230
|
-
|
|
13231
|
-
|
|
13232
|
-
|
|
13233
|
-
|
|
13692
|
+
const [program, ...prefix] = compilerCommand(cc);
|
|
13693
|
+
const child = spawn(program, [...prefix, ...args], {
|
|
13694
|
+
cwd,
|
|
13695
|
+
stdio: [
|
|
13696
|
+
"ignore",
|
|
13697
|
+
"inherit",
|
|
13698
|
+
"pipe"
|
|
13699
|
+
]
|
|
13700
|
+
});
|
|
13234
13701
|
const filter = new DiagnosticFilter((text) => process.stderr.write(text));
|
|
13235
13702
|
child.stderr.on("data", (chunk) => {
|
|
13236
13703
|
filter.write(chunk.toString());
|
|
@@ -13585,6 +14052,8 @@ function buildTypedUnit(files, primitives) {
|
|
|
13585
14052
|
const exports = {};
|
|
13586
14053
|
const exportedFns = /* @__PURE__ */ new Map();
|
|
13587
14054
|
for (const [name, loc] of exported) {
|
|
14055
|
+
const array = signatures.get(loc)?.arrays[0];
|
|
14056
|
+
if (array) throw compileError(array, `export '${name}' takes an array: static code doesn't take arrays from JavaScript yet`);
|
|
13588
14057
|
const fn = ir.functions.find((f) => at(f) === loc);
|
|
13589
14058
|
exportedFns.set(name, fn.name);
|
|
13590
14059
|
exports[name] = {
|
|
@@ -14577,6 +15046,316 @@ function lineCount(text) {
|
|
|
14577
15046
|
return n;
|
|
14578
15047
|
}
|
|
14579
15048
|
//#endregion
|
|
15049
|
+
//#region cli/src/size.ts
|
|
15050
|
+
const ZEROFILL = /* @__PURE__ */ new Set([
|
|
15051
|
+
"__DATA,__bss",
|
|
15052
|
+
"__DATA,__common",
|
|
15053
|
+
"__DATA,__thread_bss"
|
|
15054
|
+
]);
|
|
15055
|
+
const CODE = "__TEXT,__text";
|
|
15056
|
+
function parseLinkMap(text) {
|
|
15057
|
+
const objects = [], sections = [], symbols = [];
|
|
15058
|
+
let part = "";
|
|
15059
|
+
for (const line of text.split("\n")) {
|
|
15060
|
+
if (line.startsWith("# ")) {
|
|
15061
|
+
part = line.startsWith("# Object files") ? "objects" : line.startsWith("# Sections") ? "sections" : line.startsWith("# Symbols") ? "symbols" : line.startsWith("# Dead Stripped") ? "" : part;
|
|
15062
|
+
continue;
|
|
15063
|
+
}
|
|
15064
|
+
if (part === "objects") {
|
|
15065
|
+
const m = /^\[\s*(\d+)\] (.*)$/.exec(line);
|
|
15066
|
+
if (m) objects[Number(m[1])] = m[2];
|
|
15067
|
+
} else if (part === "sections") {
|
|
15068
|
+
const [address, bytes, segment, section] = line.split(" ");
|
|
15069
|
+
if (section) sections.push({
|
|
15070
|
+
address: parseInt(address, 16),
|
|
15071
|
+
size: parseInt(bytes, 16),
|
|
15072
|
+
name: `${segment},${section.trim()}`
|
|
15073
|
+
});
|
|
15074
|
+
} else if (part === "symbols") {
|
|
15075
|
+
const m = /^0x([0-9A-F]+)\t0x([0-9A-F]+)\t\[\s*(\d+)\] (.*)$/.exec(line);
|
|
15076
|
+
if (m) symbols.push({
|
|
15077
|
+
address: parseInt(m[1], 16),
|
|
15078
|
+
size: parseInt(m[2], 16),
|
|
15079
|
+
object: Number(m[3]),
|
|
15080
|
+
name: m[4]
|
|
15081
|
+
});
|
|
15082
|
+
}
|
|
15083
|
+
}
|
|
15084
|
+
return {
|
|
15085
|
+
objects,
|
|
15086
|
+
sections,
|
|
15087
|
+
symbols
|
|
15088
|
+
};
|
|
15089
|
+
}
|
|
15090
|
+
/** The line table's address ranges, each with its source file, sorted by address. `text` is
|
|
15091
|
+
* `dwarfdump --debug-line`'s output. */
|
|
15092
|
+
function parseLineTable(text) {
|
|
15093
|
+
const ranges = [];
|
|
15094
|
+
let dirs = [], files = [];
|
|
15095
|
+
let pendingFile;
|
|
15096
|
+
let prev;
|
|
15097
|
+
for (const line of text.split("\n")) {
|
|
15098
|
+
if (line.startsWith("debug_line[")) {
|
|
15099
|
+
dirs = [];
|
|
15100
|
+
files = [];
|
|
15101
|
+
prev = void 0;
|
|
15102
|
+
continue;
|
|
15103
|
+
}
|
|
15104
|
+
let m = /^include_directories\[\s*(\d+)\] = "(.*)"$/.exec(line);
|
|
15105
|
+
if (m) {
|
|
15106
|
+
dirs[Number(m[1])] = m[2];
|
|
15107
|
+
continue;
|
|
15108
|
+
}
|
|
15109
|
+
m = /^file_names\[\s*(\d+)\]:$/.exec(line);
|
|
15110
|
+
if (m) {
|
|
15111
|
+
pendingFile = Number(m[1]);
|
|
15112
|
+
continue;
|
|
15113
|
+
}
|
|
15114
|
+
m = /^\s+name: "(.*)"$/.exec(line);
|
|
15115
|
+
if (m && pendingFile !== void 0) {
|
|
15116
|
+
files[pendingFile] = m[1];
|
|
15117
|
+
continue;
|
|
15118
|
+
}
|
|
15119
|
+
m = /^\s+dir_index: (\d+)$/.exec(line);
|
|
15120
|
+
if (m && pendingFile !== void 0) {
|
|
15121
|
+
const name = files[pendingFile];
|
|
15122
|
+
files[pendingFile] = isAbsolute(name) ? name : join(dirs[Number(m[1])] ?? "", name);
|
|
15123
|
+
pendingFile = void 0;
|
|
15124
|
+
continue;
|
|
15125
|
+
}
|
|
15126
|
+
m = /^0x([0-9a-f]+)\s+(\d+)\s+\d+\s+(\d+)\s.*$/.exec(line);
|
|
15127
|
+
if (!m) continue;
|
|
15128
|
+
const address = parseInt(m[1], 16);
|
|
15129
|
+
if (prev && address > prev.address) ranges.push({
|
|
15130
|
+
start: prev.address,
|
|
15131
|
+
end: address,
|
|
15132
|
+
file: prev.file,
|
|
15133
|
+
line: prev.line
|
|
15134
|
+
});
|
|
15135
|
+
prev = line.includes("end_sequence") ? void 0 : {
|
|
15136
|
+
address,
|
|
15137
|
+
file: files[Number(m[3])] ?? "?",
|
|
15138
|
+
line: Number(m[2])
|
|
15139
|
+
};
|
|
15140
|
+
}
|
|
15141
|
+
return ranges.sort((a, b) => a.start - b.start);
|
|
15142
|
+
}
|
|
15143
|
+
/** The bundle's modules by line: its //#region comments, whose paths are relative to the entry's
|
|
15144
|
+
* directory (the bundler's cwd) or a virtual module's id. The source map leaves out what the
|
|
15145
|
+
* bundler generates or converts: JSON modules, CommonJS wrappers, namespace objects. */
|
|
15146
|
+
function bundleRegions(code, entryDir) {
|
|
15147
|
+
const { starts, files } = parseRegions(code, entryDir);
|
|
15148
|
+
return (line) => {
|
|
15149
|
+
let lo = 0, hi = starts.length;
|
|
15150
|
+
while (lo < hi) {
|
|
15151
|
+
const mid = lo + hi >> 1;
|
|
15152
|
+
if (starts[mid] <= line) lo = mid + 1;
|
|
15153
|
+
else hi = mid;
|
|
15154
|
+
}
|
|
15155
|
+
return lo ? files[lo - 1] : void 0;
|
|
15156
|
+
};
|
|
15157
|
+
}
|
|
15158
|
+
/** Each region's first line (1-based) and module; undefined: outside any, or the bundler's own. */
|
|
15159
|
+
function parseRegions(code, entryDir) {
|
|
15160
|
+
const starts = [], files = [];
|
|
15161
|
+
const lines = code.split("\n");
|
|
15162
|
+
for (let i = 0; i < lines.length; i++) {
|
|
15163
|
+
const m = /^\/\/#(region|endregion)(?: (.*))?$/.exec(lines[i]);
|
|
15164
|
+
if (!m) continue;
|
|
15165
|
+
const id = m[2]?.replace(/^(?:\0|\\0)visaljs-[\w-]+:/, "");
|
|
15166
|
+
starts.push(i + 1);
|
|
15167
|
+
files.push(m[1] === "endregion" || id === void 0 || /^(?:\0|\\0)/.test(id) ? void 0 : resolve(entryDir, id));
|
|
15168
|
+
}
|
|
15169
|
+
return {
|
|
15170
|
+
starts,
|
|
15171
|
+
files,
|
|
15172
|
+
lines
|
|
15173
|
+
};
|
|
15174
|
+
}
|
|
15175
|
+
/** The bundle's bytes by module (--emit bundle): what the compiler is given, before any C. The
|
|
15176
|
+
* "use static" files aren't in it (each is a stub of host imports): they come as `staticFiles`. */
|
|
15177
|
+
function bundleSizes(code, entryDir, staticFiles, cwd) {
|
|
15178
|
+
const { starts, files, lines } = parseRegions(code, entryDir);
|
|
15179
|
+
const totals = /* @__PURE__ */ new Map();
|
|
15180
|
+
const add = (group, name, bytes) => {
|
|
15181
|
+
const key = `${group}\0${name}`;
|
|
15182
|
+
(totals.get(key) ?? totals.set(key, {
|
|
15183
|
+
group,
|
|
15184
|
+
name,
|
|
15185
|
+
bytes: 0
|
|
15186
|
+
}).get(key)).bytes += bytes;
|
|
15187
|
+
};
|
|
15188
|
+
let region = -1;
|
|
15189
|
+
for (let i = 0; i < lines.length; i++) {
|
|
15190
|
+
if (starts[region + 1] === i + 1) region++;
|
|
15191
|
+
const file = region >= 0 ? files[region] : void 0;
|
|
15192
|
+
const bytes = Buffer.byteLength(lines[i]) + 1;
|
|
15193
|
+
const { group, name } = jsEntry(file, cwd);
|
|
15194
|
+
add(group, name, bytes);
|
|
15195
|
+
}
|
|
15196
|
+
for (const f of staticFiles) add("\"use static\" files (compiled apart, not in the bundle)", jsModule(f, cwd), statSync(f).size);
|
|
15197
|
+
return [...totals.values()];
|
|
15198
|
+
}
|
|
15199
|
+
const isCSource = (file) => /\.(?:c|cc|h|inc)$/.test(file);
|
|
15200
|
+
/** A JS file's group and module, the same in both reports. `file`: undefined, or the bundle
|
|
15201
|
+
* itself, for code the bundler generated outside any module. */
|
|
15202
|
+
function jsEntry(file, cwd) {
|
|
15203
|
+
if (file === void 0 || basename(file) === "bundle.js") return {
|
|
15204
|
+
group: "Bundler glue",
|
|
15205
|
+
name: "rolldown's runtime, imports and exports"
|
|
15206
|
+
};
|
|
15207
|
+
const name = jsModule(file, cwd);
|
|
15208
|
+
return {
|
|
15209
|
+
group: name.startsWith("node:") ? "Node built-ins" : /(?:^|[\\/])node_modules[\\/]/.test(file) ? "npm packages" : "Your code",
|
|
15210
|
+
name
|
|
15211
|
+
};
|
|
15212
|
+
}
|
|
15213
|
+
/** A JS file's module: a Node built-in, a package, or the program's own file. */
|
|
15214
|
+
function jsModule(file, cwd) {
|
|
15215
|
+
const prelude = relative(preludeDir, file);
|
|
15216
|
+
if (!prelude.startsWith("..") && !isAbsolute(prelude)) return `node:${prelude.replace(/\.js$/, "").replaceAll(sep, "/")}`;
|
|
15217
|
+
const packages = [...file.matchAll(/(?:^|[\\/])node_modules[\\/]((?:@[^\\/]+[\\/])?[^\\/]+)/g)].map((m) => m[1].replaceAll("\\", "/"));
|
|
15218
|
+
if (packages.length) return packages.length > 1 ? `${packages.at(-1)} (in ${packages.at(-2)})` : packages[0];
|
|
15219
|
+
const rel = relative(cwd, resolve(cwd, file));
|
|
15220
|
+
return rel.startsWith("..") ? file : rel;
|
|
15221
|
+
}
|
|
15222
|
+
/** An archive member's library and source: lib<name>.a(<i>.o), or a prebuilt <name>-<key>.a(<i>.o),
|
|
15223
|
+
* is the library's i-th source (buildArchive). */
|
|
15224
|
+
function librarySource(object, libraries) {
|
|
15225
|
+
const m = /([^\\/]+)\.a\((\d+)\.o\)$/.exec(object);
|
|
15226
|
+
if (!m) return void 0;
|
|
15227
|
+
const name = m[1].replace(/^lib/, "").replace(/-[0-9a-f]{16,}$/, "");
|
|
15228
|
+
const lib = libraries.find((l) => l.name === name);
|
|
15229
|
+
const src = lib?.sources[Number(m[2])];
|
|
15230
|
+
return {
|
|
15231
|
+
library: `lib${name}`,
|
|
15232
|
+
source: src && lib ? relative(commonDir(lib.sources), src) : `${m[2]}.o`
|
|
15233
|
+
};
|
|
15234
|
+
}
|
|
15235
|
+
function commonDir(files) {
|
|
15236
|
+
let dir = files[0] ? resolve(files[0], "..") : "";
|
|
15237
|
+
while (dir && !files.every((f) => f.startsWith(dir + sep))) dir = resolve(dir, "..");
|
|
15238
|
+
return dir;
|
|
15239
|
+
}
|
|
15240
|
+
const EMITTED_DATA = [
|
|
15241
|
+
[/^_\w*?jss_\d+$/, "string constants"],
|
|
15242
|
+
[/^_\w*?jsfi_/, "function descriptors"],
|
|
15243
|
+
[/^_\w*?jsrl?_\d+$/, "compiled regular expressions"],
|
|
15244
|
+
[/^_\w*?mod_/, "module tables (atoms, shapes)"]
|
|
15245
|
+
];
|
|
15246
|
+
/** A data symbol's kind: ld64 names literals by their kind ("literal string: โฆ", "16-byte-literal"). */
|
|
15247
|
+
function dataKind(name) {
|
|
15248
|
+
if (name.startsWith("literal string")) return "C string literals";
|
|
15249
|
+
if (/^\d+-byte-literal/.test(name)) return "number literals";
|
|
15250
|
+
return EMITTED_DATA.find(([re]) => re.test(name))?.[1] ?? "other data";
|
|
15251
|
+
}
|
|
15252
|
+
/** Each symbol's bytes, attributed: the program's code to its JS modules, its data by kind, a
|
|
15253
|
+
* library's to its source files. `programObjects` are the program's own objects' base names. */
|
|
15254
|
+
function attribute(map, lines, libraries, programObjects, cwd, regionOf = () => void 0) {
|
|
15255
|
+
const totals = /* @__PURE__ */ new Map();
|
|
15256
|
+
const add = (group, name, bytes) => {
|
|
15257
|
+
const key = `${group}\0${name}`;
|
|
15258
|
+
const e = totals.get(key) ?? totals.set(key, {
|
|
15259
|
+
group,
|
|
15260
|
+
name,
|
|
15261
|
+
bytes: 0
|
|
15262
|
+
}).get(key);
|
|
15263
|
+
e.bytes += bytes;
|
|
15264
|
+
};
|
|
15265
|
+
const sections = [...map.sections].sort((a, b) => a.address - b.address);
|
|
15266
|
+
const sectionOf = (address) => sections.find((s) => address >= s.address && address < s.address + s.size)?.name ?? "";
|
|
15267
|
+
let next = 0;
|
|
15268
|
+
const bySymbol = [...map.symbols].sort((a, b) => a.address - b.address);
|
|
15269
|
+
for (const sym of bySymbol) {
|
|
15270
|
+
if (sym.size === 0) continue;
|
|
15271
|
+
const section = sectionOf(sym.address);
|
|
15272
|
+
if (ZEROFILL.has(section)) continue;
|
|
15273
|
+
const object = map.objects[sym.object] ?? "";
|
|
15274
|
+
const program = programObjects.has(basename(object));
|
|
15275
|
+
if (program && section === CODE) {
|
|
15276
|
+
while (next < lines.length && lines[next].end <= sym.address) next++;
|
|
15277
|
+
const files = /* @__PURE__ */ new Map();
|
|
15278
|
+
for (let i = next; i < lines.length && lines[i].start < sym.address + sym.size; i++) {
|
|
15279
|
+
const r = lines[i];
|
|
15280
|
+
const bytes = Math.min(r.end, sym.address + sym.size) - Math.max(r.start, sym.address);
|
|
15281
|
+
const file = basename(r.file) === "bundle.js" ? regionOf(r.line) ?? r.file : r.file;
|
|
15282
|
+
if (bytes > 0 && !isCSource(file)) files.set(file, (files.get(file) ?? 0) + bytes);
|
|
15283
|
+
}
|
|
15284
|
+
const js = [...files.values()].reduce((a, b) => a + b, 0);
|
|
15285
|
+
const typed = basename(object) === "typed.o";
|
|
15286
|
+
if (js === 0) add("Runtime helpers (C, compiled with the program)", typed ? "in the \"use static\" unit" : "in the program", sym.size);
|
|
15287
|
+
for (const [file, bytes] of files) {
|
|
15288
|
+
const entry = typed ? {
|
|
15289
|
+
group: "\"use static\" files",
|
|
15290
|
+
name: jsModule(file, cwd)
|
|
15291
|
+
} : jsEntry(file, cwd);
|
|
15292
|
+
add(entry.group, entry.name, sym.size * bytes / js);
|
|
15293
|
+
}
|
|
15294
|
+
} else if (program) add("Program data", dataKind(sym.name), sym.size);
|
|
15295
|
+
else if (sym.object === 0) add("Linker", sym.name.replace(/^_+/, ""), sym.size);
|
|
15296
|
+
else {
|
|
15297
|
+
const lib = librarySource(object, libraries);
|
|
15298
|
+
if (lib) add(lib.library, lib.source, sym.size);
|
|
15299
|
+
else add("Linker", object.endsWith(".tbd") ? "stubs for system libraries" : basename(object), sym.size);
|
|
15300
|
+
}
|
|
15301
|
+
}
|
|
15302
|
+
const listed = /* @__PURE__ */ new Map();
|
|
15303
|
+
for (const sym of bySymbol) {
|
|
15304
|
+
const s = sectionOf(sym.address);
|
|
15305
|
+
listed.set(s, (listed.get(s) ?? 0) + sym.size);
|
|
15306
|
+
}
|
|
15307
|
+
for (const s of sections) {
|
|
15308
|
+
const rest = s.size - (listed.get(s.name) ?? 0);
|
|
15309
|
+
if (!ZEROFILL.has(s.name) && rest > 0) add("Linker", s.name, rest);
|
|
15310
|
+
}
|
|
15311
|
+
return [...totals.values()];
|
|
15312
|
+
}
|
|
15313
|
+
/** `binary`'s bytes, attributed: linked with linkMapFlags(`mapFile`) and not stripped, while its
|
|
15314
|
+
* `objects` (the program's own) still exist, for dsymutil reads their debug info. */
|
|
15315
|
+
function measureSizes(binary, mapFile, dsym, objects, libraries, bundle) {
|
|
15316
|
+
execFileSync("dsymutil", [
|
|
15317
|
+
binary,
|
|
15318
|
+
"-o",
|
|
15319
|
+
dsym
|
|
15320
|
+
], { stdio: [
|
|
15321
|
+
"ignore",
|
|
15322
|
+
"ignore",
|
|
15323
|
+
"inherit"
|
|
15324
|
+
] });
|
|
15325
|
+
const lines = parseLineTable(execFileSync("dwarfdump", ["--debug-line", dsym], {
|
|
15326
|
+
encoding: "utf8",
|
|
15327
|
+
maxBuffer: 1 << 30
|
|
15328
|
+
}));
|
|
15329
|
+
const map = parseLinkMap(readFileSync(mapFile, "latin1"));
|
|
15330
|
+
const regions = bundle ? bundleRegions(bundle.code, bundle.entryDir) : void 0;
|
|
15331
|
+
return attribute(map, lines, libraries, new Set(objects.map((o) => basename(o))), process.cwd(), regions);
|
|
15332
|
+
}
|
|
15333
|
+
const TOP = 12;
|
|
15334
|
+
function formatSizeReport(entries, fileBytes, all) {
|
|
15335
|
+
return `\nWhere the binary's ${size(entries.reduce((a, e) => a + e.bytes, 0))} of code and data come from (the file is ${size(fileBytes)}: the rest is page padding and the linker's tables):\n\n${formatEntries(entries, all)}`;
|
|
15336
|
+
}
|
|
15337
|
+
function formatBundleSizes(entries, all) {
|
|
15338
|
+
return `\nWhere the program's ${size(entries.reduce((a, e) => a + e.bytes, 0))} of JavaScript come from:\n\n${formatEntries(entries, all)}`;
|
|
15339
|
+
}
|
|
15340
|
+
function formatEntries(entries, all) {
|
|
15341
|
+
const groups = /* @__PURE__ */ new Map();
|
|
15342
|
+
for (const e of entries) (groups.get(e.group) ?? groups.set(e.group, []).get(e.group)).push(e);
|
|
15343
|
+
const sum = (es) => es.reduce((a, e) => a + e.bytes, 0);
|
|
15344
|
+
const counted = sum(entries);
|
|
15345
|
+
const pct = (bytes) => `${(100 * bytes / counted).toFixed(1).padStart(5)}%`;
|
|
15346
|
+
const width = Math.min(72, Math.max(...entries.map((e) => e.name.length + 6)));
|
|
15347
|
+
const row = (indent, name, bytes) => `${indent}${name.padEnd(width - indent.length)} ${size(Math.round(bytes)).padStart(9)} ${pct(bytes)}\n`;
|
|
15348
|
+
let out = "";
|
|
15349
|
+
for (const [group, es] of [...groups].sort((a, b) => sum(b[1]) - sum(a[1]))) {
|
|
15350
|
+
out += row(" ", group, sum(es));
|
|
15351
|
+
const sorted = [...es].sort((a, b) => b.bytes - a.bytes);
|
|
15352
|
+
const shown = all ? sorted : sorted.slice(0, TOP);
|
|
15353
|
+
for (const e of shown) out += row(" ", e.name, e.bytes);
|
|
15354
|
+
if (shown.length < sorted.length) out += row(" ", `${sorted.length - shown.length} more (--verbose lists them)`, sum(sorted.slice(shown.length)));
|
|
15355
|
+
}
|
|
15356
|
+
return out;
|
|
15357
|
+
}
|
|
15358
|
+
//#endregion
|
|
14580
15359
|
//#region cli/src/main.ts
|
|
14581
15360
|
const VERSION = "0.0.7";
|
|
14582
15361
|
/** A program's C splits into files of about this many IR instructions. */
|
|
@@ -14595,10 +15374,7 @@ TypeScript (.ts, .mts, .cts, .tsx) is compiled too: its types are stripped, not
|
|
|
14595
15374
|
for that), with the nearest tsconfig.json's settings (paths, decorators).
|
|
14596
15375
|
|
|
14597
15376
|
options:
|
|
14598
|
-
-o <file> output binary
|
|
14599
|
-
--emit-c <dir> stop after C emission
|
|
14600
|
-
--dump-ast print the syntax tree and stop
|
|
14601
|
-
--dump-ir print the IR and stop
|
|
15377
|
+
-o <file> output binary (with --emit: what to write)
|
|
14602
15378
|
--debug build without optimization (-O0), keeping symbols and debug info
|
|
14603
15379
|
--symbols keep symbols and debug info in the optimized build (for profilers such as perf)
|
|
14604
15380
|
--no-optimize skip the IR optimizer (to compare, or to rule it out)
|
|
@@ -14617,7 +15393,26 @@ options:
|
|
|
14617
15393
|
--verbose list each place a warning is about
|
|
14618
15394
|
--version print the version
|
|
14619
15395
|
--help print this help
|
|
15396
|
+
|
|
15397
|
+
inspecting the build:
|
|
15398
|
+
--emit <stage> stop after a stage and write what it made:
|
|
15399
|
+
bundle the bundle (tree-shaken) and the "use static" files to the directory
|
|
15400
|
+
-o names, and how much of the bundle each module and package is
|
|
15401
|
+
ast the syntax tree, to stdout or the file -o names
|
|
15402
|
+
ir the optimized IR, to stdout or the file -o names
|
|
15403
|
+
c the C files, to the directory -o names
|
|
15404
|
+
--report <kind> build the binary, then report on it (repeatable):
|
|
15405
|
+
size where its bytes come from: each module, package, Node built-in and
|
|
15406
|
+
runtime library (macOS for now; --verbose lists every file)
|
|
14620
15407
|
`;
|
|
15408
|
+
const STAGES = [
|
|
15409
|
+
"bundle",
|
|
15410
|
+
"ast",
|
|
15411
|
+
"ir",
|
|
15412
|
+
"c"
|
|
15413
|
+
];
|
|
15414
|
+
const WRITES_FILES = /* @__PURE__ */ new Set(["bundle", "c"]);
|
|
15415
|
+
const REPORTS = ["size"];
|
|
14621
15416
|
/** Runs the CLI and returns the process exit code. */
|
|
14622
15417
|
async function main(argv, io) {
|
|
14623
15418
|
let parsed;
|
|
@@ -14630,6 +15425,11 @@ async function main(argv, io) {
|
|
|
14630
15425
|
type: "string",
|
|
14631
15426
|
short: "o"
|
|
14632
15427
|
},
|
|
15428
|
+
emit: { type: "string" },
|
|
15429
|
+
report: {
|
|
15430
|
+
type: "string",
|
|
15431
|
+
multiple: true
|
|
15432
|
+
},
|
|
14633
15433
|
"emit-c": { type: "string" },
|
|
14634
15434
|
"dump-ast": { type: "boolean" },
|
|
14635
15435
|
"dump-ir": { type: "boolean" },
|
|
@@ -14680,7 +15480,18 @@ async function main(argv, io) {
|
|
|
14680
15480
|
io.stderr(`visaljs build: expected one entry file or project directory\n${USAGE}`);
|
|
14681
15481
|
return 2;
|
|
14682
15482
|
}
|
|
14683
|
-
|
|
15483
|
+
{
|
|
15484
|
+
const inspect = inspectOptions(values);
|
|
15485
|
+
if (typeof inspect === "string") {
|
|
15486
|
+
io.stderr(`visaljs: ${inspect}\n`);
|
|
15487
|
+
return 2;
|
|
15488
|
+
}
|
|
15489
|
+
return await build(rest[0] ?? ".", {
|
|
15490
|
+
...values,
|
|
15491
|
+
output: inspect.emit ? void 0 : values.output,
|
|
15492
|
+
...inspect
|
|
15493
|
+
}, io);
|
|
15494
|
+
}
|
|
14684
15495
|
case "licenses":
|
|
14685
15496
|
if (rest.length) {
|
|
14686
15497
|
io.stderr(`visaljs licenses: takes no arguments\n${USAGE}`);
|
|
@@ -14693,11 +15504,53 @@ async function main(argv, io) {
|
|
|
14693
15504
|
return 2;
|
|
14694
15505
|
}
|
|
14695
15506
|
}
|
|
15507
|
+
/** --emit and --report, with the flags they replace (--emit-c <dir>, --dump-ast, --dump-ir), or
|
|
15508
|
+
* what's wrong with them. */
|
|
15509
|
+
function inspectOptions(values) {
|
|
15510
|
+
const asked = [];
|
|
15511
|
+
if (values.emit !== void 0) asked.push({
|
|
15512
|
+
stage: values.emit,
|
|
15513
|
+
to: values.output
|
|
15514
|
+
});
|
|
15515
|
+
if (values["emit-c"] !== void 0) asked.push({
|
|
15516
|
+
stage: "c",
|
|
15517
|
+
to: values["emit-c"]
|
|
15518
|
+
});
|
|
15519
|
+
if (values["dump-ast"]) asked.push({
|
|
15520
|
+
stage: "ast",
|
|
15521
|
+
to: void 0
|
|
15522
|
+
});
|
|
15523
|
+
if (values["dump-ir"]) asked.push({
|
|
15524
|
+
stage: "ir",
|
|
15525
|
+
to: void 0
|
|
15526
|
+
});
|
|
15527
|
+
if (asked.length > 1) return "--emit takes one stage: the build stops after it";
|
|
15528
|
+
const reports = values.report ?? [];
|
|
15529
|
+
const unknown = reports.find((r) => !REPORTS.includes(r));
|
|
15530
|
+
if (unknown !== void 0) return `--report takes ${REPORTS.join(", ")}, not '${unknown}'`;
|
|
15531
|
+
if (reports.includes("size") && process.platform !== "darwin") return "--report size reads ld64's link map: it needs macOS for now";
|
|
15532
|
+
const [want] = asked;
|
|
15533
|
+
if (!want) return {
|
|
15534
|
+
emit: void 0,
|
|
15535
|
+
emitTo: void 0,
|
|
15536
|
+
reports
|
|
15537
|
+
};
|
|
15538
|
+
if (!STAGES.includes(want.stage)) return `--emit takes ${STAGES.join(", ")}, not '${want.stage}'`;
|
|
15539
|
+
const stage = want.stage;
|
|
15540
|
+
if (reports.length) return `--report reports on the binary: not with --emit ${stage}, which stops before it`;
|
|
15541
|
+
if (WRITES_FILES.has(stage) && !want.to) return `--emit ${stage} writes files: give their directory with -o`;
|
|
15542
|
+
return {
|
|
15543
|
+
emit: stage,
|
|
15544
|
+
emitTo: want.to,
|
|
15545
|
+
reports: []
|
|
15546
|
+
};
|
|
15547
|
+
}
|
|
14696
15548
|
async function build(entry, options, io) {
|
|
14697
|
-
const dump = options
|
|
15549
|
+
const dump = options.emit === "ast" || options.emit === "ir";
|
|
14698
15550
|
const style = options.quiet || dump ? void 0 : io.report;
|
|
14699
15551
|
const report = new Report(io.stderr, style);
|
|
14700
|
-
const
|
|
15552
|
+
const emitBundle = options.emit === "bundle" ? options.emitTo : void 0;
|
|
15553
|
+
const binary = options.emit === void 0;
|
|
14701
15554
|
const hosts = DEFAULT_HOSTS;
|
|
14702
15555
|
let primitives = hostPrimitives(hosts);
|
|
14703
15556
|
const nodeEnv = options["node-env"] === "" ? void 0 : options["node-env"] ?? "production";
|
|
@@ -14734,7 +15587,12 @@ async function build(entry, options, io) {
|
|
|
14734
15587
|
io.stderr(`visaljs: ${e.message}\n`);
|
|
14735
15588
|
return 1;
|
|
14736
15589
|
}
|
|
14737
|
-
const
|
|
15590
|
+
const script = options.script === true;
|
|
15591
|
+
const bundled = !script && options["no-bundle"] !== true;
|
|
15592
|
+
if (emitBundle !== void 0 && !bundled) {
|
|
15593
|
+
io.stderr(`visaljs: --emit bundle writes the bundle: not with ${script ? "--script" : "--no-bundle"}\n`);
|
|
15594
|
+
return 2;
|
|
15595
|
+
}
|
|
14738
15596
|
let map;
|
|
14739
15597
|
const typedFiles = /* @__PURE__ */ new Set();
|
|
14740
15598
|
let typed;
|
|
@@ -14747,6 +15605,12 @@ async function build(entry, options, io) {
|
|
|
14747
15605
|
}), (b) => `Rolled ${count(b.modules, "module")} into a single file (${size(Buffer.byteLength(b.code))})` + (b.required.length ? `; for a require() at run time: ${b.required.join(", ")}` : ""));
|
|
14748
15606
|
source = b.code;
|
|
14749
15607
|
if (b.map) map = b.map;
|
|
15608
|
+
if (emitBundle !== void 0) {
|
|
15609
|
+
writeBundle(emitBundle, b.code, b.map, [...typedFiles]);
|
|
15610
|
+
report.finish("๐", (time) => `Wrote the bundle and ${count(typedFiles.size, "\"use static\" file")} to ${displayPath(resolve(emitBundle))} in ${time}`);
|
|
15611
|
+
io.stdout(formatBundleSizes(bundleSizes(b.code, dirname(resolve(entry)), [...typedFiles], process.cwd()), options.verbose === true));
|
|
15612
|
+
return 0;
|
|
15613
|
+
}
|
|
14750
15614
|
if (typedFiles.size) {
|
|
14751
15615
|
const files = [...typedFiles];
|
|
14752
15616
|
typed = await report.step("๐งท", "Compiling the typed files", () => buildTypedUnit(files, primitives), (u) => [`Compiled ${count(files.length, "typed file")}: ${count(Object.keys(u.exports).length, "export")}`, ...formatReport(u.report).map((line) => ` โข ${line}`)].join("\n"));
|
|
@@ -14764,7 +15628,7 @@ async function build(entry, options, io) {
|
|
|
14764
15628
|
io.stderr(`visaljs: --jobs takes a positive whole number, not '${options.jobs}'\n`);
|
|
14765
15629
|
return 2;
|
|
14766
15630
|
}
|
|
14767
|
-
const emitDir = options
|
|
15631
|
+
const emitDir = options.emit === "c" ? options.emitTo : void 0;
|
|
14768
15632
|
let output = "";
|
|
14769
15633
|
if (binary) {
|
|
14770
15634
|
output = pipeline?.output ?? options.output ?? basename(entry).replace(/\.(?:[cm]?[jt]s|[jt]sx)$/, "");
|
|
@@ -14775,6 +15639,7 @@ async function build(entry, options, io) {
|
|
|
14775
15639
|
}
|
|
14776
15640
|
}
|
|
14777
15641
|
const dir = emitDir ?? (binary ? scratchDir() : "");
|
|
15642
|
+
let sizes;
|
|
14778
15643
|
try {
|
|
14779
15644
|
const typedLink = typed ? {
|
|
14780
15645
|
atoms: [...typed.atoms],
|
|
@@ -14799,7 +15664,8 @@ async function build(entry, options, io) {
|
|
|
14799
15664
|
}
|
|
14800
15665
|
compilers = c.compilers;
|
|
14801
15666
|
if (typeof c.result === "string") {
|
|
14802
|
-
|
|
15667
|
+
if (options.emitTo) writeFileSync(options.emitTo, c.result);
|
|
15668
|
+
else io.stdout(c.result);
|
|
14803
15669
|
return 0;
|
|
14804
15670
|
}
|
|
14805
15671
|
const written = c.result;
|
|
@@ -14815,7 +15681,9 @@ async function build(entry, options, io) {
|
|
|
14815
15681
|
cFiles.push(join(dir, "typed.c"));
|
|
14816
15682
|
}
|
|
14817
15683
|
const opt = [...options.debug ? ["-O0"] : ["-O2"], ...gcCheckFlags()];
|
|
14818
|
-
const
|
|
15684
|
+
const sizeReport = options.reports.includes("size");
|
|
15685
|
+
const strip = !options.debug && !options.symbols && !sizeReport;
|
|
15686
|
+
const mapFile = sizeReport ? join(dir, "link.map") : void 0;
|
|
14819
15687
|
const jobs = options.jobs === void 0 ? compileJobs(strip ? 8e8 : 15e8) : Number(options.jobs);
|
|
14820
15688
|
try {
|
|
14821
15689
|
await withCompiler(compilers, report, async (cc) => {
|
|
@@ -14833,9 +15701,21 @@ async function build(entry, options, io) {
|
|
|
14833
15701
|
const parallel = cFiles.length > 1 ? `${cFiles.length} files, ${Math.min(jobs, cFiles.length)} at a time` : "";
|
|
14834
15702
|
await report.step("๐จ", parallel ? `${compiling} (${parallel})` : compiling, () => compileProgram(tc, cFiles, output, archives, {
|
|
14835
15703
|
jobs,
|
|
15704
|
+
mapFile,
|
|
14836
15705
|
compiled: (done, total) => report.relabel(done < total ? `${compiling} (${done}/${total} files, ${Math.min(jobs, total)} at a time)` : `Linking with ${describeCompiler(cc)}`)
|
|
14837
15706
|
}), () => `Compiled the binary with ${describeCompiler(cc)} (${[...opt, ...parallel ? [parallel] : []].join(", ")}, ${tc.strip ? "stripped" : "with debug info"})`);
|
|
14838
15707
|
});
|
|
15708
|
+
if (mapFile) {
|
|
15709
|
+
sizes = await report.step("๐", "Measuring where the binary's bytes come from", () => measureSizes(output, mapFile, join(dir, "program.dSYM"), cFiles.map((f) => f.replace(/\.c$/, ".o")), programLibraries(hosts), bundled ? {
|
|
15710
|
+
code: source,
|
|
15711
|
+
entryDir: dirname(resolve(entry))
|
|
15712
|
+
} : void 0), (es) => `Measured ${count(es.length, "source")} of the binary's bytes`);
|
|
15713
|
+
if (!options.debug && !options.symbols) execFileSync("strip", [
|
|
15714
|
+
"-S",
|
|
15715
|
+
"-x",
|
|
15716
|
+
output
|
|
15717
|
+
]);
|
|
15718
|
+
}
|
|
14839
15719
|
} catch (e) {
|
|
14840
15720
|
io.stderr(`visaljs: C compilation failed: ${e.message}\n`);
|
|
14841
15721
|
return 1;
|
|
@@ -14848,9 +15728,23 @@ async function build(entry, options, io) {
|
|
|
14848
15728
|
}
|
|
14849
15729
|
const bytes = statSync(output).size;
|
|
14850
15730
|
report.finish("๐", (time) => `Built ${displayPath(resolve(output))} in ${time}: ${size(bytes)}, ${sizeQuip(bytes)}`);
|
|
15731
|
+
if (sizes) io.stdout(formatSizeReport(sizes, bytes, options.verbose === true));
|
|
14851
15732
|
pipeline?.done(resolve(output));
|
|
14852
15733
|
return 0;
|
|
14853
15734
|
}
|
|
15735
|
+
/** --emit bundle's files: the bundle, its map, and each "use static" file at its path from the
|
|
15736
|
+
* current directory under static/ (outside it: by its name). */
|
|
15737
|
+
function writeBundle(dir, code, map, staticFiles) {
|
|
15738
|
+
mkdirSync(dir, { recursive: true });
|
|
15739
|
+
writeFileSync(join(dir, "bundle.js"), code);
|
|
15740
|
+
if (map) writeFileSync(join(dir, "bundle.js.map"), map);
|
|
15741
|
+
for (const file of staticFiles) {
|
|
15742
|
+
const rel = relative(process.cwd(), file);
|
|
15743
|
+
const to = join(dir, "static", rel.startsWith("..") || isAbsolute(rel) ? basename(file) : rel);
|
|
15744
|
+
mkdirSync(dirname(to), { recursive: true });
|
|
15745
|
+
copyFileSync(file, to);
|
|
15746
|
+
}
|
|
15747
|
+
}
|
|
14854
15748
|
const WORKER = "visaljs-compile";
|
|
14855
15749
|
/** compileToC in a worker thread, so its heap (gigabytes for a large program) goes back to the
|
|
14856
15750
|
* system for the C compilers when it ends. The worker is this module (bundled: cli.js). */
|
|
@@ -14957,7 +15851,7 @@ async function runCompileJob(job) {
|
|
|
14957
15851
|
}
|
|
14958
15852
|
}
|
|
14959
15853
|
if (!isMainThread && workerData?.[WORKER]) await runCompileJob(workerData[WORKER]);
|
|
14960
|
-
/** The program's C files' names, or the text --
|
|
15854
|
+
/** The program's C files' names, or the text --emit ast or --emit ir writes. Its own function, as
|
|
14961
15855
|
* is toIR, so the syntax tree and then the IR become garbage: a large program's take gigabytes. */
|
|
14962
15856
|
async function compileToC(source, entry, map, options, report, primitives, compilers, typed, write) {
|
|
14963
15857
|
const program = await toIR(source, entry, map, options, report, primitives, compilers, typed?.calls);
|
|
@@ -14995,7 +15889,7 @@ async function compileToC(source, entry, map, options, report, primitives, compi
|
|
|
14995
15889
|
}
|
|
14996
15890
|
async function toIR(source, entry, map, options, report, primitives, compilers, typedCalls) {
|
|
14997
15891
|
const ast = await report.step("๐ณ", "Parsing the JavaScript", () => options.script ? parseScript(source, entry) : parseModule(source, map ? "bundle.js" : entry, map, resolve(entry), primitives), () => `Parsed ${count(lineCount(source), "line")} of JavaScript`);
|
|
14998
|
-
if (options
|
|
15892
|
+
if (options.emit === "ast") return JSON.stringify(ast, null, 2) + "\n";
|
|
14999
15893
|
const info = analyze(ast);
|
|
15000
15894
|
const evalWarn = evalWarning(evalCalls(ast, info), options.verbose === true);
|
|
15001
15895
|
if (evalWarn) report.warn(evalWarn);
|
|
@@ -15009,7 +15903,7 @@ async function toIR(source, entry, map, options, report, primitives, compilers,
|
|
|
15009
15903
|
if (typedCalls) annotateTypedCalls(lowered, typedCalls);
|
|
15010
15904
|
return optimize(lowered, options["no-optimize"] ? [] : void 0, passes);
|
|
15011
15905
|
}, (ir) => [`Converted ${count(ir.functions.length + 1, "function")} to IR and optimized them`, ...formatReport(passes).map((line) => ` โข ${line}`)].join("\n"));
|
|
15012
|
-
if (options
|
|
15906
|
+
if (options.emit === "ir") return printModule(ir);
|
|
15013
15907
|
return {
|
|
15014
15908
|
ir,
|
|
15015
15909
|
names: programNames(ast),
|