|
146 | 146 | //! [iterator]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators |
147 | 147 | //! [question-mark]: https://doc.rust-lang.org/edition-guide/rust-2018/error-handling-and-panics/the-question-mark-operator-for-easier-error-handling.html |
148 | 148 |
|
| 149 | +#[cfg(feature = "napi-1")] |
| 150 | +pub mod ffi; |
149 | 151 | pub(crate) mod internal; |
150 | 152 |
|
151 | 153 | use crate::borrow::internal::Ledger; |
@@ -181,6 +183,8 @@ use std::marker::PhantomData; |
181 | 183 | use std::os::raw::c_void; |
182 | 184 | use std::panic::UnwindSafe; |
183 | 185 |
|
| 186 | +#[cfg(feature = "napi-1")] |
| 187 | +use self::ffi::RawEnv; |
184 | 188 | use self::internal::{ContextInternal, Scope, ScopeMetadata}; |
185 | 189 |
|
186 | 190 | #[repr(C)] |
@@ -294,10 +298,21 @@ impl<'a> Lock<'a> { |
294 | 298 | /// |
295 | 299 | /// A context has a lifetime `'a`, which ensures the safety of handles managed by the JS garbage collector. All handles created during the lifetime of a context are kept alive for that duration and cannot outlive the context. |
296 | 300 | pub trait Context<'a>: ContextInternal<'a> { |
297 | | - /// Get the underlying `napi-env` of the context |
| 301 | + /// Gets the underlying env handle of the context |
| 302 | + /// |
| 303 | + /// RawEnv is an opaque C struct, so `&mut RawEnv` is allowed to be converted to a `*mut void`, passed |
| 304 | + /// across FFI boundaries, and converted back to `&mut RawEnv`. |
298 | 305 | #[cfg(feature = "napi-1")] |
299 | | - fn as_mut_ptr(&mut self) -> *mut c_void { |
300 | | - self.env().to_raw() as *mut c_void |
| 306 | + fn with_raw_env<T, F>(&mut self, f: F) -> T |
| 307 | + where |
| 308 | + F: for<'b> FnOnce(&'b mut RawEnv) -> T, |
| 309 | + { |
| 310 | + self.check_active(); |
| 311 | + self.deactivate(); |
| 312 | + let raw_env = unsafe { &mut *(self.env().to_raw().cast::<RawEnv>()) }; |
| 313 | + let result = f(raw_env); |
| 314 | + self.activate(); |
| 315 | + result |
301 | 316 | } |
302 | 317 |
|
303 | 318 | /// Lock the JavaScript engine, returning an RAII guard that keeps the lock active as long as the guard is alive. |
@@ -824,20 +839,7 @@ impl<'a> TaskContext<'a> { |
824 | 839 | Scope::with(env, |scope| f(TaskContext { scope })) |
825 | 840 | } |
826 | 841 |
|
827 | | - /// Constructs a context from a raw pointer. |
828 | | - /// |
829 | | - /// # Safety |
830 | | - /// The raw pointer `env` must be a `napi_env` that remains valid during the call of this method. |
831 | | - #[cfg(feature = "napi-1")] |
832 | | - pub unsafe fn with_raw_env<T, F: for<'b> FnOnce(TaskContext<'b>) -> T>( |
833 | | - env: *mut c_void, |
834 | | - f: F, |
835 | | - ) -> T { |
836 | | - let env = std::mem::transmute(env); |
837 | | - Self::with_context(env, f) |
838 | | - } |
839 | | - |
840 | | - #[cfg(feature = "napi-1")] |
| 842 | + #[cfg(all(feature = "napi-4", feature = "channel-api"))] |
841 | 843 | pub(crate) fn with_context<T, F: for<'b> FnOnce(TaskContext<'b>) -> T>(env: Env, f: F) -> T { |
842 | 844 | Scope::with(env, |scope| f(TaskContext { scope })) |
843 | 845 | } |
|
0 commit comments