@scriptc/runtime 0.0.0 → 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 (416) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +16 -6
  3. package/src/scr_array.c +488 -0
  4. package/src/scr_assert.c +1393 -0
  5. package/src/scr_async.c +2593 -0
  6. package/src/scr_async_dyn.c +607 -0
  7. package/src/scr_bytes.c +1425 -0
  8. package/src/scr_bytes_io.c +161 -0
  9. package/src/scr_child.c +3587 -0
  10. package/src/scr_closure.c +214 -0
  11. package/src/scr_console.c +143 -0
  12. package/src/scr_cycle.c +218 -0
  13. package/src/scr_dc.c +805 -0
  14. package/src/scr_dgram.c +1007 -0
  15. package/src/scr_dyn_handle.c +154 -0
  16. package/src/scr_dyn_invoke.c +644 -0
  17. package/src/scr_error.c +332 -0
  18. package/src/scr_events.c +714 -0
  19. package/src/scr_events_emitter.c +699 -0
  20. package/src/scr_exception.c +242 -0
  21. package/src/scr_fetch.c +1130 -0
  22. package/src/scr_fetch_curl.c +654 -0
  23. package/src/scr_http.c +3482 -0
  24. package/src/scr_http2.c +3030 -0
  25. package/src/scr_inspect.c +803 -0
  26. package/src/scr_inspect_island.c +51 -0
  27. package/src/scr_island.c +9363 -0
  28. package/src/scr_json.c +2151 -0
  29. package/src/scr_lib.c +3612 -0
  30. package/src/scr_loop_epoll.c +241 -0
  31. package/src/scr_loop_kqueue.c +121 -0
  32. package/src/scr_loop_wsapoll.c +208 -0
  33. package/src/scr_map.c +591 -0
  34. package/src/scr_net.c +3017 -0
  35. package/src/scr_net_island.c +458 -0
  36. package/src/scr_number.c +115 -0
  37. package/src/scr_object.c +25 -0
  38. package/src/scr_path.c +1266 -0
  39. package/src/scr_platform.h +119 -0
  40. package/src/scr_readline.c +287 -0
  41. package/src/scr_regex.c +1080 -0
  42. package/src/scr_runtime.h +5046 -0
  43. package/src/scr_stream.c +2877 -0
  44. package/src/scr_string.c +1264 -0
  45. package/src/scr_symbol.c +132 -0
  46. package/src/scr_test.c +662 -0
  47. package/src/scr_tls.c +1520 -0
  48. package/src/scr_union.c +105 -0
  49. package/src/scr_url.c +911 -0
  50. package/src/scr_url_internal.h +29 -0
  51. package/src/scr_url_params.c +561 -0
  52. package/src/scr_watch.c +568 -0
  53. package/src/scr_web.c +1778 -0
  54. package/src/scr_win.c +76 -0
  55. package/src/scr_zlib.c +197 -0
  56. package/src/scr_zlib_island.c +15 -0
  57. package/vendor/README.md +52 -0
  58. package/vendor/curl/COPYRIGHT +534 -0
  59. package/vendor/curl/include/curl/curl.h +3214 -0
  60. package/vendor/curl/include/curl/curlver.h +79 -0
  61. package/vendor/curl/include/curl/easy.h +125 -0
  62. package/vendor/curl/include/curl/header.h +74 -0
  63. package/vendor/curl/include/curl/mprintf.h +52 -0
  64. package/vendor/curl/include/curl/multi.h +460 -0
  65. package/vendor/curl/include/curl/options.h +70 -0
  66. package/vendor/curl/include/curl/stdcheaders.h +35 -0
  67. package/vendor/curl/include/curl/system.h +508 -0
  68. package/vendor/curl/include/curl/typecheck-gcc.h +716 -0
  69. package/vendor/curl/include/curl/urlapi.h +149 -0
  70. package/vendor/curl/include/curl/websockets.h +84 -0
  71. package/vendor/mbedtls/LICENSE +553 -0
  72. package/vendor/mbedtls/include/CMakeLists.txt +22 -0
  73. package/vendor/mbedtls/include/mbedtls/aes.h +631 -0
  74. package/vendor/mbedtls/include/mbedtls/aria.h +343 -0
  75. package/vendor/mbedtls/include/mbedtls/asn1.h +642 -0
  76. package/vendor/mbedtls/include/mbedtls/asn1write.h +390 -0
  77. package/vendor/mbedtls/include/mbedtls/base64.h +82 -0
  78. package/vendor/mbedtls/include/mbedtls/bignum.h +1088 -0
  79. package/vendor/mbedtls/include/mbedtls/block_cipher.h +76 -0
  80. package/vendor/mbedtls/include/mbedtls/build_info.h +194 -0
  81. package/vendor/mbedtls/include/mbedtls/camellia.h +305 -0
  82. package/vendor/mbedtls/include/mbedtls/ccm.h +526 -0
  83. package/vendor/mbedtls/include/mbedtls/chacha20.h +209 -0
  84. package/vendor/mbedtls/include/mbedtls/chachapoly.h +351 -0
  85. package/vendor/mbedtls/include/mbedtls/check_config.h +1149 -0
  86. package/vendor/mbedtls/include/mbedtls/cipher.h +1250 -0
  87. package/vendor/mbedtls/include/mbedtls/cmac.h +246 -0
  88. package/vendor/mbedtls/include/mbedtls/compat-2.x.h +46 -0
  89. package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_crypto.h +578 -0
  90. package/vendor/mbedtls/include/mbedtls/config_adjust_legacy_from_psa.h +873 -0
  91. package/vendor/mbedtls/include/mbedtls/config_adjust_psa_from_legacy.h +359 -0
  92. package/vendor/mbedtls/include/mbedtls/config_adjust_psa_superset_legacy.h +145 -0
  93. package/vendor/mbedtls/include/mbedtls/config_adjust_ssl.h +91 -0
  94. package/vendor/mbedtls/include/mbedtls/config_adjust_x509.h +35 -0
  95. package/vendor/mbedtls/include/mbedtls/config_psa.h +61 -0
  96. package/vendor/mbedtls/include/mbedtls/constant_time.h +36 -0
  97. package/vendor/mbedtls/include/mbedtls/ctr_drbg.h +596 -0
  98. package/vendor/mbedtls/include/mbedtls/debug.h +156 -0
  99. package/vendor/mbedtls/include/mbedtls/des.h +385 -0
  100. package/vendor/mbedtls/include/mbedtls/dhm.h +972 -0
  101. package/vendor/mbedtls/include/mbedtls/ecdh.h +455 -0
  102. package/vendor/mbedtls/include/mbedtls/ecdsa.h +674 -0
  103. package/vendor/mbedtls/include/mbedtls/ecjpake.h +298 -0
  104. package/vendor/mbedtls/include/mbedtls/ecp.h +1517 -0
  105. package/vendor/mbedtls/include/mbedtls/entropy.h +274 -0
  106. package/vendor/mbedtls/include/mbedtls/error.h +201 -0
  107. package/vendor/mbedtls/include/mbedtls/gcm.h +387 -0
  108. package/vendor/mbedtls/include/mbedtls/hkdf.h +124 -0
  109. package/vendor/mbedtls/include/mbedtls/hmac_drbg.h +434 -0
  110. package/vendor/mbedtls/include/mbedtls/lms.h +440 -0
  111. package/vendor/mbedtls/include/mbedtls/mbedtls_config.h +4446 -0
  112. package/vendor/mbedtls/include/mbedtls/md.h +526 -0
  113. package/vendor/mbedtls/include/mbedtls/md5.h +190 -0
  114. package/vendor/mbedtls/include/mbedtls/memory_buffer_alloc.h +142 -0
  115. package/vendor/mbedtls/include/mbedtls/net_sockets.h +299 -0
  116. package/vendor/mbedtls/include/mbedtls/nist_kw.h +166 -0
  117. package/vendor/mbedtls/include/mbedtls/oid.h +727 -0
  118. package/vendor/mbedtls/include/mbedtls/pem.h +160 -0
  119. package/vendor/mbedtls/include/mbedtls/pk.h +1303 -0
  120. package/vendor/mbedtls/include/mbedtls/pkcs12.h +186 -0
  121. package/vendor/mbedtls/include/mbedtls/pkcs5.h +198 -0
  122. package/vendor/mbedtls/include/mbedtls/pkcs7.h +252 -0
  123. package/vendor/mbedtls/include/mbedtls/platform.h +516 -0
  124. package/vendor/mbedtls/include/mbedtls/platform_time.h +79 -0
  125. package/vendor/mbedtls/include/mbedtls/platform_util.h +247 -0
  126. package/vendor/mbedtls/include/mbedtls/poly1305.h +168 -0
  127. package/vendor/mbedtls/include/mbedtls/private_access.h +20 -0
  128. package/vendor/mbedtls/include/mbedtls/psa_util.h +207 -0
  129. package/vendor/mbedtls/include/mbedtls/ripemd160.h +136 -0
  130. package/vendor/mbedtls/include/mbedtls/rsa.h +1170 -0
  131. package/vendor/mbedtls/include/mbedtls/sha1.h +219 -0
  132. package/vendor/mbedtls/include/mbedtls/sha256.h +200 -0
  133. package/vendor/mbedtls/include/mbedtls/sha3.h +172 -0
  134. package/vendor/mbedtls/include/mbedtls/sha512.h +208 -0
  135. package/vendor/mbedtls/include/mbedtls/ssl.h +5887 -0
  136. package/vendor/mbedtls/include/mbedtls/ssl_cache.h +187 -0
  137. package/vendor/mbedtls/include/mbedtls/ssl_ciphersuites.h +482 -0
  138. package/vendor/mbedtls/include/mbedtls/ssl_cookie.h +106 -0
  139. package/vendor/mbedtls/include/mbedtls/ssl_ticket.h +199 -0
  140. package/vendor/mbedtls/include/mbedtls/threading.h +167 -0
  141. package/vendor/mbedtls/include/mbedtls/timing.h +94 -0
  142. package/vendor/mbedtls/include/mbedtls/version.h +78 -0
  143. package/vendor/mbedtls/include/mbedtls/x509.h +500 -0
  144. package/vendor/mbedtls/include/mbedtls/x509_crl.h +184 -0
  145. package/vendor/mbedtls/include/mbedtls/x509_crt.h +1208 -0
  146. package/vendor/mbedtls/include/mbedtls/x509_csr.h +382 -0
  147. package/vendor/mbedtls/include/psa/build_info.h +20 -0
  148. package/vendor/mbedtls/include/psa/crypto.h +4998 -0
  149. package/vendor/mbedtls/include/psa/crypto_adjust_auto_enabled.h +31 -0
  150. package/vendor/mbedtls/include/psa/crypto_adjust_config_dependencies.h +51 -0
  151. package/vendor/mbedtls/include/psa/crypto_adjust_config_key_pair_types.h +101 -0
  152. package/vendor/mbedtls/include/psa/crypto_adjust_config_synonyms.h +49 -0
  153. package/vendor/mbedtls/include/psa/crypto_builtin_composites.h +214 -0
  154. package/vendor/mbedtls/include/psa/crypto_builtin_key_derivation.h +118 -0
  155. package/vendor/mbedtls/include/psa/crypto_builtin_primitives.h +114 -0
  156. package/vendor/mbedtls/include/psa/crypto_compat.h +230 -0
  157. package/vendor/mbedtls/include/psa/crypto_config.h +145 -0
  158. package/vendor/mbedtls/include/psa/crypto_driver_common.h +44 -0
  159. package/vendor/mbedtls/include/psa/crypto_driver_contexts_composites.h +151 -0
  160. package/vendor/mbedtls/include/psa/crypto_driver_contexts_key_derivation.h +52 -0
  161. package/vendor/mbedtls/include/psa/crypto_driver_contexts_primitives.h +105 -0
  162. package/vendor/mbedtls/include/psa/crypto_extra.h +2145 -0
  163. package/vendor/mbedtls/include/psa/crypto_legacy.h +88 -0
  164. package/vendor/mbedtls/include/psa/crypto_platform.h +102 -0
  165. package/vendor/mbedtls/include/psa/crypto_se_driver.h +1383 -0
  166. package/vendor/mbedtls/include/psa/crypto_sizes.h +1319 -0
  167. package/vendor/mbedtls/include/psa/crypto_struct.h +527 -0
  168. package/vendor/mbedtls/include/psa/crypto_types.h +508 -0
  169. package/vendor/mbedtls/include/psa/crypto_values.h +2782 -0
  170. package/vendor/mbedtls/library/aes.c +2294 -0
  171. package/vendor/mbedtls/library/aesce.c +624 -0
  172. package/vendor/mbedtls/library/aesce.h +136 -0
  173. package/vendor/mbedtls/library/aesni.c +846 -0
  174. package/vendor/mbedtls/library/aesni.h +162 -0
  175. package/vendor/mbedtls/library/alignment.h +704 -0
  176. package/vendor/mbedtls/library/aria.c +969 -0
  177. package/vendor/mbedtls/library/asn1parse.c +468 -0
  178. package/vendor/mbedtls/library/asn1write.c +440 -0
  179. package/vendor/mbedtls/library/base64.c +322 -0
  180. package/vendor/mbedtls/library/base64_internal.h +45 -0
  181. package/vendor/mbedtls/library/bignum.c +2583 -0
  182. package/vendor/mbedtls/library/bignum_core.c +1240 -0
  183. package/vendor/mbedtls/library/bignum_core.h +872 -0
  184. package/vendor/mbedtls/library/bignum_core_invasive.h +38 -0
  185. package/vendor/mbedtls/library/bignum_internal.h +122 -0
  186. package/vendor/mbedtls/library/bignum_mod.c +394 -0
  187. package/vendor/mbedtls/library/bignum_mod.h +452 -0
  188. package/vendor/mbedtls/library/bignum_mod_raw.c +276 -0
  189. package/vendor/mbedtls/library/bignum_mod_raw.h +416 -0
  190. package/vendor/mbedtls/library/bignum_mod_raw_invasive.h +34 -0
  191. package/vendor/mbedtls/library/block_cipher.c +207 -0
  192. package/vendor/mbedtls/library/block_cipher_internal.h +99 -0
  193. package/vendor/mbedtls/library/bn_mul.h +1094 -0
  194. package/vendor/mbedtls/library/camellia.c +1058 -0
  195. package/vendor/mbedtls/library/ccm.c +777 -0
  196. package/vendor/mbedtls/library/chacha20.c +563 -0
  197. package/vendor/mbedtls/library/chacha20_internal.h +23 -0
  198. package/vendor/mbedtls/library/chachapoly.c +487 -0
  199. package/vendor/mbedtls/library/check_crypto_config.h +136 -0
  200. package/vendor/mbedtls/library/cipher.c +1712 -0
  201. package/vendor/mbedtls/library/cipher_invasive.h +28 -0
  202. package/vendor/mbedtls/library/cipher_wrap.c +2482 -0
  203. package/vendor/mbedtls/library/cipher_wrap.h +178 -0
  204. package/vendor/mbedtls/library/cmac.c +1067 -0
  205. package/vendor/mbedtls/library/common.h +487 -0
  206. package/vendor/mbedtls/library/constant_time.c +247 -0
  207. package/vendor/mbedtls/library/constant_time_impl.h +541 -0
  208. package/vendor/mbedtls/library/constant_time_internal.h +579 -0
  209. package/vendor/mbedtls/library/ctr.h +35 -0
  210. package/vendor/mbedtls/library/ctr_drbg.c +1016 -0
  211. package/vendor/mbedtls/library/debug.c +475 -0
  212. package/vendor/mbedtls/library/debug_internal.h +185 -0
  213. package/vendor/mbedtls/library/des.c +1042 -0
  214. package/vendor/mbedtls/library/dhm.c +700 -0
  215. package/vendor/mbedtls/library/ecdh.c +696 -0
  216. package/vendor/mbedtls/library/ecdsa.c +858 -0
  217. package/vendor/mbedtls/library/ecjpake.c +1216 -0
  218. package/vendor/mbedtls/library/ecp.c +3674 -0
  219. package/vendor/mbedtls/library/ecp_curves.c +6125 -0
  220. package/vendor/mbedtls/library/ecp_curves_new.c +9 -0
  221. package/vendor/mbedtls/library/ecp_internal_alt.h +287 -0
  222. package/vendor/mbedtls/library/ecp_invasive.h +305 -0
  223. package/vendor/mbedtls/library/entropy.c +680 -0
  224. package/vendor/mbedtls/library/entropy_poll.c +233 -0
  225. package/vendor/mbedtls/library/entropy_poll.h +64 -0
  226. package/vendor/mbedtls/library/error.c +878 -0
  227. package/vendor/mbedtls/library/gcm.c +1330 -0
  228. package/vendor/mbedtls/library/hkdf.c +161 -0
  229. package/vendor/mbedtls/library/hmac_drbg.c +633 -0
  230. package/vendor/mbedtls/library/lmots.c +789 -0
  231. package/vendor/mbedtls/library/lmots.h +288 -0
  232. package/vendor/mbedtls/library/lms.c +778 -0
  233. package/vendor/mbedtls/library/md.c +1108 -0
  234. package/vendor/mbedtls/library/md5.c +426 -0
  235. package/vendor/mbedtls/library/md_psa.h +26 -0
  236. package/vendor/mbedtls/library/md_wrap.h +46 -0
  237. package/vendor/mbedtls/library/memory_buffer_alloc.c +751 -0
  238. package/vendor/mbedtls/library/mps_common.h +181 -0
  239. package/vendor/mbedtls/library/mps_error.h +89 -0
  240. package/vendor/mbedtls/library/mps_reader.c +538 -0
  241. package/vendor/mbedtls/library/mps_reader.h +366 -0
  242. package/vendor/mbedtls/library/mps_trace.c +112 -0
  243. package/vendor/mbedtls/library/mps_trace.h +154 -0
  244. package/vendor/mbedtls/library/net_sockets.c +694 -0
  245. package/vendor/mbedtls/library/nist_kw.c +729 -0
  246. package/vendor/mbedtls/library/oid.c +1166 -0
  247. package/vendor/mbedtls/library/padlock.c +157 -0
  248. package/vendor/mbedtls/library/padlock.h +111 -0
  249. package/vendor/mbedtls/library/pem.c +554 -0
  250. package/vendor/mbedtls/library/pk.c +1602 -0
  251. package/vendor/mbedtls/library/pk_ecc.c +261 -0
  252. package/vendor/mbedtls/library/pk_internal.h +241 -0
  253. package/vendor/mbedtls/library/pk_wrap.c +1618 -0
  254. package/vendor/mbedtls/library/pk_wrap.h +138 -0
  255. package/vendor/mbedtls/library/pkcs12.c +437 -0
  256. package/vendor/mbedtls/library/pkcs5.c +500 -0
  257. package/vendor/mbedtls/library/pkcs7.c +787 -0
  258. package/vendor/mbedtls/library/pkparse.c +1392 -0
  259. package/vendor/mbedtls/library/pkwrite.c +631 -0
  260. package/vendor/mbedtls/library/pkwrite.h +121 -0
  261. package/vendor/mbedtls/library/platform.c +402 -0
  262. package/vendor/mbedtls/library/platform_util.c +258 -0
  263. package/vendor/mbedtls/library/poly1305.c +492 -0
  264. package/vendor/mbedtls/library/psa_crypto.c +9532 -0
  265. package/vendor/mbedtls/library/psa_crypto_aead.c +646 -0
  266. package/vendor/mbedtls/library/psa_crypto_aead.h +499 -0
  267. package/vendor/mbedtls/library/psa_crypto_cipher.c +747 -0
  268. package/vendor/mbedtls/library/psa_crypto_cipher.h +316 -0
  269. package/vendor/mbedtls/library/psa_crypto_client.c +22 -0
  270. package/vendor/mbedtls/library/psa_crypto_core.h +983 -0
  271. package/vendor/mbedtls/library/psa_crypto_core_common.h +52 -0
  272. package/vendor/mbedtls/library/psa_crypto_driver_wrappers.h +2896 -0
  273. package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.c +256 -0
  274. package/vendor/mbedtls/library/psa_crypto_driver_wrappers_no_static.h +31 -0
  275. package/vendor/mbedtls/library/psa_crypto_ecp.c +594 -0
  276. package/vendor/mbedtls/library/psa_crypto_ecp.h +267 -0
  277. package/vendor/mbedtls/library/psa_crypto_ffdh.c +361 -0
  278. package/vendor/mbedtls/library/psa_crypto_ffdh.h +131 -0
  279. package/vendor/mbedtls/library/psa_crypto_hash.c +470 -0
  280. package/vendor/mbedtls/library/psa_crypto_hash.h +211 -0
  281. package/vendor/mbedtls/library/psa_crypto_invasive.h +92 -0
  282. package/vendor/mbedtls/library/psa_crypto_its.h +131 -0
  283. package/vendor/mbedtls/library/psa_crypto_mac.c +505 -0
  284. package/vendor/mbedtls/library/psa_crypto_mac.h +264 -0
  285. package/vendor/mbedtls/library/psa_crypto_pake.c +571 -0
  286. package/vendor/mbedtls/library/psa_crypto_pake.h +159 -0
  287. package/vendor/mbedtls/library/psa_crypto_random.c +181 -0
  288. package/vendor/mbedtls/library/psa_crypto_random.h +72 -0
  289. package/vendor/mbedtls/library/psa_crypto_random_impl.h +200 -0
  290. package/vendor/mbedtls/library/psa_crypto_rsa.c +714 -0
  291. package/vendor/mbedtls/library/psa_crypto_rsa.h +321 -0
  292. package/vendor/mbedtls/library/psa_crypto_se.c +373 -0
  293. package/vendor/mbedtls/library/psa_crypto_se.h +192 -0
  294. package/vendor/mbedtls/library/psa_crypto_slot_management.c +1137 -0
  295. package/vendor/mbedtls/library/psa_crypto_slot_management.h +344 -0
  296. package/vendor/mbedtls/library/psa_crypto_storage.c +481 -0
  297. package/vendor/mbedtls/library/psa_crypto_storage.h +392 -0
  298. package/vendor/mbedtls/library/psa_its_file.c +254 -0
  299. package/vendor/mbedtls/library/psa_util.c +614 -0
  300. package/vendor/mbedtls/library/psa_util_internal.h +100 -0
  301. package/vendor/mbedtls/library/ripemd160.c +490 -0
  302. package/vendor/mbedtls/library/rsa.c +3121 -0
  303. package/vendor/mbedtls/library/rsa_alt_helpers.c +455 -0
  304. package/vendor/mbedtls/library/rsa_alt_helpers.h +209 -0
  305. package/vendor/mbedtls/library/rsa_internal.h +188 -0
  306. package/vendor/mbedtls/library/sha1.c +480 -0
  307. package/vendor/mbedtls/library/sha256.c +983 -0
  308. package/vendor/mbedtls/library/sha3.c +721 -0
  309. package/vendor/mbedtls/library/sha512.c +1115 -0
  310. package/vendor/mbedtls/library/ssl_cache.c +410 -0
  311. package/vendor/mbedtls/library/ssl_ciphersuites.c +2050 -0
  312. package/vendor/mbedtls/library/ssl_ciphersuites_internal.h +154 -0
  313. package/vendor/mbedtls/library/ssl_client.c +1023 -0
  314. package/vendor/mbedtls/library/ssl_client.h +22 -0
  315. package/vendor/mbedtls/library/ssl_cookie.c +384 -0
  316. package/vendor/mbedtls/library/ssl_debug_helpers.h +85 -0
  317. package/vendor/mbedtls/library/ssl_debug_helpers_generated.c +251 -0
  318. package/vendor/mbedtls/library/ssl_misc.h +3198 -0
  319. package/vendor/mbedtls/library/ssl_msg.c +6619 -0
  320. package/vendor/mbedtls/library/ssl_ticket.c +556 -0
  321. package/vendor/mbedtls/library/ssl_tls.c +10234 -0
  322. package/vendor/mbedtls/library/ssl_tls12_client.c +3688 -0
  323. package/vendor/mbedtls/library/ssl_tls12_server.c +4311 -0
  324. package/vendor/mbedtls/library/ssl_tls13_client.c +3208 -0
  325. package/vendor/mbedtls/library/ssl_tls13_generic.c +1793 -0
  326. package/vendor/mbedtls/library/ssl_tls13_invasive.h +23 -0
  327. package/vendor/mbedtls/library/ssl_tls13_keys.c +1918 -0
  328. package/vendor/mbedtls/library/ssl_tls13_keys.h +668 -0
  329. package/vendor/mbedtls/library/ssl_tls13_server.c +3624 -0
  330. package/vendor/mbedtls/library/threading.c +193 -0
  331. package/vendor/mbedtls/library/threading_internal.h +28 -0
  332. package/vendor/mbedtls/library/timing.c +152 -0
  333. package/vendor/mbedtls/library/version.c +32 -0
  334. package/vendor/mbedtls/library/version_features.c +856 -0
  335. package/vendor/mbedtls/library/x509.c +1776 -0
  336. package/vendor/mbedtls/library/x509_create.c +570 -0
  337. package/vendor/mbedtls/library/x509_crl.c +708 -0
  338. package/vendor/mbedtls/library/x509_crt.c +3311 -0
  339. package/vendor/mbedtls/library/x509_csr.c +648 -0
  340. package/vendor/mbedtls/library/x509_internal.h +101 -0
  341. package/vendor/mbedtls/library/x509write.c +174 -0
  342. package/vendor/mbedtls/library/x509write_crt.c +688 -0
  343. package/vendor/mbedtls/library/x509write_csr.c +336 -0
  344. package/vendor/quickjs-ng/CMakeLists.txt +566 -0
  345. package/vendor/quickjs-ng/LICENSE +24 -0
  346. package/vendor/quickjs-ng/README.md +24 -0
  347. package/vendor/quickjs-ng/api-test.c +1195 -0
  348. package/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
  349. package/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
  350. package/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
  351. package/vendor/quickjs-ng/cutils.h +1998 -0
  352. package/vendor/quickjs-ng/dtoa.c +1619 -0
  353. package/vendor/quickjs-ng/dtoa.h +87 -0
  354. package/vendor/quickjs-ng/gen/function_source.c +81 -0
  355. package/vendor/quickjs-ng/gen/hello.c +53 -0
  356. package/vendor/quickjs-ng/gen/hello_module.c +106 -0
  357. package/vendor/quickjs-ng/gen/repl.c +3036 -0
  358. package/vendor/quickjs-ng/gen/standalone.c +323 -0
  359. package/vendor/quickjs-ng/gen/test_fib.c +81 -0
  360. package/vendor/quickjs-ng/libregexp-opcode.h +73 -0
  361. package/vendor/quickjs-ng/libregexp.c +3474 -0
  362. package/vendor/quickjs-ng/libregexp.h +101 -0
  363. package/vendor/quickjs-ng/libunicode-table.h +5173 -0
  364. package/vendor/quickjs-ng/libunicode.c +2069 -0
  365. package/vendor/quickjs-ng/libunicode.h +172 -0
  366. package/vendor/quickjs-ng/list.h +107 -0
  367. package/vendor/quickjs-ng/lre-test.c +52 -0
  368. package/vendor/quickjs-ng/qjs.c +762 -0
  369. package/vendor/quickjs-ng/qjsc.c +673 -0
  370. package/vendor/quickjs-ng/quickjs-atom.h +280 -0
  371. package/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
  372. package/vendor/quickjs-ng/quickjs-libc.c +5037 -0
  373. package/vendor/quickjs-ng/quickjs-libc.h +87 -0
  374. package/vendor/quickjs-ng/quickjs-opcode.h +377 -0
  375. package/vendor/quickjs-ng/quickjs.c +64041 -0
  376. package/vendor/quickjs-ng/quickjs.h +1447 -0
  377. package/vendor/quickjs-ng/run-test262.c +2374 -0
  378. package/vendor/quickjs-ng/unicode_gen.c +3121 -0
  379. package/vendor/quickjs-ng/unicode_gen_def.h +310 -0
  380. package/vendor/ryu/LICENSE-Boost +23 -0
  381. package/vendor/ryu/common.h +114 -0
  382. package/vendor/ryu/d2s.c +509 -0
  383. package/vendor/ryu/d2s_full_table.h +367 -0
  384. package/vendor/ryu/d2s_intrinsics.h +357 -0
  385. package/vendor/ryu/d2s_small_table.h +186 -0
  386. package/vendor/ryu/digit_table.h +35 -0
  387. package/vendor/ryu/ryu.h +46 -0
  388. package/vendor/zlib/LICENSE +22 -0
  389. package/vendor/zlib/adler32.c +164 -0
  390. package/vendor/zlib/compress.c +75 -0
  391. package/vendor/zlib/crc32.c +1049 -0
  392. package/vendor/zlib/crc32.h +9446 -0
  393. package/vendor/zlib/deflate.c +2139 -0
  394. package/vendor/zlib/deflate.h +377 -0
  395. package/vendor/zlib/gzclose.c +23 -0
  396. package/vendor/zlib/gzguts.h +214 -0
  397. package/vendor/zlib/gzlib.c +582 -0
  398. package/vendor/zlib/gzread.c +602 -0
  399. package/vendor/zlib/gzwrite.c +631 -0
  400. package/vendor/zlib/infback.c +628 -0
  401. package/vendor/zlib/inffast.c +320 -0
  402. package/vendor/zlib/inffast.h +11 -0
  403. package/vendor/zlib/inffixed.h +94 -0
  404. package/vendor/zlib/inflate.c +1526 -0
  405. package/vendor/zlib/inflate.h +126 -0
  406. package/vendor/zlib/inftrees.c +299 -0
  407. package/vendor/zlib/inftrees.h +62 -0
  408. package/vendor/zlib/trees.c +1117 -0
  409. package/vendor/zlib/trees.h +128 -0
  410. package/vendor/zlib/uncompr.c +85 -0
  411. package/vendor/zlib/zconf.h +543 -0
  412. package/vendor/zlib/zlib.h +1938 -0
  413. package/vendor/zlib/zutil.c +299 -0
  414. package/vendor/zlib/zutil.h +254 -0
  415. package/README.md +0 -3
  416. package/index.js +0 -2
