visaljs 0.0.9 → 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 +3745 -890
- package/node/include/js_node.h +12 -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 +405 -94
- 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/http_chars.ts +22 -0
- 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 +30 -14
- 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 +79 -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_buffer.h +185 -0
- package/runtime/include/js_builtins.h +58 -0
- package/runtime/include/js_crypto.h +11 -0
- package/runtime/include/js_exception.h +3 -0
- package/runtime/include/js_function.h +1 -1
- package/runtime/include/js_gc.h +13 -10
- package/runtime/include/js_jobs.h +2 -0
- package/runtime/include/js_object.h +79 -3
- package/runtime/include/js_ops.h +27 -0
- package/runtime/include/js_runtime.h +1 -0
- package/runtime/include/js_web.h +0 -3
- package/runtime/include/jscontext.h +8 -0
- package/runtime/src/builtins.c +17 -4
- 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/function.c +37 -10
- package/runtime/src/gc.c +76 -93
- package/runtime/src/inspect.c +18 -1
- package/runtime/src/iterator.c +5 -1
- package/runtime/src/jobs.c +37 -22
- package/runtime/src/object.c +91 -8
- package/runtime/src/os.c +16 -6
- package/runtime/src/os.h +2 -0
- package/runtime/src/process.c +97 -10
- package/runtime/src/typedarray.c +23 -0
package/runtime/include/js_gc.h
CHANGED
|
@@ -50,24 +50,27 @@ typedef struct JSBlock {
|
|
|
50
50
|
size_t map_size; /* JS_BLOCK_SIZE, or the large object's mapping */
|
|
51
51
|
uint32_t cell_size;
|
|
52
52
|
uint32_t cell_count;
|
|
53
|
-
uint8_t size_class;
|
|
53
|
+
uint8_t size_class; /* a small block's */
|
|
54
54
|
uint8_t is_large;
|
|
55
|
-
|
|
56
|
-
uint8_t queued; /* in its class's sweep queue */
|
|
57
|
-
uint8_t remembered; /* a large object: in the remembered set, with cards marked */
|
|
58
|
-
};
|
|
55
|
+
uint8_t queued; /* in its class's sweep queue */
|
|
59
56
|
uint8_t has_finalizable;
|
|
60
57
|
uint32_t index_magic; /* ceil(2^32 / cell_size): a cell's index is (offset * magic) >> 32 */
|
|
61
58
|
uint8_t young; /* the allocator took it since the last collection */
|
|
59
|
+
uint8_t remembered; /* a large object: in the remembered set, with cards marked */
|
|
60
|
+
uint8_t card_shift; /* a large object: a card is 2^card_shift bytes of it */
|
|
62
61
|
uint64_t mark_bits[JS_BITMAP_WORDS];
|
|
63
|
-
|
|
62
|
+
union {
|
|
63
|
+
uint64_t alloc_bits[JS_BITMAP_WORDS]; /* exact only while the world is stopped */
|
|
64
|
+
/* A large object's: its one cell's allocation bit, then its cards, a bit per card that a
|
|
65
|
+
* store gave a young cell since the last collection. */
|
|
66
|
+
struct {
|
|
67
|
+
uint64_t large_alloc;
|
|
68
|
+
uint64_t cards[JS_BITMAP_WORDS - 1];
|
|
69
|
+
};
|
|
70
|
+
};
|
|
64
71
|
} JSBlock;
|
|
65
72
|
|
|
66
|
-
/* A large object's cards: a bit per 2^card_shift bytes of the object
|
|
67
|
-
* that a store gave a young cell since the last collection. They live in the allocation bitmap,
|
|
68
|
-
* whose only other bit is bit 0 of word 0. A large object's size_class is its card_shift. */
|
|
69
73
|
#define JS_LARGE_CARDS ((JS_BITMAP_WORDS - 1) * 64)
|
|
70
|
-
static inline uint64_t *js_large_cards(JSBlock *b) { return &b->alloc_bits[1]; }
|
|
71
74
|
|
|
72
75
|
#define JS_BLOCK_FIRST_CELL \
|
|
73
76
|
((sizeof(JSBlock) + JS_CELL_ALIGN - 1) & ~(size_t)(JS_CELL_ALIGN - 1))
|
|
@@ -65,6 +65,8 @@ typedef enum JSRejectionMode {
|
|
|
65
65
|
} JSRejectionMode;
|
|
66
66
|
|
|
67
67
|
void js_enqueue_microtask(JSContext *ctx, const JSJob *job);
|
|
68
|
+
/* process.nextTick's queue, which a checkpoint runs before the microtasks (Node's order) */
|
|
69
|
+
void js_enqueue_tick(JSContext *ctx, const JSJob *job);
|
|
68
70
|
/* The checkpoint: runs every queued job (and the ones they queue), then processes
|
|
69
71
|
* unhandled rejections. A nested call does nothing. 0, or -1 after an uncaught error
|
|
70
72
|
* or a strict unhandled rejection (already reported). */
|
|
@@ -296,10 +296,10 @@ JS_WARN_UNUSED JSValue js_own_keys(JSContext *ctx, JSObject *o);
|
|
|
296
296
|
#define JS_IC_EMPTY 0
|
|
297
297
|
#define JS_IC_OWN 1 /* get: an own data property; set: an own writable data property */
|
|
298
298
|
#define JS_IC_PROTO 2 /* get: a data property of `holder`, `depth` prototypes up */
|
|
299
|
-
#define JS_IC_ADD 3 /* set: adding the key takes the receiver from `shape` to `next` */
|
|
299
|
+
#define JS_IC_ADD 3 /* set: adding the key takes the receiver from `shape` to `next`; `depth` prototypes up to null, or to one whose writable data property it shadows */
|
|
300
300
|
#define JS_IC_GETTER 4 /* get: an accessor of `holder` (NULL: the receiver), `depth` prototypes up */
|
|
301
301
|
#define JS_IC_ABSENT 5 /* get: no such property on the receiver or its `depth` prototypes (the last's proto is null) */
|
|
302
|
-
#define JS_IC_MAX_DEPTH
|
|
302
|
+
#define JS_IC_MAX_DEPTH 8 /* prototypes a cache can check: Node's sockets are 6 deep (Socket, Duplex, Readable, Stream, EventEmitter, Object) */
|
|
303
303
|
|
|
304
304
|
/* One per property access site with a constant named key; a site is either a get or a
|
|
305
305
|
* set. Monomorphic: a miss refills it. Never caches dictionary shapes (their layout
|
|
@@ -314,7 +314,7 @@ typedef struct JSPropCache {
|
|
|
314
314
|
JSShape *fast; /* OWN, inline slot: the receiver shape; else NULL */
|
|
315
315
|
uint16_t fast_off; /* with `fast`: the slot's byte offset in the object */
|
|
316
316
|
uint8_t kind; /* JS_IC_* */
|
|
317
|
-
uint8_t depth; /* PROTO: hops to the holder; ADD: prototypes
|
|
317
|
+
uint8_t depth; /* PROTO: hops to the holder; ADD: prototypes checked (JS_IC_ADD) */
|
|
318
318
|
uint32_t slot; /* OWN, PROTO: the slot */
|
|
319
319
|
JSShape *shape; /* receiver shape; NULL = empty */
|
|
320
320
|
JSObject *holder; /* PROTO */
|
|
@@ -326,6 +326,8 @@ typedef struct JSPropCache {
|
|
|
326
326
|
/* A module's caches, once at startup (the GC resets them weakly). */
|
|
327
327
|
void js_register_prop_caches(JSRuntime *rt, JSPropCache *ics, size_t n);
|
|
328
328
|
|
|
329
|
+
/* The slow paths of a named access: `ic` is the site's cache, or NULL for a computed key's access
|
|
330
|
+
* (the runtime's shared caches only). */
|
|
329
331
|
JS_WARN_UNUSED JSValue js_get_prop_slow(JSContext *ctx, JSValue obj, JSValue key, JSPropCache *ic);
|
|
330
332
|
JS_WARN_UNUSED int js_set_prop_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool strict, JSPropCache *ic);
|
|
331
333
|
|
|
@@ -373,6 +375,22 @@ static inline int js_set_prop(JSContext *ctx, JSValue obj, JSValue key, JSValue
|
|
|
373
375
|
return js_set_prop_slow(ctx, obj, key, v, strict, ic);
|
|
374
376
|
}
|
|
375
377
|
|
|
378
|
+
/* obj[key] and obj[key] = v at a site whose key is most likely always the same symbol or string
|
|
379
|
+
* (the optimizer's guess: a module binding stored once, as Node's kState). `site` holds the key
|
|
380
|
+
* the site's cache is for (EMPTY: none yet): while the key is that one, the access is a named
|
|
381
|
+
* access's, inline cache and all. Another key the slow path makes the site's, or, when it isn't
|
|
382
|
+
* a property key already (an index, a string not interned), accesses generically. */
|
|
383
|
+
JS_WARN_UNUSED JSValue js_get_keyed_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue *site, JSPropCache *ic);
|
|
384
|
+
JS_WARN_UNUSED int js_set_keyed_slow(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool strict, JSValue *site, JSPropCache *ic);
|
|
385
|
+
static inline JSValue js_get_keyed(JSContext *ctx, JSValue obj, JSValue key, JSValue *site, JSPropCache *ic) {
|
|
386
|
+
if (JS_LIKELY(js_same_bits(key, *site))) return js_get_prop(ctx, obj, key, ic);
|
|
387
|
+
return js_get_keyed_slow(ctx, obj, key, site, ic);
|
|
388
|
+
}
|
|
389
|
+
static inline int js_set_keyed(JSContext *ctx, JSValue obj, JSValue key, JSValue v, bool strict, JSValue *site, JSPropCache *ic) {
|
|
390
|
+
if (JS_LIKELY(js_same_bits(key, *site))) return js_set_prop(ctx, obj, key, v, strict, ic);
|
|
391
|
+
return js_set_keyed_slow(ctx, obj, key, v, strict, site, ic);
|
|
392
|
+
}
|
|
393
|
+
|
|
376
394
|
/* An object's new shape. When the object is a prototype, caches that checked the chain it's on
|
|
377
395
|
* may be stale: the runtime's proto_epoch moves on. */
|
|
378
396
|
static JS_FAST_PATH void js_object_set_shape(JSContext *ctx, JSObject *o, JSShape *s) {
|
|
@@ -475,6 +493,64 @@ static inline JSValue js_get_length(JSContext *ctx, JSValue obj, JSValue key, JS
|
|
|
475
493
|
if (js_is_string(obj)) return js_int32((int32_t)js_string_length(obj)); /* below 2^30 */
|
|
476
494
|
return js_get_prop(ctx, obj, key, ic);
|
|
477
495
|
}
|
|
496
|
+
/* ---- Static code's arrays ("use static": number[], string[], boolean[]) ------------------ */
|
|
497
|
+
|
|
498
|
+
/* An element's kind (an i32[] is a number[] whose reads the code converts). tsc's element types
|
|
499
|
+
* aren't sound (a cast, an i32[] alias of a number[]), so every read checks it: a read's value is
|
|
500
|
+
* of the kind or the read throws. An index past the end is a RangeError, never undefined or a hole. */
|
|
501
|
+
enum { JS_SARRAY_NUMBER, JS_SARRAY_STRING, JS_SARRAY_BOOLEAN };
|
|
502
|
+
|
|
503
|
+
static inline bool js_sarray_is(JSValue v, int kind) {
|
|
504
|
+
switch (kind) {
|
|
505
|
+
case JS_SARRAY_NUMBER: return js_is_number(v);
|
|
506
|
+
case JS_SARRAY_STRING: return !js_is_empty(v) && js_is_string(v);
|
|
507
|
+
default: return js_is_bool(v);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
/* A Number key as an index: -1 (past every end) when it isn't one. */
|
|
511
|
+
static inline int64_t js_sarray_index_f64(double key) {
|
|
512
|
+
return key >= 0 && key < 4294967295.0 && (double)(int64_t)key == key ? (int64_t)key : -1;
|
|
513
|
+
}
|
|
514
|
+
static inline int64_t js_sarray_index(JSValue key) {
|
|
515
|
+
return js_is_int32(key) ? js_as_int32(key) : js_sarray_index_f64(js_as_number(key));
|
|
516
|
+
}
|
|
517
|
+
JS_WARN_UNUSED JSValue js_sarray_get_slow(JSContext *ctx, JSValue arr, int64_t i, int kind);
|
|
518
|
+
JS_WARN_UNUSED int js_sarray_set_slow(JSContext *ctx, JSValue arr, int64_t i, JSValue v, int kind);
|
|
519
|
+
JS_WARN_UNUSED JSValue js_sarray_length_slow(JSContext *ctx, JSValue arr);
|
|
520
|
+
JS_WARN_UNUSED JSValue js_sarray_push_slow(JSContext *ctx, JSValue arr, JSValue v, int kind);
|
|
521
|
+
|
|
522
|
+
static JS_FAST_PATH JSValue js_sarray_get(JSContext *ctx, JSValue arr, int64_t i, int kind) {
|
|
523
|
+
if (JS_LIKELY(js_is_array(arr))) {
|
|
524
|
+
JSElements *d = js_as_object(arr)->elements;
|
|
525
|
+
if (JS_LIKELY(d->kind == JS_ELEMENTS_DENSE && (uint64_t)i < d->length && js_sarray_is(d->data[i], kind))) return d->data[i];
|
|
526
|
+
}
|
|
527
|
+
return js_sarray_get_slow(ctx, arr, i, kind);
|
|
528
|
+
}
|
|
529
|
+
/* a[i] = v: at the length, a push; past it, a RangeError. */
|
|
530
|
+
static JS_FAST_PATH int js_sarray_set(JSContext *ctx, JSValue arr, int64_t i, JSValue v, int kind) {
|
|
531
|
+
if (JS_LIKELY(js_is_array(arr) && js_sarray_is(v, kind))) {
|
|
532
|
+
JSElements *d = js_as_object(arr)->elements;
|
|
533
|
+
if (JS_LIKELY(d->kind == JS_ELEMENTS_DENSE && (uint64_t)i < d->length && !js_is_empty(d->data[i]))) {
|
|
534
|
+
js_store(ctx, &d->cell, &d->data[i], v);
|
|
535
|
+
return 1;
|
|
536
|
+
}
|
|
537
|
+
}
|
|
538
|
+
return js_sarray_set_slow(ctx, arr, i, v, kind);
|
|
539
|
+
}
|
|
540
|
+
/* a.length, an int32 (a longer array is a RangeError). */
|
|
541
|
+
static JS_FAST_PATH JSValue js_sarray_length(JSContext *ctx, JSValue arr) {
|
|
542
|
+
if (JS_LIKELY(js_is_array(arr) && js_array_length(js_as_object(arr)) <= INT32_MAX)) return js_int32((int32_t)js_array_length(js_as_object(arr)));
|
|
543
|
+
return js_sarray_length_slow(ctx, arr);
|
|
544
|
+
}
|
|
545
|
+
/* a.push(v): the new length, an int32. */
|
|
546
|
+
static JS_FAST_PATH JSValue js_sarray_push(JSContext *ctx, JSValue arr, JSValue v, int kind) {
|
|
547
|
+
if (JS_LIKELY(js_is_array(arr) && js_sarray_is(v, kind) && js_array_length(js_as_object(arr)) < INT32_MAX)) {
|
|
548
|
+
if (JS_UNLIKELY(js_array_push(ctx, js_as_object(arr), v) < 0)) return JS_EXCEPTION;
|
|
549
|
+
return js_int32((int32_t)js_array_length(js_as_object(arr)));
|
|
550
|
+
}
|
|
551
|
+
return js_sarray_push_slow(ctx, arr, v, kind);
|
|
552
|
+
}
|
|
553
|
+
|
|
478
554
|
/* delete obj[key]: true or false (sloppy), a TypeError when strict and not deletable.
|
|
479
555
|
* `key` is a property key; js_delete_elem converts it first. */
|
|
480
556
|
JS_WARN_UNUSED JSValue js_delete_value(JSContext *ctx, JSValue obj, JSValue key, bool strict);
|
package/runtime/include/js_ops.h
CHANGED
|
@@ -46,6 +46,33 @@ JS_WARN_UNUSED JSValue js_ge(JSContext *ctx, JSValue a, JSValue b);
|
|
|
46
46
|
/* ===, !==: never throw (strings compare by content). */
|
|
47
47
|
bool js_strict_equals(JSContext *ctx, JSValue a, JSValue b);
|
|
48
48
|
static inline JSValue js_strict_eq(JSContext *ctx, JSValue a, JSValue b) { return js_bool(js_strict_equals(ctx, a, b)); }
|
|
49
|
+
/* A Number as a typed file's ("use static") int, an int64_t: truncated toward zero and wrapped
|
|
50
|
+
* modulo 2^64, as ToInt32 is for 32 bits; NaN and the infinities 0 (a plain C conversion of those
|
|
51
|
+
* would be undefined behaviour). */
|
|
52
|
+
static inline int64_t js_f64_to_i64(double d) {
|
|
53
|
+
if (d >= -9223372036854775808.0 && d < 9223372036854775808.0) return (int64_t)d;
|
|
54
|
+
if (d != d || d == INFINITY || d == -INFINITY) return 0;
|
|
55
|
+
double m = fmod(trunc(d), 18446744073709551616.0); /* exact: d is an integer this large */
|
|
56
|
+
if (m < 0) m += 18446744073709551616.0;
|
|
57
|
+
return (int64_t)(uint64_t)m;
|
|
58
|
+
}
|
|
59
|
+
/* A Number value as an int; anything else (typed code's caller passed it unchecked) 0. */
|
|
60
|
+
static inline int64_t js_value_to_i64(JSValue v) {
|
|
61
|
+
if (js_is_int32(v)) return js_as_int32(v);
|
|
62
|
+
return js_is_number(v) ? js_f64_to_i64(js_as_number(v)) : 0;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/* v === d, d a number literal (not NaN): v is a Number of that value (0 and -0 alike). */
|
|
66
|
+
static inline bool js_strict_eq_num(JSValue v, double d) {
|
|
67
|
+
if (js_is_int32(v)) return (double)js_as_int32(v) == d;
|
|
68
|
+
return js_is_number(v) && js_as_number(v) == d;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/* a === s, s a string literal: an atom, so a string with its units is s itself unless it isn't
|
|
72
|
+
* interned */
|
|
73
|
+
static inline bool js_strict_eq_atom(JSContext *ctx, JSValue a, JSValue s) {
|
|
74
|
+
return js_same_bits(a, s) || (js_is_string(a) && !js_is_atom(a) && js_string_equals(ctx, a, s));
|
|
75
|
+
}
|
|
49
76
|
static inline JSValue js_strict_ne(JSContext *ctx, JSValue a, JSValue b) { return js_bool(!js_strict_equals(ctx, a, b)); }
|
|
50
77
|
|
|
51
78
|
/* A switch whose cases are all string literals: the index of the first case `v` is === to, or
|
package/runtime/include/js_web.h
CHANGED
|
@@ -13,9 +13,6 @@
|
|
|
13
13
|
JS_WARN_UNUSED JSValue js_throw_node_error(JSContext *ctx, JSErrorKind kind, const char *code, const char *fmt, ...);
|
|
14
14
|
/* ERR_INVALID_THIS: `Value of "this" must be of type TextDecoder`. */
|
|
15
15
|
JS_WARN_UNUSED JSValue js_throw_invalid_this(JSContext *ctx, const char *type);
|
|
16
|
-
/* ERR_INVALID_ARG_TYPE: `The "dest" argument must be <expected>. Received …` (Node's wording
|
|
17
|
-
* of the value). */
|
|
18
|
-
JS_WARN_UNUSED JSValue js_throw_invalid_arg_type(JSContext *ctx, const char *name, const char *expected, JSValue value);
|
|
19
16
|
/* Node's "Received …" tail for a value: " Received type number (1)", " Received an instance of
|
|
20
17
|
* Array", " Received undefined". */
|
|
21
18
|
void js_node_received(JSContext *ctx, JSValue v, char *buf, size_t cap);
|
|
@@ -189,6 +189,7 @@ struct JSRuntime {
|
|
|
189
189
|
JSValue symbol_registry; /* Symbol.for's GlobalSymbolRegistry: key -> symbol (a root) */
|
|
190
190
|
uintptr_t stack_limit; /* lowest usable stack address, margin included */
|
|
191
191
|
JSJobQueue jobs; /* microtasks */
|
|
192
|
+
JSJobQueue ticks; /* process.nextTick's: each checkpoint runs them all before the microtasks (Node's) */
|
|
192
193
|
JSTimers timers; /* setTimeout / setInterval */
|
|
193
194
|
/* The async context: an opaque value the host keeps per chain of async work
|
|
194
195
|
* (node:async_hooks' AsyncLocalStorage keeps its stores in it). Every job, timer and promise
|
|
@@ -226,6 +227,12 @@ struct JSRuntime {
|
|
|
226
227
|
const JSBigIntOps *bigint; /* set by the bigint component */
|
|
227
228
|
/* A typed array's length now: -1 when out of bounds (detached), -2 for anything else. */
|
|
228
229
|
double (*typed_array_length)(JSValue v);
|
|
230
|
+
/* Set by typed arrays: obj[i] and obj[i] = d (a Number) of a typed array, inline, for an index
|
|
231
|
+
* in bounds and an element that is a Number (not a BigInt): true when done; false for
|
|
232
|
+
* anything else, which takes the generic path. */
|
|
233
|
+
bool (*typed_array_get)(JSValue v, int32_t i, JSValue *out);
|
|
234
|
+
bool (*typed_array_set)(JSValue v, int32_t i, double d);
|
|
235
|
+
const struct JSClass *typed_array_class; /* set by typed arrays: js_buffer.h's inline element access tests it */
|
|
229
236
|
/* Set by typed arrays: a typed array's or DataView's bytes (its current window), true; false
|
|
230
237
|
* for anything else (an ArrayBuffer too: process.stdout.write takes views only). */
|
|
231
238
|
bool (*view_bytes)(JSValue v, uint8_t **data, size_t *length);
|
|
@@ -240,6 +247,7 @@ struct JSContext {
|
|
|
240
247
|
uint8_t barrier_threshold; /* js_store's slow path runs for an owner whose GC byte is this or more */
|
|
241
248
|
JSValue intrinsics[JS_INTRINSIC_COUNT];
|
|
242
249
|
JSContext *next_realm;
|
|
250
|
+
struct JSShape *array_shape; /* the root shape of its arrays with Array.prototype (js_new_array), made at the first */
|
|
243
251
|
};
|
|
244
252
|
|
|
245
253
|
JSRuntime *js_runtime_new(void);
|
package/runtime/src/builtins.c
CHANGED
|
@@ -793,7 +793,7 @@ CORE(object_proto_lookup_setter) {
|
|
|
793
793
|
|
|
794
794
|
/* ---- Function.prototype (§20.2.3) --------------------------------------------------------------- */
|
|
795
795
|
|
|
796
|
-
|
|
796
|
+
JSValue js_function_proto_call(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
797
797
|
UNUSED_ARGS;
|
|
798
798
|
if (!js_is_callable(this_val)) return js_throw_type_error(ctx, "Function.prototype.call called on a non-function");
|
|
799
799
|
return js_call(ctx, this_val, ARG(0), argc > 1 ? argc - 1 : 0, argv + (argc > 1 ? 1 : argc));
|
|
@@ -822,10 +822,23 @@ static JSValueArray *list_from_array_like(JSContext *ctx, JSValue v) {
|
|
|
822
822
|
|
|
823
823
|
JSValueArray *js_list_from_array_like(JSContext *ctx, JSValue v) { return list_from_array_like(ctx, v); }
|
|
824
824
|
|
|
825
|
-
|
|
825
|
+
JSValue js_function_proto_apply(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc, const JSValue *argv, JSValue new_target) {
|
|
826
826
|
UNUSED_ARGS;
|
|
827
827
|
if (!js_is_callable(this_val)) return js_throw_type_error(ctx, "Function.prototype.apply was called on a non-function");
|
|
828
828
|
if (js_is_nullish(ARG(1))) return js_call(ctx, this_val, ARG(0), 0, NULL);
|
|
829
|
+
/* a short dense array without holes (emit's arguments): its elements are its own data
|
|
830
|
+
* properties, so reading them can't run code. Copied, as the callee may change the array. */
|
|
831
|
+
if (js_is_array(ARG(1))) {
|
|
832
|
+
JSObject *a = js_as_object(ARG(1));
|
|
833
|
+
JSElements *e = a->elements;
|
|
834
|
+
uint32_t n = js_array_length(a);
|
|
835
|
+
JSValue args[8];
|
|
836
|
+
if (e->kind == JS_ELEMENTS_DENSE && e->length == n && n <= 8) {
|
|
837
|
+
uint32_t i = 0;
|
|
838
|
+
while (i < n && !js_is_empty(e->data[i])) args[i] = e->data[i], i++;
|
|
839
|
+
if (i == n) return js_call(ctx, this_val, ARG(0), n, args);
|
|
840
|
+
}
|
|
841
|
+
}
|
|
829
842
|
JSValueArray *list = list_from_array_like(ctx, ARG(1));
|
|
830
843
|
if (!list) return JS_EXCEPTION;
|
|
831
844
|
JSValue r = js_call(ctx, this_val, ARG(0), list->cell.aux, list->values);
|
|
@@ -959,8 +972,8 @@ void js_builtins_realm_init(JSContext *ctx, JSObject *global) {
|
|
|
959
972
|
|
|
960
973
|
JSValue object = define_constructor(ctx, global, "Object", object_ctor, 1, in[JS_INTRINSIC_OBJECT_PROTOTYPE]);
|
|
961
974
|
static const JSBuiltin function_proto[] = {
|
|
962
|
-
JS_BUILTIN_FN("call",
|
|
963
|
-
JS_BUILTIN_FN("apply",
|
|
975
|
+
JS_BUILTIN_FN("call", js_function_proto_call, 1),
|
|
976
|
+
JS_BUILTIN_FN("apply", js_function_proto_apply, 2),
|
|
964
977
|
JS_BUILTIN_FN("bind", function_proto_bind, 1),
|
|
965
978
|
JS_BUILTIN_FN("toString", function_proto_to_string, 0),
|
|
966
979
|
};
|
|
@@ -267,6 +267,7 @@ const char *js_ec_curve_jwk(int curve);
|
|
|
267
267
|
typedef enum JSWebAlg {
|
|
268
268
|
JS_WEB_HMAC = 1, JS_WEB_PBKDF2, JS_WEB_HKDF, JS_WEB_AES_CTR, JS_WEB_AES_CBC, JS_WEB_AES_GCM, JS_WEB_AES_KW,
|
|
269
269
|
JS_WEB_RSASSA, JS_WEB_RSA_PSS, JS_WEB_RSA_OAEP, JS_WEB_ECDSA, JS_WEB_ECDH, JS_WEB_X25519, JS_WEB_ED25519,
|
|
270
|
+
JS_WEB_CHACHA20_POLY1305,
|
|
270
271
|
} JSWebAlg;
|
|
271
272
|
|
|
272
273
|
/* KeyUsage, as bits in this order */
|
|
@@ -226,14 +226,15 @@ static int arg_enum(Call *c, JSValue v, const char *const *values, int count, co
|
|
|
226
226
|
c->op, where, shown, type));
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
|
|
230
|
-
|
|
229
|
+
/* the raw-* formats (Node 24's, from WebCrypto's Modern Algorithms draft) say which key raw is */
|
|
230
|
+
enum { FORMAT_RAW, FORMAT_SPKI, FORMAT_PKCS8, FORMAT_JWK, FORMAT_RAW_PUBLIC, FORMAT_RAW_PRIVATE, FORMAT_RAW_SEED, FORMAT_RAW_SECRET };
|
|
231
|
+
static const char *const FORMATS[] = { "raw", "spki", "pkcs8", "jwk", "raw-public", "raw-private", "raw-seed", "raw-secret" };
|
|
231
232
|
static const char *const USAGES[] = { "encrypt", "decrypt", "sign", "verify", "deriveKey", "deriveBits", "wrapKey", "unwrapKey" };
|
|
232
233
|
|
|
233
234
|
static int arg_format(Call *c, JSValue v, int i) {
|
|
234
235
|
char where[32];
|
|
235
236
|
snprintf(where, sizeof where, "%s argument", ORDINALS[i]);
|
|
236
|
-
return arg_enum(c, v, FORMATS,
|
|
237
|
+
return arg_enum(c, v, FORMATS, 8, "KeyFormat", where);
|
|
237
238
|
}
|
|
238
239
|
|
|
239
240
|
/* sequence<KeyUsage>: a new array of the strings, in order (duplicates kept, as Node keeps them),
|
|
@@ -373,7 +374,7 @@ typedef enum Op {
|
|
|
373
374
|
|
|
374
375
|
/* Parameter dictionaries, and their members (alphabetical, as WebIDL converts them) */
|
|
375
376
|
typedef enum Dict {
|
|
376
|
-
DICT_NONE, DICT_HMAC_IMPORT, DICT_HMAC_KEYGEN, DICT_PBKDF2, DICT_HKDF, DICT_AES_CBC, DICT_AES_CTR, DICT_AES_GCM, DICT_AES_KEYGEN,
|
|
377
|
+
DICT_NONE, DICT_HMAC_IMPORT, DICT_HMAC_KEYGEN, DICT_PBKDF2, DICT_HKDF, DICT_AES_CBC, DICT_AES_CTR, DICT_AES_GCM, DICT_AEAD, DICT_AES_KEYGEN,
|
|
377
378
|
DICT_AES_DERIVED, DICT_RSA_HASHED_IMPORT, DICT_RSA_HASHED_KEYGEN, DICT_RSA_PSS, DICT_RSA_OAEP, DICT_EC_IMPORT, DICT_EC_KEYGEN,
|
|
378
379
|
DICT_ECDSA, DICT_ECDH_DERIVE,
|
|
379
380
|
} Dict;
|
|
@@ -402,6 +403,7 @@ static const struct {
|
|
|
402
403
|
[DICT_AES_CBC] = { "AesCbcParams", { M_IV, M_END }, 1, 0 },
|
|
403
404
|
[DICT_AES_CTR] = { "AesCtrParams", { M_COUNTER, M_LENGTH, M_END }, 3, 255 },
|
|
404
405
|
[DICT_AES_GCM] = { "AesGcmParams", { M_ADDITIONAL_DATA, M_IV, M_TAG_LENGTH, M_END }, 2, 0 },
|
|
406
|
+
[DICT_AEAD] = { "AeadParams", { M_ADDITIONAL_DATA, M_IV, M_TAG_LENGTH, M_END }, 2, 0 },
|
|
405
407
|
[DICT_AES_KEYGEN] = { "AesKeyGenParams", { M_LENGTH, M_END }, 1, 65535 },
|
|
406
408
|
[DICT_AES_DERIVED] = { "AesDerivedKeyParams", { M_LENGTH, M_END }, 1, 65535 },
|
|
407
409
|
[DICT_RSA_HASHED_IMPORT] = { "RsaHashedImportParams", { M_HASH, M_END }, 1, 0 },
|
|
@@ -446,6 +448,8 @@ static const struct {
|
|
|
446
448
|
{ [OP_IMPORT_KEY] = DICT_EC_IMPORT, [OP_GENERATE_KEY] = DICT_EC_KEYGEN, [OP_DERIVE_BITS] = DICT_ECDH_DERIVE } },
|
|
447
449
|
{ "X25519", JS_WEB_X25519, KEY_OPS | BIT(OP_DERIVE_BITS), { [OP_DERIVE_BITS] = DICT_ECDH_DERIVE } },
|
|
448
450
|
{ "Ed25519", JS_WEB_ED25519, KEY_OPS | BIT(OP_SIGN) | BIT(OP_VERIFY), { 0 } },
|
|
451
|
+
{ "ChaCha20-Poly1305", JS_WEB_CHACHA20_POLY1305, BIT(OP_IMPORT_KEY) | BIT(OP_GENERATE_KEY) | BIT(OP_ENCRYPT) | BIT(OP_DECRYPT),
|
|
452
|
+
{ [OP_ENCRYPT] = DICT_AEAD, [OP_DECRYPT] = DICT_AEAD } },
|
|
449
453
|
};
|
|
450
454
|
|
|
451
455
|
/* A normalized algorithm: its registry entry and the members its dictionary has. */
|
|
@@ -714,6 +718,7 @@ static bool is_aes(uint8_t alg) { return alg >= JS_WEB_AES_CTR && alg <= JS_WEB_
|
|
|
714
718
|
/* A JWK's `alg` for a secret key: HS256, A128GCM, … */
|
|
715
719
|
static void jwk_alg(uint8_t alg, const JSHashAlg *hash, uint32_t length, char *out, size_t cap) {
|
|
716
720
|
if (alg == JS_WEB_HMAC) snprintf(out, cap, "HS%s", hash->web + 4);
|
|
721
|
+
else if (alg == JS_WEB_CHACHA20_POLY1305) snprintf(out, cap, "C20P");
|
|
717
722
|
else snprintf(out, cap, "A%u%s", length, web_alg_name(alg) + 4);
|
|
718
723
|
}
|
|
719
724
|
|
|
@@ -728,6 +733,14 @@ static JSValue aes_algorithm(JSContext *ctx, const char *name, uint32_t length)
|
|
|
728
733
|
return o;
|
|
729
734
|
}
|
|
730
735
|
|
|
736
|
+
/* a secret key's algorithm object: { name, length } for AES; ChaCha20-Poly1305's, { name } */
|
|
737
|
+
static JSValue secret_algorithm(JSContext *ctx, uint8_t alg, const char *name, uint32_t length) {
|
|
738
|
+
if (alg != JS_WEB_CHACHA20_POLY1305) return aes_algorithm(ctx, name, length);
|
|
739
|
+
JSValue a = js_new_object(ctx);
|
|
740
|
+
put(ctx, a, "name", str(ctx, name));
|
|
741
|
+
return a;
|
|
742
|
+
}
|
|
743
|
+
|
|
731
744
|
static JSValue import_aes(JSContext *ctx, int format, JSValue key_data, const JWK *jwk, Params *p, bool extractable, JSValue usages,
|
|
732
745
|
uint16_t mask) {
|
|
733
746
|
uint8_t alg = params_alg(p);
|
|
@@ -750,7 +763,7 @@ static JSValue import_aes(JSContext *ctx, int format, JSValue key_data, const JW
|
|
|
750
763
|
return dom_error(ctx, "NotSupportedError", m);
|
|
751
764
|
}
|
|
752
765
|
uint32_t length = (uint32_t)raw.n * 8;
|
|
753
|
-
if (length != 128 && length != 192 && length != 256) {
|
|
766
|
+
if (alg == JS_WEB_CHACHA20_POLY1305 ? length != 256 : length != 128 && length != 192 && length != 256) {
|
|
754
767
|
bytes_free(&raw);
|
|
755
768
|
return dom_error(ctx, "DataError", "Invalid key length");
|
|
756
769
|
}
|
|
@@ -764,7 +777,7 @@ static JSValue import_aes(JSContext *ctx, int format, JSValue key_data, const JW
|
|
|
764
777
|
}
|
|
765
778
|
JSValue data = js_new_secret_key(ctx, raw.p, raw.n);
|
|
766
779
|
bytes_free(&raw);
|
|
767
|
-
return js_new_crypto_key(ctx, data, alg, NULL, length,
|
|
780
|
+
return js_new_crypto_key(ctx, data, alg, NULL, length, secret_algorithm(ctx, alg, p->name, length), usages, mask, extractable);
|
|
768
781
|
}
|
|
769
782
|
|
|
770
783
|
/* ---- Asymmetric keys: RSA, EC, X25519 and Ed25519 ------------------------------------------------- */
|
|
@@ -1048,6 +1061,18 @@ static JSValue generate_asym(JSContext *ctx, Params *p, bool extractable, uint16
|
|
|
1048
1061
|
return pair;
|
|
1049
1062
|
}
|
|
1050
1063
|
|
|
1064
|
+
/* A raw-* format as raw for the algorithm it fits (raw-secret: a secret key's; raw-public: an EC,
|
|
1065
|
+
* X25519 or Ed25519 public key's), other formats as they are; -1 where it doesn't fit (raw-private
|
|
1066
|
+
* and raw-seed are ML-DSA's and ML-KEM's). */
|
|
1067
|
+
static int raw_alias(int alg, int format) {
|
|
1068
|
+
if (format == FORMAT_RAW && alg == JS_WEB_CHACHA20_POLY1305) return -1; /* Node: raw-secret only */
|
|
1069
|
+
if (format < FORMAT_RAW_PUBLIC) return format;
|
|
1070
|
+
bool secret = !is_asym_alg(alg);
|
|
1071
|
+
if (format == FORMAT_RAW_SECRET && secret) return FORMAT_RAW;
|
|
1072
|
+
if (format == FORMAT_RAW_PUBLIC && !secret && alg != JS_WEB_RSASSA && alg != JS_WEB_RSA_PSS && alg != JS_WEB_RSA_OAEP) return FORMAT_RAW;
|
|
1073
|
+
return -1;
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1051
1076
|
/* importKey's steps after the `this` check, for subtle.importKey and deriveKey. */
|
|
1052
1077
|
static JSValue import_key(JSContext *ctx, uint32_t argc, const JSValue *argv) {
|
|
1053
1078
|
Call c = { ctx, "importKey" };
|
|
@@ -1066,6 +1091,14 @@ static JSValue import_key(JSContext *ctx, uint32_t argc, const JSValue *argv) {
|
|
|
1066
1091
|
params_free(&p);
|
|
1067
1092
|
return JS_EXCEPTION;
|
|
1068
1093
|
}
|
|
1094
|
+
int raw = raw_alias(REGISTRY[p.entry].alg, format);
|
|
1095
|
+
if (raw < 0) {
|
|
1096
|
+
char m[96];
|
|
1097
|
+
snprintf(m, sizeof m, "Unable to import %s using %s format", p.name, FORMATS[format]);
|
|
1098
|
+
params_free(&p);
|
|
1099
|
+
return dom_error(ctx, "NotSupportedError", m);
|
|
1100
|
+
}
|
|
1101
|
+
format = raw;
|
|
1069
1102
|
JSValue key;
|
|
1070
1103
|
switch (REGISTRY[p.entry].alg) {
|
|
1071
1104
|
case JS_WEB_HMAC:
|
|
@@ -1075,6 +1108,7 @@ static JSValue import_key(JSContext *ctx, uint32_t argc, const JSValue *argv) {
|
|
|
1075
1108
|
case JS_WEB_AES_CBC:
|
|
1076
1109
|
case JS_WEB_AES_GCM:
|
|
1077
1110
|
case JS_WEB_AES_KW:
|
|
1111
|
+
case JS_WEB_CHACHA20_POLY1305:
|
|
1078
1112
|
key = import_aes(ctx, format, argv[1], &jwk, &p, extractable, usages, mask);
|
|
1079
1113
|
break;
|
|
1080
1114
|
case JS_WEB_RSASSA:
|
|
@@ -1121,6 +1155,14 @@ static JSValue export_key(JSContext *ctx, uint32_t argc, const JSValue *argv) {
|
|
|
1121
1155
|
return dom_error(ctx, "NotSupportedError", m);
|
|
1122
1156
|
}
|
|
1123
1157
|
if (!k->extractable) return dom_error(ctx, "InvalidAccessError", "key is not extractable");
|
|
1158
|
+
int raw = raw_alias(k->alg, format);
|
|
1159
|
+
if (raw < 0 || (format == FORMAT_RAW_PUBLIC && js_key_data(k->data)->type != JS_KEY_PUBLIC)) {
|
|
1160
|
+
uint8_t type = js_key_data(k->data)->type;
|
|
1161
|
+
snprintf(m, sizeof m, "Unable to export %s %s key using %s format", web_alg_name(k->alg),
|
|
1162
|
+
type == JS_KEY_SECRET ? "secret" : type == JS_KEY_PUBLIC ? "public" : "private", FORMATS[format]);
|
|
1163
|
+
return dom_error(ctx, "NotSupportedError", m);
|
|
1164
|
+
}
|
|
1165
|
+
format = raw;
|
|
1124
1166
|
if (is_asym_alg(k->alg)) return export_asym(ctx, format, k);
|
|
1125
1167
|
JSKeyData *d = js_key_data(k->data);
|
|
1126
1168
|
if (format == FORMAT_RAW) return array_buffer_of(ctx, d->bytes, d->len);
|
|
@@ -1229,6 +1271,9 @@ static JSValue generate_key(JSContext *ctx, uint32_t argc, const JSValue *argv)
|
|
|
1229
1271
|
if (p.has_length && p.length == 0) return dom_error(ctx, "OperationError", "HmacKeyGenParams.length cannot be 0");
|
|
1230
1272
|
length = p.has_length ? p.length : (uint32_t)p.hash->block_len * 8;
|
|
1231
1273
|
if (has_any_not_in(mask, JS_USAGE_SIGN | JS_USAGE_VERIFY)) return dom_error(ctx, "SyntaxError", "Unsupported key usage for HMAC key");
|
|
1274
|
+
} else if (alg == JS_WEB_CHACHA20_POLY1305) {
|
|
1275
|
+
length = 256;
|
|
1276
|
+
if (has_any_not_in(mask, aes_usages(alg))) return usage_error(ctx, p.name);
|
|
1232
1277
|
} else {
|
|
1233
1278
|
length = p.length;
|
|
1234
1279
|
if (length != 128 && length != 192 && length != 256)
|
|
@@ -1245,7 +1290,7 @@ static JSValue generate_key(JSContext *ctx, uint32_t argc, const JSValue *argv)
|
|
|
1245
1290
|
JSValue data = js_new_secret_key(ctx, bytes, n);
|
|
1246
1291
|
free(bytes);
|
|
1247
1292
|
if (js_array_length(js_as_object(usages)) == 0) return dom_error(ctx, "SyntaxError", "Usages cannot be empty when creating a key.");
|
|
1248
|
-
JSValue algorithm = alg == JS_WEB_HMAC ? hmac_algorithm(ctx, p.hash, length) :
|
|
1293
|
+
JSValue algorithm = alg == JS_WEB_HMAC ? hmac_algorithm(ctx, p.hash, length) : secret_algorithm(ctx, alg, p.name, length);
|
|
1249
1294
|
return js_new_crypto_key(ctx, data, alg, p.hash, length, algorithm, usages, mask, extractable);
|
|
1250
1295
|
}
|
|
1251
1296
|
|
|
@@ -1564,6 +1609,20 @@ static JSValue aes_cipher(JSContext *ctx, bool encrypt, JSCryptoKey *k, Params *
|
|
|
1564
1609
|
data->p, data->n - tag_n, &out);
|
|
1565
1610
|
break;
|
|
1566
1611
|
}
|
|
1612
|
+
case JS_WEB_CHACHA20_POLY1305: {
|
|
1613
|
+
uint32_t tag_bits = p->has_tag_length ? p->tag_length : 128;
|
|
1614
|
+
if (tag_bits != 128) {
|
|
1615
|
+
char m[64];
|
|
1616
|
+
snprintf(m, sizeof m, "%u is not a valid ChaCha20-Poly1305 tag length", tag_bits);
|
|
1617
|
+
return dom_error(ctx, "OperationError", m);
|
|
1618
|
+
}
|
|
1619
|
+
if (p->iv.n != 12) return dom_error(ctx, "OperationError", "algorithm.iv must contain exactly 12 bytes");
|
|
1620
|
+
if (!encrypt && data->n < 16) return op_failed(ctx);
|
|
1621
|
+
const JSCipherAlg *alg = js_cipher_by_name("chacha20-poly1305");
|
|
1622
|
+
ok = encrypt ? run_cipher(alg, true, d, p->iv.p, 12, 16, &p->additional_data, NULL, 0, data->p, data->n, &out)
|
|
1623
|
+
: run_cipher(alg, false, d, p->iv.p, 12, 16, &p->additional_data, data->p + data->n - 16, 16, data->p, data->n - 16, &out);
|
|
1624
|
+
break;
|
|
1625
|
+
}
|
|
1567
1626
|
default: { /* AES-KW, with RFC 3394's default IV */
|
|
1568
1627
|
static const uint8_t KW_IV[8] = { 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6 };
|
|
1569
1628
|
ok = run_cipher(js_cipher_aes(JS_CIPHER_WRAP, d->len), encrypt, d, KW_IV, 8, -1, NULL, NULL, 0, data->p, data->n, &out);
|