visaljs 0.0.0-stage → 0.0.2

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.
Files changed (520) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +45 -2
  3. package/cli.js +8084 -0
  4. package/node/include/js_node.h +46 -0
  5. package/node/prelude/async_hooks.js +88 -0
  6. package/node/prelude/buffer.js +31 -0
  7. package/node/prelude/crypto.js +114 -0
  8. package/node/prelude/events.js +227 -0
  9. package/node/prelude/fs.js +79 -0
  10. package/node/prelude/http.js +536 -0
  11. package/node/prelude/http2.js +30 -0
  12. package/node/prelude/internal/crypto/asym.js +333 -0
  13. package/node/prelude/internal/crypto/cipher.js +205 -0
  14. package/node/prelude/internal/crypto/hash.js +137 -0
  15. package/node/prelude/internal/crypto/kdf.js +182 -0
  16. package/node/prelude/internal/crypto/keys.js +603 -0
  17. package/node/prelude/internal/crypto/random.js +118 -0
  18. package/node/prelude/internal/crypto/util.js +76 -0
  19. package/node/prelude/internal/errors.js +88 -0
  20. package/node/prelude/internal/querystring.js +105 -0
  21. package/node/prelude/module.js +53 -0
  22. package/node/prelude/net.js +51 -0
  23. package/node/prelude/os.js +129 -0
  24. package/node/prelude/path.js +257 -0
  25. package/node/prelude/process.js +21 -0
  26. package/node/prelude/querystring.js +469 -0
  27. package/node/prelude/stream.js +1327 -0
  28. package/node/prelude/stream_promises.js +7 -0
  29. package/node/prelude/stream_web.js +6 -0
  30. package/node/prelude/string_decoder.js +236 -0
  31. package/node/prelude/tty.js +18 -0
  32. package/node/prelude/url.js +1156 -0
  33. package/node/prelude/util.js +64 -0
  34. package/node/prelude/zlib.js +81 -0
  35. package/node/src/host_fs.c +126 -0
  36. package/node/src/host_http.c +486 -0
  37. package/node/src/host_os.c +505 -0
  38. package/node/src/host_sys.c +78 -0
  39. package/node/third_party/libuv/LICENSE +19 -0
  40. package/node/third_party/libuv/include/uv/aix.h +32 -0
  41. package/node/third_party/libuv/include/uv/bsd.h +34 -0
  42. package/node/third_party/libuv/include/uv/darwin.h +61 -0
  43. package/node/third_party/libuv/include/uv/errno.h +483 -0
  44. package/node/third_party/libuv/include/uv/linux.h +34 -0
  45. package/node/third_party/libuv/include/uv/os390.h +33 -0
  46. package/node/third_party/libuv/include/uv/posix.h +31 -0
  47. package/node/third_party/libuv/include/uv/sunos.h +44 -0
  48. package/node/third_party/libuv/include/uv/threadpool.h +37 -0
  49. package/node/third_party/libuv/include/uv/tree.h +521 -0
  50. package/node/third_party/libuv/include/uv/unix.h +512 -0
  51. package/node/third_party/libuv/include/uv/version.h +43 -0
  52. package/node/third_party/libuv/include/uv/win.h +698 -0
  53. package/node/third_party/libuv/include/uv.h +1990 -0
  54. package/node/third_party/libuv/src/fs-poll.c +290 -0
  55. package/node/third_party/libuv/src/heap-inl.h +245 -0
  56. package/node/third_party/libuv/src/idna.c +560 -0
  57. package/node/third_party/libuv/src/idna.h +31 -0
  58. package/node/third_party/libuv/src/inet.c +298 -0
  59. package/node/third_party/libuv/src/queue.h +90 -0
  60. package/node/third_party/libuv/src/random.c +123 -0
  61. package/node/third_party/libuv/src/strscpy.c +38 -0
  62. package/node/third_party/libuv/src/strscpy.h +39 -0
  63. package/node/third_party/libuv/src/strtok.c +52 -0
  64. package/node/third_party/libuv/src/strtok.h +27 -0
  65. package/node/third_party/libuv/src/thread-common.c +175 -0
  66. package/node/third_party/libuv/src/threadpool.c +419 -0
  67. package/node/third_party/libuv/src/timer.c +200 -0
  68. package/node/third_party/libuv/src/unix/async.c +418 -0
  69. package/node/third_party/libuv/src/unix/bsd-ifaddrs.c +164 -0
  70. package/node/third_party/libuv/src/unix/core.c +2104 -0
  71. package/node/third_party/libuv/src/unix/darwin-proctitle.c +176 -0
  72. package/node/third_party/libuv/src/unix/darwin-stub.h +97 -0
  73. package/node/third_party/libuv/src/unix/darwin-syscalls.h +17 -0
  74. package/node/third_party/libuv/src/unix/darwin.c +237 -0
  75. package/node/third_party/libuv/src/unix/dl.c +80 -0
  76. package/node/third_party/libuv/src/unix/fs.c +2303 -0
  77. package/node/third_party/libuv/src/unix/fsevents.c +906 -0
  78. package/node/third_party/libuv/src/unix/getaddrinfo.c +252 -0
  79. package/node/third_party/libuv/src/unix/getnameinfo.c +121 -0
  80. package/node/third_party/libuv/src/unix/internal.h +530 -0
  81. package/node/third_party/libuv/src/unix/kqueue.c +667 -0
  82. package/node/third_party/libuv/src/unix/linux.c +2761 -0
  83. package/node/third_party/libuv/src/unix/loop-watcher.c +68 -0
  84. package/node/third_party/libuv/src/unix/loop.c +240 -0
  85. package/node/third_party/libuv/src/unix/pipe.c +555 -0
  86. package/node/third_party/libuv/src/unix/poll.c +159 -0
  87. package/node/third_party/libuv/src/unix/process.c +1123 -0
  88. package/node/third_party/libuv/src/unix/procfs-exepath.c +45 -0
  89. package/node/third_party/libuv/src/unix/proctitle.c +157 -0
  90. package/node/third_party/libuv/src/unix/random-devurandom.c +93 -0
  91. package/node/third_party/libuv/src/unix/random-getentropy.c +57 -0
  92. package/node/third_party/libuv/src/unix/random-getrandom.c +86 -0
  93. package/node/third_party/libuv/src/unix/random-sysctl-linux.c +99 -0
  94. package/node/third_party/libuv/src/unix/signal.c +581 -0
  95. package/node/third_party/libuv/src/unix/stream.c +1567 -0
  96. package/node/third_party/libuv/src/unix/tcp.c +673 -0
  97. package/node/third_party/libuv/src/unix/thread.c +975 -0
  98. package/node/third_party/libuv/src/unix/tty.c +510 -0
  99. package/node/third_party/libuv/src/unix/udp.c +1434 -0
  100. package/node/third_party/libuv/src/uv-common.c +1051 -0
  101. package/node/third_party/libuv/src/uv-common.h +474 -0
  102. package/node/third_party/libuv/src/uv-data-getter-setters.c +119 -0
  103. package/node/third_party/libuv/src/version.c +45 -0
  104. package/node/third_party/llhttp/LICENSE +22 -0
  105. package/node/third_party/llhttp/api.c +509 -0
  106. package/node/third_party/llhttp/http.c +170 -0
  107. package/node/third_party/llhttp/llhttp.c +10099 -0
  108. package/node/third_party/llhttp/llhttp.h +907 -0
  109. package/package.json +25 -4
  110. package/runtime/include/js_atoms.gen.h +68 -0
  111. package/runtime/include/js_atoms.h +54 -0
  112. package/runtime/include/js_bigint.h +93 -0
  113. package/runtime/include/js_buffer.h +79 -0
  114. package/runtime/include/js_builtins.h +168 -0
  115. package/runtime/include/js_console.h +58 -0
  116. package/runtime/include/js_convert.h +22 -0
  117. package/runtime/include/js_core.def +188 -0
  118. package/runtime/include/js_crypto.h +58 -0
  119. package/runtime/include/js_error.h +37 -0
  120. package/runtime/include/js_exception.h +65 -0
  121. package/runtime/include/js_function.h +167 -0
  122. package/runtime/include/js_gc.h +195 -0
  123. package/runtime/include/js_generator.h +96 -0
  124. package/runtime/include/js_host.h +19 -0
  125. package/runtime/include/js_jobs.h +84 -0
  126. package/runtime/include/js_module.h +16 -0
  127. package/runtime/include/js_object.h +384 -0
  128. package/runtime/include/js_ops.h +111 -0
  129. package/runtime/include/js_promise.h +45 -0
  130. package/runtime/include/js_regexp.h +25 -0
  131. package/runtime/include/js_runtime.h +30 -0
  132. package/runtime/include/js_symbol.h +62 -0
  133. package/runtime/include/js_web.h +110 -0
  134. package/runtime/include/jscell.h +48 -0
  135. package/runtime/include/jscontext.h +240 -0
  136. package/runtime/include/jsnum.h +42 -0
  137. package/runtime/include/jsstring.h +161 -0
  138. package/runtime/include/jsvalue.h +142 -0
  139. package/runtime/src/arguments.c +115 -0
  140. package/runtime/src/array.c +1145 -0
  141. package/runtime/src/arraybuffer.c +608 -0
  142. package/runtime/src/async_iter.c +479 -0
  143. package/runtime/src/atoms.c +157 -0
  144. package/runtime/src/base64.c +107 -0
  145. package/runtime/src/bigint.c +1189 -0
  146. package/runtime/src/blob.c +371 -0
  147. package/runtime/src/buffer.c +1357 -0
  148. package/runtime/src/builtin_table.c +100 -0
  149. package/runtime/src/builtins.c +987 -0
  150. package/runtime/src/builtins_util.h +53 -0
  151. package/runtime/src/collections.c +912 -0
  152. package/runtime/src/components.c +28 -0
  153. package/runtime/src/console.c +637 -0
  154. package/runtime/src/convert.c +82 -0
  155. package/runtime/src/core_all.c +21 -0
  156. package/runtime/src/crypto.c +116 -0
  157. package/runtime/src/crypto_asym.c +644 -0
  158. package/runtime/src/crypto_cipher.c +671 -0
  159. package/runtime/src/crypto_hash.c +260 -0
  160. package/runtime/src/crypto_host.c +414 -0
  161. package/runtime/src/crypto_internal.h +304 -0
  162. package/runtime/src/crypto_kdf.c +143 -0
  163. package/runtime/src/crypto_key.c +171 -0
  164. package/runtime/src/crypto_pkey.c +794 -0
  165. package/runtime/src/crypto_subtle.c +1675 -0
  166. package/runtime/src/date.c +940 -0
  167. package/runtime/src/domexception.c +169 -0
  168. package/runtime/src/elements.c +312 -0
  169. package/runtime/src/elements.h +45 -0
  170. package/runtime/src/encoding.c +485 -0
  171. package/runtime/src/error.c +297 -0
  172. package/runtime/src/events.c +793 -0
  173. package/runtime/src/exception.c +56 -0
  174. package/runtime/src/fetch.c +772 -0
  175. package/runtime/src/function.c +530 -0
  176. package/runtime/src/gc.c +803 -0
  177. package/runtime/src/generator.c +218 -0
  178. package/runtime/src/global.c +119 -0
  179. package/runtime/src/headers.c +557 -0
  180. package/runtime/src/inspect.c +1792 -0
  181. package/runtime/src/internal.h +80 -0
  182. package/runtime/src/iterate.c +94 -0
  183. package/runtime/src/iterator.c +409 -0
  184. package/runtime/src/jobs.c +337 -0
  185. package/runtime/src/jsnum.c +353 -0
  186. package/runtime/src/json.c +1028 -0
  187. package/runtime/src/math.c +243 -0
  188. package/runtime/src/module.c +336 -0
  189. package/runtime/src/number.c +176 -0
  190. package/runtime/src/object.c +1265 -0
  191. package/runtime/src/ops.c +322 -0
  192. package/runtime/src/os.c +196 -0
  193. package/runtime/src/os.h +29 -0
  194. package/runtime/src/process.c +432 -0
  195. package/runtime/src/promise.c +721 -0
  196. package/runtime/src/proxy.c +570 -0
  197. package/runtime/src/reflect.c +194 -0
  198. package/runtime/src/regexp.c +1141 -0
  199. package/runtime/src/regexp_anchor.h +34 -0
  200. package/runtime/src/regexp_message.h +32 -0
  201. package/runtime/src/shape.c +294 -0
  202. package/runtime/src/shape.h +46 -0
  203. package/runtime/src/streams.c +1046 -0
  204. package/runtime/src/streams.h +47 -0
  205. package/runtime/src/string.c +364 -0
  206. package/runtime/src/string_builtins.c +837 -0
  207. package/runtime/src/symbol.c +143 -0
  208. package/runtime/src/test_host.c +59 -0
  209. package/runtime/src/typedarray.c +1330 -0
  210. package/runtime/src/tznames.gen.h +712 -0
  211. package/runtime/src/uri.c +169 -0
  212. package/runtime/src/url.c +2116 -0
  213. package/runtime/src/weak.c +486 -0
  214. package/runtime/src/web.c +214 -0
  215. package/runtime/src/wrapper.c +59 -0
  216. package/runtime/src/writable.c +1486 -0
  217. package/runtime/third_party/ada-idna/LICENSE-MIT +18 -0
  218. package/runtime/third_party/ada-idna/README.md +27 -0
  219. package/runtime/third_party/ada-idna/convert.mjs +83 -0
  220. package/runtime/third_party/ada-idna/idna.c +416 -0
  221. package/runtime/third_party/ada-idna/idna.h +15 -0
  222. package/runtime/third_party/ada-idna/idna_tables.h +2657 -0
  223. package/runtime/third_party/bearssl/LICENSE.txt +21 -0
  224. package/runtime/third_party/bearssl/README.txt +136 -0
  225. package/runtime/third_party/bearssl/VERSION +1 -0
  226. package/runtime/third_party/bearssl/inc/bearssl.h +183 -0
  227. package/runtime/third_party/bearssl/inc/bearssl_aead.h +1059 -0
  228. package/runtime/third_party/bearssl/inc/bearssl_block.h +2618 -0
  229. package/runtime/third_party/bearssl/inc/bearssl_ec.h +967 -0
  230. package/runtime/third_party/bearssl/inc/bearssl_hash.h +1346 -0
  231. package/runtime/third_party/bearssl/inc/bearssl_hmac.h +241 -0
  232. package/runtime/third_party/bearssl/inc/bearssl_kdf.h +284 -0
  233. package/runtime/third_party/bearssl/inc/bearssl_pem.h +294 -0
  234. package/runtime/third_party/bearssl/inc/bearssl_prf.h +150 -0
  235. package/runtime/third_party/bearssl/inc/bearssl_rand.h +397 -0
  236. package/runtime/third_party/bearssl/inc/bearssl_rsa.h +1655 -0
  237. package/runtime/third_party/bearssl/inc/bearssl_ssl.h +4296 -0
  238. package/runtime/third_party/bearssl/inc/bearssl_x509.h +1474 -0
  239. package/runtime/third_party/bearssl/src/aead/ccm.c +346 -0
  240. package/runtime/third_party/bearssl/src/aead/eax.c +525 -0
  241. package/runtime/third_party/bearssl/src/aead/gcm.c +318 -0
  242. package/runtime/third_party/bearssl/src/codec/ccopy.c +44 -0
  243. package/runtime/third_party/bearssl/src/codec/dec16be.c +38 -0
  244. package/runtime/third_party/bearssl/src/codec/dec16le.c +38 -0
  245. package/runtime/third_party/bearssl/src/codec/dec32be.c +38 -0
  246. package/runtime/third_party/bearssl/src/codec/dec32le.c +38 -0
  247. package/runtime/third_party/bearssl/src/codec/dec64be.c +38 -0
  248. package/runtime/third_party/bearssl/src/codec/dec64le.c +38 -0
  249. package/runtime/third_party/bearssl/src/codec/enc16be.c +38 -0
  250. package/runtime/third_party/bearssl/src/codec/enc16le.c +38 -0
  251. package/runtime/third_party/bearssl/src/codec/enc32be.c +38 -0
  252. package/runtime/third_party/bearssl/src/codec/enc32le.c +38 -0
  253. package/runtime/third_party/bearssl/src/codec/enc64be.c +38 -0
  254. package/runtime/third_party/bearssl/src/codec/enc64le.c +38 -0
  255. package/runtime/third_party/bearssl/src/codec/pemdec.c +526 -0
  256. package/runtime/third_party/bearssl/src/codec/pemdec.t0 +314 -0
  257. package/runtime/third_party/bearssl/src/codec/pemenc.c +173 -0
  258. package/runtime/third_party/bearssl/src/config.h +247 -0
  259. package/runtime/third_party/bearssl/src/ec/ec_all_m15.c +121 -0
  260. package/runtime/third_party/bearssl/src/ec/ec_all_m31.c +171 -0
  261. package/runtime/third_party/bearssl/src/ec/ec_c25519_i15.c +398 -0
  262. package/runtime/third_party/bearssl/src/ec/ec_c25519_i31.c +390 -0
  263. package/runtime/third_party/bearssl/src/ec/ec_c25519_m15.c +1478 -0
  264. package/runtime/third_party/bearssl/src/ec/ec_c25519_m31.c +800 -0
  265. package/runtime/third_party/bearssl/src/ec/ec_c25519_m62.c +605 -0
  266. package/runtime/third_party/bearssl/src/ec/ec_c25519_m64.c +831 -0
  267. package/runtime/third_party/bearssl/src/ec/ec_curve25519.c +46 -0
  268. package/runtime/third_party/bearssl/src/ec/ec_default.c +36 -0
  269. package/runtime/third_party/bearssl/src/ec/ec_keygen.c +86 -0
  270. package/runtime/third_party/bearssl/src/ec/ec_p256_m15.c +2124 -0
  271. package/runtime/third_party/bearssl/src/ec/ec_p256_m31.c +1469 -0
  272. package/runtime/third_party/bearssl/src/ec/ec_p256_m62.c +1765 -0
  273. package/runtime/third_party/bearssl/src/ec/ec_p256_m64.c +1781 -0
  274. package/runtime/third_party/bearssl/src/ec/ec_prime_i15.c +824 -0
  275. package/runtime/third_party/bearssl/src/ec/ec_prime_i31.c +826 -0
  276. package/runtime/third_party/bearssl/src/ec/ec_pubkey.c +85 -0
  277. package/runtime/third_party/bearssl/src/ec/ec_secp256r1.c +51 -0
  278. package/runtime/third_party/bearssl/src/ec/ec_secp384r1.c +57 -0
  279. package/runtime/third_party/bearssl/src/ec/ec_secp521r1.c +64 -0
  280. package/runtime/third_party/bearssl/src/ec/ecdsa_atr.c +134 -0
  281. package/runtime/third_party/bearssl/src/ec/ecdsa_default_sign_asn1.c +36 -0
  282. package/runtime/third_party/bearssl/src/ec/ecdsa_default_sign_raw.c +36 -0
  283. package/runtime/third_party/bearssl/src/ec/ecdsa_default_vrfy_asn1.c +36 -0
  284. package/runtime/third_party/bearssl/src/ec/ecdsa_default_vrfy_raw.c +36 -0
  285. package/runtime/third_party/bearssl/src/ec/ecdsa_i15_bits.c +47 -0
  286. package/runtime/third_party/bearssl/src/ec/ecdsa_i15_sign_asn1.c +45 -0
  287. package/runtime/third_party/bearssl/src/ec/ecdsa_i15_sign_raw.c +174 -0
  288. package/runtime/third_party/bearssl/src/ec/ecdsa_i15_vrfy_asn1.c +48 -0
  289. package/runtime/third_party/bearssl/src/ec/ecdsa_i15_vrfy_raw.c +166 -0
  290. package/runtime/third_party/bearssl/src/ec/ecdsa_i31_bits.c +47 -0
  291. package/runtime/third_party/bearssl/src/ec/ecdsa_i31_sign_asn1.c +45 -0
  292. package/runtime/third_party/bearssl/src/ec/ecdsa_i31_sign_raw.c +173 -0
  293. package/runtime/third_party/bearssl/src/ec/ecdsa_i31_vrfy_asn1.c +48 -0
  294. package/runtime/third_party/bearssl/src/ec/ecdsa_i31_vrfy_raw.c +165 -0
  295. package/runtime/third_party/bearssl/src/ec/ecdsa_rta.c +121 -0
  296. package/runtime/third_party/bearssl/src/hash/dig_oid.c +84 -0
  297. package/runtime/third_party/bearssl/src/hash/dig_size.c +50 -0
  298. package/runtime/third_party/bearssl/src/hash/ghash_ctmul.c +345 -0
  299. package/runtime/third_party/bearssl/src/hash/ghash_ctmul32.c +251 -0
  300. package/runtime/third_party/bearssl/src/hash/ghash_ctmul64.c +154 -0
  301. package/runtime/third_party/bearssl/src/hash/ghash_pclmul.c +389 -0
  302. package/runtime/third_party/bearssl/src/hash/ghash_pwr8.c +411 -0
  303. package/runtime/third_party/bearssl/src/hash/md5.c +208 -0
  304. package/runtime/third_party/bearssl/src/hash/md5sha1.c +141 -0
  305. package/runtime/third_party/bearssl/src/hash/mgf1.c +56 -0
  306. package/runtime/third_party/bearssl/src/hash/multihash.c +166 -0
  307. package/runtime/third_party/bearssl/src/hash/sha1.c +191 -0
  308. package/runtime/third_party/bearssl/src/hash/sha2big.c +285 -0
  309. package/runtime/third_party/bearssl/src/hash/sha2small.c +341 -0
  310. package/runtime/third_party/bearssl/src/inner.h +2577 -0
  311. package/runtime/third_party/bearssl/src/int/i15_add.c +46 -0
  312. package/runtime/third_party/bearssl/src/int/i15_bitlen.c +44 -0
  313. package/runtime/third_party/bearssl/src/int/i15_decmod.c +124 -0
  314. package/runtime/third_party/bearssl/src/int/i15_decode.c +56 -0
  315. package/runtime/third_party/bearssl/src/int/i15_decred.c +100 -0
  316. package/runtime/third_party/bearssl/src/int/i15_encode.c +56 -0
  317. package/runtime/third_party/bearssl/src/int/i15_fmont.c +59 -0
  318. package/runtime/third_party/bearssl/src/int/i15_iszero.c +39 -0
  319. package/runtime/third_party/bearssl/src/int/i15_moddiv.c +465 -0
  320. package/runtime/third_party/bearssl/src/int/i15_modpow.c +50 -0
  321. package/runtime/third_party/bearssl/src/int/i15_modpow2.c +160 -0
  322. package/runtime/third_party/bearssl/src/int/i15_montmul.c +184 -0
  323. package/runtime/third_party/bearssl/src/int/i15_mulacc.c +61 -0
  324. package/runtime/third_party/bearssl/src/int/i15_muladd.c +173 -0
  325. package/runtime/third_party/bearssl/src/int/i15_ninv15.c +38 -0
  326. package/runtime/third_party/bearssl/src/int/i15_reduce.c +66 -0
  327. package/runtime/third_party/bearssl/src/int/i15_rshift.c +47 -0
  328. package/runtime/third_party/bearssl/src/int/i15_sub.c +46 -0
  329. package/runtime/third_party/bearssl/src/int/i15_tmont.c +36 -0
  330. package/runtime/third_party/bearssl/src/int/i31_add.c +46 -0
  331. package/runtime/third_party/bearssl/src/int/i31_bitlen.c +44 -0
  332. package/runtime/third_party/bearssl/src/int/i31_decmod.c +124 -0
  333. package/runtime/third_party/bearssl/src/int/i31_decode.c +57 -0
  334. package/runtime/third_party/bearssl/src/int/i31_decred.c +103 -0
  335. package/runtime/third_party/bearssl/src/int/i31_encode.c +79 -0
  336. package/runtime/third_party/bearssl/src/int/i31_fmont.c +60 -0
  337. package/runtime/third_party/bearssl/src/int/i31_iszero.c +39 -0
  338. package/runtime/third_party/bearssl/src/int/i31_moddiv.c +488 -0
  339. package/runtime/third_party/bearssl/src/int/i31_modpow.c +65 -0
  340. package/runtime/third_party/bearssl/src/int/i31_modpow2.c +160 -0
  341. package/runtime/third_party/bearssl/src/int/i31_montmul.c +127 -0
  342. package/runtime/third_party/bearssl/src/int/i31_mulacc.c +74 -0
  343. package/runtime/third_party/bearssl/src/int/i31_muladd.c +157 -0
  344. package/runtime/third_party/bearssl/src/int/i31_ninv31.c +39 -0
  345. package/runtime/third_party/bearssl/src/int/i31_reduce.c +66 -0
  346. package/runtime/third_party/bearssl/src/int/i31_rshift.c +47 -0
  347. package/runtime/third_party/bearssl/src/int/i31_sub.c +46 -0
  348. package/runtime/third_party/bearssl/src/int/i31_tmont.c +36 -0
  349. package/runtime/third_party/bearssl/src/int/i32_add.c +51 -0
  350. package/runtime/third_party/bearssl/src/int/i32_bitlen.c +44 -0
  351. package/runtime/third_party/bearssl/src/int/i32_decmod.c +77 -0
  352. package/runtime/third_party/bearssl/src/int/i32_decode.c +63 -0
  353. package/runtime/third_party/bearssl/src/int/i32_decred.c +107 -0
  354. package/runtime/third_party/bearssl/src/int/i32_div32.c +56 -0
  355. package/runtime/third_party/bearssl/src/int/i32_encode.c +72 -0
  356. package/runtime/third_party/bearssl/src/int/i32_fmont.c +60 -0
  357. package/runtime/third_party/bearssl/src/int/i32_iszero.c +39 -0
  358. package/runtime/third_party/bearssl/src/int/i32_modpow.c +65 -0
  359. package/runtime/third_party/bearssl/src/int/i32_montmul.c +69 -0
  360. package/runtime/third_party/bearssl/src/int/i32_mulacc.c +56 -0
  361. package/runtime/third_party/bearssl/src/int/i32_muladd.c +138 -0
  362. package/runtime/third_party/bearssl/src/int/i32_ninv32.c +39 -0
  363. package/runtime/third_party/bearssl/src/int/i32_reduce.c +66 -0
  364. package/runtime/third_party/bearssl/src/int/i32_sub.c +51 -0
  365. package/runtime/third_party/bearssl/src/int/i32_tmont.c +36 -0
  366. package/runtime/third_party/bearssl/src/int/i62_modpow2.c +493 -0
  367. package/runtime/third_party/bearssl/src/kdf/hkdf.c +107 -0
  368. package/runtime/third_party/bearssl/src/kdf/shake.c +590 -0
  369. package/runtime/third_party/bearssl/src/mac/hmac.c +122 -0
  370. package/runtime/third_party/bearssl/src/mac/hmac_ct.c +193 -0
  371. package/runtime/third_party/bearssl/src/rand/aesctr_drbg.c +206 -0
  372. package/runtime/third_party/bearssl/src/rand/hmac_drbg.c +157 -0
  373. package/runtime/third_party/bearssl/src/rand/sysrng.c +252 -0
  374. package/runtime/third_party/bearssl/src/rsa/rsa_default_keygen.c +38 -0
  375. package/runtime/third_party/bearssl/src/rsa/rsa_default_modulus.c +36 -0
  376. package/runtime/third_party/bearssl/src/rsa/rsa_default_oaep_decrypt.c +38 -0
  377. package/runtime/third_party/bearssl/src/rsa/rsa_default_oaep_encrypt.c +38 -0
  378. package/runtime/third_party/bearssl/src/rsa/rsa_default_pkcs1_sign.c +38 -0
  379. package/runtime/third_party/bearssl/src/rsa/rsa_default_pkcs1_vrfy.c +38 -0
  380. package/runtime/third_party/bearssl/src/rsa/rsa_default_priv.c +38 -0
  381. package/runtime/third_party/bearssl/src/rsa/rsa_default_privexp.c +36 -0
  382. package/runtime/third_party/bearssl/src/rsa/rsa_default_pss_sign.c +38 -0
  383. package/runtime/third_party/bearssl/src/rsa/rsa_default_pss_vrfy.c +38 -0
  384. package/runtime/third_party/bearssl/src/rsa/rsa_default_pub.c +38 -0
  385. package/runtime/third_party/bearssl/src/rsa/rsa_default_pubexp.c +36 -0
  386. package/runtime/third_party/bearssl/src/rsa/rsa_i15_keygen.c +583 -0
  387. package/runtime/third_party/bearssl/src/rsa/rsa_i15_modulus.c +99 -0
  388. package/runtime/third_party/bearssl/src/rsa/rsa_i15_oaep_decrypt.c +41 -0
  389. package/runtime/third_party/bearssl/src/rsa/rsa_i15_oaep_encrypt.c +44 -0
  390. package/runtime/third_party/bearssl/src/rsa/rsa_i15_pkcs1_sign.c +37 -0
  391. package/runtime/third_party/bearssl/src/rsa/rsa_i15_pkcs1_vrfy.c +43 -0
  392. package/runtime/third_party/bearssl/src/rsa/rsa_i15_priv.c +209 -0
  393. package/runtime/third_party/bearssl/src/rsa/rsa_i15_privexp.c +320 -0
  394. package/runtime/third_party/bearssl/src/rsa/rsa_i15_pss_sign.c +40 -0
  395. package/runtime/third_party/bearssl/src/rsa/rsa_i15_pss_vrfy.c +44 -0
  396. package/runtime/third_party/bearssl/src/rsa/rsa_i15_pub.c +113 -0
  397. package/runtime/third_party/bearssl/src/rsa/rsa_i15_pubexp.c +152 -0
  398. package/runtime/third_party/bearssl/src/rsa/rsa_i31_keygen.c +37 -0
  399. package/runtime/third_party/bearssl/src/rsa/rsa_i31_keygen_inner.c +608 -0
  400. package/runtime/third_party/bearssl/src/rsa/rsa_i31_modulus.c +99 -0
  401. package/runtime/third_party/bearssl/src/rsa/rsa_i31_oaep_decrypt.c +41 -0
  402. package/runtime/third_party/bearssl/src/rsa/rsa_i31_oaep_encrypt.c +44 -0
  403. package/runtime/third_party/bearssl/src/rsa/rsa_i31_pkcs1_sign.c +37 -0
  404. package/runtime/third_party/bearssl/src/rsa/rsa_i31_pkcs1_vrfy.c +43 -0
  405. package/runtime/third_party/bearssl/src/rsa/rsa_i31_priv.c +203 -0
  406. package/runtime/third_party/bearssl/src/rsa/rsa_i31_privexp.c +318 -0
  407. package/runtime/third_party/bearssl/src/rsa/rsa_i31_pss_sign.c +40 -0
  408. package/runtime/third_party/bearssl/src/rsa/rsa_i31_pss_vrfy.c +44 -0
  409. package/runtime/third_party/bearssl/src/rsa/rsa_i31_pub.c +106 -0
  410. package/runtime/third_party/bearssl/src/rsa/rsa_i31_pubexp.c +152 -0
  411. package/runtime/third_party/bearssl/src/rsa/rsa_i32_oaep_decrypt.c +41 -0
  412. package/runtime/third_party/bearssl/src/rsa/rsa_i32_oaep_encrypt.c +44 -0
  413. package/runtime/third_party/bearssl/src/rsa/rsa_i32_pkcs1_sign.c +37 -0
  414. package/runtime/third_party/bearssl/src/rsa/rsa_i32_pkcs1_vrfy.c +43 -0
  415. package/runtime/third_party/bearssl/src/rsa/rsa_i32_priv.c +160 -0
  416. package/runtime/third_party/bearssl/src/rsa/rsa_i32_pss_sign.c +40 -0
  417. package/runtime/third_party/bearssl/src/rsa/rsa_i32_pss_vrfy.c +44 -0
  418. package/runtime/third_party/bearssl/src/rsa/rsa_i32_pub.c +77 -0
  419. package/runtime/third_party/bearssl/src/rsa/rsa_i62_keygen.c +57 -0
  420. package/runtime/third_party/bearssl/src/rsa/rsa_i62_oaep_decrypt.c +61 -0
  421. package/runtime/third_party/bearssl/src/rsa/rsa_i62_oaep_encrypt.c +64 -0
  422. package/runtime/third_party/bearssl/src/rsa/rsa_i62_pkcs1_sign.c +57 -0
  423. package/runtime/third_party/bearssl/src/rsa/rsa_i62_pkcs1_vrfy.c +63 -0
  424. package/runtime/third_party/bearssl/src/rsa/rsa_i62_priv.c +223 -0
  425. package/runtime/third_party/bearssl/src/rsa/rsa_i62_pss_sign.c +60 -0
  426. package/runtime/third_party/bearssl/src/rsa/rsa_i62_pss_vrfy.c +64 -0
  427. package/runtime/third_party/bearssl/src/rsa/rsa_i62_pub.c +125 -0
  428. package/runtime/third_party/bearssl/src/rsa/rsa_oaep_pad.c +112 -0
  429. package/runtime/third_party/bearssl/src/rsa/rsa_oaep_unpad.c +145 -0
  430. package/runtime/third_party/bearssl/src/rsa/rsa_pkcs1_sig_pad.c +100 -0
  431. package/runtime/third_party/bearssl/src/rsa/rsa_pkcs1_sig_unpad.c +121 -0
  432. package/runtime/third_party/bearssl/src/rsa/rsa_pss_sig_pad.c +106 -0
  433. package/runtime/third_party/bearssl/src/rsa/rsa_pss_sig_unpad.c +121 -0
  434. package/runtime/third_party/bearssl/src/rsa/rsa_ssl_decrypt.c +52 -0
  435. package/runtime/third_party/bearssl/src/settings.c +306 -0
  436. package/runtime/third_party/bearssl/src/symcipher/aes_big_cbcdec.c +69 -0
  437. package/runtime/third_party/bearssl/src/symcipher/aes_big_cbcenc.c +67 -0
  438. package/runtime/third_party/bearssl/src/symcipher/aes_big_ctr.c +84 -0
  439. package/runtime/third_party/bearssl/src/symcipher/aes_big_ctrcbc.c +142 -0
  440. package/runtime/third_party/bearssl/src/symcipher/aes_big_dec.c +254 -0
  441. package/runtime/third_party/bearssl/src/symcipher/aes_big_enc.c +157 -0
  442. package/runtime/third_party/bearssl/src/symcipher/aes_common.c +112 -0
  443. package/runtime/third_party/bearssl/src/symcipher/aes_ct.c +328 -0
  444. package/runtime/third_party/bearssl/src/symcipher/aes_ct64.c +398 -0
  445. package/runtime/third_party/bearssl/src/symcipher/aes_ct64_cbcdec.c +104 -0
  446. package/runtime/third_party/bearssl/src/symcipher/aes_ct64_cbcenc.c +81 -0
  447. package/runtime/third_party/bearssl/src/symcipher/aes_ct64_ctr.c +114 -0
  448. package/runtime/third_party/bearssl/src/symcipher/aes_ct64_ctrcbc.c +433 -0
  449. package/runtime/third_party/bearssl/src/symcipher/aes_ct64_dec.c +159 -0
  450. package/runtime/third_party/bearssl/src/symcipher/aes_ct64_enc.c +115 -0
  451. package/runtime/third_party/bearssl/src/symcipher/aes_ct_cbcdec.c +111 -0
  452. package/runtime/third_party/bearssl/src/symcipher/aes_ct_cbcenc.c +91 -0
  453. package/runtime/third_party/bearssl/src/symcipher/aes_ct_ctr.c +116 -0
  454. package/runtime/third_party/bearssl/src/symcipher/aes_ct_ctrcbc.c +422 -0
  455. package/runtime/third_party/bearssl/src/symcipher/aes_ct_dec.c +170 -0
  456. package/runtime/third_party/bearssl/src/symcipher/aes_ct_enc.c +112 -0
  457. package/runtime/third_party/bearssl/src/symcipher/aes_pwr8.c +445 -0
  458. package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_cbcdec.c +670 -0
  459. package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_cbcenc.c +417 -0
  460. package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_ctr.c +717 -0
  461. package/runtime/third_party/bearssl/src/symcipher/aes_pwr8_ctrcbc.c +946 -0
  462. package/runtime/third_party/bearssl/src/symcipher/aes_small_cbcdec.c +69 -0
  463. package/runtime/third_party/bearssl/src/symcipher/aes_small_cbcenc.c +67 -0
  464. package/runtime/third_party/bearssl/src/symcipher/aes_small_ctr.c +84 -0
  465. package/runtime/third_party/bearssl/src/symcipher/aes_small_ctrcbc.c +142 -0
  466. package/runtime/third_party/bearssl/src/symcipher/aes_small_dec.c +176 -0
  467. package/runtime/third_party/bearssl/src/symcipher/aes_small_enc.c +129 -0
  468. package/runtime/third_party/bearssl/src/symcipher/aes_x86ni.c +240 -0
  469. package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_cbcdec.c +223 -0
  470. package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_cbcenc.c +122 -0
  471. package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_ctr.c +211 -0
  472. package/runtime/third_party/bearssl/src/symcipher/aes_x86ni_ctrcbc.c +596 -0
  473. package/runtime/third_party/bearssl/src/symcipher/chacha20_ct.c +106 -0
  474. package/runtime/third_party/bearssl/src/symcipher/chacha20_sse2.c +237 -0
  475. package/runtime/third_party/bearssl/src/symcipher/des_ct.c +411 -0
  476. package/runtime/third_party/bearssl/src/symcipher/des_ct_cbcdec.c +87 -0
  477. package/runtime/third_party/bearssl/src/symcipher/des_ct_cbcenc.c +69 -0
  478. package/runtime/third_party/bearssl/src/symcipher/des_support.c +166 -0
  479. package/runtime/third_party/bearssl/src/symcipher/des_tab.c +310 -0
  480. package/runtime/third_party/bearssl/src/symcipher/des_tab_cbcdec.c +85 -0
  481. package/runtime/third_party/bearssl/src/symcipher/des_tab_cbcenc.c +67 -0
  482. package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmul.c +260 -0
  483. package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmul32.c +297 -0
  484. package/runtime/third_party/bearssl/src/symcipher/poly1305_ctmulq.c +475 -0
  485. package/runtime/third_party/bearssl/src/symcipher/poly1305_i15.c +221 -0
  486. package/runtime/third_party/bearssl/src/x509/asn1.t0 +757 -0
  487. package/runtime/third_party/bearssl/src/x509/asn1enc.c +93 -0
  488. package/runtime/third_party/bearssl/src/x509/encode_ec_pk8der.c +110 -0
  489. package/runtime/third_party/bearssl/src/x509/encode_ec_rawder.c +161 -0
  490. package/runtime/third_party/bearssl/src/x509/encode_rsa_pk8der.c +97 -0
  491. package/runtime/third_party/bearssl/src/x509/encode_rsa_rawder.c +96 -0
  492. package/runtime/third_party/bearssl/src/x509/skey_decoder.c +653 -0
  493. package/runtime/third_party/bearssl/src/x509/skey_decoder.t0 +376 -0
  494. package/runtime/third_party/bearssl/src/x509/x509_decoder.c +776 -0
  495. package/runtime/third_party/bearssl/src/x509/x509_decoder.t0 +324 -0
  496. package/runtime/third_party/bearssl/src/x509/x509_knownkey.c +105 -0
  497. package/runtime/third_party/bearssl/src/x509/x509_minimal.c +1722 -0
  498. package/runtime/third_party/bearssl/src/x509/x509_minimal.t0 +1526 -0
  499. package/runtime/third_party/bearssl/src/x509/x509_minimal_full.c +59 -0
  500. package/runtime/third_party/quickjs-dtoa/LICENSE +22 -0
  501. package/runtime/third_party/quickjs-dtoa/README.md +23 -0
  502. package/runtime/third_party/quickjs-dtoa/dtoa.c +1640 -0
  503. package/runtime/third_party/quickjs-dtoa/dtoa.h +83 -0
  504. package/runtime/third_party/quickjs-dtoa/dtoa_compat.h +89 -0
  505. package/runtime/third_party/quickjs-regexp/LICENSE +22 -0
  506. package/runtime/third_party/quickjs-regexp/README.md +22 -0
  507. package/runtime/third_party/quickjs-regexp/cutils.c +641 -0
  508. package/runtime/third_party/quickjs-regexp/cutils.h +457 -0
  509. package/runtime/third_party/quickjs-regexp/libregexp-opcode.h +73 -0
  510. package/runtime/third_party/quickjs-regexp/libregexp.c +3448 -0
  511. package/runtime/third_party/quickjs-regexp/libregexp.h +65 -0
  512. package/runtime/third_party/quickjs-regexp/libunicode-table.h +5206 -0
  513. package/runtime/third_party/quickjs-regexp/libunicode.c +2124 -0
  514. package/runtime/third_party/quickjs-regexp/libunicode.h +196 -0
  515. package/runtime/third_party/v8-ieee754/LICENSE +61 -0
  516. package/runtime/third_party/v8-ieee754/README.md +22 -0
  517. package/runtime/third_party/v8-ieee754/convert.py +84 -0
  518. package/runtime/third_party/v8-ieee754/ieee754.c +3030 -0
  519. package/runtime/third_party/v8-ieee754/ieee754.h +27 -0
  520. package/runtime/tools/regexp_compile.c +90 -0
