@scriptc/cli-darwin-arm64 0.2.1 → 0.2.3

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 (198) hide show
  1. package/dist/THIRD_PARTY_NOTICES +1 -1
  2. package/dist/bin/scriptc +0 -0
  3. package/dist/bin/scriptc.json +1 -1
  4. package/dist/lib/declarations/scriptc-node-fallback.d.ts +158 -31
  5. package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
  6. package/dist/lib/llvm/package.json +1 -1
  7. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_array.o +0 -0
  8. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_assert.o +0 -0
  9. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_async.o +0 -0
  10. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_async_dyn.o +0 -0
  11. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
  12. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
  13. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_crypto_async.o +0 -0
  14. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_dyn_invoke.o +0 -0
  15. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_events.o +0 -0
  16. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_exception.o +0 -0
  17. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
  18. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_json.o +0 -0
  19. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_lib.o +0 -0
  20. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_map.o +0 -0
  21. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
  22. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_qs.o +0 -0
  23. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_regex.o +0 -0
  24. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
  25. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_url.o +0 -0
  26. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_url_params.o +0 -0
  27. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_util_compare.o +0 -0
  28. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_util_style.o +0 -0
  29. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
  30. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
  31. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
  32. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_async_dyn.o +0 -0
  33. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
  34. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
  35. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_crypto_async.o +0 -0
  36. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_dyn_invoke.o +0 -0
  37. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
  38. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
  39. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
  40. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
  41. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
  42. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
  43. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
  44. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
  45. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_qs.o +0 -0
  46. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
  47. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
  48. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
  49. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_url_params.o +0 -0
  50. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_util_compare.o +0 -0
  51. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_util_style.o +0 -0
  52. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_web.o +0 -0
  53. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  54. package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  55. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
  56. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
  57. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
  58. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
  59. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_dyn_invoke.o +0 -0
  60. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
  61. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
  62. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
  63. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
  64. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
  65. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
  66. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
  67. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
  68. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_url_params.o +0 -0
  69. package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  70. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_array.o +0 -0
  71. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
  72. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
  73. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
  74. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_dyn_invoke.o +0 -0
  75. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
  76. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_json.o +0 -0
  77. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
  78. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_map.o +0 -0
  79. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
  80. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
  81. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
  82. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_url.o +0 -0
  83. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_url_params.o +0 -0
  84. package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  85. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
  86. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
  87. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
  88. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
  89. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_dyn_invoke.o +0 -0
  90. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
  91. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
  92. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
  93. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
  94. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
  95. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
  96. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
  97. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
  98. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_url_params.o +0 -0
  99. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  100. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
  101. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
  102. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
  103. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
  104. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_dyn_invoke.o +0 -0
  105. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
  106. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
  107. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
  108. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
  109. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
  110. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
  111. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
  112. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
  113. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_url_params.o +0 -0
  114. package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  115. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_array.o +0 -0
  116. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_assert.o +0 -0
  117. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_async.o +0 -0
  118. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_async_dyn.o +0 -0
  119. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_bytes.o +0 -0
  120. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
  121. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_crypto_async.o +0 -0
  122. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_dyn_invoke.o +0 -0
  123. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_events.o +0 -0
  124. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_exception.o +0 -0
  125. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
  126. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_json.o +0 -0
  127. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_lib.o +0 -0
  128. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_map.o +0 -0
  129. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
  130. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_qs.o +0 -0
  131. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_regex.o +0 -0
  132. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_symbol.o +0 -0
  133. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_url.o +0 -0
  134. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_url_params.o +0 -0
  135. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_util_compare.o +0 -0
  136. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_util_style.o +0 -0
  137. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
  138. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
  139. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
  140. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_async_dyn.o +0 -0
  141. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
  142. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
  143. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_crypto_async.o +0 -0
  144. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_dyn_invoke.o +0 -0
  145. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
  146. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
  147. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
  148. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
  149. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
  150. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
  151. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
  152. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
  153. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_qs.o +0 -0
  154. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
  155. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
  156. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
  157. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_url_params.o +0 -0
  158. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_util_compare.o +0 -0
  159. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_util_style.o +0 -0
  160. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_web.o +0 -0
  161. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  162. package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  163. package/dist/lib/runtime-darwin-arm64/package.json +1 -1
  164. package/dist/lib/runtime-darwin-arm64/runtime-pack.json +423 -297
  165. package/dist/lib/runtime-sources/package.json +1 -1
  166. package/dist/lib/runtime-sources/src/scr_abort.c +5 -0
  167. package/dist/lib/runtime-sources/src/scr_array.c +5 -0
  168. package/dist/lib/runtime-sources/src/scr_assert.c +26 -0
  169. package/dist/lib/runtime-sources/src/scr_async.c +56 -4
  170. package/dist/lib/runtime-sources/src/scr_async_dyn.c +118 -24
  171. package/dist/lib/runtime-sources/src/scr_bytes.c +226 -0
  172. package/dist/lib/runtime-sources/src/scr_bytes_io.c +355 -51
  173. package/dist/lib/runtime-sources/src/scr_crypto_async.c +22 -2
  174. package/dist/lib/runtime-sources/src/scr_dyn_invoke.c +181 -43
  175. package/dist/lib/runtime-sources/src/scr_events.c +9 -0
  176. package/dist/lib/runtime-sources/src/scr_exception.c +1 -0
  177. package/dist/lib/runtime-sources/src/scr_fetch.c +45 -1
  178. package/dist/lib/runtime-sources/src/scr_file_handle.c +42 -0
  179. package/dist/lib/runtime-sources/src/scr_island.c +2166 -786
  180. package/dist/lib/runtime-sources/src/scr_island_manifest.h +19 -13
  181. package/dist/lib/runtime-sources/src/scr_json.c +584 -54
  182. package/dist/lib/runtime-sources/src/scr_json.test.ts +1 -0
  183. package/dist/lib/runtime-sources/src/scr_lib.c +1192 -43
  184. package/dist/lib/runtime-sources/src/scr_map.c +8 -0
  185. package/dist/lib/runtime-sources/src/scr_node_builtin.c +78 -0
  186. package/dist/lib/runtime-sources/src/scr_qs.c +10 -0
  187. package/dist/lib/runtime-sources/src/scr_regex.c +107 -5
  188. package/dist/lib/runtime-sources/src/scr_runtime.h +136 -9
  189. package/dist/lib/runtime-sources/src/scr_symbol.c +5 -0
  190. package/dist/lib/runtime-sources/src/scr_system_errors.h +573 -0
  191. package/dist/lib/runtime-sources/src/scr_text_decoder_labels.h +12 -12
  192. package/dist/lib/runtime-sources/src/scr_url.c +547 -64
  193. package/dist/lib/runtime-sources/src/scr_url_internal.h +6 -0
  194. package/dist/lib/runtime-sources/src/scr_url_params.c +10 -0
  195. package/dist/lib/runtime-sources/src/scr_util_compare.c +222 -0
  196. package/dist/lib/runtime-sources/src/scr_util_style.c +337 -0
  197. package/dist/lib/runtime-sources/src/scr_web.c +849 -264
  198. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@scriptc/runtime",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "description": "scriptc native runtime sources and vendored dependencies",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://scriptc.dev",
