The pointer returned by `ArrayBuffer::data` might be null if the
backing store has zero length, but the return type `*mut c_void` does
not force the user to consider this case. This change makes the return
type `Option<NonNull<c_void>>`, which is semantically equivalent, but
which forces users of the API to handle the `None` case.
This PR is the `ArrayBuffer` counterpart to #817.
This is a breaking API change.
This method, introduced in V8 10.9, makes it so an `ArrayBuffer`
object is impossible to detach unless a specific detach key is passed
to the `detach` method. Such `ArrayBuffer`s still count as detachable
as per the `ArrayBuffer::is_detachable` method, but otherwise behave
much like WebAssembly memories.
This commit adds "v8::Module::get_stalled_top_level_await_message" API
that allows to retrieve a vector of tuples with handles to v8::Module and v8::Message.
This information can be used to display a nice error when event loop runs out
of work to do but there are still unresolved promises.
This commit adds "v8::Isolate::snapshot_creator_from_existing_snapshot" API,
that allows to create a new snapshot from already existing snapshot.
Following APIs were added as well:
"v8::Context::from_snapshot"
"v8::Isolate::add_context"
Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.com>
Co-authored-by: Bert Belder <bertbelder@gmail.com>
This commit removes "v8::SnapshotCreator" in favor of
"v8::Isolate::snapshot_creator" API. All methods from
"v8::SnapshotCreator" are now available on the "v8::Isolate".
If a method is called and isolate was not set up as a snapshot
creator then it will panic.
This commit gets rid of long standing unsoundness in typing
that allowed to easily induce a panic or segfault if a user didn't
use snapshot creator API properly.
Check that it actually performs the expected operation (adding two
numbers) because it didn't - the callback's function prototype was
wrong. V8 always passes the receiver object as the first parameter.
Currently, when a finalizer callback is registered, it is not
guaranteed to be called if there is a global reference to the
corresponding object that survives the isolate. This is because the
finalizer callback takes a `&mut Isolate`, and so it must be called
before the isolate is fully destroyed, but all existing globals
(including possibly the one being currently finalized) are still
usable while there still exists a mutable reference to the isolate.
However, there are still use cases for having finalizers that are
guaranteed to run regardless of any remaining globals, but that don't
require any interaction with the isolate. This change adds them.
This change also changes the context annex to use a guaranteed
finalizer, fixing a bug with context slots not being freed if there
were any globals to the context at the time the isolate is dropped.
property_attribute previously had an addition operator overload which
doesn't make much sense in comparison to the corresponding V8
enumeration. This changes that to a bitor overload.
Signed-off-by: Darshan Sen <raisinten@gmail.com>
This change allows the customization of the behavior of
v8::Object::GetOwnPropertyNames() and v8::Object::GetPropertyNames() by
accepting all the options that the raw V8 API supports.
Signed-off-by: Darshan Sen <raisinten@gmail.com>
This change adds support for weak handles that don't prevent GC of the
referenced objects, through the `v8::Weak<T>` API. A weak handle can
be empty (if it was created empty or its object was GC'd) or
non-empty, and if non-empty it allows getting its object as a global
or local.
When creating a `v8::Weak` you can also set a finalizer that will be
called at some point after the object is GC'd, as long as the weak
handle is still alive at that point. This finalization corresponds to
the second-pass callback in `kParameter` mode in the C++ API, so it
will only be called after the object is GC'd. The finalizer function
is a `FnOnce` that may close over data, and which takes a
`&mut Isolate` as an argument.
The C++ finalization API doesn't guarantee _when_ or even _if_ the
finalizer will ever be called, but in order to prevent memory leaks,
the rusty_v8 wrapper ensures that it will be called at some point,
even if it's just before the isolate gets dropped.
`v8::Weak<T>` implements `Clone`, but a finalizer is tied to a single
weak handle, so its clones won't be able to keep the finalizer alive.
And in fact, cloning will create a new weak handle that isn't tied to
a finalizer at all. `v8::Weak::clone_with_finalizer` can be used to
make a clone of a weak handle which has a finalizer tied to it.
Note that `v8::Weak<T>` doesn't implement `Hash`, because the hash
would have to change once the handle's object is GC'd, which is a big
gotcha and would break some of the algorithms that rely on hashes,
such as the Rust std's `HashMap`.
This fixes in a segmentation fault when dropping a `BackingStore`
constructed through `ArrayBuffer::new_backing_store_from_boxed_slice()`
from an empty slice, since zero length boxed slices are invalid
(dangling) pointers, while Rust expects a `Box<c_void>` to always be a
valid pointer.
Fixes: #849
This patch includes a test for this issue.
The V8 patch is intentionally left simple to avoid merge conflicts in
the future. To be landed upstream, the `unwindinfo_use_count_` would
probably have to be made non-atomic and we'd have to add a cctest.
Upstream bug: https://bugs.chromium.org/p/v8/issues/detail?id=12393
Fixes: #714
The pointer returned by `BackingStore::data` might be null if the
backing store has zero length, but the return type `*mut c_void` does
not force the user to consider this case. This change makes the return
type `Option<NonNull<c_void>>`, which is semantically equivalent, but
which forces users of the API to handle the `None` case.
This is a breaking API change.
For zero-size `BackingStore`s, it seems like `BackingStore::data` always
returns a null pointer. The `Deref` impl for `BackingStore` called
`std::slice::from_raw_parts` on that pointer, even though it is UB to
call that function on a null pointer even for empty slices. This change
fixes that by obtaining a valid pointer from `NonNull::dangling()` if
the original is null.
Reported in
https://github.com/denoland/rusty_v8/issues/711#issuecomment-950637136.
Best case, it produces serialized output that cannot be deserialized.
Worst case, it hits this assert in V8:
# Fatal error in v8::FromJust
# Maybe value is Nothing.
Serializing `new String("")` requires that the wire format header is
written, otherwise V8 assumes an incompatible legacy wire format when
deserializing.
The test started a new thread that slept for a bit, then terminated the
isolate, assuming that the delay was long enough for the isolate and the
context to get fully initialized. It wasn't.
Fixes #710.