@@ -0,0 +1,1425 @@
1
+ /* Typed arrays / Buffer: ONE runtime representation (ScrBytes — see the
2
+ * header contract). Element buffers own their storage outright: no views,
3
+ * no byteOffset, slice/subarray both copy. Coercions are JS-exact
4
+ * (ToUint8/ToUint32 modular truncation, double→float rounding); the
5
+ * encoding conversions (utf8 with WHATWG replacement, hex, base64) match
6
+ * Node byte-for-byte — the differential corpus holds them to it. */
7
+ #include "scr_runtime.h"
8
+
9
+ #include <math.h>
10
+ #include <stdio.h>
11
+ #include <stdlib.h>
12
+ #include <string.h>
13
+
14
+ #ifdef SCR_RC_AUDIT
15
+ static long scr_live_bytes = 0;
16
+ long scr_bytes_live_count(void) { return scr_live_bytes; }
17
+ #endif
18
+
19
+ static void scr_bytes_oom(void) {
20
+ fputs("scriptc: out of memory\n", stderr);
21
+ abort();
22
+ }
23
+
24
+ size_t scr_bytes_elem_size(ScrBytesElem elem) {
25
+ return elem == SCR_BYTES_U8 ? 1 : 4;
26
+ }
27
+
28
+ /* ── lifecycle ─────────────────────────────────────────────────────────── */
29
+
30
+ static ScrBytes *scr_bytes_alloc(ScrBytesElem elem, size_t len) {
31
+ ScrBytes *b = malloc(sizeof(ScrBytes));
32
+ if (!b) scr_bytes_oom();
33
+ b->rc = 1;
34
+ b->len = len;
35
+ b->elem = elem;
36
+ b->data = calloc(len ? len : 1, scr_bytes_elem_size(elem));
37
+ if (!b->data) scr_bytes_oom();
38
+ b->backing = NULL;
39
+ #ifdef SCR_RC_AUDIT
40
+ scr_live_bytes++;
41
+ #endif
42
+ return b;
43
+ }
44
+
45
+ ScrBytes *scr_bytes_new(ScrBytesElem elem, double n) {
46
+ /* ToIndex: NaN → 0, truncate toward zero; a negative or > 2^53-1 result
47
+ * throws Node's RangeError ("Invalid typed array length: -1"). A
48
+ * fractional 3.5 is length 3 — ToIndex never compares back. */
49
+ double t = (n != n) ? 0 : trunc(n);
50
+ if (!(t >= 0) || t > 9007199254740991.0 || t > (double)(SIZE_MAX / 8)) {
51
+ char num[32];
52
+ size_t numlen = scr_f64_to_str(t, num);
53
+ char msg[80];
54
+ int mlen = snprintf(msg, sizeof msg, "Invalid typed array length: %.*s",
55
+ (int)numlen, num);
56
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
57
+ return NULL;
58
+ }
59
+ return scr_bytes_alloc(elem, (size_t)t);
60
+ }
61
+
62
+ ScrBytes *scr_bytes_copy(const ScrBytes *src) {
63
+ ScrBytes *b = scr_bytes_alloc(src->elem, src->len);
64
+ memcpy(b->data, src->data, src->len * scr_bytes_elem_size(src->elem));
65
+ return b;
66
+ }
67
+
68
+ void scr_bytes_release(ScrBytes *b) {
69
+ if (!b || b->rc == SIZE_MAX) return; /* NULL: an uninitialized `let` local */
70
+ if (--b->rc == 0) {
71
+ if (b->backing) {
72
+ scr_bytes_release(b->backing); /* a view: data points into the owner */
73
+ } else {
74
+ free(b->data);
75
+ }
76
+ #ifdef SCR_RC_AUDIT
77
+ scr_live_bytes--;
78
+ #endif
79
+ free(b);
80
+ }
81
+ }
82
+
83
+ void *scr_bytes_retain_v(void *b) { return scr_bytes_retain((ScrBytes *)b); }
84
+ void scr_bytes_release_v(void *b) { scr_bytes_release((ScrBytes *)b); }
85
+
86
+ double scr_bytes_len(const ScrBytes *b) { return (double)b->len; }
87
+
88
+ double scr_bytes_byte_len(const ScrBytes *b) {
89
+ return (double)(b->len * scr_bytes_elem_size(b->elem));
90
+ }
91
+
92
+ /* ── element access ────────────────────────────────────────────────────
93
+ * JS reads undefined and IGNORES writes out of bounds on typed arrays;
94
+ * both are unrepresentable here, so any invalid index traps — the array
95
+ * runtime's exact discipline (SEMANTICS.md). */
96
+
97
+ static size_t scr_bytes_check_index(const ScrBytes *b, double i) {
98
+ if (!(i >= 0) || i != trunc(i) || i >= (double)b->len) {
99
+ char buf[32];
100
+ scr_f64_to_str(i, buf);
101
+ fprintf(stderr,
102
+ "scriptc: RangeError: typed array index %s out of bounds (length %zu)\n",
103
+ buf, b->len);
104
+ abort();
105
+ }
106
+ return (size_t)i;
107
+ }
108
+
109
+ /* ToUint32: NaN/±Infinity → 0, truncate toward zero, wrap mod 2^32.
110
+ * ToUint8 is its low byte (2^8 divides 2^32, so the residues agree). */
111
+ static uint32_t scr_bytes_to_u32(double v) {
112
+ if (v != v || isinf(v)) return 0;
113
+ double t = trunc(v);
114
+ t = fmod(t, 4294967296.0);
115
+ if (t < 0) t += 4294967296.0;
116
+ return (uint32_t)t;
117
+ }
118
+
119
+ double scr_bytes_get(const ScrBytes *b, double i) {
120
+ size_t idx = scr_bytes_check_index(b, i);
121
+ switch (b->elem) {
122
+ case SCR_BYTES_U8:
123
+ return (double)b->data[idx];
124
+ case SCR_BYTES_U32: {
125
+ uint32_t v;
126
+ memcpy(&v, b->data + idx * 4, 4);
127
+ return (double)v;
128
+ }
129
+ case SCR_BYTES_F32: {
130
+ float v;
131
+ memcpy(&v, b->data + idx * 4, 4);
132
+ return (double)v;
133
+ }
134
+ case SCR_BYTES_I32: {
135
+ int32_t v;
136
+ memcpy(&v, b->data + idx * 4, 4);
137
+ return (double)v;
138
+ }
139
+ }
140
+ return 0; /* unreachable */
141
+ }
142
+
143
+ void scr_bytes_set(ScrBytes *b, double i, double v) {
144
+ size_t idx = scr_bytes_check_index(b, i);
145
+ switch (b->elem) {
146
+ case SCR_BYTES_U8:
147
+ b->data[idx] = (uint8_t)scr_bytes_to_u32(v);
148
+ break;
149
+ case SCR_BYTES_U32: {
150
+ uint32_t u = scr_bytes_to_u32(v);
151
+ memcpy(b->data + idx * 4, &u, 4);
152
+ break;
153
+ }
154
+ case SCR_BYTES_F32: {
155
+ float f = (float)v; /* round-to-nearest-even, exactly Float32Array */
156
+ memcpy(b->data + idx * 4, &f, 4);
157
+ break;
158
+ }
159
+ case SCR_BYTES_I32: {
160
+ /* ToInt32 is ToUint32 reinterpreted signed (same 2^32 residue). */
161
+ uint32_t u = scr_bytes_to_u32(v);
162
+ int32_t s;
163
+ memcpy(&s, &u, 4);
164
+ memcpy(b->data + idx * 4, &s, 4);
165
+ break;
166
+ }
167
+ }
168
+ }
169
+
170
+ /* ── slice / subarray (both COPY) ──────────────────────────────────────── */
171
+
172
+ /* Relative index: ToIntegerOrInfinity, negatives from the end, clamped. */
173
+ static size_t scr_bytes_rel_index(double i, size_t len) {
174
+ if (i != i) return 0;
175
+ double t = trunc(i);
176
+ if (t < 0) t += (double)len;
177
+ if (t < 0) return 0;
178
+ if (t > (double)len) return len;
179
+ return (size_t)t;
180
+ }
181
+
182
+ ScrBytes *scr_bytes_slice(const ScrBytes *b, double start, double end) {
183
+ size_t s = scr_bytes_rel_index(start, b->len);
184
+ size_t e = scr_bytes_rel_index(end, b->len);
185
+ size_t count = e > s ? e - s : 0;
186
+ size_t esize = scr_bytes_elem_size(b->elem);
187
+ ScrBytes *out = scr_bytes_alloc(b->elem, count);
188
+ memcpy(out->data, b->data + s * esize, count * esize);
189
+ return out;
190
+ }
191
+
192
+ void scr_bytes_set_from(ScrBytes *dst, const ScrBytes *src, double offset) {
193
+ double t = (offset != offset) ? 0 : trunc(offset);
194
+ if (!(t >= 0) || (double)src->len + t > (double)dst->len) {
195
+ static const char msg[] = "offset is out of bounds";
196
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, sizeof msg - 1);
197
+ return;
198
+ }
199
+ size_t esize = scr_bytes_elem_size(dst->elem);
200
+ memmove(dst->data + (size_t)t * esize, src->data, src->len * esize);
201
+ }
202
+
203
+ /* ── DataView (the ONE view kind — see the header contract) ────────────── */
204
+
205
+ double scr_bytes_byte_offset(const ScrBytes *b) {
206
+ return b->backing ? (double)(size_t)(b->data - b->backing->data) : 0;
207
+ }
208
+
209
+ ScrBytes *scr_dataview_new(ScrBytes *src, double byte_off, bool has_len, double byte_len) {
210
+ /* `x.buffer` names the ONE buffer behind x — for a view src that is its
211
+ * owner's storage, so indices stay buffer-relative exactly like JS. */
212
+ ScrBytes *owner = src->backing ? src->backing : src;
213
+ double buf_bytes = (double)(owner->len * scr_bytes_elem_size(owner->elem));
214
+ /* ToIndex on the offset; every bad value takes Node's ONE message
215
+ * (negative, > 2^53-1, Infinity, and past-the-end alike). */
216
+ double off = (byte_off != byte_off) ? 0 : trunc(byte_off);
217
+ if (!(off >= 0) || off > 9007199254740991.0 || off > buf_bytes) {
218
+ char num[32];
219
+ size_t numlen = scr_f64_to_str(off, num);
220
+ char msg[96];
221
+ int mlen = snprintf(msg, sizeof msg, "Start offset %.*s is outside the bounds of the buffer",
222
+ (int)numlen, num);
223
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
224
+ return NULL;
225
+ }
226
+ double len;
227
+ if (has_len) {
228
+ len = (byte_len != byte_len) ? 0 : trunc(byte_len);
229
+ if (!(len >= 0) || len > 9007199254740991.0 || off + len > buf_bytes) {
230
+ char num[32];
231
+ size_t numlen = scr_f64_to_str(len, num);
232
+ char msg[64];
233
+ int mlen = snprintf(msg, sizeof msg, "Invalid DataView length %.*s", (int)numlen, num);
234
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
235
+ return NULL;
236
+ }
237
+ } else {
238
+ len = buf_bytes - off;
239
+ }
240
+ ScrBytes *v = malloc(sizeof(ScrBytes));
241
+ if (!v) scr_bytes_oom();
242
+ v->rc = 1;
243
+ v->len = (size_t)len; /* elem u8 — len IS the byte length */
244
+ v->elem = SCR_BYTES_U8;
245
+ v->data = owner->data + (size_t)off;
246
+ v->backing = scr_bytes_retain(owner);
247
+ #ifdef SCR_RC_AUDIT
248
+ scr_live_bytes++;
249
+ #endif
250
+ return v;
251
+ }
252
+
253
+ static size_t scr_dataview_get_size(ScrDataViewGet kind) {
254
+ switch (kind) {
255
+ case SCR_DV_U8:
256
+ case SCR_DV_I8:
257
+ return 1;
258
+ case SCR_DV_U16:
259
+ case SCR_DV_I16:
260
+ return 2;
261
+ case SCR_DV_U32:
262
+ case SCR_DV_I32:
263
+ case SCR_DV_F32:
264
+ return 4;
265
+ default:
266
+ return 8;
267
+ }
268
+ }
269
+
270
+ double scr_dataview_get(const ScrBytes *b, double byte_off, ScrDataViewGet kind, bool le) {
271
+ size_t width = scr_dataview_get_size(kind);
272
+ /* ToIndex, then the view-relative bounds check — Node's ONE constant
273
+ * message for every failure mode (negative, NaN is fine, too large). */
274
+ double off = (byte_off != byte_off) ? 0 : trunc(byte_off);
275
+ if (!(off >= 0) || off > 9007199254740991.0 || off + (double)width > (double)b->len) {
276
+ static const char msg[] = "Offset is outside the bounds of the DataView";
277
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, sizeof msg - 1);
278
+ return 0;
279
+ }
280
+ const uint8_t *p = b->data + (size_t)off;
281
+ /* Assemble host-independently; le false is the JS big-endian default. */
282
+ uint64_t u = 0;
283
+ for (size_t i = 0; i < width; i++) {
284
+ u |= (uint64_t)p[le ? i : width - 1 - i] << (8 * i);
285
+ }
286
+ switch (kind) {
287
+ case SCR_DV_U8:
288
+ case SCR_DV_U16:
289
+ case SCR_DV_U32:
290
+ return (double)u;
291
+ case SCR_DV_I8:
292
+ return (double)(int8_t)u;
293
+ case SCR_DV_I16:
294
+ return (double)(int16_t)u;
295
+ case SCR_DV_I32:
296
+ return (double)(int32_t)u;
297
+ case SCR_DV_F32: {
298
+ uint32_t bits = (uint32_t)u;
299
+ float f;
300
+ memcpy(&f, &bits, 4);
301
+ return (double)f;
302
+ }
303
+ case SCR_DV_F64: {
304
+ double d;
305
+ memcpy(&d, &u, 8);
306
+ return d;
307
+ }
308
+ case SCR_DV_BIGU64:
309
+ /* Number(view.getBigUint64(...)): u64 → double rounds to nearest
310
+ * even — the same conversion Number(bigint) performs. */
311
+ return (double)u;
312
+ case SCR_DV_BIGI64:
313
+ return (double)(int64_t)u;
314
+ }
315
+ return 0; /* unreachable */
316
+ }
317
+
318
+ /* ── encodings (u8 only — the compiler routes only u8 receivers here) ──── */
319
+
320
+ static const char scr_hex_digits[] = "0123456789abcdef";
321
+
322
+ /* WHATWG UTF-8 decode with U+FFFD replacement per maximal invalid subpart
323
+ * — what Buffer.prototype.toString("utf8") does. Output re-encodes as
324
+ * (now valid) UTF-8: worst case 3 bytes per input byte. */
325
+ static ScrStr *scr_bytes_decode_utf8(const uint8_t *in, size_t n) {
326
+ char *out = malloc(n * 3 + 1);
327
+ if (!out) scr_bytes_oom();
328
+ size_t o = 0;
329
+ uint32_t cp = 0;
330
+ int needed = 0;
331
+ uint8_t lower = 0x80, upper = 0xbf;
332
+ for (size_t i = 0; i <= n; i++) {
333
+ if (i == n) {
334
+ if (needed > 0) { /* EOF inside a sequence: one replacement */
335
+ memcpy(out + o, "\xef\xbf\xbd", 3);
336
+ o += 3;
337
+ }
338
+ break;
339
+ }
340
+ uint8_t byte = in[i];
341
+ if (needed == 0) {
342
+ if (byte <= 0x7f) {
343
+ out[o++] = (char)byte;
344
+ } else if (byte >= 0xc2 && byte <= 0xdf) {
345
+ needed = 1; cp = byte & 0x1f;
346
+ } else if (byte >= 0xe0 && byte <= 0xef) {
347
+ if (byte == 0xe0) lower = 0xa0;
348
+ if (byte == 0xed) upper = 0x9f;
349
+ needed = 2; cp = byte & 0xf;
350
+ } else if (byte >= 0xf0 && byte <= 0xf4) {
351
+ if (byte == 0xf0) lower = 0x90;
352
+ if (byte == 0xf4) upper = 0x8f;
353
+ needed = 3; cp = byte & 0x7;
354
+ } else {
355
+ memcpy(out + o, "\xef\xbf\xbd", 3);
356
+ o += 3;
357
+ }
358
+ continue;
359
+ }
360
+ if (byte < lower || byte > upper) {
361
+ /* Invalid continuation: replace the subpart, REPROCESS this byte. */
362
+ memcpy(out + o, "\xef\xbf\xbd", 3);
363
+ o += 3;
364
+ needed = 0; lower = 0x80; upper = 0xbf;
365
+ i--;
366
+ continue;
367
+ }
368
+ lower = 0x80; upper = 0xbf;
369
+ cp = (cp << 6) | (byte & 0x3f);
370
+ if (--needed == 0) {
371
+ /* Re-encode the (valid, non-surrogate, <= 10FFFF) code point. */
372
+ if (cp <= 0x7f) {
373
+ out[o++] = (char)cp;
374
+ } else if (cp <= 0x7ff) {
375
+ out[o++] = (char)(0xc0 | (cp >> 6));
376
+ out[o++] = (char)(0x80 | (cp & 0x3f));
377
+ } else if (cp <= 0xffff) {
378
+ out[o++] = (char)(0xe0 | (cp >> 12));
379
+ out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
380
+ out[o++] = (char)(0x80 | (cp & 0x3f));
381
+ } else {
382
+ out[o++] = (char)(0xf0 | (cp >> 18));
383
+ out[o++] = (char)(0x80 | ((cp >> 12) & 0x3f));
384
+ out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
385
+ out[o++] = (char)(0x80 | (cp & 0x3f));
386
+ }
387
+ }
388
+ }
389
+ ScrStr *s = scr_str_new(out, o);
390
+ free(out);
391
+ return s;
392
+ }
393
+
394
+ /* WHATWG TextDecoder.decode (utf-8, default options): the SAME maximal-
395
+ * subpart replacement decode as toString("utf8") above, with one
396
+ * difference — a leading UTF-8 BOM is stripped (ignoreBOM defaults to
397
+ * false in the spec; Buffer.toString keeps the BOM as U+FEFF). */
398
+ ScrStr *scr_text_decode(const ScrBytes *b) {
399
+ const uint8_t *in = b->data;
400
+ size_t n = b->len;
401
+ if (n >= 3 && in[0] == 0xef && in[1] == 0xbb && in[2] == 0xbf) {
402
+ in += 3;
403
+ n -= 3;
404
+ }
405
+ return scr_bytes_decode_utf8(in, n);
406
+ }
407
+
408
+ /* ── node:string_decoder, the utf8 StringDecoder ─────────────────────────
409
+ * The decoder VALUE is a one-field record holding the pending partial
410
+ * sequence PACKED into an f64 (count in the low byte, then up to three
411
+ * raw bytes — at most 3 pend, so 32 bits): the compiler's interned
412
+ * %strdec helpers thread it through these three pure functions. The
413
+ * algorithm is Node's utf8 StringDecoder pinned by oracle (corpus 1474):
414
+ * write() decodes pending+chunk minus the trailing INCOMPLETE sequence
415
+ * (the decode above — invalid bytes become U+FFFD immediately, only a
416
+ * truncated valid lead buffers), end() flushes the buffered partial as
417
+ * its replacement chars. */
418
+
419
+ /* Encoding helpers defined beside toString below (the strdec steps share
420
+ * them). */
421
+ static ScrStr *scr_bytes_encode_b64(const uint8_t *in, size_t n, bool url);
422
+ static ScrStr *scr_bytes_decode_utf16le(const uint8_t *in, size_t n);
423
+ static bool scr_enc_is(const ScrStr *enc, const char *name);
424
+
425
+ static size_t scr_strdec_unpack(double pending, uint8_t out[3]) {
426
+ uint32_t p = (uint32_t)pending;
427
+ size_t n = p & 0xff;
428
+ if (n > 3) n = 3;
429
+ out[0] = (uint8_t)((p >> 8) & 0xff);
430
+ out[1] = (uint8_t)((p >> 16) & 0xff);
431
+ out[2] = (uint8_t)((p >> 24) & 0xff);
432
+ return n;
433
+ }
434
+
435
+ static double scr_strdec_pack(const uint8_t *bytes, size_t n) {
436
+ uint32_t p = (uint32_t)n;
437
+ if (n > 0) p |= (uint32_t)bytes[0] << 8;
438
+ if (n > 1) p |= (uint32_t)bytes[1] << 16;
439
+ if (n > 2) p |= (uint32_t)bytes[2] << 24;
440
+ return (double)p;
441
+ }
442
+
443
+ /* Node's utf8CheckIncomplete over the COMBINED tail: the length (0-3) of
444
+ * a trailing truncated-but-valid sequence prefix. Bare continuations and
445
+ * invalid leads are NOT incomplete — they decode (to U+FFFD) now. */
446
+ static size_t scr_strdec_tail(const uint8_t *buf, size_t n) {
447
+ size_t scan = n < 3 ? n : 3;
448
+ for (size_t back = 1; back <= scan; back++) {
449
+ uint8_t b = buf[n - back];
450
+ if ((b & 0xc0) == 0x80) continue; /* continuation: keep walking */
451
+ size_t need = 0;
452
+ if ((b & 0xe0) == 0xc0) need = 2;
453
+ else if ((b & 0xf0) == 0xe0) need = 3;
454
+ else if ((b & 0xf8) == 0xf0) need = 4;
455
+ else return 0; /* ascii or invalid lead: nothing buffers */
456
+ return back < need ? back : 0; /* complete: decode now */
457
+ }
458
+ return 0; /* 3 continuations (or empty): invalid, decode now */
459
+ }
460
+
461
+ /* The combined pending+chunk buffer (malloc'd; *out_n set). */
462
+ static uint8_t *scr_strdec_combined(double pending, const ScrBytes *chunk, size_t *out_n) {
463
+ uint8_t pend[3];
464
+ size_t np = scr_strdec_unpack(pending, pend);
465
+ size_t n = np + chunk->len;
466
+ uint8_t *buf = malloc(n > 0 ? n : 1);
467
+ if (!buf) scr_bytes_oom();
468
+ memcpy(buf, pend, np);
469
+ memcpy(buf + np, chunk->data, chunk->len);
470
+ *out_n = n;
471
+ return buf;
472
+ }
473
+
474
+ /* The utf16le step, Node's utf16Text/fillLast: a pending partial fills
475
+ * first (an odd byte completes its unit; a held LEAD surrogate completes
476
+ * its pair — 4 bytes total), then the rest holds back an odd tail byte
477
+ * (with NO surrogate check — Node's own quirk emits a lead surrogate
478
+ * before an odd boundary) or a trailing lead surrogate's 2 bytes. The
479
+ * emitted bytes decode JOINTLY, so pair halves split across the fill
480
+ * boundary reassemble exactly like Node's string concatenation. */
481
+ static ScrStr *scr_strdec_u16(double pending, const ScrBytes *chunk, bool want_str, double *out_hold) {
482
+ uint8_t held[3];
483
+ size_t k = scr_strdec_unpack(pending, held);
484
+ const uint8_t *c = chunk->data;
485
+ size_t cn = chunk->len;
486
+ uint8_t complete[4];
487
+ size_t comp_n = 0;
488
+ if (k > 0) {
489
+ size_t total = k == 1 ? 2 : 4; /* 1 = odd byte; 2 or 3 = lead-surrogate hold */
490
+ size_t need = total - k;
491
+ if (cn < need) {
492
+ uint8_t nh[3];
493
+ memcpy(nh, held, k);
494
+ memcpy(nh + k, c, cn);
495
+ *out_hold = scr_strdec_pack(nh, k + cn);
496
+ return want_str ? scr_str_new("", 0) : NULL;
497
+ }
498
+ memcpy(complete, held, k);
499
+ memcpy(complete + k, c, need);
500
+ comp_n = total;
501
+ c += need;
502
+ cn -= need;
503
+ }
504
+ size_t keep = cn;
505
+ if (cn % 2 == 1) {
506
+ keep = cn - 1;
507
+ } else if (cn >= 2) {
508
+ uint32_t last = (uint32_t)c[cn - 2] | ((uint32_t)c[cn - 1] << 8);
509
+ if (last >= 0xd800 && last <= 0xdbff) keep = cn - 2;
510
+ }
511
+ *out_hold = scr_strdec_pack(c + keep, cn - keep);
512
+ if (!want_str) return NULL;
513
+ size_t n = comp_n + keep;
514
+ uint8_t *buf = malloc(n > 0 ? n : 1);
515
+ if (!buf) scr_bytes_oom();
516
+ memcpy(buf, complete, comp_n);
517
+ memcpy(buf + comp_n, c, keep);
518
+ ScrStr *s = scr_bytes_decode_utf16le(buf, n);
519
+ free(buf);
520
+ return s;
521
+ }
522
+
523
+ /* The base64/base64url step: complete 3-byte groups encode now, the
524
+ * 1-2-byte remainder buffers (the combined walk is Node's fillLast+text
525
+ * exactly — base64 of a concatenation splits at group boundaries). */
526
+ static ScrStr *scr_strdec_b64(double pending, const ScrBytes *chunk, bool url, bool want_str, double *out_hold) {
527
+ size_t n;
528
+ uint8_t *buf = scr_strdec_combined(pending, chunk, &n);
529
+ size_t tail = n % 3;
530
+ *out_hold = scr_strdec_pack(buf + (n - tail), tail);
531
+ ScrStr *s = want_str ? scr_bytes_encode_b64(buf, n - tail, url) : NULL;
532
+ free(buf);
533
+ return s;
534
+ }
535
+
536
+ /* One dispatcher computes the decoded string (when wanted) and the new
537
+ * packed pending for a write. latin1/ascii/hex are stateless (write IS
538
+ * toString); utf8 keeps the oracle-pinned combined walk. */
539
+ static ScrStr *scr_strdec_step(const ScrStr *enc, double pending, const ScrBytes *chunk,
540
+ bool want_str, double *out_hold) {
541
+ if (scr_enc_is(enc, "utf16le")) return scr_strdec_u16(pending, chunk, want_str, out_hold);
542
+ if (scr_enc_is(enc, "base64")) return scr_strdec_b64(pending, chunk, false, want_str, out_hold);
543
+ if (scr_enc_is(enc, "base64url")) return scr_strdec_b64(pending, chunk, true, want_str, out_hold);
544
+ if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii") || scr_enc_is(enc, "hex")) {
545
+ *out_hold = 0;
546
+ return want_str ? scr_bytes_to_str(chunk, enc) : NULL;
547
+ }
548
+ size_t n;
549
+ uint8_t *buf = scr_strdec_combined(pending, chunk, &n);
550
+ size_t tail = scr_strdec_tail(buf, n);
551
+ *out_hold = scr_strdec_pack(buf + (n - tail), tail);
552
+ ScrStr *s = want_str ? scr_bytes_decode_utf8(buf, n - tail) : NULL;
553
+ free(buf);
554
+ return s;
555
+ }
556
+
557
+ /* decoder.write(chunk): the decoded complete prefix (+1). */
558
+ ScrStr *scr_strdec_write(const ScrStr *enc, double pending, const ScrBytes *chunk) {
559
+ double hold;
560
+ return scr_strdec_step(enc, pending, chunk, true, &hold);
561
+ }
562
+
563
+ /* The decoder state AFTER a write: the packed trailing partial sequence. */
564
+ double scr_strdec_next(const ScrStr *enc, double pending, const ScrBytes *chunk) {
565
+ double hold = 0;
566
+ scr_strdec_step(enc, pending, chunk, false, &hold);
567
+ return hold;
568
+ }
569
+
570
+ /* decoder.end(): the buffered partial flushes — utf8's truncated sequence
571
+ * becomes its replacement chars (the maximal-subpart rule), base64's
572
+ * remainder encodes (padded; unpadded for base64url), utf16le's held
573
+ * bytes decode as they stand (an odd byte drops; a held lead surrogate is
574
+ * the documented U+FFFD divergence), and the stateless encodings flush
575
+ * nothing. +1. */
576
+ ScrStr *scr_strdec_end(const ScrStr *enc, double pending) {
577
+ uint8_t pend[3];
578
+ size_t np = scr_strdec_unpack(pending, pend);
579
+ if (scr_enc_is(enc, "base64")) return scr_bytes_encode_b64(pend, np, false);
580
+ if (scr_enc_is(enc, "base64url")) return scr_bytes_encode_b64(pend, np, true);
581
+ if (scr_enc_is(enc, "utf16le")) return scr_bytes_decode_utf16le(pend, np);
582
+ if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii") || scr_enc_is(enc, "hex")) {
583
+ return scr_str_new("", 0);
584
+ }
585
+ return scr_bytes_decode_utf8(pend, np);
586
+ }
587
+
588
+ /* toString(enc, start, end): Node slices then decodes — start/end clamp
589
+ * to [0, len] with start > end collapsing to empty and negative ends
590
+ * clamping to 0 (Node's slice-then-decode; an OMITTED end never reaches
591
+ * here — the emitter supplies the receiver's length for the 2-arg
592
+ * form). Delegates to the whole-buffer decoder
593
+ * through a stack view — no allocation, no rc traffic. */
594
+ ScrStr *scr_bytes_to_str_range(const ScrBytes *b, const ScrStr *enc, double start, double end) {
595
+ size_t len = b->len;
596
+ size_t s0 = start <= 0 ? 0 : ((size_t)start > len ? len : (size_t)start);
597
+ size_t e0 = end <= 0 ? 0 : ((size_t)end > len ? len : (size_t)end);
598
+ if (e0 < s0) e0 = s0;
599
+ ScrBytes view = { .rc = 1, .len = e0 - s0, .elem = b->elem, .data = b->data + s0, .backing = NULL };
600
+ return scr_bytes_to_str(&view, enc);
601
+ }
602
+
603
+ /* The base64 encoder behind toString("base64") and toString("base64url"):
604
+ * the url flavor swaps the alphabet's last two chars for -_ and drops the
605
+ * padding, exactly Node. */
606
+ static ScrStr *scr_bytes_encode_b64(const uint8_t *in, size_t n, bool url) {
607
+ static const char std_abc[] =
608
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
609
+ static const char url_abc[] =
610
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
611
+ const char *abc = url ? url_abc : std_abc;
612
+ size_t outlen = (n + 2) / 3 * 4;
613
+ char *out = malloc(outlen + 1);
614
+ if (!out) scr_bytes_oom();
615
+ size_t o = 0;
616
+ for (size_t i = 0; i < n; i += 3) {
617
+ unsigned v = (unsigned)in[i] << 16;
618
+ if (i + 1 < n) v |= (unsigned)in[i + 1] << 8;
619
+ if (i + 2 < n) v |= (unsigned)in[i + 2];
620
+ out[o++] = abc[(v >> 18) & 63];
621
+ out[o++] = abc[(v >> 12) & 63];
622
+ if (i + 1 < n) out[o++] = abc[(v >> 6) & 63];
623
+ else if (!url) out[o++] = '=';
624
+ if (i + 2 < n) out[o++] = abc[v & 63];
625
+ else if (!url) out[o++] = '=';
626
+ }
627
+ ScrStr *s = scr_str_new(out, o);
628
+ free(out);
629
+ return s;
630
+ }
631
+
632
+ /* Append one code point as UTF-8 (the caller sized the buffer). */
633
+ static size_t scr_bytes_put_cp(char *out, size_t o, uint32_t cp) {
634
+ if (cp <= 0x7f) {
635
+ out[o++] = (char)cp;
636
+ } else if (cp <= 0x7ff) {
637
+ out[o++] = (char)(0xc0 | (cp >> 6));
638
+ out[o++] = (char)(0x80 | (cp & 0x3f));
639
+ } else if (cp <= 0xffff) {
640
+ out[o++] = (char)(0xe0 | (cp >> 12));
641
+ out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
642
+ out[o++] = (char)(0x80 | (cp & 0x3f));
643
+ } else {
644
+ out[o++] = (char)(0xf0 | (cp >> 18));
645
+ out[o++] = (char)(0x80 | ((cp >> 12) & 0x3f));
646
+ out[o++] = (char)(0x80 | ((cp >> 6) & 0x3f));
647
+ out[o++] = (char)(0x80 | (cp & 0x3f));
648
+ }
649
+ return o;
650
+ }
651
+
652
+ /* Decode the next code point from an ScrStr's storage — ALWAYS valid
653
+ * UTF-8 (the string runtime never stores ill-formed sequences), so no
654
+ * validation re-runs here. */
655
+ static uint32_t scr_bytes_next_cp(const uint8_t *in, size_t *ip) {
656
+ uint8_t b = in[*ip];
657
+ if (b < 0x80) {
658
+ *ip += 1;
659
+ return b;
660
+ }
661
+ if ((b & 0xe0) == 0xc0) {
662
+ uint32_t cp = ((uint32_t)(b & 0x1f) << 6) | (in[*ip + 1] & 0x3f);
663
+ *ip += 2;
664
+ return cp;
665
+ }
666
+ if ((b & 0xf0) == 0xe0) {
667
+ uint32_t cp = ((uint32_t)(b & 0xf) << 12) | ((uint32_t)(in[*ip + 1] & 0x3f) << 6) |
668
+ (in[*ip + 2] & 0x3f);
669
+ *ip += 3;
670
+ return cp;
671
+ }
672
+ uint32_t cp = ((uint32_t)(b & 0x7) << 18) | ((uint32_t)(in[*ip + 1] & 0x3f) << 12) |
673
+ ((uint32_t)(in[*ip + 2] & 0x3f) << 6) | (in[*ip + 3] & 0x3f);
674
+ *ip += 4;
675
+ return cp;
676
+ }
677
+
678
+ static bool scr_enc_is(const ScrStr *enc, const char *name) {
679
+ size_t n = strlen(name);
680
+ return enc->len == n && memcmp(enc->data, name, n) == 0;
681
+ }
682
+
683
+ /* toString("utf16le"): LE code-unit pairs (an odd tail byte drops, like
684
+ * Node). Valid surrogate pairs combine into their code point; a LONE
685
+ * surrogate becomes U+FFFD — Node keeps it as a lone UTF-16 unit, which
686
+ * UTF-8 string storage cannot hold (SEMANTICS.md divergence; stdout
687
+ * agrees byte-for-byte because Node's own write replaces it there too). */
688
+ static ScrStr *scr_bytes_decode_utf16le(const uint8_t *in, size_t n) {
689
+ size_t units = n / 2;
690
+ char *out = malloc(units * 3 + 2);
691
+ if (!out) scr_bytes_oom();
692
+ size_t o = 0;
693
+ for (size_t u = 0; u < units; u++) {
694
+ uint32_t cu = (uint32_t)in[u * 2] | ((uint32_t)in[u * 2 + 1] << 8);
695
+ if (cu >= 0xd800 && cu <= 0xdbff && u + 1 < units) {
696
+ uint32_t lo = (uint32_t)in[(u + 1) * 2] | ((uint32_t)in[(u + 1) * 2 + 1] << 8);
697
+ if (lo >= 0xdc00 && lo <= 0xdfff) {
698
+ o = scr_bytes_put_cp(out, o, 0x10000 + ((cu - 0xd800) << 10) + (lo - 0xdc00));
699
+ u++;
700
+ continue;
701
+ }
702
+ }
703
+ o = scr_bytes_put_cp(out, o, cu >= 0xd800 && cu <= 0xdfff ? 0xfffd : cu);
704
+ }
705
+ ScrStr *s = scr_str_new(out, o);
706
+ free(out);
707
+ return s;
708
+ }
709
+
710
+ ScrStr *scr_bytes_to_str(const ScrBytes *b, const ScrStr *enc) {
711
+ const uint8_t *in = b->data;
712
+ size_t n = b->len; /* u8: len == byte length */
713
+ if (scr_enc_is(enc, "hex")) {
714
+ char *out = malloc(n * 2 + 1);
715
+ if (!out) scr_bytes_oom();
716
+ for (size_t i = 0; i < n; i++) {
717
+ out[i * 2] = scr_hex_digits[in[i] >> 4];
718
+ out[i * 2 + 1] = scr_hex_digits[in[i] & 0xf];
719
+ }
720
+ ScrStr *s = scr_str_new(out, n * 2);
721
+ free(out);
722
+ return s;
723
+ }
724
+ if (scr_enc_is(enc, "base64")) return scr_bytes_encode_b64(in, n, false);
725
+ if (scr_enc_is(enc, "base64url")) return scr_bytes_encode_b64(in, n, true);
726
+ if (scr_enc_is(enc, "latin1")) {
727
+ /* Each byte is U+00XX ("binary" normalizes here upstream). */
728
+ char *out = malloc(n * 2 + 1);
729
+ if (!out) scr_bytes_oom();
730
+ size_t o = 0;
731
+ for (size_t i = 0; i < n; i++) o = scr_bytes_put_cp(out, o, in[i]);
732
+ ScrStr *s = scr_str_new(out, o);
733
+ free(out);
734
+ return s;
735
+ }
736
+ if (scr_enc_is(enc, "ascii")) {
737
+ /* Node's ascii decode masks the high bit: byte & 0x7f. */
738
+ char *out = malloc(n + 1);
739
+ if (!out) scr_bytes_oom();
740
+ for (size_t i = 0; i < n; i++) out[i] = (char)(in[i] & 0x7f);
741
+ ScrStr *s = scr_str_new(out, n);
742
+ free(out);
743
+ return s;
744
+ }
745
+ if (scr_enc_is(enc, "utf16le")) return scr_bytes_decode_utf16le(in, n);
746
+ /* utf8 (the compiler completes an omitted encoding to "utf8") */
747
+ return scr_bytes_decode_utf8(in, n);
748
+ }
749
+
750
+ static int scr_hex_val(uint8_t c) {
751
+ if (c >= '0' && c <= '9') return c - '0';
752
+ if (c >= 'a' && c <= 'f') return c - 'a' + 10;
753
+ if (c >= 'A' && c <= 'F') return c - 'A' + 10;
754
+ return -1;
755
+ }
756
+
757
+ static int scr_b64_val(uint8_t c) {
758
+ if (c >= 'A' && c <= 'Z') return c - 'A';
759
+ if (c >= 'a' && c <= 'z') return c - 'a' + 26;
760
+ if (c >= '0' && c <= '9') return c - '0' + 52;
761
+ if (c == '+' || c == '-') return 62; /* '-': base64url, accepted like Node */
762
+ if (c == '/' || c == '_') return 63; /* '_': base64url */
763
+ return -1;
764
+ }
765
+
766
+ ScrBytes *scr_bytes_from_str(const ScrStr *s, const ScrStr *enc) {
767
+ const uint8_t *in = (const uint8_t *)s->data;
768
+ size_t n = s->len;
769
+ if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii")) {
770
+ /* Node writes charCodeAt(i) & 0xFF for BOTH spellings — an astral
771
+ * code point contributes its two surrogates' low bytes. */
772
+ ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n);
773
+ size_t o = 0, i = 0;
774
+ while (i < n) {
775
+ uint32_t cp = scr_bytes_next_cp(in, &i);
776
+ if (cp > 0xffff) {
777
+ cp -= 0x10000;
778
+ b->data[o++] = (uint8_t)(0xd800 + (cp >> 10));
779
+ b->data[o++] = (uint8_t)(0xdc00 + (cp & 0x3ff));
780
+ } else {
781
+ b->data[o++] = (uint8_t)cp;
782
+ }
783
+ }
784
+ b->len = o; /* never grows past n: multi-byte cps shrink */
785
+ return b;
786
+ }
787
+ if (scr_enc_is(enc, "utf16le")) {
788
+ ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n * 2);
789
+ size_t o = 0, i = 0;
790
+ while (i < n) {
791
+ uint32_t cp = scr_bytes_next_cp(in, &i);
792
+ if (cp > 0xffff) {
793
+ cp -= 0x10000;
794
+ uint32_t hi = 0xd800 + (cp >> 10), lo = 0xdc00 + (cp & 0x3ff);
795
+ b->data[o++] = (uint8_t)hi;
796
+ b->data[o++] = (uint8_t)(hi >> 8);
797
+ b->data[o++] = (uint8_t)lo;
798
+ b->data[o++] = (uint8_t)(lo >> 8);
799
+ } else {
800
+ b->data[o++] = (uint8_t)cp;
801
+ b->data[o++] = (uint8_t)(cp >> 8);
802
+ }
803
+ }
804
+ b->len = o;
805
+ return b;
806
+ }
807
+ if (enc->len == 3 && memcmp(enc->data, "hex", 3) == 0) {
808
+ /* Node-lenient: parse pairs, stop at the first invalid pair or the
809
+ * odd tail (Buffer.from("a1g2", "hex") is <Buffer a1>). */
810
+ ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n / 2);
811
+ size_t o = 0;
812
+ for (size_t i = 0; i + 1 < n; i += 2) {
813
+ int hi = scr_hex_val(in[i]);
814
+ int lo = scr_hex_val(in[i + 1]);
815
+ if (hi < 0 || lo < 0) break;
816
+ b->data[o++] = (uint8_t)((hi << 4) | lo);
817
+ }
818
+ b->len = o; /* never grows: shrinking the count is safe */
819
+ return b;
820
+ }
821
+ if (scr_enc_is(enc, "base64") || scr_enc_is(enc, "base64url")) {
822
+ /* Node-lenient: skip bytes outside the (standard + url-safe)
823
+ * alphabets — whitespace, '=', stray punctuation; decode 4-char
824
+ * groups, and a 2/3-char tail into 1/2 bytes. Both spellings share
825
+ * the decoder (Node accepts either alphabet under either name). */
826
+ ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n / 4 * 3 + 2);
827
+ size_t o = 0;
828
+ unsigned acc = 0;
829
+ int have = 0;
830
+ for (size_t i = 0; i < n; i++) {
831
+ int v = scr_b64_val(in[i]);
832
+ if (v < 0) continue;
833
+ acc = (acc << 6) | (unsigned)v;
834
+ if (++have == 4) {
835
+ b->data[o++] = (uint8_t)(acc >> 16);
836
+ b->data[o++] = (uint8_t)(acc >> 8);
837
+ b->data[o++] = (uint8_t)acc;
838
+ acc = 0;
839
+ have = 0;
840
+ }
841
+ }
842
+ if (have == 2) b->data[o++] = (uint8_t)(acc >> 4);
843
+ else if (have == 3) {
844
+ b->data[o++] = (uint8_t)(acc >> 10);
845
+ b->data[o++] = (uint8_t)(acc >> 2);
846
+ }
847
+ b->len = o;
848
+ return b;
849
+ }
850
+ /* utf8: ScrStr storage IS the bytes */
851
+ ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, n);
852
+ memcpy(b->data, in, n);
853
+ return b;
854
+ }
855
+
856
+ ScrBytes *scr_bytes_from_arr(ScrBytesElem elem, const ScrArr *arr) {
857
+ ScrBytes *b = scr_bytes_alloc(elem, arr->len);
858
+ for (size_t i = 0; i < arr->len; i++) {
859
+ double v;
860
+ memcpy(&v, &arr->data[i], sizeof v); /* SCR_ELEM_F64 slots hold doubles */
861
+ switch (elem) {
862
+ case SCR_BYTES_U8:
863
+ b->data[i] = (uint8_t)scr_bytes_to_u32(v);
864
+ break;
865
+ case SCR_BYTES_U32: {
866
+ uint32_t u = scr_bytes_to_u32(v);
867
+ memcpy(b->data + i * 4, &u, 4);
868
+ break;
869
+ }
870
+ case SCR_BYTES_F32: {
871
+ float f = (float)v;
872
+ memcpy(b->data + i * 4, &f, 4);
873
+ break;
874
+ }
875
+ case SCR_BYTES_I32: {
876
+ uint32_t u = scr_bytes_to_u32(v);
877
+ memcpy(b->data + i * 4, &u, 4); /* same residue reinterpreted */
878
+ break;
879
+ }
880
+ }
881
+ }
882
+ return b;
883
+ }
884
+
885
+ /* ── equals / compare / indexOf / fill / copy / swap / write (u8; the
886
+ * error ladders mirror Node's validateOffset — 'an integer' first, then
887
+ * the '>= 0 && <= max' render, ERR_OUT_OF_RANGE's Received rules — and
888
+ * copy's C++-side ladder; pinned by corpus 1663) ─────────────────────── */
889
+
890
+ static size_t scr_bytes_received(double v, char out[48]); /* the numeric section below */
891
+
892
+ /* validateOffset(name, 0, max): non-integers are 'an integer', the rest
893
+ * '>= 0 && <= max' (Node spells '&&' here, unlike the read/write
894
+ * families' 'and'). max < 0 means copy's no-upper-bound '>= 0' render. */
895
+ static bool scr_bytes_validate_off(const char *name, double value, double max) {
896
+ if (floor(value) == value && value >= 0 && (max < 0 || value <= max)) return true;
897
+ char recv[48];
898
+ scr_bytes_received(value, recv);
899
+ char msg[160];
900
+ int mlen;
901
+ if (floor(value) != value) {
902
+ mlen = snprintf(msg, sizeof msg,
903
+ "The value of \"%s\" is out of range. It must be an integer. Received %s",
904
+ name, recv);
905
+ } else if (max < 0) {
906
+ mlen = snprintf(msg, sizeof msg,
907
+ "The value of \"%s\" is out of range. It must be >= 0. Received %s", name, recv);
908
+ } else {
909
+ char maxb[32];
910
+ scr_f64_to_str(max, maxb);
911
+ mlen = snprintf(msg, sizeof msg,
912
+ "The value of \"%s\" is out of range. It must be >= 0 && <= %s. Received %s",
913
+ name, maxb, recv);
914
+ }
915
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
916
+ return false;
917
+ }
918
+
919
+ bool scr_bytes_equals(const ScrBytes *a, const ScrBytes *b) {
920
+ return a->len == b->len && memcmp(a->data, b->data, a->len) == 0;
921
+ }
922
+
923
+ /* src.compare(target, targetStart?, targetEnd?, sourceStart?, sourceEnd?)
924
+ * — nargs counts the PRESENT index args (defaults skip validation, like
925
+ * Node). Empty-range shortcuts and the memcmp-with-length-tiebreak are
926
+ * Node's exactly. */
927
+ double scr_bytes_compare(const ScrBytes *src, const ScrBytes *target, double nargs,
928
+ double ts, double te, double ss, double se) {
929
+ size_t n = (size_t)nargs;
930
+ if (n < 1) ts = 0;
931
+ else if (!scr_bytes_validate_off("targetStart", ts, 9007199254740991.0)) return 0;
932
+ if (n < 2) te = (double)target->len;
933
+ else if (!scr_bytes_validate_off("targetEnd", te, (double)target->len)) return 0;
934
+ if (n < 3) ss = 0;
935
+ else if (!scr_bytes_validate_off("sourceStart", ss, 9007199254740991.0)) return 0;
936
+ if (n < 4) se = (double)src->len;
937
+ else if (!scr_bytes_validate_off("sourceEnd", se, (double)src->len)) return 0;
938
+ if (ts >= te) return ss >= se ? 0 : 1;
939
+ if (ss >= se) return -1;
940
+ /* Clamp the starts into range (a start past the length reads empty —
941
+ * handled above; here both windows are non-empty). */
942
+ size_t t0 = ts > (double)target->len ? target->len : (size_t)ts;
943
+ size_t s0 = ss > (double)src->len ? src->len : (size_t)ss;
944
+ size_t tn = (size_t)te - t0, sn = (size_t)se - s0;
945
+ size_t m = sn < tn ? sn : tn;
946
+ int c = memcmp(src->data + s0, target->data + t0, m);
947
+ if (c != 0) return c < 0 ? -1 : 1;
948
+ if (sn == tn) return 0;
949
+ return sn < tn ? -1 : 1;
950
+ }
951
+
952
+ /* The shared search core: needle bytes, a coerced byteOffset (trunc; NaN
953
+ * means 'search everything' — 0 forward, the end backward; negatives
954
+ * count from the end, and a still-negative backward search answers -1),
955
+ * and the utf16le alignment stride. */
956
+ double scr_bytes_index_of(const ScrBytes *b, const ScrBytes *needle, double off, double align, bool fwd) {
957
+ size_t len = b->len, nlen = needle->len;
958
+ size_t step = align == 2 ? 2 : 1;
959
+ double o = (off != off) ? (fwd ? 0 : (double)len) : trunc(off);
960
+ if (o < 0) {
961
+ o += (double)len;
962
+ if (o < 0) {
963
+ if (!fwd) return -1;
964
+ o = 0;
965
+ }
966
+ }
967
+ if (nlen == 0) return o > (double)len ? (double)len : o; /* '' matches at the clamp */
968
+ if (nlen > len) return -1;
969
+ if (fwd) {
970
+ size_t start = o > (double)len ? len : (size_t)o;
971
+ if (step == 2) start += start % 2;
972
+ for (size_t i = start; i + nlen <= len; i += step) {
973
+ if (memcmp(b->data + i, needle->data, nlen) == 0) return (double)i;
974
+ }
975
+ return -1;
976
+ }
977
+ size_t start = o > (double)(len - nlen) ? len - nlen : (size_t)o;
978
+ if (step == 2) start -= start % 2;
979
+ for (size_t i = start;; i -= step) {
980
+ if (memcmp(b->data + i, needle->data, nlen) == 0) return (double)i;
981
+ if (i < step) break;
982
+ }
983
+ return -1;
984
+ }
985
+
986
+ double scr_bytes_index_of_num(const ScrBytes *b, double v, double off, bool fwd) {
987
+ uint8_t byte = (uint8_t)scr_bytes_to_u32(v);
988
+ ScrBytes needle = { .rc = 1, .len = 1, .elem = SCR_BYTES_U8, .data = &byte, .backing = NULL };
989
+ return scr_bytes_index_of(b, &needle, off, 1, fwd);
990
+ }
991
+
992
+ /* fill's shared core over a normalized byte pattern. nargs counts the
993
+ * present offset/end args. An EMPTY pattern zero-fills when zero_ok
994
+ * (Node's '' string) and is the constant TypeError otherwise (an empty
995
+ * Uint8Array value). Returns the receiver (+1) — fill chains. */
996
+ static ScrBytes *scr_bytes_fill_core(ScrBytes *b, const uint8_t *pat, size_t patn,
997
+ bool zero_ok, double nargs, double offset, double end) {
998
+ if (patn == 0 && !zero_ok) {
999
+ static const char msg[] = "The argument 'value' is invalid. Received <Buffer >";
1000
+ scr_throw_error_msg(SCR_ERR_TYPE, msg, sizeof msg - 1);
1001
+ return NULL;
1002
+ }
1003
+ size_t n = (size_t)nargs;
1004
+ if (n < 1) offset = 0;
1005
+ else if (!scr_bytes_validate_off("offset", offset, 9007199254740991.0)) return NULL;
1006
+ if (n < 2) end = (double)b->len;
1007
+ else if (!scr_bytes_validate_off("end", end, (double)b->len)) return NULL;
1008
+ if (offset < end) {
1009
+ size_t o = (size_t)offset > b->len ? b->len : (size_t)offset;
1010
+ size_t e = (size_t)end;
1011
+ if (patn == 0) {
1012
+ memset(b->data + o, 0, e - o);
1013
+ } else if (patn == 1) {
1014
+ memset(b->data + o, pat[0], e - o);
1015
+ } else {
1016
+ for (size_t i = o; i < e; i++) b->data[i] = pat[(i - o) % patn];
1017
+ }
1018
+ }
1019
+ return scr_bytes_retain(b);
1020
+ }
1021
+
1022
+ ScrBytes *scr_bytes_fill(ScrBytes *b, const ScrBytes *pattern, double nargs, double offset, double end) {
1023
+ return scr_bytes_fill_core(b, pattern->data, pattern->len, false, nargs, offset, end);
1024
+ }
1025
+
1026
+ ScrBytes *scr_bytes_fill_num(ScrBytes *b, double v, double nargs, double offset, double end) {
1027
+ uint8_t byte = (uint8_t)scr_bytes_to_u32(v);
1028
+ return scr_bytes_fill_core(b, &byte, 1, false, nargs, offset, end);
1029
+ }
1030
+
1031
+ ScrBytes *scr_bytes_fill_str(ScrBytes *b, const ScrStr *s, const ScrStr *enc,
1032
+ double nargs, double offset, double end) {
1033
+ ScrBytes *pat = scr_bytes_from_str(s, enc);
1034
+ ScrBytes *r = scr_bytes_fill_core(b, pat->data, pat->len, true, nargs, offset, end);
1035
+ scr_bytes_release(pat);
1036
+ return r;
1037
+ }
1038
+
1039
+ /* src.copy(dst, targetStart?, sourceStart?, sourceEnd?): Node's C++-side
1040
+ * ladder — fractional indices TRUNCATE silently, targetStart/sourceEnd
1041
+ * check only >= 0 (past-the-end clamps to nothing), sourceStart is
1042
+ * bounded by the source length. Returns the byte count copied. */
1043
+ double scr_bytes_copy_into(const ScrBytes *src, ScrBytes *dst, double nargs,
1044
+ double ts, double ss, double se) {
1045
+ size_t n = (size_t)nargs;
1046
+ ts = n < 1 ? 0 : trunc(ts);
1047
+ ss = n < 2 ? 0 : trunc(ss);
1048
+ se = n < 3 ? (double)src->len : trunc(se);
1049
+ if (!scr_bytes_validate_off("targetStart", ts, -1)) return 0;
1050
+ if (!scr_bytes_validate_off("sourceStart", ss, (double)src->len)) return 0;
1051
+ if (!scr_bytes_validate_off("sourceEnd", se, -1)) return 0;
1052
+ if (ts >= (double)dst->len) return 0;
1053
+ size_t t0 = (size_t)ts;
1054
+ size_t s0 = (size_t)ss;
1055
+ size_t e0 = se > (double)src->len ? src->len : (size_t)se;
1056
+ if (s0 >= e0) return 0;
1057
+ size_t count = e0 - s0;
1058
+ if (count > dst->len - t0) count = dst->len - t0;
1059
+ memmove(dst->data + t0, src->data + s0, count);
1060
+ return (double)count;
1061
+ }
1062
+
1063
+ /* swap16/32/64: in-place byte reversal per group; the receiver answers
1064
+ * (+1, chaining like fill). A length off the width is Node's constant
1065
+ * ERR_INVALID_BUFFER_SIZE RangeError. */
1066
+ ScrBytes *scr_bytes_swap(ScrBytes *b, double width) {
1067
+ size_t w = (size_t)width;
1068
+ if (b->len % w != 0) {
1069
+ char msg[64];
1070
+ int mlen = snprintf(msg, sizeof msg, "Buffer size must be a multiple of %zu-bits", w * 8);
1071
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
1072
+ return NULL;
1073
+ }
1074
+ for (size_t g = 0; g < b->len; g += w) {
1075
+ for (size_t i = 0; i < w / 2; i++) {
1076
+ uint8_t t = b->data[g + i];
1077
+ b->data[g + i] = b->data[g + w - 1 - i];
1078
+ b->data[g + w - 1 - i] = t;
1079
+ }
1080
+ }
1081
+ return scr_bytes_retain(b);
1082
+ }
1083
+
1084
+ /* buf.write(string, offset?, length?, enc): encodes, clamps the byte
1085
+ * budget (offset and an explicit length validate against the buffer
1086
+ * length with Node's '&&' render; the length then clamps to the space
1087
+ * left), and truncates at a UNIT boundary — whole UTF-8 code points,
1088
+ * whole utf16le code units (a surrogate pair CAN split — Node writes the
1089
+ * lone lead), byte-level for the rest. Returns the bytes written. */
1090
+ double scr_bytes_write_str(ScrBytes *b, const ScrStr *s, const ScrStr *enc,
1091
+ double offset, double len, bool has_len) {
1092
+ if (!scr_bytes_validate_off("offset", offset, (double)b->len)) return 0;
1093
+ size_t o = (size_t)offset;
1094
+ size_t remaining = b->len - o;
1095
+ size_t budget;
1096
+ if (has_len) {
1097
+ if (!scr_bytes_validate_off("length", len, (double)b->len)) return 0;
1098
+ budget = (size_t)len > remaining ? remaining : (size_t)len;
1099
+ } else {
1100
+ budget = remaining;
1101
+ }
1102
+ ScrBytes *encd = scr_bytes_from_str(s, enc);
1103
+ size_t k = encd->len < budget ? encd->len : budget;
1104
+ if (k < encd->len) {
1105
+ if (scr_enc_is(enc, "utf16le")) {
1106
+ k -= k % 2;
1107
+ } else if (!scr_enc_is(enc, "hex") && !scr_enc_is(enc, "base64") &&
1108
+ !scr_enc_is(enc, "base64url") && !scr_enc_is(enc, "latin1") &&
1109
+ !scr_enc_is(enc, "ascii")) {
1110
+ /* utf8: back off a split multi-byte sequence (whole chars only). */
1111
+ size_t lead = k;
1112
+ while (lead > 0 && (encd->data[lead] & 0xc0) == 0x80) lead--;
1113
+ if (lead < k) {
1114
+ uint8_t l = encd->data[lead];
1115
+ size_t need = (l & 0xf8) == 0xf0 ? 4 : (l & 0xf0) == 0xe0 ? 3 : (l & 0xe0) == 0xc0 ? 2 : 1;
1116
+ if (lead + need > k) k = lead;
1117
+ }
1118
+ }
1119
+ }
1120
+ memcpy(b->data + o, encd->data, k);
1121
+ scr_bytes_release(encd);
1122
+ return (double)k;
1123
+ }
1124
+
1125
+ /* Buffer.concat(list, totalLength): the same concatenation truncated or
1126
+ * zero-padded to the validated total. */
1127
+ ScrBytes *scr_bytes_concat_len(const ScrArr *list, double total) {
1128
+ /* An empty list short-circuits BEFORE the total validates — Node's
1129
+ * own `if (list.length === 0) return new FastBuffer()`. */
1130
+ if (list->len == 0) return scr_bytes_alloc(SCR_BYTES_U8, 0);
1131
+ if (!scr_bytes_validate_off("length", total, 9007199254740991.0)) return NULL;
1132
+ ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, (size_t)total);
1133
+ size_t o = 0;
1134
+ for (size_t i = 0; i < list->len && o < b->len; i++) {
1135
+ const ScrBytes *part = (const ScrBytes *)(uintptr_t)list->data[i];
1136
+ size_t take = part->len < b->len - o ? part->len : b->len - o;
1137
+ memcpy(b->data + o, part->data, take);
1138
+ o += take;
1139
+ }
1140
+ return b;
1141
+ }
1142
+
1143
+ /* Buffer.byteLength(string, enc): utf8 is the storage length (ScrStr IS
1144
+ * utf8 bytes), latin1/ascii count UTF-16 units, utf16le doubles them,
1145
+ * hex halves the length, base64/base64url use Node's padding-trimmed
1146
+ * (len * 3) >>> 2. The enc arrives NORMALIZED (the compiler folds
1147
+ * aliases). */
1148
+ double scr_bytes_byte_length_str(ScrStr *s, const ScrStr *enc) {
1149
+ if (scr_enc_is(enc, "latin1") || scr_enc_is(enc, "ascii")) {
1150
+ return scr_str_utf16_len(s);
1151
+ }
1152
+ if (scr_enc_is(enc, "utf16le")) return 2 * scr_str_utf16_len(s);
1153
+ if (scr_enc_is(enc, "hex")) {
1154
+ return floor(scr_str_utf16_len(s) / 2);
1155
+ }
1156
+ if (scr_enc_is(enc, "base64") || scr_enc_is(enc, "base64url")) {
1157
+ size_t units = (size_t)scr_str_utf16_len(s);
1158
+ /* Trailing '=' padding trims (at most two) — checked on the raw
1159
+ * bytes: '=' is ASCII, so the last byte IS the last unit. */
1160
+ if (units > 0 && s->len >= 1 && s->data[s->len - 1] == '=') units--;
1161
+ if (units > 1 && s->len >= 2 && s->data[s->len - 2] == '=') units--;
1162
+ return (double)((units * 3) >> 2);
1163
+ }
1164
+ return (double)s->len; /* utf8 */
1165
+ }
1166
+
1167
+ /* Buffer.isEncoding(name): case-insensitive over Node's alias set. */
1168
+ bool scr_bytes_is_encoding(const ScrStr *s) {
1169
+ static const char *const names[] = {
1170
+ "utf8", "utf-8", "ascii", "latin1", "binary", "base64",
1171
+ "hex", "ucs2", "ucs-2", "utf16le", "utf-16le", "base64url",
1172
+ };
1173
+ if (s->len < 3 || s->len > 9) return false;
1174
+ char low[10];
1175
+ for (size_t i = 0; i < s->len; i++) {
1176
+ char c = s->data[i];
1177
+ low[i] = c >= 'A' && c <= 'Z' ? (char)(c + 32) : c;
1178
+ }
1179
+ low[s->len] = 0;
1180
+ for (size_t i = 0; i < sizeof names / sizeof names[0]; i++) {
1181
+ if (strlen(names[i]) == s->len && memcmp(low, names[i], s->len) == 0) return true;
1182
+ }
1183
+ return false;
1184
+ }
1185
+
1186
+ ScrBytes *scr_bytes_concat(const ScrArr *list) {
1187
+ size_t total = 0;
1188
+ for (size_t i = 0; i < list->len; i++) {
1189
+ const ScrBytes *part = (const ScrBytes *)(uintptr_t)list->data[i];
1190
+ total += part->len;
1191
+ }
1192
+ ScrBytes *b = scr_bytes_alloc(SCR_BYTES_U8, total);
1193
+ size_t o = 0;
1194
+ for (size_t i = 0; i < list->len; i++) {
1195
+ const ScrBytes *part = (const ScrBytes *)(uintptr_t)list->data[i];
1196
+ memcpy(b->data + o, part->data, part->len);
1197
+ o += part->len;
1198
+ }
1199
+ return b;
1200
+ }
1201
+
1202
+ /* ── the buf.read* / buf.write* numeric families (Node's exact bounds
1203
+ * discipline; the error ladders below mirror lib/internal/buffer.js's
1204
+ * boundsError/checkInt/checkBounds byte-for-byte — pinned by corpus
1205
+ * 1660 against the live Node oracle) ───────────────────────────────── */
1206
+
1207
+ /* ERR_OUT_OF_RANGE's "Received" rendering: integers with |v| > 2^32 get
1208
+ * Node's addNumericalSeparator underscores applied to the plain String()
1209
+ * form — INCLUDING its quirks on exponent renderings ("1e_+21",
1210
+ * "1e+_300"); everything else is the shortest-roundtrip number. */
1211
+ static size_t scr_bytes_received(double v, char out[48]) {
1212
+ char plain[32];
1213
+ size_t n = scr_f64_to_str(v, plain);
1214
+ if (!(isfinite(v) && trunc(v) == v && fabs(v) > 4294967296.0)) {
1215
+ memcpy(out, plain, n + 1);
1216
+ return n;
1217
+ }
1218
+ /* addNumericalSeparator: head of 1-3 chars (past a leading '-'), then
1219
+ * '_'-joined groups of 3 — walked over the STRING, exactly Node. */
1220
+ size_t start = plain[0] == '-' ? 1 : 0;
1221
+ size_t head = n;
1222
+ while (head >= start + 4) head -= 3;
1223
+ memcpy(out, plain, head);
1224
+ size_t o = head;
1225
+ for (size_t p = head; p < n; p += 3) {
1226
+ out[o++] = '_';
1227
+ memcpy(out + o, plain + p, 3);
1228
+ o += 3;
1229
+ }
1230
+ out[o] = 0;
1231
+ return o;
1232
+ }
1233
+
1234
+ /* Node's boundsError: a non-integer index is "an integer" first, a
1235
+ * negative capacity (buffer shorter than the read/write width) is the
1236
+ * constant ERR_BUFFER_OUT_OF_BOUNDS text, and everything else renders
1237
+ * the ">= min and <= max" range. type NULL means "offset" (min 0);
1238
+ * "byteLength" renders min 1. All catchable RangeErrors. */
1239
+ static void scr_bytes_bounds_error(double value, double length, const char *type) {
1240
+ char recv[48];
1241
+ scr_bytes_received(value, recv);
1242
+ char msg[160];
1243
+ int mlen;
1244
+ if (floor(value) != value) {
1245
+ mlen = snprintf(msg, sizeof msg,
1246
+ "The value of \"%s\" is out of range. It must be an integer. Received %s",
1247
+ type ? type : "offset", recv);
1248
+ } else if (length < 0) {
1249
+ static const char oob[] = "Attempt to access memory outside buffer bounds";
1250
+ scr_throw_error_msg(SCR_ERR_RANGE, oob, sizeof oob - 1);
1251
+ return;
1252
+ } else {
1253
+ char lenbuf[32];
1254
+ scr_f64_to_str(length, lenbuf);
1255
+ mlen = snprintf(msg, sizeof msg,
1256
+ "The value of \"%s\" is out of range. It must be >= %d and <= %s. Received %s",
1257
+ type ? type : "offset", type ? 1 : 0, lenbuf, recv);
1258
+ }
1259
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
1260
+ }
1261
+
1262
+ /* The shared offset gate: width bytes at offset must lie inside b. */
1263
+ static bool scr_bytes_rw_check(const ScrBytes *b, double offset, size_t width) {
1264
+ double cap = (double)b->len - (double)width;
1265
+ if (floor(offset) != offset || cap < 0 || offset < 0 || offset > cap) {
1266
+ scr_bytes_bounds_error(offset, cap, NULL);
1267
+ return false;
1268
+ }
1269
+ return true;
1270
+ }
1271
+
1272
+ /* Node's checkInt for the integer writes: the VALUE range throws before
1273
+ * any offset check; widths past 4 bytes render the "2 ** N" range form
1274
+ * (checkInt's byteLength > 3 branch). NaN passes both comparisons —
1275
+ * exactly Node — and writes zeros downstream. */
1276
+ static bool scr_bytes_check_int(const ScrBytes *b, double value, double offset,
1277
+ size_t width, bool sign) {
1278
+ double max = sign ? exp2((double)(8 * width - 1)) - 1 : exp2((double)(8 * width)) - 1;
1279
+ double min = sign ? -exp2((double)(8 * width - 1)) : 0;
1280
+ if (value > max || value < min) {
1281
+ char recv[48];
1282
+ scr_bytes_received(value, recv);
1283
+ char msg[160];
1284
+ int mlen;
1285
+ if (width > 4) {
1286
+ if (sign) {
1287
+ mlen = snprintf(msg, sizeof msg,
1288
+ "The value of \"value\" is out of range. It must be >= -(2 ** %zu) and < 2 ** %zu. Received %s",
1289
+ 8 * width - 1, 8 * width - 1, recv);
1290
+ } else {
1291
+ mlen = snprintf(msg, sizeof msg,
1292
+ "The value of \"value\" is out of range. It must be >= 0 and < 2 ** %zu. Received %s",
1293
+ 8 * width, recv);
1294
+ }
1295
+ } else {
1296
+ char minb[32], maxb[32];
1297
+ scr_f64_to_str(min, minb);
1298
+ scr_f64_to_str(max, maxb);
1299
+ mlen = snprintf(msg, sizeof msg,
1300
+ "The value of \"value\" is out of range. It must be >= %s and <= %s. Received %s",
1301
+ minb, maxb, recv);
1302
+ }
1303
+ scr_throw_error_msg(SCR_ERR_RANGE, msg, (size_t)mlen);
1304
+ return false;
1305
+ }
1306
+ return scr_bytes_rw_check(b, offset, width);
1307
+ }
1308
+
1309
+ static size_t scr_bytes_num_width(ScrBytesNumKind kind) {
1310
+ switch (kind) {
1311
+ case SCR_BN_U8:
1312
+ case SCR_BN_I8:
1313
+ return 1;
1314
+ case SCR_BN_U16:
1315
+ case SCR_BN_I16:
1316
+ return 2;
1317
+ case SCR_BN_F64:
1318
+ return 8;
1319
+ default:
1320
+ return 4; /* u32 / i32 / f32 */
1321
+ }
1322
+ }
1323
+
1324
+ double scr_bytes_read_num(const ScrBytes *b, double offset, ScrBytesNumKind kind, bool le) {
1325
+ size_t width = scr_bytes_num_width(kind);
1326
+ if (!scr_bytes_rw_check(b, offset, width)) return 0;
1327
+ const uint8_t *p = b->data + (size_t)offset;
1328
+ uint64_t u = 0;
1329
+ for (size_t i = 0; i < width; i++) {
1330
+ u |= (uint64_t)p[le ? i : width - 1 - i] << (8 * i);
1331
+ }
1332
+ switch (kind) {
1333
+ case SCR_BN_U8:
1334
+ case SCR_BN_U16:
1335
+ case SCR_BN_U32:
1336
+ return (double)u;
1337
+ case SCR_BN_I8:
1338
+ return (double)(int8_t)u;
1339
+ case SCR_BN_I16:
1340
+ return (double)(int16_t)u;
1341
+ case SCR_BN_I32:
1342
+ return (double)(int32_t)u;
1343
+ case SCR_BN_F32: {
1344
+ uint32_t bits = (uint32_t)u;
1345
+ float f;
1346
+ memcpy(&f, &bits, 4);
1347
+ return (double)f;
1348
+ }
1349
+ case SCR_BN_F64: {
1350
+ double d;
1351
+ memcpy(&d, &u, 8);
1352
+ return d;
1353
+ }
1354
+ }
1355
+ return 0; /* unreachable */
1356
+ }
1357
+
1358
+ double scr_bytes_write_num(ScrBytes *b, double value, double offset, ScrBytesNumKind kind, bool le) {
1359
+ size_t width = scr_bytes_num_width(kind);
1360
+ uint64_t u;
1361
+ if (kind == SCR_BN_F32 || kind == SCR_BN_F64) {
1362
+ /* Float writes carry no value check (any double stores; the float
1363
+ * cast rounds to nearest exactly like Float32Array assignment). */
1364
+ if (!scr_bytes_rw_check(b, offset, width)) return 0;
1365
+ if (kind == SCR_BN_F32) {
1366
+ float f = (float)value;
1367
+ uint32_t bits;
1368
+ memcpy(&bits, &f, 4);
1369
+ u = bits;
1370
+ } else {
1371
+ memcpy(&u, &value, 8);
1372
+ }
1373
+ } else {
1374
+ bool sign = kind == SCR_BN_I8 || kind == SCR_BN_I16 || kind == SCR_BN_I32;
1375
+ if (!scr_bytes_check_int(b, value, offset, width, sign)) return 0;
1376
+ double t = trunc(value);
1377
+ if (t != t) t = 0; /* NaN passed the range gate: zeros, like Node */
1378
+ u = (uint64_t)(int64_t)t; /* two's complement of the truncation */
1379
+ }
1380
+ uint8_t *p = b->data + (size_t)offset;
1381
+ for (size_t i = 0; i < width; i++) {
1382
+ p[le ? i : width - 1 - i] = (uint8_t)(u >> (8 * i));
1383
+ }
1384
+ return offset + (double)width;
1385
+ }
1386
+
1387
+ /* readUIntLE/BE / readIntLE/BE — the variable-width family: byteLength
1388
+ * validates FIRST (1-6, its own error ladder), then the offset gate. */
1389
+ double scr_bytes_read_var(const ScrBytes *b, double offset, double byte_length, bool sign, bool le) {
1390
+ if (floor(byte_length) != byte_length || byte_length < 1 || byte_length > 6) {
1391
+ scr_bytes_bounds_error(byte_length, 6, "byteLength");
1392
+ return 0;
1393
+ }
1394
+ size_t width = (size_t)byte_length;
1395
+ if (!scr_bytes_rw_check(b, offset, width)) return 0;
1396
+ const uint8_t *p = b->data + (size_t)offset;
1397
+ uint64_t u = 0;
1398
+ for (size_t i = 0; i < width; i++) {
1399
+ u |= (uint64_t)p[le ? i : width - 1 - i] << (8 * i);
1400
+ }
1401
+ if (sign && (u & ((uint64_t)1 << (8 * width - 1)))) {
1402
+ return (double)(int64_t)(u - ((uint64_t)1 << (8 * width)));
1403
+ }
1404
+ return (double)u;
1405
+ }
1406
+
1407
+ /* writeUIntLE/BE / writeIntLE/BE: byteLength, then value, then offset —
1408
+ * Node's exact check order. Returns offset + byteLength. */
1409
+ double scr_bytes_write_var(ScrBytes *b, double value, double offset, double byte_length, bool sign, bool le) {
1410
+ if (floor(byte_length) != byte_length || byte_length < 1 || byte_length > 6) {
1411
+ scr_bytes_bounds_error(byte_length, 6, "byteLength");
1412
+ return 0;
1413
+ }
1414
+ size_t width = (size_t)byte_length;
1415
+ if (!scr_bytes_check_int(b, value, offset, width, sign)) return 0;
1416
+ double t = trunc(value);
1417
+ if (t != t) t = 0;
1418
+ uint64_t u = (uint64_t)(int64_t)t;
1419
+ uint8_t *p = b->data + (size_t)offset;
1420
+ for (size_t i = 0; i < width; i++) {
1421
+ p[le ? i : width - 1 - i] = (uint8_t)(u >> (8 * i));
1422
+ }
1423
+ return offset + (double)width;
1424
+ }
1425
+