From 5b6a03d70a001f5b482d5be9cf45d89b4e5e1b38 Mon Sep 17 00:00:00 2001 From: delskayn Date: Mon, 5 Jun 2023 09:32:46 +0200 Subject: [PATCH] Fixed minor safety issue, added `AsyncContext::with` function --- core/src/context/async.rs | 22 +++++++++++++++++----- core/src/runtime/async.rs | 5 +---- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/core/src/context/async.rs b/core/src/context/async.rs index 96f6a857..8f2f3f30 100644 --- a/core/src/context/async.rs +++ b/core/src/context/async.rs @@ -207,10 +207,6 @@ impl AsyncContext { } /// A entry point for manipulating and using javascript objects and scripts. - /// The api is structured this way to avoid repeated locking the runtime when ever - /// any function is called. This way the runtime is locked once before executing the callback. - /// Furthermore, this way it is impossible to use values from different runtimes in this - /// context which would otherwise be undefined behaviour. /// /// This function is rather limited in what environment it can capture. If you need to borrow /// the environment in the closure use the [`async_with!`] macro. @@ -218,10 +214,11 @@ impl AsyncContext { /// Unfortunatly it is currently impossible to have closures return a generic future which has a higher /// rank trait bound lifetime. So, to allow closures to work, the closure must return a boxed /// future. - pub async fn async_with<'a, F, R: 'a>(&'a self, f: F) -> R + pub async fn async_with(&self, f: F) -> R where F: for<'js> FnOnce(Ctx<'js>) -> Pin + 'js + Send>> + ParallelSend, + R: ParallelSend, { let future = { let guard = self.rt.inner.lock().await; @@ -236,6 +233,21 @@ impl AsyncContext { } .await } + + /// A entry point for manipulating and using javascript objects and scripts. + /// + /// This closure can't return a future, if you need to await javascript promises prefer the + /// [`async_with!`] macro. + pub async fn with(&self, f: F) -> R + where + F: for<'js> FnOnce(Ctx<'js>) -> R + ParallelSend, + R: ParallelSend, + { + let guard = self.rt.inner.lock().await; + guard.update_stack_top(); + let ctx = unsafe { Ctx::new_async(self) }; + f(ctx) + } } impl Drop for AsyncContext { diff --git a/core/src/runtime/async.rs b/core/src/runtime/async.rs index 46249e7e..aafa7246 100644 --- a/core/src/runtime/async.rs +++ b/core/src/runtime/async.rs @@ -11,10 +11,7 @@ use async_lock::Mutex; use crate::allocator::Allocator; #[cfg(feature = "loader")] use crate::loader::{RawLoader, Resolver}; -use crate::{ - context::AsyncContext, markers::ParallelSend, result::AsyncJobException, Ctx, Error, Exception, - Result, -}; +use crate::{context::AsyncContext, result::AsyncJobException, Ctx, Error, Exception, Result}; use super::{ raw::{Opaque, RawRuntime},