Skip to content

Commit

Permalink
Merge pull request #1087 from neon-bindings/kv/jsbox-lifetime
Browse files Browse the repository at this point in the history
feat(neon): Allow getting a `&'cx T` from a `Handle<'cx, JsBox<T>>`
  • Loading branch information
kjvalencik authored Jan 13, 2025
2 parents efba683 + c0f0442 commit e996288
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ jobs:
- name: npm install
run: npm ci --prefer-offline --no-audit --no-fund

- name: Allow unprivileged X server
if: matrix.os == 'ubuntu-latest'
run: sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0

- name: Test (Linux)
if: matrix.os == 'ubuntu-latest'
run: xvfb-run --auto-servernum npm test -- --nocapture
Expand Down
31 changes: 29 additions & 2 deletions crates/neon/src/types_impl/boxed.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,12 +259,39 @@ impl<T: Finalize + 'static> JsBox<T> {
}
}

impl<T: 'static> JsBox<T> {
/// Gets a reference to the inner value of a [`JsBox`]. This method is similar to
/// [dereferencing](JsBox::deref) a `JsBox` (e.g., `&*boxed`), but the lifetime
/// is _safely_ extended to `'cx`.
///
/// See also [`Handle<JsBox>::as_inner`].
// N.B.: This would be cleaner with https://github.com/rust-lang/rust/issues/44874
pub fn deref<'cx>(v: &Handle<'cx, Self>) -> &'cx T {
v.as_inner()
}
}

impl<'cx, T: 'static> Handle<'cx, JsBox<T>> {
/// Gets a reference to the inner value of a [`JsBox`]. This method is similar to
/// [dereferencing](JsBox::deref) a `JsBox` (e.g., `&*boxed`), but the lifetime
/// is _safely_ extended to `'cx`.
///
/// See also [`JsBox::deref`].
pub fn as_inner(&self) -> &'cx T {
// # Safety
// JS values associated with an in-scope `Context` *cannot* be garbage collected.
// This value is guaranteed to live at least as long as `'cx`.
unsafe { &*self.0.raw_data }
}
}

impl<T: 'static> Deref for JsBox<T> {
type Target = T;

fn deref(&self) -> &Self::Target {
// Safety: This depends on a `Handle<'a, JsBox<T>>` wrapper to provide
// a proper lifetime.
// # Safety
// `T` will live at least as long as `JsBox<T>` because it may not be garbage
// collected while in scope and only immutable references can be obtained.
unsafe { &*self.0.raw_data }
}
}
Expand Down

0 comments on commit e996288

Please sign in to comment.