@@ -0,0 +1,1792 @@
1
+ /* util.inspect and util.format (ADR 0012), natively: Node's algorithms
2
+ * (lib/internal/util/inspect.js), so console output matches Node's byte for byte.
3
+ *
4
+ * Every string built here, and every object reached, is also pushed on `keep`, a JS array
5
+ * the conservative stack scan sees (ADR 0002): user code (getters, toString, custom
6
+ * inspectors) can run and collect, and the C lists below are not roots themselves. */
7
+ #include "js_console.h"
8
+
9
+ #include <math.h>
10
+ #include <stdio.h>
11
+ #include <stdlib.h>
12
+ #include <string.h>
13
+
14
+ #include "internal.h"
15
+ #include "js_buffer.h"
16
+ #include "js_builtins.h"
17
+ #include "js_atoms.h"
18
+ #include "js_convert.h"
19
+ #include "js_error.h"
20
+ #include "js_exception.h"
21
+ #include "js_ops.h"
22
+ #include "js_promise.h"
23
+ #include "js_symbol.h"
24
+ #include "jsnum.h"
25
+ #include "jsstring.h"
26
+
27
+ /* ---- A growable UTF-16 buffer --------------------------------------------- */
28
+
29
+ typedef struct {
30
+ uint16_t *units;
31
+ size_t length, cap;
32
+ } Builder;
33
+
34
+ static void reserve(Builder *b, size_t more) {
35
+ if (b->length + more <= b->cap) return;
36
+ size_t cap = b->cap ? b->cap * 2 : 128;
37
+ while (cap < b->length + more) cap *= 2;
38
+ uint16_t *u = realloc(b->units, cap * sizeof *u);
39
+ if (!u) js_fatal("out of memory formatting output");
40
+ b->units = u;
41
+ b->cap = cap;
42
+ }
43
+
44
+ static void put_unit(Builder *b, uint32_t unit) {
45
+ reserve(b, 1);
46
+ b->units[b->length++] = (uint16_t)unit;
47
+ }
48
+
49
+ static void put_ascii(Builder *b, const char *s) {
50
+ size_t n = strlen(s);
51
+ reserve(b, n);
52
+ for (size_t i = 0; i < n; i++) b->units[b->length++] = (uint8_t)s[i];
53
+ }
54
+
55
+ static void put_view(Builder *b, JSStrView v, uint32_t start, uint32_t end) {
56
+ reserve(b, end - start);
57
+ for (uint32_t i = start; i < end; i++) b->units[b->length++] = (uint16_t)js_view_at(v, i);
58
+ }
59
+
60
+ static void put_repeat(Builder *b, uint32_t unit, size_t n) {
61
+ reserve(b, n);
62
+ for (size_t i = 0; i < n; i++) b->units[b->length++] = (uint16_t)unit;
63
+ }
64
+
65
+ /* The code units [start, end) of v. */
66
+ static JSStrView view_slice(JSStrView v, uint32_t start, uint32_t end) {
67
+ JSStrView r = v;
68
+ r.chars = v.latin1 ? (const void *)((const uint8_t *)v.chars + start) : (const void *)((const uint16_t *)v.chars + start);
69
+ r.length = end - start;
70
+ return r;
71
+ }
72
+
73
+ static JSValue finish(JSContext *ctx, Builder *b) {
74
+ if (b->length > JS_STRING_MAX_LENGTH) {
75
+ free(b->units);
76
+ return js_throw_range_error(ctx, "Invalid string length");
77
+ }
78
+ JSValue s = js_new_string_utf16(ctx, b->units, (uint32_t)b->length);
79
+ free(b->units);
80
+ return s;
81
+ }
82
+
83
+ /* ---- The inspection's state ---------------------------------------------- */
84
+
85
+ typedef struct {
86
+ JSValue *v;
87
+ size_t n, cap;
88
+ } List;
89
+
90
+ static void list_push(List *l, JSValue v) {
91
+ if (l->n == l->cap) {
92
+ l->cap = l->cap ? l->cap * 2 : 16;
93
+ JSValue *grown = realloc(l->v, l->cap * sizeof *grown);
94
+ if (!grown) js_fatal("out of memory formatting output");
95
+ l->v = grown;
96
+ }
97
+ l->v[l->n++] = v;
98
+ }
99
+
100
+ static void list_remove(List *l, size_t i) {
101
+ memmove(l->v + i, l->v + i + 1, (l->n - i - 1) * sizeof *l->v);
102
+ l->n--;
103
+ }
104
+
105
+ static void list_free(List *l) {
106
+ free(l->v);
107
+ *l = (List){ 0 };
108
+ }
109
+
110
+ #define COMPACT_TRUE (-1) /* JSInspectOptions.compact */
111
+
112
+ typedef struct {
113
+ JSContext *ctx;
114
+ JSValue keep; /* a JS array: keeps everything below alive */
115
+ List seen; /* the objects being formatted, outermost first */
116
+ List circular; /* objects found inside themselves: their index + 1 is the *n */
117
+ double indentation;
118
+ double current_depth;
119
+ JSInspectOptions o;
120
+ } Insp;
121
+
122
+ const JSInspectOptions js_inspect_defaults = { false, 2, true, 100, 10000, 80, 3, false };
123
+
124
+ static void insp_init(Insp *ip, JSContext *ctx, const JSInspectOptions *o) {
125
+ *ip = (Insp){ ctx, JS_UNDEFINED, { 0 }, { 0 }, 0, 0, *o };
126
+ ip->keep = js_new_array(ctx, 0);
127
+ }
128
+
129
+ static void insp_free(Insp *ip) {
130
+ list_free(&ip->seen);
131
+ list_free(&ip->circular);
132
+ }
133
+
134
+ /* Keeps v alive for the rest of the inspection; returns it (or the exception). */
135
+ static JSValue keep(Insp *ip, JSValue v) {
136
+ if (js_is_exception(v) || !js_is_cell(v) || js_is_exception(ip->keep)) return v;
137
+ if (js_array_push(ip->ctx, js_as_object(ip->keep), v) < 0) return JS_EXCEPTION;
138
+ return v;
139
+ }
140
+
141
+ static JSValue cstr(Insp *ip, const char *s) {
142
+ return keep(ip, js_new_string_cstr(ip->ctx, s));
143
+ }
144
+
145
+ static JSValue done(Insp *ip, Builder *b) {
146
+ return keep(ip, finish(ip->ctx, b));
147
+ }
148
+
149
+ static void put_str(Builder *b, JSContext *ctx, JSValue s) {
150
+ JSStrView v = js_string_view(ctx, s);
151
+ put_view(b, v, 0, v.length);
152
+ }
153
+
154
+ static bool str_contains_unit(JSContext *ctx, JSValue s, uint32_t unit) {
155
+ JSStrView v = js_string_view(ctx, s);
156
+ for (uint32_t i = 0; i < v.length; i++)
157
+ if (js_view_at(v, i) == unit) return true;
158
+ return false;
159
+ }
160
+
161
+ /* The index of `sub` in `s` from `from`, or -1. */
162
+ static int64_t str_index_of(JSContext *ctx, JSValue s, JSValue sub, uint32_t from) {
163
+ JSStrView a = js_string_view(ctx, s), b = js_string_view(ctx, sub);
164
+ if (b.length > a.length) return -1;
165
+ for (uint32_t i = from; i + b.length <= a.length; i++) {
166
+ uint32_t j = 0;
167
+ while (j < b.length && js_view_at(a, i + j) == js_view_at(b, j)) j++;
168
+ if (j == b.length) return i;
169
+ }
170
+ return -1;
171
+ }
172
+
173
+ static bool str_eq_cstr(JSContext *ctx, JSValue s, const char *c) {
174
+ JSStrView v = js_string_view(ctx, s);
175
+ size_t n = strlen(c);
176
+ if (v.length != n) return false;
177
+ for (uint32_t i = 0; i < n; i++)
178
+ if (js_view_at(v, i) != (uint8_t)c[i]) return false;
179
+ return true;
180
+ }
181
+
182
+ /* ---- Primitives -------------------------------------------------------------- */
183
+
184
+ /* formatNumber: -0 prints as "-0". */
185
+ static void put_number(Builder *b, double d) {
186
+ char buf[JS_NUM_BUF_SIZE];
187
+ if (d == 0 && signbit(d)) put_ascii(b, "-0");
188
+ else {
189
+ js_num_to_cstr(buf, d);
190
+ put_ascii(b, buf);
191
+ }
192
+ }
193
+
194
+ static bool view_contains(JSStrView v, uint32_t unit) {
195
+ for (uint32_t i = 0; i < v.length; i++)
196
+ if (js_view_at(v, i) == unit) return true;
197
+ return false;
198
+ }
199
+
200
+ static bool view_contains_dollar_brace(JSStrView v) {
201
+ for (uint32_t i = 0; i + 1 < v.length; i++)
202
+ if (js_view_at(v, i) == '$' && js_view_at(v, i + 1) == '{') return true;
203
+ return false;
204
+ }
205
+
206
+ /* Node's `meta` escapes: code units below 0x20 and 0x7F…0x9F. */
207
+ static void put_meta(Builder *b, uint32_t c) {
208
+ char esc[8];
209
+ switch (c) {
210
+ case '\b': put_ascii(b, "\\b"); return;
211
+ case '\t': put_ascii(b, "\\t"); return;
212
+ case '\n': put_ascii(b, "\\n"); return;
213
+ case '\f': put_ascii(b, "\\f"); return;
214
+ case '\r': put_ascii(b, "\\r"); return;
215
+ default:
216
+ snprintf(esc, sizeof esc, "\\x%02X", c);
217
+ put_ascii(b, esc);
218
+ }
219
+ }
220
+
221
+ /* strEscape: quoted with ', else " if it contains ' but no ", else ` if it has neither ` nor ${. */
222
+ static void put_quoted(Builder *b, JSStrView v) {
223
+ uint32_t quote = '\'';
224
+ if (view_contains(v, '\'')) {
225
+ if (!view_contains(v, '"')) quote = '"';
226
+ else if (!view_contains(v, '`') && !view_contains_dollar_brace(v)) quote = '`';
227
+ }
228
+ put_unit(b, quote);
229
+ for (uint32_t i = 0; i < v.length; i++) {
230
+ uint32_t c = js_view_at(v, i);
231
+ if (c == quote && quote == '\'') {
232
+ put_ascii(b, "\\'");
233
+ } else if (c == '\\') {
234
+ put_ascii(b, "\\\\");
235
+ } else if (c < 0x20 || (c >= 0x7F && c <= 0x9F)) {
236
+ put_meta(b, c);
237
+ } else if (c >= 0xD800 && c <= 0xDFFF) {
238
+ uint32_t d = i + 1 < v.length ? js_view_at(v, i + 1) : 0;
239
+ if (c <= 0xDBFF && d >= 0xDC00 && d <= 0xDFFF) { /* a pair: printed as is */
240
+ put_unit(b, c);
241
+ put_unit(b, d);
242
+ i++;
243
+ } else {
244
+ char esc[8];
245
+ snprintf(esc, sizeof esc, "\\u%x", c); /* lone surrogate, lowercase like Node */
246
+ put_ascii(b, esc);
247
+ }
248
+ } else {
249
+ put_unit(b, c);
250
+ }
251
+ }
252
+ put_unit(b, quote);
253
+ }
254
+
255
+ /* Escapes without quotes: a symbol's description, a non-enumerable key (Node's escapeFn). */
256
+ static void put_escaped(Builder *b, JSStrView v) {
257
+ for (uint32_t i = 0; i < v.length; i++) {
258
+ uint32_t c = js_view_at(v, i);
259
+ if (c == '\'') put_ascii(b, "\\'");
260
+ else if (c == '\\') put_ascii(b, "\\\\");
261
+ else if (c < 0x20 || (c >= 0x7F && c <= 0x9F)) put_meta(b, c);
262
+ else put_unit(b, c);
263
+ }
264
+ }
265
+
266
+ static JSValue format_primitive(Insp *ip, JSValue v) {
267
+ JSContext *ctx = ip->ctx;
268
+ Builder b = { 0 };
269
+ if (js_is_string(v)) {
270
+ JSStrView s = js_string_view(ctx, v);
271
+ uint32_t len = s.length;
272
+ double trailer = 0;
273
+ if (len > ip->o.max_string_length) {
274
+ trailer = len - ip->o.max_string_length;
275
+ len = (uint32_t)ip->o.max_string_length;
276
+ }
277
+ if (ip->o.compact != COMPACT_TRUE && len > 16 && len > ip->o.break_length - ip->indentation - 4) {
278
+ /* long strings: one quoted piece per line, each keeping its \n */
279
+ uint32_t start = 0;
280
+ bool first = true;
281
+ for (uint32_t i = 0; i < len; i++) {
282
+ if (js_view_at(s, i) != '\n') continue;
283
+ if (!first) {
284
+ put_ascii(&b, " +\n");
285
+ put_repeat(&b, ' ', (size_t)ip->indentation + 2);
286
+ }
287
+ put_quoted(&b, view_slice(s, start, i + 1));
288
+ first = false;
289
+ start = i + 1;
290
+ }
291
+ if (start < len || first) {
292
+ if (!first) {
293
+ put_ascii(&b, " +\n");
294
+ put_repeat(&b, ' ', (size_t)ip->indentation + 2);
295
+ }
296
+ put_quoted(&b, view_slice(s, start, len));
297
+ }
298
+ } else {
299
+ put_quoted(&b, view_slice(s, 0, len));
300
+ }
301
+ if (trailer > 0) {
302
+ char t[64];
303
+ snprintf(t, sizeof t, "... %.0f more character%s", trailer, trailer > 1 ? "s" : "");
304
+ put_ascii(&b, t);
305
+ }
306
+ } else if (js_is_number(v)) {
307
+ put_number(&b, js_as_number(v));
308
+ } else if (js_is_bool(v)) {
309
+ put_ascii(&b, js_as_bool(v) ? "true" : "false");
310
+ } else if (js_is_undefined(v)) {
311
+ put_ascii(&b, "undefined");
312
+ } else if (js_is_null(v)) {
313
+ put_ascii(&b, "null");
314
+ } else if (js_is_bigint(v)) { /* 12n */
315
+ JSValue s = js_to_string(ctx, v);
316
+ if (js_is_exception(s)) {
317
+ free(b.units);
318
+ return s;
319
+ }
320
+ put_str(&b, ctx, s);
321
+ put_ascii(&b, "n");
322
+ } else if (js_is_symbol(v)) {
323
+ JSValue s = js_symbol_descriptive_string(ctx, v);
324
+ if (js_is_exception(s)) {
325
+ free(b.units);
326
+ return s;
327
+ }
328
+ put_str(&b, ctx, s);
329
+ }
330
+ return done(ip, &b);
331
+ }
332
+
333
+ /* ---- Objects ---------------------------------------------------------------------- */
334
+
335
+ enum { OBJECT_TYPE, ARRAY_TYPE, ARRAY_EXTRAS_TYPE };
336
+
337
+ static JSValue format_value(Insp *ip, JSValue value, double recurse);
338
+ static JSValue inspect_value(JSContext *ctx, JSValue v, const JSInspectOptions *o);
339
+
340
+ static bool is_object_like(JSValue v) {
341
+ return js_is_object(v); /* functions are objects too */
342
+ }
343
+
344
+ /* (own property, found) → 1, absent → 0, an exception → -1 */
345
+ static int own(JSContext *ctx, JSValue o, JSValue key, JSPropertyDescriptor *d) {
346
+ return js_get_own_property(ctx, js_as_object(o), key, d);
347
+ }
348
+
349
+ static bool own_enumerable(JSContext *ctx, JSValue o, JSValue key) {
350
+ JSPropertyDescriptor d;
351
+ int has = own(ctx, o, key, &d);
352
+ if (has < 0) {
353
+ js_discard(js_take_exception(ctx));
354
+ return false;
355
+ }
356
+ return has && (d.attrs & JS_PROP_ENUMERABLE);
357
+ }
358
+
359
+ static bool has_own(JSContext *ctx, JSValue o, JSValue key) {
360
+ JSPropertyDescriptor d;
361
+ int has = own(ctx, o, key, &d);
362
+ if (has < 0) {
363
+ js_discard(js_take_exception(ctx));
364
+ return false;
365
+ }
366
+ return has;
367
+ }
368
+
369
+ static JSValue get(Insp *ip, JSValue o, JSValue key) {
370
+ return keep(ip, js_get_value(ip->ctx, o, key));
371
+ }
372
+
373
+ /* A property key as the string Node's key lists hold (indices are numbers here). */
374
+ static JSValue key_string(Insp *ip, JSValue key) {
375
+ if (js_is_number(key)) return keep(ip, js_number_to_string(ip->ctx, key));
376
+ return key;
377
+ }
378
+
379
+ static JSValue concat3(Insp *ip, const char *a, JSValue s, const char *c) {
380
+ Builder b = { 0 };
381
+ put_ascii(&b, a);
382
+ put_str(&b, ip->ctx, s);
383
+ put_ascii(&b, c);
384
+ return done(ip, &b);
385
+ }
386
+
387
+ /* The name of the nearest constructor on the prototype chain whose `prototype` the value
388
+ * inherits from; null for a null-prototype chain. */
389
+ static JSValue get_constructor_name(Insp *ip, JSValue obj, double recurse) {
390
+ JSContext *ctx = ip->ctx;
391
+ JSValue tmp = obj, first_proto = JS_UNDEFINED;
392
+ bool have_first = false;
393
+ while (js_is_object(obj)) {
394
+ JSPropertyDescriptor d;
395
+ int has = own(ctx, obj, JS_ATOM(constructor), &d);
396
+ if (has < 0) return JS_EXCEPTION;
397
+ if (has && (d.has & JS_DESC_VALUE) && js_is_function(d.value)) {
398
+ JSValue name = get(ip, d.value, JS_ATOM(name));
399
+ if (js_is_exception(name)) return name;
400
+ if (!(js_is_string(name) && js_string_length(name) == 0)) {
401
+ JSValue r = js_instanceof(ctx, tmp, d.value);
402
+ if (js_is_exception(r)) js_discard(js_take_exception(ctx));
403
+ else if (js_truthy(r)) return keep(ip, js_to_string(ctx, name));
404
+ }
405
+ }
406
+ obj = js_get_prototype_of(js_as_object(obj));
407
+ if (!have_first) {
408
+ first_proto = obj;
409
+ have_first = true;
410
+ }
411
+ }
412
+ if (js_is_null(first_proto)) return JS_NULL;
413
+ JSValue res = cstr(ip, js_as_object(tmp)->shape->cls->name);
414
+ if (js_is_exception(res)) return res;
415
+ if (recurse > ip->o.depth) return concat3(ip, "", res, " <Complex prototype>");
416
+ JSValue proto_constr = get_constructor_name(ip, first_proto, recurse + 1);
417
+ if (js_is_exception(proto_constr)) return proto_constr;
418
+ Builder b = { 0 };
419
+ put_str(&b, ctx, res);
420
+ put_ascii(&b, " <");
421
+ if (js_is_null(proto_constr)) {
422
+ JSInspectOptions o = ip->o;
423
+ o.depth = -1;
424
+ o.custom_inspect = false;
425
+ JSValue s = keep(ip, inspect_value(ctx, first_proto, &o));
426
+ if (js_is_exception(s)) {
427
+ free(b.units);
428
+ return s;
429
+ }
430
+ put_str(&b, ctx, s);
431
+ } else {
432
+ put_str(&b, ctx, proto_constr);
433
+ }
434
+ put_ascii(&b, ">");
435
+ return done(ip, &b);
436
+ }
437
+
438
+ /* getPrefix: "Foo ", "Foo [Tag] ", "[Object: null prototype] " */
439
+ static void put_prefix(Builder *b, JSContext *ctx, JSValue constructor, JSValue tag, const char *fallback, const char *size) {
440
+ bool has_tag = js_string_length(tag) != 0;
441
+ if (js_is_null(constructor)) {
442
+ put_ascii(b, "[");
443
+ put_ascii(b, fallback);
444
+ put_ascii(b, size);
445
+ put_ascii(b, ": null prototype] ");
446
+ if (has_tag && !str_eq_cstr(ctx, tag, fallback)) {
447
+ b->length--;
448
+ put_ascii(b, " [");
449
+ put_str(b, ctx, tag);
450
+ put_ascii(b, "] ");
451
+ }
452
+ return;
453
+ }
454
+ put_str(b, ctx, constructor);
455
+ put_ascii(b, size);
456
+ if (has_tag && !js_string_equals(ctx, constructor, tag)) {
457
+ put_ascii(b, " [");
458
+ put_str(b, ctx, tag);
459
+ put_ascii(b, "]");
460
+ }
461
+ put_ascii(b, " ");
462
+ }
463
+
464
+ static JSValue prefix_string(Insp *ip, JSValue constructor, JSValue tag, const char *fallback, const char *size, const char *suffix) {
465
+ Builder b = { 0 };
466
+ put_prefix(&b, ip->ctx, constructor, tag, fallback, size);
467
+ put_ascii(&b, suffix);
468
+ return done(ip, &b);
469
+ }
470
+
471
+ /* The keys to show: own enumerable ones (all with showHidden), strings then symbols; for
472
+ * arrays without the indices. */
473
+ static int get_keys(Insp *ip, JSValue value, bool non_index, List *keys) {
474
+ JSContext *ctx = ip->ctx;
475
+ JSValue all = keep(ip, js_own_keys(ctx, js_as_object(value)));
476
+ if (js_is_exception(all)) return -1;
477
+ JSValueArray *list = (JSValueArray *)js_as_cell(all);
478
+ for (uint32_t i = 0; i < list->cell.aux; i++) {
479
+ JSValue key = list->values[i];
480
+ if (non_index && js_is_number(key)) continue;
481
+ if (ip->o.show_hidden || own_enumerable(ctx, value, key)) list_push(keys, key);
482
+ }
483
+ return 0;
484
+ }
485
+
486
+ static bool is_identifier_key(JSContext *ctx, JSValue key) {
487
+ JSStrView v = js_string_view(ctx, key);
488
+ if (v.length == 0) return false;
489
+ for (uint32_t i = 0; i < v.length; i++) {
490
+ uint32_t c = js_view_at(v, i);
491
+ bool letter = (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || c == '_';
492
+ if (!letter && !(i > 0 && c >= '0' && c <= '9')) return false;
493
+ }
494
+ return true;
495
+ }
496
+
497
+ static JSValue format_property(Insp *ip, JSValue value, double recurse, JSValue key, int type) {
498
+ JSContext *ctx = ip->ctx;
499
+ JSPropertyDescriptor d;
500
+ int has = own(ctx, value, key, &d);
501
+ if (has < 0) return JS_EXCEPTION;
502
+ bool enumerable = true;
503
+ if (!has) {
504
+ d.has = JS_DESC_VALUE;
505
+ d.value = get(ip, value, key);
506
+ if (js_is_exception(d.value)) return d.value;
507
+ } else {
508
+ enumerable = (d.attrs & JS_PROP_ENUMERABLE) != 0;
509
+ keep(ip, d.value);
510
+ }
511
+ Builder b = { 0 };
512
+ JSValue str;
513
+ if ((d.has & JS_DESC_VALUE) && !js_is_undefined(d.value)) {
514
+ int diff = ip->o.compact != COMPACT_TRUE || type != OBJECT_TYPE ? 2 : 3;
515
+ ip->indentation += diff;
516
+ str = format_value(ip, d.value, recurse);
517
+ ip->indentation -= diff;
518
+ if (js_is_exception(str)) return str;
519
+ } else if ((d.has & JS_DESC_GET) && !js_is_undefined(d.get)) {
520
+ str = cstr(ip, (d.has & JS_DESC_SET) && !js_is_undefined(d.set) ? "[Getter/Setter]" : "[Getter]");
521
+ } else if ((d.has & JS_DESC_SET) && !js_is_undefined(d.set)) {
522
+ str = cstr(ip, "[Setter]");
523
+ } else {
524
+ str = cstr(ip, "undefined");
525
+ }
526
+ if (js_is_exception(str)) return str;
527
+ if (type == ARRAY_TYPE) return str;
528
+ if (js_is_symbol(key)) {
529
+ JSValue s = js_symbol_descriptive_string(ctx, key);
530
+ if (js_is_exception(s)) return s;
531
+ put_ascii(&b, "[");
532
+ put_escaped(&b, js_string_view(ctx, s));
533
+ put_ascii(&b, "]");
534
+ } else {
535
+ JSValue k = key_string(ip, key);
536
+ if (js_is_exception(k)) return k;
537
+ if (str_eq_cstr(ctx, k, "__proto__")) put_ascii(&b, "['__proto__']");
538
+ else if (!enumerable) {
539
+ put_ascii(&b, "[");
540
+ put_escaped(&b, js_string_view(ctx, k));
541
+ put_ascii(&b, "]");
542
+ } else if (is_identifier_key(ctx, k)) put_str(&b, ctx, k);
543
+ else put_quoted(&b, js_string_view(ctx, k));
544
+ }
545
+ put_ascii(&b, ": ");
546
+ put_str(&b, ctx, str);
547
+ return done(ip, &b);
548
+ }
549
+
550
+ static JSValue remaining_text(Insp *ip, double remaining) {
551
+ char t[64];
552
+ snprintf(t, sizeof t, "... %.0f more item%s", remaining, remaining > 1 ? "s" : "");
553
+ return cstr(ip, t);
554
+ }
555
+
556
+ static JSValue empty_items(Insp *ip, double n) {
557
+ char t[64];
558
+ snprintf(t, sizeof t, "<%.0f empty item%s>", n, n > 1 ? "s" : "");
559
+ return cstr(ip, t);
560
+ }
561
+
562
+ static int push_result(List *out, JSValue s) {
563
+ if (js_is_exception(s)) return -1;
564
+ list_push(out, s);
565
+ return 0;
566
+ }
567
+
568
+ /* An array with holes: runs of them become "<n empty items>" (formatSpecialArray). */
569
+ static int format_special_array(Insp *ip, JSValue value, double recurse, double max_length, List *out, uint32_t i) {
570
+ JSContext *ctx = ip->ctx;
571
+ List keys = { 0 };
572
+ bool saved = ip->o.show_hidden;
573
+ ip->o.show_hidden = false;
574
+ int rc = get_keys(ip, value, false, &keys); /* Object.keys */
575
+ ip->o.show_hidden = saved;
576
+ if (rc < 0) {
577
+ list_free(&keys);
578
+ return -1;
579
+ }
580
+ double index = i;
581
+ for (; i < keys.n && out->n < max_length; i++) {
582
+ JSValue key = keys.v[i];
583
+ if (!js_is_number(key)) break; /* only index keys */
584
+ double tmp = js_as_number(key);
585
+ if (tmp != index) {
586
+ if (push_result(out, empty_items(ip, tmp - index)) < 0) goto fail;
587
+ index = tmp;
588
+ if (out->n == max_length) break;
589
+ }
590
+ if (push_result(out, format_property(ip, value, recurse, key, ARRAY_TYPE)) < 0) goto fail;
591
+ index++;
592
+ }
593
+ list_free(&keys);
594
+ {
595
+ double remaining = js_array_length(js_as_object(value)) - index;
596
+ if (out->n != max_length) {
597
+ if (remaining > 0 && push_result(out, empty_items(ip, remaining)) < 0) return -1;
598
+ } else if (remaining > 0) {
599
+ if (push_result(out, remaining_text(ip, remaining)) < 0) return -1;
600
+ }
601
+ }
602
+ (void)ctx;
603
+ return 0;
604
+ fail:
605
+ list_free(&keys);
606
+ return -1;
607
+ }
608
+
609
+ static int format_array(Insp *ip, JSValue value, double recurse, List *out) {
610
+ double length = js_array_length(js_as_object(value));
611
+ double len = ip->o.max_array_length < 0 ? 0 : ip->o.max_array_length;
612
+ if (len > length) len = length;
613
+ double remaining = length - len;
614
+ for (uint32_t i = 0; i < len; i++) {
615
+ if (!has_own(ip->ctx, value, js_index_key(i))) return format_special_array(ip, value, recurse, len, out, i);
616
+ if (push_result(out, format_property(ip, value, recurse, js_index_key(i), ARRAY_TYPE)) < 0) return -1;
617
+ }
618
+ if (remaining > 0 && push_result(out, remaining_text(ip, remaining)) < 0) return -1;
619
+ return 0;
620
+ }
621
+
622
+ /* ---- Functions, errors, promises -------------------------------------------------------- */
623
+
624
+ /* getBoxedBase: "[Number: 5]", "[String (Foo): 'ab']"; a String wrapper's index keys are left out. */
625
+ static JSValue boxed_base(Insp *ip, JSValue value, JSValue constructor, JSValue tag, List *keys) {
626
+ JSContext *ctx = ip->ctx;
627
+ JSValue prim = js_wrapped_value(value);
628
+ const char *type = js_is_number(prim) ? "Number" : js_is_string(prim) ? "String" : js_is_bool(prim) ? "Boolean"
629
+ : js_is_bigint(prim) ? "BigInt" : "Symbol";
630
+ if (js_is_string(prim)) {
631
+ size_t n = js_string_length(prim);
632
+ if (n > keys->n) n = keys->n;
633
+ memmove(keys->v, keys->v + n, (keys->n - n) * sizeof *keys->v);
634
+ keys->n -= n;
635
+ }
636
+ JSValue text = format_primitive(ip, prim);
637
+ if (js_is_exception(text)) return text;
638
+ Builder b = { 0 };
639
+ put_ascii(&b, "[");
640
+ put_ascii(&b, type);
641
+ if (js_is_null(constructor)) {
642
+ put_ascii(&b, " (null prototype)");
643
+ } else if (!str_eq_cstr(ctx, constructor, type)) {
644
+ put_ascii(&b, " (");
645
+ put_str(&b, ctx, constructor);
646
+ put_ascii(&b, ")");
647
+ }
648
+ put_ascii(&b, ": ");
649
+ put_str(&b, ctx, text);
650
+ put_ascii(&b, "]");
651
+ if (js_string_length(tag) != 0 && (js_is_null(constructor) || !js_string_equals(ctx, constructor, tag))) {
652
+ put_ascii(&b, " [");
653
+ put_str(&b, ctx, tag);
654
+ put_ascii(&b, "]");
655
+ }
656
+ return done(ip, &b);
657
+ }
658
+
659
+ static JSValue function_base(Insp *ip, JSValue value, JSValue constructor, JSValue tag) {
660
+ JSContext *ctx = ip->ctx;
661
+ uint32_t flags = js_as_function(value)->flags;
662
+ Builder b = { 0 };
663
+ bool has_tag = js_string_length(tag) != 0;
664
+ if (flags & JS_FN_CLASS_CTOR) {
665
+ JSValue name = JS_UNDEFINED;
666
+ if (has_own(ctx, value, JS_ATOM(name))) {
667
+ name = get(ip, value, JS_ATOM(name));
668
+ if (js_is_exception(name)) return name;
669
+ }
670
+ put_ascii(&b, "[class ");
671
+ if (js_truthy(name)) {
672
+ JSValue s = keep(ip, js_to_string(ctx, name));
673
+ if (js_is_exception(s)) goto fail;
674
+ put_str(&b, ctx, s);
675
+ } else {
676
+ put_ascii(&b, "(anonymous)");
677
+ }
678
+ if (!js_is_null(constructor) && !str_eq_cstr(ctx, constructor, "Function")) {
679
+ put_ascii(&b, " [");
680
+ put_str(&b, ctx, constructor);
681
+ put_ascii(&b, "]");
682
+ }
683
+ if (has_tag && (js_is_null(constructor) || !js_string_equals(ctx, constructor, tag))) {
684
+ put_ascii(&b, " [");
685
+ put_str(&b, ctx, tag);
686
+ put_ascii(&b, "]");
687
+ }
688
+ if (!js_is_null(constructor)) {
689
+ JSValue proto = js_get_prototype_of(js_as_object(value));
690
+ if (js_is_object(proto)) {
691
+ JSValue super_name = get(ip, proto, JS_ATOM(name));
692
+ if (js_is_exception(super_name)) goto fail;
693
+ if (js_truthy(super_name)) {
694
+ JSValue s = keep(ip, js_to_string(ctx, super_name));
695
+ if (js_is_exception(s)) goto fail;
696
+ put_ascii(&b, " extends ");
697
+ put_str(&b, ctx, s);
698
+ }
699
+ }
700
+ } else {
701
+ put_ascii(&b, " extends [null prototype]");
702
+ }
703
+ put_ascii(&b, "]");
704
+ return done(ip, &b);
705
+ }
706
+ const char *type = (flags & JS_FN_ASYNC) && (flags & JS_FN_GENERATOR) ? "AsyncGeneratorFunction"
707
+ : flags & JS_FN_ASYNC ? "AsyncFunction"
708
+ : flags & JS_FN_GENERATOR ? "GeneratorFunction" : "Function";
709
+ /* visaljs has no %AsyncFunction% or %GeneratorFunction% constructors yet: such functions
710
+ * find Function, which Node would never print after their own type */
711
+ if (!js_is_null(constructor) && strcmp(type, "Function") != 0 && str_eq_cstr(ctx, constructor, "Function")) {
712
+ constructor = cstr(ip, type);
713
+ if (js_is_exception(constructor)) goto fail;
714
+ }
715
+ bool constructor_is_type = !js_is_null(constructor) && str_eq_cstr(ctx, constructor, type);
716
+ put_ascii(&b, "[");
717
+ put_ascii(&b, type);
718
+ if (js_is_null(constructor)) put_ascii(&b, " (null prototype)");
719
+ JSValue name = get(ip, value, JS_ATOM(name));
720
+ if (js_is_exception(name)) goto fail;
721
+ if (js_is_string(name) && js_string_length(name) == 0) {
722
+ put_ascii(&b, " (anonymous)");
723
+ } else {
724
+ JSValue s = keep(ip, js_to_string(ctx, name));
725
+ if (js_is_exception(s)) goto fail;
726
+ put_ascii(&b, ": ");
727
+ put_str(&b, ctx, s);
728
+ }
729
+ put_ascii(&b, "]");
730
+ if (!constructor_is_type && !js_is_null(constructor)) {
731
+ put_ascii(&b, " ");
732
+ put_str(&b, ctx, constructor);
733
+ }
734
+ if (has_tag && (js_is_null(constructor) || !js_string_equals(ctx, constructor, tag))) {
735
+ put_ascii(&b, " [");
736
+ put_str(&b, ctx, tag);
737
+ put_ascii(&b, "]");
738
+ }
739
+ return done(ip, &b);
740
+ fail:
741
+ free(b.units);
742
+ return JS_EXCEPTION;
743
+ }
744
+
745
+ static bool starts_with_value(JSContext *ctx, JSValue s, JSValue prefix) {
746
+ return js_string_length(prefix) <= js_string_length(s) && str_index_of(ctx, s, prefix, 0) == 0;
747
+ }
748
+
749
+ static bool ends_with_cstr(JSContext *ctx, JSValue s, const char *suffix) {
750
+ JSStrView v = js_string_view(ctx, s);
751
+ size_t n = strlen(suffix);
752
+ if (n > v.length) return false;
753
+ for (size_t i = 0; i < n; i++)
754
+ if (js_view_at(v, (uint32_t)(v.length - n + i)) != (uint8_t)suffix[i]) return false;
755
+ return true;
756
+ }
757
+
758
+ /* improveStack: "MyErr [Error]: m" when the constructor isn't the name. */
759
+ static JSValue improve_stack(Insp *ip, JSValue stack, JSValue constructor, JSValue name, JSValue tag) {
760
+ JSContext *ctx = ip->ctx;
761
+ uint32_t len = js_string_length(name);
762
+ JSStrView sv = js_string_view(ctx, stack);
763
+ if (js_is_null(constructor) ||
764
+ (ends_with_cstr(ctx, name, "Error") && starts_with_value(ctx, stack, name) &&
765
+ (sv.length == len || js_view_at(sv, len) == ':' || js_view_at(sv, len) == '\n'))) {
766
+ Builder pb = { 0 };
767
+ put_prefix(&pb, ctx, constructor, tag, "Error", "");
768
+ pb.length--; /* without the trailing space */
769
+ JSValue prefix = done(ip, &pb);
770
+ if (js_is_exception(prefix)) return prefix;
771
+ if (!js_string_equals(ctx, name, prefix)) {
772
+ Builder b = { 0 };
773
+ if (str_index_of(ctx, prefix, name, 0) != -1) {
774
+ put_str(&b, ctx, prefix);
775
+ if (len == 0) {
776
+ put_ascii(&b, ": ");
777
+ put_str(&b, ctx, stack);
778
+ } else {
779
+ put_view(&b, sv, len, sv.length);
780
+ }
781
+ } else {
782
+ put_str(&b, ctx, prefix);
783
+ put_ascii(&b, " [");
784
+ put_str(&b, ctx, name);
785
+ put_ascii(&b, "]");
786
+ put_view(&b, sv, len, sv.length);
787
+ }
788
+ return done(ip, &b);
789
+ }
790
+ }
791
+ return stack;
792
+ }
793
+
794
+ static JSValue replace_newlines(Insp *ip, JSValue s, double indentation) {
795
+ if (!str_contains_unit(ip->ctx, s, '\n')) return s;
796
+ JSStrView v = js_string_view(ip->ctx, s);
797
+ Builder b = { 0 };
798
+ for (uint32_t i = 0; i < v.length; i++) {
799
+ uint32_t c = js_view_at(v, i);
800
+ put_unit(&b, c);
801
+ if (c == '\n') put_repeat(&b, ' ', (size_t)indentation);
802
+ }
803
+ return done(ip, &b);
804
+ }
805
+
806
+ static int64_t list_index_of_key(List *keys, JSValue key) {
807
+ for (size_t i = 0; i < keys->n; i++)
808
+ if (js_same_bits(keys->v[i], key)) return (int64_t)i;
809
+ return -1;
810
+ }
811
+
812
+ /* Node's isError also takes `value instanceof Error` (a DOMException, Object.create(Error.prototype)):
813
+ * %Error.prototype% on the prototype chain, read without running proxy traps. */
814
+ static bool inherits_error(JSContext *ctx, JSValue value) {
815
+ JSValue error_proto = ctx->intrinsics[JS_INTRINSIC_ERROR_PROTOTYPE];
816
+ for (JSValue p = js_as_object(value)->shape->proto; js_is_object(p); p = js_as_object(p)->shape->proto)
817
+ if (js_same_bits(p, error_proto)) return true;
818
+ return false;
819
+ }
820
+
821
+ static JSValue format_error(Insp *ip, JSValue err, JSValue constructor, JSValue tag, List *keys) {
822
+ JSContext *ctx = ip->ctx;
823
+ JSValue name_v = get(ip, err, JS_ATOM(name));
824
+ if (js_is_exception(name_v)) return name_v;
825
+ JSValue name = js_is_nullish(name_v) ? cstr(ip, "Error") : keep(ip, js_to_string(ctx, name_v));
826
+ if (js_is_exception(name)) return name;
827
+ JSValue stack_v = get(ip, err, JS_ATOM(stack));
828
+ if (js_is_exception(stack_v)) return stack_v;
829
+ JSValue stack = keep(ip, js_truthy(stack_v) ? js_to_string(ctx, stack_v) : js_error_to_string(ctx, err));
830
+ if (js_is_exception(stack)) return stack;
831
+ if (!ip->o.show_hidden && keys->n) {
832
+ const JSValue names[] = { JS_ATOM(name), JS_ATOM(message), JS_ATOM(stack) };
833
+ for (size_t k = 0; k < 3; k++) {
834
+ int64_t index = list_index_of_key(keys, names[k]);
835
+ if (index == -1) continue;
836
+ JSValue v = get(ip, err, names[k]);
837
+ if (js_is_exception(v)) return v;
838
+ /* only hidden when the stack already shows it */
839
+ if (!js_is_string(v) || str_index_of(ctx, stack, v, 0) != -1) list_remove(keys, (size_t)index);
840
+ }
841
+ }
842
+ int has_cause = js_has_property(ctx, js_as_object(err), JS_ATOM(cause));
843
+ if (has_cause < 0) return JS_EXCEPTION;
844
+ if (has_cause && list_index_of_key(keys, JS_ATOM(cause)) == -1) list_push(keys, JS_ATOM(cause));
845
+ JSValue errors_key = keep(ip, js_atom_from_cstr(ctx, "errors"));
846
+ JSValue errors = get(ip, err, errors_key);
847
+ if (js_is_exception(errors)) return errors;
848
+ if (js_is_array(errors) && list_index_of_key(keys, errors_key) == -1) list_push(keys, errors_key);
849
+ stack = improve_stack(ip, stack, constructor, name, tag);
850
+ if (js_is_exception(stack)) return stack;
851
+
852
+ JSValue message = get(ip, err, JS_ATOM(message));
853
+ if (js_is_exception(message)) return message;
854
+ int64_t pos = -1;
855
+ if (js_truthy(message)) {
856
+ JSValue m = keep(ip, js_to_string(ctx, message));
857
+ if (js_is_exception(m)) return m;
858
+ pos = str_index_of(ctx, stack, m, 0);
859
+ if (pos == 0) pos = -1; /* Node: `(err.message && stack.indexOf(err.message)) || -1` */
860
+ if (pos != -1) pos += js_string_length(m);
861
+ }
862
+ /* no stack trace (visaljs records none: plan/unsupported.md): the error in brackets */
863
+ JSValue at = cstr(ip, "\n at");
864
+ if (js_is_exception(at)) return at;
865
+ if (str_index_of(ctx, stack, at, pos < 0 ? 0 : (uint32_t)pos) == -1) stack = concat3(ip, "[", stack, "]");
866
+ if (js_is_exception(stack)) return stack;
867
+ if (ip->indentation != 0) stack = replace_newlines(ip, stack, ip->indentation);
868
+ return stack;
869
+ }
870
+
871
+ /* ---- Laying out ------------------------------------------------------------------------- */
872
+
873
+ static bool is_below_break_length(Insp *ip, List *output, double start, JSValue base) {
874
+ double total = output->n + start;
875
+ if (total + output->n > ip->o.break_length) return false;
876
+ for (size_t i = 0; i < output->n; i++) {
877
+ total += js_string_length(output->v[i]);
878
+ if (total > ip->o.break_length) return false;
879
+ }
880
+ return js_string_length(base) == 0 || !str_contains_unit(ip->ctx, base, '\n');
881
+ }
882
+
883
+ static void put_joined(Builder *b, JSContext *ctx, List *output, const char *sep, double indentation) {
884
+ for (size_t i = 0; i < output->n; i++) {
885
+ if (i) {
886
+ put_ascii(b, sep);
887
+ if (indentation >= 0) put_repeat(b, ' ', (size_t)indentation + 2);
888
+ }
889
+ put_str(b, ctx, output->v[i]);
890
+ }
891
+ }
892
+
893
+ /* Arrays of more than six short entries are laid out in columns (groupArrayElements). */
894
+ static int group_array_elements(Insp *ip, List *output, JSValue value) {
895
+ JSContext *ctx = ip->ctx;
896
+ double total_length = 0, max_length = 0;
897
+ size_t output_length = output->n;
898
+ if (ip->o.max_array_length < output->n) output_length--; /* "... n more items" isn't laid out */
899
+ const double separator_space = 2;
900
+ double *data_len = malloc((output_length ? output_length : 1) * sizeof *data_len);
901
+ if (!data_len) js_fatal("out of memory formatting output");
902
+ for (size_t i = 0; i < output_length; i++) {
903
+ double len = js_string_length(output->v[i]);
904
+ data_len[i] = len;
905
+ total_length += len + separator_space;
906
+ if (max_length < len) max_length = len;
907
+ }
908
+ double actual_max = max_length + separator_space;
909
+ if (actual_max * 3 + ip->indentation < ip->o.break_length &&
910
+ (total_length / actual_max > 5 || max_length <= 6)) {
911
+ const double approx_char_heights = 2.5;
912
+ double average_bias = sqrt(actual_max - total_length / output->n);
913
+ double biased_max = fmax(actual_max - 3 - average_bias, 1);
914
+ double columns = fmin(fmin(floor(sqrt(approx_char_heights * biased_max * output_length) / biased_max + 0.5),
915
+ floor((ip->o.break_length - ip->indentation) / actual_max)),
916
+ fmin(ip->o.compact * 4.0, 15));
917
+ if (columns <= 1) {
918
+ free(data_len);
919
+ return 0;
920
+ }
921
+ size_t cols = (size_t)columns;
922
+ double *max_line_length = malloc(cols * sizeof *max_line_length);
923
+ if (!max_line_length) js_fatal("out of memory formatting output");
924
+ for (size_t c = 0; c < cols; c++) {
925
+ double line_length = 0;
926
+ for (size_t j = c; j < output_length; j += cols)
927
+ if (data_len[j] > line_length) line_length = data_len[j];
928
+ max_line_length[c] = line_length + separator_space;
929
+ }
930
+ bool pad_start = true;
931
+ if (!js_is_undefined(value)) {
932
+ for (size_t k = 0; k < output->n; k++) {
933
+ JSValue e = get(ip, value, js_index_key((uint32_t)k));
934
+ if (js_is_exception(e)) {
935
+ free(data_len);
936
+ free(max_line_length);
937
+ return -1;
938
+ }
939
+ if (!js_is_number(e)) {
940
+ pad_start = false;
941
+ break;
942
+ }
943
+ }
944
+ }
945
+ List grouped = { 0 };
946
+ for (size_t k = 0; k < output_length; k += cols) {
947
+ size_t last = k + cols < output_length ? k + cols : output_length;
948
+ Builder b = { 0 };
949
+ size_t j = k;
950
+ for (; j < last - 1; j++) {
951
+ double width = max_line_length[j - k], len = data_len[j] + 2;
952
+ if (pad_start) put_repeat(&b, ' ', width > len ? (size_t)(width - len) : 0);
953
+ put_str(&b, ctx, output->v[j]);
954
+ put_ascii(&b, ", ");
955
+ if (!pad_start) put_repeat(&b, ' ', width > len ? (size_t)(width - len) : 0);
956
+ }
957
+ if (pad_start) {
958
+ double width = max_line_length[j - k] - separator_space;
959
+ put_repeat(&b, ' ', width > data_len[j] ? (size_t)(width - data_len[j]) : 0);
960
+ }
961
+ put_str(&b, ctx, output->v[j]);
962
+ JSValue line = done(ip, &b);
963
+ if (js_is_exception(line)) {
964
+ list_free(&grouped);
965
+ free(data_len);
966
+ free(max_line_length);
967
+ return -1;
968
+ }
969
+ list_push(&grouped, line);
970
+ }
971
+ if (ip->o.max_array_length < output->n) list_push(&grouped, output->v[output_length]);
972
+ list_free(output);
973
+ *output = grouped;
974
+ free(max_line_length);
975
+ }
976
+ free(data_len);
977
+ return 0;
978
+ }
979
+
980
+ static JSValue reduce_to_single_string(Insp *ip, List *output, JSValue base, JSValue brace0, const char *brace1,
981
+ int extras_type, double recurse, JSValue value) {
982
+ JSContext *ctx = ip->ctx;
983
+ Builder b = { 0 };
984
+ bool has_base = js_string_length(base) != 0;
985
+ if (ip->o.compact != COMPACT_TRUE) {
986
+ if (ip->o.compact >= 1) {
987
+ size_t entries = output->n;
988
+ if (extras_type == ARRAY_EXTRAS_TYPE && entries > 6 && group_array_elements(ip, output, value) < 0) return JS_EXCEPTION;
989
+ if (ip->current_depth - recurse < ip->o.compact && entries == output->n) {
990
+ double start = output->n + ip->indentation + js_string_length(brace0) + js_string_length(base) + 10;
991
+ if (is_below_break_length(ip, output, start, base)) {
992
+ Builder j = { 0 };
993
+ put_joined(&j, ctx, output, ", ", -1);
994
+ bool newline = false;
995
+ for (size_t i = 0; i < j.length && !newline; i++) newline = j.units[i] == '\n';
996
+ if (!newline) {
997
+ if (has_base) {
998
+ put_str(&b, ctx, base);
999
+ put_ascii(&b, " ");
1000
+ }
1001
+ put_str(&b, ctx, brace0);
1002
+ put_ascii(&b, " ");
1003
+ reserve(&b, j.length);
1004
+ if (j.length) memcpy(b.units + b.length, j.units, j.length * sizeof *j.units);
1005
+ b.length += j.length;
1006
+ free(j.units);
1007
+ put_ascii(&b, " ");
1008
+ put_ascii(&b, brace1);
1009
+ return done(ip, &b);
1010
+ }
1011
+ free(j.units);
1012
+ }
1013
+ }
1014
+ }
1015
+ if (has_base) {
1016
+ put_str(&b, ctx, base);
1017
+ put_ascii(&b, " ");
1018
+ }
1019
+ put_str(&b, ctx, brace0);
1020
+ put_ascii(&b, "\n");
1021
+ put_repeat(&b, ' ', (size_t)ip->indentation + 2);
1022
+ put_joined(&b, ctx, output, ",\n", ip->indentation);
1023
+ put_ascii(&b, "\n");
1024
+ put_repeat(&b, ' ', (size_t)ip->indentation);
1025
+ put_ascii(&b, brace1);
1026
+ return done(ip, &b);
1027
+ }
1028
+ /* compact: true */
1029
+ if (is_below_break_length(ip, output, 0, base)) {
1030
+ put_str(&b, ctx, brace0);
1031
+ if (has_base) {
1032
+ put_ascii(&b, " ");
1033
+ put_str(&b, ctx, base);
1034
+ }
1035
+ put_ascii(&b, " ");
1036
+ put_joined(&b, ctx, output, ", ", -1);
1037
+ put_ascii(&b, " ");
1038
+ put_ascii(&b, brace1);
1039
+ return done(ip, &b);
1040
+ }
1041
+ put_str(&b, ctx, brace0);
1042
+ if (!has_base && js_string_length(brace0) == 1) {
1043
+ put_ascii(&b, " ");
1044
+ } else {
1045
+ if (has_base) {
1046
+ put_ascii(&b, " ");
1047
+ put_str(&b, ctx, base);
1048
+ }
1049
+ put_ascii(&b, "\n");
1050
+ put_repeat(&b, ' ', (size_t)ip->indentation + 2);
1051
+ }
1052
+ put_joined(&b, ctx, output, ",\n", ip->indentation);
1053
+ put_ascii(&b, " ");
1054
+ put_ascii(&b, brace1);
1055
+ return done(ip, &b);
1056
+ }
1057
+
1058
+ /* ---- formatRaw ------------------------------------------------------------------------- */
1059
+
1060
+ /* getIteratorBraces: "[Map Iterator] {", "[Foo] [Set Iterator] {"; "Entries" for entries(). */
1061
+ static JSValue iterator_braces(Insp *ip, JSValue tag, JSCollectionPreview what) {
1062
+ bool map = what == JS_PREVIEW_MAP_ITERATOR || what == JS_PREVIEW_MAP_ENTRIES;
1063
+ bool entries = what == JS_PREVIEW_MAP_ENTRIES || what == JS_PREVIEW_SET_ENTRIES;
1064
+ const char *type = map ? "Map Iterator" : "Set Iterator";
1065
+ Builder b = { 0 };
1066
+ put_ascii(&b, "[");
1067
+ if (!str_eq_cstr(ip->ctx, tag, type) && js_string_length(tag) != 0) {
1068
+ put_str(&b, ip->ctx, tag);
1069
+ put_ascii(&b, "] [");
1070
+ }
1071
+ put_ascii(&b, map ? "Map" : "Set");
1072
+ put_ascii(&b, entries ? " Entries] {" : " Iterator] {");
1073
+ return done(ip, &b);
1074
+ }
1075
+
1076
+ /* formatMap, formatSet, formatIterator: "k => v", values, or "[ k, v ]" pairs. */
1077
+ static int format_collection(Insp *ip, JSValue items, JSCollectionPreview what, double recurse, List *out) {
1078
+ JSContext *ctx = ip->ctx;
1079
+ bool pairs = what == JS_PREVIEW_MAP || what == JS_PREVIEW_MAP_ENTRIES || what == JS_PREVIEW_SET_ENTRIES;
1080
+ double length = js_array_length(js_as_object(items)) / (pairs ? 2 : 1);
1081
+ double max = ip->o.max_array_length < 0 ? 0 : ip->o.max_array_length;
1082
+ if (max > length) max = length;
1083
+ ip->indentation += 2;
1084
+ for (uint32_t i = 0; i < max; i++) {
1085
+ if (!pairs) {
1086
+ if (push_result(out, format_value(ip, js_get_value(ctx, items, js_int32((int32_t)i)), recurse)) < 0) return -1;
1087
+ continue;
1088
+ }
1089
+ List pair = { 0 };
1090
+ JSValue k = format_value(ip, js_get_value(ctx, items, js_int32((int32_t)(2 * i))), recurse);
1091
+ JSValue v = js_is_exception(k) ? k : format_value(ip, js_get_value(ctx, items, js_int32((int32_t)(2 * i + 1))), recurse);
1092
+ if (js_is_exception(v)) return -1;
1093
+ JSValue s;
1094
+ if (what == JS_PREVIEW_MAP) {
1095
+ s = concat3(ip, "", k, " => ");
1096
+ if (!js_is_exception(s)) s = keep(ip, js_concat(ctx, s, v));
1097
+ } else {
1098
+ list_push(&pair, k);
1099
+ list_push(&pair, v);
1100
+ s = reduce_to_single_string(ip, &pair, js_empty_string(), cstr(ip, "["), "]", ARRAY_EXTRAS_TYPE, recurse, JS_UNDEFINED);
1101
+ list_free(&pair);
1102
+ }
1103
+ if (push_result(out, s) < 0) return -1;
1104
+ }
1105
+ ip->indentation -= 2;
1106
+ if (length > max && push_result(out, remaining_text(ip, length - max)) < 0) return -1;
1107
+ return 0;
1108
+ }
1109
+
1110
+ /* Whether the builder holds exactly the ASCII text s: 0 if so. */
1111
+ static int memcmp_units(const Builder *b, const char *s) {
1112
+ for (size_t i = 0; i < b->length; i++)
1113
+ if (b->units[i] != (unsigned char)s[i]) return 1;
1114
+ return 0;
1115
+ }
1116
+
1117
+ /* "[name]: value", for the internal values Node lists before the keys. */
1118
+ static JSValue hidden_entry(Insp *ip, const char *name, JSValue v, double recurse) {
1119
+ ip->indentation += 2;
1120
+ JSValue s = format_value(ip, v, recurse);
1121
+ ip->indentation -= 2;
1122
+ if (js_is_exception(s)) return s;
1123
+ Builder b = { 0 };
1124
+ put_ascii(&b, "[");
1125
+ put_ascii(&b, name);
1126
+ put_ascii(&b, "]: ");
1127
+ put_str(&b, ip->ctx, s);
1128
+ return done(ip, &b);
1129
+ }
1130
+
1131
+ /* formatArrayBuffer: "[Uint8Contents]: <00 ff …>" (or "(detached)"), then "[byteLength]: n". */
1132
+ static int format_array_buffer(Insp *ip, JSValue value, List *out) {
1133
+ const JSArrayBuffer *ab = js_as_array_buffer(value);
1134
+ if (js_buffer_is_detached(ab)) {
1135
+ if (push_result(out, cstr(ip, "(detached)")) < 0) return -1;
1136
+ } else {
1137
+ double max = ip->o.max_array_length < 0 ? 0 : ip->o.max_array_length;
1138
+ size_t n = (double)ab->byte_length < max ? ab->byte_length : (size_t)max;
1139
+ Builder b = { 0 };
1140
+ put_ascii(&b, "[Uint8Contents]: <");
1141
+ for (size_t i = 0; i < n; i++) {
1142
+ char hex[4];
1143
+ snprintf(hex, sizeof hex, i ? " %02x" : "%02x", ab->data[i]);
1144
+ put_ascii(&b, hex);
1145
+ }
1146
+ if (ab->byte_length > n) {
1147
+ char more[64];
1148
+ size_t remaining = ab->byte_length - n;
1149
+ snprintf(more, sizeof more, " ... %zu more byte%s", remaining, remaining > 1 ? "s" : "");
1150
+ put_ascii(&b, more);
1151
+ }
1152
+ put_ascii(&b, ">");
1153
+ if (push_result(out, done(ip, &b)) < 0) return -1;
1154
+ }
1155
+ return push_result(out, hidden_entry(ip, "byteLength", js_number((double)ab->byte_length), 0));
1156
+ }
1157
+
1158
+ static JSValue format_raw(Insp *ip, JSValue value, double recurse) {
1159
+ JSContext *ctx = ip->ctx;
1160
+ JSValue result = JS_EXCEPTION;
1161
+ List keys = { 0 }, output = { 0 };
1162
+ JSValue constructor = get_constructor_name(ip, value, recurse);
1163
+ if (js_is_exception(constructor)) return constructor;
1164
+ JSValue tag = get(ip, value, JS_SYMBOL(toStringTag));
1165
+ if (js_is_exception(tag)) return tag;
1166
+ /* only listed when not an own enumerable property (it would be printed twice) */
1167
+ if (!js_is_string(tag) ||
1168
+ (js_string_length(tag) != 0 && (ip->o.show_hidden ? has_own(ctx, value, JS_SYMBOL(toStringTag))
1169
+ : own_enumerable(ctx, value, JS_SYMBOL(toStringTag)))))
1170
+ tag = js_empty_string();
1171
+ const char *cls = js_as_object(value)->shape->cls->name;
1172
+ JSValue base = js_empty_string();
1173
+ JSValue brace0;
1174
+ const char *brace1 = "}";
1175
+ int extras_type = OBJECT_TYPE;
1176
+ enum { PLAIN, ARRAY, PROMISE, WEAK, COLLECTION, BUFFER, DATA_VIEW, TYPED } formatter = PLAIN;
1177
+ double typed_length = ctx->rt->typed_array_length ? ctx->rt->typed_array_length(value) : -2;
1178
+ /* a Map, a Set or their iterators: the entries to show (the collections component) */
1179
+ JSCollectionPreview what = JS_PREVIEW_MAP;
1180
+ JSValue items = JS_EMPTY;
1181
+ if (ctx->rt->collection_preview) {
1182
+ items = keep(ip, ctx->rt->collection_preview(ctx, value, &what));
1183
+ if (js_is_exception(items)) return items;
1184
+ }
1185
+
1186
+ if (js_is_array(value)) {
1187
+ /* only non-ordinary arrays name their constructor: "Foo(2) [ … ]" */
1188
+ bool named = js_is_null(constructor) || !str_eq_cstr(ctx, constructor, "Array") || js_string_length(tag) != 0;
1189
+ if (get_keys(ip, value, true, &keys) < 0) goto out;
1190
+ Builder b = { 0 };
1191
+ if (named) {
1192
+ char size[32];
1193
+ snprintf(size, sizeof size, "(%u)", js_array_length(js_as_object(value)));
1194
+ put_prefix(&b, ctx, constructor, tag, "Array", size);
1195
+ }
1196
+ put_ascii(&b, "[");
1197
+ brace0 = done(ip, &b);
1198
+ brace1 = "]";
1199
+ if (js_is_exception(brace0)) goto out;
1200
+ if (js_array_length(js_as_object(value)) == 0 && keys.n == 0) {
1201
+ result = concat3(ip, "", brace0, "]");
1202
+ goto out;
1203
+ }
1204
+ extras_type = ARRAY_EXTRAS_TYPE;
1205
+ formatter = ARRAY;
1206
+ } else if (typed_length != -2) { /* a typed array: "Uint8Array(3) [ 1, 2, 3 ]" */
1207
+ if (typed_length < 0) typed_length = 0;
1208
+ if (get_keys(ip, value, true, &keys) < 0) goto out;
1209
+ char size[32];
1210
+ snprintf(size, sizeof size, "(%.0f)", typed_length);
1211
+ JSValue fallback = js_is_null(constructor) ? get(ip, value, JS_SYMBOL(toStringTag)) : JS_UNDEFINED;
1212
+ char fb[32] = "";
1213
+ if (js_is_string(fallback)) fb[js_view_to_utf8(js_string_view(ctx, fallback), fb, sizeof fb - 1)] = '\0';
1214
+ Builder b = { 0 };
1215
+ put_prefix(&b, ctx, constructor, tag, fb, size);
1216
+ put_ascii(&b, "[");
1217
+ brace0 = done(ip, &b);
1218
+ brace1 = "]";
1219
+ if (js_is_exception(brace0)) goto out;
1220
+ if (typed_length == 0 && keys.n == 0) {
1221
+ result = concat3(ip, "", brace0, "]");
1222
+ goto out;
1223
+ }
1224
+ extras_type = ARRAY_EXTRAS_TYPE;
1225
+ formatter = TYPED;
1226
+ } else {
1227
+ if (get_keys(ip, value, false, &keys) < 0) goto out;
1228
+ brace0 = cstr(ip, "{");
1229
+ /* a Date's ISO string or a RegExp's /source/flags: the base, after a subclass's prefix */
1230
+ const char *special = "Date";
1231
+ JSValue date = ctx->rt->date_inspect ? keep(ip, ctx->rt->date_inspect(ctx, value)) : JS_EMPTY;
1232
+ if (js_is_empty(date) && ctx->rt->regexp_inspect) {
1233
+ date = keep(ip, ctx->rt->regexp_inspect(ctx, value));
1234
+ special = "RegExp";
1235
+ }
1236
+ if (js_is_exception(date)) goto out;
1237
+ bool object = !js_is_null(constructor) && str_eq_cstr(ctx, constructor, "Object");
1238
+ if (!js_is_empty(items) && (what == JS_PREVIEW_MAP || what == JS_PREVIEW_SET)) {
1239
+ bool map = what == JS_PREVIEW_MAP;
1240
+ uint32_t size = js_array_length(js_as_object(items)) / (map ? 2 : 1);
1241
+ char sz[32];
1242
+ snprintf(sz, sizeof sz, "(%u)", size);
1243
+ if (size == 0 && keys.n == 0) {
1244
+ result = prefix_string(ip, constructor, tag, map ? "Map" : "Set", sz, "{}");
1245
+ goto out;
1246
+ }
1247
+ brace0 = prefix_string(ip, constructor, tag, map ? "Map" : "Set", sz, "{");
1248
+ formatter = COLLECTION;
1249
+ } else if (!js_is_empty(items)) {
1250
+ brace0 = iterator_braces(ip, tag, what);
1251
+ formatter = COLLECTION;
1252
+ } else if (!js_is_empty(date)) {
1253
+ /* "MyDate 1970-…", "MyRegExp /a/g" */
1254
+ base = date;
1255
+ Builder b = { 0 };
1256
+ char plain[16];
1257
+ snprintf(plain, sizeof plain, "%s ", special);
1258
+ put_prefix(&b, ctx, constructor, tag, special, "");
1259
+ if (b.length != strlen(plain) || memcmp_units(&b, plain)) {
1260
+ put_str(&b, ctx, base);
1261
+ base = done(ip, &b);
1262
+ if (js_is_exception(base)) goto out;
1263
+ } else {
1264
+ free(b.units);
1265
+ }
1266
+ if (keys.n == 0) {
1267
+ result = base;
1268
+ goto out;
1269
+ }
1270
+ brace0 = cstr(ip, "{");
1271
+ } else if (js_is_array_buffer(value)) {
1272
+ brace0 = prefix_string(ip, constructor, tag, "ArrayBuffer", "", "{");
1273
+ formatter = BUFFER;
1274
+ } else if (strcmp(cls, "DataView") == 0) {
1275
+ brace0 = prefix_string(ip, constructor, tag, "DataView", "", "{");
1276
+ formatter = DATA_VIEW;
1277
+ } else if (js_is_function(value)) {
1278
+ base = function_base(ip, value, constructor, tag);
1279
+ if (js_is_exception(base) || keys.n == 0) {
1280
+ result = base;
1281
+ goto out;
1282
+ }
1283
+ } else if (object && strcmp(cls, "Arguments") == 0) {
1284
+ brace0 = cstr(ip, "[Arguments] {");
1285
+ if (keys.n == 0) {
1286
+ result = cstr(ip, "[Arguments] {}");
1287
+ goto out;
1288
+ }
1289
+ } else if (object) {
1290
+ if (js_string_length(tag) != 0) brace0 = prefix_string(ip, constructor, tag, "Object", "", "{");
1291
+ if (keys.n == 0) {
1292
+ result = concat3(ip, "", brace0, "}");
1293
+ goto out;
1294
+ }
1295
+ } else if (strcmp(cls, "Error") == 0 || js_is_error(value) || inherits_error(ctx, value)) {
1296
+ base = format_error(ip, value, constructor, tag, &keys);
1297
+ if (js_is_exception(base) || keys.n == 0) {
1298
+ result = base;
1299
+ goto out;
1300
+ }
1301
+ } else if (js_is_wrapper(value)) {
1302
+ base = boxed_base(ip, value, constructor, tag, &keys);
1303
+ if (js_is_exception(base) || keys.n == 0) {
1304
+ result = base;
1305
+ goto out;
1306
+ }
1307
+ } else if (js_is_promise(value)) {
1308
+ brace0 = prefix_string(ip, constructor, tag, "Promise", "", "{");
1309
+ formatter = PROMISE;
1310
+ } else if (strcmp(cls, "WeakSet") == 0) {
1311
+ brace0 = prefix_string(ip, constructor, tag, "WeakSet", "", "{");
1312
+ formatter = WEAK;
1313
+ } else if (strcmp(cls, "WeakMap") == 0) {
1314
+ brace0 = prefix_string(ip, constructor, tag, "WeakMap", "", "{");
1315
+ formatter = WEAK;
1316
+ } else {
1317
+ if (keys.n == 0) {
1318
+ result = prefix_string(ip, constructor, tag, "Object", "", "{}");
1319
+ goto out;
1320
+ }
1321
+ brace0 = prefix_string(ip, constructor, tag, "Object", "", "{");
1322
+ }
1323
+ if (js_is_exception(brace0)) goto out;
1324
+ }
1325
+
1326
+ if (recurse > ip->o.depth) {
1327
+ Builder b = { 0 };
1328
+ if (!js_is_null(constructor)) put_ascii(&b, "[");
1329
+ put_prefix(&b, ctx, constructor, tag, "Object", "");
1330
+ b.length--;
1331
+ if (!js_is_null(constructor)) put_ascii(&b, "]");
1332
+ result = done(ip, &b);
1333
+ goto out;
1334
+ }
1335
+ recurse += 1;
1336
+ list_push(&ip->seen, value);
1337
+ ip->current_depth = recurse;
1338
+ switch (formatter) {
1339
+ case ARRAY:
1340
+ if (format_array(ip, value, recurse, &output) < 0) goto out;
1341
+ break;
1342
+ case PROMISE: {
1343
+ JSPromise *p = js_as_promise(value);
1344
+ if (p->state == JS_PROMISE_PENDING) {
1345
+ if (push_result(&output, cstr(ip, "<pending>")) < 0) goto out;
1346
+ } else {
1347
+ ip->indentation += 2;
1348
+ JSValue str = format_value(ip, p->result, recurse);
1349
+ ip->indentation -= 2;
1350
+ if (js_is_exception(str)) goto out;
1351
+ if (p->state == JS_PROMISE_REJECTED) str = concat3(ip, "<rejected> ", str, "");
1352
+ if (push_result(&output, str) < 0) goto out;
1353
+ }
1354
+ break;
1355
+ }
1356
+ case WEAK:
1357
+ if (push_result(&output, cstr(ip, "<items unknown>")) < 0) goto out;
1358
+ break;
1359
+ case COLLECTION:
1360
+ if (format_collection(ip, items, what, recurse, &output) < 0) goto out;
1361
+ break;
1362
+ case BUFFER:
1363
+ if (format_array_buffer(ip, value, &output) < 0) goto out;
1364
+ break;
1365
+ case TYPED: { /* formatTypedArray */
1366
+ double max = ip->o.max_array_length < 0 ? 0 : ip->o.max_array_length;
1367
+ if (max > typed_length) max = typed_length;
1368
+ for (uint32_t i = 0; i < max; i++) {
1369
+ JSValue e = get(ip, value, js_index_key(i));
1370
+ if (js_is_exception(e) || push_result(&output, format_primitive(ip, e)) < 0) goto out;
1371
+ }
1372
+ if (typed_length > max && push_result(&output, remaining_text(ip, typed_length - max)) < 0) goto out;
1373
+ break;
1374
+ }
1375
+ case DATA_VIEW: {
1376
+ static const char *const names[] = { "byteLength", "byteOffset", "buffer" };
1377
+ for (int i = 0; i < 3; i++) {
1378
+ JSValue v = get(ip, value, js_atom_from_cstr(ctx, names[i]));
1379
+ if (js_is_exception(v) || push_result(&output, hidden_entry(ip, names[i], v, recurse)) < 0) goto out;
1380
+ }
1381
+ break;
1382
+ }
1383
+ case PLAIN:
1384
+ break;
1385
+ }
1386
+ for (size_t i = 0; i < keys.n; i++)
1387
+ if (push_result(&output, format_property(ip, value, recurse, keys.v[i], extras_type)) < 0) goto out;
1388
+
1389
+ for (size_t i = 0; i < ip->circular.n; i++) {
1390
+ if (!js_same_bits(ip->circular.v[i], value)) continue;
1391
+ char ref[32];
1392
+ snprintf(ref, sizeof ref, "<ref *%zu>", i + 1);
1393
+ Builder b = { 0 };
1394
+ put_ascii(&b, ref);
1395
+ if (js_string_length(base) != 0) {
1396
+ put_ascii(&b, " ");
1397
+ put_str(&b, ctx, base);
1398
+ }
1399
+ if (ip->o.compact != COMPACT_TRUE) {
1400
+ base = done(ip, &b);
1401
+ if (js_is_exception(base)) goto out;
1402
+ } else {
1403
+ free(b.units);
1404
+ Builder c = { 0 };
1405
+ put_ascii(&c, ref);
1406
+ put_ascii(&c, " ");
1407
+ put_str(&c, ctx, brace0);
1408
+ brace0 = done(ip, &c);
1409
+ if (js_is_exception(brace0)) goto out;
1410
+ }
1411
+ break;
1412
+ }
1413
+ ip->seen.n--;
1414
+ result = reduce_to_single_string(ip, &output, base, brace0, brace1, extras_type, recurse, value);
1415
+ out:
1416
+ list_free(&keys);
1417
+ list_free(&output);
1418
+ return result;
1419
+ }
1420
+
1421
+ /* ---- formatValue ------------------------------------------------------------------------ */
1422
+
1423
+ static JSValue identity_stylize(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc,
1424
+ const JSValue *argv, JSValue new_target) {
1425
+ (void)ctx, (void)callee, (void)this_val, (void)new_target;
1426
+ return argc ? argv[0] : JS_UNDEFINED;
1427
+ }
1428
+
1429
+ /* The options a custom inspector receives (getUserOptions): `depth` is the option, not the depth left. */
1430
+ static JSValue user_options(Insp *ip) {
1431
+ JSContext *ctx = ip->ctx;
1432
+ JSValue o = keep(ip, js_new_object(ctx));
1433
+ if (js_is_exception(o)) return o;
1434
+ JSObject *obj = js_as_object(o);
1435
+ const JSInspectOptions *p = &ip->o;
1436
+ #define FIELD(name, v) js_define_data(ctx, obj, js_atom_from_cstr(ctx, name), (v), JS_PROP_DEFAULT)
1437
+ FIELD("showHidden", js_bool(p->show_hidden));
1438
+ FIELD("depth", isinf(p->depth) ? JS_NULL : js_number(p->depth));
1439
+ FIELD("colors", JS_FALSE);
1440
+ FIELD("customInspect", js_bool(p->custom_inspect));
1441
+ FIELD("showProxy", JS_FALSE);
1442
+ FIELD("maxArrayLength", js_number(p->max_array_length));
1443
+ FIELD("maxStringLength", js_number(p->max_string_length));
1444
+ FIELD("breakLength", js_number(p->break_length));
1445
+ FIELD("compact", p->compact == COMPACT_TRUE ? JS_TRUE : p->compact == 0 ? JS_FALSE : js_int32(p->compact));
1446
+ FIELD("sorted", js_bool(p->sorted));
1447
+ FIELD("getters", JS_FALSE);
1448
+ FIELD("numericSeparator", JS_FALSE);
1449
+ JSValue stylize = js_new_native(ctx, identity_stylize, js_atom_from_cstr(ctx, "stylize"), 2, JS_FN_STRICT);
1450
+ if (js_is_exception(stylize)) return stylize;
1451
+ FIELD("stylize", stylize);
1452
+ #undef FIELD
1453
+ return o;
1454
+ }
1455
+
1456
+ static JSValue format_value(Insp *ip, JSValue value, double recurse) {
1457
+ JSContext *ctx = ip->ctx;
1458
+ if (!is_object_like(value)) return format_primitive(ip, value);
1459
+ keep(ip, value);
1460
+ /* a proxy shows its target, and never runs its traps (getProxyDetails) */
1461
+ for (JSValue target; !js_is_empty(target = js_proxy_target(value));) {
1462
+ if (js_is_null(target)) return cstr(ip, "<Revoked Proxy>");
1463
+ value = target;
1464
+ }
1465
+
1466
+ if (ip->o.custom_inspect) {
1467
+ JSValue key = keep(ip, js_symbol_for(ctx, js_new_string_cstr(ctx, "nodejs.util.inspect.custom")));
1468
+ if (js_is_exception(key)) return key;
1469
+ JSValue custom = get(ip, value, key);
1470
+ if (js_is_exception(custom)) return custom;
1471
+ JSValue inspect_fn = js_util_inspect_function(ctx);
1472
+ if (js_is_callable(custom) && !js_same_bits(custom, inspect_fn)) {
1473
+ /* not a class's prototype inspecting itself */
1474
+ bool own_prototype = false;
1475
+ JSValue ctor = get(ip, value, JS_ATOM(constructor));
1476
+ if (js_is_exception(ctor)) return ctor;
1477
+ if (js_is_object(ctor)) {
1478
+ JSValue proto = get(ip, ctor, JS_ATOM(prototype));
1479
+ if (js_is_exception(proto)) return proto;
1480
+ own_prototype = js_same_bits(proto, value);
1481
+ }
1482
+ if (!own_prototype) {
1483
+ JSValue depth = isinf(ip->o.depth) ? JS_NULL : js_number(ip->o.depth - recurse);
1484
+ JSValue options = user_options(ip);
1485
+ if (js_is_exception(options)) return options;
1486
+ JSValue args[3] = { depth, options, inspect_fn };
1487
+ JSValue ret = keep(ip, js_call(ctx, custom, value, 3, args));
1488
+ if (js_is_exception(ret)) return ret;
1489
+ if (!js_same_bits(ret, value)) {
1490
+ if (!js_is_string(ret)) return format_value(ip, ret, recurse);
1491
+ return replace_newlines(ip, ret, ip->indentation);
1492
+ }
1493
+ }
1494
+ }
1495
+ }
1496
+
1497
+ for (size_t i = 0; i < ip->seen.n; i++) {
1498
+ if (!js_same_bits(ip->seen.v[i], value)) continue;
1499
+ size_t index = 0;
1500
+ for (size_t c = 0; c < ip->circular.n; c++)
1501
+ if (js_same_bits(ip->circular.v[c], value)) index = c + 1;
1502
+ if (!index) {
1503
+ list_push(&ip->circular, value);
1504
+ index = ip->circular.n;
1505
+ }
1506
+ char ref[40];
1507
+ snprintf(ref, sizeof ref, "[Circular *%zu]", index);
1508
+ return cstr(ip, ref);
1509
+ }
1510
+ return format_raw(ip, value, recurse);
1511
+ }
1512
+
1513
+ static JSValue inspect_value(JSContext *ctx, JSValue v, const JSInspectOptions *o) {
1514
+ Insp ip;
1515
+ insp_init(&ip, ctx, o);
1516
+ if (js_is_exception(ip.keep)) return ip.keep;
1517
+ JSValue r = format_value(&ip, v, 0);
1518
+ insp_free(&ip);
1519
+ return r;
1520
+ }
1521
+
1522
+ JSValue js_inspect_with(JSContext *ctx, JSValue v, const JSInspectOptions *o) {
1523
+ return inspect_value(ctx, v, o);
1524
+ }
1525
+
1526
+ JSValue js_inspect(JSContext *ctx, JSValue v) {
1527
+ return inspect_value(ctx, v, &js_inspect_defaults);
1528
+ }
1529
+
1530
+ /* ---- %j ---------------------------------------------------------------------------------- */
1531
+
1532
+ /* tryStringify: JSON.stringify, "[Circular]" for a cycle; undefined → "undefined". */
1533
+ static int put_stringified(Insp *ip, Builder *b, JSValue v) {
1534
+ bool circular;
1535
+ JSValue s = js_json_stringify(ip->ctx, v, JS_UNDEFINED, JS_UNDEFINED, &circular);
1536
+ if (js_is_exception(s)) {
1537
+ if (!circular) return -1;
1538
+ js_discard(js_take_exception(ip->ctx));
1539
+ put_ascii(b, "[Circular]");
1540
+ } else if (js_is_undefined(s)) {
1541
+ put_ascii(b, "undefined");
1542
+ } else {
1543
+ put_str(b, ip->ctx, s);
1544
+ }
1545
+ return 0;
1546
+ }
1547
+
1548
+ /* ---- util.format ------------------------------------------------------------------------ */
1549
+
1550
+ /* Whether `value`'s toString is a built-in one: %s then inspects it rather than calling it. */
1551
+ static int has_built_in_to_string(Insp *ip, JSValue value) {
1552
+ JSContext *ctx = ip->ctx;
1553
+ JSValue to_string = get(ip, value, JS_ATOM(toString));
1554
+ if (js_is_exception(to_string)) return -1;
1555
+ if (!js_is_callable(to_string)) return 1;
1556
+ if (has_own(ctx, value, JS_ATOM(toString))) return 0;
1557
+ JSValue pointer = value;
1558
+ do {
1559
+ pointer = js_get_prototype_of(js_as_object(pointer));
1560
+ } while (js_is_object(pointer) && !has_own(ctx, pointer, JS_ATOM(toString)));
1561
+ if (!js_is_object(pointer)) return 1;
1562
+ JSPropertyDescriptor d;
1563
+ int has = own(ctx, pointer, JS_ATOM(constructor), &d);
1564
+ if (has < 0) return -1;
1565
+ if (!has || !(d.has & JS_DESC_VALUE) || !js_is_function(d.value)) return 0;
1566
+ /* Node's builtInObjects: the global functions whose names start with a capital letter */
1567
+ JSValue name = get(ip, d.value, JS_ATOM(name));
1568
+ if (js_is_exception(name)) return -1;
1569
+ if (!js_is_string(name) || js_string_length(name) == 0) return 0;
1570
+ uint32_t c = js_view_at(js_string_view(ctx, name), 0);
1571
+ if (c < 'A' || c > 'Z') return 0;
1572
+ JSValue key = keep(ip, js_to_property_key(ctx, name));
1573
+ if (js_is_exception(key)) return -1;
1574
+ JSValue global = ctx->intrinsics[JS_INTRINSIC_GLOBAL_OBJECT];
1575
+ if (own(ctx, global, key, &d) <= 0) return 0;
1576
+ return (d.has & JS_DESC_VALUE) && js_is_function(d.value);
1577
+ }
1578
+
1579
+ static int put_inspected(Insp *ip, Builder *b, JSValue v, const JSInspectOptions *o) {
1580
+ JSValue s = keep(ip, inspect_value(ip->ctx, v, o));
1581
+ if (js_is_exception(s)) return -1;
1582
+ put_str(b, ip->ctx, s);
1583
+ return 0;
1584
+ }
1585
+
1586
+ /* %d and %i of a BigInt: "5n" */
1587
+ static int put_bigint(Insp *ip, Builder *b, JSValue v) {
1588
+ JSValue s = keep(ip, js_to_string(ip->ctx, v));
1589
+ if (js_is_exception(s)) return -1;
1590
+ put_str(b, ip->ctx, s);
1591
+ put_ascii(b, "n");
1592
+ return 0;
1593
+ }
1594
+
1595
+ static int put_to_number(Insp *ip, Builder *b, JSValue v) {
1596
+ if (js_is_bigint(v)) return put_bigint(ip, b, v);
1597
+ if (js_is_symbol(v)) {
1598
+ put_ascii(b, "NaN");
1599
+ return 0;
1600
+ }
1601
+ double d;
1602
+ if (js_to_number(ip->ctx, &d, v)) return -1;
1603
+ put_number(b, d);
1604
+ return 0;
1605
+ }
1606
+
1607
+ static int put_parsed(Insp *ip, Builder *b, JSValue v, bool integer) {
1608
+ if (integer && js_is_bigint(v)) return put_bigint(ip, b, v);
1609
+ if (js_is_symbol(v)) {
1610
+ put_ascii(b, "NaN");
1611
+ return 0;
1612
+ }
1613
+ JSValue s = keep(ip, js_to_string(ip->ctx, v));
1614
+ if (js_is_exception(s)) return -1;
1615
+ JSStrView sv = js_string_view(ip->ctx, s);
1616
+ put_number(b, integer ? js_parse_int(sv, 0) : js_parse_float(sv));
1617
+ return 0;
1618
+ }
1619
+
1620
+ JSValue js_format_with(JSContext *ctx, const JSInspectOptions *o, uint32_t argc, const JSValue *argv) {
1621
+ if (argc == 0) return js_empty_string();
1622
+ if (argc == 1 && js_is_string(argv[0])) return argv[0];
1623
+ Insp ip;
1624
+ insp_init(&ip, ctx, o);
1625
+ if (js_is_exception(ip.keep)) return ip.keep;
1626
+ Builder b = { 0 };
1627
+ uint32_t a = 0;
1628
+ const char *join = "";
1629
+ int rc = 0;
1630
+
1631
+ if (js_is_string(argv[0])) {
1632
+ JSStrView f = js_string_view(ctx, argv[0]);
1633
+ uint32_t last = 0;
1634
+ for (uint32_t i = 0; f.length && i < f.length - 1 && rc == 0; i++) {
1635
+ if (js_view_at(f, i) != '%') continue;
1636
+ uint32_t next = js_view_at(f, ++i);
1637
+ if (a + 1 == argc) { /* no argument left: only %% is replaced */
1638
+ if (next == '%') {
1639
+ put_view(&b, f, last, i);
1640
+ last = i + 1;
1641
+ }
1642
+ continue;
1643
+ }
1644
+ Builder piece = { 0 };
1645
+ JSValue arg = JS_UNDEFINED;
1646
+ switch (next) {
1647
+ case 's': {
1648
+ arg = argv[++a];
1649
+ if (js_is_number(arg)) {
1650
+ put_number(&piece, js_as_number(arg));
1651
+ break;
1652
+ }
1653
+ if (js_is_bigint(arg)) { /* 7n */
1654
+ rc = put_bigint(&ip, &piece, arg);
1655
+ break;
1656
+ }
1657
+ int builtin = js_is_object(arg) ? has_built_in_to_string(&ip, arg) : 0;
1658
+ if (builtin < 0) {
1659
+ rc = -1;
1660
+ } else if (!js_is_object(arg) || !builtin) {
1661
+ /* String(arg): a symbol is its description, not a TypeError */
1662
+ JSValue s = keep(&ip, js_is_symbol(arg) ? js_symbol_descriptive_string(ctx, arg) : js_to_string(ctx, arg));
1663
+ if (js_is_exception(s)) rc = -1;
1664
+ else put_str(&piece, ctx, s);
1665
+ } else {
1666
+ JSInspectOptions so = *o;
1667
+ so.depth = 0;
1668
+ so.compact = 3;
1669
+ rc = put_inspected(&ip, &piece, arg, &so);
1670
+ }
1671
+ break;
1672
+ }
1673
+ case 'j': rc = put_stringified(&ip, &piece, argv[++a]); break;
1674
+ case 'd': rc = put_to_number(&ip, &piece, argv[++a]); break;
1675
+ case 'i': rc = put_parsed(&ip, &piece, argv[++a], true); break;
1676
+ case 'f': rc = put_parsed(&ip, &piece, argv[++a], false); break;
1677
+ case 'O': rc = put_inspected(&ip, &piece, argv[++a], o); break;
1678
+ case 'o': {
1679
+ JSInspectOptions oo = *o;
1680
+ oo.show_hidden = true;
1681
+ oo.depth = 4;
1682
+ rc = put_inspected(&ip, &piece, argv[++a], &oo);
1683
+ break;
1684
+ }
1685
+ case 'c': a++; break;
1686
+ case '%':
1687
+ put_view(&b, f, last, i);
1688
+ last = i + 1;
1689
+ free(piece.units);
1690
+ continue;
1691
+ default:
1692
+ free(piece.units);
1693
+ continue;
1694
+ }
1695
+ if (rc == 0) {
1696
+ if (last != i - 1) put_view(&b, f, last, i - 1);
1697
+ reserve(&b, piece.length);
1698
+ if (piece.length) memcpy(b.units + b.length, piece.units, piece.length * sizeof *piece.units);
1699
+ b.length += piece.length;
1700
+ last = i + 1;
1701
+ }
1702
+ free(piece.units);
1703
+ }
1704
+ if (rc == 0 && last != 0) {
1705
+ a++;
1706
+ join = " ";
1707
+ if (last < f.length) put_view(&b, f, last, f.length);
1708
+ }
1709
+ }
1710
+ for (; a < argc && rc == 0; a++) {
1711
+ put_ascii(&b, join);
1712
+ if (js_is_string(argv[a])) put_str(&b, ctx, argv[a]);
1713
+ else rc = put_inspected(&ip, &b, argv[a], o);
1714
+ join = " ";
1715
+ }
1716
+ insp_free(&ip);
1717
+ if (rc) {
1718
+ free(b.units);
1719
+ return JS_EXCEPTION;
1720
+ }
1721
+ return finish(ctx, &b);
1722
+ }
1723
+
1724
+ JSValue js_format(JSContext *ctx, uint32_t argc, const JSValue *argv) {
1725
+ return js_format_with(ctx, &js_inspect_defaults, argc, argv);
1726
+ }
1727
+
1728
+ /* ---- Options from JavaScript, and node:util's functions ------------------------------------ */
1729
+
1730
+ /* util.inspect's options object: the keys Node knows (others are ignored). */
1731
+ int js_inspect_options_from(JSContext *ctx, JSValue opts, JSInspectOptions *o) {
1732
+ if (!js_is_object(opts)) return 0;
1733
+ JSValue all = js_own_keys(ctx, js_as_object(opts));
1734
+ if (js_is_exception(all)) return -1;
1735
+ JSValueArray *list = (JSValueArray *)js_as_cell(all);
1736
+ for (uint32_t i = 0; i < list->cell.aux; i++) {
1737
+ JSValue key = list->values[i];
1738
+ if (!js_is_string(key) || !own_enumerable(ctx, opts, key)) continue;
1739
+ JSValue v = js_get_value(ctx, opts, key);
1740
+ if (js_is_exception(v)) return -1;
1741
+ double d = js_is_number(v) ? js_as_number(v) : NAN;
1742
+ if (str_eq_cstr(ctx, key, "showHidden")) o->show_hidden = js_truthy(v);
1743
+ else if (str_eq_cstr(ctx, key, "depth")) o->depth = js_is_null(v) ? INFINITY : js_is_number(v) ? d : o->depth;
1744
+ else if (str_eq_cstr(ctx, key, "customInspect")) o->custom_inspect = js_truthy(v);
1745
+ else if (str_eq_cstr(ctx, key, "maxArrayLength")) o->max_array_length = js_is_null(v) ? INFINITY : js_is_number(v) ? d : o->max_array_length;
1746
+ else if (str_eq_cstr(ctx, key, "maxStringLength")) o->max_string_length = js_is_null(v) ? INFINITY : js_is_number(v) ? d : o->max_string_length;
1747
+ else if (str_eq_cstr(ctx, key, "breakLength")) o->break_length = js_is_number(v) ? d : o->break_length;
1748
+ else if (str_eq_cstr(ctx, key, "compact")) o->compact = js_is_bool(v) ? (js_as_bool(v) ? COMPACT_TRUE : 0) : js_is_number(v) ? (int)d : o->compact;
1749
+ else if (str_eq_cstr(ctx, key, "sorted")) o->sorted = js_truthy(v);
1750
+ }
1751
+ return 0;
1752
+ }
1753
+
1754
+ /* util.inspect(value, options) — also inspect(value, showHidden, depth) */
1755
+ JSValue js_util_inspect(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc,
1756
+ const JSValue *argv, JSValue new_target) {
1757
+ (void)callee, (void)this_val, (void)new_target;
1758
+ JSInspectOptions o = js_inspect_defaults;
1759
+ if (argc > 1) {
1760
+ if (js_is_bool(argv[1])) o.show_hidden = js_as_bool(argv[1]);
1761
+ else if (js_inspect_options_from(ctx, argv[1], &o) < 0) return JS_EXCEPTION;
1762
+ if (argc > 2 && !js_is_undefined(argv[2])) o.depth = js_is_null(argv[2]) ? INFINITY : js_is_number(argv[2]) ? js_as_number(argv[2]) : o.depth;
1763
+ }
1764
+ return inspect_value(ctx, argc ? argv[0] : JS_UNDEFINED, &o);
1765
+ }
1766
+
1767
+ /* util.format(...args) */
1768
+ JSValue js_util_format(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc,
1769
+ const JSValue *argv, JSValue new_target) {
1770
+ (void)callee, (void)this_val, (void)new_target;
1771
+ return js_format(ctx, argc, argv);
1772
+ }
1773
+
1774
+ /* util.formatWithOptions(options, ...args) */
1775
+ JSValue js_util_format_with_options(JSContext *ctx, JSValue callee, JSValue this_val, uint32_t argc,
1776
+ const JSValue *argv, JSValue new_target) {
1777
+ (void)callee, (void)this_val, (void)new_target;
1778
+ JSInspectOptions o = js_inspect_defaults;
1779
+ if (argc && js_inspect_options_from(ctx, argv[0], &o) < 0) return JS_EXCEPTION;
1780
+ return js_format_with(ctx, &o, argc ? argc - 1 : 0, argv + (argc ? 1 : 0));
1781
+ }
1782
+
1783
+ /* The util.inspect function object custom inspectors receive: one per realm. */
1784
+ JSValue js_util_inspect_function(JSContext *ctx) {
1785
+ JSValue *slot = &ctx->intrinsics[JS_INTRINSIC_UTIL_INSPECT];
1786
+ if (!js_is_function(*slot)) {
1787
+ JSValue f = js_new_native(ctx, js_util_inspect, js_atom_from_cstr(ctx, "inspect"), 2, JS_FN_STRICT);
1788
+ if (js_is_exception(f)) return f;
1789
+ *slot = f;
1790
+ }
1791
+ return *slot;
1792
+ }