From dade6783f379e7307d1672238c7ba0a00f2c6635 Mon Sep 17 00:00:00 2001 From: Adrian Taylor Date: Mon, 28 Feb 2022 19:50:10 -0800 Subject: [PATCH] Fix moved-in-memory problem. Partially fixes #833. --- .../codegen_rs/function_wrapper_rs.rs | 6 ++++-- src/value_param.rs | 21 ++++++++++++------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/engine/src/conversion/codegen_rs/function_wrapper_rs.rs b/engine/src/conversion/codegen_rs/function_wrapper_rs.rs index 074501e8e..a098d00ea 100644 --- a/engine/src/conversion/codegen_rs/function_wrapper_rs.rs +++ b/engine/src/conversion/codegen_rs/function_wrapper_rs.rs @@ -109,7 +109,7 @@ impl TypeConversionPolicy { panic!("Unexpected non-ident parameter name"); }; let space_var_name = make_ident(format!("{}_space", var_name)); - let call = quote! { autocxx::ValueParamHandler::new(#var_name) }; + let call = quote! { #space_var_name.populate() }; let call = if wrap_in_unsafe { quote! { unsafe { @@ -121,7 +121,9 @@ impl TypeConversionPolicy { }; ( Some(quote! { - let mut #space_var_name = #call; + let mut #space_var_name = autocxx::ValueParamHandler::new(#var_name); + let #space_var_name = &mut #space_var_name; + #call }), quote! { #space_var_name.get_ptr() diff --git a/src/value_param.rs b/src/value_param.rs index a8319ded3..0b85ad5dd 100644 --- a/src/value_param.rs +++ b/src/value_param.rs @@ -162,11 +162,7 @@ impl> ValueParamHandler { /// this may be largely a no-op or it may involve storing a whole /// extra copy of the type. /// - /// # Safety - /// - /// Callers must guarantee that this type will not move - /// in memory. - pub unsafe fn new(param: VP) -> Self { + pub fn new(param: VP) -> Self { let mut this = Self { param, space: None, @@ -174,12 +170,23 @@ impl> ValueParamHandler { }; if this.param.needs_stack_space() { this.space = Some(MaybeUninit::uninit()); - this.param - .populate_stack_space(Pin::new_unchecked(this.space.as_mut().unwrap())); } this } + /// Populate this stack space if needs be. + /// + /// # Safety + /// + /// Callers must guarantee that this type will not move + /// in memory between calls to [`populate`] and [`get_ptr`]. + pub unsafe fn populate(&mut self) { + if self.param.needs_stack_space() { + self.param + .populate_stack_space(Pin::new_unchecked(self.space.as_mut().unwrap())); + } + } + /// Return a pointer to the underlying value which can be passed to C++. /// Per the unsafety contract of `new`, the object must not have moved /// since it was created.