@scriptc/cli-darwin-x64 0.2.4 → 0.2.6
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 +972 -245
- package/dist/lib/declarations/scriptc-overrides.d.ts +5 -1
- package/dist/lib/declarations/scriptc.d.ts +22 -2
- package/dist/lib/llvm/bin/scriptc-llvm-codegen +0 -0
- package/dist/lib/llvm/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_dgram.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_fetch.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_readline.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_tls.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_bigint_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_crypto_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_dc.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_dgram.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_dyn_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_fetch.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_ffi.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_ffi_queue.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_http.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_http2.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_inspect.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_loop_epoll.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_loop_kqueue.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_loop_wsapoll.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_net.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_path.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_qs.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_readline.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_test.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_tls.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_tls_ca.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_util.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_watch.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/default-workers/scr_zlib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_dgram.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_readline.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_tls.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/text-decoder-legacy-workers/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/workers/scr_mailbox.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/workers/scr_message.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/workers/scr_worker.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/dev/runtime/workers/scr_worker_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/default/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/default/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_inspect.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/default/scr_zlib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-dev/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_inspect.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/default/scr_zlib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/library-thread-release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_dgram.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_fetch.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_readline.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_tls.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_async_dyn.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_bigint.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_bigint_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_console_native.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_crypto_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_dc.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_dgram.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_dyn_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_dyn_invoke.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_fetch.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_ffi.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_ffi_queue.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_grapheme.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_http.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_http2.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_inspect.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_loop_epoll.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_loop_kqueue.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_loop_wsapoll.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_net.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_node_builtin.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_path.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_qs.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_readline.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_symbol.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_test.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_tls.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_tls_ca.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_url.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_url_params.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_util.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_util_style.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_watch.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/default-workers/scr_zlib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_array.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_assert.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_async.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_bytes_io.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_child.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_closure.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_console.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_context.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_copying.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_cycle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_dgram.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_error.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_events_emitter.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_exception.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_file_handle.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_island.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_json.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_lib.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_map.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_number.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_object.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_readline.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_regex.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_shared.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_stream.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_string.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_tls.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_union.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic/scr_util_compare.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/dynamic-text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/text-decoder-legacy/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/text-decoder-legacy-workers/scr_bytes.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/workers/scr_mailbox.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/workers/scr_message.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/workers/scr_worker.o +0 -0
- package/dist/lib/runtime-darwin-x64/artifacts/release/runtime/workers/scr_worker_events.o +0 -0
- package/dist/lib/runtime-darwin-x64/package.json +1 -1
- package/dist/lib/runtime-darwin-x64/runtime-pack.json +3318 -790
- package/dist/lib/runtime-sources/package.json +1 -1
- package/dist/lib/runtime-sources/src/scr_array.c +479 -46
- package/dist/lib/runtime-sources/src/scr_assert.c +3 -3
- package/dist/lib/runtime-sources/src/scr_async.c +401 -71
- package/dist/lib/runtime-sources/src/scr_async.test.ts +16 -6
- package/dist/lib/runtime-sources/src/scr_async_dyn.c +30 -30
- package/dist/lib/runtime-sources/src/scr_bytes.c +487 -221
- package/dist/lib/runtime-sources/src/scr_bytes.test.c +85 -0
- package/dist/lib/runtime-sources/src/scr_bytes_io.c +45 -64
- package/dist/lib/runtime-sources/src/scr_child.c +48 -30
- package/dist/lib/runtime-sources/src/scr_closure.c +21 -11
- package/dist/lib/runtime-sources/src/scr_console.c +27 -5
- package/dist/lib/runtime-sources/src/scr_context.c +167 -0
- package/dist/lib/runtime-sources/src/scr_context.test.c +118 -0
- package/dist/lib/runtime-sources/src/scr_context.test.ts +47 -0
- package/dist/lib/runtime-sources/src/scr_copying.c +13 -2
- package/dist/lib/runtime-sources/src/scr_cycle.c +112 -12
- package/dist/lib/runtime-sources/src/scr_dc.c +8 -8
- package/dist/lib/runtime-sources/src/scr_dgram.c +10 -7
- package/dist/lib/runtime-sources/src/scr_error.c +26 -14
- package/dist/lib/runtime-sources/src/scr_events.c +45 -31
- package/dist/lib/runtime-sources/src/scr_events_emitter.c +34 -1
- package/dist/lib/runtime-sources/src/scr_exception.c +26 -7
- package/dist/lib/runtime-sources/src/scr_fetch.c +23 -20
- package/dist/lib/runtime-sources/src/scr_fetch_curl.c +1 -1
- package/dist/lib/runtime-sources/src/scr_ffi.c +3 -3
- package/dist/lib/runtime-sources/src/scr_file_handle.c +1 -0
- package/dist/lib/runtime-sources/src/scr_http.c +20 -16
- package/dist/lib/runtime-sources/src/scr_http2.c +10 -8
- package/dist/lib/runtime-sources/src/scr_inspect.c +1 -0
- package/dist/lib/runtime-sources/src/scr_island.c +1 -1
- package/dist/lib/runtime-sources/src/scr_json.c +652 -189
- package/dist/lib/runtime-sources/src/scr_json.test.c +339 -1
- package/dist/lib/runtime-sources/src/scr_json.test.ts +59 -25
- package/dist/lib/runtime-sources/src/scr_key.h +92 -0
- package/dist/lib/runtime-sources/src/scr_lib.c +256 -136
- package/dist/lib/runtime-sources/src/scr_mailbox.c +233 -0
- package/dist/lib/runtime-sources/src/scr_mailbox.h +28 -0
- package/dist/lib/runtime-sources/src/scr_mailbox.test.c +86 -0
- package/dist/lib/runtime-sources/src/scr_mailbox.test.ts +46 -0
- package/dist/lib/runtime-sources/src/scr_map.c +240 -107
- package/dist/lib/runtime-sources/src/scr_message.c +443 -0
- package/dist/lib/runtime-sources/src/scr_message.h +14 -0
- package/dist/lib/runtime-sources/src/scr_message.test.c +152 -0
- package/dist/lib/runtime-sources/src/scr_message.test.ts +44 -0
- package/dist/lib/runtime-sources/src/scr_net.c +14 -12
- package/dist/lib/runtime-sources/src/scr_number.c +36 -4
- package/dist/lib/runtime-sources/src/scr_numeric.h +25 -0
- package/dist/lib/runtime-sources/src/scr_numeric.test.c +37 -0
- package/dist/lib/runtime-sources/src/scr_numeric.test.ts +33 -0
- package/dist/lib/runtime-sources/src/scr_object.c +9 -4
- package/dist/lib/runtime-sources/src/scr_path.c +1 -1
- package/dist/lib/runtime-sources/src/scr_readline.c +8 -8
- package/dist/lib/runtime-sources/src/scr_regex.c +351 -167
- package/dist/lib/runtime-sources/src/scr_runtime.h +207 -34
- package/dist/lib/runtime-sources/src/scr_shared.c +280 -0
- package/dist/lib/runtime-sources/src/scr_shared.test.c +113 -0
- package/dist/lib/runtime-sources/src/scr_shared.test.ts +45 -0
- package/dist/lib/runtime-sources/src/scr_stream.c +9 -9
- package/dist/lib/runtime-sources/src/scr_string.c +365 -141
- package/dist/lib/runtime-sources/src/scr_test.c +8 -8
- package/dist/lib/runtime-sources/src/scr_tls.c +12 -12
- package/dist/lib/runtime-sources/src/scr_tls_ca.c +34 -12
- package/dist/lib/runtime-sources/src/scr_union.c +10 -5
- package/dist/lib/runtime-sources/src/scr_util_compare.c +1 -0
- package/dist/lib/runtime-sources/src/scr_util_style.c +11 -11
- package/dist/lib/runtime-sources/src/scr_watch.c +16 -6
- package/dist/lib/runtime-sources/src/scr_worker.c +232 -0
- package/dist/lib/runtime-sources/src/scr_worker.h +42 -0
- package/dist/lib/runtime-sources/src/scr_worker.test.c +115 -0
- package/dist/lib/runtime-sources/src/scr_worker.test.ts +49 -0
- package/dist/lib/runtime-sources/src/scr_worker_events.c +443 -0
- package/dist/lib/runtime-sources/src/scr_zlib.c +6 -0
- package/package.json +1 -1
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
* serializers (and the error messages here).
|
|
23
23
|
*/
|
|
24
24
|
#include "scr_runtime.h"
|
|
25
|
+
#include "scr_key.h"
|
|
25
26
|
|
|
26
27
|
static SCR_TL ScrDyn *scr_builtin_object_prototype;
|
|
27
28
|
|
|
@@ -159,7 +160,9 @@ void scr_jb_init(ScrJsonBuf *b) {
|
|
|
159
160
|
}
|
|
160
161
|
|
|
161
162
|
static void scr_jb_grow(ScrJsonBuf *b, size_t need) {
|
|
162
|
-
if (
|
|
163
|
+
if (need > SIZE_MAX - sizeof(ScrStr) - 1 - b->len) scr_json_oom();
|
|
164
|
+
size_t required = b->len + need;
|
|
165
|
+
if (required <= b->cap) return;
|
|
163
166
|
if (!b->data) { /* first allocation: len == 0 */
|
|
164
167
|
size_t cap = scr_jb_hint >= need ? scr_jb_hint : need;
|
|
165
168
|
ScrStr *s = scr_str_alloc_raw(0, cap);
|
|
@@ -168,7 +171,13 @@ static void scr_jb_grow(ScrJsonBuf *b, size_t need) {
|
|
|
168
171
|
return;
|
|
169
172
|
}
|
|
170
173
|
size_t cap = b->cap;
|
|
171
|
-
while (cap <
|
|
174
|
+
while (cap < required) {
|
|
175
|
+
if (cap > (SIZE_MAX - sizeof(ScrStr) - 1) / 2) {
|
|
176
|
+
cap = required;
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
cap *= 2;
|
|
180
|
+
}
|
|
172
181
|
ScrStr *s = scr_str_regrow(SCR_JB_STR(b), cap);
|
|
173
182
|
b->data = s->data;
|
|
174
183
|
b->cap = cap;
|
|
@@ -186,7 +195,8 @@ void scr_jb_putc(ScrJsonBuf *b, char c) {
|
|
|
186
195
|
b->data[b->len++] = c;
|
|
187
196
|
}
|
|
188
197
|
|
|
189
|
-
|
|
198
|
+
void scr_jb_write(ScrJsonBuf *b, const char *s, size_t n) {
|
|
199
|
+
if (n == 0) return;
|
|
190
200
|
scr_jb_grow(b, n);
|
|
191
201
|
memcpy(b->data + b->len, s, n);
|
|
192
202
|
b->len += n;
|
|
@@ -198,6 +208,12 @@ void scr_jb_put_str(ScrJsonBuf *b, const ScrStr *s) {
|
|
|
198
208
|
|
|
199
209
|
void scr_jb_puts(ScrJsonBuf *b, const char *s) { scr_jb_write(b, s, strlen(s)); }
|
|
200
210
|
|
|
211
|
+
void scr_jb_put_number(ScrJsonBuf *b, double v) {
|
|
212
|
+
char buf[32];
|
|
213
|
+
size_t n = scr_f64_to_str(v, buf);
|
|
214
|
+
scr_jb_write(b, buf, n);
|
|
215
|
+
}
|
|
216
|
+
|
|
201
217
|
void scr_jb_put_f64(ScrJsonBuf *b, double v) {
|
|
202
218
|
/* JSON.stringify number rules: non-finite → null, -0 → "0" (String(-0)
|
|
203
219
|
* is "0" too, so scr_f64_to_str would agree — the zero test just makes
|
|
@@ -210,42 +226,82 @@ void scr_jb_put_f64(ScrJsonBuf *b, double v) {
|
|
|
210
226
|
scr_jb_putc(b, '0');
|
|
211
227
|
return;
|
|
212
228
|
}
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
229
|
+
scr_jb_put_number(b, v);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/* Find the next quote, backslash or control byte. memcpy keeps the word
|
|
233
|
+
* loads unaligned-safe, and the length guard never reads past the input.
|
|
234
|
+
* The masks only decide whether to inspect a word byte by byte: borrow
|
|
235
|
+
* propagation may mark extra lanes, so it must not determine a byte index.
|
|
236
|
+
* High UTF-8 bytes are ordinary data, independent of host byte order. */
|
|
237
|
+
static size_t scr_json_plain_bytes(const char *data, size_t len) {
|
|
238
|
+
const uint64_t ones = UINT64_C(0x0101010101010101);
|
|
239
|
+
const uint64_t high = UINT64_C(0x8080808080808080);
|
|
240
|
+
size_t i = 0;
|
|
241
|
+
while (len - i >= sizeof(uint64_t)) {
|
|
242
|
+
uint64_t word;
|
|
243
|
+
memcpy(&word, data + i, sizeof word);
|
|
244
|
+
uint64_t quotes = word ^ (ones * '"');
|
|
245
|
+
uint64_t slashes = word ^ (ones * '\\');
|
|
246
|
+
uint64_t special = ((quotes - ones) & ~quotes) |
|
|
247
|
+
((slashes - ones) & ~slashes) |
|
|
248
|
+
((word - ones * 0x20) & ~word);
|
|
249
|
+
if (special & high) break;
|
|
250
|
+
i += sizeof word;
|
|
251
|
+
}
|
|
252
|
+
while (i < len) {
|
|
253
|
+
unsigned char c = (unsigned char)data[i];
|
|
254
|
+
if (c < 0x20 || c == '"' || c == '\\') break;
|
|
255
|
+
i++;
|
|
256
|
+
}
|
|
257
|
+
return i;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
static void scr_jb_put_json_span(ScrJsonBuf *b, const char *data, size_t len) {
|
|
261
|
+
if (len > SIZE_MAX - 2) scr_json_oom();
|
|
262
|
+
size_t run = scr_json_plain_bytes(data, len);
|
|
263
|
+
/* The overwhelmingly common unescaped string needs one capacity check,
|
|
264
|
+
* including both quotes, and no per-byte builder calls. */
|
|
265
|
+
scr_jb_grow(b, run + 2);
|
|
266
|
+
b->data[b->len++] = '"';
|
|
267
|
+
if (run) memcpy(b->data + b->len, data, run);
|
|
268
|
+
b->len += run;
|
|
269
|
+
size_t i = run;
|
|
270
|
+
while (i < len) {
|
|
271
|
+
unsigned char c = (unsigned char)data[i++];
|
|
272
|
+
char escaped[6] = {'\\', 0, '0', '0', 0, 0};
|
|
273
|
+
size_t count = 2;
|
|
230
274
|
switch (c) {
|
|
231
|
-
case '"':
|
|
232
|
-
case '\\':
|
|
233
|
-
case '\n':
|
|
234
|
-
case '\r':
|
|
235
|
-
case '\t':
|
|
236
|
-
case '\b':
|
|
237
|
-
case '\f':
|
|
275
|
+
case '"': escaped[1] = '"'; break;
|
|
276
|
+
case '\\': escaped[1] = '\\'; break;
|
|
277
|
+
case '\n': escaped[1] = 'n'; break;
|
|
278
|
+
case '\r': escaped[1] = 'r'; break;
|
|
279
|
+
case '\t': escaped[1] = 't'; break;
|
|
280
|
+
case '\b': escaped[1] = 'b'; break;
|
|
281
|
+
case '\f': escaped[1] = 'f'; break;
|
|
238
282
|
default: {
|
|
239
|
-
char
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
283
|
+
static const char hex[] = "0123456789abcdef";
|
|
284
|
+
escaped[1] = 'u';
|
|
285
|
+
escaped[4] = hex[c >> 4];
|
|
286
|
+
escaped[5] = hex[c & 15];
|
|
287
|
+
count = 6;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
run = scr_json_plain_bytes(data + i, len - i);
|
|
291
|
+
if (run > SIZE_MAX - count) scr_json_oom();
|
|
292
|
+
scr_jb_grow(b, count + run);
|
|
293
|
+
memcpy(b->data + b->len, escaped, count);
|
|
294
|
+
b->len += count;
|
|
295
|
+
if (run) memcpy(b->data + b->len, data + i, run);
|
|
296
|
+
b->len += run;
|
|
297
|
+
i += run;
|
|
246
298
|
}
|
|
247
|
-
|
|
248
|
-
|
|
299
|
+
scr_jb_grow(b, 1);
|
|
300
|
+
b->data[b->len++] = '"';
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
void scr_jb_put_json_str(ScrJsonBuf *b, const ScrStr *s) {
|
|
304
|
+
scr_jb_put_json_span(b, s->data, s->len);
|
|
249
305
|
}
|
|
250
306
|
|
|
251
307
|
ScrStr *scr_jb_finish(ScrJsonBuf *b) {
|
|
@@ -264,6 +320,81 @@ ScrStr *scr_jb_finish(ScrJsonBuf *b) {
|
|
|
264
320
|
return s;
|
|
265
321
|
}
|
|
266
322
|
|
|
323
|
+
/* Write newline and a repeated gap with one reservation. Copies never
|
|
324
|
+
* overlap: each doubling reads only the already initialized prefix. */
|
|
325
|
+
static void scr_jb_indent(ScrJsonBuf *b, const char *gap, size_t gap_len, size_t depth) {
|
|
326
|
+
if (gap_len && depth > (SIZE_MAX - 1) / gap_len) scr_json_oom();
|
|
327
|
+
size_t count = gap_len * depth;
|
|
328
|
+
scr_jb_grow(b, count + 1);
|
|
329
|
+
b->data[b->len++] = '\n';
|
|
330
|
+
if (!count) return;
|
|
331
|
+
memcpy(b->data + b->len, gap, gap_len);
|
|
332
|
+
size_t filled = gap_len;
|
|
333
|
+
while (filled < count) {
|
|
334
|
+
size_t take = filled < count - filled ? filled : count - filled;
|
|
335
|
+
memcpy(b->data + b->len + filled, b->data + b->len, take);
|
|
336
|
+
filled += take;
|
|
337
|
+
}
|
|
338
|
+
b->len += count;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
ScrStr *scr_json_indent(const ScrStr *compact, const char *gap, size_t gap_len) {
|
|
342
|
+
if (!gap_len) return scr_str_retain((ScrStr *)compact);
|
|
343
|
+
/* Node stops copying the gap at its first NUL but still inserts breaks
|
|
344
|
+
* and colon spaces when the original gap is nonempty. */
|
|
345
|
+
const char *end = memchr(gap, 0, gap_len);
|
|
346
|
+
if (end) gap_len = (size_t)(end - gap);
|
|
347
|
+
ScrJsonBuf b;
|
|
348
|
+
scr_jb_init(&b);
|
|
349
|
+
size_t depth = 0, start = 0, i = 0;
|
|
350
|
+
while (i < compact->len) {
|
|
351
|
+
char c = compact->data[i];
|
|
352
|
+
if (c == '"') {
|
|
353
|
+
/* Quoted punctuation is data. Scan ordinary runs and skip the byte
|
|
354
|
+
* after each backslash so an escaped quote cannot end this string. */
|
|
355
|
+
i++;
|
|
356
|
+
while (i < compact->len) {
|
|
357
|
+
i += scr_json_plain_bytes(compact->data + i, compact->len - i);
|
|
358
|
+
if (i == compact->len) break;
|
|
359
|
+
if (compact->data[i] == '\\') {
|
|
360
|
+
i += compact->len - i >= 2 ? 2 : 1;
|
|
361
|
+
} else {
|
|
362
|
+
i++;
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
continue;
|
|
367
|
+
}
|
|
368
|
+
if (c == '{' || c == '[') {
|
|
369
|
+
char closer = c == '{' ? '}' : ']';
|
|
370
|
+
if (i + 1 < compact->len && compact->data[i + 1] == closer) {
|
|
371
|
+
i += 2;
|
|
372
|
+
continue;
|
|
373
|
+
}
|
|
374
|
+
scr_jb_write(&b, compact->data + start, i + 1 - start);
|
|
375
|
+
scr_jb_indent(&b, gap, gap_len, ++depth);
|
|
376
|
+
start = ++i;
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
if (c == '}' || c == ']') {
|
|
380
|
+
scr_jb_write(&b, compact->data + start, i - start);
|
|
381
|
+
scr_jb_indent(&b, gap, gap_len, --depth);
|
|
382
|
+
start = i++;
|
|
383
|
+
continue;
|
|
384
|
+
}
|
|
385
|
+
if (c == ',' || c == ':') {
|
|
386
|
+
scr_jb_write(&b, compact->data + start, i + 1 - start);
|
|
387
|
+
if (c == ',') scr_jb_indent(&b, gap, gap_len, depth);
|
|
388
|
+
else scr_jb_putc(&b, ' ');
|
|
389
|
+
start = ++i;
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
i++;
|
|
393
|
+
}
|
|
394
|
+
scr_jb_write(&b, compact->data + start, compact->len - start);
|
|
395
|
+
return scr_jb_finish(&b);
|
|
396
|
+
}
|
|
397
|
+
|
|
267
398
|
/* ── circular-structure detection ──────────────────────────────────────
|
|
268
399
|
* RECURSIVE record types permit runtime reference cycles; JSON.stringify
|
|
269
400
|
* of a cyclic value throws V8's exact TypeError. The compiler-emitted
|
|
@@ -413,11 +544,110 @@ void scr_dyn_from_leave(void) {
|
|
|
413
544
|
* strict alloc/free balance.
|
|
414
545
|
*/
|
|
415
546
|
static SCR_TL ScrDyn *scr_builtin_array_prototype;
|
|
547
|
+
|
|
548
|
+
/* Property names are immutable and often repeated across simultaneously live
|
|
549
|
+
* objects. Entries own references to their bytes; this fixed weak table owns
|
|
550
|
+
* none. Collisions only reduce sharing, and the final release removes a weak
|
|
551
|
+
* entry before freeing storage. Long keys bypass lookup entirely. */
|
|
552
|
+
#define SCR_DYN_KEY_SHARE_SLOTS 256
|
|
553
|
+
#define SCR_DYN_KEY_SHARE_LENGTH 64
|
|
554
|
+
typedef struct {
|
|
555
|
+
size_t rc;
|
|
556
|
+
char bytes[];
|
|
557
|
+
} ScrDynKey;
|
|
558
|
+
typedef struct {
|
|
559
|
+
ScrDynKey *key;
|
|
560
|
+
size_t length;
|
|
561
|
+
} ScrDynKeySlot;
|
|
562
|
+
static SCR_TL ScrDynKeySlot scr_dyn_keys[SCR_DYN_KEY_SHARE_SLOTS];
|
|
563
|
+
#ifdef SCR_RC_AUDIT
|
|
564
|
+
static SCR_TL long scr_live_dyn_keys;
|
|
565
|
+
long scr_dyn_key_live_count(void) { return scr_live_dyn_keys; }
|
|
566
|
+
#endif
|
|
567
|
+
|
|
568
|
+
static size_t scr_dyn_key_slot(const char *key, size_t length) {
|
|
569
|
+
size_t hash = length;
|
|
570
|
+
for (size_t i = 0; i < length; i++) hash = hash * 31 + (unsigned char)key[i];
|
|
571
|
+
return hash % SCR_DYN_KEY_SHARE_SLOTS;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
static char *scr_dyn_key_copy(const char *key, size_t length) {
|
|
575
|
+
ScrDynKeySlot *slot = length <= SCR_DYN_KEY_SHARE_LENGTH
|
|
576
|
+
? &scr_dyn_keys[scr_dyn_key_slot(key, length)] : NULL;
|
|
577
|
+
if (slot && slot->key && slot->length == length &&
|
|
578
|
+
!memcmp(slot->key->bytes, key, length)) {
|
|
579
|
+
slot->key->rc++;
|
|
580
|
+
return slot->key->bytes;
|
|
581
|
+
}
|
|
582
|
+
if (length > SIZE_MAX - sizeof(ScrDynKey) - 1) scr_json_oom();
|
|
583
|
+
ScrDynKey *owned = malloc(sizeof *owned + length + 1);
|
|
584
|
+
if (!owned) scr_json_oom();
|
|
585
|
+
#ifdef SCR_RC_AUDIT
|
|
586
|
+
scr_live_dyn_keys++;
|
|
587
|
+
#endif
|
|
588
|
+
owned->rc = 1;
|
|
589
|
+
memcpy(owned->bytes, key, length);
|
|
590
|
+
owned->bytes[length] = '\0';
|
|
591
|
+
if (slot) *slot = (ScrDynKeySlot){owned, length};
|
|
592
|
+
return owned->bytes;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
static void scr_dyn_key_release(char *key, size_t length) {
|
|
596
|
+
if (!key) return;
|
|
597
|
+
ScrDynKey *owned = (ScrDynKey *)(key - offsetof(ScrDynKey, bytes));
|
|
598
|
+
if (--owned->rc) return;
|
|
599
|
+
if (length <= SCR_DYN_KEY_SHARE_LENGTH) {
|
|
600
|
+
ScrDynKeySlot *slot = &scr_dyn_keys[scr_dyn_key_slot(key, length)];
|
|
601
|
+
if (slot->key == owned) slot->key = NULL;
|
|
602
|
+
}
|
|
603
|
+
#ifdef SCR_RC_AUDIT
|
|
604
|
+
scr_live_dyn_keys--;
|
|
605
|
+
#endif
|
|
606
|
+
free(owned);
|
|
607
|
+
}
|
|
608
|
+
|
|
416
609
|
#ifndef SCR_RC_AUDIT
|
|
417
610
|
static SCR_TL ScrDyn *scr_dyn_free_arr, *scr_dyn_free_obj, *scr_dyn_free_misc;
|
|
418
611
|
static SCR_TL size_t scr_dyn_free_count;
|
|
419
612
|
#define SCR_DYN_FREE_MAX 8192
|
|
613
|
+
/* Recycled small objects may retain key bytes, but never values or an
|
|
614
|
+
* unbounded document's keys. This budget applies across the whole pool. */
|
|
615
|
+
static SCR_TL size_t scr_dyn_cached_key_bytes;
|
|
616
|
+
#define SCR_DYN_KEY_CACHE_MAX ((size_t)64 * 1024)
|
|
617
|
+
#define SCR_DYN_KEY_CACHE_SLOTS 16
|
|
618
|
+
#define SCR_DYN_KEY_CACHE_LENGTH 64
|
|
619
|
+
#endif
|
|
620
|
+
|
|
621
|
+
static void scr_dyn_obj_drop_keys(ScrDyn *d, bool cache) {
|
|
622
|
+
for (size_t i = 0; i < d->v.obj.cap; i++) {
|
|
623
|
+
ScrDynEntry *entry = &d->v.obj.entries[i];
|
|
624
|
+
if (!entry->key) continue;
|
|
625
|
+
#ifndef SCR_RC_AUDIT
|
|
626
|
+
if (cache && d->v.obj.cap <= SCR_DYN_KEY_CACHE_SLOTS &&
|
|
627
|
+
entry->key_len <= SCR_DYN_KEY_CACHE_LENGTH &&
|
|
628
|
+
sizeof(ScrDynKey) + entry->key_len + 1 <= SCR_DYN_KEY_CACHE_MAX - scr_dyn_cached_key_bytes) {
|
|
629
|
+
scr_dyn_cached_key_bytes += sizeof(ScrDynKey) + entry->key_len + 1;
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
#else
|
|
633
|
+
(void)cache;
|
|
420
634
|
#endif
|
|
635
|
+
scr_dyn_key_release(entry->key, entry->key_len);
|
|
636
|
+
entry->key = NULL;
|
|
637
|
+
entry->key_len = 0;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/* Primitive kinds cannot acquire properties or change kind while live, so
|
|
642
|
+
* an object property edge to one cannot participate in a cycle. Keep its RC edge
|
|
643
|
+
* out of trial deletion and release it in collected teardown instead. Other
|
|
644
|
+
* owners may still trace the same primitive through the uniform header ABI;
|
|
645
|
+
* our untraced reference keeps it alive until that teardown releases it.
|
|
646
|
+
* Entry metadata snapshots this decision during trace, before any white node
|
|
647
|
+
* can be freed. Teardown must never inspect the child's kind again. */
|
|
648
|
+
static bool scr_dyn_member_is_traced(const ScrDyn *value) {
|
|
649
|
+
return value && value->kind > SCR_DYN_STR && value->kind != SCR_DYN_UNDEF;
|
|
650
|
+
}
|
|
421
651
|
|
|
422
652
|
/* Checked objects and functions can close over one another. All heap dyn
|
|
423
653
|
* nodes carry a collector header so a captured unknown value has one uniform
|
|
@@ -425,19 +655,21 @@ static SCR_TL size_t scr_dyn_free_count;
|
|
|
425
655
|
* capsules keep their conservative ownership edges. */
|
|
426
656
|
void scr_dyn_trace_v(void *ptr, ScrTraceVisit visit, void *ctx) {
|
|
427
657
|
ScrDyn *d = ptr;
|
|
428
|
-
visit(d->prototype, ctx);
|
|
429
|
-
visit(d->symbol_properties, ctx);
|
|
430
|
-
visit(d->symbol_keys, ctx);
|
|
658
|
+
if (d->prototype) visit(d->prototype, ctx);
|
|
659
|
+
if (d->symbol_properties) visit(d->symbol_properties, ctx);
|
|
660
|
+
if (d->symbol_keys) visit(d->symbol_keys, ctx);
|
|
431
661
|
switch (d->kind) {
|
|
432
662
|
case SCR_DYN_ARR:
|
|
433
663
|
for (size_t i = 0; i < d->v.arr.len; i++) visit(d->v.arr.items[i], ctx);
|
|
434
|
-
visit(d->v.arr.properties, ctx);
|
|
664
|
+
if (d->v.arr.properties) visit(d->v.arr.properties, ctx);
|
|
435
665
|
break;
|
|
436
666
|
case SCR_DYN_OBJ:
|
|
437
667
|
for (size_t i = 0; i < d->v.obj.len; i++) {
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
visit(
|
|
668
|
+
ScrDynEntry *entry = &d->v.obj.entries[i];
|
|
669
|
+
entry->value_traced = scr_dyn_member_is_traced(entry->value);
|
|
670
|
+
if (entry->value_traced) visit(entry->value, ctx);
|
|
671
|
+
if (entry->getter) visit(entry->getter, ctx);
|
|
672
|
+
if (entry->setter) visit(entry->setter, ctx);
|
|
441
673
|
}
|
|
442
674
|
break;
|
|
443
675
|
case SCR_DYN_FUNC: visit(d->v.fn.clo, ctx); break;
|
|
@@ -539,6 +771,12 @@ static ScrDyn *scr_dyn_alloc(ScrDynKind kind) {
|
|
|
539
771
|
d->v.arr.presence = NULL;
|
|
540
772
|
} else if (kind == SCR_DYN_OBJ) {
|
|
541
773
|
d->v.obj.len = 0; /* cap/entries preserved */
|
|
774
|
+
if (d->v.obj.cap <= SCR_DYN_KEY_CACHE_SLOTS) {
|
|
775
|
+
for (size_t i = 0; i < d->v.obj.cap; i++) {
|
|
776
|
+
ScrDynEntry *entry = &d->v.obj.entries[i];
|
|
777
|
+
if (entry->key) scr_dyn_cached_key_bytes -= sizeof(ScrDynKey) + entry->key_len + 1;
|
|
778
|
+
}
|
|
779
|
+
}
|
|
542
780
|
d->v.obj.source_identity = NULL;
|
|
543
781
|
d->v.obj.source_access = NULL;
|
|
544
782
|
} else {
|
|
@@ -565,6 +803,10 @@ static void scr_dyn_handle_release(void *h, ScrDynHandleTag tag);
|
|
|
565
803
|
static bool scr_dyn_to_primitive_result_is_object(const ScrDyn *d);
|
|
566
804
|
|
|
567
805
|
static void scr_dyn_dispose(ScrDyn *d, bool collected) {
|
|
806
|
+
if (d->kind == SCR_DYN_OBJ) {
|
|
807
|
+
free(d->v.obj.index);
|
|
808
|
+
d->v.obj.index = NULL;
|
|
809
|
+
}
|
|
568
810
|
if (!collected) scr_dyn_release(d->prototype);
|
|
569
811
|
if (!collected) scr_dyn_release(d->symbol_properties);
|
|
570
812
|
if (!collected) scr_dyn_release(d->symbol_keys);
|
|
@@ -592,12 +834,15 @@ static void scr_dyn_dispose(ScrDyn *d, bool collected) {
|
|
|
592
834
|
break;
|
|
593
835
|
case SCR_DYN_OBJ:
|
|
594
836
|
for (size_t i = 0; i < d->v.obj.len; i++) {
|
|
595
|
-
|
|
837
|
+
ScrDyn *value = d->v.obj.entries[i].value;
|
|
838
|
+
if (!collected || !d->v.obj.entries[i].value_traced) scr_dyn_release(value);
|
|
596
839
|
if (!collected) {
|
|
597
|
-
scr_dyn_release(d->v.obj.entries[i].value);
|
|
598
840
|
scr_dyn_release(d->v.obj.entries[i].getter);
|
|
599
841
|
scr_dyn_release(d->v.obj.entries[i].setter);
|
|
600
842
|
}
|
|
843
|
+
d->v.obj.entries[i].value = NULL;
|
|
844
|
+
d->v.obj.entries[i].getter = NULL;
|
|
845
|
+
d->v.obj.entries[i].setter = NULL;
|
|
601
846
|
}
|
|
602
847
|
if (d->v.obj.source_identity) {
|
|
603
848
|
d->v.obj.source_access(d->v.obj.source_identity, false);
|
|
@@ -646,6 +891,7 @@ static void scr_dyn_dispose(ScrDyn *d, bool collected) {
|
|
|
646
891
|
#endif
|
|
647
892
|
#ifndef SCR_RC_AUDIT
|
|
648
893
|
if (!collected && scr_dyn_free_count < SCR_DYN_FREE_MAX) {
|
|
894
|
+
if (d->kind == SCR_DYN_OBJ) scr_dyn_obj_drop_keys(d, true);
|
|
649
895
|
/* Pooled blocks retain their headers and count toward the bounded
|
|
650
896
|
* allocated heap, but never remain in a candidate buffer. */
|
|
651
897
|
scr_weak_dispose(d);
|
|
@@ -659,12 +905,17 @@ static void scr_dyn_dispose(ScrDyn *d, bool collected) {
|
|
|
659
905
|
}
|
|
660
906
|
#endif
|
|
661
907
|
if (d->kind == SCR_DYN_ARR) free(d->v.arr.items);
|
|
662
|
-
else if (d->kind == SCR_DYN_OBJ)
|
|
908
|
+
else if (d->kind == SCR_DYN_OBJ) {
|
|
909
|
+
scr_dyn_obj_drop_keys(d, false);
|
|
910
|
+
free(d->v.obj.entries);
|
|
911
|
+
}
|
|
663
912
|
scr_cyc_free(d);
|
|
664
913
|
}
|
|
665
914
|
|
|
666
915
|
static void scr_dyn_gcfree(void *ptr) { scr_dyn_dispose(ptr, true); }
|
|
667
916
|
|
|
917
|
+
static void scr_dyn_destroy(void *ptr) { scr_dyn_dispose(ptr, false); }
|
|
918
|
+
|
|
668
919
|
void scr_dyn_release(ScrDyn *d) {
|
|
669
920
|
if (!d || d->rc == SIZE_MAX) return;
|
|
670
921
|
if (--d->rc != 0) {
|
|
@@ -675,7 +926,84 @@ void scr_dyn_release(ScrDyn *d) {
|
|
|
675
926
|
return;
|
|
676
927
|
}
|
|
677
928
|
scr_cyc_on_dead(d);
|
|
678
|
-
|
|
929
|
+
scr_rc_destroy(d, scr_dyn_destroy);
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/* Small objects retain their compact linear representation. A wide object
|
|
933
|
+
* owns a bucket index of entry positions; entries remain insertion ordered.
|
|
934
|
+
* No key/value ownership lives here, and callbacks never retain its slots. */
|
|
935
|
+
#define SCR_DYN_OBJECT_INDEX_MIN 32
|
|
936
|
+
typedef struct ScrDynObjectIndex {
|
|
937
|
+
size_t buckets;
|
|
938
|
+
size_t slots[]; /* zero is empty; occupied slots store entry + 1 */
|
|
939
|
+
} ScrDynObjectIndex;
|
|
940
|
+
|
|
941
|
+
static void scr_dyn_index_insert(ScrDynObjectIndex *index, const ScrDynEntry *entry, size_t position) {
|
|
942
|
+
size_t slot = scr_key_hash(entry->key, entry->key_len) & (index->buckets - 1);
|
|
943
|
+
while (index->slots[slot]) slot = (slot + 1) & (index->buckets - 1);
|
|
944
|
+
index->slots[slot] = position + 1;
|
|
945
|
+
}
|
|
946
|
+
|
|
947
|
+
/* Keep index allocation/probing outside compact object insertion and reads. */
|
|
948
|
+
static __attribute__((noinline)) void scr_dyn_index_append(ScrDyn *object) {
|
|
949
|
+
size_t count = object->v.obj.len;
|
|
950
|
+
ScrDynObjectIndex *index = object->v.obj.index;
|
|
951
|
+
if (!index || count > index->buckets / 2) {
|
|
952
|
+
size_t buckets = index ? index->buckets : 64;
|
|
953
|
+
while (count > buckets / 2) {
|
|
954
|
+
if (buckets > (SIZE_MAX - sizeof *index) / sizeof(size_t) / 2) scr_json_oom();
|
|
955
|
+
buckets *= 2;
|
|
956
|
+
}
|
|
957
|
+
free(index);
|
|
958
|
+
index = calloc(1, sizeof *index + buckets * sizeof(size_t));
|
|
959
|
+
if (!index) scr_json_oom();
|
|
960
|
+
index->buckets = buckets;
|
|
961
|
+
object->v.obj.index = index;
|
|
962
|
+
for (size_t i = 0; i < count; i++) scr_dyn_index_insert(index, &object->v.obj.entries[i], i);
|
|
963
|
+
} else {
|
|
964
|
+
scr_dyn_index_insert(index, &object->v.obj.entries[count - 1], count - 1);
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
|
|
968
|
+
/* A checked hint avoids repeating a linear walk for recurring property
|
|
969
|
+
* names. Slots store indices only, never object/key pointers. Every hit
|
|
970
|
+
* checks the current entry, so different shapes, deletion and reordering
|
|
971
|
+
* need no invalidation and collisions fall back to the ordinary search. */
|
|
972
|
+
#define SCR_DYN_PROPERTY_HINTS 64
|
|
973
|
+
static SCR_TL size_t scr_dyn_property_hints[SCR_DYN_PROPERTY_HINTS];
|
|
974
|
+
|
|
975
|
+
static ScrDynEntry *scr_dyn_find_linear_entry(const ScrDyn *object, const char *key, size_t length) {
|
|
976
|
+
for (size_t i = 0; i < object->v.obj.len; i++) {
|
|
977
|
+
ScrDynEntry *entry = &object->v.obj.entries[i];
|
|
978
|
+
if (entry->key_len == length && scr_key_equal(entry->key, key, length)) return entry;
|
|
979
|
+
}
|
|
980
|
+
return NULL;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
static __attribute__((noinline)) ScrDynEntry *scr_dyn_find_indexed_entry(
|
|
984
|
+
const ScrDyn *object, const char *key, size_t length) {
|
|
985
|
+
const ScrDynObjectIndex *index = object->v.obj.index;
|
|
986
|
+
size_t slot = scr_key_hash(key, length) & (index->buckets - 1);
|
|
987
|
+
while (index->slots[slot]) {
|
|
988
|
+
ScrDynEntry *entry = &object->v.obj.entries[index->slots[slot] - 1];
|
|
989
|
+
if (entry->key_len == length && scr_key_equal(entry->key, key, length)) return entry;
|
|
990
|
+
slot = (slot + 1) & (index->buckets - 1);
|
|
991
|
+
}
|
|
992
|
+
return NULL;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
static ScrDynEntry *scr_dyn_find_entry(const ScrDyn *object, const char *key, size_t length) {
|
|
996
|
+
if (object->kind != SCR_DYN_OBJ) return NULL;
|
|
997
|
+
if (object->v.obj.index) return scr_dyn_find_indexed_entry(object, key, length);
|
|
998
|
+
size_t slot = (length + (length ? (unsigned char)key[0] * 7u : 0)) % SCR_DYN_PROPERTY_HINTS;
|
|
999
|
+
size_t hint = scr_dyn_property_hints[slot];
|
|
1000
|
+
if (hint < object->v.obj.len) {
|
|
1001
|
+
ScrDynEntry *entry = &object->v.obj.entries[hint];
|
|
1002
|
+
if (entry->key_len == length && scr_key_equal(entry->key, key, length)) return entry;
|
|
1003
|
+
}
|
|
1004
|
+
ScrDynEntry *entry = scr_dyn_find_linear_entry(object, key, length);
|
|
1005
|
+
if (entry) scr_dyn_property_hints[slot] = (size_t)(entry - object->v.obj.entries);
|
|
1006
|
+
return entry;
|
|
679
1007
|
}
|
|
680
1008
|
|
|
681
1009
|
ScrDyn *scr_dyn_obj_get(const ScrDyn *d, const char *key, size_t key_len) {
|
|
@@ -683,20 +1011,13 @@ ScrDyn *scr_dyn_obj_get(const ScrDyn *d, const char *key, size_t key_len) {
|
|
|
683
1011
|
scr_dyn_proxy_unsupported("raw object inspection");
|
|
684
1012
|
return NULL;
|
|
685
1013
|
}
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
const ScrDynEntry *e = &d->v.obj.entries[i];
|
|
689
|
-
if (e->key_len == key_len && memcmp(e->key, key, key_len) == 0) return e->value;
|
|
690
|
-
}
|
|
691
|
-
return NULL;
|
|
1014
|
+
ScrDynEntry *entry = scr_dyn_find_entry(d, key, key_len);
|
|
1015
|
+
return entry ? entry->value : NULL;
|
|
692
1016
|
}
|
|
693
1017
|
|
|
694
1018
|
bool scr_dyn_obj_enumerable(const ScrDyn *d, const char *key, size_t key_len) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
if (e->key_len == key_len && memcmp(e->key, key, key_len) == 0) return e->enumerable;
|
|
698
|
-
}
|
|
699
|
-
return false;
|
|
1019
|
+
ScrDynEntry *entry = scr_dyn_find_entry(d, key, key_len);
|
|
1020
|
+
return entry && entry->enumerable;
|
|
700
1021
|
}
|
|
701
1022
|
|
|
702
1023
|
static const ScrDyn *scr_dyn_property_owner(const ScrDyn *object, const char *key, size_t length);
|
|
@@ -983,29 +1304,27 @@ ScrDyn *scr_dyn_arr_named_get(const ScrDyn *d, const ScrStr *key) {
|
|
|
983
1304
|
return value;
|
|
984
1305
|
}
|
|
985
1306
|
|
|
986
|
-
/*
|
|
987
|
-
*
|
|
988
|
-
*
|
|
989
|
-
static void scr_dyn_obj_put(ScrDyn *obj, char *key, size_t key_len, ScrDyn *value) {
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
}
|
|
1000
|
-
ScrDyn *old = e->value;
|
|
1001
|
-
e->value = value;
|
|
1002
|
-
scr_dyn_release(old);
|
|
1003
|
-
free(key);
|
|
1307
|
+
/* Borrows key and takes ownership of value. Duplicate keys retain their
|
|
1308
|
+
* original spelling/storage and insertion position; the later value wins.
|
|
1309
|
+
* A recycled entry can reuse equal key bytes without a malloc/free pair. */
|
|
1310
|
+
static void scr_dyn_obj_put(ScrDyn *obj, const char *key, size_t key_len, ScrDyn *value) {
|
|
1311
|
+
/* Construction usually appends an absent name. Avoid a read hint that
|
|
1312
|
+
* repeats comparisons on compact objects; wide objects use their index. */
|
|
1313
|
+
ScrDynEntry *existing = obj->v.obj.index ? scr_dyn_find_entry(obj, key, key_len)
|
|
1314
|
+
: scr_dyn_find_linear_entry(obj, key, key_len);
|
|
1315
|
+
if (existing) {
|
|
1316
|
+
if (existing->accessor || !existing->writable) {
|
|
1317
|
+
scr_dyn_release(value);
|
|
1318
|
+
static const char message[] = "Cannot assign to read only property";
|
|
1319
|
+
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
1004
1320
|
return;
|
|
1005
1321
|
}
|
|
1322
|
+
ScrDyn *old = existing->value;
|
|
1323
|
+
existing->value = value;
|
|
1324
|
+
scr_dyn_release(old);
|
|
1325
|
+
return;
|
|
1006
1326
|
}
|
|
1007
1327
|
if (obj->non_extensible) {
|
|
1008
|
-
free(key);
|
|
1009
1328
|
scr_dyn_release(value);
|
|
1010
1329
|
static const char message[] = "Cannot add property, object is not extensible";
|
|
1011
1330
|
scr_throw_error_msg(SCR_ERR_TYPE, message, sizeof message - 1);
|
|
@@ -1015,11 +1334,16 @@ static void scr_dyn_obj_put(ScrDyn *obj, char *key, size_t key_len, ScrDyn *valu
|
|
|
1015
1334
|
size_t cap = obj->v.obj.cap ? obj->v.obj.cap * 2 : 4;
|
|
1016
1335
|
ScrDynEntry *entries = realloc(obj->v.obj.entries, cap * sizeof *entries);
|
|
1017
1336
|
if (!entries) scr_json_oom();
|
|
1337
|
+
memset(entries + obj->v.obj.cap, 0, (cap - obj->v.obj.cap) * sizeof *entries);
|
|
1018
1338
|
obj->v.obj.entries = entries;
|
|
1019
1339
|
obj->v.obj.cap = cap;
|
|
1020
1340
|
}
|
|
1021
1341
|
ScrDynEntry *e = &obj->v.obj.entries[obj->v.obj.len++];
|
|
1022
|
-
e->key
|
|
1342
|
+
if (!e->key || e->key_len != key_len || memcmp(e->key, key, key_len)) {
|
|
1343
|
+
char *owned = scr_dyn_key_copy(key, key_len);
|
|
1344
|
+
scr_dyn_key_release(e->key, e->key_len);
|
|
1345
|
+
e->key = owned;
|
|
1346
|
+
}
|
|
1023
1347
|
e->key_len = key_len;
|
|
1024
1348
|
e->value = value;
|
|
1025
1349
|
e->getter = NULL;
|
|
@@ -1028,6 +1352,7 @@ static void scr_dyn_obj_put(ScrDyn *obj, char *key, size_t key_len, ScrDyn *valu
|
|
|
1028
1352
|
e->writable = true;
|
|
1029
1353
|
e->enumerable = true;
|
|
1030
1354
|
e->configurable = true;
|
|
1355
|
+
if (obj->v.obj.len >= SCR_DYN_OBJECT_INDEX_MIN) scr_dyn_index_append(obj);
|
|
1031
1356
|
}
|
|
1032
1357
|
|
|
1033
1358
|
/* ── dyn construction (compiler-emitted converters & overflow reads) ───── */
|
|
@@ -1088,6 +1413,22 @@ ScrDyn *scr_dyn_symbol_get(const ScrDyn *value, const ScrStr *key) {
|
|
|
1088
1413
|
}
|
|
1089
1414
|
|
|
1090
1415
|
ScrDyn *scr_dyn_new_num(double n) {
|
|
1416
|
+
/* Small integers are immutable primitives, just like the boolean and null
|
|
1417
|
+
* singletons. Initialize only touched slots; the table neither grows nor
|
|
1418
|
+
* owns heap references. Preserve negative zero as a distinct payload. */
|
|
1419
|
+
if (n >= -128 && n <= 255) {
|
|
1420
|
+
int value = (int)n;
|
|
1421
|
+
if ((double)value == n && (value != 0 || !signbit(n))) {
|
|
1422
|
+
static SCR_TL ScrDyn values[384];
|
|
1423
|
+
ScrDyn *cached = &values[value + 128];
|
|
1424
|
+
if (cached->rc == 0) {
|
|
1425
|
+
cached->rc = SIZE_MAX;
|
|
1426
|
+
cached->kind = SCR_DYN_NUM;
|
|
1427
|
+
cached->v.num = n;
|
|
1428
|
+
}
|
|
1429
|
+
return cached;
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1091
1432
|
ScrDyn *d = scr_dyn_alloc(SCR_DYN_NUM);
|
|
1092
1433
|
d->v.num = n;
|
|
1093
1434
|
return d;
|
|
@@ -1927,7 +2268,9 @@ bool scr_dyn_util_type_is(const ScrDyn *value, const ScrStr *probe) {
|
|
|
1927
2268
|
if (!value) return false;
|
|
1928
2269
|
if (value->kind == SCR_DYN_JSVAL) return scr_dyn_jsval_ops()->type_probe(value->v.jsval.cell, probe);
|
|
1929
2270
|
#define PROBE(name) (probe->len == sizeof(name) - 1 && memcmp(probe->data, name, sizeof(name) - 1) == 0)
|
|
1930
|
-
if (PROBE("isAnyArrayBuffer")
|
|
2271
|
+
if (PROBE("isAnyArrayBuffer")) return scr_buffer_storage_is(value);
|
|
2272
|
+
if (PROBE("isArrayBuffer")) return scr_array_buffer_is(value);
|
|
2273
|
+
if (PROBE("isSharedArrayBuffer")) return scr_shared_array_buffer_is(value);
|
|
1931
2274
|
if (PROBE("isArrayBufferView")) return value->kind == SCR_DYN_BYTES;
|
|
1932
2275
|
if (PROBE("isDataView")) return value->kind == SCR_DYN_BYTES && value->v.bytes->is_data_view;
|
|
1933
2276
|
if (PROBE("isTypedArray")) return value->kind == SCR_DYN_BYTES && !value->v.bytes->is_data_view;
|
|
@@ -2165,7 +2508,7 @@ void scr_dyn_chunk_enc(bool utf8) { scr_dyn_chunk_utf8 = utf8; }
|
|
|
2165
2508
|
* a Buffer-flavored bytes box, or a string inside a setEncoding window. */
|
|
2166
2509
|
ScrDyn *scr_dyn_new_chunk(const ScrBytes *b) {
|
|
2167
2510
|
if (scr_dyn_chunk_utf8) {
|
|
2168
|
-
ScrStr *s =
|
|
2511
|
+
ScrStr *s = scr_bytes_string(b, 0, b->len);
|
|
2169
2512
|
ScrDyn *d = scr_dyn_new_str(s);
|
|
2170
2513
|
scr_str_release(s);
|
|
2171
2514
|
return d;
|
|
@@ -2343,7 +2686,7 @@ ScrDyn *scr_dyn_bind(ScrDyn *target, ScrDyn *const *args, size_t argc) {
|
|
|
2343
2686
|
* always-linked core never references gated units. A missing tag at use
|
|
2344
2687
|
* is an internal error: emitted programs install a unit's ops whenever
|
|
2345
2688
|
* they can box its handles. */
|
|
2346
|
-
static const ScrDynHandleOps *scr_dynh_ops[SCR_DYNH_COUNT];
|
|
2689
|
+
static SCR_TL const ScrDynHandleOps *scr_dynh_ops[SCR_DYNH_COUNT];
|
|
2347
2690
|
|
|
2348
2691
|
void scr_dyn_handle_install(ScrDynHandleTag tag, const ScrDynHandleOps *ops) {
|
|
2349
2692
|
scr_dynh_ops[tag] = ops;
|
|
@@ -2590,6 +2933,7 @@ ScrDyn *scr_dyn_new_handle(void *h, ScrDynHandleTag tag) {
|
|
|
2590
2933
|
d->v.handle.ptr = scr_dyn_handle_ops(tag)->retain(h);
|
|
2591
2934
|
d->v.handle.tag = tag;
|
|
2592
2935
|
d->v.handle.traced = tag == SCR_DYNH_WEAK_MAP || tag == SCR_DYNH_WEAK_SET ||
|
|
2936
|
+
tag == SCR_DYNH_WORKER || tag == SCR_DYNH_MESSAGE_PORT ||
|
|
2593
2937
|
((tag == SCR_DYNH_SET || tag == SCR_DYNH_MAP) &&
|
|
2594
2938
|
(((ScrMap *)h)->key_trace != NULL || ((ScrMap *)h)->val_trace != NULL));
|
|
2595
2939
|
return d;
|
|
@@ -2599,8 +2943,8 @@ ScrDyn *scr_dyn_new_handle(void *h, ScrDynHandleTag tag) {
|
|
|
2599
2943
|
* allocator view; the freelist stays private, and the release arm's
|
|
2600
2944
|
* scr_promise_release edge installs HERE — a promise-free link never
|
|
2601
2945
|
* references the fiber machinery (the unit-test subset links). */
|
|
2602
|
-
void (*scr_dyn_promise_release_fn)(ScrPromise *p) = NULL;
|
|
2603
|
-
bool (*scr_dyn_promise_identity_fn)(ScrPromise *a, ScrPromise *b) = NULL;
|
|
2946
|
+
SCR_TL void (*scr_dyn_promise_release_fn)(ScrPromise *p) = NULL;
|
|
2947
|
+
SCR_TL bool (*scr_dyn_promise_identity_fn)(ScrPromise *a, ScrPromise *b) = NULL;
|
|
2604
2948
|
|
|
2605
2949
|
ScrDyn *scr_dyn_alloc_promise(void (*release_fn)(ScrPromise *p)) {
|
|
2606
2950
|
scr_dyn_promise_release_fn = release_fn;
|
|
@@ -2765,7 +3109,15 @@ typedef struct {
|
|
|
2765
3109
|
static SCR_TL ScrDynThisEnt *scr_dyn_this_stack;
|
|
2766
3110
|
static SCR_TL size_t scr_dyn_this_n, scr_dyn_this_cap;
|
|
2767
3111
|
|
|
3112
|
+
static void scr_dyn_this_cleanup(void) {
|
|
3113
|
+
while (scr_dyn_this_n) scr_dyn_this_pop();
|
|
3114
|
+
free(scr_dyn_this_stack);
|
|
3115
|
+
scr_dyn_this_stack = NULL;
|
|
3116
|
+
scr_dyn_this_cap = 0;
|
|
3117
|
+
}
|
|
3118
|
+
|
|
2768
3119
|
static ScrDynThisEnt *scr_dyn_this_grow(void) {
|
|
3120
|
+
if (!scr_dyn_this_stack) scr_atexit(scr_dyn_this_cleanup);
|
|
2769
3121
|
if (scr_dyn_this_n == scr_dyn_this_cap) {
|
|
2770
3122
|
size_t cap = scr_dyn_this_cap ? scr_dyn_this_cap * 2 : 8;
|
|
2771
3123
|
ScrDynThisEnt *s = realloc(scr_dyn_this_stack, cap * sizeof *s);
|
|
@@ -2827,14 +3179,10 @@ static void scr_dyn_handle_key_set(ScrDyn *recv, ScrStr *key, ScrDyn *value) {
|
|
|
2827
3179
|
scr_throw_error(SCR_ERR_ERROR, scr_jb_finish(&b));
|
|
2828
3180
|
}
|
|
2829
3181
|
|
|
2830
|
-
/* Public obj insertion
|
|
2831
|
-
*
|
|
3182
|
+
/* Public obj insertion copies a new key only when needed, owns the value,
|
|
3183
|
+
* and preserves the existing entry for duplicate keys. */
|
|
2832
3184
|
void scr_dyn_obj_set(ScrDyn *obj, const char *key, size_t key_len, ScrDyn *value) {
|
|
2833
|
-
|
|
2834
|
-
if (!copy) scr_json_oom();
|
|
2835
|
-
memcpy(copy, key, key_len);
|
|
2836
|
-
copy[key_len] = '\0';
|
|
2837
|
-
scr_dyn_obj_put(obj, copy, key_len, value);
|
|
3185
|
+
scr_dyn_obj_put(obj, key, key_len, value);
|
|
2838
3186
|
}
|
|
2839
3187
|
|
|
2840
3188
|
static ScrStr *scr_dyn_property_key(const ScrDyn *key) {
|
|
@@ -2842,12 +3190,7 @@ static ScrStr *scr_dyn_property_key(const ScrDyn *key) {
|
|
|
2842
3190
|
}
|
|
2843
3191
|
|
|
2844
3192
|
static ScrDynEntry *scr_dyn_entry(ScrDyn *obj, const ScrStr *key) {
|
|
2845
|
-
|
|
2846
|
-
for (size_t i = 0; i < obj->v.obj.len; i++) {
|
|
2847
|
-
ScrDynEntry *entry = &obj->v.obj.entries[i];
|
|
2848
|
-
if (entry->key_len == key->len && memcmp(entry->key, key->data, key->len) == 0) return entry;
|
|
2849
|
-
}
|
|
2850
|
-
return NULL;
|
|
3193
|
+
return scr_dyn_find_entry(obj, key->data, key->len);
|
|
2851
3194
|
}
|
|
2852
3195
|
|
|
2853
3196
|
static bool scr_dyn_property_same_value(const ScrDyn *a, const ScrDyn *b) {
|
|
@@ -3030,6 +3373,7 @@ typedef struct {
|
|
|
3030
3373
|
unsigned kind; /* 0: array, 1: string, 2: Map, 3: Set */
|
|
3031
3374
|
unsigned selection; /* 0: values, 1: keys, 2: entries */
|
|
3032
3375
|
bool array_like;
|
|
3376
|
+
bool step_done; /* completion of the last compiler-consumed step */
|
|
3033
3377
|
double limit;
|
|
3034
3378
|
} ScrNativeIterator;
|
|
3035
3379
|
|
|
@@ -3071,21 +3415,18 @@ static void scr_native_iterator_release(void *ptr) {
|
|
|
3071
3415
|
free(iterator);
|
|
3072
3416
|
}
|
|
3073
3417
|
|
|
3074
|
-
|
|
3418
|
+
/* Produce an owned value without allocating the protocol result. The
|
|
3419
|
+
* compiler uses this only after checking the captured next function; public
|
|
3420
|
+
* next() calls still receive a fresh, independently mutable result object. */
|
|
3421
|
+
static ScrDyn *scr_native_iterator_value(ScrNativeIterator *iterator, bool *done_out) {
|
|
3075
3422
|
ScrDyn *source = iterator->source;
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
if (scr_dyn_truthy(scr_dyn_obj_get(result, "done", 4))) {
|
|
3080
|
-
iterator->source = NULL;
|
|
3081
|
-
scr_dyn_release(source);
|
|
3082
|
-
}
|
|
3083
|
-
return result;
|
|
3084
|
-
}
|
|
3423
|
+
/* An inherited indexed getter can advance this same iterator recursively.
|
|
3424
|
+
* Keep the source alive even if that nested call exhausts the iterator. */
|
|
3425
|
+
if (source) scr_dyn_retain(source);
|
|
3085
3426
|
/* Native array capsules retain the live array, so refresh its view at each
|
|
3086
3427
|
* step rather than iterating a snapshot taken when the iterator opened. */
|
|
3087
3428
|
ScrDyn *view = source && source->kind == SCR_DYN_TYPED_REF ? scr_dyn_typed_ref_materialize(source) : NULL;
|
|
3088
|
-
if (scr_exc_pending()) { scr_dyn_release(view); return NULL; }
|
|
3429
|
+
if (scr_exc_pending()) { scr_dyn_release(view); scr_dyn_release(source); return NULL; }
|
|
3089
3430
|
ScrDyn *items = view ? view : source;
|
|
3090
3431
|
ScrMap *map = source && (iterator->kind == 2 || iterator->kind == 3) ? source->v.handle.ptr : NULL;
|
|
3091
3432
|
if (map) while (iterator->index < scr_map_iter_count(map) && !scr_map_iter_live(map, iterator->index)) iterator->index++;
|
|
@@ -3131,6 +3472,24 @@ static ScrDyn *scr_native_iterator_next(ScrNativeIterator *iterator) {
|
|
|
3131
3472
|
scr_str_release(point);
|
|
3132
3473
|
}
|
|
3133
3474
|
scr_dyn_release(view);
|
|
3475
|
+
scr_dyn_release(source);
|
|
3476
|
+
*done_out = done;
|
|
3477
|
+
return value;
|
|
3478
|
+
}
|
|
3479
|
+
|
|
3480
|
+
static ScrDyn *scr_native_iterator_next(ScrNativeIterator *iterator) {
|
|
3481
|
+
ScrDyn *source = iterator->source;
|
|
3482
|
+
if (source && iterator->kind == 4) {
|
|
3483
|
+
ScrDyn *result = scr_dyn_handle_ops_of(source)->iter_step(source->v.handle.ptr, &iterator->index, iterator->selection);
|
|
3484
|
+
if (!result) return NULL;
|
|
3485
|
+
if (scr_dyn_truthy(scr_dyn_obj_get(result, "done", 4))) {
|
|
3486
|
+
iterator->source = NULL;
|
|
3487
|
+
scr_dyn_release(source);
|
|
3488
|
+
}
|
|
3489
|
+
return result;
|
|
3490
|
+
}
|
|
3491
|
+
bool done;
|
|
3492
|
+
ScrDyn *value = scr_native_iterator_value(iterator, &done);
|
|
3134
3493
|
if (!value) return NULL;
|
|
3135
3494
|
ScrDyn *result = scr_dyn_new_obj();
|
|
3136
3495
|
scr_dyn_obj_set(result, "value", 5, value);
|
|
@@ -3180,6 +3539,28 @@ static ScrDyn *scr_native_handle_iterator_next_call(ScrClosure *closure, ScrDyn
|
|
|
3180
3539
|
return scr_native_iterator_next_checked(4);
|
|
3181
3540
|
}
|
|
3182
3541
|
|
|
3542
|
+
bool scr_dyn_iterator_can_step(const ScrDyn *iterator, const ScrDyn *next) {
|
|
3543
|
+
if (iterator->kind != SCR_DYN_HANDLE || iterator->v.handle.tag != SCR_DYNH_ITERATOR) return false;
|
|
3544
|
+
unsigned kind = ((ScrNativeIterator *)iterator->v.handle.ptr)->kind;
|
|
3545
|
+
if (kind > 3) return false;
|
|
3546
|
+
size_t index = kind == 3 ? 8 : kind == 2 ? 7 : kind == 1 ? 5 : 0;
|
|
3547
|
+
return next == scr_iterator_functions[index];
|
|
3548
|
+
}
|
|
3549
|
+
|
|
3550
|
+
ScrDyn *scr_dyn_iterator_step(const ScrDyn *value) {
|
|
3551
|
+
ScrNativeIterator *iterator = value->v.handle.ptr;
|
|
3552
|
+
bool done = false;
|
|
3553
|
+
ScrDyn *item = scr_native_iterator_value(iterator, &done);
|
|
3554
|
+
/* Publish after getters finish, so recursive steps cannot overwrite this
|
|
3555
|
+
* step's completion. No user code runs between step and step_done. */
|
|
3556
|
+
iterator->step_done = done;
|
|
3557
|
+
return item;
|
|
3558
|
+
}
|
|
3559
|
+
|
|
3560
|
+
bool scr_dyn_iterator_step_done(const ScrDyn *value) {
|
|
3561
|
+
return ((ScrNativeIterator *)value->v.handle.ptr)->step_done;
|
|
3562
|
+
}
|
|
3563
|
+
|
|
3183
3564
|
static ScrDyn *scr_native_iterator_get(void *ptr, const char *key, size_t len) {
|
|
3184
3565
|
if (len != 4 || memcmp(key, "next", 4)) return NULL;
|
|
3185
3566
|
unsigned kind = ((ScrNativeIterator *)ptr)->kind;
|
|
@@ -3945,7 +4326,7 @@ ScrStr *scr_dyn_object_tag(const ScrDyn *d) {
|
|
|
3945
4326
|
case SCR_DYN_OBJ: tag = "[object Object]"; break;
|
|
3946
4327
|
case SCR_DYN_HANDLE:
|
|
3947
4328
|
if ((d->v.handle.tag >= SCR_DYNH_ABORT_SIGNAL &&
|
|
3948
|
-
d->v.handle.tag <= SCR_DYNH_ABORT_CONTROLLER) || d->v.handle.tag == SCR_DYNH_ARRAY_BUFFER ||
|
|
4329
|
+
d->v.handle.tag <= SCR_DYNH_ABORT_CONTROLLER) || d->v.handle.tag == SCR_DYNH_ARRAY_BUFFER || d->v.handle.tag == SCR_DYNH_SHARED_ARRAY_BUFFER ||
|
|
3949
4330
|
d->v.handle.tag == SCR_DYNH_WEAK_MAP || d->v.handle.tag == SCR_DYNH_WEAK_SET ||
|
|
3950
4331
|
d->v.handle.tag == SCR_DYNH_SET || d->v.handle.tag == SCR_DYNH_MAP || d->v.handle.tag == SCR_DYNH_REGEXP ||
|
|
3951
4332
|
d->v.handle.tag == SCR_DYNH_DATE) {
|
|
@@ -4438,7 +4819,7 @@ ScrStr *scr_dyn_to_string(const ScrDyn *d, const ScrStr *enc) {
|
|
|
4438
4819
|
return out;
|
|
4439
4820
|
}
|
|
4440
4821
|
if ((d->v.handle.tag >= SCR_DYNH_ABORT_SIGNAL &&
|
|
4441
|
-
d->v.handle.tag <= SCR_DYNH_ABORT_CONTROLLER) || d->v.handle.tag == SCR_DYNH_ARRAY_BUFFER || d->v.handle.tag == SCR_DYNH_SET || d->v.handle.tag == SCR_DYNH_MAP) {
|
|
4822
|
+
d->v.handle.tag <= SCR_DYNH_ABORT_CONTROLLER) || d->v.handle.tag == SCR_DYNH_ARRAY_BUFFER || d->v.handle.tag == SCR_DYNH_SHARED_ARRAY_BUFFER || d->v.handle.tag == SCR_DYNH_SET || d->v.handle.tag == SCR_DYNH_MAP) {
|
|
4442
4823
|
ScrJsonBuf b;
|
|
4443
4824
|
scr_jb_init(&b);
|
|
4444
4825
|
scr_jb_puts(&b, "[object ");
|
|
@@ -5483,10 +5864,7 @@ void scr_jb_put_dyn(ScrJsonBuf *b, const ScrDyn *d) {
|
|
|
5483
5864
|
if (e->value->kind == SCR_DYN_JSVAL && scr_dyn_isl_typeof_is(e->value, "function")) continue; /* engine functions drop too */
|
|
5484
5865
|
if (!first) scr_jb_putc(b, ',');
|
|
5485
5866
|
first = false;
|
|
5486
|
-
|
|
5487
|
-
ScrStr *k = scr_str_new(e->key, e->key_len);
|
|
5488
|
-
scr_jb_put_json_str(b, k);
|
|
5489
|
-
scr_str_release(k);
|
|
5867
|
+
scr_jb_put_json_span(b, e->key, e->key_len);
|
|
5490
5868
|
scr_jb_putc(b, ':');
|
|
5491
5869
|
scr_jb_put_dyn(b, e->value);
|
|
5492
5870
|
}
|
|
@@ -5647,8 +6025,10 @@ static int32_t scr_json_hex4(ScrJsonP *p) {
|
|
|
5647
6025
|
* slow path would produce) and returns -1. */
|
|
5648
6026
|
static int scr_json_string_span(ScrJsonP *p, const char **span,
|
|
5649
6027
|
size_t *span_len) {
|
|
5650
|
-
|
|
5651
|
-
|
|
6028
|
+
*span = p->s + p->pos + 1;
|
|
6029
|
+
*span_len = scr_json_plain_bytes(*span, p->len - p->pos - 1);
|
|
6030
|
+
size_t i = p->pos + 1 + *span_len;
|
|
6031
|
+
if (i < p->len) {
|
|
5652
6032
|
unsigned char c = (unsigned char)p->s[i];
|
|
5653
6033
|
if (c == '"') {
|
|
5654
6034
|
*span = p->s + p->pos + 1;
|
|
@@ -5661,7 +6041,6 @@ static int scr_json_string_span(ScrJsonP *p, const char **span,
|
|
|
5661
6041
|
scr_json_throw_pos("Bad control character in string literal", i);
|
|
5662
6042
|
return -1;
|
|
5663
6043
|
}
|
|
5664
|
-
i++;
|
|
5665
6044
|
}
|
|
5666
6045
|
scr_json_throw_pos("Unterminated string", p->pos);
|
|
5667
6046
|
return -1;
|
|
@@ -5669,11 +6048,13 @@ static int scr_json_string_span(ScrJsonP *p, const char **span,
|
|
|
5669
6048
|
|
|
5670
6049
|
/* Slow path: parses the string literal at p->pos (the opening quote),
|
|
5671
6050
|
* decoding escapes, into a +1 ScrStr. NULL on error (thrown). */
|
|
5672
|
-
static ScrStr *scr_json_string_slow(ScrJsonP *p) {
|
|
6051
|
+
static ScrStr *scr_json_string_slow(ScrJsonP *p, size_t prefix) {
|
|
5673
6052
|
size_t open = p->pos;
|
|
5674
6053
|
p->pos++; /* opening quote */
|
|
5675
6054
|
ScrJsonBuf b;
|
|
5676
6055
|
scr_jb_init(&b);
|
|
6056
|
+
scr_jb_write(&b, p->s + p->pos, prefix);
|
|
6057
|
+
p->pos += prefix;
|
|
5677
6058
|
for (;;) {
|
|
5678
6059
|
if (p->pos >= p->len) {
|
|
5679
6060
|
scr_jb_dispose(&b);
|
|
@@ -5691,8 +6072,9 @@ static ScrStr *scr_json_string_slow(ScrJsonP *p) {
|
|
|
5691
6072
|
return NULL;
|
|
5692
6073
|
}
|
|
5693
6074
|
if (c != '\\') {
|
|
5694
|
-
|
|
5695
|
-
p->pos
|
|
6075
|
+
size_t run = scr_json_plain_bytes(p->s + p->pos, p->len - p->pos);
|
|
6076
|
+
scr_jb_write(&b, p->s + p->pos, run);
|
|
6077
|
+
p->pos += run;
|
|
5696
6078
|
continue;
|
|
5697
6079
|
}
|
|
5698
6080
|
p->pos++; /* backslash */
|
|
@@ -5767,7 +6149,7 @@ static ScrStr *scr_json_string_scr(ScrJsonP *p) {
|
|
|
5767
6149
|
int r = scr_json_string_span(p, &span, &span_len);
|
|
5768
6150
|
if (r < 0) return NULL;
|
|
5769
6151
|
if (r > 0) return scr_str_new(span, span_len);
|
|
5770
|
-
return scr_json_string_slow(p);
|
|
6152
|
+
return scr_json_string_slow(p, span_len);
|
|
5771
6153
|
}
|
|
5772
6154
|
|
|
5773
6155
|
static ScrDyn *scr_json_value(ScrJsonP *p);
|
|
@@ -5846,20 +6228,17 @@ static ScrDyn *scr_json_number(ScrJsonP *p) {
|
|
|
5846
6228
|
}
|
|
5847
6229
|
exp10 += eneg ? -ev : ev;
|
|
5848
6230
|
}
|
|
5849
|
-
ScrDyn *d = scr_dyn_alloc(SCR_DYN_NUM);
|
|
5850
6231
|
if (precise && exp10 >= -22 && exp10 <= 22) {
|
|
5851
6232
|
double v = (double)mant; /* exact: mant < 10^15 < 2^53 */
|
|
5852
6233
|
if (exp10 > 0) v *= scr_json_pow10[exp10];
|
|
5853
6234
|
else if (exp10 < 0) v /= scr_json_pow10[-exp10];
|
|
5854
|
-
|
|
5855
|
-
return d;
|
|
6235
|
+
return scr_dyn_new_num(neg ? -v : v);
|
|
5856
6236
|
}
|
|
5857
6237
|
/* The validated span re-parses with strtod (correctly rounded, and the
|
|
5858
6238
|
* grammar above is a strict subset of what strtod accepts). The ScrStr
|
|
5859
6239
|
* data is NUL-terminated, and strtod stops at the first non-number char,
|
|
5860
6240
|
* so parsing from `start` reads exactly the validated token. */
|
|
5861
|
-
|
|
5862
|
-
return d;
|
|
6241
|
+
return scr_dyn_new_num(strtod(p->s + start, NULL));
|
|
5863
6242
|
}
|
|
5864
6243
|
|
|
5865
6244
|
static bool scr_json_lit(ScrJsonP *p, const char *word, size_t n) {
|
|
@@ -5926,10 +6305,12 @@ static ScrDyn *scr_json_object(ScrJsonP *p) {
|
|
|
5926
6305
|
scr_json_throw_pos("Expected property name or '}'", p->pos);
|
|
5927
6306
|
return NULL;
|
|
5928
6307
|
}
|
|
5929
|
-
/*
|
|
5930
|
-
*
|
|
6308
|
+
/* Keep the key borrowed until insertion determines whether it already
|
|
6309
|
+
* exists or can reuse a recycled slot. Escaped keys own their decoded
|
|
6310
|
+
* string until the value has been parsed and inserted. */
|
|
5931
6311
|
size_t key_len = 0;
|
|
5932
|
-
char *key;
|
|
6312
|
+
const char *key;
|
|
6313
|
+
ScrStr *decoded_key = NULL;
|
|
5933
6314
|
{
|
|
5934
6315
|
const char *span;
|
|
5935
6316
|
size_t span_len;
|
|
@@ -5939,27 +6320,21 @@ static ScrDyn *scr_json_object(ScrJsonP *p) {
|
|
|
5939
6320
|
return NULL;
|
|
5940
6321
|
}
|
|
5941
6322
|
if (r > 0) {
|
|
5942
|
-
key =
|
|
5943
|
-
if (!key) scr_json_oom();
|
|
5944
|
-
memcpy(key, span, span_len);
|
|
5945
|
-
key[span_len] = '\0';
|
|
6323
|
+
key = span;
|
|
5946
6324
|
key_len = span_len;
|
|
5947
6325
|
} else {
|
|
5948
|
-
|
|
5949
|
-
if (!
|
|
6326
|
+
decoded_key = scr_json_string_slow(p, span_len);
|
|
6327
|
+
if (!decoded_key) {
|
|
5950
6328
|
scr_dyn_release(obj);
|
|
5951
6329
|
return NULL;
|
|
5952
6330
|
}
|
|
5953
|
-
key =
|
|
5954
|
-
|
|
5955
|
-
memcpy(key, ks->data, ks->len + 1);
|
|
5956
|
-
key_len = ks->len;
|
|
5957
|
-
scr_str_release(ks);
|
|
6331
|
+
key = decoded_key->data;
|
|
6332
|
+
key_len = decoded_key->len;
|
|
5958
6333
|
}
|
|
5959
6334
|
}
|
|
5960
6335
|
scr_json_ws(p);
|
|
5961
6336
|
if (p->pos >= p->len || p->s[p->pos] != ':') {
|
|
5962
|
-
|
|
6337
|
+
scr_str_release(decoded_key);
|
|
5963
6338
|
scr_dyn_release(obj);
|
|
5964
6339
|
if (p->pos >= p->len) scr_json_throw("Unexpected end of JSON input");
|
|
5965
6340
|
else scr_json_throw_pos("Expected ':' after property name", p->pos);
|
|
@@ -5968,11 +6343,12 @@ static ScrDyn *scr_json_object(ScrJsonP *p) {
|
|
|
5968
6343
|
p->pos++; /* ':' */
|
|
5969
6344
|
ScrDyn *value = scr_json_value(p);
|
|
5970
6345
|
if (!value) {
|
|
5971
|
-
|
|
6346
|
+
scr_str_release(decoded_key);
|
|
5972
6347
|
scr_dyn_release(obj);
|
|
5973
6348
|
return NULL;
|
|
5974
6349
|
}
|
|
5975
6350
|
scr_dyn_obj_put(obj, key, key_len, value); /* later duplicate keys win */
|
|
6351
|
+
scr_str_release(decoded_key);
|
|
5976
6352
|
scr_json_ws(p);
|
|
5977
6353
|
if (p->pos >= p->len) {
|
|
5978
6354
|
scr_dyn_release(obj);
|
|
@@ -6121,7 +6497,12 @@ static void scr_json_delete_member(ScrDyn *object, const ScrStr *key) {
|
|
|
6121
6497
|
ScrDynEntry removed = *entry;
|
|
6122
6498
|
memmove(entry, entry + 1, (object->v.obj.len - i - 1) * sizeof *entry);
|
|
6123
6499
|
object->v.obj.len--;
|
|
6124
|
-
free(
|
|
6500
|
+
free(object->v.obj.index);
|
|
6501
|
+
object->v.obj.index = NULL;
|
|
6502
|
+
/* The moved tail aliases a live entry; spare slots own only their own
|
|
6503
|
+
* retained key bytes, never a second pointer to a surviving property. */
|
|
6504
|
+
memset(&object->v.obj.entries[object->v.obj.len], 0, sizeof *entry);
|
|
6505
|
+
scr_dyn_key_release(removed.key, removed.key_len);
|
|
6125
6506
|
scr_dyn_release(removed.value);
|
|
6126
6507
|
scr_dyn_release(removed.getter);
|
|
6127
6508
|
scr_dyn_release(removed.setter);
|
|
@@ -6324,8 +6705,71 @@ static bool scr_json_omitted(const ScrDyn *value) {
|
|
|
6324
6705
|
|
|
6325
6706
|
static void scr_json_gap(ScrJsonBuf *buffer, const ScrStr *gap, size_t depth) {
|
|
6326
6707
|
if (!gap->len) return;
|
|
6327
|
-
|
|
6328
|
-
|
|
6708
|
+
const char *end = memchr(gap->data, 0, gap->len);
|
|
6709
|
+
size_t length = end ? (size_t)(end - gap->data) : gap->len;
|
|
6710
|
+
scr_jb_indent(buffer, gap->data, length, depth);
|
|
6711
|
+
}
|
|
6712
|
+
|
|
6713
|
+
/* These primitive values cannot invoke toJSON or mutate a containing frame.
|
|
6714
|
+
* BigInts, functions and every reference kind keep the protocol walk. */
|
|
6715
|
+
static bool scr_json_plain_value(const ScrDyn *value) {
|
|
6716
|
+
switch (value->kind) {
|
|
6717
|
+
case SCR_DYN_NULL: case SCR_DYN_UNDEF: case SCR_DYN_SYMBOL:
|
|
6718
|
+
case SCR_DYN_BOOL: case SCR_DYN_NUM: case SCR_DYN_STR: return true;
|
|
6719
|
+
default: return false;
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
|
|
6723
|
+
/* Prove the whole immediate container before writing any of it. Without a
|
|
6724
|
+
* replacer or executable children, entries cannot change and borrowed names
|
|
6725
|
+
* need neither a key snapshot nor repeated lookups. Numeric property names
|
|
6726
|
+
* keep the ordinary sorted-key walk; sparse/accessor arrays keep Get. This
|
|
6727
|
+
* proof is repeated per call, so later mutations never leave a stale fact. */
|
|
6728
|
+
static bool scr_json_plain_container(const ScrDyn *value) {
|
|
6729
|
+
if (value->kind == SCR_DYN_ARR) {
|
|
6730
|
+
if (value->v.arr.presence || value->v.arr.properties) return false;
|
|
6731
|
+
for (size_t i = 0; i < value->v.arr.len; i++)
|
|
6732
|
+
if (!scr_json_plain_value(value->v.arr.items[i])) return false;
|
|
6733
|
+
return true;
|
|
6734
|
+
}
|
|
6735
|
+
if (value->kind != SCR_DYN_OBJ) return false;
|
|
6736
|
+
for (size_t i = 0; i < value->v.obj.len; i++) {
|
|
6737
|
+
const ScrDynEntry *entry = &value->v.obj.entries[i];
|
|
6738
|
+
if (!entry->enumerable) continue;
|
|
6739
|
+
double index;
|
|
6740
|
+
if (entry->accessor || !scr_json_plain_value(entry->value) ||
|
|
6741
|
+
scr_dyn_key_is_index(entry->key, entry->key_len, &index)) return false;
|
|
6742
|
+
}
|
|
6743
|
+
return true;
|
|
6744
|
+
}
|
|
6745
|
+
|
|
6746
|
+
static bool scr_json_plain_write(ScrJsonBuf *buffer, const ScrDyn *value,
|
|
6747
|
+
const ScrStr *gap, size_t depth) {
|
|
6748
|
+
bool array = value->kind == SCR_DYN_ARR;
|
|
6749
|
+
size_t length = array ? value->v.arr.len : value->v.obj.len;
|
|
6750
|
+
scr_jb_putc(buffer, array ? '[' : '{');
|
|
6751
|
+
bool first = true;
|
|
6752
|
+
for (size_t i = 0; i < length; i++) {
|
|
6753
|
+
const ScrDynEntry *entry = array ? NULL : &value->v.obj.entries[i];
|
|
6754
|
+
if (entry && !entry->enumerable) continue;
|
|
6755
|
+
const ScrDyn *child = array ? value->v.arr.items[i] : entry->value;
|
|
6756
|
+
bool omitted = scr_json_omitted(child);
|
|
6757
|
+
if (!array && omitted) continue;
|
|
6758
|
+
if (!omitted && !scr_json_callback_depth(depth + 1)) return false;
|
|
6759
|
+
if (!first) scr_jb_putc(buffer, ',');
|
|
6760
|
+
first = false;
|
|
6761
|
+
scr_json_gap(buffer, gap, depth + 1);
|
|
6762
|
+
if (entry) {
|
|
6763
|
+
scr_jb_put_json_span(buffer, entry->key, entry->key_len);
|
|
6764
|
+
scr_jb_putc(buffer, ':');
|
|
6765
|
+
if (gap->len) scr_jb_putc(buffer, ' ');
|
|
6766
|
+
}
|
|
6767
|
+
if (omitted) scr_jb_puts(buffer, "null");
|
|
6768
|
+
else scr_dyn_json_write(buffer, child);
|
|
6769
|
+
}
|
|
6770
|
+
if (!first) scr_json_gap(buffer, gap, depth);
|
|
6771
|
+
scr_jb_putc(buffer, array ? ']' : '}');
|
|
6772
|
+
return true;
|
|
6329
6773
|
}
|
|
6330
6774
|
|
|
6331
6775
|
static bool scr_json_replaced_write(ScrJsonBuf *buffer, const ScrDyn *value,
|
|
@@ -6334,6 +6778,8 @@ static bool scr_json_replaced_write(ScrJsonBuf *buffer, const ScrDyn *value,
|
|
|
6334
6778
|
ScrDyn *view = value->kind == SCR_DYN_TYPED_REF ? scr_dyn_typed_ref_materialize(value) : NULL;
|
|
6335
6779
|
const ScrDyn *observed = view ? view : value;
|
|
6336
6780
|
if (scr_exc_pending()) { scr_dyn_release(view); return false; }
|
|
6781
|
+
if (!view && replacer->kind == SCR_DYN_UNDEF && scr_json_plain_container(value))
|
|
6782
|
+
return scr_json_plain_write(buffer, value, gap, depth);
|
|
6337
6783
|
if (observed->kind != SCR_DYN_OBJ && observed->kind != SCR_DYN_ARR && observed->kind != SCR_DYN_BYTES) {
|
|
6338
6784
|
/* Engine objects need an engine callback bridge, not an opaque JSON
|
|
6339
6785
|
* splice: that would silently skip all their children. */
|
|
@@ -6824,9 +7270,8 @@ static ScrDyn *scr_dyn_obj_read_receiver(const ScrDyn *d, const char *key, size_
|
|
|
6824
7270
|
continue;
|
|
6825
7271
|
}
|
|
6826
7272
|
if (current->kind != SCR_DYN_OBJ) continue;
|
|
6827
|
-
|
|
6828
|
-
|
|
6829
|
-
if (entry->key_len != key_len || memcmp(entry->key, key, key_len) != 0) continue;
|
|
7273
|
+
ScrDynEntry *entry = scr_dyn_find_entry(current, key, key_len);
|
|
7274
|
+
if (entry) {
|
|
6830
7275
|
if (!entry->accessor) return scr_dyn_retain(entry->value);
|
|
6831
7276
|
if (!entry->getter) return scr_dyn_retain(scr_dyn_undefined());
|
|
6832
7277
|
ScrDyn *getter = scr_dyn_retain(entry->getter);
|
|
@@ -7094,15 +7539,9 @@ bool scr_dyn_reflect_set(ScrDyn *target, ScrDyn *raw_key, ScrDyn *value, ScrDyn
|
|
|
7094
7539
|
|
|
7095
7540
|
/* The array-index test (ECMA: a canonical numeric string < 2^32-1). */
|
|
7096
7541
|
static bool scr_dyn_key_is_index(const char *key, size_t len, double *out) {
|
|
7097
|
-
|
|
7098
|
-
if (key
|
|
7099
|
-
|
|
7100
|
-
for (size_t i = 0; i < len; i++) {
|
|
7101
|
-
if (key[i] < '0' || key[i] > '9') return false;
|
|
7102
|
-
v = v * 10 + (key[i] - '0');
|
|
7103
|
-
}
|
|
7104
|
-
if (v > 4294967294.0) return false;
|
|
7105
|
-
*out = v;
|
|
7542
|
+
uint32_t index;
|
|
7543
|
+
if (!scr_key_array_index(key, len, &index)) return false;
|
|
7544
|
+
*out = index;
|
|
7106
7545
|
return true;
|
|
7107
7546
|
}
|
|
7108
7547
|
|
|
@@ -7120,34 +7559,31 @@ static ScrDyn *scr_dyn_objwalk_key(const char *key, size_t key_len) {
|
|
|
7120
7559
|
ScrDyn *scr_dyn_obj_own_keys(const ScrDyn *v) {
|
|
7121
7560
|
size_t n = v->v.obj.len;
|
|
7122
7561
|
ScrDyn *keys = scr_dyn_new_arr();
|
|
7123
|
-
|
|
7124
|
-
|
|
7125
|
-
if (!is_index || !idx) scr_trap("scriptc: out of memory\n");
|
|
7126
|
-
size_t index_count = 0;
|
|
7562
|
+
ScrKeyIndex *indices = NULL;
|
|
7563
|
+
size_t count = 0;
|
|
7127
7564
|
for (size_t i = 0; i < n; i++) {
|
|
7128
|
-
const ScrDynEntry *
|
|
7129
|
-
|
|
7130
|
-
if (
|
|
7131
|
-
|
|
7132
|
-
|
|
7133
|
-
|
|
7134
|
-
|
|
7135
|
-
|
|
7136
|
-
|
|
7137
|
-
|
|
7138
|
-
|
|
7139
|
-
|
|
7140
|
-
|
|
7141
|
-
scr_dyn_arr_push(keys, scr_dyn_objwalk_key(
|
|
7142
|
-
|
|
7143
|
-
|
|
7565
|
+
const ScrDynEntry *entry = &v->v.obj.entries[i];
|
|
7566
|
+
uint32_t index;
|
|
7567
|
+
if (!scr_key_array_index(entry->key, entry->key_len, &index)) continue;
|
|
7568
|
+
if (!indices) {
|
|
7569
|
+
if (n > SIZE_MAX / sizeof *indices) scr_json_oom();
|
|
7570
|
+
indices = malloc(n * sizeof *indices);
|
|
7571
|
+
if (!indices) scr_json_oom();
|
|
7572
|
+
}
|
|
7573
|
+
indices[count++] = (ScrKeyIndex){index, i};
|
|
7574
|
+
}
|
|
7575
|
+
scr_key_index_sort(indices, count);
|
|
7576
|
+
for (size_t i = 0; i < count; i++) {
|
|
7577
|
+
const ScrDynEntry *entry = &v->v.obj.entries[indices[i].entry];
|
|
7578
|
+
scr_dyn_arr_push(keys, scr_dyn_objwalk_key(entry->key, entry->key_len));
|
|
7579
|
+
}
|
|
7580
|
+
free(indices);
|
|
7144
7581
|
for (size_t i = 0; i < n; i++) {
|
|
7145
|
-
|
|
7146
|
-
|
|
7147
|
-
|
|
7582
|
+
const ScrDynEntry *entry = &v->v.obj.entries[i];
|
|
7583
|
+
uint32_t index;
|
|
7584
|
+
if (!scr_key_array_index(entry->key, entry->key_len, &index))
|
|
7585
|
+
scr_dyn_arr_push(keys, scr_dyn_objwalk_key(entry->key, entry->key_len));
|
|
7148
7586
|
}
|
|
7149
|
-
free(is_index);
|
|
7150
|
-
free(idx);
|
|
7151
7587
|
return keys;
|
|
7152
7588
|
}
|
|
7153
7589
|
|
|
@@ -8310,6 +8746,14 @@ bool scr_array_buffer_is(const ScrDyn *value) {
|
|
|
8310
8746
|
return value->kind == SCR_DYN_HANDLE && value->v.handle.tag == SCR_DYNH_ARRAY_BUFFER;
|
|
8311
8747
|
}
|
|
8312
8748
|
|
|
8749
|
+
bool scr_shared_array_buffer_is(const ScrDyn *value) {
|
|
8750
|
+
return value->kind == SCR_DYN_HANDLE && value->v.handle.tag == SCR_DYNH_SHARED_ARRAY_BUFFER;
|
|
8751
|
+
}
|
|
8752
|
+
|
|
8753
|
+
bool scr_buffer_storage_is(const ScrDyn *value) {
|
|
8754
|
+
return scr_array_buffer_is(value) || scr_shared_array_buffer_is(value);
|
|
8755
|
+
}
|
|
8756
|
+
|
|
8313
8757
|
bool scr_array_buffer_is_view(const ScrDyn *value) {
|
|
8314
8758
|
return value->kind == SCR_DYN_BYTES;
|
|
8315
8759
|
}
|
|
@@ -8318,8 +8762,9 @@ static ScrDyn *scr_array_buffer_get(void *h, const char *key, size_t len) {
|
|
|
8318
8762
|
if ((len == 10 && memcmp(key, "byteLength", len) == 0) ||
|
|
8319
8763
|
(len == 13 && memcmp(key, "maxByteLength", len) == 0))
|
|
8320
8764
|
return scr_dyn_new_num(scr_bytes_byte_len(h));
|
|
8321
|
-
if (
|
|
8322
|
-
|
|
8765
|
+
if (len == 8 && !memcmp(key, "growable", len) && ((ScrBytes *)h)->shared) return scr_dyn_new_bool(false);
|
|
8766
|
+
if (!((ScrBytes *)h)->shared && ((len == 9 && memcmp(key, "resizable", len) == 0) ||
|
|
8767
|
+
(len == 8 && memcmp(key, "detached", len) == 0))) return scr_dyn_new_bool(false);
|
|
8323
8768
|
return NULL;
|
|
8324
8769
|
}
|
|
8325
8770
|
|
|
@@ -8338,6 +8783,7 @@ static ScrDyn *scr_array_buffer_invoke(void *h, ScrDyn *self, const char *method
|
|
|
8338
8783
|
ScrBytes *view = scr_bytes_buffer_view(h, SCR_BYTES_U8, 0, false, 0);
|
|
8339
8784
|
if (!view) return NULL;
|
|
8340
8785
|
ScrBytes *copy = scr_bytes_slice(view, start, end);
|
|
8786
|
+
if (((ScrBytes *)h)->shared) scr_bytes_make_shared(copy);
|
|
8341
8787
|
scr_bytes_release(view);
|
|
8342
8788
|
ScrDyn *result = scr_array_buffer_from_bytes(copy);
|
|
8343
8789
|
scr_bytes_release(copy);
|
|
@@ -8353,8 +8799,13 @@ ScrDyn *scr_array_buffer_from_bytes(ScrBytes *view) {
|
|
|
8353
8799
|
"ArrayBuffer", &scr_bytes_retain_v, &scr_bytes_release_v,
|
|
8354
8800
|
&scr_array_buffer_invoke, &scr_array_buffer_get, &scr_array_buffer_set, NULL,
|
|
8355
8801
|
};
|
|
8356
|
-
|
|
8357
|
-
|
|
8802
|
+
static const ScrDynHandleOps shared_ops = {
|
|
8803
|
+
"SharedArrayBuffer", &scr_bytes_retain_v, &scr_bytes_release_v,
|
|
8804
|
+
&scr_array_buffer_invoke, &scr_array_buffer_get, &scr_array_buffer_set, NULL,
|
|
8805
|
+
};
|
|
8806
|
+
ScrDynHandleTag tag = view->shared ? SCR_DYNH_SHARED_ARRAY_BUFFER : SCR_DYNH_ARRAY_BUFFER;
|
|
8807
|
+
scr_dyn_handle_install(tag, view->shared ? &shared_ops : &ops);
|
|
8808
|
+
return scr_dyn_new_handle(view->backing ? view->backing : view, tag);
|
|
8358
8809
|
}
|
|
8359
8810
|
|
|
8360
8811
|
static ScrDyn *scr_ffi_fail(const char *message) {
|
|
@@ -8385,7 +8836,8 @@ ScrDyn *scr_ffi_argument(ScrDyn *value, ScrStr *type) {
|
|
|
8385
8836
|
void *address = NULL;
|
|
8386
8837
|
bool converted = value->kind == SCR_DYN_NULL || value->kind == SCR_DYN_UNDEF;
|
|
8387
8838
|
ScrBytes *bytes = value->kind == SCR_DYN_BYTES ? value->v.bytes :
|
|
8388
|
-
|
|
8839
|
+
scr_buffer_storage_is(value) ? value->v.handle.ptr : NULL;
|
|
8840
|
+
if (bytes && bytes->shared) return scr_ffi_fail("Shared byte storage cannot expose an unmanaged native pointer");
|
|
8389
8841
|
if (bytes) { address = bytes->data; converted = true; }
|
|
8390
8842
|
if (value->kind == SCR_DYN_STR) {
|
|
8391
8843
|
if (memchr(value->v.str->data, 0, value->v.str->len)) {
|
|
@@ -8635,6 +9087,7 @@ static ScrDyn *scr_ffi_memory_call(ScrClosure *closure, ScrDyn *const *args, siz
|
|
|
8635
9087
|
scr_dyn_arg_type_fail("source", "an ArrayBuffer or ArrayBufferView", value);
|
|
8636
9088
|
return NULL;
|
|
8637
9089
|
}
|
|
9090
|
+
if (bytes->shared) return scr_ffi_fail("Shared byte storage cannot expose an unmanaged native pointer");
|
|
8638
9091
|
ScrBigInt *pointer = scr_bigint_from_pointer(bytes->data);
|
|
8639
9092
|
ScrDyn *result = scr_dyn_new_bigint(pointer);
|
|
8640
9093
|
scr_bigint_release(pointer);
|
|
@@ -8822,7 +9275,7 @@ static int scr_weak_key(const ScrDyn *key, void **ptr, unsigned *kind) {
|
|
|
8822
9275
|
*ptr = key->v.fn.class_obj ? (void *)key->v.fn.class_obj : (void *)key->v.fn.clo;
|
|
8823
9276
|
*kind = key->v.fn.class_obj ? 3 : 2; return 1;
|
|
8824
9277
|
case SCR_DYN_HANDLE:
|
|
8825
|
-
if (key->v.handle.tag != SCR_DYNH_ARRAY_BUFFER && key->v.handle.tag != SCR_DYNH_WEAK_MAP &&
|
|
9278
|
+
if (key->v.handle.tag != SCR_DYNH_ARRAY_BUFFER && key->v.handle.tag != SCR_DYNH_SHARED_ARRAY_BUFFER && key->v.handle.tag != SCR_DYNH_WEAK_MAP &&
|
|
8826
9279
|
key->v.handle.tag != SCR_DYNH_WEAK_SET && key->v.handle.tag != SCR_DYNH_STDIO &&
|
|
8827
9280
|
key->v.handle.tag != SCR_DYNH_FETCH_REQUEST && key->v.handle.tag != SCR_DYNH_FETCH_RESPONSE &&
|
|
8828
9281
|
key->v.handle.tag != SCR_DYNH_MAP && key->v.handle.tag != SCR_DYNH_SET) return -1;
|
|
@@ -9053,6 +9506,16 @@ ScrDyn *scr_array_buffer_new(ScrDyn *length) {
|
|
|
9053
9506
|
return result;
|
|
9054
9507
|
}
|
|
9055
9508
|
|
|
9509
|
+
ScrDyn *scr_shared_array_buffer_new(ScrDyn *length) {
|
|
9510
|
+
ScrDyn *buffer = scr_array_buffer_new(length);
|
|
9511
|
+
if (!buffer) return NULL;
|
|
9512
|
+
ScrBytes *storage = buffer->v.handle.ptr;
|
|
9513
|
+
scr_bytes_make_shared(storage);
|
|
9514
|
+
ScrDyn *result = scr_array_buffer_from_bytes(storage);
|
|
9515
|
+
scr_dyn_release(buffer);
|
|
9516
|
+
return result;
|
|
9517
|
+
}
|
|
9518
|
+
|
|
9056
9519
|
double scr_array_buffer_byte_length_getter(void) {
|
|
9057
9520
|
ScrDyn *receiver = scr_dyn_this_get();
|
|
9058
9521
|
if (!scr_array_buffer_is(receiver)) {
|
|
@@ -9079,7 +9542,7 @@ ScrDyn *scr_array_buffer_byte_length_descriptor(ScrDyn *getter) {
|
|
|
9079
9542
|
|
|
9080
9543
|
ScrBytes *scr_array_buffer_view(ScrBytesElem elem, const ScrDyn *buffer,
|
|
9081
9544
|
const ScrDyn *offset, const ScrDyn *length) {
|
|
9082
|
-
if (!
|
|
9545
|
+
if (!scr_buffer_storage_is(buffer)) {
|
|
9083
9546
|
// Non-buffer inputs use the length/iterable/array-like constructor.
|
|
9084
9547
|
// Their extra arguments are evaluated by the caller, but not coerced.
|
|
9085
9548
|
return scr_bytes_from_dyn(elem, buffer, false);
|
|
@@ -9114,7 +9577,7 @@ SCR_ARRAY_BUFFER_VIEW(f64, SCR_BYTES_F64)
|
|
|
9114
9577
|
#undef SCR_ARRAY_BUFFER_VIEW
|
|
9115
9578
|
|
|
9116
9579
|
ScrBytes *scr_array_buffer_view_dv(ScrDyn *buffer, ScrDyn *offset, ScrDyn *length) {
|
|
9117
|
-
if (!
|
|
9580
|
+
if (!scr_buffer_storage_is(buffer)) {
|
|
9118
9581
|
static const char msg[] = "First argument to DataView constructor must be an ArrayBuffer";
|
|
9119
9582
|
scr_throw_error_msg(SCR_ERR_TYPE, msg, sizeof msg - 1);
|
|
9120
9583
|
return NULL;
|