diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp index 91038b9bdf8..af7c37b4b69 100644 --- a/core/extension/gdextension.cpp +++ b/core/extension/gdextension.cpp @@ -425,10 +425,10 @@ void GDExtension::_unregister_extension_class(GDExtensionClassLibraryPtr p_libra self->extension_classes.erase(class_name); } -void GDExtension::_get_library_path(GDExtensionClassLibraryPtr p_library, GDExtensionStringPtr r_path) { +void GDExtension::_get_library_path(GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringPtr r_path) { GDExtension *self = reinterpret_cast(p_library); - *(String *)r_path = self->library_path; + memnew_placement(r_path, String(self->library_path)); } Error GDExtension::open_library(const String &p_path, const String &p_entry_symbol) { diff --git a/core/extension/gdextension_interface.cpp b/core/extension/gdextension_interface.cpp index 96a57115bf5..b5ec04b12d4 100644 --- a/core/extension/gdextension_interface.cpp +++ b/core/extension/gdextension_interface.cpp @@ -80,10 +80,10 @@ uint64_t gdextension_get_native_struct_size(GDExtensionConstStringNamePtr p_name // Variant functions -static void gdextension_variant_new_copy(GDExtensionVariantPtr r_dest, GDExtensionConstVariantPtr p_src) { +static void gdextension_variant_new_copy(GDExtensionUninitializedVariantPtr r_dest, GDExtensionConstVariantPtr p_src) { memnew_placement(reinterpret_cast(r_dest), Variant(*reinterpret_cast(p_src))); } -static void gdextension_variant_new_nil(GDExtensionVariantPtr r_dest) { +static void gdextension_variant_new_nil(GDExtensionUninitializedVariantPtr r_dest) { memnew_placement(reinterpret_cast(r_dest), Variant); } static void gdextension_variant_destroy(GDExtensionVariantPtr p_self) { @@ -92,14 +92,14 @@ static void gdextension_variant_destroy(GDExtensionVariantPtr p_self) { // variant type -static void gdextension_variant_call(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argcount, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) { +static void gdextension_variant_call(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argcount, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error) { Variant *self = (Variant *)p_self; const StringName method = *reinterpret_cast(p_method); const Variant **args = (const Variant **)p_args; - Variant ret; Callable::CallError error; - self->callp(method, args, p_argcount, ret, error); - memnew_placement(r_return, Variant(ret)); + memnew_placement(r_return, Variant); + Variant *ret = reinterpret_cast(r_return); + self->callp(method, args, p_argcount, *ret, error); if (r_error) { r_error->error = (GDExtensionCallErrorType)(error.error); @@ -108,14 +108,14 @@ static void gdextension_variant_call(GDExtensionVariantPtr p_self, GDExtensionCo } } -static void gdextension_variant_call_static(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argcount, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) { +static void gdextension_variant_call_static(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argcount, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error) { Variant::Type type = (Variant::Type)p_type; const StringName method = *reinterpret_cast(p_method); const Variant **args = (const Variant **)p_args; - Variant ret; Callable::CallError error; - Variant::call_static(type, method, args, p_argcount, ret, error); - memnew_placement(r_return, Variant(ret)); + memnew_placement(r_return, Variant); + Variant *ret = reinterpret_cast(r_return); + Variant::call_static(type, method, args, p_argcount, *ret, error); if (r_error) { r_error->error = (GDExtensionCallErrorType)error.error; @@ -124,12 +124,13 @@ static void gdextension_variant_call_static(GDExtensionVariantType p_type, GDExt } } -static void gdextension_variant_evaluate(GDExtensionVariantOperator p_op, GDExtensionConstVariantPtr p_a, GDExtensionConstVariantPtr p_b, GDExtensionVariantPtr r_return, GDExtensionBool *r_valid) { +static void gdextension_variant_evaluate(GDExtensionVariantOperator p_op, GDExtensionConstVariantPtr p_a, GDExtensionConstVariantPtr p_b, GDExtensionUninitializedVariantPtr r_return, GDExtensionBool *r_valid) { Variant::Operator op = (Variant::Operator)p_op; const Variant *a = (const Variant *)p_a; const Variant *b = (const Variant *)p_b; - Variant *ret = (Variant *)r_return; bool valid; + memnew_placement(r_return, Variant); + Variant *ret = reinterpret_cast(r_return); Variant::evaluate(op, *a, *b, *ret, valid); *r_valid = valid; } @@ -175,7 +176,7 @@ static void gdextension_variant_set_indexed(GDExtensionVariantPtr p_self, GDExte *r_oob = oob; } -static void gdextension_variant_get(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid) { +static void gdextension_variant_get(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid) { const Variant *self = (const Variant *)p_self; const Variant *key = (const Variant *)p_key; @@ -184,7 +185,7 @@ static void gdextension_variant_get(GDExtensionConstVariantPtr p_self, GDExtensi *r_valid = valid; } -static void gdextension_variant_get_named(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid) { +static void gdextension_variant_get_named(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid) { const Variant *self = (const Variant *)p_self; const StringName *key = (const StringName *)p_key; @@ -193,7 +194,7 @@ static void gdextension_variant_get_named(GDExtensionConstVariantPtr p_self, GDE *r_valid = valid; } -static void gdextension_variant_get_keyed(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid) { +static void gdextension_variant_get_keyed(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid) { const Variant *self = (const Variant *)p_self; const Variant *key = (const Variant *)p_key; @@ -202,7 +203,7 @@ static void gdextension_variant_get_keyed(GDExtensionConstVariantPtr p_self, GDE *r_valid = valid; } -static void gdextension_variant_get_indexed(GDExtensionConstVariantPtr p_self, GDExtensionInt p_index, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid, GDExtensionBool *r_oob) { +static void gdextension_variant_get_indexed(GDExtensionConstVariantPtr p_self, GDExtensionInt p_index, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid, GDExtensionBool *r_oob) { const Variant *self = (const Variant *)p_self; bool valid; @@ -213,9 +214,10 @@ static void gdextension_variant_get_indexed(GDExtensionConstVariantPtr p_self, G } /// Iteration. -static GDExtensionBool gdextension_variant_iter_init(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionBool *r_valid) { +static GDExtensionBool gdextension_variant_iter_init(GDExtensionConstVariantPtr p_self, GDExtensionUninitializedVariantPtr r_iter, GDExtensionBool *r_valid) { const Variant *self = (const Variant *)p_self; - Variant *iter = (Variant *)r_iter; + memnew_placement(r_iter, Variant); + Variant *iter = reinterpret_cast(r_iter); bool valid; bool ret = self->iter_init(*iter, valid); @@ -233,7 +235,7 @@ static GDExtensionBool gdextension_variant_iter_next(GDExtensionConstVariantPtr return ret; } -static void gdextension_variant_iter_get(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid) { +static void gdextension_variant_iter_get(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid) { const Variant *self = (const Variant *)p_self; Variant *iter = (Variant *)r_iter; @@ -264,12 +266,12 @@ static GDExtensionBool gdextension_variant_booleanize(GDExtensionConstVariantPtr return self->booleanize(); } -static void gdextension_variant_duplicate(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_ret, GDExtensionBool p_deep) { +static void gdextension_variant_duplicate(GDExtensionConstVariantPtr p_self, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool p_deep) { const Variant *self = (const Variant *)p_self; memnew_placement(r_ret, Variant(self->duplicate(p_deep))); } -static void gdextension_variant_stringify(GDExtensionConstVariantPtr p_self, GDExtensionStringPtr r_ret) { +static void gdextension_variant_stringify(GDExtensionConstVariantPtr p_self, GDExtensionUninitializedVariantPtr r_ret) { const Variant *self = (const Variant *)p_self; memnew_placement(r_ret, String(*self)); } @@ -298,7 +300,7 @@ static GDExtensionBool gdextension_variant_has_key(GDExtensionConstVariantPtr p_ return ret; } -static void gdextension_variant_get_type_name(GDExtensionVariantType p_type, GDExtensionStringPtr r_ret) { +static void gdextension_variant_get_type_name(GDExtensionVariantType p_type, GDExtensionUninitializedVariantPtr r_ret) { String name = Variant::get_type_name((Variant::Type)p_type); memnew_placement(r_ret, String(name)); } @@ -498,11 +500,12 @@ static GDExtensionPtrConstructor gdextension_variant_get_ptr_constructor(GDExten static GDExtensionPtrDestructor gdextension_variant_get_ptr_destructor(GDExtensionVariantType p_type) { return (GDExtensionPtrDestructor)Variant::get_ptr_destructor(Variant::Type(p_type)); } -static void gdextension_variant_construct(GDExtensionVariantType p_type, GDExtensionVariantPtr p_base, const GDExtensionConstVariantPtr *p_args, int32_t p_argument_count, GDExtensionCallError *r_error) { - memnew_placement(p_base, Variant); +static void gdextension_variant_construct(GDExtensionVariantType p_type, GDExtensionUninitializedVariantPtr r_base, const GDExtensionConstVariantPtr *p_args, int32_t p_argument_count, GDExtensionCallError *r_error) { + memnew_placement(r_base, Variant); + Variant *base = reinterpret_cast(r_base); Callable::CallError error; - Variant::construct(Variant::Type(p_type), *(Variant *)p_base, (const Variant **)p_args, p_argument_count, error); + Variant::construct(Variant::Type(p_type), *base, (const Variant **)p_args, p_argument_count, error); if (r_error) { r_error->error = (GDExtensionCallErrorType)(error.error); @@ -533,7 +536,7 @@ static GDExtensionPtrKeyedGetter gdextension_variant_get_ptr_keyed_getter(GDExte static GDExtensionPtrKeyedChecker gdextension_variant_get_ptr_keyed_checker(GDExtensionVariantType p_type) { return (GDExtensionPtrKeyedChecker)Variant::get_member_ptr_keyed_checker(Variant::Type(p_type)); } -static void gdextension_variant_get_constant_value(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_constant, GDExtensionVariantPtr r_ret) { +static void gdextension_variant_get_constant_value(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_constant, GDExtensionUninitializedVariantPtr r_ret) { StringName constant = *reinterpret_cast(p_constant); memnew_placement(r_ret, Variant(Variant::get_constant_value(Variant::Type(p_type), constant))); } @@ -549,77 +552,67 @@ static GDExtensionPtrUtilityFunction gdextension_variant_get_ptr_utility_functio //string helpers -static void gdextension_string_new_with_latin1_chars(GDExtensionStringPtr r_dest, const char *p_contents) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); - *dest = String(p_contents); +static void gdextension_string_new_with_latin1_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) { + memnew_placement(r_dest, String(p_contents)); } -static void gdextension_string_new_with_utf8_chars(GDExtensionStringPtr r_dest, const char *p_contents) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); +static void gdextension_string_new_with_utf8_chars(GDExtensionUninitializedStringPtr r_dest, const char *p_contents) { + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); dest->parse_utf8(p_contents); } -static void gdextension_string_new_with_utf16_chars(GDExtensionStringPtr r_dest, const char16_t *p_contents) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); +static void gdextension_string_new_with_utf16_chars(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents) { + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); dest->parse_utf16(p_contents); } -static void gdextension_string_new_with_utf32_chars(GDExtensionStringPtr r_dest, const char32_t *p_contents) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); - *dest = String((const char32_t *)p_contents); +static void gdextension_string_new_with_utf32_chars(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents) { + memnew_placement(r_dest, String((const char32_t *)p_contents)); } -static void gdextension_string_new_with_wide_chars(GDExtensionStringPtr r_dest, const wchar_t *p_contents) { - String *dest = (String *)r_dest; +static void gdextension_string_new_with_wide_chars(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents) { if constexpr (sizeof(wchar_t) == 2) { // wchar_t is 16 bit, parse. - memnew_placement(dest, String); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); dest->parse_utf16((const char16_t *)p_contents); } else { // wchar_t is 32 bit, copy. - memnew_placement(dest, String); - *dest = String((const char32_t *)p_contents); + memnew_placement(r_dest, String((const char32_t *)p_contents)); } } -static void gdextension_string_new_with_latin1_chars_and_len(GDExtensionStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); - *dest = String(p_contents, p_size); +static void gdextension_string_new_with_latin1_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { + memnew_placement(r_dest, String(p_contents, p_size)); } -static void gdextension_string_new_with_utf8_chars_and_len(GDExtensionStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); +static void gdextension_string_new_with_utf8_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size) { + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); dest->parse_utf8(p_contents, p_size); } -static void gdextension_string_new_with_utf16_chars_and_len(GDExtensionStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_size) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); +static void gdextension_string_new_with_utf16_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_size) { + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); dest->parse_utf16(p_contents, p_size); } -static void gdextension_string_new_with_utf32_chars_and_len(GDExtensionStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_size) { - String *dest = (String *)r_dest; - memnew_placement(dest, String); - *dest = String((const char32_t *)p_contents, p_size); +static void gdextension_string_new_with_utf32_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_size) { + memnew_placement(r_dest, String((const char32_t *)p_contents, p_size)); } -static void gdextension_string_new_with_wide_chars_and_len(GDExtensionStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_size) { - String *dest = (String *)r_dest; +static void gdextension_string_new_with_wide_chars_and_len(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_size) { if constexpr (sizeof(wchar_t) == 2) { // wchar_t is 16 bit, parse. - memnew_placement(dest, String); + memnew_placement(r_dest, String); + String *dest = reinterpret_cast(r_dest); dest->parse_utf16((const char16_t *)p_contents, p_size); } else { // wchar_t is 32 bit, copy. - memnew_placement(dest, String); - *dest = String((const char32_t *)p_contents, p_size); + memnew_placement(r_dest, String((const char32_t *)p_contents, p_size)); } } @@ -936,14 +929,13 @@ static GDExtensionVariantPtr gdextension_dictionary_operator_index_const(GDExten /* OBJECT API */ -static void gdextension_object_method_bind_call(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_arg_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error) { +static void gdextension_object_method_bind_call(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_arg_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error) { const MethodBind *mb = reinterpret_cast(p_method_bind); Object *o = (Object *)p_instance; const Variant **args = (const Variant **)p_args; Callable::CallError error; - Variant ret = mb->call(o, args, p_arg_count, error); - memnew_placement(r_return, Variant(ret)); + memnew_placement(r_return, Variant(mb->call(o, args, p_arg_count, error))); if (r_error) { r_error->error = (GDExtensionCallErrorType)(error.error); diff --git a/core/extension/gdextension_interface.h b/core/extension/gdextension_interface.h index f1412d667f1..839221c24e9 100644 --- a/core/extension/gdextension_interface.h +++ b/core/extension/gdextension_interface.h @@ -139,16 +139,37 @@ typedef enum { } GDExtensionVariantOperator; +// In this API there are multiple functions which expect the caller to pass a pointer +// on return value as parameter. +// In order to make it clear if the caller should initialize the return value or not +// we have two flavor of types: +// - `GDExtensionXXXPtr` for pointer on an initialized value +// - `GDExtensionUninitializedXXXPtr` for pointer on uninitialized value +// +// Notes: +// - Not respecting those requirements can seems harmless, but will lead to unexpected +// segfault or memory leak (for instance with a specific compiler/OS, or when two +// native extensions start doing ptrcall on each other). +// - Initialization must be done with the function pointer returned by `variant_get_ptr_constructor`, +// zero-initializing the variable should not be considered a valid initialization method here ! +// - Some types have no destructor (see `extension_api.json`'s `has_destructor` field), for +// them it is always safe to skip the constructor for the return value if you are in a hurry ;-) + typedef void *GDExtensionVariantPtr; typedef const void *GDExtensionConstVariantPtr; +typedef void *GDExtensionUninitializedVariantPtr; typedef void *GDExtensionStringNamePtr; typedef const void *GDExtensionConstStringNamePtr; +typedef void *GDExtensionUninitializedStringNamePtr; typedef void *GDExtensionStringPtr; typedef const void *GDExtensionConstStringPtr; +typedef void *GDExtensionUninitializedStringPtr; typedef void *GDExtensionObjectPtr; typedef const void *GDExtensionConstObjectPtr; +typedef void *GDExtensionUninitializedObjectPtr; typedef void *GDExtensionTypePtr; typedef const void *GDExtensionConstTypePtr; +typedef void *GDExtensionUninitializedTypePtr; typedef const void *GDExtensionMethodBindPtr; typedef int64_t GDExtensionInt; typedef uint8_t GDExtensionBool; @@ -427,37 +448,37 @@ typedef struct { /* GODOT VARIANT */ /* variant general */ - void (*variant_new_copy)(GDExtensionVariantPtr r_dest, GDExtensionConstVariantPtr p_src); - void (*variant_new_nil)(GDExtensionVariantPtr r_dest); + void (*variant_new_copy)(GDExtensionUninitializedVariantPtr r_dest, GDExtensionConstVariantPtr p_src); + void (*variant_new_nil)(GDExtensionUninitializedVariantPtr r_dest); void (*variant_destroy)(GDExtensionVariantPtr p_self); /* variant type */ - void (*variant_call)(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error); - void (*variant_call_static)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionVariantPtr r_return, GDExtensionCallError *r_error); - void (*variant_evaluate)(GDExtensionVariantOperator p_op, GDExtensionConstVariantPtr p_a, GDExtensionConstVariantPtr p_b, GDExtensionVariantPtr r_return, GDExtensionBool *r_valid); + void (*variant_call)(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error); + void (*variant_call_static)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_argument_count, GDExtensionUninitializedVariantPtr r_return, GDExtensionCallError *r_error); + void (*variant_evaluate)(GDExtensionVariantOperator p_op, GDExtensionConstVariantPtr p_a, GDExtensionConstVariantPtr p_b, GDExtensionUninitializedVariantPtr r_return, GDExtensionBool *r_valid); void (*variant_set)(GDExtensionVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid); void (*variant_set_named)(GDExtensionVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid); void (*variant_set_keyed)(GDExtensionVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid); void (*variant_set_indexed)(GDExtensionVariantPtr p_self, GDExtensionInt p_index, GDExtensionConstVariantPtr p_value, GDExtensionBool *r_valid, GDExtensionBool *r_oob); - void (*variant_get)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid); - void (*variant_get_named)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid); - void (*variant_get_keyed)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid); - void (*variant_get_indexed)(GDExtensionConstVariantPtr p_self, GDExtensionInt p_index, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid, GDExtensionBool *r_oob); - GDExtensionBool (*variant_iter_init)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionBool *r_valid); + void (*variant_get)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); + void (*variant_get_named)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); + void (*variant_get_keyed)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); + void (*variant_get_indexed)(GDExtensionConstVariantPtr p_self, GDExtensionInt p_index, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid, GDExtensionBool *r_oob); + GDExtensionBool (*variant_iter_init)(GDExtensionConstVariantPtr p_self, GDExtensionUninitializedVariantPtr r_iter, GDExtensionBool *r_valid); GDExtensionBool (*variant_iter_next)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionBool *r_valid); - void (*variant_iter_get)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionVariantPtr r_ret, GDExtensionBool *r_valid); + void (*variant_iter_get)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_iter, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool *r_valid); GDExtensionInt (*variant_hash)(GDExtensionConstVariantPtr p_self); GDExtensionInt (*variant_recursive_hash)(GDExtensionConstVariantPtr p_self, GDExtensionInt p_recursion_count); GDExtensionBool (*variant_hash_compare)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_other); GDExtensionBool (*variant_booleanize)(GDExtensionConstVariantPtr p_self); - void (*variant_duplicate)(GDExtensionConstVariantPtr p_self, GDExtensionVariantPtr r_ret, GDExtensionBool p_deep); - void (*variant_stringify)(GDExtensionConstVariantPtr p_self, GDExtensionStringPtr r_ret); + void (*variant_duplicate)(GDExtensionConstVariantPtr p_self, GDExtensionUninitializedVariantPtr r_ret, GDExtensionBool p_deep); + void (*variant_stringify)(GDExtensionConstVariantPtr p_self, GDExtensionUninitializedStringPtr r_ret); GDExtensionVariantType (*variant_get_type)(GDExtensionConstVariantPtr p_self); GDExtensionBool (*variant_has_method)(GDExtensionConstVariantPtr p_self, GDExtensionConstStringNamePtr p_method); GDExtensionBool (*variant_has_member)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member); GDExtensionBool (*variant_has_key)(GDExtensionConstVariantPtr p_self, GDExtensionConstVariantPtr p_key, GDExtensionBool *r_valid); - void (*variant_get_type_name)(GDExtensionVariantType p_type, GDExtensionStringPtr r_name); + void (*variant_get_type_name)(GDExtensionVariantType p_type, GDExtensionUninitializedStringPtr r_name); GDExtensionBool (*variant_can_convert)(GDExtensionVariantType p_from, GDExtensionVariantType p_to); GDExtensionBool (*variant_can_convert_strict)(GDExtensionVariantType p_from, GDExtensionVariantType p_to); @@ -468,7 +489,7 @@ typedef struct { GDExtensionPtrBuiltInMethod (*variant_get_ptr_builtin_method)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_method, GDExtensionInt p_hash); GDExtensionPtrConstructor (*variant_get_ptr_constructor)(GDExtensionVariantType p_type, int32_t p_constructor); GDExtensionPtrDestructor (*variant_get_ptr_destructor)(GDExtensionVariantType p_type); - void (*variant_construct)(GDExtensionVariantType p_type, GDExtensionVariantPtr p_base, const GDExtensionConstVariantPtr *p_args, int32_t p_argument_count, GDExtensionCallError *r_error); + void (*variant_construct)(GDExtensionVariantType p_type, GDExtensionUninitializedVariantPtr r_base, const GDExtensionConstVariantPtr *p_args, int32_t p_argument_count, GDExtensionCallError *r_error); GDExtensionPtrSetter (*variant_get_ptr_setter)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member); GDExtensionPtrGetter (*variant_get_ptr_getter)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_member); GDExtensionPtrIndexedSetter (*variant_get_ptr_indexed_setter)(GDExtensionVariantType p_type); @@ -476,20 +497,20 @@ typedef struct { GDExtensionPtrKeyedSetter (*variant_get_ptr_keyed_setter)(GDExtensionVariantType p_type); GDExtensionPtrKeyedGetter (*variant_get_ptr_keyed_getter)(GDExtensionVariantType p_type); GDExtensionPtrKeyedChecker (*variant_get_ptr_keyed_checker)(GDExtensionVariantType p_type); - void (*variant_get_constant_value)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_constant, GDExtensionVariantPtr r_ret); + void (*variant_get_constant_value)(GDExtensionVariantType p_type, GDExtensionConstStringNamePtr p_constant, GDExtensionUninitializedVariantPtr r_ret); GDExtensionPtrUtilityFunction (*variant_get_ptr_utility_function)(GDExtensionConstStringNamePtr p_function, GDExtensionInt p_hash); /* extra utilities */ - void (*string_new_with_latin1_chars)(GDExtensionStringPtr r_dest, const char *p_contents); - void (*string_new_with_utf8_chars)(GDExtensionStringPtr r_dest, const char *p_contents); - void (*string_new_with_utf16_chars)(GDExtensionStringPtr r_dest, const char16_t *p_contents); - void (*string_new_with_utf32_chars)(GDExtensionStringPtr r_dest, const char32_t *p_contents); - void (*string_new_with_wide_chars)(GDExtensionStringPtr r_dest, const wchar_t *p_contents); - void (*string_new_with_latin1_chars_and_len)(GDExtensionStringPtr r_dest, const char *p_contents, GDExtensionInt p_size); - void (*string_new_with_utf8_chars_and_len)(GDExtensionStringPtr r_dest, const char *p_contents, GDExtensionInt p_size); - void (*string_new_with_utf16_chars_and_len)(GDExtensionStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_size); - void (*string_new_with_utf32_chars_and_len)(GDExtensionStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_size); - void (*string_new_with_wide_chars_and_len)(GDExtensionStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_size); + void (*string_new_with_latin1_chars)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents); + void (*string_new_with_utf8_chars)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents); + void (*string_new_with_utf16_chars)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents); + void (*string_new_with_utf32_chars)(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents); + void (*string_new_with_wide_chars)(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents); + void (*string_new_with_latin1_chars_and_len)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size); + void (*string_new_with_utf8_chars_and_len)(GDExtensionUninitializedStringPtr r_dest, const char *p_contents, GDExtensionInt p_size); + void (*string_new_with_utf16_chars_and_len)(GDExtensionUninitializedStringPtr r_dest, const char16_t *p_contents, GDExtensionInt p_size); + void (*string_new_with_utf32_chars_and_len)(GDExtensionUninitializedStringPtr r_dest, const char32_t *p_contents, GDExtensionInt p_size); + void (*string_new_with_wide_chars_and_len)(GDExtensionUninitializedStringPtr r_dest, const wchar_t *p_contents, GDExtensionInt p_size); /* Information about the following functions: * - The return value is the resulting encoded string length. * - The length returned is in characters, not in bytes. It also does not include a trailing zero. @@ -564,7 +585,7 @@ typedef struct { /* OBJECT */ - void (*object_method_bind_call)(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_arg_count, GDExtensionVariantPtr r_ret, GDExtensionCallError *r_error); + void (*object_method_bind_call)(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstVariantPtr *p_args, GDExtensionInt p_arg_count, GDExtensionUninitializedVariantPtr r_ret, GDExtensionCallError *r_error); void (*object_method_bind_ptrcall)(GDExtensionMethodBindPtr p_method_bind, GDExtensionObjectPtr p_instance, const GDExtensionConstTypePtr *p_args, GDExtensionTypePtr r_ret); void (*object_destroy)(GDExtensionObjectPtr p_o); GDExtensionObjectPtr (*global_get_singleton)(GDExtensionConstStringNamePtr p_name); @@ -605,7 +626,7 @@ typedef struct { void (*classdb_register_extension_class_signal)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name, GDExtensionConstStringNamePtr p_signal_name, const GDExtensionPropertyInfo *p_argument_info, GDExtensionInt p_argument_count); void (*classdb_unregister_extension_class)(GDExtensionClassLibraryPtr p_library, GDExtensionConstStringNamePtr p_class_name); /* Unregistering a parent class before a class that inherits it will result in failure. Inheritors must be unregistered first. */ - void (*get_library_path)(GDExtensionClassLibraryPtr p_library, GDExtensionStringPtr r_path); + void (*get_library_path)(GDExtensionClassLibraryPtr p_library, GDExtensionUninitializedStringPtr r_path); } GDExtensionInterface; diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h index b7bd2a9c8c4..8013c1a32a8 100644 --- a/core/variant/variant_internal.h +++ b/core/variant/variant_internal.h @@ -1534,14 +1534,14 @@ struct VariantTypeAdjust { template struct VariantTypeConstructor { - _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) { - Variant *variant = reinterpret_cast(p_variant); - VariantInitializer::init(variant); - VariantInternalAccessor::set(variant, *((T *)p_value)); + _FORCE_INLINE_ static void variant_from_type(void *r_variant, void *p_value) { + // r_variant is provided by caller as uninitialized memory + memnew_placement(r_variant, Variant(*((T *)p_value))); } - _FORCE_INLINE_ static void type_from_variant(void *p_value, void *p_variant) { - *((T *)p_value) = VariantInternalAccessor::get(reinterpret_cast(p_variant)); + _FORCE_INLINE_ static void type_from_variant(void *r_value, void *p_variant) { + // r_value is provided by caller as uninitialized memory + memnew_placement(r_value, T(VariantInternalAccessor::get(reinterpret_cast(p_variant)))); } };