Skip to content

Commit ede9046

Browse files
committed
Re-introduce from_sys_init_default() for API 4.0
Addresses a regression introduced in fc4a405: > Remove several memory leaks by constructing into uninitialized pointers
1 parent 6797f16 commit ede9046

File tree

9 files changed

+79
-14
lines changed

9 files changed

+79
-14
lines changed

godot-core/src/builtin/array.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -717,7 +717,7 @@ impl<T: VariantMetadata> FromVariant for Array<T> {
717717
}
718718

719719
let array = unsafe {
720-
Self::from_sys_init(|self_ptr| {
720+
sys::from_sys_init_or_init_default::<Self>(|self_ptr| {
721721
let array_from_variant = sys::builtin_fn!(array_from_variant);
722722
array_from_variant(self_ptr, variant.var_sys());
723723
})

godot-core/src/builtin/callable.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ impl Callable {
4545
// upcast not needed
4646
let method = method_name.into();
4747
unsafe {
48-
Self::from_sys_init(|self_ptr| {
48+
sys::from_sys_init_or_init_default::<Self>(|self_ptr| {
4949
let ctor = sys::builtin_fn!(callable_from_object_method);
5050
let args = [object.sys_const(), method.sys_const()];
5151
ctor(self_ptr, args.as_ptr());

godot-core/src/builtin/string/godot_string.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ impl FromStr for GodotString {
223223
impl From<&StringName> for GodotString {
224224
fn from(string: &StringName) -> Self {
225225
unsafe {
226-
Self::from_sys_init(|self_ptr| {
226+
sys::from_sys_init_or_init_default::<Self>(|self_ptr| {
227227
let ctor = sys::builtin_fn!(string_from_string_name);
228228
let args = [string.sys_const()];
229229
ctor(self_ptr, args.as_ptr());
@@ -244,7 +244,7 @@ impl From<StringName> for GodotString {
244244
impl From<&NodePath> for GodotString {
245245
fn from(path: &NodePath) -> Self {
246246
unsafe {
247-
Self::from_sys_init(|self_ptr| {
247+
sys::from_sys_init_or_init_default::<Self>(|self_ptr| {
248248
let ctor = sys::builtin_fn!(string_from_node_path);
249249
let args = [path.sys_const()];
250250
ctor(self_ptr, args.as_ptr());

godot-core/src/builtin/string/node_path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl_rust_string_conv!(NodePath);
101101
impl From<&GodotString> for NodePath {
102102
fn from(string: &GodotString) -> Self {
103103
unsafe {
104-
Self::from_sys_init(|self_ptr| {
104+
sys::from_sys_init_or_init_default::<Self>(|self_ptr| {
105105
let ctor = sys::builtin_fn!(node_path_from_string);
106106
let args = [string.sys_const()];
107107
ctor(self_ptr, args.as_ptr());

godot-core/src/builtin/string/string_name.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ impl_rust_string_conv!(StringName);
129129
impl From<&GodotString> for StringName {
130130
fn from(string: &GodotString) -> Self {
131131
unsafe {
132-
Self::from_sys_init(|self_ptr| {
132+
sys::from_sys_init_or_init_default::<Self>(|self_ptr| {
133133
let ctor = sys::builtin_fn!(string_name_from_string);
134134
let args = [string.sys_const()];
135135
ctor(self_ptr, args.as_ptr());

godot-core/src/builtin/variant/impls.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@ macro_rules! impl_variant_traits {
110110
};
111111

112112
(@@from_sys_init, $from_sys_init:ident) => {
113+
// let $from_sys_init = Self::from_sys_init;
114+
115+
#[cfg(gdextension_api = "4.0")]
116+
let $from_sys_init = Self::from_sys_init_default;
117+
#[cfg(not(gdextension_api = "4.0"))]
113118
let $from_sys_init = Self::from_sys_init;
114119
};
115120
}

godot-core/src/builtin/variant/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,26 @@ impl Variant {
108108
let args_sys: Vec<_> = args.iter().map(|v| v.var_sys_const()).collect();
109109
let mut error = sys::default_call_error();
110110

111+
// #[cfg(gdextension_api = "4.0")]
112+
// let result = {
113+
// #[allow(unused_mut)]
114+
// let mut result = Variant::nil();
115+
//
116+
// use sys::AsUninit;
117+
// unsafe {
118+
// interface_fn!(variant_call)(
119+
// self.var_sys(),
120+
// method.string_sys(),
121+
// args_sys.as_ptr(),
122+
// args_sys.len() as i64,
123+
// result.var_sys().as_uninit(),
124+
// ptr::addr_of_mut!(error),
125+
// )
126+
// };
127+
// result
128+
// };
129+
//
130+
// #[cfg(not(gdextension_api = "4.0"))]
111131
let result = unsafe {
112132
Variant::from_var_sys_init(|variant_ptr| {
113133
interface_fn!(variant_call)(
@@ -210,6 +230,16 @@ impl Variant {
210230
fn var_sys = sys;
211231
}
212232

233+
// #[doc(hidden)]
234+
// pub unsafe fn from_var_sys_init_default(
235+
// init_fn: impl FnOnce(sys::GDExtensionVariantPtr),
236+
// ) -> Self {
237+
// #[allow(unused_mut)]
238+
// let mut variant = Variant::nil();
239+
// init_fn(variant.var_sys());
240+
// variant
241+
// }
242+
213243
#[doc(hidden)]
214244
pub fn var_sys_const(&self) -> sys::GDExtensionConstVariantPtr {
215245
sys::to_const_ptr(self.var_sys())

godot-ffi/src/godot_ffi.rs

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,32 @@ pub unsafe trait GodotFfi {
9696
unsafe fn move_return_ptr(self, dst: sys::GDExtensionTypePtr, call_type: PtrcallType);
9797
}
9898

99+
// In Godot 4.0.x, a lot of that are "constructed into" require a default-initialized value.
100+
// In Godot 4.1+, placement new is used, requiring no prior value.
101+
// This method abstracts over that. Outside of GodotFfi because it should not be overridden.
102+
103+
/// # Safety
104+
///
105+
/// See [`GodotFfi::from_sys_init`] and [`GodotFfi::from_sys_init_default`].
106+
#[cfg(gdextension_api = "4.0")]
107+
pub unsafe fn from_sys_init_or_init_default<T: GodotFfi>(
108+
init_fn: impl FnOnce(sys::GDExtensionTypePtr),
109+
) -> T {
110+
T::from_sys_init_default(init_fn)
111+
}
112+
113+
/// # Safety
114+
///
115+
/// See [`GodotFfi::from_sys_init`] and [`GodotFfi::from_sys_init_default`].
116+
#[cfg(not(gdextension_api = "4.0"))]
117+
pub unsafe fn from_sys_init_or_init_default<T: GodotFfi>(
118+
init_fn: impl FnOnce(sys::GDExtensionUninitializedTypePtr),
119+
) -> T {
120+
T::from_sys_init(init_fn)
121+
}
122+
123+
// ----------------------------------------------------------------------------------------------------------------------------------------------
124+
99125
/// Marks a type as having a nullable counterpart in Godot.
100126
///
101127
/// This trait primarily exists to implement GodotFfi for `Option<Gd<T>>`, which is not possible
@@ -114,13 +140,6 @@ unsafe impl<T> GodotFfi for Option<T>
114140
where
115141
T: GodotNullablePtr,
116142
{
117-
fn sys(&self) -> sys::GDExtensionTypePtr {
118-
match self {
119-
Some(value) => value.sys(),
120-
None => ptr::null_mut() as sys::GDExtensionTypePtr,
121-
}
122-
}
123-
124143
unsafe fn from_sys(ptr: sys::GDExtensionTypePtr) -> Self {
125144
ptr_then(ptr, |ptr| T::from_sys(ptr))
126145
}
@@ -132,6 +151,13 @@ where
132151
Self::from_sys(raw.assume_init())
133152
}
134153

154+
fn sys(&self) -> sys::GDExtensionTypePtr {
155+
match self {
156+
Some(value) => value.sys(),
157+
None => ptr::null_mut() as sys::GDExtensionTypePtr,
158+
}
159+
}
160+
135161
unsafe fn from_arg_ptr(ptr: sys::GDExtensionTypePtr, call_type: PtrcallType) -> Self {
136162
ptr_then(ptr, |ptr| T::from_arg_ptr(ptr, call_type))
137163
}
@@ -143,6 +169,8 @@ where
143169
}
144170
}
145171

172+
// ----------------------------------------------------------------------------------------------------------------------------------------------
173+
146174
/// An indication of what type of pointer call is being made.
147175
#[derive(Default, Copy, Clone, Eq, PartialEq, Debug)]
148176
pub enum PtrcallType {

godot-ffi/src/lib.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,9 @@ use std::ffi::CStr;
3232
#[doc(hidden)]
3333
pub use paste;
3434

35-
pub use crate::godot_ffi::{GodotFfi, GodotFuncMarshal, GodotNullablePtr, PtrcallType};
35+
pub use crate::godot_ffi::{
36+
from_sys_init_or_init_default, GodotFfi, GodotFuncMarshal, GodotNullablePtr, PtrcallType,
37+
};
3638
pub use gen::central::*;
3739
pub use gen::gdextension_interface::*;
3840
pub use gen::interface::*;

0 commit comments

Comments
 (0)