[oden-js] Ensure callbacks have 'static lifetime
Because we smuggle them through we need to make sure they're not holding references that will go invalid- we can make no promises about how long they stay alive. Although maybe bounding to context lifetime is OK? But anyway.
This commit is contained in:
parent
14f9eb655f
commit
e36ab17235
3 changed files with 8 additions and 8 deletions
|
|
@ -3,9 +3,9 @@ use oden_js_sys as sys;
|
||||||
use std::ffi::c_int;
|
use std::ffi::c_int;
|
||||||
use std::panic::catch_unwind;
|
use std::panic::catch_unwind;
|
||||||
|
|
||||||
pub trait Callback: Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> ValueResult {}
|
pub trait Callback: 'static + Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> ValueResult {}
|
||||||
|
|
||||||
impl<T> Callback for T where T: Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> ValueResult {}
|
impl<T> Callback for T where T: 'static + Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> ValueResult {}
|
||||||
|
|
||||||
struct CallbackObject<T: Callback> {
|
struct CallbackObject<T: Callback> {
|
||||||
callback: T,
|
callback: T,
|
||||||
|
|
|
||||||
|
|
@ -169,14 +169,14 @@ impl ContextRef {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new value that wraps a strongly-typed closure.
|
/// Construct a new value that wraps a strongly-typed closure.
|
||||||
pub fn new_fn<F>(&self, func: impl RustFunction<F>) -> ValueResult {
|
pub fn new_fn<F>(&self, func: impl RustFunction<F> + 'static) -> ValueResult {
|
||||||
self.new_dynamic_fn(|c, _, a| func.call(c, a))
|
self.new_dynamic_fn(move |c, _, a| func.call(c, a))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Construct a new value that wraps a dynamically-typed closure.
|
/// Construct a new value that wraps a dynamically-typed closure.
|
||||||
pub fn new_dynamic_fn<F>(&self, func: F) -> ValueResult
|
pub fn new_dynamic_fn<F>(&self, func: F) -> ValueResult
|
||||||
where
|
where
|
||||||
F: Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> ValueResult,
|
F: 'static + Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> ValueResult,
|
||||||
{
|
{
|
||||||
// Constructing a new function is complicated enough that it needs to
|
// Constructing a new function is complicated enough that it needs to
|
||||||
// be out of line.
|
// be out of line.
|
||||||
|
|
@ -472,7 +472,7 @@ mod tests {
|
||||||
go.set_property(
|
go.set_property(
|
||||||
&ctx,
|
&ctx,
|
||||||
"foo",
|
"foo",
|
||||||
&ctx.new_dynamic_fn(|c, _, _| Ok(return_value.dup(c)))
|
&ctx.new_dynamic_fn(move |c, _, _| Ok(return_value.dup(c)))
|
||||||
.unwrap(),
|
.unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
|
||||||
|
|
@ -270,7 +270,7 @@ impl ValueRef {
|
||||||
&mut self,
|
&mut self,
|
||||||
ctx: &ContextRef,
|
ctx: &ContextRef,
|
||||||
prop: &str,
|
prop: &str,
|
||||||
func: impl RustFunction<F>,
|
func: impl RustFunction<F> + 'static,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let vr: Value = ctx.new_fn(func)?;
|
let vr: Value = ctx.new_fn(func)?;
|
||||||
self.set_property(ctx, prop, &vr)
|
self.set_property(ctx, prop, &vr)
|
||||||
|
|
@ -278,7 +278,7 @@ impl ValueRef {
|
||||||
|
|
||||||
pub fn set_dynamic_method<F>(&mut self, ctx: &ContextRef, prop: &str, func: F) -> Result<()>
|
pub fn set_dynamic_method<F>(&mut self, ctx: &ContextRef, prop: &str, func: F) -> Result<()>
|
||||||
where
|
where
|
||||||
F: Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> Result<Value>,
|
F: 'static + Fn(&ContextRef, &ValueRef, &[&ValueRef]) -> Result<Value>,
|
||||||
{
|
{
|
||||||
let vr: Value = ctx.new_dynamic_fn(func)?;
|
let vr: Value = ctx.new_dynamic_fn(func)?;
|
||||||
self.set_property(ctx, prop, &vr)
|
self.set_property(ctx, prop, &vr)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue