@scriptc/cli-darwin-arm64 0.2.0 → 0.2.1
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 +25 -15
- package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
- package/dist/lib/llvm/package.json +1 -1
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_fetch.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_http.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_http2.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_net.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_http.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_http2.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_net.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/licenses/v8-number-radix.txt +61 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_fetch.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_http.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_http2.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_net.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/default/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_http.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_http2.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_net.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-arm64/package.json +1 -1
- package/dist/lib/runtime-darwin-arm64/runtime-pack.json +529 -525
- package/dist/lib/runtime-sources/package.json +1 -1
- package/dist/lib/runtime-sources/src/scr_array.c +16 -0
- package/dist/lib/runtime-sources/src/scr_assert.c +1 -0
- package/dist/lib/runtime-sources/src/scr_async.c +26 -1
- package/dist/lib/runtime-sources/src/scr_async_dyn.c +90 -16
- package/dist/lib/runtime-sources/src/scr_bigint.c +8 -0
- package/dist/lib/runtime-sources/src/scr_bytes.c +205 -41
- package/dist/lib/runtime-sources/src/scr_bytes_io.c +581 -12
- package/dist/lib/runtime-sources/src/scr_child.c +544 -17
- package/dist/lib/runtime-sources/src/scr_console.c +1 -1
- package/dist/lib/runtime-sources/src/scr_dyn_invoke.c +164 -31
- package/dist/lib/runtime-sources/src/scr_error.c +52 -5
- package/dist/lib/runtime-sources/src/scr_exception.c +21 -5
- package/dist/lib/runtime-sources/src/scr_fetch.c +266 -2
- package/dist/lib/runtime-sources/src/scr_http.c +3 -0
- package/dist/lib/runtime-sources/src/scr_island.c +38 -13
- package/dist/lib/runtime-sources/src/scr_json.c +1149 -91
- package/dist/lib/runtime-sources/src/scr_map.c +47 -0
- package/dist/lib/runtime-sources/src/scr_node_builtin.c +10 -0
- package/dist/lib/runtime-sources/src/scr_object.c +11 -0
- package/dist/lib/runtime-sources/src/scr_regex.c +108 -69
- package/dist/lib/runtime-sources/src/scr_runtime.h +190 -33
- package/dist/lib/runtime-sources/src/scr_stream.c +197 -0
- package/dist/lib/runtime-sources/src/scr_string.c +16 -1
- package/dist/lib/runtime-sources/src/scr_symbol.c +5 -0
- package/dist/lib/runtime-sources/src/scr_text_decoder_labels.h +225 -0
- package/dist/lib/runtime-sources/src/scr_url.c +172 -3
- package/dist/lib/runtime-sources/vendor/v8-number-radix/LICENSE +61 -0
- package/package.json +1 -1
|
@@ -23,10 +23,17 @@
|
|
|
23
23
|
*/
|
|
24
24
|
#include "scr_runtime.h"
|
|
25
25
|
|
|
26
|
+
static SCR_TL ScrDyn *scr_builtin_object_prototype;
|
|
27
|
+
|
|
26
28
|
/* Constructor capsules expose identity and name/length, but do not model
|
|
27
29
|
* per-class static property tables yet. Never report a fabricated empty view. */
|
|
28
30
|
static bool scr_dyn_class_reflection_fence(const ScrDyn *value) {
|
|
29
|
-
if (
|
|
31
|
+
if (value && value == scr_builtin_object_prototype) {
|
|
32
|
+
static const char message[] = "scriptc: Object.prototype reflection and mutation are not supported yet";
|
|
33
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (!value || value->kind != SCR_DYN_FUNC || !value->v.fn.class_obj || value->v.fn.class_obj->static_data) return false;
|
|
30
37
|
static const char message[] = "scriptc: class reflection through unknown is not supported";
|
|
31
38
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
32
39
|
return true;
|
|
@@ -49,12 +56,22 @@ static void scr_json_oom(void) {
|
|
|
49
56
|
}
|
|
50
57
|
|
|
51
58
|
static SCR_TL ScrDyn *scr_iterator_symbol;
|
|
59
|
+
static SCR_TL ScrDyn *scr_async_iterator_symbol;
|
|
60
|
+
static bool scr_dyn_generator(const ScrDyn *value) {
|
|
61
|
+
return value && value->kind == SCR_DYN_TYPED_REF &&
|
|
62
|
+
(!strncmp(value->v.typed_ref.type_key, "generator<", 10) || !strncmp(value->v.typed_ref.type_key, "async-generator<", 16));
|
|
63
|
+
}
|
|
64
|
+
static bool scr_dyn_generator_symbol(const ScrDyn *value, const ScrDyn *key) {
|
|
65
|
+
const ScrDyn *symbol = value->v.typed_ref.type_key[0] == 'a' ? scr_async_iterator_symbol : scr_iterator_symbol;
|
|
66
|
+
return symbol && key->v.symbol.value == symbol->v.symbol.value;
|
|
67
|
+
}
|
|
52
68
|
static ScrDyn *scr_builtin_iterator_method(const ScrDyn *value);
|
|
53
69
|
static bool scr_builtin_iterable(const ScrDyn *value) {
|
|
54
70
|
return value->kind == SCR_DYN_ARR || value->kind == SCR_DYN_STR || value->kind == SCR_DYN_BYTES ||
|
|
71
|
+
(scr_dyn_generator(value) && value->v.typed_ref.type_key[0] != 'a') ||
|
|
55
72
|
(value->kind == SCR_DYN_TYPED_REF && scr_dyn_isl_is_array(value)) ||
|
|
56
|
-
(value->kind == SCR_DYN_HANDLE && (value->v.handle.tag == SCR_DYNH_ITERATOR ||
|
|
57
|
-
scr_dyn_handle_ops_of(value)->iter_pack));
|
|
73
|
+
(value->kind == SCR_DYN_HANDLE && (value->v.handle.tag == SCR_DYNH_ITERATOR || value->v.handle.tag == SCR_DYNH_MAP || value->v.handle.tag == SCR_DYNH_SET ||
|
|
74
|
+
scr_dyn_handle_ops_of(value)->iter_pack || scr_dyn_handle_ops_of(value)->iter_step));
|
|
58
75
|
}
|
|
59
76
|
static bool scr_iterator_object(const ScrDyn *value) {
|
|
60
77
|
switch (value->kind) {
|
|
@@ -82,6 +99,17 @@ static void scr_iterator_symbol_cleanup(void) {
|
|
|
82
99
|
scr_iterator_symbol = NULL;
|
|
83
100
|
}
|
|
84
101
|
|
|
102
|
+
static void scr_async_iterator_symbol_cleanup(void) {
|
|
103
|
+
scr_dyn_release(scr_async_iterator_symbol);
|
|
104
|
+
scr_async_iterator_symbol = NULL;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
void scr_dyn_install_async_iterator_symbol(ScrDyn *key) {
|
|
108
|
+
if (scr_async_iterator_symbol) return;
|
|
109
|
+
scr_async_iterator_symbol = scr_dyn_retain(key);
|
|
110
|
+
scr_atexit(scr_async_iterator_symbol_cleanup);
|
|
111
|
+
}
|
|
112
|
+
|
|
85
113
|
void scr_dyn_install_iterator_symbol(ScrDyn *key) {
|
|
86
114
|
if (scr_iterator_symbol) return;
|
|
87
115
|
scr_iterator_symbol = scr_dyn_retain(key);
|
|
@@ -408,6 +436,8 @@ void scr_dyn_trace_v(void *ptr, ScrTraceVisit visit, void *ctx) {
|
|
|
408
436
|
case SCR_DYN_TYPED_REF:
|
|
409
437
|
visit(d->v.typed_ref.materialized, ctx);
|
|
410
438
|
if (d->v.typed_ref.traced) visit(d->v.typed_ref.ptr, ctx);
|
|
439
|
+
for (ScrDynTypedCast *cast = d->v.typed_ref.casts; cast; cast = cast->next)
|
|
440
|
+
if (cast->traced) visit(cast->ptr, ctx);
|
|
411
441
|
break;
|
|
412
442
|
case SCR_DYN_HANDLE:
|
|
413
443
|
if (d->v.handle.traced) visit(d->v.handle.ptr, ctx);
|
|
@@ -416,6 +446,56 @@ void scr_dyn_trace_v(void *ptr, ScrTraceVisit visit, void *ctx) {
|
|
|
416
446
|
}
|
|
417
447
|
}
|
|
418
448
|
|
|
449
|
+
typedef struct ScrTypedRefIdentity {
|
|
450
|
+
ScrDyn *value; /* weak; removed before capsule disposal */
|
|
451
|
+
struct ScrTypedRefIdentity *next;
|
|
452
|
+
} ScrTypedRefIdentity;
|
|
453
|
+
static SCR_TL ScrTypedRefIdentity **scr_typed_ref_identities;
|
|
454
|
+
static SCR_TL size_t scr_typed_ref_capacity, scr_typed_ref_count;
|
|
455
|
+
static size_t scr_typed_ref_bucket(void *ptr) {
|
|
456
|
+
uintptr_t hash = (uintptr_t)ptr >> 4;
|
|
457
|
+
hash ^= hash >> 17;
|
|
458
|
+
hash *= (uintptr_t)0x9e3779b1u;
|
|
459
|
+
hash ^= hash >> 13;
|
|
460
|
+
return hash & (scr_typed_ref_capacity - 1);
|
|
461
|
+
}
|
|
462
|
+
static void scr_typed_ref_reserve(void) {
|
|
463
|
+
if (scr_typed_ref_capacity && scr_typed_ref_count < scr_typed_ref_capacity) return;
|
|
464
|
+
size_t old_capacity = scr_typed_ref_capacity;
|
|
465
|
+
ScrTypedRefIdentity **old = scr_typed_ref_identities;
|
|
466
|
+
scr_typed_ref_capacity = old_capacity ? old_capacity * 2 : 1024;
|
|
467
|
+
scr_typed_ref_identities = calloc(scr_typed_ref_capacity, sizeof *scr_typed_ref_identities);
|
|
468
|
+
if (!scr_typed_ref_identities) scr_json_oom();
|
|
469
|
+
for (size_t i = 0; i < old_capacity; i++) {
|
|
470
|
+
ScrTypedRefIdentity *entry = old[i];
|
|
471
|
+
while (entry) {
|
|
472
|
+
ScrTypedRefIdentity *next = entry->next;
|
|
473
|
+
size_t bucket = scr_typed_ref_bucket(entry->value->v.typed_ref.ptr);
|
|
474
|
+
entry->next = scr_typed_ref_identities[bucket];
|
|
475
|
+
scr_typed_ref_identities[bucket] = entry;
|
|
476
|
+
entry = next;
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
free(old);
|
|
480
|
+
}
|
|
481
|
+
static void scr_typed_ref_forget(ScrDyn *value) {
|
|
482
|
+
ScrTypedRefIdentity **link = &scr_typed_ref_identities[scr_typed_ref_bucket(value->v.typed_ref.ptr)];
|
|
483
|
+
while (*link) {
|
|
484
|
+
if ((*link)->value == value) {
|
|
485
|
+
ScrTypedRefIdentity *old = *link;
|
|
486
|
+
*link = old->next;
|
|
487
|
+
free(old);
|
|
488
|
+
if (--scr_typed_ref_count == 0) {
|
|
489
|
+
free(scr_typed_ref_identities);
|
|
490
|
+
scr_typed_ref_identities = NULL;
|
|
491
|
+
scr_typed_ref_capacity = 0;
|
|
492
|
+
}
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
link = &(*link)->next;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
419
499
|
static void scr_dyn_gcfree(void *ptr);
|
|
420
500
|
|
|
421
501
|
static ScrDyn *scr_dyn_alloc(ScrDynKind kind) {
|
|
@@ -527,11 +607,12 @@ static void scr_dyn_dispose(ScrDyn *d, bool collected) {
|
|
|
527
607
|
scr_dyn_jsval_ops()->release(d->v.jsval.cell);
|
|
528
608
|
break;
|
|
529
609
|
case SCR_DYN_TYPED_REF:
|
|
610
|
+
scr_typed_ref_forget(d);
|
|
530
611
|
if (!collected) scr_dyn_release(d->v.typed_ref.materialized);
|
|
531
612
|
while (d->v.typed_ref.casts) {
|
|
532
613
|
ScrDynTypedCast *cast = d->v.typed_ref.casts;
|
|
533
614
|
d->v.typed_ref.casts = cast->next;
|
|
534
|
-
cast->release(cast->ptr);
|
|
615
|
+
if (!collected || !cast->traced) cast->release(cast->ptr);
|
|
535
616
|
free(cast);
|
|
536
617
|
}
|
|
537
618
|
if (!collected || !d->v.typed_ref.traced) d->v.typed_ref.release(d->v.typed_ref.ptr);
|
|
@@ -793,6 +874,10 @@ ScrDyn *scr_dyn_iter_pack(const ScrDyn *src, const ScrStr *msg) {
|
|
|
793
874
|
return scr_dyn_not_iterable(src, msg);
|
|
794
875
|
}
|
|
795
876
|
|
|
877
|
+
ScrDyn *scr_dyn_jsval_iter_n(const ScrDyn *src, double count) {
|
|
878
|
+
return scr_dyn_jsval_ops()->iter_n(src->v.jsval.cell, count);
|
|
879
|
+
}
|
|
880
|
+
|
|
796
881
|
/* The for-of-over-dyn pack accessors: the emitted index loop drives them
|
|
797
882
|
* over a scr_dyn_iter_pack result (ARR by construction — the defensive
|
|
798
883
|
* arms cover nothing reachable from that lowering). Never throw. */
|
|
@@ -966,6 +1051,21 @@ static void scr_builtin_array_prototype_cleanup(void) {
|
|
|
966
1051
|
scr_dyn_release(prototype);
|
|
967
1052
|
}
|
|
968
1053
|
|
|
1054
|
+
static void scr_builtin_object_prototype_cleanup(void) {
|
|
1055
|
+
ScrDyn *prototype = scr_builtin_object_prototype;
|
|
1056
|
+
scr_builtin_object_prototype = NULL;
|
|
1057
|
+
scr_dyn_release(prototype);
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
ScrDyn *scr_dyn_object_prototype(void) {
|
|
1061
|
+
if (!scr_builtin_object_prototype) {
|
|
1062
|
+
scr_builtin_object_prototype = scr_dyn_alloc(SCR_DYN_OBJ);
|
|
1063
|
+
scr_builtin_object_prototype->null_proto = true;
|
|
1064
|
+
scr_atexit(scr_builtin_object_prototype_cleanup);
|
|
1065
|
+
}
|
|
1066
|
+
return scr_dyn_retain(scr_builtin_object_prototype);
|
|
1067
|
+
}
|
|
1068
|
+
|
|
969
1069
|
ScrDyn *scr_dyn_array_prototype_base(void) {
|
|
970
1070
|
if (!scr_builtin_array_prototype) {
|
|
971
1071
|
scr_builtin_array_prototype = scr_dyn_alloc(SCR_DYN_ARR);
|
|
@@ -1005,7 +1105,7 @@ ScrDyn *scr_dyn_new_obj_null_proto(void) {
|
|
|
1005
1105
|
}
|
|
1006
1106
|
|
|
1007
1107
|
ScrDyn *scr_dyn_obj_create(ScrDyn *prototype) {
|
|
1008
|
-
if (scr_dyn_class_reflection_fence(prototype)) return NULL;
|
|
1108
|
+
if (prototype != scr_builtin_object_prototype && scr_dyn_class_reflection_fence(prototype)) return NULL;
|
|
1009
1109
|
if (prototype->kind != SCR_DYN_OBJ && prototype->kind != SCR_DYN_ARR && prototype->kind != SCR_DYN_NULL) {
|
|
1010
1110
|
static const char message[] = "Object prototype may only be an Object or null";
|
|
1011
1111
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
@@ -1017,7 +1117,15 @@ ScrDyn *scr_dyn_obj_create(ScrDyn *prototype) {
|
|
|
1017
1117
|
}
|
|
1018
1118
|
|
|
1019
1119
|
ScrDyn *scr_dyn_get_prototype(ScrDyn *object) {
|
|
1120
|
+
if (object == scr_builtin_object_prototype) return scr_dyn_new_null();
|
|
1020
1121
|
if (scr_dyn_class_reflection_fence(object)) return NULL;
|
|
1122
|
+
if (object->kind == SCR_DYN_TYPED_REF && strncmp(object->v.typed_ref.type_key, "object:", 7)) {
|
|
1123
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(object);
|
|
1124
|
+
if (!view) return NULL;
|
|
1125
|
+
ScrDyn *result = scr_dyn_get_prototype(view);
|
|
1126
|
+
scr_dyn_release(view);
|
|
1127
|
+
return result;
|
|
1128
|
+
}
|
|
1021
1129
|
if (object->kind == SCR_DYN_FUNC && object->v.fn.clo->props) {
|
|
1022
1130
|
ScrDyn *table = scr_dyn_fn_properties(object);
|
|
1023
1131
|
ScrDyn *result = table->prototype ? scr_dyn_retain(table->prototype)
|
|
@@ -1032,7 +1140,9 @@ ScrDyn *scr_dyn_get_prototype(ScrDyn *object) {
|
|
|
1032
1140
|
if (object->kind == SCR_DYN_OBJ) {
|
|
1033
1141
|
if (object->prototype) return scr_dyn_retain(object->prototype);
|
|
1034
1142
|
if (object->null_proto) return scr_dyn_new_null();
|
|
1143
|
+
return scr_dyn_object_prototype();
|
|
1035
1144
|
}
|
|
1145
|
+
if (object == scr_builtin_array_prototype) return scr_dyn_object_prototype();
|
|
1036
1146
|
if (object->kind == SCR_DYN_NULL || object->kind == SCR_DYN_UNDEF) {
|
|
1037
1147
|
static const char message[] = "Cannot convert undefined or null to object";
|
|
1038
1148
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
@@ -1045,6 +1155,15 @@ ScrDyn *scr_dyn_get_prototype(ScrDyn *object) {
|
|
|
1045
1155
|
|
|
1046
1156
|
ScrDyn *scr_dyn_set_prototype(ScrDyn *object, ScrDyn *prototype) {
|
|
1047
1157
|
if (scr_dyn_class_reflection_fence(object) || scr_dyn_class_reflection_fence(prototype)) return NULL;
|
|
1158
|
+
if (object->kind == SCR_DYN_TYPED_REF) {
|
|
1159
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(object);
|
|
1160
|
+
if (scr_exc_pending()) { scr_dyn_release(view); return NULL; }
|
|
1161
|
+
ScrDyn *result = scr_dyn_set_prototype(view, prototype);
|
|
1162
|
+
scr_dyn_release(view);
|
|
1163
|
+
if (!result) return NULL;
|
|
1164
|
+
scr_dyn_release(result);
|
|
1165
|
+
return scr_dyn_retain(object);
|
|
1166
|
+
}
|
|
1048
1167
|
if (object->kind == SCR_DYN_FUNC) {
|
|
1049
1168
|
if (prototype->kind == SCR_DYN_FUNC && object->v.fn.clo == prototype->v.fn.clo) {
|
|
1050
1169
|
static const char message[] = "Cyclic __proto__ value";
|
|
@@ -1059,17 +1178,23 @@ ScrDyn *scr_dyn_set_prototype(ScrDyn *object, ScrDyn *prototype) {
|
|
|
1059
1178
|
return scr_dyn_retain(object);
|
|
1060
1179
|
}
|
|
1061
1180
|
if (object->kind != SCR_DYN_OBJ ||
|
|
1062
|
-
(prototype->kind != SCR_DYN_OBJ && prototype->kind != SCR_DYN_NULL)) {
|
|
1181
|
+
(prototype->kind != SCR_DYN_OBJ && prototype->kind != SCR_DYN_FUNC && prototype->kind != SCR_DYN_NULL)) {
|
|
1063
1182
|
static const char message[] = "Object prototype may only be an Object or null";
|
|
1064
1183
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
1065
1184
|
return NULL;
|
|
1066
1185
|
}
|
|
1067
|
-
for (ScrDyn *current = prototype; current
|
|
1186
|
+
for (ScrDyn *current = prototype; current;) {
|
|
1187
|
+
if (current->kind == SCR_DYN_FUNC) {
|
|
1188
|
+
ScrDyn *table = scr_dyn_fn_properties(current);
|
|
1189
|
+
current = table;
|
|
1190
|
+
scr_dyn_release(table); /* the function owns the table */
|
|
1191
|
+
}
|
|
1068
1192
|
if (current == object) {
|
|
1069
1193
|
static const char message[] = "Cyclic __proto__ value";
|
|
1070
1194
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
1071
1195
|
return NULL;
|
|
1072
1196
|
}
|
|
1197
|
+
current = current->prototype;
|
|
1073
1198
|
}
|
|
1074
1199
|
if (object->non_extensible && (prototype->kind == SCR_DYN_NULL ? object->prototype != NULL || !object->null_proto : object->prototype != prototype)) {
|
|
1075
1200
|
static const char message[] = "Cannot set prototype of a non-extensible object";
|
|
@@ -1131,6 +1256,12 @@ bool scr_dyn_is_sealed(const ScrDyn *object) {
|
|
|
1131
1256
|
|
|
1132
1257
|
static const ScrDyn *scr_dyn_property_owner(const ScrDyn *object, const char *key, size_t length) {
|
|
1133
1258
|
for (const ScrDyn *current = object; current; current = current->prototype) {
|
|
1259
|
+
if (current->kind == SCR_DYN_FUNC) {
|
|
1260
|
+
ScrDyn *table = scr_dyn_fn_properties(current);
|
|
1261
|
+
const ScrDyn *owner = scr_dyn_property_owner(table, key, length);
|
|
1262
|
+
scr_dyn_release(table);
|
|
1263
|
+
return owner;
|
|
1264
|
+
}
|
|
1134
1265
|
if (current->kind != SCR_DYN_OBJ) continue;
|
|
1135
1266
|
for (size_t i = 0; i < current->v.obj.len; i++) {
|
|
1136
1267
|
const ScrDynEntry *entry = ¤t->v.obj.entries[i];
|
|
@@ -1143,7 +1274,7 @@ static const ScrDyn *scr_dyn_property_owner(const ScrDyn *object, const char *ke
|
|
|
1143
1274
|
static bool scr_dyn_has_object_prototype(const ScrDyn *object) {
|
|
1144
1275
|
const ScrDyn *current = object;
|
|
1145
1276
|
while (current->prototype) current = current->prototype;
|
|
1146
|
-
return !current->null_proto;
|
|
1277
|
+
return current == scr_builtin_object_prototype || !current->null_proto;
|
|
1147
1278
|
}
|
|
1148
1279
|
|
|
1149
1280
|
void scr_dyn_proxy_unsupported(const char *operation) {
|
|
@@ -1168,9 +1299,20 @@ ScrDyn *scr_dyn_proxy_new(const ScrDyn *target, const ScrDyn *handler) {
|
|
|
1168
1299
|
scr_throw_error_msg(SCR_ERR_TYPE, msg, sizeof msg - 1);
|
|
1169
1300
|
return NULL;
|
|
1170
1301
|
}
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
if (
|
|
1302
|
+
bool native_record = target->kind == SCR_DYN_TYPED_REF &&
|
|
1303
|
+
strncmp(target->v.typed_ref.type_key, "record:", 7) == 0;
|
|
1304
|
+
if (native_record) {
|
|
1305
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(target);
|
|
1306
|
+
bool plain = view && view->kind == SCR_DYN_OBJ;
|
|
1307
|
+
if (plain) for (size_t i = 0; i < view->v.obj.len; i++) {
|
|
1308
|
+
ScrDynEntry *entry = &view->v.obj.entries[i];
|
|
1309
|
+
if (entry->accessor || !entry->configurable || !entry->writable) plain = false;
|
|
1310
|
+
}
|
|
1311
|
+
scr_dyn_release(view);
|
|
1312
|
+
if (scr_exc_pending()) return NULL;
|
|
1313
|
+
native_record = plain;
|
|
1314
|
+
}
|
|
1315
|
+
if ((target->kind != SCR_DYN_OBJ && !native_record) || handler->kind != SCR_DYN_OBJ) {
|
|
1174
1316
|
scr_dyn_proxy_unsupported("non-plain targets or handlers");
|
|
1175
1317
|
return NULL;
|
|
1176
1318
|
}
|
|
@@ -1198,6 +1340,11 @@ static ScrDyn *scr_dyn_proxy_trap(const ScrDyn *proxy, const char *name) {
|
|
|
1198
1340
|
scr_dyn_release(method);
|
|
1199
1341
|
return NULL;
|
|
1200
1342
|
}
|
|
1343
|
+
if (proxy->v.proxy.target->kind == SCR_DYN_TYPED_REF) {
|
|
1344
|
+
scr_dyn_release(method);
|
|
1345
|
+
scr_dyn_proxy_unsupported("traps over typed native targets");
|
|
1346
|
+
return NULL;
|
|
1347
|
+
}
|
|
1201
1348
|
return method;
|
|
1202
1349
|
}
|
|
1203
1350
|
|
|
@@ -1227,6 +1374,12 @@ ScrDyn *scr_dyn_proxy_get(const ScrDyn *proxy, const ScrStr *key) {
|
|
|
1227
1374
|
if (scr_exc_pending()) return NULL;
|
|
1228
1375
|
if (!trap) {
|
|
1229
1376
|
ScrDyn *target = proxy->v.proxy.target;
|
|
1377
|
+
if (target->kind == SCR_DYN_TYPED_REF) {
|
|
1378
|
+
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);
|
|
1380
|
+
scr_dyn_release(view);
|
|
1381
|
+
return result;
|
|
1382
|
+
}
|
|
1230
1383
|
if (!scr_dyn_obj_get(target, key->data, key->len) && scr_dyn_object_proto_key(target, key)) {
|
|
1231
1384
|
scr_dyn_proxy_unsupported("inherited Object.prototype member reads");
|
|
1232
1385
|
return NULL;
|
|
@@ -1432,6 +1585,10 @@ void scr_dyn_proxy_set(ScrDyn *proxy, ScrStr *key, ScrDyn *value) {
|
|
|
1432
1585
|
ScrDyn *trap = scr_dyn_proxy_trap(proxy, "set");
|
|
1433
1586
|
if (scr_exc_pending()) return;
|
|
1434
1587
|
if (!trap) {
|
|
1588
|
+
if (proxy->v.proxy.target->kind == SCR_DYN_TYPED_REF) {
|
|
1589
|
+
scr_dyn_key_set(proxy->v.proxy.target, key, value);
|
|
1590
|
+
return;
|
|
1591
|
+
}
|
|
1435
1592
|
/* OrdinarySet uses the Proxy receiver's [[GetOwnProperty]] and
|
|
1436
1593
|
* [[DefineOwnProperty]]. Keep that boundary explicit for now. */
|
|
1437
1594
|
scr_dyn_proxy_unsupported("assignment without a set trap");
|
|
@@ -1498,6 +1655,15 @@ ScrDyn *scr_dyn_new_typed_ref(
|
|
|
1498
1655
|
const char *type_key, size_t type_key_len,
|
|
1499
1656
|
ScrDyn *(*materialize)(void *),
|
|
1500
1657
|
void (*commit)(void *, const ScrDyn *)) {
|
|
1658
|
+
scr_typed_ref_reserve();
|
|
1659
|
+
size_t bucket = scr_typed_ref_bucket(ptr);
|
|
1660
|
+
for (ScrTypedRefIdentity *entry = scr_typed_ref_identities[bucket]; entry; entry = entry->next) {
|
|
1661
|
+
ScrDyn *value = entry->value;
|
|
1662
|
+
if (value->v.typed_ref.ptr == ptr && value->v.typed_ref.retain == retain &&
|
|
1663
|
+
value->v.typed_ref.materialize == materialize && value->v.typed_ref.commit == commit &&
|
|
1664
|
+
value->v.typed_ref.type_key_len == type_key_len && !memcmp(value->v.typed_ref.type_key, type_key, type_key_len))
|
|
1665
|
+
return scr_dyn_retain(value);
|
|
1666
|
+
}
|
|
1501
1667
|
ScrDyn *d = scr_dyn_alloc(SCR_DYN_TYPED_REF);
|
|
1502
1668
|
d->v.typed_ref.ptr = retain(ptr);
|
|
1503
1669
|
d->v.typed_ref.retain = retain;
|
|
@@ -1509,6 +1675,12 @@ ScrDyn *scr_dyn_new_typed_ref(
|
|
|
1509
1675
|
d->v.typed_ref.materialized = NULL;
|
|
1510
1676
|
d->v.typed_ref.casts = NULL;
|
|
1511
1677
|
d->v.typed_ref.traced = false;
|
|
1678
|
+
d->v.typed_ref.observed = false;
|
|
1679
|
+
ScrTypedRefIdentity *identity = malloc(sizeof *identity);
|
|
1680
|
+
if (!identity) scr_json_oom();
|
|
1681
|
+
identity->value = d; identity->next = scr_typed_ref_identities[bucket];
|
|
1682
|
+
scr_typed_ref_identities[bucket] = identity;
|
|
1683
|
+
scr_typed_ref_count++;
|
|
1512
1684
|
return d;
|
|
1513
1685
|
}
|
|
1514
1686
|
|
|
@@ -1520,6 +1692,16 @@ ScrDyn *scr_dyn_new_typed_ref_traced(
|
|
|
1520
1692
|
ScrDyn *value = scr_dyn_new_typed_ref(ptr, retain, release, type_key,
|
|
1521
1693
|
type_key_len, materialize, commit);
|
|
1522
1694
|
value->v.typed_ref.traced = true;
|
|
1695
|
+
value->v.typed_ref.observed = true;
|
|
1696
|
+
return value;
|
|
1697
|
+
}
|
|
1698
|
+
|
|
1699
|
+
ScrDyn *scr_dyn_new_typed_ref_observed(
|
|
1700
|
+
void *ptr, void *(*retain)(void *), void (*release)(void *),
|
|
1701
|
+
const char *type_key, size_t type_key_len,
|
|
1702
|
+
ScrDyn *(*materialize)(void *), void (*commit)(void *, const ScrDyn *)) {
|
|
1703
|
+
ScrDyn *value = scr_dyn_new_typed_ref(ptr, retain, release, type_key, type_key_len, materialize, commit);
|
|
1704
|
+
value->v.typed_ref.observed = true;
|
|
1523
1705
|
return value;
|
|
1524
1706
|
}
|
|
1525
1707
|
|
|
@@ -1601,6 +1783,34 @@ ScrDyn *scr_dyn_typed_ref_materialize(const ScrDyn *d) {
|
|
|
1601
1783
|
* detached contents without changing the cached node's address. */
|
|
1602
1784
|
scr_dyn_typed_ref_preserve_children(
|
|
1603
1785
|
capsule->v.typed_ref.materialized, fresh);
|
|
1786
|
+
/* Record layouts cannot store properties added through a checked
|
|
1787
|
+
* view. Keep those descriptors in the view across native refreshes. */
|
|
1788
|
+
ScrDyn *cached = capsule->v.typed_ref.materialized;
|
|
1789
|
+
if (fresh->kind == SCR_DYN_OBJ && cached->kind == SCR_DYN_OBJ &&
|
|
1790
|
+
capsule->v.typed_ref.type_key_len >= 7 &&
|
|
1791
|
+
memcmp(capsule->v.typed_ref.type_key, "record:", 7) == 0) {
|
|
1792
|
+
for (size_t i = 0; i < cached->v.obj.len; i++) {
|
|
1793
|
+
ScrDynEntry *entry = &cached->v.obj.entries[i];
|
|
1794
|
+
if (scr_dyn_obj_get(fresh, entry->key, entry->key_len)) continue;
|
|
1795
|
+
ScrStr *name = scr_str_new(entry->key, entry->key_len);
|
|
1796
|
+
ScrDyn *key = scr_dyn_new_str(name);
|
|
1797
|
+
ScrDyn *descriptor = scr_dyn_own_descriptor(cached, name);
|
|
1798
|
+
ScrDyn *defined = scr_dyn_define_property(fresh, key, descriptor);
|
|
1799
|
+
scr_dyn_release(defined);
|
|
1800
|
+
scr_dyn_release(descriptor);
|
|
1801
|
+
scr_dyn_release(key);
|
|
1802
|
+
scr_str_release(name);
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
/* A native record stores its own fields, while its checked view owns
|
|
1806
|
+
* prototype changes. Refreshing fields must preserve that prototype. */
|
|
1807
|
+
scr_dyn_release(fresh->prototype);
|
|
1808
|
+
fresh->prototype = capsule->v.typed_ref.materialized->prototype ? scr_dyn_retain(capsule->v.typed_ref.materialized->prototype) : NULL;
|
|
1809
|
+
fresh->null_proto = capsule->v.typed_ref.materialized->null_proto;
|
|
1810
|
+
scr_dyn_release(fresh->symbol_properties);
|
|
1811
|
+
scr_dyn_release(fresh->symbol_keys);
|
|
1812
|
+
fresh->symbol_properties = capsule->v.typed_ref.materialized->symbol_properties ? scr_dyn_retain(capsule->v.typed_ref.materialized->symbol_properties) : NULL;
|
|
1813
|
+
fresh->symbol_keys = capsule->v.typed_ref.materialized->symbol_keys ? scr_dyn_retain(capsule->v.typed_ref.materialized->symbol_keys) : NULL;
|
|
1604
1814
|
size_t cached_rc = capsule->v.typed_ref.materialized->rc;
|
|
1605
1815
|
size_t fresh_rc = fresh->rc;
|
|
1606
1816
|
ScrDyn old = *capsule->v.typed_ref.materialized;
|
|
@@ -1635,7 +1845,7 @@ void *scr_dyn_typed_ref_cached_cast(
|
|
|
1635
1845
|
|
|
1636
1846
|
void scr_dyn_typed_ref_cache_cast(
|
|
1637
1847
|
ScrDyn *d, const char *type_key, size_t type_key_len, void *ptr,
|
|
1638
|
-
void *(*retain)(void *), void (*release)(void *)) {
|
|
1848
|
+
void *(*retain)(void *), void (*release)(void *), bool traced) {
|
|
1639
1849
|
if (!ptr) return;
|
|
1640
1850
|
ScrDynTypedCast *cast = malloc(sizeof *cast);
|
|
1641
1851
|
if (!cast) scr_trap("scriptc: out of memory\n");
|
|
@@ -1644,10 +1854,15 @@ void scr_dyn_typed_ref_cache_cast(
|
|
|
1644
1854
|
cast->ptr = retain(ptr);
|
|
1645
1855
|
cast->retain = retain;
|
|
1646
1856
|
cast->release = release;
|
|
1857
|
+
cast->traced = traced;
|
|
1647
1858
|
cast->next = d->v.typed_ref.casts;
|
|
1648
1859
|
d->v.typed_ref.casts = cast;
|
|
1649
1860
|
}
|
|
1650
1861
|
|
|
1862
|
+
bool scr_dyn_typed_array_is(const ScrDyn *d, int elem) {
|
|
1863
|
+
return d && d->kind == SCR_DYN_BYTES && !d->v.bytes->is_data_view && d->v.bytes->elem == (ScrBytesElem)elem;
|
|
1864
|
+
}
|
|
1865
|
+
|
|
1651
1866
|
bool scr_dyn_bytes_is(const ScrDyn *d, int elem) {
|
|
1652
1867
|
return d && d->kind == SCR_DYN_BYTES && d->v.bytes->elem == (ScrBytesElem)elem;
|
|
1653
1868
|
}
|
|
@@ -1656,6 +1871,110 @@ ScrBytes *scr_dyn_bytes_unbox(const ScrDyn *d) {
|
|
|
1656
1871
|
return scr_bytes_retain(d->v.bytes);
|
|
1657
1872
|
}
|
|
1658
1873
|
|
|
1874
|
+
/* Numeric typed-array constructor values share native function identity.
|
|
1875
|
+
* The cache owns one reference until runtime cleanup; arbitrary strings or
|
|
1876
|
+
* functions cannot impersonate one of these constructors. */
|
|
1877
|
+
static SCR_TL ScrDyn *scr_bytes_ctors[9];
|
|
1878
|
+
static void scr_bytes_ctors_cleanup(void) {
|
|
1879
|
+
for (size_t i = 0; i < 9; i++) {
|
|
1880
|
+
scr_dyn_release(scr_bytes_ctors[i]);
|
|
1881
|
+
scr_bytes_ctors[i] = NULL;
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
static ScrDyn *scr_bytes_ctor_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
1885
|
+
(void)args; (void)argc;
|
|
1886
|
+
for (size_t i = 0; i < 9; i++) {
|
|
1887
|
+
if (!scr_bytes_ctors[i] || scr_bytes_ctors[i]->v.fn.clo != closure) continue;
|
|
1888
|
+
ScrJsonBuf message;
|
|
1889
|
+
scr_jb_init(&message);
|
|
1890
|
+
scr_jb_puts(&message, "Constructor ");
|
|
1891
|
+
scr_jb_puts(&message, scr_bytes_elem_name((ScrBytesElem)i));
|
|
1892
|
+
scr_jb_puts(&message, " requires 'new'");
|
|
1893
|
+
scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&message));
|
|
1894
|
+
return NULL;
|
|
1895
|
+
}
|
|
1896
|
+
scr_trap("scriptc: invalid typed array constructor\n");
|
|
1897
|
+
}
|
|
1898
|
+
static ScrDyn *scr_dyn_fn_properties(const ScrDyn *function);
|
|
1899
|
+
static ScrDyn *scr_bytes_constructor_for(ScrBytesElem elem) {
|
|
1900
|
+
if (!scr_bytes_ctors[elem]) {
|
|
1901
|
+
bool initialized = false;
|
|
1902
|
+
for (size_t i = 0; i < 9; i++) if (scr_bytes_ctors[i]) initialized = true;
|
|
1903
|
+
if (!initialized) scr_atexit(scr_bytes_ctors_cleanup);
|
|
1904
|
+
scr_bytes_ctors[elem] = scr_dyn_new_func(scr_closure_new(NULL, 0),
|
|
1905
|
+
scr_bytes_ctor_call, 3, "typed-array-constructor", scr_bytes_elem_name(elem));
|
|
1906
|
+
ScrDyn *properties = scr_dyn_fn_properties(scr_bytes_ctors[elem]);
|
|
1907
|
+
scr_dyn_obj_set(properties, "BYTES_PER_ELEMENT", 17, scr_dyn_new_num((double)scr_bytes_elem_size(elem)));
|
|
1908
|
+
ScrDynEntry *entry = &properties->v.obj.entries[properties->v.obj.len - 1];
|
|
1909
|
+
entry->writable = entry->enumerable = entry->configurable = false;
|
|
1910
|
+
scr_dyn_release(properties);
|
|
1911
|
+
}
|
|
1912
|
+
return scr_dyn_retain(scr_bytes_ctors[elem]);
|
|
1913
|
+
}
|
|
1914
|
+
ScrDyn *scr_bytes_constructor(const ScrStr *name) {
|
|
1915
|
+
for (size_t i = 0; i < 9; i++) {
|
|
1916
|
+
const char *candidate = scr_bytes_elem_name((ScrBytesElem)i);
|
|
1917
|
+
if (strlen(candidate) == name->len && memcmp(candidate, name->data, name->len) == 0)
|
|
1918
|
+
return scr_bytes_constructor_for((ScrBytesElem)i);
|
|
1919
|
+
}
|
|
1920
|
+
scr_trap("scriptc: invalid typed array constructor name\n");
|
|
1921
|
+
}
|
|
1922
|
+
static SCR_TL ScrDyn *scr_array_buffer_ctor;
|
|
1923
|
+
static void scr_array_buffer_ctor_cleanup(void) {
|
|
1924
|
+
scr_dyn_release(scr_array_buffer_ctor);
|
|
1925
|
+
scr_array_buffer_ctor = NULL;
|
|
1926
|
+
}
|
|
1927
|
+
static ScrDyn *scr_array_buffer_ctor_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
1928
|
+
(void)closure; (void)args; (void)argc;
|
|
1929
|
+
static const char message[] = "Constructor ArrayBuffer requires 'new'";
|
|
1930
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
1931
|
+
return NULL;
|
|
1932
|
+
}
|
|
1933
|
+
ScrDyn *scr_array_buffer_constructor(void) {
|
|
1934
|
+
if (!scr_array_buffer_ctor) {
|
|
1935
|
+
scr_array_buffer_ctor = scr_dyn_new_func(scr_closure_new(NULL, 0), scr_array_buffer_ctor_call, 1, "native:ArrayBuffer", "ArrayBuffer");
|
|
1936
|
+
scr_atexit(scr_array_buffer_ctor_cleanup);
|
|
1937
|
+
}
|
|
1938
|
+
return scr_dyn_retain(scr_array_buffer_ctor);
|
|
1939
|
+
}
|
|
1940
|
+
|
|
1941
|
+
bool scr_bytes_instanceof(const ScrDyn *value, const ScrDyn *callee) {
|
|
1942
|
+
if (!callee || callee->kind != SCR_DYN_FUNC) {
|
|
1943
|
+
static const char message[] = "Right-hand side of 'instanceof' is not callable";
|
|
1944
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
1945
|
+
return false;
|
|
1946
|
+
}
|
|
1947
|
+
if (scr_array_buffer_ctor && callee->v.fn.clo == scr_array_buffer_ctor->v.fn.clo) return scr_array_buffer_is(value);
|
|
1948
|
+
for (size_t i = 0; i < 9; i++) {
|
|
1949
|
+
if (scr_bytes_ctors[i] && callee->v.fn.clo == scr_bytes_ctors[i]->v.fn.clo)
|
|
1950
|
+
return scr_dyn_typed_array_is(value, (int)i);
|
|
1951
|
+
}
|
|
1952
|
+
static const char message[] = "instanceof against this native constructor is not supported yet";
|
|
1953
|
+
scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC1090");
|
|
1954
|
+
return false;
|
|
1955
|
+
}
|
|
1956
|
+
ScrDyn *scr_bytes_construct(const ScrDyn *callee, const ScrDyn *args, const ScrStr *what) {
|
|
1957
|
+
if (callee->kind == SCR_DYN_FUNC && scr_array_buffer_ctor && callee->v.fn.clo == scr_array_buffer_ctor->v.fn.clo)
|
|
1958
|
+
return scr_array_buffer_new(args->v.arr.len ? args->v.arr.items[0] : scr_dyn_undefined());
|
|
1959
|
+
for (size_t i = 0; i < 9; i++) {
|
|
1960
|
+
if (callee->kind != SCR_DYN_FUNC || !scr_bytes_ctors[i] || callee->v.fn.clo != scr_bytes_ctors[i]->v.fn.clo) continue;
|
|
1961
|
+
const ScrDyn *input = args->v.arr.len > 0 ? args->v.arr.items[0] : scr_dyn_undefined();
|
|
1962
|
+
const ScrDyn *offset = args->v.arr.len > 1 ? args->v.arr.items[1] : scr_dyn_undefined();
|
|
1963
|
+
const ScrDyn *length = args->v.arr.len > 2 ? args->v.arr.items[2] : scr_dyn_undefined();
|
|
1964
|
+
ScrBytes *bytes = scr_array_buffer_view((ScrBytesElem)i, input, offset, length);
|
|
1965
|
+
if (!bytes) return NULL;
|
|
1966
|
+
ScrDyn *result = scr_dyn_new_bytes(bytes);
|
|
1967
|
+
scr_bytes_release(bytes);
|
|
1968
|
+
return result;
|
|
1969
|
+
}
|
|
1970
|
+
ScrJsonBuf message;
|
|
1971
|
+
scr_jb_init(&message);
|
|
1972
|
+
scr_jb_write(&message, what->data, what->len);
|
|
1973
|
+
scr_jb_puts(&message, " is not a supported native constructor");
|
|
1974
|
+
scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&message));
|
|
1975
|
+
return NULL;
|
|
1976
|
+
}
|
|
1977
|
+
|
|
1659
1978
|
/* Shared view metadata and indexed reads for both compiler backends. */
|
|
1660
1979
|
ScrDyn *scr_dyn_bytes_key_get(const ScrDyn *value, const ScrStr *key) {
|
|
1661
1980
|
ScrBytes *bytes = value->v.bytes;
|
|
@@ -1664,7 +1983,8 @@ ScrDyn *scr_dyn_bytes_key_get(const ScrDyn *value, const ScrStr *key) {
|
|
|
1664
1983
|
if (key->len == 10 && memcmp(key->data, "byteOffset", 10) == 0) return scr_dyn_new_num(scr_bytes_byte_offset(bytes));
|
|
1665
1984
|
if (key->len == 6 && memcmp(key->data, "buffer", 6) == 0) return scr_array_buffer_from_bytes(bytes);
|
|
1666
1985
|
if (key->len == 11 && memcmp(key->data, "constructor", 11) == 0) {
|
|
1667
|
-
|
|
1986
|
+
if (!value->buffer) return scr_bytes_constructor_for(bytes->elem);
|
|
1987
|
+
/* Buffer retains its separate builtin identity. */
|
|
1668
1988
|
char token[64];
|
|
1669
1989
|
int length = snprintf(token, sizeof token, "[builtin %s]", value->buffer ? "Buffer" : scr_bytes_elem_name(bytes->elem));
|
|
1670
1990
|
ScrStr *name = scr_str_new(token, (size_t)length);
|
|
@@ -1739,6 +2059,7 @@ static ScrDyn *scr_dyn_class_call(ScrClosure *closure, ScrDyn *const *args, size
|
|
|
1739
2059
|
|
|
1740
2060
|
ScrDyn *scr_dyn_new_class(ScrClassObj *cls, const char *type_key) {
|
|
1741
2061
|
ScrClosure *closure = scr_closure_new(NULL, 1);
|
|
2062
|
+
if (cls->static_data) closure->props = scr_box_retain(cls->static_data);
|
|
1742
2063
|
closure->caps[0] = scr_box_new_obj(scr_classobj_retain_v, scr_classobj_release_v, scr_classobj_trace_v);
|
|
1743
2064
|
scr_box_set_ref(closure->caps[0], scr_classobj_retain(cls));
|
|
1744
2065
|
ScrDyn *value = scr_dyn_new_func(closure, scr_dyn_class_call, (uint32_t)cls->length, type_key, cls->name->data);
|
|
@@ -1751,6 +2072,10 @@ bool scr_dyn_class_is(const ScrDyn *value, const char *type_key) {
|
|
|
1751
2072
|
strcmp(value->v.fn.sig, type_key) == 0;
|
|
1752
2073
|
}
|
|
1753
2074
|
|
|
2075
|
+
bool scr_dyn_class_is_key(const ScrDyn *value, const ScrStr *type_key) {
|
|
2076
|
+
return scr_dyn_class_is(value, type_key->data);
|
|
2077
|
+
}
|
|
2078
|
+
|
|
1754
2079
|
ScrClassObj *scr_dyn_class_check(const ScrDyn *value, const char *type_key, const ScrDynPath *path) {
|
|
1755
2080
|
if (!scr_dyn_class_is(value, type_key)) {
|
|
1756
2081
|
scr_dyn_check_fail(path, "class constructor", value);
|
|
@@ -2076,8 +2401,9 @@ ScrDyn *scr_dyn_new_handle(void *h, ScrDynHandleTag tag) {
|
|
|
2076
2401
|
ScrDyn *d = scr_dyn_alloc(SCR_DYN_HANDLE);
|
|
2077
2402
|
d->v.handle.ptr = scr_dyn_handle_ops(tag)->retain(h);
|
|
2078
2403
|
d->v.handle.tag = tag;
|
|
2079
|
-
d->v.handle.traced =
|
|
2080
|
-
|
|
2404
|
+
d->v.handle.traced = tag == SCR_DYNH_WEAK_MAP || tag == SCR_DYNH_WEAK_SET ||
|
|
2405
|
+
((tag == SCR_DYNH_SET || tag == SCR_DYNH_MAP) &&
|
|
2406
|
+
(((ScrMap *)h)->key_trace != NULL || ((ScrMap *)h)->val_trace != NULL));
|
|
2081
2407
|
return d;
|
|
2082
2408
|
}
|
|
2083
2409
|
|
|
@@ -2086,6 +2412,7 @@ ScrDyn *scr_dyn_new_handle(void *h, ScrDynHandleTag tag) {
|
|
|
2086
2412
|
* scr_promise_release edge installs HERE — a promise-free link never
|
|
2087
2413
|
* references the fiber machinery (the unit-test subset links). */
|
|
2088
2414
|
void (*scr_dyn_promise_release_fn)(ScrPromise *p) = NULL;
|
|
2415
|
+
bool (*scr_dyn_promise_identity_fn)(ScrPromise *a, ScrPromise *b) = NULL;
|
|
2089
2416
|
|
|
2090
2417
|
ScrDyn *scr_dyn_alloc_promise(void (*release_fn)(ScrPromise *p)) {
|
|
2091
2418
|
scr_dyn_promise_release_fn = release_fn;
|
|
@@ -2114,6 +2441,7 @@ const ScrDynJsvalOps *scr_dyn_jsval_ops(void) {
|
|
|
2114
2441
|
}
|
|
2115
2442
|
|
|
2116
2443
|
bool scr_dyn_isl_typeof_is(const ScrDyn *d, const char *name) {
|
|
2444
|
+
if (scr_dyn_generator(d)) return strcmp(name, "object") == 0;
|
|
2117
2445
|
if (d->kind == SCR_DYN_TYPED_REF) {
|
|
2118
2446
|
if (d->v.typed_ref.type_key_len >= 7 &&
|
|
2119
2447
|
memcmp(d->v.typed_ref.type_key, "object:", 7) == 0)
|
|
@@ -2144,10 +2472,12 @@ bool scr_dyn_isl_typeof_is(const ScrDyn *d, const char *name) {
|
|
|
2144
2472
|
}
|
|
2145
2473
|
|
|
2146
2474
|
bool scr_dyn_isl_is_array(const ScrDyn *d) {
|
|
2475
|
+
if (scr_dyn_generator(d)) return false;
|
|
2147
2476
|
if (d->kind == SCR_DYN_TYPED_REF) {
|
|
2148
2477
|
if (d->v.typed_ref.type_key_len >= 7 &&
|
|
2149
2478
|
memcmp(d->v.typed_ref.type_key, "object:", 7) == 0) return false;
|
|
2150
2479
|
ScrDyn *materialized = scr_dyn_typed_ref_materialize(d);
|
|
2480
|
+
if (!materialized) return false;
|
|
2151
2481
|
bool out = materialized->kind == SCR_DYN_ARR ||
|
|
2152
2482
|
scr_dyn_isl_is_array(materialized);
|
|
2153
2483
|
scr_dyn_release(materialized);
|
|
@@ -2157,6 +2487,14 @@ bool scr_dyn_isl_is_array(const ScrDyn *d) {
|
|
|
2157
2487
|
}
|
|
2158
2488
|
|
|
2159
2489
|
bool scr_dyn_isl_is_error(const ScrDyn *d) {
|
|
2490
|
+
if (scr_dyn_generator(d)) return false;
|
|
2491
|
+
/* Registered native Error capsules retain their brand even when their
|
|
2492
|
+
* public property view omits the internal error marker. */
|
|
2493
|
+
ScrError *error = scr_errdyn_err_of(d);
|
|
2494
|
+
if (error) {
|
|
2495
|
+
scr_error_release(error);
|
|
2496
|
+
return true;
|
|
2497
|
+
}
|
|
2160
2498
|
if (d->kind == SCR_DYN_TYPED_REF) {
|
|
2161
2499
|
ScrDyn *materialized = scr_dyn_typed_ref_materialize(d);
|
|
2162
2500
|
bool out =
|
|
@@ -2316,6 +2654,7 @@ static ScrStr *scr_dyn_property_key(const ScrDyn *key) {
|
|
|
2316
2654
|
}
|
|
2317
2655
|
|
|
2318
2656
|
static ScrDynEntry *scr_dyn_entry(ScrDyn *obj, const ScrStr *key) {
|
|
2657
|
+
if (obj->kind != SCR_DYN_OBJ) return NULL;
|
|
2319
2658
|
for (size_t i = 0; i < obj->v.obj.len; i++) {
|
|
2320
2659
|
ScrDynEntry *entry = &obj->v.obj.entries[i];
|
|
2321
2660
|
if (entry->key_len == key->len && memcmp(entry->key, key->data, key->len) == 0) return entry;
|
|
@@ -2334,6 +2673,10 @@ static bool scr_dyn_property_same_value(const ScrDyn *a, const ScrDyn *b) {
|
|
|
2334
2673
|
return scr_dyn_strict_eq(a, b);
|
|
2335
2674
|
}
|
|
2336
2675
|
|
|
2676
|
+
bool scr_dyn_same_value(const ScrDyn *left, const ScrDyn *right) {
|
|
2677
|
+
return scr_dyn_property_same_value(left, right);
|
|
2678
|
+
}
|
|
2679
|
+
|
|
2337
2680
|
static void scr_dyn_descriptor_fields_drop(ScrDyn **fields) {
|
|
2338
2681
|
for (size_t i = 0; i < 6; i++) scr_dyn_release(fields[i]);
|
|
2339
2682
|
}
|
|
@@ -2344,6 +2687,8 @@ static void scr_error_sync_cause(ScrDyn *view, const ScrStr *key);
|
|
|
2344
2687
|
* the configurable, non-writable builtin members once so redefinitions and
|
|
2345
2688
|
* deletions retain the same behavior through every alias. Returns +1. */
|
|
2346
2689
|
static ScrDyn *scr_dyn_fn_properties(const ScrDyn *function) {
|
|
2690
|
+
if (!function->v.fn.clo->props && function->v.fn.class_obj && function->v.fn.class_obj->static_data)
|
|
2691
|
+
function->v.fn.clo->props = scr_box_retain(function->v.fn.class_obj->static_data);
|
|
2347
2692
|
if (!function->v.fn.clo->props) {
|
|
2348
2693
|
ScrDyn *table = scr_dyn_new_obj();
|
|
2349
2694
|
const char *name = function->v.fn.name ? function->v.fn.name : "";
|
|
@@ -2358,6 +2703,7 @@ static ScrDyn *scr_dyn_fn_properties(const ScrDyn *function) {
|
|
|
2358
2703
|
ScrBox *box = scr_box_new_obj(&scr_dyn_retain_v, &scr_dyn_release_v, &scr_dyn_trace_v);
|
|
2359
2704
|
scr_box_set_ref(box, table);
|
|
2360
2705
|
function->v.fn.clo->props = box;
|
|
2706
|
+
if (function->v.fn.class_obj) function->v.fn.class_obj->static_data = scr_box_retain(box);
|
|
2361
2707
|
if (function->v.fn.clo->function_kind & 4) {
|
|
2362
2708
|
ScrDyn *prototype = scr_dyn_new_obj();
|
|
2363
2709
|
scr_dyn_obj_set(prototype, "constructor", 11, scr_dyn_retain((ScrDyn *)function));
|
|
@@ -2371,6 +2717,22 @@ static ScrDyn *scr_dyn_fn_properties(const ScrDyn *function) {
|
|
|
2371
2717
|
return (ScrDyn *)scr_box_get_ref(function->v.fn.clo->props);
|
|
2372
2718
|
}
|
|
2373
2719
|
|
|
2720
|
+
ScrDyn *scr_dyn_class_inherit(ScrDyn *constructor, ScrDyn *base) {
|
|
2721
|
+
if (constructor->kind != SCR_DYN_FUNC || !constructor->v.fn.class_obj || (base->kind != SCR_DYN_FUNC && base->kind != SCR_DYN_UNDEF)) {
|
|
2722
|
+
static const char message[] = "Class inheritance requires native constructors";
|
|
2723
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
2724
|
+
return NULL;
|
|
2725
|
+
}
|
|
2726
|
+
ScrDyn *table = scr_dyn_fn_properties(constructor);
|
|
2727
|
+
if (base->kind == SCR_DYN_FUNC) scr_dyn_release(scr_dyn_fn_properties(base));
|
|
2728
|
+
ScrClassObj *cls = constructor->v.fn.class_obj;
|
|
2729
|
+
if (!cls->static_data) cls->static_data = scr_box_retain(constructor->v.fn.clo->props);
|
|
2730
|
+
ScrDyn *result = base->kind == SCR_DYN_UNDEF ? NULL : scr_dyn_set_prototype(table, base);
|
|
2731
|
+
scr_dyn_release(table);
|
|
2732
|
+
scr_dyn_release(result);
|
|
2733
|
+
return scr_exc_pending() ? NULL : scr_dyn_retain(constructor);
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2374
2736
|
ScrDyn *scr_dyn_class_base_prototype(ScrDyn *constructor) {
|
|
2375
2737
|
if (constructor->kind != SCR_DYN_FUNC || constructor->v.fn.class_obj ||
|
|
2376
2738
|
constructor->v.fn.clo->function_kind != 4) {
|
|
@@ -2399,6 +2761,35 @@ void scr_dyn_class_super(ScrDyn *constructor, ScrDyn *receiver, ScrDyn *argument
|
|
|
2399
2761
|
scr_dyn_release(result);
|
|
2400
2762
|
}
|
|
2401
2763
|
|
|
2764
|
+
bool scr_dyn_data_view_is(const ScrDyn *value) {
|
|
2765
|
+
return value->kind == SCR_DYN_BYTES && value->v.bytes->is_data_view;
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
/* Ordinary native function constructors retain their live prototype table.
|
|
2769
|
+
* A constructor may replace the fresh receiver with another object. */
|
|
2770
|
+
ScrDyn *scr_dyn_construct(const ScrDyn *callee, const ScrDyn *args, const ScrStr *what) {
|
|
2771
|
+
if (callee->kind != SCR_DYN_FUNC || callee->v.fn.class_obj || callee->v.fn.clo->function_kind != 4)
|
|
2772
|
+
return scr_bytes_construct(callee, args, what);
|
|
2773
|
+
ScrDyn *prototype = scr_dyn_fn_get(callee, "prototype", 9);
|
|
2774
|
+
if (!prototype) return NULL;
|
|
2775
|
+
ScrDyn *receiver = scr_iterator_object(prototype) ? scr_dyn_obj_create(prototype) : scr_dyn_new_obj();
|
|
2776
|
+
scr_dyn_release(prototype);
|
|
2777
|
+
if (!receiver) return NULL;
|
|
2778
|
+
scr_dyn_this_push_dyn(receiver);
|
|
2779
|
+
ScrDyn *result = scr_dyn_call(callee, args->v.arr.items, args->v.arr.len, what->data);
|
|
2780
|
+
scr_dyn_this_pop();
|
|
2781
|
+
if (!result) {
|
|
2782
|
+
scr_dyn_release(receiver);
|
|
2783
|
+
return NULL;
|
|
2784
|
+
}
|
|
2785
|
+
if (scr_iterator_object(result)) {
|
|
2786
|
+
scr_dyn_release(receiver);
|
|
2787
|
+
return result;
|
|
2788
|
+
}
|
|
2789
|
+
scr_dyn_release(result);
|
|
2790
|
+
return receiver;
|
|
2791
|
+
}
|
|
2792
|
+
|
|
2402
2793
|
/* Symbol descriptors use the ordinary descriptor implementation in an
|
|
2403
2794
|
* inaccessible table. Keep a retained key list so identities cannot be
|
|
2404
2795
|
* recycled while properties exist, and reflection returns real symbols. */
|
|
@@ -2409,11 +2800,11 @@ static ScrStr *scr_dyn_symbol_storage_key(const ScrDyn *key) {
|
|
|
2409
2800
|
}
|
|
2410
2801
|
|
|
2411
2802
|
static ScrDyn *scr_dyn_symbol_receiver(const ScrDyn *value) {
|
|
2803
|
+
if (value->kind == SCR_DYN_TYPED_REF) return scr_dyn_typed_ref_materialize(value);
|
|
2412
2804
|
if (value->kind == SCR_DYN_FUNC) return scr_dyn_fn_properties(value);
|
|
2413
|
-
if (value->kind == SCR_DYN_OBJ || value->kind == SCR_DYN_ARR)
|
|
2805
|
+
if (value->kind == SCR_DYN_OBJ || value->kind == SCR_DYN_ARR || value->kind == SCR_DYN_HANDLE)
|
|
2414
2806
|
return scr_dyn_retain((ScrDyn *)value);
|
|
2415
|
-
if (value->kind ==
|
|
2416
|
-
value->kind == SCR_DYN_PROXY || value->kind == SCR_DYN_JSVAL) {
|
|
2807
|
+
if (value->kind == SCR_DYN_PROXY || value->kind == SCR_DYN_JSVAL) {
|
|
2417
2808
|
static const char message[] = "Symbol properties on this native value have no lowering";
|
|
2418
2809
|
scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
|
|
2419
2810
|
}
|
|
@@ -2425,6 +2816,12 @@ static ScrDynEntry *scr_dyn_symbol_entry(const ScrDyn *receiver, const ScrDyn *k
|
|
|
2425
2816
|
ScrDynEntry *entry = NULL;
|
|
2426
2817
|
for (const ScrDyn *current = receiver; current; current = own ? NULL : current->prototype ? current->prototype
|
|
2427
2818
|
: current->kind == SCR_DYN_ARR && current != scr_builtin_array_prototype && !current->null_proto ? scr_builtin_array_prototype : NULL) {
|
|
2819
|
+
if (current->kind == SCR_DYN_FUNC) {
|
|
2820
|
+
ScrDyn *table = scr_dyn_fn_properties(current);
|
|
2821
|
+
entry = scr_dyn_symbol_entry(table, key, own);
|
|
2822
|
+
scr_dyn_release(table);
|
|
2823
|
+
break;
|
|
2824
|
+
}
|
|
2428
2825
|
if (current->symbol_properties) entry = scr_dyn_entry(current->symbol_properties, name);
|
|
2429
2826
|
if (entry) break;
|
|
2430
2827
|
}
|
|
@@ -2442,14 +2839,19 @@ typedef struct {
|
|
|
2442
2839
|
size_t rc;
|
|
2443
2840
|
ScrDyn *source;
|
|
2444
2841
|
double index;
|
|
2445
|
-
|
|
2842
|
+
unsigned kind; /* 0: array, 1: string, 2: Map, 3: Set */
|
|
2843
|
+
unsigned selection; /* 0: values, 1: keys, 2: entries */
|
|
2844
|
+
bool array_like;
|
|
2845
|
+
double limit;
|
|
2446
2846
|
} ScrNativeIterator;
|
|
2447
2847
|
|
|
2448
|
-
static
|
|
2848
|
+
static ScrDyn *scr_iterator_read(const ScrDyn *value, const char *key, size_t len);
|
|
2849
|
+
|
|
2850
|
+
static SCR_TL ScrDyn *scr_iterator_functions[11];
|
|
2449
2851
|
static SCR_TL bool scr_iterator_functions_registered;
|
|
2450
2852
|
|
|
2451
2853
|
static void scr_iterator_functions_cleanup(void) {
|
|
2452
|
-
for (size_t i = 0; i <
|
|
2854
|
+
for (size_t i = 0; i < 11; i++) {
|
|
2453
2855
|
ScrDyn *function = scr_iterator_functions[i];
|
|
2454
2856
|
scr_iterator_functions[i] = NULL;
|
|
2455
2857
|
scr_dyn_release(function);
|
|
@@ -2475,25 +2877,51 @@ static void *scr_native_iterator_retain(void *ptr) {
|
|
|
2475
2877
|
static void scr_native_iterator_release(void *ptr) {
|
|
2476
2878
|
ScrNativeIterator *iterator = ptr;
|
|
2477
2879
|
if (--iterator->rc) return;
|
|
2880
|
+
scr_weak_dispose(iterator);
|
|
2881
|
+
if (iterator->source && (iterator->kind == 2 || iterator->kind == 3)) scr_map_iter_exit(iterator->source->v.handle.ptr);
|
|
2478
2882
|
scr_dyn_release(iterator->source);
|
|
2479
2883
|
free(iterator);
|
|
2480
2884
|
}
|
|
2481
2885
|
|
|
2482
2886
|
static ScrDyn *scr_native_iterator_next(ScrNativeIterator *iterator) {
|
|
2483
2887
|
ScrDyn *source = iterator->source;
|
|
2888
|
+
if (source && iterator->kind == 4) {
|
|
2889
|
+
ScrDyn *result = scr_dyn_handle_ops_of(source)->iter_step(source->v.handle.ptr, &iterator->index, iterator->selection);
|
|
2890
|
+
if (!result) return NULL;
|
|
2891
|
+
if (scr_dyn_truthy(scr_dyn_obj_get(result, "done", 4))) {
|
|
2892
|
+
iterator->source = NULL;
|
|
2893
|
+
scr_dyn_release(source);
|
|
2894
|
+
}
|
|
2895
|
+
return result;
|
|
2896
|
+
}
|
|
2484
2897
|
/* Native array capsules retain the live array, so refresh its view at each
|
|
2485
2898
|
* step rather than iterating a snapshot taken when the iterator opened. */
|
|
2486
2899
|
ScrDyn *view = source && source->kind == SCR_DYN_TYPED_REF ? scr_dyn_typed_ref_materialize(source) : NULL;
|
|
2487
2900
|
if (scr_exc_pending()) { scr_dyn_release(view); return NULL; }
|
|
2488
2901
|
ScrDyn *items = view ? view : source;
|
|
2489
|
-
|
|
2902
|
+
ScrMap *map = source && (iterator->kind == 2 || iterator->kind == 3) ? source->v.handle.ptr : NULL;
|
|
2903
|
+
if (map) while (iterator->index < scr_map_iter_count(map) && !scr_map_iter_live(map, iterator->index)) iterator->index++;
|
|
2904
|
+
double length = !items ? 0 : iterator->array_like ? iterator->limit : map ? scr_map_iter_count(map) : items->kind == SCR_DYN_ARR ? (double)items->v.arr.len
|
|
2490
2905
|
: items->kind == SCR_DYN_BYTES ? (double)items->v.bytes->len : scr_str_utf16_len(items->v.str);
|
|
2491
2906
|
bool done = !source || iterator->index >= length;
|
|
2492
2907
|
ScrDyn *value;
|
|
2493
2908
|
if (done) {
|
|
2494
2909
|
value = scr_dyn_retain(scr_dyn_undefined());
|
|
2495
2910
|
iterator->source = NULL;
|
|
2911
|
+
if (map) scr_map_iter_exit(map);
|
|
2496
2912
|
scr_dyn_release(source);
|
|
2913
|
+
} else if (iterator->array_like) {
|
|
2914
|
+
char key[32];
|
|
2915
|
+
int size = snprintf(key, sizeof key, "%.0f", iterator->index++);
|
|
2916
|
+
value = scr_iterator_read(items, key, (size_t)size);
|
|
2917
|
+
} else if (map) {
|
|
2918
|
+
double index = iterator->index++;
|
|
2919
|
+
if (iterator->selection == 2) {
|
|
2920
|
+
value = scr_dyn_new_arr();
|
|
2921
|
+
scr_dyn_arr_push(value, scr_map_dyn_key(map, index));
|
|
2922
|
+
scr_dyn_arr_push(value, iterator->kind == 3 ? scr_map_dyn_key(map, index) : scr_map_dyn_value(map, index));
|
|
2923
|
+
} else value = iterator->selection == 1 || iterator->kind == 3
|
|
2924
|
+
? scr_map_dyn_key(map, index) : scr_map_dyn_value(map, index);
|
|
2497
2925
|
} else if (items->kind == SCR_DYN_ARR) {
|
|
2498
2926
|
value = scr_dyn_arr_at(items, iterator->index++);
|
|
2499
2927
|
} else if (items->kind == SCR_DYN_BYTES) {
|
|
@@ -2512,14 +2940,15 @@ static ScrDyn *scr_native_iterator_next(ScrNativeIterator *iterator) {
|
|
|
2512
2940
|
return result;
|
|
2513
2941
|
}
|
|
2514
2942
|
|
|
2515
|
-
static ScrDyn *scr_native_iterator_next_checked(
|
|
2943
|
+
static ScrDyn *scr_native_iterator_next_checked(unsigned kind) {
|
|
2516
2944
|
ScrDyn *self = scr_dyn_this_get();
|
|
2517
2945
|
ScrDyn *result = NULL;
|
|
2518
2946
|
if (self->kind == SCR_DYN_HANDLE && self->v.handle.tag == SCR_DYNH_ITERATOR &&
|
|
2519
|
-
((ScrNativeIterator *)self->v.handle.ptr)->
|
|
2947
|
+
((ScrNativeIterator *)self->v.handle.ptr)->kind == kind)
|
|
2520
2948
|
result = scr_native_iterator_next(self->v.handle.ptr);
|
|
2521
2949
|
else {
|
|
2522
|
-
const char *message =
|
|
2950
|
+
const char *message = kind == 3 ? "Method Set Iterator.prototype.next called on incompatible receiver"
|
|
2951
|
+
: kind == 2 ? "Method Map Iterator.prototype.next called on incompatible receiver" : kind == 1
|
|
2523
2952
|
? "Method String Iterator.prototype.next called on incompatible receiver"
|
|
2524
2953
|
: "Method Array Iterator.prototype.next called on incompatible receiver";
|
|
2525
2954
|
scr_throw_error_msg(SCR_ERR_TYPE, message, strlen(message));
|
|
@@ -2530,17 +2959,35 @@ static ScrDyn *scr_native_iterator_next_checked(bool string_iterator) {
|
|
|
2530
2959
|
|
|
2531
2960
|
static ScrDyn *scr_native_array_iterator_next_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
2532
2961
|
(void)closure; (void)args; (void)argc;
|
|
2533
|
-
return scr_native_iterator_next_checked(
|
|
2962
|
+
return scr_native_iterator_next_checked(0);
|
|
2534
2963
|
}
|
|
2535
2964
|
|
|
2536
2965
|
static ScrDyn *scr_native_string_iterator_next_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
2537
2966
|
(void)closure; (void)args; (void)argc;
|
|
2538
|
-
return scr_native_iterator_next_checked(
|
|
2967
|
+
return scr_native_iterator_next_checked(1);
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2970
|
+
static ScrDyn *scr_native_map_iterator_next_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
2971
|
+
(void)closure; (void)args; (void)argc;
|
|
2972
|
+
return scr_native_iterator_next_checked(2);
|
|
2973
|
+
}
|
|
2974
|
+
|
|
2975
|
+
static ScrDyn *scr_native_set_iterator_next_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
2976
|
+
(void)closure; (void)args; (void)argc;
|
|
2977
|
+
return scr_native_iterator_next_checked(3);
|
|
2978
|
+
}
|
|
2979
|
+
|
|
2980
|
+
static ScrDyn *scr_native_handle_iterator_next_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
2981
|
+
(void)closure; (void)args; (void)argc;
|
|
2982
|
+
return scr_native_iterator_next_checked(4);
|
|
2539
2983
|
}
|
|
2540
2984
|
|
|
2541
2985
|
static ScrDyn *scr_native_iterator_get(void *ptr, const char *key, size_t len) {
|
|
2542
2986
|
if (len != 4 || memcmp(key, "next", 4)) return NULL;
|
|
2543
|
-
|
|
2987
|
+
unsigned kind = ((ScrNativeIterator *)ptr)->kind;
|
|
2988
|
+
if (kind == 4) return scr_iterator_function(10, &scr_native_handle_iterator_next_call, "next");
|
|
2989
|
+
return kind == 3 ? scr_iterator_function(8, &scr_native_set_iterator_next_call, "next")
|
|
2990
|
+
: kind == 2 ? scr_iterator_function(7, &scr_native_map_iterator_next_call, "next") : kind == 1
|
|
2544
2991
|
? scr_iterator_function(5, &scr_native_string_iterator_next_call, "next")
|
|
2545
2992
|
: scr_iterator_function(0, &scr_native_array_iterator_next_call, "next");
|
|
2546
2993
|
}
|
|
@@ -2562,12 +3009,26 @@ static ScrDyn *scr_native_iterator_new(ScrDyn *source) {
|
|
|
2562
3009
|
ScrNativeIterator *iterator = malloc(sizeof *iterator);
|
|
2563
3010
|
if (!iterator) scr_json_oom();
|
|
2564
3011
|
*iterator = (ScrNativeIterator){ .rc = 1, .source = scr_dyn_retain(source), .index = 0,
|
|
2565
|
-
.
|
|
3012
|
+
.kind = source->kind == SCR_DYN_STR ? 1 : source->kind == SCR_DYN_HANDLE && source->v.handle.tag == SCR_DYNH_MAP ? 2
|
|
3013
|
+
: source->kind == SCR_DYN_HANDLE && source->v.handle.tag == SCR_DYNH_SET ? 3
|
|
3014
|
+
: source->kind == SCR_DYN_HANDLE && scr_dyn_handle_ops_of(source)->iter_step ? 4 : 0,
|
|
3015
|
+
.selection = source->kind == SCR_DYN_HANDLE && (source->v.handle.tag == SCR_DYNH_MAP || scr_dyn_handle_ops_of(source)->iter_step) ? 2 : 0 };
|
|
3016
|
+
if (iterator->kind == 2 || iterator->kind == 3) scr_map_iter_enter(source->v.handle.ptr);
|
|
2566
3017
|
ScrDyn *result = scr_dyn_new_handle(iterator, SCR_DYNH_ITERATOR);
|
|
2567
3018
|
scr_native_iterator_release(iterator);
|
|
2568
3019
|
return result;
|
|
2569
3020
|
}
|
|
2570
3021
|
|
|
3022
|
+
static ScrDyn *scr_native_collection_iterator(ScrDyn *source, unsigned selection) {
|
|
3023
|
+
ScrDyn *result = scr_native_iterator_new(source);
|
|
3024
|
+
((ScrNativeIterator *)result->v.handle.ptr)->selection = selection;
|
|
3025
|
+
return result;
|
|
3026
|
+
}
|
|
3027
|
+
|
|
3028
|
+
ScrDyn *scr_dyn_native_handle_iterator(ScrDyn *source, unsigned selection) {
|
|
3029
|
+
return scr_native_collection_iterator(source, selection);
|
|
3030
|
+
}
|
|
3031
|
+
|
|
2571
3032
|
static ScrDyn *scr_builtin_iterator_checked(int kind) {
|
|
2572
3033
|
ScrDyn *self = scr_dyn_this_get();
|
|
2573
3034
|
ScrDyn *result = NULL;
|
|
@@ -2604,6 +3065,11 @@ static ScrDyn *scr_iterator_self_call(ScrClosure *closure, ScrDyn *const *args,
|
|
|
2604
3065
|
static ScrDyn *scr_handle_iterator_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
2605
3066
|
(void)closure; (void)args; (void)argc;
|
|
2606
3067
|
ScrDyn *self = scr_dyn_this_get();
|
|
3068
|
+
if (self->kind == SCR_DYN_HANDLE && (self->v.handle.tag == SCR_DYNH_MAP || self->v.handle.tag == SCR_DYNH_SET || scr_dyn_handle_ops_of(self)->iter_step)) {
|
|
3069
|
+
ScrDyn *result = scr_native_iterator_new(self);
|
|
3070
|
+
scr_dyn_release(self);
|
|
3071
|
+
return result;
|
|
3072
|
+
}
|
|
2607
3073
|
ScrDyn *items = scr_dyn_iter_pack(self, NULL);
|
|
2608
3074
|
ScrDyn *result = items ? scr_native_iterator_new(items) : NULL;
|
|
2609
3075
|
scr_dyn_release(items);
|
|
@@ -2616,10 +3082,11 @@ ScrDyn *scr_dyn_array_values_function(void) {
|
|
|
2616
3082
|
}
|
|
2617
3083
|
|
|
2618
3084
|
static ScrDyn *scr_builtin_iterator_method(const ScrDyn *value) {
|
|
3085
|
+
if (scr_dyn_generator(value)) return scr_iterator_function(4, &scr_iterator_self_call, "[Symbol.iterator]");
|
|
2619
3086
|
if (value->kind == SCR_DYN_ARR || (value->kind == SCR_DYN_TYPED_REF && scr_dyn_isl_is_array(value))) return scr_dyn_array_values_function();
|
|
2620
3087
|
if (value->kind == SCR_DYN_BYTES) return scr_iterator_function(2, &scr_builtin_bytes_iterator_call, "values");
|
|
2621
3088
|
if (value->kind == SCR_DYN_STR) return scr_iterator_function(3, &scr_builtin_string_iterator_call, "[Symbol.iterator]");
|
|
2622
|
-
if (value->kind == SCR_DYN_HANDLE && scr_dyn_handle_ops_of(value)->iter_pack)
|
|
3089
|
+
if (value->kind == SCR_DYN_HANDLE && (value->v.handle.tag == SCR_DYNH_MAP || value->v.handle.tag == SCR_DYNH_SET || scr_dyn_handle_ops_of(value)->iter_pack || scr_dyn_handle_ops_of(value)->iter_step))
|
|
2623
3090
|
return scr_iterator_function(6, &scr_handle_iterator_call, "[Symbol.iterator]");
|
|
2624
3091
|
return scr_iterator_function(4, &scr_iterator_self_call, "[Symbol.iterator]");
|
|
2625
3092
|
}
|
|
@@ -2644,6 +3111,21 @@ static ScrDyn *scr_iterator_method(const ScrDyn *source) {
|
|
|
2644
3111
|
}
|
|
2645
3112
|
|
|
2646
3113
|
/* Compiled class methods are dispatched before this checked-object path. */
|
|
3114
|
+
ScrDyn *scr_dyn_iterator_optional(const ScrDyn *source) {
|
|
3115
|
+
ScrDyn *method = scr_iterator_method(source);
|
|
3116
|
+
if (!method) return NULL;
|
|
3117
|
+
if (method->kind == SCR_DYN_UNDEF || method->kind == SCR_DYN_NULL) {
|
|
3118
|
+
scr_dyn_release(method);
|
|
3119
|
+
return NULL;
|
|
3120
|
+
}
|
|
3121
|
+
ScrDyn *iterator = scr_iterator_call(method, source, "value[Symbol.iterator]");
|
|
3122
|
+
scr_dyn_release(method);
|
|
3123
|
+
if (!iterator) return NULL;
|
|
3124
|
+
ScrDyn *checked = scr_dyn_iterator_result(iterator);
|
|
3125
|
+
scr_dyn_release(iterator);
|
|
3126
|
+
return checked;
|
|
3127
|
+
}
|
|
3128
|
+
|
|
2647
3129
|
ScrDyn *scr_dyn_iterator(const ScrDyn *source, const ScrStr *spell) {
|
|
2648
3130
|
if (source->kind == SCR_DYN_JSVAL) return scr_dyn_jsval_ops()->iterator(source->v.jsval.cell, spell, false);
|
|
2649
3131
|
if (source->kind == SCR_DYN_NULL || source->kind == SCR_DYN_UNDEF) return scr_dyn_not_iterable(source, spell);
|
|
@@ -2662,6 +3144,14 @@ ScrDyn *scr_dyn_iterator(const ScrDyn *source, const ScrStr *spell) {
|
|
|
2662
3144
|
}
|
|
2663
3145
|
|
|
2664
3146
|
static ScrDyn *scr_iterator_read(const ScrDyn *value, const char *key, size_t len) {
|
|
3147
|
+
if (value->kind == SCR_DYN_TYPED_REF) {
|
|
3148
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(value);
|
|
3149
|
+
if (!view) return NULL;
|
|
3150
|
+
ScrDyn *result = scr_iterator_read(view, key, len);
|
|
3151
|
+
scr_dyn_release(view);
|
|
3152
|
+
return result;
|
|
3153
|
+
}
|
|
3154
|
+
if (value->kind == SCR_DYN_PROXY) return scr_dyn_obj_read(value, key, len);
|
|
2665
3155
|
if (value->kind == SCR_DYN_HANDLE) {
|
|
2666
3156
|
ScrStr *name = scr_str_new(key, len);
|
|
2667
3157
|
ScrDyn *result = scr_dyn_handle_key_get(value, name);
|
|
@@ -2701,14 +3191,10 @@ ScrDyn *scr_dyn_array_from_iterator(const ScrDyn *source) {
|
|
|
2701
3191
|
numeric = false;
|
|
2702
3192
|
}
|
|
2703
3193
|
if (!numeric) { scr_dyn_release(out); return NULL; }
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
if (!value) { scr_dyn_release(out); return NULL; }
|
|
2709
|
-
scr_dyn_arr_push(out, value);
|
|
2710
|
-
}
|
|
2711
|
-
ScrDyn *iterator = scr_native_iterator_new(out);
|
|
3194
|
+
ScrDyn *iterator = scr_native_iterator_new((ScrDyn *)source);
|
|
3195
|
+
ScrNativeIterator *state = iterator->v.handle.ptr;
|
|
3196
|
+
state->array_like = true;
|
|
3197
|
+
state->limit = isnan(n) || n < 0 ? 0 : floor(n);
|
|
2712
3198
|
scr_dyn_release(out);
|
|
2713
3199
|
return iterator;
|
|
2714
3200
|
}
|
|
@@ -2722,7 +3208,9 @@ ScrDyn *scr_dyn_array_from_iterator(const ScrDyn *source) {
|
|
|
2722
3208
|
}
|
|
2723
3209
|
|
|
2724
3210
|
ScrDyn *scr_dyn_symbol_key_get(const ScrDyn *value, const ScrDyn *key, bool optional) {
|
|
2725
|
-
if (value
|
|
3211
|
+
if (scr_dyn_generator(value)) return scr_dyn_generator_symbol(value, key)
|
|
3212
|
+
? scr_iterator_function(4, &scr_iterator_self_call, "[Symbol.iterator]") : scr_dyn_retain(scr_dyn_undefined());
|
|
3213
|
+
if (value->kind == SCR_DYN_TYPED_REF) {
|
|
2726
3214
|
ScrDyn *view = scr_dyn_typed_ref_materialize(value);
|
|
2727
3215
|
ScrDyn *result = scr_exc_pending() ? NULL : scr_dyn_symbol_key_get(view, key, optional);
|
|
2728
3216
|
scr_dyn_release(view);
|
|
@@ -2823,7 +3311,12 @@ static bool scr_dyn_key_probe_computed(const ScrDyn *value, const ScrDyn *raw_ke
|
|
|
2823
3311
|
scr_dyn_release(key);
|
|
2824
3312
|
return out;
|
|
2825
3313
|
}
|
|
2826
|
-
if (
|
|
3314
|
+
if (scr_dyn_generator(value)) {
|
|
3315
|
+
bool found = mode == 0 && scr_dyn_generator_symbol(value, key);
|
|
3316
|
+
scr_dyn_release(key);
|
|
3317
|
+
return found;
|
|
3318
|
+
}
|
|
3319
|
+
if (value->kind == SCR_DYN_TYPED_REF) {
|
|
2827
3320
|
ScrDyn *view = scr_dyn_typed_ref_materialize(value);
|
|
2828
3321
|
bool out = !scr_exc_pending() && scr_dyn_key_probe_computed(view, key, mode);
|
|
2829
3322
|
scr_dyn_release(view);
|
|
@@ -2892,7 +3385,7 @@ void scr_dyn_key_delete_computed(ScrDyn *value, const ScrDyn *raw_key, bool stri
|
|
|
2892
3385
|
* Refuse overrides until every typed call site observes the property table. */
|
|
2893
3386
|
static bool scr_dyn_fn_property_fence(const ScrStr *key) {
|
|
2894
3387
|
static const char *const reserved[] = {
|
|
2895
|
-
"call", "apply", "bind", "
|
|
3388
|
+
"call", "apply", "bind", "valueOf", "toLocaleString",
|
|
2896
3389
|
"hasOwnProperty", "propertyIsEnumerable", "isPrototypeOf",
|
|
2897
3390
|
"constructor", "caller", "arguments", "__proto__",
|
|
2898
3391
|
};
|
|
@@ -2906,6 +3399,20 @@ static bool scr_dyn_fn_property_fence(const ScrStr *key) {
|
|
|
2906
3399
|
}
|
|
2907
3400
|
|
|
2908
3401
|
ScrDyn *scr_dyn_define_property(ScrDyn *target, ScrDyn *key, ScrDyn *descriptor) {
|
|
3402
|
+
if (target->kind == SCR_DYN_TYPED_REF) {
|
|
3403
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(target);
|
|
3404
|
+
ScrDyn *defined = scr_exc_pending() ? NULL : scr_dyn_define_property(view, key, descriptor);
|
|
3405
|
+
if (!scr_exc_pending()) scr_dyn_typed_ref_commit(target);
|
|
3406
|
+
scr_dyn_release(defined);
|
|
3407
|
+
scr_dyn_release(view);
|
|
3408
|
+
return scr_exc_pending() ? NULL : scr_dyn_retain(target);
|
|
3409
|
+
}
|
|
3410
|
+
if (descriptor->kind == SCR_DYN_TYPED_REF) {
|
|
3411
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(descriptor);
|
|
3412
|
+
ScrDyn *result = scr_exc_pending() ? NULL : scr_dyn_define_property(target, key, view);
|
|
3413
|
+
scr_dyn_release(view);
|
|
3414
|
+
return result;
|
|
3415
|
+
}
|
|
2909
3416
|
if (key->kind == SCR_DYN_SYMBOL) return scr_dyn_define_symbol(target, key, descriptor);
|
|
2910
3417
|
if (target->kind == SCR_DYN_PROXY || descriptor->kind == SCR_DYN_PROXY) {
|
|
2911
3418
|
scr_dyn_proxy_unsupported("Object.defineProperty");
|
|
@@ -3415,6 +3922,29 @@ static SCR_TL ScrErrDynEnt *scr_errdyn_cache = NULL;
|
|
|
3415
3922
|
static SCR_TL size_t scr_errdyn_n = 0, scr_errdyn_cap = 0;
|
|
3416
3923
|
static SCR_TL bool scr_errdyn_teardown_registered = false;
|
|
3417
3924
|
|
|
3925
|
+
typedef struct {
|
|
3926
|
+
const ScrVt *vt;
|
|
3927
|
+
ScrDyn *(*box)(void *);
|
|
3928
|
+
} ScrErrorDynType;
|
|
3929
|
+
static SCR_TL ScrErrorDynType *scr_error_dyn_types = NULL;
|
|
3930
|
+
static SCR_TL size_t scr_error_dyn_type_count = 0;
|
|
3931
|
+
|
|
3932
|
+
static void scr_error_dyn_types_drop(void) {
|
|
3933
|
+
free(scr_error_dyn_types);
|
|
3934
|
+
scr_error_dyn_types = NULL;
|
|
3935
|
+
scr_error_dyn_type_count = 0;
|
|
3936
|
+
}
|
|
3937
|
+
|
|
3938
|
+
void scr_error_register_dyn(const ScrVt *vt, ScrDyn *(*box)(void *)) {
|
|
3939
|
+
for (size_t i = 0; i < scr_error_dyn_type_count; i++) {
|
|
3940
|
+
if (scr_error_dyn_types[i].vt == vt) return;
|
|
3941
|
+
}
|
|
3942
|
+
if (!scr_error_dyn_type_count) scr_atexit(scr_error_dyn_types_drop);
|
|
3943
|
+
scr_error_dyn_types = realloc(scr_error_dyn_types, (scr_error_dyn_type_count + 1) * sizeof *scr_error_dyn_types);
|
|
3944
|
+
if (!scr_error_dyn_types) scr_json_oom();
|
|
3945
|
+
scr_error_dyn_types[scr_error_dyn_type_count++] = (ScrErrorDynType){vt, box};
|
|
3946
|
+
}
|
|
3947
|
+
|
|
3418
3948
|
static void scr_errdyn_teardown(void) {
|
|
3419
3949
|
for (size_t i = 0; i < scr_errdyn_n; i++) {
|
|
3420
3950
|
scr_error_release(scr_errdyn_cache[i].err);
|
|
@@ -3425,14 +3955,32 @@ static void scr_errdyn_teardown(void) {
|
|
|
3425
3955
|
scr_errdyn_n = scr_errdyn_cap = 0;
|
|
3426
3956
|
}
|
|
3427
3957
|
|
|
3428
|
-
ScrDyn *
|
|
3429
|
-
for (size_t i = 0; i < scr_errdyn_n; i++) {
|
|
3430
|
-
if (scr_errdyn_cache[i].err == e) return scr_dyn_retain(scr_errdyn_cache[i].dyn);
|
|
3431
|
-
}
|
|
3958
|
+
ScrDyn *scr_error_dyn_fields(const ScrError *e) {
|
|
3432
3959
|
ScrDyn *d = scr_dyn_new_obj();
|
|
3433
3960
|
scr_dyn_obj_set(d, "%error", 6, scr_dyn_new_bool(true)); /* the checked-dynamic tree's error marker */
|
|
3434
|
-
|
|
3435
|
-
|
|
3961
|
+
d->v.obj.entries[d->v.obj.len - 1].enumerable = false;
|
|
3962
|
+
if (e->name_present) {
|
|
3963
|
+
scr_dyn_obj_set(d, "name", 4, scr_dyn_new_str(e->name));
|
|
3964
|
+
d->v.obj.entries[d->v.obj.len - 1].enumerable = e->name_enumerable;
|
|
3965
|
+
}
|
|
3966
|
+
if (!e->name_present || !e->message_present) {
|
|
3967
|
+
ScrDyn *prototype = scr_dyn_new_obj();
|
|
3968
|
+
if (!e->name_present) {
|
|
3969
|
+
scr_dyn_obj_set(prototype, "name", 4, scr_dyn_new_str(e->name));
|
|
3970
|
+
prototype->v.obj.entries[prototype->v.obj.len - 1].enumerable = false;
|
|
3971
|
+
}
|
|
3972
|
+
if (!e->message_present) {
|
|
3973
|
+
scr_dyn_obj_set(prototype, "message", 7, scr_dyn_new_str(e->message));
|
|
3974
|
+
prototype->v.obj.entries[prototype->v.obj.len - 1].enumerable = false;
|
|
3975
|
+
}
|
|
3976
|
+
scr_dyn_release(scr_dyn_set_prototype(d, prototype));
|
|
3977
|
+
scr_dyn_release(prototype);
|
|
3978
|
+
}
|
|
3979
|
+
if (e->message_present) {
|
|
3980
|
+
scr_dyn_obj_set(d, "message", 7, scr_dyn_new_str(e->message));
|
|
3981
|
+
d->v.obj.entries[d->v.obj.len - 1].enumerable = e->message_enumerable;
|
|
3982
|
+
}
|
|
3983
|
+
if (e->stack) scr_dyn_obj_set(d, "stack", 5, scr_dyn_new_str(e->stack));
|
|
3436
3984
|
if (e->code) scr_dyn_obj_set(d, "code", 4, scr_dyn_new_str(e->code));
|
|
3437
3985
|
if (e->error_cause) {
|
|
3438
3986
|
scr_dyn_obj_set(d, "cause", 5, scr_dyn_retain(e->error_cause));
|
|
@@ -3446,6 +3994,21 @@ ScrDyn *scr_dyn_from_error(const ScrError *e) {
|
|
|
3446
3994
|
scr_dyn_obj_set(d, "cause", 5, scr_domex_cause((ScrError *)e));
|
|
3447
3995
|
}
|
|
3448
3996
|
}
|
|
3997
|
+
return d;
|
|
3998
|
+
}
|
|
3999
|
+
|
|
4000
|
+
ScrDyn *scr_dyn_from_error(const ScrError *e) {
|
|
4001
|
+
for (size_t i = 0; i < scr_errdyn_n; i++) {
|
|
4002
|
+
if (scr_errdyn_cache[i].err == e) return scr_dyn_retain(scr_errdyn_cache[i].dyn);
|
|
4003
|
+
}
|
|
4004
|
+
ScrDyn *d = NULL;
|
|
4005
|
+
for (size_t i = 0; i < scr_error_dyn_type_count; i++) {
|
|
4006
|
+
if (scr_error_dyn_types[i].vt == e->vt) {
|
|
4007
|
+
d = scr_error_dyn_types[i].box((void *)e);
|
|
4008
|
+
break;
|
|
4009
|
+
}
|
|
4010
|
+
}
|
|
4011
|
+
if (!d) d = scr_error_dyn_fields(e);
|
|
3449
4012
|
if (scr_errdyn_n == scr_errdyn_cap) {
|
|
3450
4013
|
scr_errdyn_cap = scr_errdyn_cap ? scr_errdyn_cap * 2 : 8;
|
|
3451
4014
|
scr_errdyn_cache = realloc(scr_errdyn_cache, scr_errdyn_cap * sizeof *scr_errdyn_cache);
|
|
@@ -3474,6 +4037,54 @@ ScrDyn *scr_dyn_from_error(const ScrError *e) {
|
|
|
3474
4037
|
* its next boxing answers the same dyn node. The dyn node is borrowed. */
|
|
3475
4038
|
static void scr_error_cause_drop_impl(void *obj);
|
|
3476
4039
|
|
|
4040
|
+
void scr_error_commit_dyn(ScrError *e, const ScrDyn *view) {
|
|
4041
|
+
ScrDynEntry *name_entry = NULL;
|
|
4042
|
+
for (size_t i = 0; i < view->v.obj.len; i++) {
|
|
4043
|
+
ScrDynEntry *entry = &view->v.obj.entries[i];
|
|
4044
|
+
if (entry->key_len == 4 && memcmp(entry->key, "name", 4) == 0) { name_entry = entry; break; }
|
|
4045
|
+
}
|
|
4046
|
+
ScrDyn *name = name_entry ? name_entry->value : NULL;
|
|
4047
|
+
if (name && name->kind != SCR_DYN_STR) {
|
|
4048
|
+
scr_dyn_check_fail(NULL, "string", name);
|
|
4049
|
+
return;
|
|
4050
|
+
}
|
|
4051
|
+
ScrStr *next_name = name ? scr_str_retain(name->v.str) : scr_error_default_name(e);
|
|
4052
|
+
scr_str_release(e->name);
|
|
4053
|
+
e->name = next_name;
|
|
4054
|
+
e->name_present = name != NULL;
|
|
4055
|
+
e->name_enumerable = name_entry && name_entry->enumerable;
|
|
4056
|
+
ScrDyn *message = scr_dyn_obj_get(view, "message", 7);
|
|
4057
|
+
if (message && message->kind != SCR_DYN_STR) {
|
|
4058
|
+
scr_dyn_check_fail(NULL, "string", message);
|
|
4059
|
+
return;
|
|
4060
|
+
}
|
|
4061
|
+
ScrStr *next_message = message ? scr_str_retain(message->v.str) : scr_str_new("", 0);
|
|
4062
|
+
scr_str_release(e->message);
|
|
4063
|
+
e->message = next_message;
|
|
4064
|
+
e->message_present = message != NULL;
|
|
4065
|
+
e->message_enumerable = false;
|
|
4066
|
+
for (size_t i = 0; message && i < view->v.obj.len; i++) {
|
|
4067
|
+
const ScrDynEntry *entry = &view->v.obj.entries[i];
|
|
4068
|
+
if (entry->key_len == 7 && memcmp(entry->key, "message", 7) == 0) e->message_enumerable = entry->enumerable;
|
|
4069
|
+
}
|
|
4070
|
+
ScrDyn *stack = scr_dyn_obj_get(view, "stack", 5);
|
|
4071
|
+
if (stack && stack->kind == SCR_DYN_STR) {
|
|
4072
|
+
ScrStr *replacement = scr_str_retain(stack->v.str);
|
|
4073
|
+
scr_str_release(e->stack);
|
|
4074
|
+
e->stack = replacement;
|
|
4075
|
+
}
|
|
4076
|
+
ScrDyn *cause = scr_dyn_obj_get(view, "cause", 5);
|
|
4077
|
+
scr_error_install_cause_drop(&scr_error_cause_drop_impl);
|
|
4078
|
+
ScrDyn *replacement = cause ? scr_dyn_retain(cause) : NULL;
|
|
4079
|
+
scr_dyn_release(e->error_cause);
|
|
4080
|
+
e->error_cause = replacement;
|
|
4081
|
+
e->cause_enumerable = false;
|
|
4082
|
+
for (size_t i = 0; cause && i < view->v.obj.len; i++) {
|
|
4083
|
+
const ScrDynEntry *entry = &view->v.obj.entries[i];
|
|
4084
|
+
if (entry->key_len == 5 && memcmp(entry->key, "cause", 5) == 0) e->cause_enumerable = entry->enumerable;
|
|
4085
|
+
}
|
|
4086
|
+
}
|
|
4087
|
+
|
|
3477
4088
|
ScrError *scr_error_from_dyn(const ScrDyn *d) {
|
|
3478
4089
|
ScrError *hit = scr_errdyn_err_of(d);
|
|
3479
4090
|
if (hit) return hit;
|
|
@@ -3494,6 +4105,8 @@ ScrError *scr_error_from_dyn(const ScrDyn *d) {
|
|
|
3494
4105
|
if (en && en->kind == SCR_DYN_STR) {
|
|
3495
4106
|
scr_str_release(e->name);
|
|
3496
4107
|
e->name = scr_str_retain(en->v.str);
|
|
4108
|
+
e->name_present = true;
|
|
4109
|
+
e->name_enumerable = true;
|
|
3497
4110
|
}
|
|
3498
4111
|
if (ec && ec->kind == SCR_DYN_STR) e->code = scr_str_retain(ec->v.str);
|
|
3499
4112
|
ScrDyn *cause = scr_dyn_obj_get(d, "cause", 5);
|
|
@@ -3539,11 +4152,20 @@ void scr_errdyn_put(ScrError *e, ScrDyn *d) {
|
|
|
3539
4152
|
/* Error.cause has one live value even when the Error already crossed a
|
|
3540
4153
|
* checked-value boundary. Reflective data-property edits update its slot. */
|
|
3541
4154
|
static void scr_error_sync_cause(ScrDyn *view, const ScrStr *key) {
|
|
3542
|
-
|
|
4155
|
+
bool cause = key->len == 5 && memcmp(key->data, "cause", 5) == 0;
|
|
4156
|
+
bool stack = key->len == 5 && memcmp(key->data, "stack", 5) == 0;
|
|
4157
|
+
if (!cause && !stack) return;
|
|
3543
4158
|
ScrDynEntry *entry = scr_dyn_entry(view, key);
|
|
3544
4159
|
for (size_t i = 0; i < scr_errdyn_n; i++) {
|
|
3545
4160
|
if (scr_errdyn_cache[i].dyn != view) continue;
|
|
3546
4161
|
ScrError *e = scr_errdyn_cache[i].err;
|
|
4162
|
+
if (stack) {
|
|
4163
|
+
if (entry && entry->value->kind == SCR_DYN_STR) {
|
|
4164
|
+
scr_str_release(e->stack);
|
|
4165
|
+
e->stack = scr_str_retain(entry->value->v.str);
|
|
4166
|
+
}
|
|
4167
|
+
continue;
|
|
4168
|
+
}
|
|
3547
4169
|
if (e->vt == &scr_error_vts[SCR_ERR_DOMEX]) continue;
|
|
3548
4170
|
ScrDyn *replacement = entry ? scr_dyn_retain(entry->value) : NULL;
|
|
3549
4171
|
scr_error_install_cause_drop(&scr_error_cause_drop_impl);
|
|
@@ -3687,20 +4309,7 @@ ScrStr *scr_dyn_to_string_argument(const ScrDyn *d, const ScrDyn *argument, cons
|
|
|
3687
4309
|
scr_str_release(encoding);
|
|
3688
4310
|
return result;
|
|
3689
4311
|
}
|
|
3690
|
-
if (d->kind == SCR_DYN_NUM
|
|
3691
|
-
double radix;
|
|
3692
|
-
if (!scr_dyn_number_coerce_js(argument, &radix)) return NULL;
|
|
3693
|
-
if (!isfinite(radix) || trunc(radix) < 2 || trunc(radix) > 36) {
|
|
3694
|
-
static const char message[] = "toString() radix argument must be between 2 and 36";
|
|
3695
|
-
scr_throw_error_msg(SCR_ERR_RANGE, message, sizeof message - 1);
|
|
3696
|
-
return NULL;
|
|
3697
|
-
}
|
|
3698
|
-
if (trunc(radix) != 10) {
|
|
3699
|
-
static const char message[] = "Number.toString with a non-decimal radix has no native lowering";
|
|
3700
|
-
scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
|
|
3701
|
-
return NULL;
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
4312
|
+
if (d->kind == SCR_DYN_NUM) return scr_num_to_string_radix(d->v.num, argument);
|
|
3704
4313
|
if (d->kind == SCR_DYN_OBJ && !scr_dyn_property_owner(d, "toString", 8) && !scr_dyn_has_object_prototype(d)) {
|
|
3705
4314
|
ScrJsonBuf b;
|
|
3706
4315
|
scr_jb_init(&b);
|
|
@@ -3709,7 +4318,7 @@ ScrStr *scr_dyn_to_string_argument(const ScrDyn *d, const ScrDyn *argument, cons
|
|
|
3709
4318
|
scr_throw_error(SCR_ERR_TYPE, scr_jb_finish(&b));
|
|
3710
4319
|
return scr_str_new("", 0);
|
|
3711
4320
|
}
|
|
3712
|
-
return
|
|
4321
|
+
return scr_dyn_to_string_method(d, NULL, what);
|
|
3713
4322
|
}
|
|
3714
4323
|
|
|
3715
4324
|
/* JS String() over the dyn kind — the WebIDL ToString the web globals
|
|
@@ -3929,6 +4538,26 @@ double scr_dyn_number_constructor(const ScrDyn *d) {
|
|
|
3929
4538
|
return result;
|
|
3930
4539
|
}
|
|
3931
4540
|
|
|
4541
|
+
ScrBigInt *scr_dyn_bigint_constructor(const ScrDyn *d) {
|
|
4542
|
+
ScrDyn *primitive = scr_dyn_add_primitive(d);
|
|
4543
|
+
if (!primitive) return NULL;
|
|
4544
|
+
ScrBigInt *result = NULL;
|
|
4545
|
+
switch (primitive->kind) {
|
|
4546
|
+
case SCR_DYN_BIGINT: result = scr_bigint_retain(primitive->v.bigint); break;
|
|
4547
|
+
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;
|
|
4549
|
+
case SCR_DYN_BOOL: result = scr_bigint_from_i64(primitive->v.b ? 1 : 0); break;
|
|
4550
|
+
default: {
|
|
4551
|
+
const char *message = primitive->kind == SCR_DYN_NULL ? "Cannot convert null to a BigInt"
|
|
4552
|
+
: primitive->kind == SCR_DYN_UNDEF ? "Cannot convert undefined to a BigInt" : "Cannot convert Symbol() to a BigInt";
|
|
4553
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, strlen(message));
|
|
4554
|
+
break;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
scr_dyn_release(primitive);
|
|
4558
|
+
return result;
|
|
4559
|
+
}
|
|
4560
|
+
|
|
3932
4561
|
/* OrdinaryToPrimitive's default hint is numeric for the represented
|
|
3933
4562
|
* ordinary objects. Retain the primitive itself: addition must choose
|
|
3934
4563
|
* string concatenation before either side is converted to a number. */
|
|
@@ -4040,6 +4669,44 @@ ScrDyn *scr_dyn_increment(const ScrDyn *value, bool increment) {
|
|
|
4040
4669
|
return scr_dyn_new_num(value->v.num + (increment ? 1 : -1));
|
|
4041
4670
|
}
|
|
4042
4671
|
|
|
4672
|
+
bool scr_dyn_compare(const ScrDyn *left, const ScrDyn *right, const ScrStr *operation) {
|
|
4673
|
+
// ToPrimitive is observable and always visits the original left operand
|
|
4674
|
+
// first, including the > and <= spellings of relational comparison.
|
|
4675
|
+
ScrDyn *l = scr_dyn_add_primitive(left);
|
|
4676
|
+
if (!l) return false;
|
|
4677
|
+
ScrDyn *r = scr_dyn_add_primitive(right);
|
|
4678
|
+
if (!r) { scr_dyn_release(l); return false; }
|
|
4679
|
+
double order = 2;
|
|
4680
|
+
if (l->kind == SCR_DYN_STR && r->kind == SCR_DYN_STR) {
|
|
4681
|
+
int compared = scr_str_cmp_u16(l->v.str, r->v.str);
|
|
4682
|
+
order = compared < 0 ? -1 : compared > 0 ? 1 : 0;
|
|
4683
|
+
} else if (l->kind == SCR_DYN_BIGINT && r->kind == SCR_DYN_STR) {
|
|
4684
|
+
order = scr_bigint_cmp_string(l->v.bigint, r->v.str);
|
|
4685
|
+
} else if (l->kind == SCR_DYN_STR && r->kind == SCR_DYN_BIGINT) {
|
|
4686
|
+
double opposite = scr_bigint_cmp_string(r->v.bigint, l->v.str);
|
|
4687
|
+
order = opposite == 2 ? 2 : -opposite;
|
|
4688
|
+
} else if (l->kind == SCR_DYN_BIGINT && r->kind == SCR_DYN_BIGINT) {
|
|
4689
|
+
order = scr_bigint_cmp_f64(l->v.bigint, r->v.bigint);
|
|
4690
|
+
} else {
|
|
4691
|
+
double a = 0, b = 0;
|
|
4692
|
+
bool valid = (l->kind == SCR_DYN_BIGINT || scr_dyn_number_coerce_js(l, &a)) &&
|
|
4693
|
+
(r->kind == SCR_DYN_BIGINT || scr_dyn_number_coerce_js(r, &b));
|
|
4694
|
+
if (valid) {
|
|
4695
|
+
if (l->kind == SCR_DYN_BIGINT) order = scr_bigint_cmp_number(l->v.bigint, b);
|
|
4696
|
+
else if (r->kind == SCR_DYN_BIGINT) {
|
|
4697
|
+
double opposite = scr_bigint_cmp_number(r->v.bigint, a);
|
|
4698
|
+
order = opposite == 2 ? 2 : -opposite;
|
|
4699
|
+
} else if (!isnan(a) && !isnan(b)) order = a < b ? -1 : a > b ? 1 : 0;
|
|
4700
|
+
}
|
|
4701
|
+
}
|
|
4702
|
+
scr_dyn_release(l);
|
|
4703
|
+
scr_dyn_release(r);
|
|
4704
|
+
if (scr_exc_pending() || order == 2) return false;
|
|
4705
|
+
return operation->data[0] == '<'
|
|
4706
|
+
? (operation->len == 2 ? order <= 0 : order < 0)
|
|
4707
|
+
: (operation->len == 2 ? order >= 0 : order > 0);
|
|
4708
|
+
}
|
|
4709
|
+
|
|
4043
4710
|
ScrDyn *scr_dyn_arithmetic(const ScrDyn *left, const ScrDyn *right, const ScrStr *operation) {
|
|
4044
4711
|
ScrDyn *l = scr_dyn_to_numeric(left);
|
|
4045
4712
|
if (!l) return NULL;
|
|
@@ -4121,6 +4788,12 @@ static const char *scr_dyn_kind_name(const ScrDyn *d);
|
|
|
4121
4788
|
* valid dense index, every other kind false (tsc admits `in` only on
|
|
4122
4789
|
* object-typed operands). Proxy traps may throw. Borrows both. */
|
|
4123
4790
|
bool scr_dyn_has_key(const ScrDyn *v, const ScrStr *key) {
|
|
4791
|
+
if (scr_dyn_generator(v)) {
|
|
4792
|
+
static const char *const inherited[] = { "next", "return", "throw", "constructor", "toString", "valueOf", "hasOwnProperty", "propertyIsEnumerable", "isPrototypeOf", "toLocaleString", "__proto__" };
|
|
4793
|
+
for (size_t i = 0; i < sizeof inherited / sizeof inherited[0]; i++)
|
|
4794
|
+
if (key->len == strlen(inherited[i]) && memcmp(key->data, inherited[i], key->len) == 0) return true;
|
|
4795
|
+
return false;
|
|
4796
|
+
}
|
|
4124
4797
|
if (scr_dyn_class_reflection_fence(v)) return false;
|
|
4125
4798
|
if (v->kind == SCR_DYN_PROXY) return scr_dyn_proxy_has(v, key);
|
|
4126
4799
|
if (v->kind == SCR_DYN_JSVAL) return scr_dyn_isl_fence(v, "'in'");
|
|
@@ -4131,12 +4804,10 @@ bool scr_dyn_has_key(const ScrDyn *v, const ScrStr *key) {
|
|
|
4131
4804
|
return out;
|
|
4132
4805
|
}
|
|
4133
4806
|
if (v->kind == SCR_DYN_OBJ) {
|
|
4134
|
-
|
|
4135
|
-
if (scr_dyn_obj_get(current, key->data, key->len)) return true;
|
|
4136
|
-
}
|
|
4137
|
-
return false;
|
|
4807
|
+
return scr_dyn_property_owner(v, key->data, key->len) != NULL;
|
|
4138
4808
|
}
|
|
4139
4809
|
if (v->kind == SCR_DYN_FUNC) {
|
|
4810
|
+
if (scr_dyn_property_owner(v, key->data, key->len)) return true;
|
|
4140
4811
|
ScrDyn *descriptor = scr_dyn_own_descriptor(v, key);
|
|
4141
4812
|
bool present = descriptor && descriptor->kind != SCR_DYN_UNDEF;
|
|
4142
4813
|
scr_dyn_release(descriptor);
|
|
@@ -5151,6 +5822,14 @@ static void scr_json_delete_member(ScrDyn *object, const ScrStr *key) {
|
|
|
5151
5822
|
void scr_dyn_key_delete(ScrDyn *recv, const ScrStr *key, bool strict) {
|
|
5152
5823
|
if (scr_dyn_class_reflection_fence(recv)) return;
|
|
5153
5824
|
if (recv->kind == SCR_DYN_PROXY) { scr_dyn_proxy_delete(recv, key); return; }
|
|
5825
|
+
if (recv->kind == SCR_DYN_TYPED_REF && recv->v.typed_ref.commit &&
|
|
5826
|
+
!strncmp(recv->v.typed_ref.type_key, "record:", 7)) {
|
|
5827
|
+
ScrDyn *materialized = scr_dyn_typed_ref_materialize(recv);
|
|
5828
|
+
if (!scr_exc_pending()) scr_dyn_key_delete(materialized, key, strict);
|
|
5829
|
+
if (!scr_exc_pending()) scr_dyn_typed_ref_commit(recv);
|
|
5830
|
+
scr_dyn_release(materialized);
|
|
5831
|
+
return;
|
|
5832
|
+
}
|
|
5154
5833
|
if (recv->kind == SCR_DYN_FUNC) {
|
|
5155
5834
|
if (scr_dyn_fn_property_fence(key)) return;
|
|
5156
5835
|
ScrDyn *table = scr_dyn_fn_properties(recv);
|
|
@@ -5242,6 +5921,7 @@ static ScrDyn *scr_json_revive(ScrDyn *holder, const ScrStr *key,
|
|
|
5242
5921
|
ScrDyn *scr_json_parse_reviver(ScrStr *text, const ScrDyn *reviver) {
|
|
5243
5922
|
ScrDyn *parsed = scr_json_parse(text);
|
|
5244
5923
|
if (!parsed) return NULL; /* No callback runs on invalid input. */
|
|
5924
|
+
if (reviver->kind != SCR_DYN_FUNC) return parsed;
|
|
5245
5925
|
ScrDyn *holder = scr_dyn_new_obj();
|
|
5246
5926
|
scr_dyn_obj_set(holder, "", 0, parsed);
|
|
5247
5927
|
ScrStr *key = scr_str_new("", 0);
|
|
@@ -5461,7 +6141,7 @@ bool scr_dyn_strict_eq(const ScrDyn *a, const ScrDyn *b) {
|
|
|
5461
6141
|
return a->v.handle.tag == b->v.handle.tag && a->v.handle.ptr == b->v.handle.ptr;
|
|
5462
6142
|
case SCR_DYN_PROMISE:
|
|
5463
6143
|
/* And the PROMISE: one promise crossing twice is one JS value. */
|
|
5464
|
-
return a->v.promise == b->v.promise;
|
|
6144
|
+
return a->v.promise == b->v.promise || (scr_dyn_promise_identity_fn && scr_dyn_promise_identity_fn(a->v.promise, b->v.promise));
|
|
5465
6145
|
case SCR_DYN_JSVAL:
|
|
5466
6146
|
/* Identity is the ENGINE VALUE, not the box or even the cell: two
|
|
5467
6147
|
* wraps of one engine value compare ===-equal (the engine's own
|
|
@@ -5511,6 +6191,8 @@ static ScrDyn *scr_function_constructor(uint32_t kind) {
|
|
|
5511
6191
|
/* Keyed read on a FUNC node (see scr_runtime.h): own props first, then
|
|
5512
6192
|
* the function-instance built-ins name/length. +1 or NULL. */
|
|
5513
6193
|
ScrDyn *scr_dyn_fn_get(const ScrDyn *d, const char *key, size_t key_len) {
|
|
6194
|
+
if (d->v.fn.class_obj && d->v.fn.class_obj->static_data && !d->v.fn.clo->props)
|
|
6195
|
+
d->v.fn.clo->props = scr_box_retain(d->v.fn.class_obj->static_data);
|
|
5514
6196
|
if (!d->v.fn.class_obj && key_len == 9 && !memcmp(key, "prototype", 9) && !d->v.fn.clo->props) {
|
|
5515
6197
|
if (d->v.fn.clo->function_kind & 1) {
|
|
5516
6198
|
static const char message[] = "Native generator function prototypes have no lowering";
|
|
@@ -5551,6 +6233,7 @@ ScrDyn *scr_dyn_fn_get(const ScrDyn *d, const char *key, size_t key_len) {
|
|
|
5551
6233
|
if (key_len == 6 && memcmp(key, "length", 6) == 0) {
|
|
5552
6234
|
return scr_dyn_new_num((double)d->v.fn.arity);
|
|
5553
6235
|
}
|
|
6236
|
+
if (key_len == 5 && memcmp(key, "apply", 5) == 0) return scr_dyn_function_apply();
|
|
5554
6237
|
if (d->v.fn.class_obj) {
|
|
5555
6238
|
static const char message[] = "scriptc: class properties through unknown other than name and length are not supported";
|
|
5556
6239
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
@@ -5567,6 +6250,12 @@ ScrDyn *scr_dyn_fn_get(const ScrDyn *d, const char *key, size_t key_len) {
|
|
|
5567
6250
|
|
|
5568
6251
|
void scr_sc_validate_options(const ScrDyn *options) {
|
|
5569
6252
|
if (options == NULL || options->kind == SCR_DYN_UNDEF || options->kind == SCR_DYN_NULL) return;
|
|
6253
|
+
if (options->kind == SCR_DYN_TYPED_REF) {
|
|
6254
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(options);
|
|
6255
|
+
if (view && !scr_exc_pending()) scr_sc_validate_options(view);
|
|
6256
|
+
scr_dyn_release(view);
|
|
6257
|
+
return;
|
|
6258
|
+
}
|
|
5570
6259
|
/* An engine-held options bag IS a dictionary to Node — the "cannot be
|
|
5571
6260
|
* converted" TypeError would be a wrong claim. Loud fence. */
|
|
5572
6261
|
if (options->kind == SCR_DYN_JSVAL) {
|
|
@@ -5581,10 +6270,14 @@ void scr_sc_validate_options(const ScrDyn *options) {
|
|
|
5581
6270
|
}
|
|
5582
6271
|
ScrDyn *tr = scr_dyn_obj_get(options, "transfer", 8); /* borrowed */
|
|
5583
6272
|
if (tr == NULL || tr->kind == SCR_DYN_UNDEF) return;
|
|
6273
|
+
ScrDyn *transferView = tr->kind == SCR_DYN_TYPED_REF ? scr_dyn_typed_ref_materialize(tr) : NULL;
|
|
6274
|
+
if (scr_exc_pending()) { scr_dyn_release(transferView); return; }
|
|
6275
|
+
if (transferView) tr = transferView;
|
|
5584
6276
|
if (tr->kind != SCR_DYN_ARR) {
|
|
5585
6277
|
static const char msg[] =
|
|
5586
6278
|
"Failed to execute 'structuredClone': transfer in Options can not be converted to sequence.";
|
|
5587
6279
|
scr_throw_error_msg_code(SCR_ERR_TYPE, msg, sizeof msg - 1, "ERR_INVALID_ARG_TYPE");
|
|
6280
|
+
scr_dyn_release(transferView);
|
|
5588
6281
|
return;
|
|
5589
6282
|
}
|
|
5590
6283
|
if (tr->v.arr.len > 0) {
|
|
@@ -5592,6 +6285,7 @@ void scr_sc_validate_options(const ScrDyn *options) {
|
|
|
5592
6285
|
* a non-transferable list member. */
|
|
5593
6286
|
scr_throw_domex("DataCloneError", "Found invalid value in transferList.");
|
|
5594
6287
|
}
|
|
6288
|
+
scr_dyn_release(transferView);
|
|
5595
6289
|
}
|
|
5596
6290
|
|
|
5597
6291
|
/* The parent chain rides the C stack: a revisit is a cycle. */
|
|
@@ -5745,6 +6439,16 @@ bool scr_dyn_err_instanceof(const ScrDyn *d, double kind) {
|
|
|
5745
6439
|
|
|
5746
6440
|
static ScrDyn *scr_dyn_obj_read_receiver(const ScrDyn *d, const char *key, size_t key_len, const ScrDyn *receiver) {
|
|
5747
6441
|
for (const ScrDyn *current = d; current; current = current->prototype) {
|
|
6442
|
+
if (current == scr_builtin_object_prototype) {
|
|
6443
|
+
scr_dyn_class_reflection_fence(current);
|
|
6444
|
+
return NULL;
|
|
6445
|
+
}
|
|
6446
|
+
if (current->kind == SCR_DYN_FUNC) {
|
|
6447
|
+
ScrDyn *table = scr_dyn_fn_properties(current);
|
|
6448
|
+
ScrDyn *result = scr_dyn_obj_read_receiver(table, key, key_len, receiver);
|
|
6449
|
+
scr_dyn_release(table);
|
|
6450
|
+
return result;
|
|
6451
|
+
}
|
|
5748
6452
|
if (current->kind == SCR_DYN_ARR) {
|
|
5749
6453
|
if (key_len == 6 && memcmp(key, "length", 6) == 0) return scr_dyn_new_num((double)current->v.arr.len);
|
|
5750
6454
|
double index;
|
|
@@ -5793,7 +6497,77 @@ static ScrDyn *scr_dyn_obj_read_receiver(const ScrDyn *d, const char *key, size_
|
|
|
5793
6497
|
return scr_dyn_retain(scr_dyn_undefined());
|
|
5794
6498
|
}
|
|
5795
6499
|
|
|
6500
|
+
static SCR_TL ScrDyn *scr_function_apply_value;
|
|
6501
|
+
|
|
6502
|
+
static void scr_function_apply_cleanup(void) {
|
|
6503
|
+
scr_dyn_release(scr_function_apply_value);
|
|
6504
|
+
scr_function_apply_value = NULL;
|
|
6505
|
+
}
|
|
6506
|
+
|
|
6507
|
+
ScrDyn *scr_dyn_apply_array_like(const ScrDyn *target, const ScrDyn *receiver, const ScrDyn *arguments, const char *what) {
|
|
6508
|
+
ScrDyn *list = scr_dyn_new_arr();
|
|
6509
|
+
if (arguments && arguments->kind != SCR_DYN_UNDEF && arguments->kind != SCR_DYN_NULL) {
|
|
6510
|
+
if (!scr_iterator_object(arguments)) {
|
|
6511
|
+
static const char message[] = "CreateListFromArrayLike called on non-object";
|
|
6512
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
6513
|
+
} else {
|
|
6514
|
+
ScrDyn *length = scr_iterator_read(arguments, "length", 6);
|
|
6515
|
+
double count = 0;
|
|
6516
|
+
bool ok = length && scr_dyn_number_coerce_js(length, &count);
|
|
6517
|
+
scr_dyn_release(length);
|
|
6518
|
+
if (ok && count > 1000000) {
|
|
6519
|
+
static const char message[] = "Function.prototype.apply exceeds the native argument limit";
|
|
6520
|
+
scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
|
|
6521
|
+
} else if (ok) for (size_t i = 0; (double)i < floor(count); i++) {
|
|
6522
|
+
char key[32];
|
|
6523
|
+
int size = snprintf(key, sizeof key, "%zu", i);
|
|
6524
|
+
ScrDyn *value = scr_iterator_read(arguments, key, (size_t)size);
|
|
6525
|
+
if (!value) break;
|
|
6526
|
+
scr_dyn_arr_push(list, value);
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
}
|
|
6530
|
+
ScrDyn *result = NULL;
|
|
6531
|
+
if (!scr_exc_pending()) {
|
|
6532
|
+
scr_dyn_this_push_dyn(receiver);
|
|
6533
|
+
result = scr_dyn_call(target, list->v.arr.items, list->v.arr.len, what);
|
|
6534
|
+
scr_dyn_this_pop();
|
|
6535
|
+
}
|
|
6536
|
+
scr_dyn_release(list);
|
|
6537
|
+
return result;
|
|
6538
|
+
}
|
|
6539
|
+
|
|
6540
|
+
static ScrDyn *scr_function_apply_call(ScrClosure *closure, ScrDyn *const *args, size_t argc) {
|
|
6541
|
+
(void)closure;
|
|
6542
|
+
ScrDyn *receiver = scr_dyn_this_get();
|
|
6543
|
+
if (receiver->kind != SCR_DYN_FUNC) {
|
|
6544
|
+
scr_dyn_release(receiver);
|
|
6545
|
+
static const char message[] = "Function.prototype.apply was called on a non-callable value";
|
|
6546
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
6547
|
+
return NULL;
|
|
6548
|
+
}
|
|
6549
|
+
ScrDyn *result = scr_dyn_apply_array_like(receiver, argc ? args[0] : scr_dyn_undefined(),
|
|
6550
|
+
argc > 1 ? args[1] : scr_dyn_undefined(), "Function.prototype.apply");
|
|
6551
|
+
scr_dyn_release(receiver);
|
|
6552
|
+
return result;
|
|
6553
|
+
}
|
|
6554
|
+
|
|
6555
|
+
ScrDyn *scr_dyn_function_apply(void) {
|
|
6556
|
+
if (!scr_function_apply_value) {
|
|
6557
|
+
scr_function_apply_value = scr_dyn_new_func(scr_closure_new(NULL, 0), scr_function_apply_call,
|
|
6558
|
+
2, "native:Function.prototype.apply", "apply");
|
|
6559
|
+
scr_atexit(scr_function_apply_cleanup);
|
|
6560
|
+
}
|
|
6561
|
+
return scr_dyn_retain(scr_function_apply_value);
|
|
6562
|
+
}
|
|
6563
|
+
|
|
5796
6564
|
ScrDyn *scr_dyn_obj_read(const ScrDyn *d, const char *key, size_t key_len) {
|
|
6565
|
+
if (d->kind == SCR_DYN_PROXY) {
|
|
6566
|
+
ScrStr *name = scr_str_new(key, key_len);
|
|
6567
|
+
ScrDyn *value = scr_dyn_proxy_get(d, name);
|
|
6568
|
+
scr_str_release(name);
|
|
6569
|
+
return value;
|
|
6570
|
+
}
|
|
5797
6571
|
return scr_dyn_obj_read_receiver(d, key, key_len, d);
|
|
5798
6572
|
}
|
|
5799
6573
|
|
|
@@ -5864,6 +6638,13 @@ ScrDyn *scr_dyn_obj_own_keys(const ScrDyn *v) {
|
|
|
5864
6638
|
}
|
|
5865
6639
|
|
|
5866
6640
|
ScrDyn *scr_dyn_get_own_property_names(const ScrDyn *value) {
|
|
6641
|
+
if (value->kind == SCR_DYN_TYPED_REF) {
|
|
6642
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(value);
|
|
6643
|
+
if (scr_exc_pending()) { scr_dyn_release(view); return NULL; }
|
|
6644
|
+
ScrDyn *result = scr_dyn_get_own_property_names(view);
|
|
6645
|
+
scr_dyn_release(view);
|
|
6646
|
+
return result;
|
|
6647
|
+
}
|
|
5867
6648
|
if (value->kind == SCR_DYN_FUNC) {
|
|
5868
6649
|
if (scr_dyn_class_reflection_fence(value)) return NULL;
|
|
5869
6650
|
ScrDyn *table = scr_dyn_fn_properties(value);
|
|
@@ -5905,6 +6686,13 @@ ScrDyn *scr_dyn_get_own_property_names(const ScrDyn *value) {
|
|
|
5905
6686
|
}
|
|
5906
6687
|
|
|
5907
6688
|
ScrDyn *scr_dyn_get_own_property_symbols(const ScrDyn *value) {
|
|
6689
|
+
if (value->kind == SCR_DYN_TYPED_REF) {
|
|
6690
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(value);
|
|
6691
|
+
if (scr_exc_pending()) { scr_dyn_release(view); return NULL; }
|
|
6692
|
+
ScrDyn *result = scr_dyn_get_own_property_symbols(view);
|
|
6693
|
+
scr_dyn_release(view);
|
|
6694
|
+
return result;
|
|
6695
|
+
}
|
|
5908
6696
|
if (value->kind == SCR_DYN_NULL || value->kind == SCR_DYN_UNDEF) {
|
|
5909
6697
|
static const char message[] = "Cannot convert undefined or null to object";
|
|
5910
6698
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
@@ -5920,13 +6708,20 @@ ScrDyn *scr_dyn_get_own_property_symbols(const ScrDyn *value) {
|
|
|
5920
6708
|
}
|
|
5921
6709
|
|
|
5922
6710
|
ScrDyn *scr_dyn_get_own_property_descriptors(ScrDyn *object) {
|
|
6711
|
+
if (object->kind == SCR_DYN_TYPED_REF) {
|
|
6712
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(object);
|
|
6713
|
+
if (scr_exc_pending()) { scr_dyn_release(view); return NULL; }
|
|
6714
|
+
ScrDyn *result = scr_dyn_get_own_property_descriptors(view);
|
|
6715
|
+
scr_dyn_release(view);
|
|
6716
|
+
return result;
|
|
6717
|
+
}
|
|
5923
6718
|
if (scr_dyn_class_reflection_fence(object)) return NULL;
|
|
5924
6719
|
if (object->kind == SCR_DYN_UNDEF || object->kind == SCR_DYN_NULL) {
|
|
5925
6720
|
static const char message[] = "Cannot convert undefined or null to object";
|
|
5926
6721
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
5927
6722
|
return NULL;
|
|
5928
6723
|
}
|
|
5929
|
-
if (object->kind == SCR_DYN_PROXY ||
|
|
6724
|
+
if (object->kind == SCR_DYN_PROXY ||
|
|
5930
6725
|
object->kind == SCR_DYN_JSVAL || object->kind == SCR_DYN_HANDLE) {
|
|
5931
6726
|
static const char message[] = "Object.getOwnPropertyDescriptors on this value is not supported yet";
|
|
5932
6727
|
scr_throw_error_msg(SCR_ERR_ERROR, message, sizeof message - 1);
|
|
@@ -5957,6 +6752,21 @@ ScrDyn *scr_dyn_get_own_property_descriptors(ScrDyn *object) {
|
|
|
5957
6752
|
return result;
|
|
5958
6753
|
}
|
|
5959
6754
|
|
|
6755
|
+
ScrDyn *scr_dyn_own_keys(const ScrDyn *value) {
|
|
6756
|
+
if (!scr_dyn_to_primitive_result_is_object(value)) {
|
|
6757
|
+
static const char message[] = "Reflect.ownKeys called on non-object";
|
|
6758
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
6759
|
+
return NULL;
|
|
6760
|
+
}
|
|
6761
|
+
ScrDyn *names = scr_dyn_get_own_property_names(value);
|
|
6762
|
+
if (!names) return NULL;
|
|
6763
|
+
ScrDyn *symbols = scr_dyn_get_own_property_symbols(value);
|
|
6764
|
+
if (!symbols) { scr_dyn_release(names); return NULL; }
|
|
6765
|
+
for (size_t i = 0; i < symbols->v.arr.len; i++) scr_dyn_arr_push(names, scr_dyn_retain(symbols->v.arr.items[i]));
|
|
6766
|
+
scr_dyn_release(symbols);
|
|
6767
|
+
return names;
|
|
6768
|
+
}
|
|
6769
|
+
|
|
5960
6770
|
static void scr_dyn_objwalk_push(ScrDyn *out, ScrObjWalk mode, const char *key,
|
|
5961
6771
|
size_t key_len, ScrDyn *value /* borrowed */) {
|
|
5962
6772
|
switch (mode) {
|
|
@@ -6386,6 +7196,33 @@ ScrDyn *scr_dyn_copy_data_properties(ScrDyn *target, const ScrDyn *src) {
|
|
|
6386
7196
|
return scr_exc_pending() ? NULL : scr_dyn_retain(target);
|
|
6387
7197
|
}
|
|
6388
7198
|
|
|
7199
|
+
ScrDyn *scr_dyn_object_rest(const ScrDyn *source, const ScrDyn *excluded) {
|
|
7200
|
+
ScrDyn *out = scr_dyn_new_obj();
|
|
7201
|
+
ScrDyn *names = scr_dyn_get_own_property_names(source);
|
|
7202
|
+
if (!names) { scr_dyn_release(out); return NULL; }
|
|
7203
|
+
ScrDyn *symbols = scr_dyn_get_own_property_symbols(source);
|
|
7204
|
+
if (!symbols) { scr_dyn_release(names); scr_dyn_release(out); return NULL; }
|
|
7205
|
+
for (size_t i = 0; i < symbols->v.arr.len; i++) scr_dyn_arr_push(names, scr_dyn_retain(symbols->v.arr.items[i]));
|
|
7206
|
+
scr_dyn_release(symbols);
|
|
7207
|
+
for (size_t i = 0; i < names->v.arr.len && !scr_exc_pending(); i++) {
|
|
7208
|
+
ScrDyn *key = names->v.arr.items[i];
|
|
7209
|
+
bool skip = false;
|
|
7210
|
+
for (size_t j = 0; j < excluded->v.arr.len; j++) {
|
|
7211
|
+
if (scr_dyn_strict_eq(key, excluded->v.arr.items[j])) { skip = true; break; }
|
|
7212
|
+
}
|
|
7213
|
+
if (skip || !scr_dyn_key_probe_computed(source, key, 2)) continue;
|
|
7214
|
+
ScrDyn *value = key->kind == SCR_DYN_SYMBOL ? scr_dyn_symbol_key_get(source, key, false) : scr_iterator_read(source, key->v.str->data, key->v.str->len);
|
|
7215
|
+
if (!scr_exc_pending()) {
|
|
7216
|
+
if (key->kind == SCR_DYN_SYMBOL) scr_dyn_symbol_key_set(out, key, value);
|
|
7217
|
+
else scr_dyn_obj_set(out, key->v.str->data, key->v.str->len, scr_dyn_retain(value));
|
|
7218
|
+
}
|
|
7219
|
+
scr_dyn_release(value);
|
|
7220
|
+
}
|
|
7221
|
+
scr_dyn_release(names);
|
|
7222
|
+
if (scr_exc_pending()) { scr_dyn_release(out); return NULL; }
|
|
7223
|
+
return out;
|
|
7224
|
+
}
|
|
7225
|
+
|
|
6389
7226
|
/* Compiler-owned native class views retain every property and its flags,
|
|
6390
7227
|
* including nonenumerable data, without invoking accessors. */
|
|
6391
7228
|
ScrDyn *scr_dyn_copy_property_descriptors(ScrDyn *target, const ScrDyn *src) {
|
|
@@ -6429,6 +7266,19 @@ void scr_dyn_pack_push_spread(ScrDyn *pack, const ScrDyn *src, const ScrStr *wha
|
|
|
6429
7266
|
* Symbol(Symbol.iterator))". The compiler picks the variant by the
|
|
6430
7267
|
* spread's syntactic position. MAY THROW (pending). Borrows src. */
|
|
6431
7268
|
void scr_dyn_pack_push_spread_iter(ScrDyn *pack, const ScrDyn *src) {
|
|
7269
|
+
if (src->kind == SCR_DYN_TYPED_REF) {
|
|
7270
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(src);
|
|
7271
|
+
if (!scr_exc_pending()) scr_dyn_pack_push_spread_iter(pack, view);
|
|
7272
|
+
scr_dyn_release(view);
|
|
7273
|
+
return;
|
|
7274
|
+
}
|
|
7275
|
+
if (src->kind == SCR_DYN_HANDLE && scr_dyn_handle_ops_of(src)->iter_pack) {
|
|
7276
|
+
ScrDyn *items = scr_dyn_handle_ops_of(src)->iter_pack(src->v.handle.ptr);
|
|
7277
|
+
if (!items) return;
|
|
7278
|
+
scr_dyn_pack_push_spread_iter(pack, items);
|
|
7279
|
+
scr_dyn_release(items);
|
|
7280
|
+
return;
|
|
7281
|
+
}
|
|
6432
7282
|
if (src->kind == SCR_DYN_ARR || src->kind == SCR_DYN_BYTES ||
|
|
6433
7283
|
src->kind == SCR_DYN_STR) {
|
|
6434
7284
|
scr_dyn_arr_push_spread(pack, src, ""); /* iterable kinds never throw */
|
|
@@ -6470,6 +7320,10 @@ void scr_dyn_pack_push_spread_iter(ScrDyn *pack, const ScrDyn *src) {
|
|
|
6470
7320
|
* ToObject TypeError first (Node throws before looking at sources), then
|
|
6471
7321
|
* each source's own-member copy left to right, answering the target
|
|
6472
7322
|
* retained (+1) — identity, like JS. */
|
|
7323
|
+
ScrDyn *scr_dyn_reflect_apply(ScrDyn *target, ScrDyn *receiver, ScrDyn *arguments_list) {
|
|
7324
|
+
return scr_dyn_apply_array_like(target, receiver, arguments_list, "Reflect.apply");
|
|
7325
|
+
}
|
|
7326
|
+
|
|
6473
7327
|
ScrDyn *scr_dyn_assign_all(ScrDyn *target, const ScrDyn *sources) {
|
|
6474
7328
|
if (target->kind == SCR_DYN_UNDEF || target->kind == SCR_DYN_NULL) {
|
|
6475
7329
|
const char *m = "Cannot convert undefined or null to object";
|
|
@@ -6598,6 +7452,12 @@ bool scr_dyn_has_own(const ScrDyn *v, const ScrStr *key) {
|
|
|
6598
7452
|
|
|
6599
7453
|
bool scr_dyn_property_is_enumerable(const ScrDyn *value, const ScrStr *key) {
|
|
6600
7454
|
if (scr_dyn_class_reflection_fence(value)) return false;
|
|
7455
|
+
if (value->kind == SCR_DYN_TYPED_REF) {
|
|
7456
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(value);
|
|
7457
|
+
bool result = !scr_exc_pending() && scr_dyn_property_is_enumerable(view, key);
|
|
7458
|
+
scr_dyn_release(view);
|
|
7459
|
+
return result;
|
|
7460
|
+
}
|
|
6601
7461
|
if (value->kind == SCR_DYN_UNDEF || value->kind == SCR_DYN_NULL) {
|
|
6602
7462
|
static const char message[] = "Cannot convert undefined or null to object";
|
|
6603
7463
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
@@ -6641,6 +7501,7 @@ void scr_error_init_options(void *obj, int kind, const ScrDyn *message, const Sc
|
|
|
6641
7501
|
return;
|
|
6642
7502
|
}
|
|
6643
7503
|
scr_error_init(obj, kind, text);
|
|
7504
|
+
((ScrError *)obj)->message_present = message && message->kind != SCR_DYN_UNDEF;
|
|
6644
7505
|
scr_str_release(text);
|
|
6645
7506
|
ScrDyn *view = options && options->kind == SCR_DYN_TYPED_REF
|
|
6646
7507
|
? scr_dyn_typed_ref_materialize(options) : NULL;
|
|
@@ -6673,7 +7534,15 @@ ScrError *scr_error_new_options(int kind, const ScrDyn *message, const ScrDyn *o
|
|
|
6673
7534
|
|
|
6674
7535
|
ScrDyn *scr_error_cause(ScrError *e) {
|
|
6675
7536
|
for (size_t i = 0; i < scr_errdyn_n; i++) {
|
|
6676
|
-
if (scr_errdyn_cache[i].err
|
|
7537
|
+
if (scr_errdyn_cache[i].err != e) continue;
|
|
7538
|
+
ScrDyn *value = scr_errdyn_cache[i].dyn;
|
|
7539
|
+
if (value->kind == SCR_DYN_TYPED_REF) {
|
|
7540
|
+
ScrDyn *view = scr_dyn_typed_ref_materialize(value);
|
|
7541
|
+
ScrDyn *cause = scr_dyn_obj_read(view, "cause", 5);
|
|
7542
|
+
scr_dyn_release(view);
|
|
7543
|
+
return cause;
|
|
7544
|
+
}
|
|
7545
|
+
return scr_dyn_obj_read(value, "cause", 5);
|
|
6677
7546
|
}
|
|
6678
7547
|
return e->error_cause ? scr_dyn_retain(e->error_cause) : scr_dyn_undefined();
|
|
6679
7548
|
}
|
|
@@ -6693,6 +7562,12 @@ void scr_error_set_cause(ScrError *e, ScrDyn *value) {
|
|
|
6693
7562
|
e->error_cause = replacement;
|
|
6694
7563
|
}
|
|
6695
7564
|
|
|
7565
|
+
void scr_error_define_cause(ScrError *e, ScrDyn *value) {
|
|
7566
|
+
scr_error_delete_cause(e);
|
|
7567
|
+
scr_error_set_cause(e, value);
|
|
7568
|
+
}
|
|
7569
|
+
|
|
7570
|
+
|
|
6696
7571
|
void scr_error_delete_cause(ScrError *e) {
|
|
6697
7572
|
for (size_t i = 0; i < scr_errdyn_n; i++) {
|
|
6698
7573
|
if (scr_errdyn_cache[i].err != e) continue;
|
|
@@ -7337,7 +8212,7 @@ typedef struct ScrWeakEntry {
|
|
|
7337
8212
|
} ScrWeakEntry;
|
|
7338
8213
|
|
|
7339
8214
|
struct ScrWeakMap { size_t rc; ScrWeakEntry *entries; bool is_set; };
|
|
7340
|
-
/* Weak observers borrow key identities. Values
|
|
8215
|
+
/* Weak observers borrow key identities. Values are traced strong edges;
|
|
7341
8216
|
* value-to-key cycles require explicit deletion or container disposal. */
|
|
7342
8217
|
#define SCR_WEAK_BUCKETS 1024
|
|
7343
8218
|
static SCR_TL ScrWeakEntry *scr_weak_entries[SCR_WEAK_BUCKETS];
|
|
@@ -7346,7 +8221,7 @@ static size_t scr_weak_bucket(void *key) {
|
|
|
7346
8221
|
return ((bits >> 4) ^ (bits >> 14)) & (SCR_WEAK_BUCKETS - 1);
|
|
7347
8222
|
}
|
|
7348
8223
|
|
|
7349
|
-
static void
|
|
8224
|
+
static void scr_weak_remove_impl(ScrWeakEntry *entry, bool collected) {
|
|
7350
8225
|
ScrWeakEntry **slot = &entry->owner->entries;
|
|
7351
8226
|
while (*slot != entry) slot = &(*slot)->next;
|
|
7352
8227
|
*slot = entry->next;
|
|
@@ -7356,7 +8231,22 @@ static void scr_weak_remove(ScrWeakEntry *entry) {
|
|
|
7356
8231
|
ScrDyn *value = entry->value;
|
|
7357
8232
|
free(entry);
|
|
7358
8233
|
/* Unlink before release: releasing a value can dispose another key. */
|
|
7359
|
-
scr_dyn_release(value);
|
|
8234
|
+
if (!collected) scr_dyn_release(value);
|
|
8235
|
+
}
|
|
8236
|
+
|
|
8237
|
+
static void scr_weak_remove(ScrWeakEntry *entry) {
|
|
8238
|
+
scr_weak_remove_impl(entry, scr_cyc_hdr(entry->owner)->color == SCR_CYC_DOOMED);
|
|
8239
|
+
}
|
|
8240
|
+
|
|
8241
|
+
static void scr_weak_map_trace(void *ptr, ScrTraceVisit visit, void *ctx) {
|
|
8242
|
+
for (ScrWeakEntry *entry = ((ScrWeakMap *)ptr)->entries; entry; entry = entry->next)
|
|
8243
|
+
visit(entry->value, ctx);
|
|
8244
|
+
}
|
|
8245
|
+
|
|
8246
|
+
static void scr_weak_map_gcfree(void *ptr) {
|
|
8247
|
+
ScrWeakMap *map = ptr;
|
|
8248
|
+
while (map->entries) scr_weak_remove_impl(map->entries, true);
|
|
8249
|
+
scr_cyc_free(map);
|
|
7360
8250
|
}
|
|
7361
8251
|
|
|
7362
8252
|
static void scr_weak_disposed(void *key) {
|
|
@@ -7375,10 +8265,11 @@ static void *scr_weak_map_retain(void *ptr) {
|
|
|
7375
8265
|
|
|
7376
8266
|
static void scr_weak_map_release(void *ptr) {
|
|
7377
8267
|
ScrWeakMap *map = ptr;
|
|
7378
|
-
if (--map->rc) return;
|
|
8268
|
+
if (--map->rc) { scr_cyc_on_release(map); return; }
|
|
8269
|
+
scr_cyc_on_dead(map);
|
|
7379
8270
|
scr_weak_dispose(map);
|
|
7380
8271
|
while (map->entries) scr_weak_remove(map->entries);
|
|
7381
|
-
|
|
8272
|
+
scr_cyc_free(map);
|
|
7382
8273
|
}
|
|
7383
8274
|
|
|
7384
8275
|
/* Return 1 for an observed identity, 0 for a primitive, and -1 for a
|
|
@@ -7399,9 +8290,16 @@ static int scr_weak_key(const ScrDyn *key, void **ptr, unsigned *kind) {
|
|
|
7399
8290
|
*kind = key->v.fn.class_obj ? 3 : 2; return 1;
|
|
7400
8291
|
case SCR_DYN_HANDLE:
|
|
7401
8292
|
if (key->v.handle.tag != SCR_DYNH_ARRAY_BUFFER && key->v.handle.tag != SCR_DYNH_WEAK_MAP &&
|
|
7402
|
-
key->v.handle.tag != SCR_DYNH_WEAK_SET && key->v.handle.tag != SCR_DYNH_STDIO
|
|
8293
|
+
key->v.handle.tag != SCR_DYNH_WEAK_SET && key->v.handle.tag != SCR_DYNH_STDIO &&
|
|
8294
|
+
key->v.handle.tag != SCR_DYNH_FETCH_REQUEST && key->v.handle.tag != SCR_DYNH_FETCH_RESPONSE &&
|
|
8295
|
+
key->v.handle.tag != SCR_DYNH_MAP && key->v.handle.tag != SCR_DYNH_SET) return -1;
|
|
7403
8296
|
*ptr = key->v.handle.ptr; *kind = 4 + key->v.handle.tag; return 1;
|
|
7404
|
-
case SCR_DYN_TYPED_REF:
|
|
8297
|
+
case SCR_DYN_TYPED_REF:
|
|
8298
|
+
if (!key->v.typed_ref.observed) return -1;
|
|
8299
|
+
*ptr = key->v.typed_ref.ptr; *kind = 32; return 1;
|
|
8300
|
+
case SCR_DYN_PROMISE:
|
|
8301
|
+
*ptr = key->v.promise; *kind = 33; return 1;
|
|
8302
|
+
case SCR_DYN_JSVAL:
|
|
7405
8303
|
return -1;
|
|
7406
8304
|
default: return 0;
|
|
7407
8305
|
}
|
|
@@ -7533,7 +8431,7 @@ static ScrDyn *scr_weak_collection_new(ScrDyn *seed, bool is_set) {
|
|
|
7533
8431
|
ScrDynHandleTag tag = is_set ? SCR_DYNH_WEAK_SET : SCR_DYNH_WEAK_MAP;
|
|
7534
8432
|
scr_weak_dispose_hook = &scr_weak_disposed;
|
|
7535
8433
|
scr_dyn_handle_install(tag, is_set ? &set_ops : &map_ops);
|
|
7536
|
-
ScrWeakMap *map =
|
|
8434
|
+
ScrWeakMap *map = scr_cyc_alloc(sizeof *map, scr_weak_map_trace, scr_weak_map_gcfree);
|
|
7537
8435
|
if (!map) scr_json_oom();
|
|
7538
8436
|
map->rc = 1;
|
|
7539
8437
|
map->is_set = is_set;
|
|
@@ -7720,12 +8618,15 @@ static ScrDyn *scr_native_set_invoke(void *ptr, ScrDyn *self, const char *method
|
|
|
7720
8618
|
ScrMap *set = ptr;
|
|
7721
8619
|
ScrDyn *value = argc ? args[0] : scr_dyn_undefined();
|
|
7722
8620
|
if (strcmp(method, "add") == 0) {
|
|
7723
|
-
|
|
8621
|
+
scr_map_dyn_set(set, value, NULL, true);
|
|
8622
|
+
if (scr_exc_pending()) return NULL;
|
|
7724
8623
|
return scr_dyn_retain(self);
|
|
7725
8624
|
}
|
|
7726
|
-
if (strcmp(method, "has") == 0) return scr_dyn_new_bool(
|
|
7727
|
-
if (strcmp(method, "delete") == 0) return scr_dyn_new_bool(
|
|
8625
|
+
if (strcmp(method, "has") == 0) return scr_dyn_new_bool(scr_map_dyn_has(set, value, false));
|
|
8626
|
+
if (strcmp(method, "delete") == 0) return scr_dyn_new_bool(scr_map_dyn_has(set, value, true));
|
|
7728
8627
|
if (strcmp(method, "clear") == 0) { scr_map_clear(set); return scr_dyn_retain(scr_dyn_undefined()); }
|
|
8628
|
+
if (strcmp(method, "values") == 0 || strcmp(method, "keys") == 0) return scr_native_collection_iterator(self, 0);
|
|
8629
|
+
if (strcmp(method, "entries") == 0) return scr_native_collection_iterator(self, 2);
|
|
7729
8630
|
if (strcmp(method, "forEach") == 0) {
|
|
7730
8631
|
if (value->kind != SCR_DYN_FUNC &&
|
|
7731
8632
|
!(value->kind == SCR_DYN_JSVAL && scr_dyn_isl_typeof_is(value, "function"))) {
|
|
@@ -7748,7 +8649,7 @@ static ScrDyn *scr_native_set_invoke(void *ptr, ScrDyn *self, const char *method
|
|
|
7748
8649
|
scr_map_iter_enter(set);
|
|
7749
8650
|
for (double i = 0; i < scr_map_iter_count(set); i++) {
|
|
7750
8651
|
if (!scr_map_iter_live(set, i)) continue;
|
|
7751
|
-
ScrDyn *entry =
|
|
8652
|
+
ScrDyn *entry = scr_map_dyn_key(set, i);
|
|
7752
8653
|
ScrDyn *callback_args[] = {entry, entry, self};
|
|
7753
8654
|
scr_dyn_this_push_dyn(this_arg);
|
|
7754
8655
|
ScrDyn *result = scr_dyn_call(value, callback_args, 3, "callback");
|
|
@@ -7766,10 +8667,21 @@ static ScrDyn *scr_native_set_invoke(void *ptr, ScrDyn *self, const char *method
|
|
|
7766
8667
|
return NULL;
|
|
7767
8668
|
}
|
|
7768
8669
|
|
|
8670
|
+
static ScrDyn *scr_native_set_pack(void *ptr) {
|
|
8671
|
+
ScrMap *set = ptr;
|
|
8672
|
+
ScrDyn *values = scr_dyn_new_arr();
|
|
8673
|
+
scr_map_iter_enter(set);
|
|
8674
|
+
for (double i = 0; i < scr_map_iter_count(set); i++) {
|
|
8675
|
+
if (scr_map_iter_live(set, i)) scr_dyn_arr_push(values, scr_map_dyn_key(set, i));
|
|
8676
|
+
}
|
|
8677
|
+
scr_map_iter_exit(set);
|
|
8678
|
+
return values;
|
|
8679
|
+
}
|
|
8680
|
+
|
|
7769
8681
|
ScrDyn *scr_dyn_native_set(ScrMap *value) {
|
|
7770
8682
|
static const ScrDynHandleOps ops = {
|
|
7771
8683
|
"Set", &scr_map_retain_v, &scr_map_release_v, &scr_native_set_invoke,
|
|
7772
|
-
&scr_native_set_get, &scr_weak_map_write, NULL,
|
|
8684
|
+
&scr_native_set_get, &scr_weak_map_write, NULL, &scr_native_set_pack,
|
|
7773
8685
|
};
|
|
7774
8686
|
scr_dyn_handle_install(SCR_DYNH_SET, &ops);
|
|
7775
8687
|
return scr_dyn_new_handle(value, SCR_DYNH_SET);
|
|
@@ -7818,16 +8730,44 @@ static ScrDyn *scr_native_map_invoke(void *ptr, ScrDyn *self, const char *method
|
|
|
7818
8730
|
ScrMap *map = ptr;
|
|
7819
8731
|
ScrDyn *key = argc ? args[0] : scr_dyn_undefined();
|
|
7820
8732
|
if (strcmp(method, "set") == 0) {
|
|
7821
|
-
|
|
8733
|
+
scr_map_dyn_set(map, key, argc > 1 ? args[1] : scr_dyn_undefined(), false);
|
|
8734
|
+
if (scr_exc_pending()) return NULL;
|
|
7822
8735
|
return scr_dyn_retain(self);
|
|
7823
8736
|
}
|
|
7824
8737
|
if (strcmp(method, "get") == 0) {
|
|
7825
|
-
|
|
7826
|
-
return value ? value : scr_dyn_retain(scr_dyn_undefined());
|
|
8738
|
+
return scr_map_dyn_get(map, key);
|
|
7827
8739
|
}
|
|
7828
|
-
if (strcmp(method, "has") == 0) return scr_dyn_new_bool(
|
|
7829
|
-
if (strcmp(method, "delete") == 0) return scr_dyn_new_bool(
|
|
8740
|
+
if (strcmp(method, "has") == 0) return scr_dyn_new_bool(scr_map_dyn_has(map, key, false));
|
|
8741
|
+
if (strcmp(method, "delete") == 0) return scr_dyn_new_bool(scr_map_dyn_has(map, key, true));
|
|
7830
8742
|
if (strcmp(method, "clear") == 0) { scr_map_clear(map); return scr_dyn_retain(scr_dyn_undefined()); }
|
|
8743
|
+
if (strcmp(method, "values") == 0) return scr_native_collection_iterator(self, 0);
|
|
8744
|
+
if (strcmp(method, "keys") == 0) return scr_native_collection_iterator(self, 1);
|
|
8745
|
+
if (strcmp(method, "entries") == 0) return scr_native_collection_iterator(self, 2);
|
|
8746
|
+
if (strcmp(method, "forEach") == 0) {
|
|
8747
|
+
if (key->kind != SCR_DYN_FUNC && !(key->kind == SCR_DYN_JSVAL && scr_dyn_isl_typeof_is(key, "function"))) {
|
|
8748
|
+
/* Validate even when there are no entries to visit. */
|
|
8749
|
+
ScrDyn *result = scr_dyn_call(key, NULL, 0, "callback");
|
|
8750
|
+
scr_dyn_release(result);
|
|
8751
|
+
return NULL;
|
|
8752
|
+
}
|
|
8753
|
+
ScrDyn *this_arg = argc > 1 ? args[1] : scr_dyn_undefined();
|
|
8754
|
+
scr_map_iter_enter(map);
|
|
8755
|
+
for (double i = 0; i < scr_map_iter_count(map); i++) {
|
|
8756
|
+
if (!scr_map_iter_live(map, i)) continue;
|
|
8757
|
+
ScrDyn *entry_key = scr_map_dyn_key(map, i);
|
|
8758
|
+
ScrDyn *value = scr_map_dyn_value(map, i);
|
|
8759
|
+
ScrDyn *callback_args[] = {value, entry_key, self};
|
|
8760
|
+
scr_dyn_this_push_dyn(this_arg);
|
|
8761
|
+
ScrDyn *result = scr_dyn_call(key, callback_args, 3, "callback");
|
|
8762
|
+
scr_dyn_this_pop();
|
|
8763
|
+
scr_dyn_release(entry_key);
|
|
8764
|
+
scr_dyn_release(value);
|
|
8765
|
+
scr_dyn_release(result);
|
|
8766
|
+
if (scr_exc_pending()) break;
|
|
8767
|
+
}
|
|
8768
|
+
scr_map_iter_exit(map);
|
|
8769
|
+
return scr_exc_pending() ? NULL : scr_dyn_retain(scr_dyn_undefined());
|
|
8770
|
+
}
|
|
7831
8771
|
(void)what;
|
|
7832
8772
|
static const char message[] = "Native Map method has no lowering";
|
|
7833
8773
|
scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
|
|
@@ -7841,8 +8781,8 @@ static ScrDyn *scr_native_map_pack(void *ptr) {
|
|
|
7841
8781
|
for (double i = 0; i < scr_map_iter_count(map); i++) {
|
|
7842
8782
|
if (!scr_map_iter_live(map, i)) continue;
|
|
7843
8783
|
ScrDyn *pair = scr_dyn_new_arr();
|
|
7844
|
-
scr_dyn_arr_push(pair,
|
|
7845
|
-
scr_dyn_arr_push(pair,
|
|
8784
|
+
scr_dyn_arr_push(pair, scr_map_dyn_key(map, i));
|
|
8785
|
+
scr_dyn_arr_push(pair, scr_map_dyn_value(map, i));
|
|
7846
8786
|
scr_dyn_arr_push(entries, pair);
|
|
7847
8787
|
}
|
|
7848
8788
|
scr_map_iter_exit(map);
|
|
@@ -7852,7 +8792,7 @@ static ScrDyn *scr_native_map_pack(void *ptr) {
|
|
|
7852
8792
|
ScrDyn *scr_dyn_native_map(ScrMap *value) {
|
|
7853
8793
|
static const ScrDynHandleOps ops = {
|
|
7854
8794
|
"Map", &scr_map_retain_v, &scr_map_release_v, &scr_native_map_invoke,
|
|
7855
|
-
&scr_native_map_get, &scr_weak_map_write, NULL,
|
|
8795
|
+
&scr_native_map_get, &scr_weak_map_write, NULL, &scr_native_map_pack,
|
|
7856
8796
|
};
|
|
7857
8797
|
scr_dyn_handle_install(SCR_DYNH_MAP, &ops);
|
|
7858
8798
|
return scr_dyn_new_handle(value, SCR_DYNH_MAP);
|
|
@@ -7867,7 +8807,40 @@ ScrMap *scr_dyn_native_map_check(const ScrDyn *value, const ScrDynPath *path) {
|
|
|
7867
8807
|
return scr_map_retain(value->v.handle.ptr);
|
|
7868
8808
|
}
|
|
7869
8809
|
|
|
8810
|
+
bool scr_dyn_native_collection_is(const ScrDyn *value, int map, const char *type) {
|
|
8811
|
+
if (!(map ? scr_dyn_native_map_is(value) : scr_dyn_native_set_is(value))) return false;
|
|
8812
|
+
const ScrMap *storage = value->v.handle.ptr;
|
|
8813
|
+
return type ? storage->dyn_ops && strcmp(storage->dyn_ops->type, type) == 0 : !storage->dyn_ops;
|
|
8814
|
+
}
|
|
8815
|
+
|
|
8816
|
+
ScrMap *scr_dyn_native_collection_check(const ScrDyn *value, int map, const char *type, const ScrDynPath *path) {
|
|
8817
|
+
if (!scr_dyn_native_collection_is(value, map, type)) {
|
|
8818
|
+
scr_dyn_check_fail(path, type ? type : map ? "Map" : "Set", value);
|
|
8819
|
+
return NULL;
|
|
8820
|
+
}
|
|
8821
|
+
return scr_map_retain(value->v.handle.ptr);
|
|
8822
|
+
}
|
|
8823
|
+
|
|
7870
8824
|
ScrStr *scr_dyn_to_string_method(const ScrDyn *d, const ScrStr *enc, const ScrStr *what) {
|
|
8825
|
+
/* Object.create receivers must run their inherited formatter before the
|
|
8826
|
+
* default object tag; Effect shard keys use it to produce distinct hashes. */
|
|
8827
|
+
const bool object_method = d->kind == SCR_DYN_OBJ && scr_dyn_property_owner(d, "toString", 8);
|
|
8828
|
+
if (d->kind == SCR_DYN_FUNC || object_method) {
|
|
8829
|
+
ScrDyn *member = object_method ? scr_dyn_obj_read(d, "toString", 8) : scr_dyn_fn_get(d, "toString", 8);
|
|
8830
|
+
if (scr_exc_pending()) { scr_dyn_release(member); return NULL; }
|
|
8831
|
+
if (member && (object_method || member->kind != SCR_DYN_UNDEF)) {
|
|
8832
|
+
scr_dyn_this_push_dyn(d);
|
|
8833
|
+
ScrDyn *value = scr_dyn_call(member, NULL, 0, what->data);
|
|
8834
|
+
scr_dyn_this_pop();
|
|
8835
|
+
scr_dyn_release(member);
|
|
8836
|
+
if (!value) return NULL;
|
|
8837
|
+
ScrStr *result = value->kind == SCR_DYN_STR ? scr_str_retain(value->v.str) : NULL;
|
|
8838
|
+
if (!result) scr_dyn_check_fail(NULL, "string", value);
|
|
8839
|
+
scr_dyn_release(value);
|
|
8840
|
+
return result;
|
|
8841
|
+
}
|
|
8842
|
+
scr_dyn_release(member);
|
|
8843
|
+
}
|
|
7871
8844
|
if (d->kind == SCR_DYN_OBJ && !scr_dyn_property_owner(d, "toString", 8) && !scr_dyn_has_object_prototype(d)) {
|
|
7872
8845
|
ScrJsonBuf b;
|
|
7873
8846
|
scr_jb_init(&b);
|
|
@@ -7926,3 +8899,88 @@ bool scr_dyn_is_frozen(const ScrDyn *value) {
|
|
|
7926
8899
|
scr_throw_error_msg_code(SCR_ERR_ERROR, message, sizeof message - 1, "SC2020");
|
|
7927
8900
|
return false;
|
|
7928
8901
|
}
|
|
8902
|
+
|
|
8903
|
+
double scr_buffer_byte_length_dyn(ScrDyn *value, ScrStr *encoding) {
|
|
8904
|
+
if (value->kind == SCR_DYN_STR) return scr_bytes_byte_length_str(value->v.str, encoding);
|
|
8905
|
+
if (value->kind == SCR_DYN_BYTES) return scr_bytes_byte_len(value->v.bytes);
|
|
8906
|
+
if (scr_array_buffer_is(value)) return scr_bytes_byte_len(value->v.handle.ptr);
|
|
8907
|
+
static const char message[] = "The string argument must be of type string or an instance of Buffer or ArrayBuffer";
|
|
8908
|
+
scr_throw_error_msg_code(SCR_ERR_TYPE, message, sizeof message - 1, "ERR_INVALID_ARG_TYPE");
|
|
8909
|
+
return 0;
|
|
8910
|
+
}
|
|
8911
|
+
|
|
8912
|
+
/* Radix digit generation follows V8's DoubleToRadixStringView algorithm.
|
|
8913
|
+
* Copyright 2012 the V8 project authors. BSD license in
|
|
8914
|
+
* ../vendor/v8-number-radix/LICENSE. The decimal path retains Ryū. */
|
|
8915
|
+
ScrStr *scr_num_to_string_radix(double value, const ScrDyn *argument) {
|
|
8916
|
+
double requested = 10;
|
|
8917
|
+
if (argument && argument->kind != SCR_DYN_UNDEF &&
|
|
8918
|
+
!scr_dyn_number_coerce_js(argument, &requested)) return NULL;
|
|
8919
|
+
requested = isnan(requested) ? 0 : trunc(requested);
|
|
8920
|
+
if (requested < 2 || requested > 36 || !isfinite(requested)) {
|
|
8921
|
+
static const char message[] = "toString() radix argument must be between 2 and 36";
|
|
8922
|
+
scr_throw_error_msg(SCR_ERR_RANGE, message, sizeof message - 1);
|
|
8923
|
+
return NULL;
|
|
8924
|
+
}
|
|
8925
|
+
int radix = (int)requested;
|
|
8926
|
+
if (radix == 10 || !isfinite(value) || value == 0) return scr_f64_to_scrstr(value);
|
|
8927
|
+
static const char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
8928
|
+
char buffer[2200];
|
|
8929
|
+
const size_t middle = sizeof buffer / 2;
|
|
8930
|
+
size_t begin = middle, end = middle;
|
|
8931
|
+
bool negative = value < 0;
|
|
8932
|
+
value = fabs(value);
|
|
8933
|
+
double integer = floor(value), fraction = value - integer;
|
|
8934
|
+
double tolerance = 0.5 * (nextafter(value, INFINITY) - value);
|
|
8935
|
+
if (tolerance <= 0) tolerance = nextafter(0, INFINITY);
|
|
8936
|
+
if (fraction >= tolerance) {
|
|
8937
|
+
buffer[end++] = '.';
|
|
8938
|
+
do {
|
|
8939
|
+
fraction *= radix;
|
|
8940
|
+
tolerance *= radix;
|
|
8941
|
+
int digit = (int)fraction;
|
|
8942
|
+
buffer[end++] = digits[digit];
|
|
8943
|
+
fraction -= digit;
|
|
8944
|
+
if ((fraction > 0.5 || (fraction == 0.5 && (digit & 1))) && fraction + tolerance > 1) {
|
|
8945
|
+
for (;;) {
|
|
8946
|
+
end--;
|
|
8947
|
+
if (end == middle) { integer += 1; break; }
|
|
8948
|
+
char last = buffer[end];
|
|
8949
|
+
digit = last > '9' ? last - 'a' + 10 : last - '0';
|
|
8950
|
+
if (digit + 1 < radix) { buffer[end++] = digits[digit + 1]; break; }
|
|
8951
|
+
}
|
|
8952
|
+
break;
|
|
8953
|
+
}
|
|
8954
|
+
} while (fraction >= tolerance);
|
|
8955
|
+
}
|
|
8956
|
+
/* V8's Double::Exponent is the unbiased exponent minus 52. Beyond
|
|
8957
|
+
* that precision boundary, trailing digits are unrepresented zeros. */
|
|
8958
|
+
while (integer / radix >= 0x1p53) {
|
|
8959
|
+
integer /= radix;
|
|
8960
|
+
buffer[--begin] = '0';
|
|
8961
|
+
}
|
|
8962
|
+
do {
|
|
8963
|
+
double remainder = fmod(integer, radix);
|
|
8964
|
+
buffer[--begin] = digits[(int)remainder];
|
|
8965
|
+
integer = (integer - remainder) / radix;
|
|
8966
|
+
} while (integer > 0);
|
|
8967
|
+
if (negative) buffer[--begin] = '-';
|
|
8968
|
+
return scr_str_new(buffer + begin, end - begin);
|
|
8969
|
+
}
|
|
8970
|
+
|
|
8971
|
+
ScrDyn *scr_caught_to_dyn(const ScrCaught *c) {
|
|
8972
|
+
switch (c->kind) {
|
|
8973
|
+
case SCR_EXC_F64: return scr_dyn_new_num(c->f64);
|
|
8974
|
+
case SCR_EXC_BOOL: return scr_dyn_new_bool(c->b);
|
|
8975
|
+
case SCR_EXC_STR: return scr_dyn_new_str((ScrStr *)c->payload);
|
|
8976
|
+
case SCR_EXC_REF:
|
|
8977
|
+
case SCR_EXC_PRIMITIVE_REF:
|
|
8978
|
+
if (c->retain_fn == scr_dyn_retain_v) return scr_dyn_retain((ScrDyn *)c->payload);
|
|
8979
|
+
return scr_dyn_new_obj();
|
|
8980
|
+
case SCR_EXC_OBJ:
|
|
8981
|
+
if (scr_error_is(c->payload)) return scr_dyn_from_error((const ScrError *)c->payload);
|
|
8982
|
+
return scr_dyn_new_obj();
|
|
8983
|
+
default:
|
|
8984
|
+
return scr_dyn_new_obj();
|
|
8985
|
+
}
|
|
8986
|
+
}
|