@scriptc/cli-darwin-x64 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-x64/artifacts/dev/runtime/default/scr_array.o +0 -0
  8. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_assert.o +0 -0
  9. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async.o +0 -0
  10. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async_dyn.o +0 -0
  11. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
  12. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
  13. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_crypto_async.o +0 -0
  14. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dyn_invoke.o +0 -0
  15. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events.o +0 -0
  16. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_exception.o +0 -0
  17. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
  18. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_json.o +0 -0
  19. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_lib.o +0 -0
  20. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_map.o +0 -0
  21. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
  22. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_qs.o +0 -0
  23. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_regex.o +0 -0
  24. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
  25. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url.o +0 -0
  26. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url_params.o +0 -0
  27. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util_compare.o +0 -0
  28. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util_style.o +0 -0
  29. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
  30. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
  31. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
  32. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async_dyn.o +0 -0
  33. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
  34. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
  35. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_crypto_async.o +0 -0
  36. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dyn_invoke.o +0 -0
  37. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
  38. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
  39. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
  40. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
  41. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
  42. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
  43. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
  44. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
  45. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_qs.o +0 -0
  46. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
  47. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
  48. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
  49. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url_params.o +0 -0
  50. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util_compare.o +0 -0
  51. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util_style.o +0 -0
  52. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_web.o +0 -0
  53. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  54. package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  55. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
  56. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
  57. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
  58. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
  59. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_dyn_invoke.o +0 -0
  60. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
  61. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
  62. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
  63. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
  64. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
  65. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
  66. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
  67. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
  68. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url_params.o +0 -0
  69. package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  70. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_array.o +0 -0
  71. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
  72. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
  73. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
  74. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_dyn_invoke.o +0 -0
  75. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
  76. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_json.o +0 -0
  77. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
  78. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_map.o +0 -0
  79. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
  80. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
  81. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
  82. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url.o +0 -0
  83. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url_params.o +0 -0
  84. package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  85. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
  86. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
  87. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
  88. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
  89. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_dyn_invoke.o +0 -0
  90. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
  91. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
  92. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
  93. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
  94. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
  95. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
  96. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
  97. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
  98. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url_params.o +0 -0
  99. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  100. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
  101. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
  102. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
  103. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
  104. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_dyn_invoke.o +0 -0
  105. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
  106. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
  107. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
  108. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
  109. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
  110. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
  111. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
  112. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
  113. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url_params.o +0 -0
  114. package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  115. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_array.o +0 -0
  116. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_assert.o +0 -0
  117. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async.o +0 -0
  118. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async_dyn.o +0 -0
  119. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes.o +0 -0
  120. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
  121. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_crypto_async.o +0 -0
  122. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dyn_invoke.o +0 -0
  123. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events.o +0 -0
  124. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_exception.o +0 -0
  125. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
  126. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_json.o +0 -0
  127. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_lib.o +0 -0
  128. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_map.o +0 -0
  129. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
  130. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_qs.o +0 -0
  131. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_regex.o +0 -0
  132. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_symbol.o +0 -0
  133. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url.o +0 -0
  134. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url_params.o +0 -0
  135. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util_compare.o +0 -0
  136. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util_style.o +0 -0
  137. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
  138. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
  139. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
  140. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async_dyn.o +0 -0
  141. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
  142. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
  143. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_crypto_async.o +0 -0
  144. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dyn_invoke.o +0 -0
  145. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
  146. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
  147. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
  148. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
  149. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
  150. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
  151. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
  152. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
  153. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_qs.o +0 -0
  154. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
  155. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
  156. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
  157. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url_params.o +0 -0
  158. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util_compare.o +0 -0
  159. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util_style.o +0 -0
  160. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_web.o +0 -0
  161. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
  162. package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
  163. package/dist/lib/runtime-darwin-x64/package.json +1 -1
  164. package/dist/lib/runtime-darwin-x64/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
