-
Notifications
You must be signed in to change notification settings - Fork 285
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create functions from closures #811
Conversation
We talked about this and decided it's better to conditionally compile it for now and avoid the leak; most users won't even notice the lack of functionality in older Node-API versions but it will avoid a hard-to-detect bug. |
As appealing as this is, unfortunately allowing let mut data = /* ... */;
let f = JsFunction::new(move |mut cx| {
let this: Handle<JsObject> = cx.this()?;
let method: Handle<JsFunction> = this.get(&mut cx, "recursive")?;
let n: Handle<JsNumber> = cx.argument(0)?;
let n = n.value(&mut cx) as u32;
println!("obj.recursive({})", n);
do_something(&data); // borrow the mutable data in the closure
if (n > 0) {
let n = cx.number(n - 1);
let args = vec![n.upcast()];
method.call(&mut cx, this, args)?;
}
});
obj.set("recursive", f)?; |
67c049d
to
29886fd
Compare
fc0e01b
to
45e123a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks great. I just have a few suggestions for clarity and one question about a possible leak.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the clarifying comments. Looks great!
feat(neon): Create functions from closures
What
Allow Neon users to create functions from closures.
How
The closure is boxed and added as data. It works very similar to the current functions except the trampoline function is generic.
Dropping the Rust closure requires
napi_add_finalizer
which was added in Node-API 5. For this reason, when using older Node-API versions, onlyfn
instead ofFn
are accepted.Future Expansion
It would be unsound to accept
FnMut
because a function may be reentrant. A function could trivially accept a reference to itself and then call that function. However, it is very cumbersome to useRefCell
to get access to mutable state.Since most functions will not have any possibility for reentrancy and since closure lifetime inference is very limited in Rust, it would be useful for Neon to provide a
JsFunction::new_mut
that accepts anFnMut
and wraps it in aRefCell
.