Skip to content

Commit e50907a

Browse files
committed
Ok all working again
1 parent 5505668 commit e50907a

File tree

5 files changed

+66
-56
lines changed

5 files changed

+66
-56
lines changed

crates/neon/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ features = ["sync"]
4444
optional = true
4545

4646
[features]
47-
default = ["napi-8", "futures"]
47+
default = ["napi-8"]
4848

4949
# Enable extracting values by serializing to JSON
5050
serde = ["dep:serde", "dep:serde_json"]

crates/neon/src/context/mod.rs

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ pub use crate::types::buffer::lock::Lock;
149149
// use crate::async_local::{root::RootGlobal, spawn_async_local};
150150
#[cfg(feature = "async_local")]
151151
use futures::Future;
152+
#[cfg(feature = "async_local")]
153+
use crate::handle::StaticHandle;
152154

153155
use crate::{
154156
event::TaskBuilder,
@@ -291,20 +293,16 @@ pub trait Context<'a>: ContextInternal<'a> {
291293
}
292294

293295
#[cfg(feature = "async_local")]
294-
fn execute_async_local<F, Fut>(&mut self, f: F)
296+
fn spawn_local<F, Fut>(&mut self, f: F)
295297
where
296298
Fut: Future<Output = ()>,
297299
F: FnOnce(AsyncContext) -> Fut + 'static,
298300
{
299-
use futures::Future;
300-
301301
let env = self.env();
302302

303303
crate::async_local::spawn_async_local(self, async move {
304-
// let scope = unsafe { HandleScope::new(env.to_raw()) };
305304
let future = f(AsyncContext { env });
306305
future.await;
307-
// drop(scope);
308306
}).unwrap();
309307
}
310308

@@ -623,29 +621,31 @@ impl<'a> ModuleContext<'a> {
623621
F: Fn(AsyncFunctionContext) -> Fut + 'static + Copy,
624622
V: Value,
625623
{
626-
// let wrapper = JsFunction::new(self, move |mut cx| {
627-
// let mut args = vec![];
628-
629-
// while let Some(arg) = cx.argument_opt(args.len()) {
630-
// let arg = arg.as_value(&mut cx);
631-
// let arg = RootGlobal::new(&mut cx, arg);
632-
// args.push(arg);
633-
// }
634-
635-
// let (deferred, promise) = cx.promise();
636-
// cx.execute_async_local(move |mut cx| async move {
637-
// let acx = AsyncFunctionContext {
638-
// env: cx.env(),
639-
// arguments: args,
640-
// };
641-
// deferred.resolve(&mut cx, f(acx).await.unwrap());
642-
// ()
643-
// });
644-
645-
// Ok(promise)
646-
// })?;
647-
648-
// self.exports.clone().set(self, key, wrapper)?;
624+
use crate::handle::StaticHandle;
625+
626+
let wrapper = JsFunction::new(self, move |mut cx| {
627+
let mut args = vec![];
628+
629+
while let Some(arg) = cx.argument_opt(args.len()) {
630+
let arg = arg.as_value(&mut cx);
631+
let arg = StaticHandle::new(&mut cx, arg)?;
632+
args.push(arg);
633+
}
634+
635+
let (deferred, promise) = cx.promise();
636+
cx.spawn_local(move |mut cx| async move {
637+
let acx = AsyncFunctionContext {
638+
env: cx.env(),
639+
arguments: args,
640+
};
641+
deferred.resolve(&mut cx, f(acx).await.unwrap());
642+
()
643+
});
644+
645+
Ok(promise)
646+
})?;
647+
648+
self.exports.clone().set(self, key, wrapper)?;
649649
Ok(())
650650
}
651651

@@ -851,16 +851,17 @@ impl<'a> Context<'a> for FunctionContext<'a> {}
851851
#[cfg(feature = "async_local")]
852852
pub struct AsyncFunctionContext {
853853
env: Env,
854-
// arguments: Vec<RootGlobal>,
854+
arguments: Vec<StaticHandle<JsValue>>,
855855
}
856856

857857
#[cfg(feature = "async_local")]
858858
impl<'a> AsyncFunctionContext {
859859
pub fn argument<V: Value>(&mut self, i: usize) -> JsResult<'a, V> {
860-
// let arg = self.arguments.get(i).unwrap().clone();
861-
// let handle = arg.into_inner(self);
862-
// Ok(handle)
863-
todo!()
860+
let arg = self.arguments.get(i).unwrap().clone();
861+
let arg = arg.from_static(self)?;
862+
let value = unsafe { V::from_local(self.env(), arg.to_local()) };
863+
let handle = Handle::new_internal(value);
864+
Ok(handle)
864865
}
865866
}
866867

crates/neon/src/handle/mod.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,11 @@ impl<'a, V: Value + 'a> Handle<'a, V> {
9696
}
9797
}
9898

99-
pub fn root_global(self, cx: &mut impl Context<'a>) -> NeonResult<RootGlobal<V>> {
100-
RootGlobal::new(cx, self)
99+
/// Detaches the value from the Nodejs garbage collector
100+
/// and manages the variable lifetime via reference counting.
101+
/// Useful when interacting with a value within async closures
102+
pub fn to_static(self, cx: &mut impl Context<'a>) -> NeonResult<StaticHandle<V>> {
103+
StaticHandle::new(cx, self)
101104
}
102105
}
103106