@@ -57,6 +57,7 @@ static void scr_json_oom(void) {
57
57
 
58
58
  static SCR_TL ScrDyn *scr_iterator_symbol;
59
59
  static SCR_TL ScrDyn *scr_async_iterator_symbol;
60
+ static SCR_TL ScrDyn *scr_to_primitive_symbol;
60
61
  static bool scr_dyn_generator(const ScrDyn *value) {
61
62
  return value && value->kind == SCR_DYN_TYPED_REF &&
62
63
  (!strncmp(value->v.typed_ref.type_key, "generator<", 10) || !strncmp(value->v.typed_ref.type_key, "async-generator<", 16));
@@ -104,6 +105,17 @@ static void scr_async_iterator_symbol_cleanup(void) {
104
105
  scr_async_iterator_symbol = NULL;
105
106
  }
106
107
 
108
+ static void scr_to_primitive_symbol_cleanup(void) {
109
+ scr_dyn_release(scr_to_primitive_symbol);
110
+ scr_to_primitive_symbol = NULL;
111
+ }
112
+
113
+ void scr_dyn_install_to_primitive_symbol(ScrDyn *key) {
114
+ if (scr_to_primitive_symbol) return;
115
+ scr_to_primitive_symbol = scr_dyn_retain(key);
116
+ scr_atexit(scr_to_primitive_symbol_cleanup);
117
+ }
118
+
107
119
  void scr_dyn_install_async_iterator_symbol(ScrDyn *key) {
108
120
  if (scr_async_iterator_symbol) return;
109
121
  scr_async_iterator_symbol = scr_dyn_retain(key);
@@ -524,6 +536,7 @@ static ScrDyn *scr_dyn_alloc(ScrDynKind kind) {
524
536
  d->v.arr.properties = NULL;
525
537
  d->v.arr.sealed = false;
526
538
  d->v.arr.frozen = false;
539
+ d->v.arr.presence = NULL;
527
540
  } else if (kind == SCR_DYN_OBJ) {
528
541
  d->v.obj.len = 0; /* cap/entries preserved */
529
542
  d->v.obj.source_identity = NULL;
@@ -570,6 +583,8 @@ static void scr_dyn_dispose(ScrDyn *d, bool collected) {
570
583
  scr_bytes_release(d->v.bytes);
571
584
  break;
572
585
  case SCR_DYN_ARR:
586
+ free(d->v.arr.presence);
587
+ d->v.arr.presence = NULL;
573
588
  if (!collected) {
574
589
  for (size_t i = 0; i < d->v.arr.len; i++) scr_dyn_release(d->v.arr.items[i]);
575
590
  scr_dyn_release(d->v.arr.properties);
@@ -733,11 +748,31 @@ void scr_dyn_arr_push(ScrDyn *arr, ScrDyn *item) {
733
748
  ScrDyn **items = realloc(arr->v.arr.items, cap * sizeof *items);
734
749
  if (!items) scr_json_oom();
735
750
  arr->v.arr.items = items;
751
+ if (arr->v.arr.presence) {
752
+ unsigned char *presence = realloc(arr->v.arr.presence, cap);
753
+ if (!presence) scr_json_oom();
754
+ arr->v.arr.presence = presence;
755
+ }
736
756
  arr->v.arr.cap = cap;
737
757
  }
758
+ if (arr->v.arr.presence) arr->v.arr.presence[arr->v.arr.len] = 1;
738
759
  arr->v.arr.items[arr->v.arr.len++] = item; /* ownership moves in */
739
760
  }
740
761
 
762
+ bool scr_dyn_arr_has_index(const ScrDyn *arr, size_t index) {
763
+ return index < arr->v.arr.len && (!arr->v.arr.presence || arr->v.arr.presence[index]);
764
+ }
765
+
766
+ void scr_dyn_arr_push_hole(ScrDyn *arr) {
767
+ scr_dyn_arr_push(arr, scr_dyn_retain(scr_dyn_undefined()));
768
+ if (!arr->v.arr.presence) {
769
+ arr->v.arr.presence = malloc(arr->v.arr.cap);
770
+ if (!arr->v.arr.presence) scr_json_oom();
771
+ memset(arr->v.arr.presence, 1, arr->v.arr.len);
772
+ }
773
+ arr->v.arr.presence[arr->v.arr.len - 1] = 0;
774
+ }
775
+
741
776
  /* Spread completion for a runtime-arity argument list (`f(...xs)` in the
742
777
  * checked-dynamic tier): JS's spread over the checked-dynamic tree's iterable kinds —
743
778
  * arrays element-by-element (retained), strings by code POINT (the string
@@ -925,7 +960,13 @@ ScrDyn *scr_dyn_arr_at(const ScrDyn *d, double i) {
925
960
  if (d->kind != SCR_DYN_ARR || i < 0 || i >= (double)d->v.arr.len) {
926
961
  return scr_dyn_retain(scr_dyn_undefined());
927
962
  }
928
- return scr_dyn_retain(d->v.arr.items[(size_t)i]);
963
+ if (scr_dyn_arr_has_index(d, (size_t)i)) return scr_dyn_retain(d->v.arr.items[(size_t)i]);
964
+ char text[32];
965
+ int length = snprintf(text, sizeof text, "%zu", (size_t)i);
966
+ ScrStr *key = scr_str_new(text, (size_t)length);
967
+ ScrDyn *result = scr_dyn_arr_named_get(d, key);
968
+ scr_str_release(key);
969
+ return result;
929
970
  }
930
971
 
931
972
  ScrDyn *scr_dyn_arr_named_get(const ScrDyn *d, const ScrStr *key) {
@@ -933,8 +974,13 @@ ScrDyn *scr_dyn_arr_named_get(const ScrDyn *d, const ScrStr *key) {
933
974
  return scr_dyn_obj_read_receiver(d->v.arr.properties, key->data, key->len, d);
934
975
  const ScrDyn *prototype = d->prototype ? d->prototype :
935
976
  d != scr_builtin_array_prototype ? scr_builtin_array_prototype : NULL;
936
- return prototype ? scr_dyn_obj_read_receiver(prototype, key->data, key->len, d)
977
+ ScrDyn *value = prototype ? scr_dyn_obj_read_receiver(prototype, key->data, key->len, d)
937
978
  : scr_dyn_retain(scr_dyn_undefined());
979
+ if (value && value->kind == SCR_DYN_UNDEF && !d->null_proto && key->len == 11 && !memcmp(key->data, "constructor", 11)) {
980
+ scr_dyn_release(value);
981
+ return scr_dyn_array_constructor();
982
+ }
983
+ return value;
938
984
  }
939
985
 
940
986
  /* Takes ownership of key (malloc'd) and value. Duplicate keys: the LATER
@@ -1177,8 +1223,8 @@ ScrDyn *scr_dyn_set_prototype(ScrDyn *object, ScrDyn *prototype) {
1177
1223
  scr_dyn_release(result);
1178
1224
  return scr_dyn_retain(object);
1179
1225
  }
1180
- if (object->kind != SCR_DYN_OBJ ||
1181
- (prototype->kind != SCR_DYN_OBJ && prototype->kind != SCR_DYN_FUNC && prototype->kind != SCR_DYN_NULL)) {
1226
+ if ((object->kind != SCR_DYN_OBJ && object->kind != SCR_DYN_ARR) ||
1227
+ (prototype->kind != SCR_DYN_OBJ && prototype->kind != SCR_DYN_ARR && prototype->kind != SCR_DYN_FUNC && prototype->kind != SCR_DYN_NULL)) {
1182
1228
  static const char message[] = "Object prototype may only be an Object or null";
1183
1229
  scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
1184
1230
  return NULL;
@@ -1312,7 +1358,7 @@ ScrDyn *scr_dyn_proxy_new(const ScrDyn *target, const ScrDyn *handler) {
1312
1358
  if (scr_exc_pending()) return NULL;
1313
1359
  native_record = plain;
1314
1360
  }
1315
- if ((target->kind != SCR_DYN_OBJ && !native_record) || handler->kind != SCR_DYN_OBJ) {
1361
+ if ((target->kind != SCR_DYN_OBJ && target->kind != SCR_DYN_FUNC && !native_record) || handler->kind != SCR_DYN_OBJ) {
1316
1362
  scr_dyn_proxy_unsupported("non-plain targets or handlers");
1317
1363
  return NULL;
1318
1364
  }
@@ -1330,7 +1376,7 @@ static ScrDyn *scr_dyn_proxy_trap(const ScrDyn *proxy, const char *name) {
1330
1376
  scr_dyn_release(method);
1331
1377
  return NULL;
1332
1378
  }
1333
- if (method->kind != SCR_DYN_FUNC) {
1379
+ if (!scr_dyn_is_callable(method)) {
1334
1380
  ScrJsonBuf msg;
1335
1381
  scr_jb_init(&msg);
1336
1382
  scr_jb_puts(&msg, "Proxy handler '");
@@ -1369,14 +1415,14 @@ static bool scr_dyn_object_proto_key(const ScrDyn *target, const ScrStr *key) {
1369
1415
  return false;
1370
1416
  }
1371
1417
 
1372
- ScrDyn *scr_dyn_proxy_get(const ScrDyn *proxy, const ScrStr *key) {
1418
+ static ScrDyn *scr_dyn_proxy_get_receiver(const ScrDyn *proxy, const ScrStr *key, const ScrDyn *receiver) {
1373
1419
  ScrDyn *trap = scr_dyn_proxy_trap(proxy, "get");
1374
1420
  if (scr_exc_pending()) return NULL;
1375
1421
  if (!trap) {
1376
1422
  ScrDyn *target = proxy->v.proxy.target;
1377
1423
  if (target->kind == SCR_DYN_TYPED_REF) {
1378
1424
  ScrDyn *view = scr_dyn_typed_ref_materialize(target);
1379
- ScrDyn *result = scr_exc_pending() ? NULL : scr_dyn_obj_read_receiver(view, key->data, key->len, proxy);
1425
+ ScrDyn *result = scr_exc_pending() ? NULL : scr_dyn_obj_read_receiver(view, key->data, key->len, receiver);
1380
1426
  scr_dyn_release(view);
1381
1427
  return result;
1382
1428
  }
@@ -1384,10 +1430,10 @@ ScrDyn *scr_dyn_proxy_get(const ScrDyn *proxy, const ScrStr *key) {
1384
1430
  scr_dyn_proxy_unsupported("inherited Object.prototype member reads");
1385
1431
  return NULL;
1386
1432
  }
1387
- return scr_dyn_obj_read(target, key->data, key->len);
1433
+ return scr_dyn_obj_read_receiver(target, key->data, key->len, receiver);
1388
1434
  }
1389
1435
  ScrDyn *property = scr_dyn_new_str((ScrStr *)key);
1390
- ScrDyn *args[] = { proxy->v.proxy.target, property, (ScrDyn *)proxy };
1436
+ ScrDyn *args[] = { proxy->v.proxy.target, property, (ScrDyn *)receiver };
1391
1437
  ScrDyn *result = scr_dyn_proxy_call(proxy, trap, args, 3);
1392
1438
  scr_dyn_release(property);
1393
1439
  ScrDynEntry *entry = scr_dyn_entry(proxy->v.proxy.target, key);
@@ -1401,6 +1447,10 @@ ScrDyn *scr_dyn_proxy_get(const ScrDyn *proxy, const ScrStr *key) {
1401
1447
  return result;
1402
1448
  }
1403
1449
 
1450
+ ScrDyn *scr_dyn_proxy_get(const ScrDyn *proxy, const ScrStr *key) {
1451
+ return scr_dyn_proxy_get_receiver(proxy, key, proxy);
1452
+ }
1453
+
1404
1454
  bool scr_dyn_proxy_has(const ScrDyn *proxy, const ScrStr *key) {
1405
1455
  ScrDyn *trap = scr_dyn_proxy_trap(proxy, "has");
1406
1456
  if (scr_exc_pending()) return false;
@@ -1459,6 +1509,7 @@ ScrDyn *scr_dyn_own_descriptor(const ScrDyn *value, const ScrStr *key) {
1459
1509
  if (scr_dyn_canonical_own_index(key, value->v.arr.len)) {
1460
1510
  size_t index = 0;
1461
1511
  for (size_t i = 0; i < key->len; i++) index = index * 10 + (size_t)(key->data[i] - '0');
1512
+ if (!scr_dyn_arr_has_index(value, index)) return scr_dyn_retain(scr_dyn_undefined());
1462
1513
  ScrDyn *out = scr_dyn_new_obj();
1463
1514
  scr_dyn_obj_set(out, "value", 5, scr_dyn_retain(value->v.arr.items[index]));
1464
1515
  scr_dyn_obj_set(out, "writable", 8, scr_dyn_new_bool(!value->v.arr.frozen));
@@ -1863,6 +1914,56 @@ bool scr_dyn_typed_array_is(const ScrDyn *d, int elem) {
1863
1914
  return d && d->kind == SCR_DYN_BYTES && !d->v.bytes->is_data_view && d->v.bytes->elem == (ScrBytesElem)elem;
1864
1915
  }
1865
1916
 
1917
+ /* Node util.types reads internal brands, never user properties or prototypes. */
1918
+ bool scr_dyn_util_type_is(const ScrDyn *value, const ScrStr *probe) {
1919
+ if (!value) return false;
1920
+ if (value->kind == SCR_DYN_JSVAL) return scr_dyn_jsval_ops()->type_probe(value->v.jsval.cell, probe);
1921
+ #define PROBE(name) (probe->len == sizeof(name) - 1 && memcmp(probe->data, name, sizeof(name) - 1) == 0)
1922
+ if (PROBE("isAnyArrayBuffer") || PROBE("isArrayBuffer")) return scr_array_buffer_is(value);
1923
+ if (PROBE("isArrayBufferView")) return value->kind == SCR_DYN_BYTES;
1924
+ if (PROBE("isDataView")) return value->kind == SCR_DYN_BYTES && value->v.bytes->is_data_view;
1925
+ if (PROBE("isTypedArray")) return value->kind == SCR_DYN_BYTES && !value->v.bytes->is_data_view;
1926
+ if (PROBE("isUint8Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_U8);
1927
+ if (PROBE("isUint8ClampedArray")) return scr_dyn_typed_array_is(value, SCR_BYTES_U8C);
1928
+ if (PROBE("isUint16Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_U16);
1929
+ if (PROBE("isUint32Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_U32);
1930
+ if (PROBE("isInt8Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_I8);
1931
+ if (PROBE("isInt16Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_I16);
1932
+ if (PROBE("isInt32Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_I32);
1933
+ if (PROBE("isFloat32Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_F32);
1934
+ if (PROBE("isFloat64Array")) return scr_dyn_typed_array_is(value, SCR_BYTES_F64);
1935
+ if (PROBE("isMap")) return value->kind == SCR_DYN_HANDLE && value->v.handle.tag == SCR_DYNH_MAP;
1936
+ if (PROBE("isSet")) return value->kind == SCR_DYN_HANDLE && value->v.handle.tag == SCR_DYNH_SET;
1937
+ if (PROBE("isWeakMap")) return value->kind == SCR_DYN_HANDLE && value->v.handle.tag == SCR_DYNH_WEAK_MAP;
1938
+ if (PROBE("isWeakSet")) return value->kind == SCR_DYN_HANDLE && value->v.handle.tag == SCR_DYNH_WEAK_SET;
1939
+ if (PROBE("isRegExp")) return value->kind == SCR_DYN_HANDLE && value->v.handle.tag == SCR_DYNH_REGEXP;
1940
+ if (PROBE("isPromise")) return value->kind == SCR_DYN_PROMISE;
1941
+ if (PROBE("isProxy")) return value->kind == SCR_DYN_PROXY;
1942
+ if (PROBE("isAsyncFunction")) return value->kind == SCR_DYN_FUNC && (value->v.fn.clo->function_kind & 2) != 0;
1943
+ if (PROBE("isGeneratorFunction")) return value->kind == SCR_DYN_FUNC && (value->v.fn.clo->function_kind & 1) != 0;
1944
+ if (PROBE("isGeneratorObject")) return scr_dyn_generator(value);
1945
+ if (PROBE("isNativeError")) {
1946
+ ScrError *error = scr_errdyn_err_of(value);
1947
+ if (!error) return false;
1948
+ scr_error_release(error);
1949
+ return true;
1950
+ }
1951
+ #undef PROBE
1952
+ return false;
1953
+ }
1954
+
1955
+ /* Node's JavaScript wrappers have names/arity; engine-native probes are
1956
+ * anonymous with length zero. Keep their native closure identity intact. */
1957
+ ScrDyn *scr_dyn_util_type_value(const ScrDyn *value, const ScrStr *probe) {
1958
+ static const char *const named[] = { "isTypedArray", "isUint8Array", "isUint8ClampedArray", "isUint16Array", "isUint32Array",
1959
+ "isInt8Array", "isInt16Array", "isInt32Array", "isFloat32Array", "isFloat64Array" };
1960
+ const char *name = "";
1961
+ if (probe->len == 17 && memcmp(probe->data, "isArrayBufferView", 17) == 0) name = "isView";
1962
+ for (size_t i = 0; i < sizeof named / sizeof named[0]; i++)
1963
+ if (probe->len == strlen(named[i]) && memcmp(probe->data, named[i], probe->len) == 0) name = named[i];
1964
+ return scr_dyn_new_func(scr_closure_retain(value->v.fn.clo), value->v.fn.thunk, *name ? 1 : 0, value->v.fn.sig, name);
1965
+ }
1966
+
1866
1967
  bool scr_dyn_bytes_is(const ScrDyn *d, int elem) {
1867
1968
  return d && d->kind == SCR_DYN_BYTES && d->v.bytes->elem == (ScrBytesElem)elem;
1868
1969
  }
@@ -1920,6 +2021,39 @@ ScrDyn *scr_bytes_constructor(const ScrStr *name) {
1920
2021
  scr_trap("scriptc: invalid typed array constructor name\n");
1921
2022
  }
1922
2023
  static SCR_TL ScrDyn *scr_array_buffer_ctor;
2024
+ static SCR_TL ScrDyn *scr_array_ctor;
2025
+ static void scr_array_ctor_cleanup(void) {
2026
+ scr_dyn_release(scr_array_ctor);
2027
+ scr_array_ctor = NULL;
2028
+ }
2029
+ static ScrDyn *scr_array_ctor_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
2030
+ (void)closure;
2031
+ ScrDyn *result = scr_dyn_new_arr();
2032
+ if (argc == 1 && args[0]->kind == SCR_DYN_NUM) {
2033
+ double length = args[0]->v.num;
2034
+ if (!isfinite(length) || length < 0 || length > 4294967295.0 || trunc(length) != length) {
2035
+ scr_dyn_release(result);
2036
+ static const char message[] = "Invalid array length";
2037
+ scr_throw_error_msg(SCR_ERR_RANGE, message, sizeof message - 1);
2038
+ return NULL;
2039
+ }
2040
+ if (length > 1000000) {
2041
+ scr_dyn_release(result);
2042
+ static const char message[] = "Checked array construction exceeds the native allocation limit";
2043
+ scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
2044
+ return NULL;
2045
+ }
2046
+ for (size_t i = 0; i < (size_t)length; i++) scr_dyn_arr_push_hole(result);
2047
+ } else for (size_t i = 0; i < argc; i++) scr_dyn_arr_push(result, scr_dyn_retain(args[i]));
2048
+ return result;
2049
+ }
2050
+ ScrDyn *scr_dyn_array_constructor(void) {
2051
+ if (!scr_array_ctor) {
2052
+ scr_array_ctor = scr_dyn_new_func(scr_closure_new(NULL, 0), scr_array_ctor_call, 1, "native:Array", "Array");
2053
+ scr_atexit(scr_array_ctor_cleanup);
2054
+ }
2055
+ return scr_dyn_retain(scr_array_ctor);
2056
+ }
1923
2057
  static void scr_array_buffer_ctor_cleanup(void) {
1924
2058
  scr_dyn_release(scr_array_buffer_ctor);
1925
2059
  scr_array_buffer_ctor = NULL;
@@ -1945,6 +2079,7 @@ bool scr_bytes_instanceof(const ScrDyn *value, const ScrDyn *callee) {
1945
2079
  return false;
1946
2080
  }
1947
2081
  if (scr_array_buffer_ctor && callee->v.fn.clo == scr_array_buffer_ctor->v.fn.clo) return scr_array_buffer_is(value);
2082
+ if (scr_array_ctor && callee->v.fn.clo == scr_array_ctor->v.fn.clo) return value->kind == SCR_DYN_ARR || scr_dyn_isl_is_array(value);
1948
2083
  for (size_t i = 0; i < 9; i++) {
1949
2084
  if (scr_bytes_ctors[i] && callee->v.fn.clo == scr_bytes_ctors[i]->v.fn.clo)
1950
2085
  return scr_dyn_typed_array_is(value, (int)i);
@@ -1954,6 +2089,8 @@ bool scr_bytes_instanceof(const ScrDyn *value, const ScrDyn *callee) {
1954
2089
  return false;
1955
2090
  }
1956
2091
  ScrDyn *scr_bytes_construct(const ScrDyn *callee, const ScrDyn *args, const ScrStr *what) {
2092
+ if (callee->kind == SCR_DYN_FUNC && scr_array_ctor && callee->v.fn.clo == scr_array_ctor->v.fn.clo)
2093
+ return scr_array_ctor_call(callee->v.fn.clo, args->v.arr.items, args->v.arr.len);
1957
2094
  if (callee->kind == SCR_DYN_FUNC && scr_array_buffer_ctor && callee->v.fn.clo == scr_array_buffer_ctor->v.fn.clo)
1958
2095
  return scr_array_buffer_new(args->v.arr.len ? args->v.arr.items[0] : scr_dyn_undefined());
1959
2096
  for (size_t i = 0; i < 9; i++) {
@@ -2031,6 +2168,11 @@ ScrDyn *scr_dyn_new_chunk(const ScrBytes *b) {
2031
2168
  /* A boxed static function value (the compiler's static→dyn converters).
2032
2169
  * Ownership of the closure MOVES in; sig/name are static literals. */
2033
2170
  ScrDyn *scr_dyn_new_func(ScrClosure *clo, ScrDynThunk thunk, uint32_t arity, const char *sig, const char *name) {
2171
+ if (clo->function_kind & 8) {
2172
+ ScrDyn *original = scr_box_get_ref(clo->caps[0]);
2173
+ scr_closure_release(clo);
2174
+ return original;
2175
+ }
2034
2176
  ScrDyn *d = scr_dyn_alloc(SCR_DYN_FUNC);
2035
2177
  d->v.fn.clo = clo;
2036
2178
  d->v.fn.thunk = thunk;
@@ -2108,6 +2250,19 @@ ScrDyn *scr_dyn_class_prototype(ScrDyn *value, ScrDyn *base) {
2108
2250
  * compiled per signature). Args borrowed; result owned (+1) or NULL with
2109
2251
  * the exception pending. */
2110
2252
  ScrDyn *scr_dyn_call(const ScrDyn *d, ScrDyn *const *args, size_t argc, const char *what) {
2253
+ if (d->kind == SCR_DYN_PROXY && scr_dyn_is_callable(d->v.proxy.target)) {
2254
+ ScrDyn *trap = scr_dyn_proxy_trap(d, "apply");
2255
+ if (scr_exc_pending()) return NULL;
2256
+ if (!trap) return scr_dyn_call(d->v.proxy.target, args, argc, what);
2257
+ ScrDyn *receiver = scr_dyn_this_get();
2258
+ ScrDyn *arguments = scr_dyn_new_arr();
2259
+ for (size_t i = 0; i < argc; i++) scr_dyn_arr_push(arguments, scr_dyn_retain(args[i]));
2260
+ ScrDyn *trap_args[] = { d->v.proxy.target, receiver, arguments };
2261
+ ScrDyn *result = scr_dyn_proxy_call(d, trap, trap_args, 3);
2262
+ scr_dyn_release(arguments);
2263
+ scr_dyn_release(receiver);
2264
+ return result;
2265
+ }
2111
2266
  if (d->kind == SCR_DYN_JSVAL) {
2112
2267
  /* An ENGINE callee: the call routes through scr_jsval_call with the
2113
2268
  * uniform argument conversion (wrapped cells by reference, dyn data
@@ -2218,7 +2373,7 @@ const char *scr_dyn_specific_type(const ScrDyn *cb, char *detail, size_t cap) {
2218
2373
  case SCR_DYN_OBJ: d = "an instance of Object"; break;
2219
2374
  case SCR_DYN_ARR: d = "an instance of Array"; break;
2220
2375
  case SCR_DYN_BYTES:
2221
- snprintf(detail, cap, "an instance of %s", cb->buffer ? "Buffer" : scr_bytes_elem_name(cb->v.bytes->elem));
2376
+ snprintf(detail, cap, "an instance of %s", cb->buffer ? "Buffer" : cb->v.bytes->is_data_view ? "DataView" : scr_bytes_elem_name(cb->v.bytes->elem));
2222
2377
  break;
2223
2378
  case SCR_DYN_FUNC:
2224
2379
  /* determineSpecificType: `function ${value.name}` — anonymous
@@ -2245,26 +2400,51 @@ const char *scr_dyn_specific_type(const ScrDyn *cb, char *detail, size_t cap) {
2245
2400
  case SCR_DYN_BOOL:
2246
2401
  snprintf(detail, cap, "type boolean (%s)", cb->v.b ? "true" : "false");
2247
2402
  break;
2403
+ case SCR_DYN_BIGINT: {
2404
+ ScrStr *value = scr_bigint_inspect(cb->v.bigint);
2405
+ snprintf(detail, cap, "type bigint (%.*s)", (int)value->len, value->data);
2406
+ scr_str_release(value);
2407
+ break;
2408
+ }
2409
+ case SCR_DYN_SYMBOL: {
2410
+ ScrStr *value = cb->v.symbol.render(cb->v.symbol.value);
2411
+ snprintf(detail, cap, "type symbol (%.*s)", (int)value->len, value->data);
2412
+ scr_str_release(value);
2413
+ break;
2414
+ }
2248
2415
  case SCR_DYN_NUM: {
2249
2416
  char num[32];
2250
- size_t n = scr_f64_to_str(cb->v.num, num);
2417
+ size_t n;
2418
+ if (cb->v.num == 0 && signbit(cb->v.num)) { memcpy(num, "-0", 3); n = 2; }
2419
+ else n = scr_f64_to_str(cb->v.num, num);
2251
2420
  snprintf(detail, cap, "type number (%.*s)", (int)n, num);
2252
2421
  break;
2253
2422
  }
2254
2423
  case SCR_DYN_STR: {
2255
- const ScrStr *sv = cb->v.str;
2256
- char insp[32];
2257
- size_t n = 0;
2258
- insp[n++] = '\'';
2259
- for (size_t i = 0; i < sv->len && n < 28; i++) insp[n++] = sv->data[i];
2260
- if (sv->len + 2 > 28) {
2261
- n = 25;
2262
- memcpy(insp + n, "...", 3);
2263
- n += 3;
2424
+ ScrStr *value = scr_str_retain(cb->v.str);
2425
+ if (scr_str_utf16_len(value) > 28) {
2426
+ ScrStr *prefix = scr_str_slice(value, 0, 25);
2427
+ ScrStr *dots = scr_str_new("...", 3);
2428
+ scr_str_release(value);
2429
+ value = scr_str_concat(prefix, dots);
2430
+ scr_str_release(prefix);
2431
+ scr_str_release(dots);
2432
+ }
2433
+ ScrJsonBuf shown;
2434
+ scr_jb_init(&shown);
2435
+ scr_jb_puts(&shown, "type string (");
2436
+ if (memchr(value->data, '\'', value->len)) {
2437
+ scr_jb_put_json_str(&shown, value);
2264
2438
  } else {
2265
- insp[n++] = '\'';
2439
+ scr_jb_putc(&shown, '\'');
2440
+ scr_jb_put_str(&shown, value);
2441
+ scr_jb_putc(&shown, '\'');
2266
2442
  }
2267
- snprintf(detail, cap, "type string (%.*s)", (int)n, insp);
2443
+ scr_jb_putc(&shown, ')');
2444
+ ScrStr *text = scr_jb_finish(&shown);
2445
+ snprintf(detail, cap, "%.*s", (int)text->len, text->data);
2446
+ scr_str_release(text);
2447
+ scr_str_release(value);
2268
2448
  break;
2269
2449
  }
2270
2450
  default: d = "an instance of Object"; break;
@@ -2286,7 +2466,7 @@ void scr_throw_arg_type(const ScrStr *argname, const ScrStr *expected, const Scr
2286
2466
  }
2287
2467
 
2288
2468
  void scr_dyn_arg_type_fail(const char *argname, const char *expected, const ScrDyn *got) {
2289
- char detail[64];
2469
+ char detail[256];
2290
2470
  const char *d = scr_dyn_specific_type(got, detail, sizeof detail);
2291
2471
  ScrJsonBuf b;
2292
2472
  scr_jb_init(&b);
@@ -2307,7 +2487,7 @@ void scr_dyn_arg_type_fail(const char *argname, const char *expected, const ScrD
2307
2487
  * wording on the name, but every property-path caller here knows it is
2308
2488
  * one). Same runtime-rendered Received tail; always throws catchably. */
2309
2489
  void scr_dyn_prop_type_fail(const char *name, const char *expected, const ScrDyn *got) {
2310
- char detail[64];
2490
+ char detail[256];
2311
2491
  const char *d = scr_dyn_specific_type(got, detail, sizeof detail);
2312
2492
  ScrJsonBuf b;
2313
2493
  scr_jb_init(&b);
@@ -2923,7 +3103,17 @@ static ScrDyn *scr_native_iterator_next(ScrNativeIterator *iterator) {
2923
3103
  } else value = iterator->selection == 1 || iterator->kind == 3
2924
3104
  ? scr_map_dyn_key(map, index) : scr_map_dyn_value(map, index);
2925
3105
  } else if (items->kind == SCR_DYN_ARR) {
2926
- value = scr_dyn_arr_at(items, iterator->index++);
3106
+ double index = iterator->index++;
3107
+ if (iterator->selection == 1) value = scr_dyn_new_num(index);
3108
+ else {
3109
+ value = scr_dyn_arr_at(items, index);
3110
+ if (value && iterator->selection == 2) {
3111
+ ScrDyn *entry = scr_dyn_new_arr();
3112
+ scr_dyn_arr_push(entry, scr_dyn_new_num(index));
3113
+ scr_dyn_arr_push(entry, value);
3114
+ value = entry;
3115
+ }
3116
+ }
2927
3117
  } else if (items->kind == SCR_DYN_BYTES) {
2928
3118
  value = scr_dyn_new_num(scr_bytes_get(items->v.bytes, iterator->index++));
2929
3119
  } else {
@@ -3248,6 +3438,15 @@ ScrDyn *scr_dyn_symbol_key_get(const ScrDyn *value, const ScrDyn *key, bool opti
3248
3438
  return out;
3249
3439
  }
3250
3440
 
3441
+ /* Native field tables retain presence and attributes without owning a second
3442
+ * copy of the field's value. This internal update bypasses writable flags. */
3443
+ void scr_dyn_symbol_key_placeholder(ScrDyn *value, ScrDyn *key) {
3444
+ ScrDynEntry *entry = scr_dyn_symbol_entry(value, key, true);
3445
+ if (!entry || entry->accessor) return;
3446
+ scr_dyn_release(entry->value);
3447
+ entry->value = scr_dyn_retain(scr_dyn_undefined());
3448
+ }
3449
+
3251
3450
  void scr_dyn_symbol_key_set(ScrDyn *value, ScrDyn *key, ScrDyn *stored) {
3252
3451
  ScrDyn *receiver = scr_dyn_symbol_receiver(value);
3253
3452
  if (!receiver) {
@@ -3643,6 +3842,7 @@ bool scr_dyn_truthy(const ScrDyn *d) {
3643
3842
  * null answers "object" — JS's oldest wart, preserved. */
3644
3843
  ScrStr *scr_dyn_typeof(const ScrDyn *d) {
3645
3844
  const char *s;
3845
+ if (d->kind == SCR_DYN_PROXY) return scr_dyn_typeof(d->v.proxy.target);
3646
3846
  if (d->kind == SCR_DYN_TYPED_REF) {
3647
3847
  if (d->v.typed_ref.type_key_len >= 7 &&
3648
3848
  memcmp(d->v.typed_ref.type_key, "object:", 7) == 0)
@@ -3677,6 +3877,16 @@ ScrStr *scr_dyn_typeof(const ScrDyn *d) {
3677
3877
  return scr_str_new(s, strlen(s));
3678
3878
  }
3679
3879
 
3880
+ bool scr_dyn_is_callable(const ScrDyn *value) {
3881
+ while (value->kind == SCR_DYN_PROXY) value = value->v.proxy.target;
3882
+ return value->kind == SCR_DYN_FUNC || scr_dyn_isl_typeof_is(value, "function");
3883
+ }
3884
+
3885
+ int scr_dyn_function_kind(const ScrDyn *value) {
3886
+ while (value->kind == SCR_DYN_PROXY) value = value->v.proxy.target;
3887
+ return value->kind == SCR_DYN_FUNC ? value->v.fn.clo->function_kind : 0;
3888
+ }
3889
+
3680
3890
  bool scr_dyn_is_object(const ScrDyn *d) {
3681
3891
  ScrStr *type = scr_dyn_typeof(d);
3682
3892
  bool object = type->len == 6 && memcmp(type->data, "object", 6) == 0;
@@ -4404,7 +4614,16 @@ ScrStr *scr_dyn_string_coerce_js(const ScrDyn *d) {
4404
4614
  for (int i = 0; i < 2; i++) {
4405
4615
  const ScrDyn *owner = scr_dyn_property_owner(d, hint[i], strlen(hint[i]));
4406
4616
  ScrDyn *m = owner ? scr_dyn_obj_read(d, hint[i], strlen(hint[i])) : NULL;
4617
+ if (scr_exc_pending()) { scr_dyn_release(m); return NULL; }
4407
4618
  if (!m && i == 0 && scr_dyn_has_object_prototype(d)) {
4619
+ // Checked Error values retain their Error.prototype formatter even
4620
+ // when their fields are exposed through the cached object view.
4621
+ ScrError *error = scr_errdyn_err_of(d);
4622
+ if (error) {
4623
+ ScrStr *text = scr_error_to_string(error);
4624
+ scr_error_release(error);
4625
+ return text;
4626
+ }
4408
4627
  return scr_str_new("[object Object]", 15);
4409
4628
  }
4410
4629
  if (!m || m->kind != SCR_DYN_FUNC) { scr_dyn_release(m); continue; }
@@ -4430,6 +4649,65 @@ ScrStr *scr_dyn_string_coerce_js(const ScrDyn *d) {
4430
4649
  return scr_dyn_string_coerce(d);
4431
4650
  }
4432
4651
 
4652
+ ScrStr *scr_util_to_usv_string(const ScrDyn *input) {
4653
+ const ScrDyn *value = input ? input : scr_dyn_undefined();
4654
+ /* Native string producers already replace unpaired surrogate code units.
4655
+ * Preserve ToString's object protocol before using that storage invariant. */
4656
+ if (scr_to_primitive_symbol && scr_iterator_object(value)) {
4657
+ ScrDyn *method = scr_dyn_reflect_get((ScrDyn *)value, scr_to_primitive_symbol, (ScrDyn *)value);
4658
+ if (!method) return NULL;
4659
+ if (method->kind != SCR_DYN_UNDEF && method->kind != SCR_DYN_NULL) {
4660
+ if (!scr_dyn_is_callable(method)) {
4661
+ ScrJsonBuf buffer;
4662
+ scr_jb_init(&buffer);
4663
+ if (scr_iterator_object(method)) scr_jb_puts(&buffer, "object");
4664
+ else {
4665
+ ScrStr *type = scr_dyn_typeof(method);
4666
+ scr_jb_put_str(&buffer, type);
4667
+ scr_str_release(type);
4668
+ if (method->kind != SCR_DYN_SYMBOL && method->kind != SCR_DYN_BIGINT) scr_jb_puts(&buffer, " ");
4669
+ if (method->kind == SCR_DYN_STR) {
4670
+ scr_jb_puts(&buffer, "\"");
4671
+ scr_jb_put_str(&buffer, method->v.str);
4672
+ scr_jb_puts(&buffer, "\"");
4673
+ }
4674
+ else if (method->kind != SCR_DYN_SYMBOL && method->kind != SCR_DYN_BIGINT) {
4675
+ ScrStr *text = scr_dyn_string_coerce(method);
4676
+ scr_jb_put_str(&buffer, text);
4677
+ scr_str_release(text);
4678
+ }
4679
+ }
4680
+ scr_jb_puts(&buffer, " is not a function");
4681
+ ScrStr *message = scr_jb_finish(&buffer);
4682
+ scr_throw_error_msg(SCR_ERR_TYPE, message->data, message->len);
4683
+ scr_str_release(message);
4684
+ scr_dyn_release(method);
4685
+ return NULL;
4686
+ }
4687
+ ScrStr *hint = scr_str_new("string", 6);
4688
+ ScrDyn *argument = scr_dyn_new_str(hint);
4689
+ scr_str_release(hint);
4690
+ scr_dyn_this_push_dyn(value);
4691
+ ScrDyn *primitive = scr_dyn_call(method, &argument, 1, "Symbol.toPrimitive");
4692
+ scr_dyn_this_pop();
4693
+ scr_dyn_release(argument);
4694
+ scr_dyn_release(method);
4695
+ if (!primitive) return NULL;
4696
+ if (scr_dyn_to_primitive_result_is_object(primitive)) {
4697
+ static const char message[] = "Cannot convert object to primitive value";
4698
+ scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
4699
+ scr_dyn_release(primitive);
4700
+ return NULL;
4701
+ }
4702
+ ScrStr *text = scr_dyn_string_coerce(primitive);
4703
+ scr_dyn_release(primitive);
4704
+ return text;
4705
+ }
4706
+ scr_dyn_release(method);
4707
+ }
4708
+ return scr_dyn_string_coerce_js(value);
4709
+ }
4710
+
4433
4711
  /* JS ToNumber over a checked-dynamic value, including OrdinaryToPrimitive's
4434
4712
  * NUMBER hint for object snapshots. This is the numeric twin of
4435
4713
  * scr_dyn_string_coerce_js above: valueOf precedes toString, inherited
@@ -4538,14 +4816,26 @@ double scr_dyn_number_constructor(const ScrDyn *d) {
4538
4816
  return result;
4539
4817
  }
4540
4818
 
4541
- ScrBigInt *scr_dyn_bigint_constructor(const ScrDyn *d) {
4819
+ static ScrBigInt *scr_dyn_bigint_convert(const ScrDyn *d, bool allow_number) {
4542
4820
  ScrDyn *primitive = scr_dyn_add_primitive(d);
4543
4821
  if (!primitive) return NULL;
4544
4822
  ScrBigInt *result = NULL;
4545
4823
  switch (primitive->kind) {
4546
4824
  case SCR_DYN_BIGINT: result = scr_bigint_retain(primitive->v.bigint); break;
4547
4825
  case SCR_DYN_STR: result = scr_bigint_parse(primitive->v.str); break;
4548
- case SCR_DYN_NUM: result = scr_bigint_from_f64(primitive->v.num); break;
4826
+ case SCR_DYN_NUM:
4827
+ if (allow_number) result = scr_bigint_from_f64(primitive->v.num);
4828
+ else {
4829
+ ScrStr *text = scr_dyn_string_coerce_js(primitive);
4830
+ ScrJsonBuf message;
4831
+ scr_jb_init(&message);
4832
+ scr_jb_puts(&message, "Cannot convert ");
4833
+ for (size_t i = 0; i < text->len; i++) scr_jb_putc(&message, text->data[i]);
4834
+ scr_jb_puts(&message, " to a BigInt");
4835
+ scr_str_release(text);
4836
+ scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&message));
4837
+ }
4838
+ break;
4549
4839
  case SCR_DYN_BOOL: result = scr_bigint_from_i64(primitive->v.b ? 1 : 0); break;
4550
4840
  default: {
4551
4841
  const char *message = primitive->kind == SCR_DYN_NULL ? "Cannot convert null to a BigInt"
@@ -4558,6 +4848,14 @@ ScrBigInt *scr_dyn_bigint_constructor(const ScrDyn *d) {
4558
4848
  return result;
4559
4849
  }
4560
4850
 
4851
+ ScrBigInt *scr_dyn_bigint_constructor(const ScrDyn *d) {
4852
+ return scr_dyn_bigint_convert(d, true);
4853
+ }
4854
+
4855
+ ScrBigInt *scr_dyn_bigint_coerce(const ScrDyn *d) {
4856
+ return scr_dyn_bigint_convert(d, false);
4857
+ }
4858
+
4561
4859
  /* OrdinaryToPrimitive's default hint is numeric for the represented
4562
4860
  * ordinary objects. Retain the primitive itself: addition must choose
4563
4861
  * string concatenation before either side is converted to a number. */
@@ -4826,6 +5124,8 @@ bool scr_dyn_has_key(const ScrDyn *v, const ScrStr *key) {
4826
5124
  if (v->kind == SCR_DYN_ARR) {
4827
5125
  if (key->len == 6 && memcmp(key->data, "length", 6) == 0) return true;
4828
5126
  if (v->v.arr.properties && scr_dyn_obj_get(v->v.arr.properties, key->data, key->len)) return true;
5127
+ const ScrDyn *prototype = v->prototype ? v->prototype : !v->null_proto && v != scr_builtin_array_prototype ? scr_builtin_array_prototype : NULL;
5128
+ if (prototype && scr_dyn_has_key(prototype, key)) return true;
4829
5129
  if (key->len == 0 || key->len > 10) return false;
4830
5130
  size_t idx = 0;
4831
5131
  for (size_t i = 0; i < key->len; i++) {
@@ -4835,7 +5135,7 @@ bool scr_dyn_has_key(const ScrDyn *v, const ScrStr *key) {
4835
5135
  if (idx > (4294967294ULL - (size_t)(c - '0')) / 10) return false;
4836
5136
  idx = idx * 10 + (size_t)(c - '0');
4837
5137
  }
4838
- return idx < v->v.arr.len;
5138
+ return scr_dyn_arr_has_index(v, idx);
4839
5139
  }
4840
5140
  if (v->kind == SCR_DYN_STR)
4841
5141
  return scr_dyn_canonical_own_index(key, (size_t)scr_str_utf16_len(v->v.str));
@@ -4863,9 +5163,16 @@ static void scr_dyn_object_key_set(ScrDyn *recv, ScrStr *key, ScrDyn *value, con
4863
5163
  }
4864
5164
  }
4865
5165
  if (!scr_dyn_entry(recv, key)) {
4866
- for (const ScrDyn *current = recv->prototype; current && current->kind == SCR_DYN_OBJ; current = current->prototype) {
4867
- ScrDynEntry *inherited = scr_dyn_entry((ScrDyn *)current, key);
4868
- if (!inherited) continue;
5166
+ for (const ScrDyn *current = recv->prototype; current;) {
5167
+ ScrDyn *table = current->kind == SCR_DYN_FUNC ? scr_dyn_fn_properties(current) : NULL;
5168
+ const ScrDyn *object = table ? table : current;
5169
+ if (object->kind != SCR_DYN_OBJ) { scr_dyn_release(table); break; }
5170
+ ScrDynEntry *inherited = scr_dyn_entry((ScrDyn *)object, key);
5171
+ if (!inherited) {
5172
+ current = object->prototype;
5173
+ scr_dyn_release(table);
5174
+ continue;
5175
+ }
4869
5176
  if (inherited->accessor && inherited->setter) {
4870
5177
  ScrDyn *args[] = {value};
4871
5178
  ScrDyn *setter = scr_dyn_retain(inherited->setter);
@@ -4874,13 +5181,16 @@ static void scr_dyn_object_key_set(ScrDyn *recv, ScrStr *key, ScrDyn *value, con
4874
5181
  scr_dyn_this_pop();
4875
5182
  scr_dyn_release(setter);
4876
5183
  scr_dyn_release(result);
5184
+ scr_dyn_release(table);
4877
5185
  return;
4878
5186
  }
4879
5187
  if (inherited->accessor || !inherited->writable) {
4880
5188
  static const char message[] = "Cannot assign to read only property";
4881
5189
  scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
5190
+ scr_dyn_release(table);
4882
5191
  return;
4883
5192
  }
5193
+ scr_dyn_release(table);
4884
5194
  break;
4885
5195
  }
4886
5196
  }
@@ -4934,22 +5244,20 @@ void scr_dyn_key_set(ScrDyn *recv, ScrStr *key, ScrDyn *value) {
4934
5244
  return;
4935
5245
  }
4936
5246
  size_t length = (size_t)number;
4937
- if (length > recv->v.arr.len && recv->non_extensible) {
4938
- static const char message[] = "Cannot add property, object is not extensible";
4939
- scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
4940
- return;
4941
- }
4942
- if (length > recv->v.arr.len) {
4943
- static const char message[] = "Sparse array lengths are not supported yet";
5247
+ if (length > recv->v.arr.len + 1000000) {
5248
+ static const char message[] = "Checked array growth exceeds the native allocation limit";
4944
5249
  scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
4945
5250
  return;
4946
5251
  }
4947
- if (length < recv->v.arr.len && recv->v.arr.sealed) {
4948
- static const char message[] = "Cannot delete non-configurable property";
4949
- scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
4950
- return;
5252
+ while (recv->v.arr.len < length) scr_dyn_arr_push_hole(recv);
5253
+ while (recv->v.arr.len > length) {
5254
+ if (recv->v.arr.sealed && scr_dyn_arr_has_index(recv, recv->v.arr.len - 1)) {
5255
+ static const char message[] = "Cannot delete non-configurable property";
5256
+ scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
5257
+ return;
5258
+ }
5259
+ scr_dyn_release(recv->v.arr.items[--recv->v.arr.len]);
4951
5260
  }
4952
- while (recv->v.arr.len > length) scr_dyn_release(recv->v.arr.items[--recv->v.arr.len]);
4953
5261
  return;
4954
5262
  }
4955
5263
  /* Canonical indexes extend the dense portion; other names live in the
@@ -4967,7 +5275,7 @@ void scr_dyn_key_set(ScrDyn *recv, ScrStr *key, ScrDyn *value) {
4967
5275
  scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
4968
5276
  return;
4969
5277
  }
4970
- if (recv->non_extensible && idx >= recv->v.arr.len) {
5278
+ if (recv->non_extensible && !scr_dyn_arr_has_index(recv, idx)) {
4971
5279
  static const char message[] = "Cannot add property, object is not extensible";
4972
5280
  scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
4973
5281
  return;
@@ -4978,10 +5286,11 @@ void scr_dyn_key_set(ScrDyn *recv, ScrStr *key, ScrDyn *value) {
4978
5286
  return;
4979
5287
  }
4980
5288
  while (recv->v.arr.len <= idx) {
4981
- scr_dyn_arr_push(recv, scr_dyn_retain(scr_dyn_undefined()));
5289
+ scr_dyn_arr_push_hole(recv);
4982
5290
  }
4983
5291
  ScrDyn *old = recv->v.arr.items[idx];
4984
5292
  recv->v.arr.items[idx] = scr_dyn_retain(value);
5293
+ if (recv->v.arr.presence) recv->v.arr.presence[idx] = 1;
4985
5294
  scr_dyn_release(old);
4986
5295
  return;
4987
5296
  }
@@ -5850,6 +6159,27 @@ void scr_dyn_key_delete(ScrDyn *recv, const ScrStr *key, bool strict) {
5850
6159
  scr_error_sync_cause(recv, key);
5851
6160
  return;
5852
6161
  }
6162
+ if (recv->kind == SCR_DYN_ARR && scr_dyn_canonical_own_index(key, recv->v.arr.len)) {
6163
+ size_t index = 0;
6164
+ for (size_t i = 0; i < key->len; i++) index = index * 10 + (size_t)(key->data[i] - '0');
6165
+ if (!scr_dyn_arr_has_index(recv, index)) return;
6166
+ if (recv->v.arr.sealed) {
6167
+ if (strict) {
6168
+ static const char message[] = "Cannot delete non-configurable property";
6169
+ scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
6170
+ }
6171
+ return;
6172
+ }
6173
+ if (!recv->v.arr.presence) {
6174
+ recv->v.arr.presence = malloc(recv->v.arr.cap);
6175
+ if (!recv->v.arr.presence) scr_json_oom();
6176
+ memset(recv->v.arr.presence, 1, recv->v.arr.len);
6177
+ }
6178
+ recv->v.arr.presence[index] = 0;
6179
+ scr_dyn_release(recv->v.arr.items[index]);
6180
+ recv->v.arr.items[index] = scr_dyn_retain(scr_dyn_undefined());
6181
+ return;
6182
+ }
5853
6183
  if (recv->kind == SCR_DYN_ARR && recv->v.arr.properties &&
5854
6184
  scr_dyn_obj_get(recv->v.arr.properties, key->data, key->len)) {
5855
6185
  scr_dyn_key_delete(recv->v.arr.properties, key, strict);
@@ -5953,7 +6283,7 @@ static ScrDyn *scr_json_replace(const ScrDyn *holder, const ScrStr *key, const S
5953
6283
  ScrDyn *view = value->kind == SCR_DYN_TYPED_REF ? scr_dyn_typed_ref_materialize(value) : NULL;
5954
6284
  const ScrDyn *inspected = view ? view : value;
5955
6285
  if (scr_exc_pending()) { scr_dyn_release(view); scr_dyn_release(value); return NULL; }
5956
- if (inspected->kind == SCR_DYN_HANDLE && inspected->v.handle.tag == SCR_DYNH_DATE) {
6286
+ if (inspected->kind == SCR_DYN_HANDLE && (inspected->v.handle.tag == SCR_DYNH_DATE || inspected->v.handle.tag == SCR_DYNH_URL)) {
5957
6287
  const ScrDynHandleOps *ops = scr_dyn_handle_ops_of(inspected);
5958
6288
  ScrDyn *converted = ops->invoke(inspected->v.handle.ptr, value, "toJSON", NULL, 0, "toJSON");
5959
6289
  scr_dyn_release(value);
@@ -6156,6 +6486,36 @@ bool scr_dyn_strict_eq(const ScrDyn *a, const ScrDyn *b) {
6156
6486
  }
6157
6487
  }
6158
6488
 
6489
+ bool scr_dyn_abstract_eq(const ScrDyn *a, const ScrDyn *b) {
6490
+ if (a->kind == b->kind) return scr_dyn_strict_eq(a, b);
6491
+ bool an = a->kind == SCR_DYN_NULL || a->kind == SCR_DYN_UNDEF;
6492
+ bool bn = b->kind == SCR_DYN_NULL || b->kind == SCR_DYN_UNDEF;
6493
+ if (an || bn) return an && bn;
6494
+ if (a->kind == SCR_DYN_BOOL || b->kind == SCR_DYN_BOOL) {
6495
+ ScrDyn *numeric = scr_dyn_new_num(a->kind == SCR_DYN_BOOL ? (a->v.b ? 1 : 0) : (b->v.b ? 1 : 0));
6496
+ bool equal = a->kind == SCR_DYN_BOOL ? scr_dyn_abstract_eq(numeric, b) : scr_dyn_abstract_eq(a, numeric);
6497
+ scr_dyn_release(numeric);
6498
+ return equal;
6499
+ }
6500
+ if (scr_dyn_to_primitive_result_is_object(a) || scr_dyn_to_primitive_result_is_object(b)) {
6501
+ if (scr_dyn_to_primitive_result_is_object(a) && scr_dyn_to_primitive_result_is_object(b)) return scr_dyn_strict_eq(a, b);
6502
+ const ScrDyn *object = scr_dyn_to_primitive_result_is_object(a) ? a : b;
6503
+ ScrDyn *primitive = scr_dyn_add_primitive(object);
6504
+ bool equal = primitive && (object == a ? scr_dyn_abstract_eq(primitive, b) : scr_dyn_abstract_eq(a, primitive));
6505
+ scr_dyn_release(primitive);
6506
+ return equal;
6507
+ }
6508
+ if (a->kind == SCR_DYN_SYMBOL || b->kind == SCR_DYN_SYMBOL) return false;
6509
+ if (a->kind == SCR_DYN_BIGINT || b->kind == SCR_DYN_BIGINT) {
6510
+ const ScrDyn *integer = a->kind == SCR_DYN_BIGINT ? a : b;
6511
+ const ScrDyn *other = integer == a ? b : a;
6512
+ return other->kind == SCR_DYN_STR ? scr_bigint_eq_string(integer->v.bigint, other->v.str)
6513
+ : other->kind == SCR_DYN_NUM && scr_bigint_cmp_number(integer->v.bigint, other->v.num) == 0;
6514
+ }
6515
+ double left, right;
6516
+ return scr_dyn_number_coerce_js(a, &left) && scr_dyn_number_coerce_js(b, &right) && left == right;
6517
+ }
6518
+
6159
6519
  static SCR_TL ScrDyn *scr_function_constructors[4];
6160
6520
  static SCR_TL bool scr_function_constructors_registered;
6161
6521
 
@@ -6234,7 +6594,7 @@ ScrDyn *scr_dyn_fn_get(const ScrDyn *d, const char *key, size_t key_len) {
6234
6594
  return scr_dyn_new_num((double)d->v.fn.arity);
6235
6595
  }
6236
6596
  if (key_len == 5 && memcmp(key, "apply", 5) == 0) return scr_dyn_function_apply();
6237
- if (d->v.fn.class_obj) {
6597
+ if (d->v.fn.class_obj && !d->v.fn.class_obj->static_data) {
6238
6598
  static const char message[] = "scriptc: class properties through unknown other than name and length are not supported";
6239
6599
  scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
6240
6600
  }
@@ -6345,6 +6705,7 @@ static ScrDyn *scr_sc_clone(const ScrDyn *v, const ScrScParent *up) {
6345
6705
  if (v->kind == SCR_DYN_ARR) {
6346
6706
  ScrDyn *out = scr_dyn_new_arr();
6347
6707
  for (size_t i = 0; i < v->v.arr.len; i++) {
6708
+ if (!scr_dyn_arr_has_index(v, i)) { scr_dyn_arr_push_hole(out); continue; }
6348
6709
  ScrDyn *c = scr_sc_clone(v->v.arr.items[i], &self);
6349
6710
  if (c == NULL) { /* threw */
6350
6711
  scr_dyn_release(out);
@@ -6452,8 +6813,8 @@ static ScrDyn *scr_dyn_obj_read_receiver(const ScrDyn *d, const char *key, size_
6452
6813
  if (current->kind == SCR_DYN_ARR) {
6453
6814
  if (key_len == 6 && memcmp(key, "length", 6) == 0) return scr_dyn_new_num((double)current->v.arr.len);
6454
6815
  double index;
6455
- if (scr_dyn_key_is_index(key, key_len, &index) && index < (double)current->v.arr.len)
6456
- return scr_dyn_arr_at(current, index);
6816
+ if (scr_dyn_key_is_index(key, key_len, &index) && scr_dyn_arr_has_index(current, (size_t)index))
6817
+ return scr_dyn_retain(current->v.arr.items[(size_t)index]);
6457
6818
  if (current->v.arr.properties && scr_dyn_obj_get(current->v.arr.properties, key, key_len))
6458
6819
  return scr_dyn_obj_read_receiver(current->v.arr.properties, key, key_len, receiver);
6459
6820
  continue;
@@ -6571,6 +6932,155 @@ ScrDyn *scr_dyn_obj_read(const ScrDyn *d, const char *key, size_t key_len) {
6571
6932
  return scr_dyn_obj_read_receiver(d, key, key_len, d);
6572
6933
  }
6573
6934
 
6935
+ /* Compiler-owned class property tables use their native instance as the
6936
+ * receiver of inherited accessors, retaining field updates on that instance. */
6937
+ ScrDyn *scr_dyn_bag_get(ScrDyn *bag, ScrStr *key, ScrDyn *receiver) {
6938
+ return scr_dyn_obj_read_receiver(bag, key->data, key->len, receiver);
6939
+ }
6940
+
6941
+ void scr_dyn_bag_set(ScrDyn *bag, ScrStr *key, ScrDyn *value, ScrDyn *receiver) {
6942
+ scr_dyn_object_key_set(bag, key, value, receiver);
6943
+ }
6944
+
6945
+ /* Reflect uses OrdinaryGet/OrdinarySet with an independently supplied
6946
+ * receiver. Failed descriptor writes return false; user callbacks still
6947
+ * propagate their exceptions. Keys are converted once before dispatch. */
6948
+ ScrDyn *scr_dyn_reflect_get(ScrDyn *target, ScrDyn *raw_key, ScrDyn *receiver) {
6949
+ if (!scr_dyn_to_primitive_result_is_object(target)) {
6950
+ static const char message[] = "Reflect.get called on non-object";
6951
+ scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
6952
+ return NULL;
6953
+ }
6954
+ ScrDyn *key = scr_dyn_property_key_value(raw_key);
6955
+ if (!key) return NULL;
6956
+ ScrDyn *result = NULL;
6957
+ if (target->kind == SCR_DYN_TYPED_REF) {
6958
+ ScrDyn *view = scr_dyn_typed_ref_materialize(target);
6959
+ if (!scr_exc_pending()) result = scr_dyn_reflect_get(view, key, receiver);
6960
+ scr_dyn_release(view);
6961
+ } else if (key->kind == SCR_DYN_SYMBOL) {
6962
+ ScrDyn *symbols = scr_dyn_symbol_receiver(target);
6963
+ ScrDynEntry *entry = symbols ? scr_dyn_symbol_entry(symbols, key, false) : NULL;
6964
+ if (entry && entry->accessor && entry->getter) {
6965
+ ScrDyn *getter = scr_dyn_retain(entry->getter);
6966
+ scr_dyn_this_push_dyn(receiver);
6967
+ result = scr_dyn_call(getter, NULL, 0, "getter");
6968
+ scr_dyn_this_pop();
6969
+ scr_dyn_release(getter);
6970
+ } else result = scr_dyn_symbol_key_get(target, key, false);
6971
+ scr_dyn_release(symbols);
6972
+ } else if (target->kind == SCR_DYN_PROXY) result = scr_dyn_proxy_get_receiver(target, key->v.str, receiver);
6973
+ else result = scr_dyn_obj_read_receiver(target, key->v.str->data, key->v.str->len, receiver);
6974
+ scr_dyn_release(key);
6975
+ return result;
6976
+ }
6977
+
6978
+ bool scr_dyn_reflect_define(ScrDyn *receiver, ScrDyn *raw_key, ScrDyn *value) {
6979
+ if (!scr_dyn_to_primitive_result_is_object(receiver)) return false;
6980
+ ScrDyn *key = scr_dyn_property_key_value(raw_key);
6981
+ if (!key) return false;
6982
+ bool ok = false;
6983
+ if (receiver->kind == SCR_DYN_TYPED_REF) {
6984
+ ScrDyn *view = scr_dyn_typed_ref_materialize(receiver);
6985
+ if (!scr_exc_pending()) ok = scr_dyn_reflect_define(view, key, value);
6986
+ if (ok) scr_dyn_typed_ref_commit(receiver);
6987
+ scr_dyn_release(view);
6988
+ } else if (receiver->kind == SCR_DYN_PROXY) {
6989
+ scr_dyn_proxy_unsupported("Reflect.set receiver definition");
6990
+ } else if (receiver->kind == SCR_DYN_FUNC) {
6991
+ ScrDyn *table = scr_dyn_fn_properties(receiver);
6992
+ ok = scr_dyn_reflect_define(table, key, value);
6993
+ scr_dyn_release(table);
6994
+ } else {
6995
+ ScrDyn *symbols = key->kind == SCR_DYN_SYMBOL ? scr_dyn_symbol_receiver(receiver) : NULL;
6996
+ ScrDynEntry *entry = key->kind == SCR_DYN_SYMBOL ? (symbols ? scr_dyn_symbol_entry(symbols, key, true) : NULL)
6997
+ : receiver->kind == SCR_DYN_OBJ ? scr_dyn_entry(receiver, key->v.str)
6998
+ : receiver->kind == SCR_DYN_ARR && receiver->v.arr.properties ? scr_dyn_entry(receiver->v.arr.properties, key->v.str) : NULL;
6999
+ if (!(entry && (entry->accessor || !entry->writable)) && !(receiver->non_extensible && !scr_dyn_has_own_computed(receiver, key))) {
7000
+ if (entry) {
7001
+ ScrDyn *old = entry->value;
7002
+ entry->value = scr_dyn_retain(value);
7003
+ scr_dyn_release(old);
7004
+ ok = true;
7005
+ } else if (key->kind == SCR_DYN_SYMBOL && symbols) {
7006
+ ScrDyn *descriptor = scr_dyn_new_obj();
7007
+ scr_dyn_obj_set(descriptor, "value", 5, scr_dyn_retain(value));
7008
+ scr_dyn_obj_set(descriptor, "writable", 8, scr_dyn_new_bool(true));
7009
+ scr_dyn_obj_set(descriptor, "enumerable", 10, scr_dyn_new_bool(true));
7010
+ scr_dyn_obj_set(descriptor, "configurable", 12, scr_dyn_new_bool(true));
7011
+ ScrDyn *defined = scr_dyn_define_symbol(receiver, key, descriptor);
7012
+ scr_dyn_release(defined);
7013
+ scr_dyn_release(descriptor);
7014
+ ok = !scr_exc_pending();
7015
+ } else if (receiver->kind == SCR_DYN_OBJ) {
7016
+ scr_dyn_obj_set(receiver, key->v.str->data, key->v.str->len, scr_dyn_retain(value));
7017
+ ok = true;
7018
+ } else if (receiver->kind == SCR_DYN_ARR) {
7019
+ if (!receiver->v.arr.frozen) {
7020
+ scr_dyn_key_set(receiver, key->v.str, value);
7021
+ ok = !scr_exc_pending();
7022
+ }
7023
+ }
7024
+ }
7025
+ scr_dyn_release(symbols);
7026
+ }
7027
+ scr_dyn_release(key);
7028
+ return ok && !scr_exc_pending();
7029
+ }
7030
+
7031
+ bool scr_dyn_reflect_set(ScrDyn *target, ScrDyn *raw_key, ScrDyn *value, ScrDyn *receiver) {
7032
+ if (!scr_dyn_to_primitive_result_is_object(target)) {
7033
+ static const char message[] = "Reflect.set called on non-object";
7034
+ scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
7035
+ return false;
7036
+ }
7037
+ ScrDyn *key = scr_dyn_property_key_value(raw_key);
7038
+ if (!key) return false;
7039
+ bool ok = false;
7040
+ if (target->kind == SCR_DYN_TYPED_REF) {
7041
+ ScrDyn *view = scr_dyn_typed_ref_materialize(target);
7042
+ if (!scr_exc_pending()) ok = scr_dyn_reflect_set(view, key, value, receiver);
7043
+ scr_dyn_release(view);
7044
+ } else if (target->kind == SCR_DYN_PROXY) {
7045
+ ScrDyn *trap = scr_dyn_proxy_trap(target, "set");
7046
+ if (!scr_exc_pending() && !trap) ok = scr_dyn_reflect_set(target->v.proxy.target, key, value, receiver);
7047
+ else if (trap) {
7048
+ ScrDyn *args[] = {target->v.proxy.target, key, value, receiver};
7049
+ ScrDyn *result = scr_dyn_proxy_call(target, trap, args, 4);
7050
+ ok = result && scr_dyn_truthy(result);
7051
+ scr_dyn_release(result);
7052
+ ScrDynEntry *entry = key->kind == SCR_DYN_STR ? scr_dyn_entry(target->v.proxy.target, key->v.str) : NULL;
7053
+ if (ok && entry && !entry->configurable && ((entry->accessor && !entry->setter) || (!entry->accessor && !entry->writable && !scr_dyn_property_same_value(entry->value, value)))) scr_dyn_proxy_invariant();
7054
+ }
7055
+ } else if (target->kind == SCR_DYN_FUNC) {
7056
+ ScrDyn *table = scr_dyn_fn_properties(target);
7057
+ ok = scr_dyn_reflect_set(table, key, value, receiver);
7058
+ scr_dyn_release(table);
7059
+ } else {
7060
+ ScrDyn *symbols = key->kind == SCR_DYN_SYMBOL ? scr_dyn_symbol_receiver(target) : NULL;
7061
+ ScrDynEntry *entry = symbols ? scr_dyn_symbol_entry(symbols, key, false) : NULL;
7062
+ if (key->kind == SCR_DYN_STR) for (ScrDyn *current = target; current; current = current->prototype) {
7063
+ if (current->kind == SCR_DYN_OBJ) entry = scr_dyn_entry(current, key->v.str);
7064
+ else if (current->kind == SCR_DYN_ARR && current->v.arr.properties) entry = scr_dyn_entry(current->v.arr.properties, key->v.str);
7065
+ if (entry) break;
7066
+ }
7067
+ if (entry && entry->accessor) {
7068
+ if (entry->setter) {
7069
+ ScrDyn *setter = scr_dyn_retain(entry->setter);
7070
+ scr_dyn_this_push_dyn(receiver);
7071
+ ScrDyn *result = scr_dyn_call(setter, &value, 1, "setter");
7072
+ scr_dyn_this_pop();
7073
+ scr_dyn_release(result);
7074
+ scr_dyn_release(setter);
7075
+ ok = !scr_exc_pending();
7076
+ }
7077
+ } else if (!entry || entry->writable) ok = scr_dyn_reflect_define(receiver, key, value);
7078
+ scr_dyn_release(symbols);
7079
+ }
7080
+ scr_dyn_release(key);
7081
+ return ok && !scr_exc_pending();
7082
+ }
7083
+
6574
7084
  /* ── Object.keys/values/entries over the checked-dynamic tree ──────────────────────────
6575
7085
  * JS own-key order: array-index keys ascending first, then the rest in
6576
7086
  * insertion order. entries answers [key, value] pairs; values RETAIN
@@ -6659,6 +7169,7 @@ ScrDyn *scr_dyn_get_own_property_names(const ScrDyn *value) {
6659
7169
  value->kind == SCR_DYN_BYTES ? value->v.bytes->len :
6660
7170
  (size_t)scr_str_utf16_len(value->v.str);
6661
7171
  for (size_t i = 0; i < length; i++) {
7172
+ if (value->kind == SCR_DYN_ARR && !scr_dyn_arr_has_index(value, i)) continue;
6662
7173
  char name[24];
6663
7174
  int size = snprintf(name, sizeof name, "%zu", i);
6664
7175
  scr_dyn_arr_push(keys, scr_dyn_objwalk_key(name, (size_t)size));
@@ -6916,6 +7427,7 @@ static ScrDyn *scr_dyn_objwalk(const ScrDyn *v, ScrObjWalk mode) {
6916
7427
  if (v->kind == SCR_DYN_ARR || v->kind == SCR_DYN_BYTES) {
6917
7428
  size_t n = v->kind == SCR_DYN_ARR ? v->v.arr.len : v->v.bytes->len;
6918
7429
  for (size_t i = 0; i < n; i++) {
7430
+ if (v->kind == SCR_DYN_ARR && !scr_dyn_arr_has_index(v, i)) continue;
6919
7431
  char key[24];
6920
7432
  int klen = snprintf(key, sizeof key, "%zu", i);
6921
7433
  ScrDyn *val = NULL;
@@ -6981,7 +7493,8 @@ ScrDyn *scr_dyn_obj_keys(const ScrDyn *v) { return scr_dyn_objwalk(v, SCR_OBJWAL
6981
7493
  * Non-enumerable own names shadow names farther up the chain. */
6982
7494
  ScrDyn *scr_dyn_for_in_keys(const ScrDyn *v) {
6983
7495
  if (scr_dyn_class_reflection_fence(v)) return NULL;
6984
- if (v->kind == SCR_DYN_TYPED_REF && scr_dyn_isl_is_array(v)) {
7496
+ if (v->kind == SCR_DYN_TYPED_REF && (scr_dyn_isl_is_array(v) ||
7497
+ !strncmp(v->v.typed_ref.type_key, "record:", 7))) {
6985
7498
  ScrDyn *view = scr_dyn_typed_ref_materialize(v);
6986
7499
  ScrDyn *keys = scr_exc_pending() ? NULL : scr_dyn_for_in_keys(view);
6987
7500
  scr_dyn_release(view);
@@ -7238,6 +7751,19 @@ ScrDyn *scr_dyn_copy_property_descriptors(ScrDyn *target, const ScrDyn *src) {
7238
7751
  if (scr_exc_pending()) break;
7239
7752
  }
7240
7753
  scr_dyn_release(keys);
7754
+ if (!scr_exc_pending()) {
7755
+ ScrDyn *symbols = scr_dyn_get_own_property_symbols(src);
7756
+ if (!symbols) return NULL;
7757
+ for (size_t i = 0; i < symbols->v.arr.len; i++) {
7758
+ ScrDyn *key = symbols->v.arr.items[i];
7759
+ ScrDyn *descriptor = scr_dyn_get_own_property_descriptor((ScrDyn *)src, key);
7760
+ ScrDyn *result = descriptor ? scr_dyn_define_property(target, key, descriptor) : NULL;
7761
+ scr_dyn_release(descriptor);
7762
+ scr_dyn_release(result);
7763
+ if (scr_exc_pending()) break;
7764
+ }
7765
+ scr_dyn_release(symbols);
7766
+ }
7241
7767
  return scr_exc_pending() ? NULL : scr_dyn_retain(target);
7242
7768
  }
7243
7769
 
@@ -7427,7 +7953,10 @@ bool scr_dyn_has_own(const ScrDyn *v, const ScrStr *key) {
7427
7953
  if (v->kind == SCR_DYN_ARR) {
7428
7954
  if (key->len == 6 && memcmp(key->data, "length", 6) == 0) return true;
7429
7955
  if (v->v.arr.properties && scr_dyn_obj_get(v->v.arr.properties, key->data, key->len)) return true;
7430
- return scr_dyn_canonical_own_index(key, v->v.arr.len);
7956
+ if (!scr_dyn_canonical_own_index(key, v->v.arr.len)) return false;
7957
+ size_t index = 0;
7958
+ for (size_t i = 0; i < key->len; i++) index = index * 10 + (size_t)(key->data[i] - '0');
7959
+ return scr_dyn_arr_has_index(v, index);
7431
7960
  }
7432
7961
  if (v->kind == SCR_DYN_STR) {
7433
7962
  if (key->len == 6 && memcmp(key->data, "length", 6) == 0) return true;
@@ -7468,7 +7997,7 @@ bool scr_dyn_property_is_enumerable(const ScrDyn *value, const ScrStr *key) {
7468
7997
  if (value->kind == SCR_DYN_STR)
7469
7998
  return scr_dyn_canonical_own_index(key, (size_t)scr_str_utf16_len(value->v.str));
7470
7999
  if (value->kind == SCR_DYN_ARR)
7471
- return scr_dyn_canonical_own_index(key, value->v.arr.len) ||
8000
+ return (scr_dyn_canonical_own_index(key, value->v.arr.len) && scr_dyn_has_own(value, key)) ||
7472
8001
  (value->v.arr.properties && scr_dyn_obj_enumerable(value->v.arr.properties, key->data, key->len));
7473
8002
  if (value->kind == SCR_DYN_BYTES)
7474
8003
  return scr_dyn_canonical_own_index(key, value->v.bytes->len);
@@ -8810,7 +9339,8 @@ ScrMap *scr_dyn_native_map_check(const ScrDyn *value, const ScrDynPath *path) {
8810
9339
  bool scr_dyn_native_collection_is(const ScrDyn *value, int map, const char *type) {
8811
9340
  if (!(map ? scr_dyn_native_map_is(value) : scr_dyn_native_set_is(value))) return false;
8812
9341
  const ScrMap *storage = value->v.handle.ptr;
8813
- return type ? storage->dyn_ops && strcmp(storage->dyn_ops->type, type) == 0 : !storage->dyn_ops;
9342
+ // A generic checked view uses dyn_ops to box/unbox the same live storage.
9343
+ return !type || (storage->dyn_ops && strcmp(storage->dyn_ops->type, type) == 0);
8814
9344
  }
8815
9345
 
8816
9346
  ScrMap *scr_dyn_native_collection_check(const ScrDyn *value, int map, const char *type, const ScrDynPath *path) {