@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.
- package/dist/THIRD_PARTY_NOTICES +1 -1
- package/dist/bin/scriptc +0 -0
- package/dist/bin/scriptc.json +1 -1
- package/dist/lib/declarations/scriptc-node-fallback.d.ts +158 -31
- package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
- package/dist/lib/llvm/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_crypto_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_qs.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_crypto_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_qs.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_web.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_crypto_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_qs.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_crypto_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_qs.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_web.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/runtime-pack.json +423 -297
- package/dist/lib/runtime-sources/package.json +1 -1
- package/dist/lib/runtime-sources/src/scr_abort.c +5 -0
- package/dist/lib/runtime-sources/src/scr_array.c +5 -0
- package/dist/lib/runtime-sources/src/scr_assert.c +26 -0
- package/dist/lib/runtime-sources/src/scr_async.c +56 -4
- package/dist/lib/runtime-sources/src/scr_async_dyn.c +118 -24
- package/dist/lib/runtime-sources/src/scr_bytes.c +226 -0
- package/dist/lib/runtime-sources/src/scr_bytes_io.c +355 -51
- package/dist/lib/runtime-sources/src/scr_crypto_async.c +22 -2
- package/dist/lib/runtime-sources/src/scr_dyn_invoke.c +181 -43
- package/dist/lib/runtime-sources/src/scr_events.c +9 -0
- package/dist/lib/runtime-sources/src/scr_exception.c +1 -0
- package/dist/lib/runtime-sources/src/scr_fetch.c +45 -1
- package/dist/lib/runtime-sources/src/scr_file_handle.c +42 -0
- package/dist/lib/runtime-sources/src/scr_island.c +2166 -786
- package/dist/lib/runtime-sources/src/scr_island_manifest.h +19 -13
- package/dist/lib/runtime-sources/src/scr_json.c +584 -54
- package/dist/lib/runtime-sources/src/scr_json.test.ts +1 -0
- package/dist/lib/runtime-sources/src/scr_lib.c +1192 -43
- package/dist/lib/runtime-sources/src/scr_map.c +8 -0
- package/dist/lib/runtime-sources/src/scr_node_builtin.c +78 -0
- package/dist/lib/runtime-sources/src/scr_qs.c +10 -0
- package/dist/lib/runtime-sources/src/scr_regex.c +107 -5
- package/dist/lib/runtime-sources/src/scr_runtime.h +136 -9
- package/dist/lib/runtime-sources/src/scr_symbol.c +5 -0
- package/dist/lib/runtime-sources/src/scr_system_errors.h +573 -0
- package/dist/lib/runtime-sources/src/scr_text_decoder_labels.h +12 -12
- package/dist/lib/runtime-sources/src/scr_url.c +547 -64
- package/dist/lib/runtime-sources/src/scr_url_internal.h +6 -0
- package/dist/lib/runtime-sources/src/scr_url_params.c +10 -0
- package/dist/lib/runtime-sources/src/scr_util_compare.c +222 -0
- package/dist/lib/runtime-sources/src/scr_util_style.c +337 -0
- package/dist/lib/runtime-sources/src/scr_web.c +849 -264
- 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
|
-
|
|
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
|
|
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 *
|
|
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,
|
|
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
|
|
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 *)
|
|
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
|
|
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
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
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
|
-
|
|
2439
|
+
scr_jb_putc(&shown, '\'');
|
|
2440
|
+
scr_jb_put_str(&shown, value);
|
|
2441
|
+
scr_jb_putc(&shown, '\'');
|
|
2266
2442
|
}
|
|
2267
|
-
|
|
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[
|
|
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[
|
|
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
|
-
|
|
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 *
|
|
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:
|
|
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
|
|
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
|
|
4867
|
-
|
|
4868
|
-
|
|
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
|
|
4938
|
-
static const char message[] = "
|
|
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
|
-
|
|
4948
|
-
|
|
4949
|
-
|
|
4950
|
-
|
|
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
|
|
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
|
-
|
|
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) &&
|
|
6456
|
-
return
|
|
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
|
-
|
|
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
|
-
|
|
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) {
|