This ensures that provided extensions are all correctly setup and ready to use once the JsRuntime constructor returns
Note: this will also initialize ops for to-be-snapshotted runtimes
Extensions allow declarative extensions to "JsRuntime" (ops, state, JS or middleware).
This allows for:
- `op_crates` to be plug-and-play & self-contained, reducing complexity leaked to consumers
- op middleware (like metrics_op) to be opt-in and for new middleware (unstable, tracing,...)
- `MainWorker` and `WebWorker` to be composable, allowing users to extend workers with their ops whilst benefiting from the other infrastructure (inspector, etc...)
In short extensions improve deno's modularity, reducing complexity and leaky abstractions for embedders and the internal codebase.
General cleanup of module loading code, tried to reduce indentation in various methods
on "JsRuntime" to improve readability.
Added "JsRuntime::handle_scope" helper function, which returns a "v8::HandleScope".
This was done to reduce a code pattern that happens all over the "deno_core".
Additionally if event loop hangs during loading of dynamic modules a list of
currently pending dynamic imports is printed.
`InvalidDNSNameError` is thrown when a string is not a valid hostname,
e.g. it contains invalid characters, or starts with a numeric digit. It
does not involve a (failed) DNS lookup.
Even if bootstrapping the JS runtime is low level, it's an abstraction leak of
core to require users to call `Deno.core.ops()` in JS space.
So instead we're introducing a `JsRuntime::sync_ops_cache()` method,
once we have runtime extensions a new runtime will ensure the ops
cache is setup (for the provided extensions) and then loading/unloading
plugins should be the only operations that require op cache syncs
- register builtin v8 errors in core.js so consumers don't have to
- remove complexity of error args handling (consumers must provide a
constructor with custom args, core simply provides msg arg)
`init()` was previously needed to init the shared queue, but now that it's
gone `init()` only registers the async msg handler which is snapshot
safe and constant since the op layer refactor.
Also cleanup `bindings::deserialize()/decode()` so they
use the `ZeroCopyBuf` abstraction rather than reimplementing it.
This cleanup will facilitate moving `ZeroCopyBuf` to `serde_v8`
since it's now self contained and there are no other
`get_backing_store_slice()` callers.
This commit replaces GothamState's internal HashMap
with a BTreeMap to improve performance.
OpState/GothamState keys by TypeId which is essentially
an opaque u64. For small sets of integer keys BTreeMap
outperforms HashMap mainly since it removes the hashing
overhead and Eq/Comp on integer-like types is very cheap,
it should also have a smaller memory footprint.
We only use ~30 unique types and thus ~30 unique keys to
access OpState, so the keyset is small and immutable
throughout the life of a JsRuntime, there's no meaningful
churn in keys added/removed.
This is another optimization to help improve the baseline overhead
of async ops. It shaves off ~55ns/op or ~7% of the current total
async op overhead.
It achieves these gains by taking advantage of the sequential
nature of promise IDs and optimistically stores them sequentially
in a pre-allocated circular buffer and fallbacks to the promise Map
for slow to resolve promises.
- Improves op performance.
- Handle op-metadata (errors, promise IDs) explicitly in the op-layer vs
per op-encoding (aka: out-of-payload).
- Remove shared queue & custom "asyncHandlers", all async values are
returned in batches via js_recv_cb.
- The op-layer should be thought of as simple function calls with little
indirection or translation besides the conceptually straightforward
serde_v8 bijections.
- Preserve concepts of json/bin/min as semantic groups of their
inputs/outputs instead of their op-encoding strategy, preserving these
groups will also facilitate partial transitions over to v8 Fast API for the
"min" and "bin" groups
This commit moves implementation of bin ops to "deno_core" crates
as well as unifying logic between bin ops and json ops to reuse
as much code as possible (both in Rust and JavaScript).
This commit rewrites "dispatch_minimal" into "dispatch_buffer".
It's part of an effort to unify JS interface for ops for both json
and minimal (buffer) ops.
Before this commit "minimal ops" could be either sync or async
depending on the return type from the op, but this commit changes
it to have separate signatures for sync and async ops (just like
in case of json ops).
In case JavaScript throws an unhandled error, part of the "shared_queue" could
be still unprocessed.
If this is the case; throw the js runtime error instead of asserting on the
queue size not being 0.
This commit rewrites implementation of "JsRuntime::mod_evaluate".
Event loop is no longer polled automatically and users must manually
drive event loop forward after calling "mod_evaluate".
Co-authored-by: Nayeem Rahman <nayeemrmn99@gmail.com>
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
This commit rewrites "JsRuntime::poll" function to fix a corner case that
might caused "overflown_response" to be overwritten by other overflown response.
The logic has been changed to allow returning multiple overflown response
alongside responses from shared queue.
This commit adds two new "Deno.core" APIs:
- "Deno.core.serialize"
- "Deno.core.deserialize"
These APIs are used to provide structured cloning of values
and will be used for further web worker implementation.
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>