crates/neon/src/handle/root_value.rs

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,36 @@ use crate::result::JsResult;
1212
use crate::result::NeonResult;
1313
use crate::types::JsFunction;
1414
use crate::types::JsObject;
15+
use crate::types::JsSymbol;
16+
17+
// This creates a rooted object and stores javascript
18+
// values on it as a way to grant any JavaScript value
19+
// a static lifetime
1520

1621
thread_local! {
17-
// Symbol("__neon_cache")
1822
static NEON_CACHE: OnceCell<Root<JsObject>> = OnceCell::default();
1923
}
2024

2125
/// Reference counted JavaScript value with a static lifetime for use in async closures
22-
pub struct RootGlobal<T> {
26+
pub struct StaticHandle<T> {
2327
pub(crate) count: Rc<RefCell<u32>>,
24-
pub(crate) inner: Rc<String>,
28+
pub(crate) inner: Rc<Root<JsSymbol>>,
2529
_p: PhantomData<T>,
2630
}
2731

28-
impl<T: Value> RootGlobal<T> {
32+
impl<T: Value> StaticHandle<T> {
2933
pub(crate) fn new<'a>(
3034
cx: &mut impl Context<'a>,
3135
value: Handle<'a, T>,
32-
) -> NeonResult<RootGlobal<T>> {
36+
) -> NeonResult<StaticHandle<T>> {
3337
Ok(Self {
3438
count: Rc::new(RefCell::new(1)),
3539
inner: Rc::new(set_ref(cx, value)?),
3640
_p: Default::default(),
3741
})
3842
}
3943

40-
pub fn clone<'a>(&self) -> RootGlobal<T> {
44+
pub fn clone(&self) -> StaticHandle<T> {
4145
let mut count = self.count.borrow_mut();
4246
*count += 1;
4347
drop(count);
@@ -49,16 +53,16 @@ impl<T: Value> RootGlobal<T> {
4953
}
5054
}
5155

52-
pub fn into_inner<'a>(&self, cx: &mut impl Context<'a>) -> JsResult<'a, T> {
53-
get_ref(cx, &*self.inner)
56+
pub fn from_static<'a>(&self, cx: &mut impl Context<'a>) -> JsResult<'a, T> {
57+
get_ref(cx, &self.inner)
5458
}
5559

5660
pub fn drop<'a>(&self, cx: &mut impl Context<'a>) -> NeonResult<()> {
5761
let mut count = self.count.borrow_mut();
5862
*count -= 1;
5963

6064
if *count == 0 {
61-
delete_ref(cx, &*self.inner)?
65+
delete_ref(cx, &self.inner)?
6266
}
6367

6468
Ok(())
@@ -81,41 +85,43 @@ fn get_cache<'a>(cx: &mut impl Context<'a>) -> JsResult<'a, JsObject> {
8185
Ok(neon_cache.into_inner(cx))
8286
}
8387

84-
fn set_ref<'a, V: Value>(cx: &mut impl Context<'a>, value: Handle<'a, V>) -> NeonResult<String> {
88+
fn set_ref<'a, V: Value>(
89+
cx: &mut impl Context<'a>,
90+
value: Handle<'a, V>,
91+
) -> NeonResult<Root<JsSymbol>> {
8592
let neon_cache = get_cache(cx)?;
86-
// Is this safe?
87-
let key = format!("{:?}", value.to_local());
93+
let symbol = cx.symbol(format!("{:?}", value.to_local())).root(cx);
8894

8995
get_cache(cx)?
9096
.get::<JsFunction, _, _>(cx, "set")?
9197
.call_with(cx)
9298
.this(neon_cache)
93-
.arg(cx.string(&key))
99+
.arg(symbol.clone(cx).into_inner(cx))
94100
.arg(value)
95101
.exec(cx)?;
96102

97-
Ok(key)
103+
Ok(symbol)
98104
}
99105

100-
fn get_ref<'a, V: Value>(cx: &mut impl Context<'a>, key: &str) -> JsResult<'a, V> {
106+
fn get_ref<'a, V: Value>(cx: &mut impl Context<'a>, key: &Root<JsSymbol>) -> JsResult<'a, V> {
101107
let neon_cache = get_cache(cx)?;
102108

103109
get_cache(cx)?
104110
.get::<JsFunction, _, _>(cx, "get")?
105111
.call_with(cx)
106112
.this(neon_cache)
107-
.arg(cx.string(&key))
113+
.arg(key.clone(cx).into_inner(cx))
108114
.apply(cx)
109115
}
110116

111-
fn delete_ref<'a>(cx: &mut impl Context<'a>, key: &str) -> NeonResult<()> {
117+
fn delete_ref<'a>(cx: &mut impl Context<'a>, key: &Root<JsSymbol>) -> NeonResult<()> {
112118
let neon_cache = get_cache(cx)?;
113119

114120
get_cache(cx)?
115121
.get::<JsFunction, _, _>(cx, "delete")?
116122
.call_with(cx)
117123
.this(neon_cache)
118-
.arg(cx.string(&key))
124+
.arg(key.clone(cx).into_inner(cx))
119125
.exec(cx)?;
120126

121127
Ok(())

crates/neon/src/prelude.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
#[doc(no_inline)]
44
pub use crate::{
55
context::{
6-
CallKind, ComputeContext, Context, ExecuteContext, FunctionContext, ModuleContext,
7-
TaskContext,
6+
AsyncContext, AsyncFunctionContext, CallKind, ComputeContext, Context, ExecuteContext,
7+
FunctionContext, ModuleContext, TaskContext,
88
},
99
handle::{Handle, Root},
1010
object::Object,

0 commit comments

Comments
 (0)