@@ -0,0 +1,5 @@
1
+ /* Portable AbortController/AbortSignal use the same implementation as native
2
+ * fetch, without its network transport, Web Streams, or global fetch setup. */
3
+ #undef SCR_DYNAMIC
4
+ #define SCR_FETCH_SIGNAL_ONLY 1
5
+ #include "scr_fetch.c"
@@ -796,6 +796,11 @@ static bool scr_arr_read_value(const ScrArr *a, double i, uint64_t *slot) {
796
796
  return state == SCR_ARR_VALUE;
797
797
  }
798
798
 
799
+ void *scr_arr_peek_ref(const ScrArr *a, double i) {
800
+ uint64_t slot;
801
+ return scr_arr_read_value(a, i, &slot) ? scr_slot_to_ptr(slot) : NULL;
802
+ }
803
+
799
804
  double scr_arr_get_number(const ScrArr *a, double i) {
800
805
  /* Keep this hot numeric-only entry self-contained: routing it through
801
806
  * scr_arr_read_value adds an out-of-line call at -O2 on native targets. */
@@ -1481,6 +1481,32 @@ void scr_assert_unwanted_rejection(ScrError *err, ScrStr *msg, bool has_msg) {
1481
1481
  scr_assert_fail_msg(ab_take(&b));
1482
1482
  }
1483
1483
 
1484
+ void scr_assert_unwanted_error(ScrStr *actual_message, bool rejection, ScrStr *msg, bool has_msg) {
1485
+ ScrAssertBuf b = {0};
1486
+ ab_cstr(&b, rejection ? "Got unwanted rejection" : "Got unwanted exception");
1487
+ if (has_msg && msg->len) {
1488
+ ab_cstr(&b, ": ");
1489
+ ab_str(&b, msg);
1490
+ } else ab_char(&b, '.');
1491
+ ab_cstr(&b, "\nActual message: \"");
1492
+ ab_str(&b, actual_message);
1493
+ ab_char(&b, '"');
1494
+ scr_assert_fail_msg(ab_take(&b));
1495
+ }
1496
+
1497
+ /* Node calls validation functions with a fresh object receiver and accepts
1498
+ * only the boolean true. A callback exception remains the pending exception. */
1499
+ bool scr_assert_no_error_predicate(ScrDyn *predicate, ScrDyn *actual) {
1500
+ ScrDyn *receiver = scr_dyn_new_obj();
1501
+ scr_dyn_this_push_dyn(receiver);
1502
+ ScrDyn *result = scr_dyn_call(predicate, &actual, 1, "expected");
1503
+ scr_dyn_this_pop();
1504
+ scr_dyn_release(receiver);
1505
+ bool matched = result && result->kind == SCR_DYN_BOOL && result->v.b;
1506
+ scr_dyn_release(result);
1507
+ return matched;
1508
+ }
1509
+
1484
1510
  /* ── assert.ifError ───────────────────────────────────────────────────
1485
1511
  * Node throws for ANY value but null/undefined (falsy included); the
1486
1512
  * frontend routes null/undefined to a no-op and everything else here.
@@ -1259,8 +1259,10 @@ static void scr_fiber_finish(ScrFiber *self) {
1259
1259
  * (moved from the fiber's cell into the promise). */
1260
1260
  scr_promise_reject_from_cell(p, &self->exc);
1261
1261
  }
1262
- /* Fulfillment payload was stored by the trampoline before finishing. */
1263
- scr_promise_settle_wake(p);
1262
+ /* A returned checked promise may still be resolving after its function
1263
+ * body finishes. Its resolver owns settlement and must not wake awaiters
1264
+ * until adoption completes (WASI continuations cannot park a C stack). */
1265
+ if (p->state != SCR_PROM_PENDING) scr_promise_settle_wake(p);
1264
1266
  self->done = true;
1265
1267
  }
1266
1268
 
@@ -1756,6 +1758,50 @@ ScrPromise *scr_fsp_chmod(ScrStr *path, double mode) {
1756
1758
  return scr_promise_settled_void();
1757
1759
  }
1758
1760
 
1761
+ ScrPromise *scr_fsp_utimes(const ScrDyn *path, const ScrDyn *atime, const ScrDyn *mtime) {
1762
+ scr_fs_utimes_checked(path, atime, mtime);
1763
+ return scr_promise_settled_void();
1764
+ }
1765
+
1766
+ ScrPromise *scr_fsp_link(const ScrDyn *existing, const ScrDyn *destination) {
1767
+ scr_fs_link_checked(existing, destination);
1768
+ return scr_promise_settled_void();
1769
+ }
1770
+
1771
+ ScrPromise *scr_fsp_symlink(const ScrDyn *target, const ScrDyn *destination, const ScrDyn *type) {
1772
+ scr_fs_symlink_promise_checked(target, destination, type);
1773
+ return scr_promise_settled_void();
1774
+ }
1775
+
1776
+ ScrPromise *scr_fsp_readlink_dyn(const ScrDyn *path, const ScrDyn *options) {
1777
+ ScrDyn *result = scr_fs_readlink_checked(path, options, true);
1778
+ return scr_promise_settled_ref(result, scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v);
1779
+ }
1780
+
1781
+ ScrPromise *scr_fsp_statfs(const ScrDyn *path, const ScrDyn *options) {
1782
+ ScrDyn *result = scr_fs_statfs_checked(path, options);
1783
+ return scr_promise_settled_ref(result, scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v);
1784
+ }
1785
+
1786
+ ScrPromise *scr_fsp_readlink_str(const ScrDyn *path, const ScrDyn *options) {
1787
+ ScrDyn *result = scr_fs_readlink_checked(path, options, true);
1788
+ ScrStr *text = result && result->kind == SCR_DYN_STR ? scr_str_retain(result->v.str) : NULL;
1789
+ scr_dyn_release(result);
1790
+ return scr_promise_settled_str(text);
1791
+ }
1792
+
1793
+ ScrPromise *scr_fsp_readlink_buffer(const ScrDyn *path, const ScrDyn *options) {
1794
+ ScrDyn *result = scr_fs_readlink_checked(path, options, true);
1795
+ ScrBytes *bytes = result ? scr_dyn_bytes_unbox(result) : NULL;
1796
+ scr_dyn_release(result);
1797
+ return scr_promise_settled_ref(bytes, scr_bytes_retain_v, scr_bytes_release_v, NULL);
1798
+ }
1799
+
1800
+ ScrPromise *scr_fsp_lutimes(const ScrDyn *path, const ScrDyn *atime, const ScrDyn *mtime) {
1801
+ scr_fs_lutimes_checked(path, atime, mtime);
1802
+ return scr_promise_settled_void();
1803
+ }
1804
+
1759
1805
  ScrPromise *scr_fsp_readdir(ScrStr *path) {
1760
1806
  ScrArr *names = scr_fs_readdir(path);
1761
1807
  return scr_promise_settled_ref(names, &scr_arr_retain_v, &scr_arr_release_v, NULL);
@@ -2146,6 +2192,7 @@ void scr_fs_rename_thunk0(ScrClosure *cb, ScrError *err) {
2146
2192
  * the emitted callback adapter. */
2147
2193
  typedef struct ScrCryptoBytesOp {
2148
2194
  ScrBytes *value;
2195
+ ScrError *error;
2149
2196
  ScrClosure *cb;
2150
2197
  ScrCryptoBytesFn fn;
2151
2198
  struct ScrCryptoBytesOp *next;
@@ -2161,6 +2208,7 @@ static void scr_crypto_bytes_shutdown(void) {
2161
2208
  ScrCryptoBytesOp *op = scr_crypto_bytes_head;
2162
2209
  scr_crypto_bytes_head = op->next;
2163
2210
  scr_bytes_release(op->value);
2211
+ scr_error_release(op->error);
2164
2212
  scr_closure_release(op->cb);
2165
2213
  free(op);
2166
2214
  }
@@ -2178,16 +2226,18 @@ static bool scr_crypto_bytes_dispatch(void) {
2178
2226
  scr_crypto_bytes_head = op->next;
2179
2227
  if (scr_crypto_bytes_head == NULL) scr_crypto_bytes_tail = &scr_crypto_bytes_head;
2180
2228
  scr_crypto_bytes_pending_count--;
2181
- op->fn(op->cb, op->value); /* adapter consumes value */
2229
+ op->fn(op->cb, op->error, op->value); /* adapter consumes value */
2230
+ scr_error_release(op->error);
2182
2231
  scr_closure_release(op->cb);
2183
2232
  free(op);
2184
2233
  return true;
2185
2234
  }
2186
2235
 
2187
- void scr_crypto_defer_bytes(ScrBytes *value, ScrClosure *cb, ScrCryptoBytesFn fn) {
2236
+ void scr_crypto_defer_bytes(ScrBytes *value, ScrError *error, ScrClosure *cb, ScrCryptoBytesFn fn) {
2188
2237
  if (!scr_crypto_bytes_cleanup_registered) {
2189
2238
  if (atexit(scr_crypto_bytes_shutdown) != 0) {
2190
2239
  scr_bytes_release(value);
2240
+ scr_error_release(error);
2191
2241
  scr_closure_release(cb);
2192
2242
  scr_trap("scriptc: could not register crypto callback cleanup\n");
2193
2243
  }
@@ -2196,10 +2246,12 @@ void scr_crypto_defer_bytes(ScrBytes *value, ScrClosure *cb, ScrCryptoBytesFn fn
2196
2246
  ScrCryptoBytesOp *op = malloc(sizeof *op);
2197
2247
  if (!op) {
2198
2248
  scr_bytes_release(value);
2249
+ scr_error_release(error);
2199
2250
  scr_closure_release(cb);
2200
2251
  scr_trap("scriptc: out of memory\n");
2201
2252
  }
2202
2253
  op->value = value;
2254
+ op->error = error;
2203
2255
  op->cb = cb;
2204
2256
  op->fn = fn;
2205
2257
  op->next = NULL;
@@ -421,6 +421,24 @@ typedef struct {
421
421
  ScrDyn *onf, *onr, *onfin; /* owned or NULL */
422
422
  } ScrDynThenPack;
423
423
 
424
+ typedef struct {
425
+ ScrPromise *src, *dst;
426
+ ScrDyn *result;
427
+ } ScrDynFinallyPack;
428
+
429
+ static void scr_dyn_finally_entry(ScrFiber *self, void *opaque) {
430
+ (void)self;
431
+ ScrDynFinallyPack *pack = opaque;
432
+ ScrDyn *result = scr_await_dyn(pack->result->v.promise);
433
+ if (scr_exc_pending()) scr_promise_reject_pending(pack->dst);
434
+ else scr_promise_adapt_copy(pack->dst, pack->src);
435
+ scr_dyn_release(result);
436
+ scr_dyn_release(pack->result);
437
+ scr_promise_release(pack->src);
438
+ scr_promise_release(pack->dst);
439
+ free(pack);
440
+ }
441
+
424
442
  static void scr_dyn_then_entry(ScrFiber *self, void *ap) {
425
443
  (void)self;
426
444
  ScrDynThenPack *a = (ScrDynThenPack *)ap;
@@ -428,7 +446,7 @@ static void scr_dyn_then_entry(ScrFiber *self, void *ap) {
428
446
  bool rejected = scr_exc_pending();
429
447
  ScrCaught *c = rejected ? scr_exc_take() : NULL;
430
448
  ScrDyn *handler = a->onfin ? a->onfin : (rejected ? a->onr : a->onf);
431
- if (handler != NULL && handler->kind == SCR_DYN_FUNC) {
449
+ if (handler != NULL && scr_dyn_is_callable(handler)) {
432
450
  ScrDyn *arg = NULL;
433
451
  if (a->onfin == NULL) arg = rejected ? scr_caught_to_dyn(c) : scr_dyn_retain(v);
434
452
  ScrDyn *r = scr_dyn_call(handler, arg ? &arg : NULL, arg ? 1 : 0, "handler");
@@ -437,30 +455,27 @@ static void scr_dyn_then_entry(ScrFiber *self, void *ap) {
437
455
  /* The handler threw: dst rejects with that. */
438
456
  scr_promise_reject_pending(a->dst);
439
457
  } else if (a->onfin != NULL) {
440
- /* finally: the callback's value is dropped and the source
441
- * settlement passes through (JS — a finally callback returning a
442
- * promise would delay adoption; that refinement waits for a use). */
443
- scr_dyn_release(r);
444
- if (rejected) {
445
- scr_rethrow(c);
446
- scr_promise_reject_pending(a->dst);
447
- } else {
448
- scr_promise_fulfill_ref(a->dst, scr_dyn_retain(v), scr_dyn_retain_v, scr_dyn_release_v, NULL);
458
+ /* finally returns PromiseResolve(result).then(valueThunk), which
459
+ * the outer reaction adopts. Even an undefined result takes those
460
+ * jobs before propagating the original fulfillment or rejection. */
461
+ if (r->kind != SCR_DYN_PROMISE) {
462
+ ScrPromise *result = scr_promise_new();
463
+ scr_promise_fulfill_ref(result, r, scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v);
464
+ r = scr_dyn_new_promise(result);
465
+ scr_promise_release(result);
449
466
  }
467
+ ScrPromise *passthrough = scr_promise_new();
468
+ ScrDynFinallyPack *pack = malloc(sizeof *pack);
469
+ if (!pack) scr_ad_oom();
470
+ pack->src = scr_promise_retain(a->src);
471
+ pack->dst = scr_promise_retain(passthrough);
472
+ pack->result = r;
473
+ ScrPromise *waiter = scr_async_spawn_after(r->v.promise, scr_dyn_finally_entry, pack);
474
+ scr_promise_release(waiter);
475
+ scr_promise_resolve_dyn(a->dst, scr_dyn_new_promise(passthrough));
476
+ scr_promise_release(passthrough);
450
477
  } else {
451
- /* Adopt dyn-promise results (JS's resolve walk). */
452
- while (r != NULL && r->kind == SCR_DYN_PROMISE) {
453
- ScrDyn *inner = scr_await_dyn(r->v.promise);
454
- scr_dyn_release(r);
455
- r = inner;
456
- if (scr_exc_pending()) {
457
- scr_promise_reject_pending(a->dst);
458
- break;
459
- }
460
- }
461
- if (r != NULL) {
462
- scr_promise_fulfill_ref(a->dst, r, scr_dyn_retain_v, scr_dyn_release_v, NULL);
463
- }
478
+ scr_promise_resolve_dyn(a->dst, r);
464
479
  }
465
480
  } else if (rejected) {
466
481
  scr_rethrow(c);
@@ -492,7 +507,7 @@ ScrDyn *scr_dyn_promise_then(ScrPromise *src, ScrDyn *onf, ScrDyn *onr, ScrDyn *
492
507
  a->onr = onr ? scr_dyn_retain(onr) : NULL;
493
508
  a->onfin = onfin ? scr_dyn_retain(onfin) : NULL;
494
509
  ScrDyn *boxed = scr_dyn_new_promise(a->dst);
495
- ScrPromise *waiter = scr_async_spawn(scr_dyn_then_entry, a);
510
+ ScrPromise *waiter = scr_async_spawn_after(src, scr_dyn_then_entry, a);
496
511
  scr_promise_release(waiter); /* the entry never rejects; nobody awaits it */
497
512
  return boxed;
498
513
  }
@@ -504,8 +519,10 @@ typedef struct {
504
519
  static void scr_dyn_resolve_entry(ScrFiber *self, void *opaque) {
505
520
  (void)self;
506
521
  ScrDynResolvePack *pack = opaque;
522
+ #ifndef __wasi__
507
523
  /* Promise resolution schedules a job before attaching its reaction. */
508
524
  scr_await_hop();
525
+ #endif
509
526
  ScrDyn *value = scr_await_dyn(pack->value->v.promise);
510
527
  if (scr_exc_pending()) scr_promise_reject_pending(pack->destination);
511
528
  else scr_promise_resolve_dyn(pack->destination, value);
@@ -514,6 +531,19 @@ static void scr_dyn_resolve_entry(ScrFiber *self, void *opaque) {
514
531
  free(pack);
515
532
  }
516
533
 
534
+ #ifdef __wasi__
535
+ static void scr_dyn_resolve_job(ScrClosure *closure) {
536
+ ScrPromise *destination = scr_box_get_ref(closure->caps[0]);
537
+ ScrDyn *value = scr_box_get_ref(closure->caps[1]);
538
+ ScrDynResolvePack *pack = malloc(sizeof *pack);
539
+ if (!pack) scr_ad_oom();
540
+ pack->destination = destination;
541
+ pack->value = value;
542
+ ScrPromise *waiter = scr_async_spawn_after(value->v.promise, scr_dyn_resolve_entry, pack);
543
+ scr_promise_release(waiter);
544
+ }
545
+ #endif
546
+
517
547
  /* The destination is borrowed; value moves in. An async function may
518
548
  * return a native promise hidden behind any/unknown without an explicit
519
549
  * await, so its completion must use resolution rather than fulfillment. */
@@ -529,12 +559,21 @@ void scr_promise_resolve_dyn(ScrPromise *destination, ScrDyn *value) {
529
559
  scr_dyn_release(value);
530
560
  return;
531
561
  }
562
+ #ifdef __wasi__
563
+ ScrClosure *job = scr_closure_new((void *)scr_dyn_resolve_job, 2);
564
+ job->caps[0] = scr_box_new_obj(scr_promise_retain_v, scr_promise_release_v, scr_promise_trace_v);
565
+ scr_box_set_ref(job->caps[0], scr_promise_retain(destination));
566
+ job->caps[1] = scr_box_new_obj(scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v);
567
+ scr_box_set_ref(job->caps[1], value);
568
+ scr_queue_microtask(job);
569
+ #else
532
570
  ScrDynResolvePack *pack = malloc(sizeof *pack);
533
571
  if (!pack) scr_ad_oom();
534
572
  pack->destination = scr_promise_retain(destination);
535
573
  pack->value = value;
536
574
  ScrPromise *waiter = scr_async_spawn(scr_dyn_resolve_entry, pack);
537
575
  scr_promise_release(waiter);
576
+ #endif
538
577
  }
539
578
 
540
579
  /* `await v` where v is a CHECKED-DYNAMIC value: a dyn promise adopts
@@ -548,6 +587,13 @@ ScrDyn *scr_await_dyn_value(ScrDyn *v) {
548
587
  return scr_dyn_retain(v);
549
588
  }
550
589
 
590
+ /* The WASI emitter has already suspended on the value's actual promise,
591
+ * or taken the non-promise microtask hop. Extraction must never suspend a
592
+ * runtime-authored C frame. */
593
+ ScrDyn *scr_await_dyn_value_settled(ScrDyn *value) {
594
+ return value->kind == SCR_DYN_PROMISE ? scr_await_dyn(value->v.promise) : scr_dyn_retain(value);
595
+ }
596
+
551
597
  /* ── process warnings (emitWarning + the 'warning' event) ─────────────
552
598
  * Gated with the rest of this TU (a deprecation-emitting unit's gate
553
599
  * must imply the dynAsync link). Listeners are dyn functions; emission
@@ -834,6 +880,54 @@ ScrPromise *scr_dyn_promise_of(const ScrDyn *d) {
834
880
  return d->kind == SCR_DYN_PROMISE ? d->v.promise : NULL;
835
881
  }
836
882
 
883
+ static void scr_dyn_all_result(ScrPromise *destination, ScrPromise *source) {
884
+ ScrArr *values = scr_promise_payload_ref(source);
885
+ ScrDyn *result = scr_dyn_new_arr();
886
+ for (size_t i = 0; i < values->len; i++) scr_dyn_arr_push(result, scr_arr_get_ref(values, (double)i));
887
+ scr_arr_release(values);
888
+ scr_promise_fulfill_ref(destination, result, scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v);
889
+ }
890
+
891
+ ScrPromise *scr_dyn_promise_all(const ScrDyn *entries) {
892
+ ScrArr *promises = scr_arr_new_ref(scr_promise_retain_v, scr_promise_release_v, scr_promise_trace_v, entries->v.arr.len);
893
+ ScrArr *values = scr_arr_new_ref(scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v, entries->v.arr.len);
894
+ for (size_t i = 0; i < entries->v.arr.len; i++) {
895
+ ScrDyn *value = entries->v.arr.items[i];
896
+ ScrPromise *source;
897
+ if (value->kind == SCR_DYN_PROMISE) source = scr_promise_retain(value->v.promise);
898
+ else {
899
+ source = scr_promise_new();
900
+ if (value->kind == SCR_DYN_OBJ || value->kind == SCR_DYN_FUNC || value->kind == SCR_DYN_PROXY) {
901
+ ScrStr *key = scr_str_new("then", 4);
902
+ ScrDyn *then = value->kind == SCR_DYN_PROXY ? scr_dyn_proxy_get(value, key)
903
+ : value->kind == SCR_DYN_FUNC ? scr_dyn_fn_get(value, "then", 4) : scr_dyn_obj_read(value, "then", 4);
904
+ scr_str_release(key);
905
+ if (then && then->kind == SCR_DYN_FUNC) {
906
+ static const char message[] = "Promise.all over custom thenables is not supported yet";
907
+ scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
908
+ }
909
+ scr_dyn_release(then);
910
+ }
911
+ if (scr_exc_pending()) scr_promise_reject_pending(source);
912
+ else scr_promise_fulfill_ref(source, scr_dyn_retain(value), scr_dyn_retain_v, scr_dyn_release_v, scr_dyn_trace_v);
913
+ }
914
+ /* Each element contributes a reaction job, even an already fulfilled
915
+ * plain value. The aggregate preserves input order and Node's hops. */
916
+ scr_promise_mark_handled(source);
917
+ ScrDyn *reaction = scr_dyn_promise_then(source, NULL, NULL, NULL);
918
+ scr_arr_push_ref(promises, scr_promise_retain(reaction->v.promise));
919
+ scr_dyn_release(reaction);
920
+ scr_promise_release(source);
921
+ }
922
+ ScrPromise *all = scr_promise_all(promises, values, scr_promise_all_store_ref);
923
+ ScrPromise *result = scr_promise_new();
924
+ scr_promise_race_add(result, all, scr_dyn_all_result);
925
+ scr_promise_release(all);
926
+ scr_arr_release(values);
927
+ scr_arr_release(promises);
928
+ return result;
929
+ }
930
+
837
931
  /* The checked native WebCrypto digest entry keeps promise and ArrayBuffer results native. */
838
932
  static ScrDyn *scr_crypto_digest_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
839
933
  (void)closure;
@@ -57,6 +57,21 @@ double scr_text_decoder_encoding(const ScrDyn *label) {
57
57
  return -1;
58
58
  }
59
59
 
60
+ ScrStr *scr_text_decoder_name(double encoding) {
61
+ static const char *names[] = {
62
+ "ibm866", "iso-8859-2", "iso-8859-3", "iso-8859-4", "iso-8859-5",
63
+ "iso-8859-6", "iso-8859-7", "iso-8859-8", "iso-8859-10", "iso-8859-13",
64
+ "iso-8859-14", "iso-8859-15", "iso-8859-16", "koi8-r", "koi8-u",
65
+ "macintosh", "windows-874", "windows-1250", "windows-1251", "windows-1252",
66
+ "windows-1253", "windows-1254", "windows-1255", "windows-1256", "windows-1257",
67
+ "windows-1258", "x-mac-cyrillic", "x-user-defined", "utf-16le", "utf-16be",
68
+ "gb18030", "big5", "euc-jp", "iso-2022-jp", "shift_jis", "euc-kr",
69
+ "iso-8859-8-i", "gbk",
70
+ };
71
+ const char *name = encoding < 0 ? "utf-8" : names[(unsigned)encoding];
72
+ return scr_str_new(name, strlen(name));
73
+ }
74
+
60
75
  #ifdef SCR_RC_AUDIT
61
76
  static SCR_TL long scr_live_bytes = 0;
62
77
  long scr_bytes_live_count(void) { return scr_live_bytes; }
@@ -1675,6 +1690,8 @@ static ScrStr *scr_td_iso_2022_jp_decode(const ScrBytes *b, bool fatal) {
1675
1690
 
1676
1691
  ScrStr *scr_text_decode_legacy_options(const ScrBytes *b, double encoding_value, bool fatal, bool ignore_bom) {
1677
1692
  unsigned encoding = (unsigned)encoding_value;
1693
+ if (encoding == 36) encoding = 7; /* ISO-8859-8-I */
1694
+ if (encoding == 37) encoding = SCR_TD_GB18030; /* GBK */
1678
1695
  if (encoding < SCR_TD_SINGLE_COUNT) return scr_td_single_byte(b, encoding, fatal);
1679
1696
  switch (encoding) {
1680
1697
  case SCR_TD_X_USER_DEFINED: return scr_td_x_user_defined(b, fatal);
@@ -1712,6 +1729,7 @@ static size_t scr_td_utf8_tail(const uint8_t *bytes, size_t n) {
1712
1729
 
1713
1730
  ScrStr *scr_text_decode_stream(ScrDyn *state, const ScrBytes *input,
1714
1731
  double encoding, bool fatal, bool ignore_bom, bool stream) {
1732
+ if (encoding == 36) encoding = 7; /* ISO-8859-8-I is a single-byte decoder. */
1715
1733
  ScrDyn *saved = scr_dyn_obj_read(state, "pending", 7);
1716
1734
  size_t pending = saved->kind == SCR_DYN_BYTES ? saved->v.bytes->len : 0;
1717
1735
  if (input->len > SIZE_MAX - pending) scr_bytes_oom();
@@ -1785,6 +1803,214 @@ static uint32_t scr_bytes_next_cp(const uint8_t *in, size_t *ip) {
1785
1803
  return cp;
1786
1804
  }
1787
1805
 
1806
+ /* encodeInto consumes complete Unicode scalars while counting UTF-16 units.
1807
+ * Borrow the destination so writes through a subarray retain their aliasing. */
1808
+ ScrDyn *scr_text_encode_into(const ScrDyn *source, const ScrDyn *destination) {
1809
+ if (source->kind != SCR_DYN_STR) {
1810
+ scr_dyn_arg_type_fail("src", "of type string", source);
1811
+ return NULL;
1812
+ }
1813
+ if (destination->kind != SCR_DYN_BYTES || destination->v.bytes->elem != SCR_BYTES_U8 || destination->v.bytes->is_data_view) {
1814
+ scr_dyn_arg_type_fail("dest", "an instance of Uint8Array", destination);
1815
+ return NULL;
1816
+ }
1817
+ const ScrStr *text = source->v.str;
1818
+ ScrBytes *dest = destination->v.bytes;
1819
+ size_t read = 0, written = 0;
1820
+ while (written < text->len) {
1821
+ size_t end = written;
1822
+ uint32_t cp = scr_bytes_next_cp((const uint8_t *)text->data, &end);
1823
+ if (end > dest->len) break;
1824
+ read += cp > 0xffff ? 2 : 1;
1825
+ written = end;
1826
+ }
1827
+ if (written) memcpy(dest->data, text->data, written);
1828
+ ScrDyn *result = scr_dyn_new_obj();
1829
+ scr_dyn_obj_set(result, "read", 4, scr_dyn_new_num((double)read));
1830
+ scr_dyn_obj_set(result, "written", 7, scr_dyn_new_num((double)written));
1831
+ return result;
1832
+ }
1833
+
1834
+ static ScrBytes *scr_buffer_validation_input(const ScrDyn *input) {
1835
+ if ((input->kind == SCR_DYN_BYTES && !input->v.bytes->is_data_view) || scr_array_buffer_is(input)) {
1836
+ return scr_bytes_buffer_source(input);
1837
+ }
1838
+ scr_dyn_arg_type_fail("input", "an instance of ArrayBuffer, Buffer, or TypedArray", input);
1839
+ return NULL;
1840
+ }
1841
+
1842
+ static bool scr_buffer_utf8_valid(const uint8_t *data, size_t len) {
1843
+ size_t i = 0;
1844
+ while (i < len) {
1845
+ unsigned byte = data[i++], count;
1846
+ unsigned low = 0x80, high = 0xbf;
1847
+ if (byte < 0x80) continue;
1848
+ if (byte >= 0xc2 && byte <= 0xdf) count = 1;
1849
+ else if (byte >= 0xe0 && byte <= 0xef) {
1850
+ count = 2;
1851
+ if (byte == 0xe0) low = 0xa0;
1852
+ if (byte == 0xed) high = 0x9f;
1853
+ } else if (byte >= 0xf0 && byte <= 0xf4) {
1854
+ count = 3;
1855
+ if (byte == 0xf0) low = 0x90;
1856
+ if (byte == 0xf4) high = 0x8f;
1857
+ } else return false;
1858
+ if (count > len - i || data[i] < low || data[i] > high) return false;
1859
+ i++;
1860
+ for (unsigned j = 1; j < count; j++, i++) if (data[i] < 0x80 || data[i] > 0xbf) return false;
1861
+ }
1862
+ return true;
1863
+ }
1864
+
1865
+ bool scr_buffer_is_ascii(const ScrDyn *input) {
1866
+ ScrBytes *bytes = scr_buffer_validation_input(input);
1867
+ if (!bytes) return false;
1868
+ bool result = true;
1869
+ for (size_t i = 0; i < bytes->len; i++) if (bytes->data[i] > 0x7f) { result = false; break; }
1870
+ scr_bytes_release(bytes);
1871
+ return result;
1872
+ }
1873
+
1874
+ bool scr_buffer_is_utf8(const ScrDyn *input) {
1875
+ ScrBytes *bytes = scr_buffer_validation_input(input);
1876
+ if (!bytes) return false;
1877
+ bool result = scr_buffer_utf8_valid(bytes->data, bytes->len);
1878
+ scr_bytes_release(bytes);
1879
+ return result;
1880
+ }
1881
+
1882
+ /* Node's ICU wrapper recognizes Buffer encoding aliases. Empty inputs return
1883
+ * before resolving either encoding. The four actual converter families are
1884
+ * implemented here without adding an ICU dependency to a native binary. */
1885
+ enum { SCR_TC_UTF8, SCR_TC_ASCII, SCR_TC_LATIN1, SCR_TC_UTF16 };
1886
+
1887
+ static int scr_transcode_encoding(const ScrDyn *value) {
1888
+ if (value->kind == SCR_DYN_NULL || value->kind == SCR_DYN_UNDEF ||
1889
+ (value->kind == SCR_DYN_STR && value->v.str->len == 0)) return SCR_TC_UTF8;
1890
+ if (value->kind != SCR_DYN_STR) return -1;
1891
+ const ScrStr *name = value->v.str;
1892
+ static const struct { const char *name; int encoding; } aliases[] = {
1893
+ {"utf8", SCR_TC_UTF8}, {"utf-8", SCR_TC_UTF8}, {"ascii", SCR_TC_ASCII},
1894
+ {"latin1", SCR_TC_LATIN1}, {"binary", SCR_TC_LATIN1},
1895
+ {"utf16le", SCR_TC_UTF16}, {"utf-16le", SCR_TC_UTF16},
1896
+ {"ucs2", SCR_TC_UTF16}, {"ucs-2", SCR_TC_UTF16},
1897
+ };
1898
+ for (size_t i = 0; i < sizeof aliases / sizeof aliases[0]; i++) {
1899
+ if (strlen(aliases[i].name) != name->len) continue;
1900
+ bool match = true;
1901
+ for (size_t j = 0; j < name->len; j++) {
1902
+ unsigned char c = (unsigned char)name->data[j];
1903
+ if (c >= 'A' && c <= 'Z') c += 'a' - 'A';
1904
+ if (c != (unsigned char)aliases[i].name[j]) { match = false; break; }
1905
+ }
1906
+ if (match) return aliases[i].encoding;
1907
+ }
1908
+ return -1;
1909
+ }
1910
+
1911
+ static ScrBytes *scr_transcode_error(bool invalid_data) {
1912
+ const char *code = invalid_data ? "U_INVALID_CHAR_FOUND" : "U_ILLEGAL_ARGUMENT_ERROR";
1913
+ char message[100];
1914
+ int length = snprintf(message, sizeof message, "Unable to transcode Buffer [%s]", code);
1915
+ ScrStr *text = scr_str_new(message, (size_t)length);
1916
+ ScrError *error = scr_error_new(SCR_ERR_ERROR, text);
1917
+ scr_str_release(text);
1918
+ scr_error_set_code(error, code);
1919
+ scr_throw_obj(error, &scr_error_retain_v, &scr_error_release_v, scr_error_trace_arg());
1920
+ return NULL;
1921
+ }
1922
+
1923
+ /* ICU's pinned substitute callback skips unmappable default-ignorable code
1924
+ * points. Mappable Latin-1 characters (including soft hyphen) still survive. */
1925
+ static bool scr_transcode_ignorable(uint32_t cp) {
1926
+ return cp == 0xad || cp == 0x34f || cp == 0x61c || cp == 0x115f || cp == 0x1160 ||
1927
+ (cp >= 0x17b4 && cp <= 0x17b5) || (cp >= 0x180b && cp <= 0x180f) ||
1928
+ (cp >= 0x200b && cp <= 0x200f) || (cp >= 0x202a && cp <= 0x202e) ||
1929
+ (cp >= 0x2060 && cp <= 0x206f) || cp == 0x3164 ||
1930
+ (cp >= 0xfe00 && cp <= 0xfe0f) || cp == 0xfeff || cp == 0xffa0 ||
1931
+ (cp >= 0xfff0 && cp <= 0xfff8) || (cp >= 0x1bca0 && cp <= 0x1bca3) ||
1932
+ (cp >= 0x1d173 && cp <= 0x1d17a) || (cp >= 0xe0000 && cp <= 0xe0fff);
1933
+ }
1934
+
1935
+ static size_t scr_transcode_put(uint8_t *out, size_t index, uint32_t cp, int encoding) {
1936
+ if (encoding == SCR_TC_ASCII || encoding == SCR_TC_LATIN1) {
1937
+ unsigned limit = encoding == SCR_TC_ASCII ? 0x7f : 0xff;
1938
+ if (cp <= limit) out[index++] = (uint8_t)cp;
1939
+ else if (!scr_transcode_ignorable(cp)) out[index++] = '?';
1940
+ } else if (encoding == SCR_TC_UTF16) {
1941
+ if (cp > 0xffff) {
1942
+ uint32_t high = 0xd800 + ((cp - 0x10000) >> 10);
1943
+ out[index++] = (uint8_t)high;
1944
+ out[index++] = (uint8_t)(high >> 8);
1945
+ cp = 0xdc00 + ((cp - 0x10000) & 0x3ff);
1946
+ }
1947
+ out[index++] = (uint8_t)cp;
1948
+ out[index++] = (uint8_t)(cp >> 8);
1949
+ } else if (cp < 0x80) out[index++] = (uint8_t)cp;
1950
+ else if (cp < 0x800) {
1951
+ out[index++] = 0xc0 | (cp >> 6); out[index++] = 0x80 | (cp & 63);
1952
+ } else if (cp < 0x10000) {
1953
+ out[index++] = 0xe0 | (cp >> 12); out[index++] = 0x80 | ((cp >> 6) & 63); out[index++] = 0x80 | (cp & 63);
1954
+ } else {
1955
+ out[index++] = 0xf0 | (cp >> 18); out[index++] = 0x80 | ((cp >> 12) & 63);
1956
+ out[index++] = 0x80 | ((cp >> 6) & 63); out[index++] = 0x80 | (cp & 63);
1957
+ }
1958
+ return index;
1959
+ }
1960
+
1961
+ ScrBytes *scr_buffer_transcode(const ScrDyn *source, const ScrDyn *from, const ScrDyn *to) {
1962
+ if (source->kind != SCR_DYN_BYTES || source->v.bytes->elem != SCR_BYTES_U8 || source->v.bytes->is_data_view) {
1963
+ scr_dyn_arg_type_fail("source", "an instance of Buffer or Uint8Array", source);
1964
+ return NULL;
1965
+ }
1966
+ const ScrBytes *input = source->v.bytes;
1967
+ size_t len = input->len;
1968
+ if (!len) { ScrBytes *empty = scr_bytes_alloc(SCR_BYTES_U8, 0); empty->is_buffer = true; return empty; }
1969
+ int from_encoding = scr_transcode_encoding(from), to_encoding = scr_transcode_encoding(to);
1970
+ if (from_encoding < 0 || to_encoding < 0) return scr_transcode_error(false);
1971
+ if (len > (SIZE_MAX - 4) / 4) scr_bytes_oom();
1972
+ ScrBytes *result = scr_bytes_alloc(SCR_BYTES_U8, len * 4 + 4);
1973
+ result->is_buffer = true;
1974
+ size_t written = 0;
1975
+ if (from_encoding == SCR_TC_UTF8) {
1976
+ if (to_encoding == SCR_TC_UTF16 && !scr_buffer_utf8_valid(input->data, len)) {
1977
+ scr_bytes_release(result); return scr_transcode_error(true);
1978
+ }
1979
+ ScrStr *text = scr_str_from_utf8_lossy(input->data, len);
1980
+ for (size_t i = 0; i < text->len;) {
1981
+ uint32_t cp = scr_bytes_next_cp((const uint8_t *)text->data, &i);
1982
+ written = scr_transcode_put(result->data, written, cp, to_encoding);
1983
+ }
1984
+ scr_str_release(text);
1985
+ } else if (from_encoding == SCR_TC_UTF16) {
1986
+ size_t end = to_encoding == SCR_TC_UTF16 ? len : len & ~(size_t)1;
1987
+ if (to_encoding == SCR_TC_UTF8 && end == 0) { scr_bytes_release(result); return scr_transcode_error(true); }
1988
+ for (size_t i = 0; i < end;) {
1989
+ uint32_t cp = 0xfffd;
1990
+ bool invalid = false;
1991
+ if (i + 1 < end) {
1992
+ cp = input->data[i] | ((uint32_t)input->data[i + 1] << 8);
1993
+ i += 2;
1994
+ if (cp >= 0xd800 && cp <= 0xdbff) {
1995
+ uint32_t next = i + 1 < end ? input->data[i] | ((uint32_t)input->data[i + 1] << 8) : 0;
1996
+ if (next >= 0xdc00 && next <= 0xdfff) { cp = 0x10000 + ((cp - 0xd800) << 10) + next - 0xdc00; i += 2; }
1997
+ else { cp = 0xfffd; invalid = true; }
1998
+ } else if (cp >= 0xdc00 && cp <= 0xdfff) { cp = 0xfffd; invalid = true; }
1999
+ } else { i++; invalid = true; }
2000
+ if (invalid && to_encoding == SCR_TC_UTF8) { scr_bytes_release(result); return scr_transcode_error(true); }
2001
+ written = scr_transcode_put(result->data, written, cp, to_encoding);
2002
+ }
2003
+ } else {
2004
+ for (size_t i = 0; i < len; i++) {
2005
+ uint32_t cp = input->data[i];
2006
+ if (from_encoding == SCR_TC_ASCII && cp > 0x7f && to_encoding != SCR_TC_UTF16) cp = 0xfffd;
2007
+ written = scr_transcode_put(result->data, written, cp, to_encoding);
2008
+ }
2009
+ }
2010
+ result->len = written;
2011
+ return result;
2012
+ }
2013
+
1788
2014
  static bool scr_enc_is(const ScrStr *enc, const char *name) {
1789
2015
  size_t n = strlen(name);
1790
2016
  return enc->len == n && memcmp(enc->data, name, n) == 0;