summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/core_bind.cpp60
-rw-r--r--core/core_bind.h30
-rw-r--r--core/extension/gdextension.cpp4
-rw-r--r--core/extension/gdextension_interface.cpp126
-rw-r--r--core/extension/gdextension_interface.h77
-rw-r--r--core/object/object.h41
-rw-r--r--core/templates/safe_refcount.h11
-rw-r--r--core/variant/variant_internal.h12
8 files changed, 196 insertions, 165 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp
index 8afca5a2df..47d40f2742 100644
--- a/core/core_bind.cpp
+++ b/core/core_bind.cpp
@@ -1317,11 +1317,11 @@ Variant ClassDB::instantiate(const StringName &p_class) const {
}
}
-bool ClassDB::has_signal(StringName p_class, StringName p_signal) const {
+bool ClassDB::class_has_signal(StringName p_class, StringName p_signal) const {
return ::ClassDB::has_signal(p_class, p_signal);
}
-Dictionary ClassDB::get_signal(StringName p_class, StringName p_signal) const {
+Dictionary ClassDB::class_get_signal(StringName p_class, StringName p_signal) const {
MethodInfo signal;
if (::ClassDB::get_signal(p_class, p_signal, &signal)) {
return signal.operator Dictionary();
@@ -1330,7 +1330,7 @@ Dictionary ClassDB::get_signal(StringName p_class, StringName p_signal) const {
}
}
-TypedArray<Dictionary> ClassDB::get_signal_list(StringName p_class, bool p_no_inheritance) const {
+TypedArray<Dictionary> ClassDB::class_get_signal_list(StringName p_class, bool p_no_inheritance) const {
List<MethodInfo> signals;
::ClassDB::get_signal_list(p_class, &signals, p_no_inheritance);
TypedArray<Dictionary> ret;
@@ -1342,7 +1342,7 @@ TypedArray<Dictionary> ClassDB::get_signal_list(StringName p_class, bool p_no_in
return ret;
}
-TypedArray<Dictionary> ClassDB::get_property_list(StringName p_class, bool p_no_inheritance) const {
+TypedArray<Dictionary> ClassDB::class_get_property_list(StringName p_class, bool p_no_inheritance) const {
List<PropertyInfo> plist;
::ClassDB::get_property_list(p_class, &plist, p_no_inheritance);
TypedArray<Dictionary> ret;
@@ -1353,13 +1353,13 @@ TypedArray<Dictionary> ClassDB::get_property_list(StringName p_class, bool p_no_
return ret;
}
-Variant ClassDB::get_property(Object *p_object, const StringName &p_property) const {
+Variant ClassDB::class_get_property(Object *p_object, const StringName &p_property) const {
Variant ret;
::ClassDB::get_property(p_object, p_property, ret);
return ret;
}
-Error ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const {
+Error ClassDB::class_set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const {
Variant ret;
bool valid;
if (!::ClassDB::set_property(p_object, p_property, p_value, &valid)) {
@@ -1370,11 +1370,11 @@ Error ClassDB::set_property(Object *p_object, const StringName &p_property, cons
return OK;
}
-bool ClassDB::has_method(StringName p_class, StringName p_method, bool p_no_inheritance) const {
+bool ClassDB::class_has_method(StringName p_class, StringName p_method, bool p_no_inheritance) const {
return ::ClassDB::has_method(p_class, p_method, p_no_inheritance);
}
-TypedArray<Dictionary> ClassDB::get_method_list(StringName p_class, bool p_no_inheritance) const {
+TypedArray<Dictionary> ClassDB::class_get_method_list(StringName p_class, bool p_no_inheritance) const {
List<MethodInfo> methods;
::ClassDB::get_method_list(p_class, &methods, p_no_inheritance);
TypedArray<Dictionary> ret;
@@ -1392,7 +1392,7 @@ TypedArray<Dictionary> ClassDB::get_method_list(StringName p_class, bool p_no_in
return ret;
}
-PackedStringArray ClassDB::get_integer_constant_list(const StringName &p_class, bool p_no_inheritance) const {
+PackedStringArray ClassDB::class_get_integer_constant_list(const StringName &p_class, bool p_no_inheritance) const {
List<String> constants;
::ClassDB::get_integer_constant_list(p_class, &constants, p_no_inheritance);
@@ -1406,24 +1406,24 @@ PackedStringArray ClassDB::get_integer_constant_list(const StringName &p_class,
return ret;
}
-bool ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name) const {
+bool ClassDB::class_has_integer_constant(const StringName &p_class, const StringName &p_name) const {
bool success;
::ClassDB::get_integer_constant(p_class, p_name, &success);
return success;
}
-int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name) const {
+int64_t ClassDB::class_get_integer_constant(const StringName &p_class, const StringName &p_name) const {
bool found;
int64_t c = ::ClassDB::get_integer_constant(p_class, p_name, &found);
ERR_FAIL_COND_V(!found, 0);
return c;
}
-bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) const {
+bool ClassDB::class_has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) const {
return ::ClassDB::has_enum(p_class, p_name, p_no_inheritance);
}
-PackedStringArray ClassDB::get_enum_list(const StringName &p_class, bool p_no_inheritance) const {
+PackedStringArray ClassDB::class_get_enum_list(const StringName &p_class, bool p_no_inheritance) const {
List<StringName> enums;
::ClassDB::get_enum_list(p_class, &enums, p_no_inheritance);
@@ -1437,7 +1437,7 @@ PackedStringArray ClassDB::get_enum_list(const StringName &p_class, bool p_no_in
return ret;
}
-PackedStringArray ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_enum, bool p_no_inheritance) const {
+PackedStringArray ClassDB::class_get_enum_constants(const StringName &p_class, const StringName &p_enum, bool p_no_inheritance) const {
List<StringName> constants;
::ClassDB::get_enum_constants(p_class, p_enum, &constants, p_no_inheritance);
@@ -1451,7 +1451,7 @@ PackedStringArray ClassDB::get_enum_constants(const StringName &p_class, const S
return ret;
}
-StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) const {
+StringName ClassDB::class_get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) const {
return ::ClassDB::get_integer_constant_enum(p_class, p_name, p_no_inheritance);
}
@@ -1468,27 +1468,27 @@ void ClassDB::_bind_methods() {
::ClassDB::bind_method(D_METHOD("can_instantiate", "class"), &ClassDB::can_instantiate);
::ClassDB::bind_method(D_METHOD("instantiate", "class"), &ClassDB::instantiate);
- ::ClassDB::bind_method(D_METHOD("class_has_signal", "class", "signal"), &ClassDB::has_signal);
- ::ClassDB::bind_method(D_METHOD("class_get_signal", "class", "signal"), &ClassDB::get_signal);
- ::ClassDB::bind_method(D_METHOD("class_get_signal_list", "class", "no_inheritance"), &ClassDB::get_signal_list, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_has_signal", "class", "signal"), &ClassDB::class_has_signal);
+ ::ClassDB::bind_method(D_METHOD("class_get_signal", "class", "signal"), &ClassDB::class_get_signal);
+ ::ClassDB::bind_method(D_METHOD("class_get_signal_list", "class", "no_inheritance"), &ClassDB::class_get_signal_list, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_get_property_list", "class", "no_inheritance"), &ClassDB::get_property_list, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_get_property", "object", "property"), &ClassDB::get_property);
- ::ClassDB::bind_method(D_METHOD("class_set_property", "object", "property", "value"), &ClassDB::set_property);
+ ::ClassDB::bind_method(D_METHOD("class_get_property_list", "class", "no_inheritance"), &ClassDB::class_get_property_list, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_get_property", "object", "property"), &ClassDB::class_get_property);
+ ::ClassDB::bind_method(D_METHOD("class_set_property", "object", "property", "value"), &ClassDB::class_set_property);
- ::ClassDB::bind_method(D_METHOD("class_has_method", "class", "method", "no_inheritance"), &ClassDB::has_method, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_has_method", "class", "method", "no_inheritance"), &ClassDB::class_has_method, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_get_method_list", "class", "no_inheritance"), &ClassDB::get_method_list, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_get_method_list", "class", "no_inheritance"), &ClassDB::class_get_method_list, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_get_integer_constant_list", "class", "no_inheritance"), &ClassDB::get_integer_constant_list, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_get_integer_constant_list", "class", "no_inheritance"), &ClassDB::class_get_integer_constant_list, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_has_integer_constant", "class", "name"), &ClassDB::has_integer_constant);
- ::ClassDB::bind_method(D_METHOD("class_get_integer_constant", "class", "name"), &ClassDB::get_integer_constant);
+ ::ClassDB::bind_method(D_METHOD("class_has_integer_constant", "class", "name"), &ClassDB::class_has_integer_constant);
+ ::ClassDB::bind_method(D_METHOD("class_get_integer_constant", "class", "name"), &ClassDB::class_get_integer_constant);
- ::ClassDB::bind_method(D_METHOD("class_has_enum", "class", "name", "no_inheritance"), &ClassDB::has_enum, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_get_enum_list", "class", "no_inheritance"), &ClassDB::get_enum_list, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_get_enum_constants", "class", "enum", "no_inheritance"), &ClassDB::get_enum_constants, DEFVAL(false));
- ::ClassDB::bind_method(D_METHOD("class_get_integer_constant_enum", "class", "name", "no_inheritance"), &ClassDB::get_integer_constant_enum, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_has_enum", "class", "name", "no_inheritance"), &ClassDB::class_has_enum, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_get_enum_list", "class", "no_inheritance"), &ClassDB::class_get_enum_list, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_get_enum_constants", "class", "enum", "no_inheritance"), &ClassDB::class_get_enum_constants, DEFVAL(false));
+ ::ClassDB::bind_method(D_METHOD("class_get_integer_constant_enum", "class", "name", "no_inheritance"), &ClassDB::class_get_integer_constant_enum, DEFVAL(false));
::ClassDB::bind_method(D_METHOD("is_class_enabled", "class"), &ClassDB::is_class_enabled);
}
diff --git a/core/core_bind.h b/core/core_bind.h
index be43ae2c9d..6083cf2e2f 100644
--- a/core/core_bind.h
+++ b/core/core_bind.h
@@ -424,26 +424,26 @@ public:
bool can_instantiate(const StringName &p_class) const;
Variant instantiate(const StringName &p_class) const;
- bool has_signal(StringName p_class, StringName p_signal) const;
- Dictionary get_signal(StringName p_class, StringName p_signal) const;
- TypedArray<Dictionary> get_signal_list(StringName p_class, bool p_no_inheritance = false) const;
+ bool class_has_signal(StringName p_class, StringName p_signal) const;
+ Dictionary class_get_signal(StringName p_class, StringName p_signal) const;
+ TypedArray<Dictionary> class_get_signal_list(StringName p_class, bool p_no_inheritance = false) const;
- TypedArray<Dictionary> get_property_list(StringName p_class, bool p_no_inheritance = false) const;
- Variant get_property(Object *p_object, const StringName &p_property) const;
- Error set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const;
+ TypedArray<Dictionary> class_get_property_list(StringName p_class, bool p_no_inheritance = false) const;
+ Variant class_get_property(Object *p_object, const StringName &p_property) const;
+ Error class_set_property(Object *p_object, const StringName &p_property, const Variant &p_value) const;
- bool has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false) const;
+ bool class_has_method(StringName p_class, StringName p_method, bool p_no_inheritance = false) const;
- TypedArray<Dictionary> get_method_list(StringName p_class, bool p_no_inheritance = false) const;
+ TypedArray<Dictionary> class_get_method_list(StringName p_class, bool p_no_inheritance = false) const;
- PackedStringArray get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const;
- bool has_integer_constant(const StringName &p_class, const StringName &p_name) const;
- int64_t get_integer_constant(const StringName &p_class, const StringName &p_name) const;
+ PackedStringArray class_get_integer_constant_list(const StringName &p_class, bool p_no_inheritance = false) const;
+ bool class_has_integer_constant(const StringName &p_class, const StringName &p_name) const;
+ int64_t class_get_integer_constant(const StringName &p_class, const StringName &p_name) const;
- bool has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false) const;
- PackedStringArray get_enum_list(const StringName &p_class, bool p_no_inheritance = false) const;
- PackedStringArray get_enum_constants(const StringName &p_class, const StringName &p_enum, bool p_no_inheritance = false) const;
- StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false) const;
+ bool class_has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false) const;
+ PackedStringArray class_get_enum_list(const StringName &p_class, bool p_no_inheritance = false) const;
+ PackedStringArray class_get_enum_constants(const StringName &p_class, const StringName &p_enum, bool p_no_inheritance = false) const;
+ StringName class_get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false) const;
bool is_class_enabled(StringName p_class) const;
diff --git a/core/extension/gdextension.cpp b/core/extension/gdextension.cpp
index 91038b9bdf..af7c37b4b6 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<GDExtension *>(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 96a57115bf..b5ec04b12d 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<Variant *>(r_dest), Variant(*reinterpret_cast<const Variant *>(p_src)));
}
-static void gdextension_variant_new_nil(GDExtensionVariantPtr r_dest) {
+static void gdextension_variant_new_nil(GDExtensionUninitializedVariantPtr r_dest) {
memnew_placement(reinterpret_cast<Variant *>(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<const StringName *>(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<Variant *>(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<const StringName *>(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<Variant *>(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<Variant *>(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<Variant *>(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<Variant *>(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<const StringName *>(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<String *>(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<String *>(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<String *>(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<String *>(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<String *>(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<String *>(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<const MethodBind *>(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 f1412d667f..839221c24e 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/object/object.h b/core/object/object.h
index ae22851c15..c4d287a71c 100644
--- a/core/object/object.h
+++ b/core/object/object.h
@@ -836,14 +836,21 @@ public:
/* SCRIPT */
- void set_script(const Variant &p_script);
- Variant get_script() const;
+// When in debug, some non-virtual functions can be overridden for multithreaded guards.
+#ifdef DEBUG_ENABLED
+#define MTVIRTUAL virtual
+#else
+#define MTVIRTUAL
+#endif
+
+ MTVIRTUAL void set_script(const Variant &p_script);
+ MTVIRTUAL Variant get_script() const;
- bool has_meta(const StringName &p_name) const;
- void set_meta(const StringName &p_name, const Variant &p_value);
- void remove_meta(const StringName &p_name);
- Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const;
- void get_meta_list(List<StringName> *p_list) const;
+ MTVIRTUAL bool has_meta(const StringName &p_name) const;
+ MTVIRTUAL void set_meta(const StringName &p_name, const Variant &p_value);
+ MTVIRTUAL void remove_meta(const StringName &p_name);
+ MTVIRTUAL Variant get_meta(const StringName &p_name, const Variant &p_default = Variant()) const;
+ MTVIRTUAL void get_meta_list(List<StringName> *p_list) const;
#ifdef TOOLS_ENABLED
void set_edited(bool p_edited);
@@ -870,17 +877,17 @@ public:
return emit_signalp(p_name, sizeof...(p_args) == 0 ? nullptr : (const Variant **)argptrs, sizeof...(p_args));
}
- Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount);
- bool has_signal(const StringName &p_name) const;
- void get_signal_list(List<MethodInfo> *p_signals) const;
- void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
- void get_all_signal_connections(List<Connection> *p_connections) const;
- int get_persistent_signal_connection_count() const;
- void get_signals_connected_to_this(List<Connection> *p_connections) const;
+ MTVIRTUAL Error emit_signalp(const StringName &p_name, const Variant **p_args, int p_argcount);
+ MTVIRTUAL bool has_signal(const StringName &p_name) const;
+ MTVIRTUAL void get_signal_list(List<MethodInfo> *p_signals) const;
+ MTVIRTUAL void get_signal_connection_list(const StringName &p_signal, List<Connection> *p_connections) const;
+ MTVIRTUAL void get_all_signal_connections(List<Connection> *p_connections) const;
+ MTVIRTUAL int get_persistent_signal_connection_count() const;
+ MTVIRTUAL void get_signals_connected_to_this(List<Connection> *p_connections) const;
- Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0);
- void disconnect(const StringName &p_signal, const Callable &p_callable);
- bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
+ MTVIRTUAL Error connect(const StringName &p_signal, const Callable &p_callable, uint32_t p_flags = 0);
+ MTVIRTUAL void disconnect(const StringName &p_signal, const Callable &p_callable);
+ MTVIRTUAL bool is_connected(const StringName &p_signal, const Callable &p_callable) const;
template <typename... VarArgs>
void call_deferred(const StringName &p_name, VarArgs... p_args) {
diff --git a/core/templates/safe_refcount.h b/core/templates/safe_refcount.h
index 58ed019287..8669bcaeeb 100644
--- a/core/templates/safe_refcount.h
+++ b/core/templates/safe_refcount.h
@@ -102,6 +102,17 @@ public:
return value.fetch_sub(p_value, std::memory_order_acq_rel) - p_value;
}
+ _ALWAYS_INLINE_ T bit_or(T p_value) {
+ return value.fetch_or(p_value, std::memory_order_acq_rel);
+ }
+ _ALWAYS_INLINE_ T bit_and(T p_value) {
+ return value.fetch_and(p_value, std::memory_order_acq_rel);
+ }
+
+ _ALWAYS_INLINE_ T bit_xor(T p_value) {
+ return value.fetch_xor(p_value, std::memory_order_acq_rel);
+ }
+
// Returns the original value instead of the new one
_ALWAYS_INLINE_ T postsub(T p_value) {
return value.fetch_sub(p_value, std::memory_order_acq_rel);
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index b7bd2a9c8c..8013c1a32a 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -1534,14 +1534,14 @@ struct VariantTypeAdjust<Object *> {
template <class T>
struct VariantTypeConstructor {
- _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) {
- Variant *variant = reinterpret_cast<Variant *>(p_variant);
- VariantInitializer<T>::init(variant);
- VariantInternalAccessor<T>::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<T>::get(reinterpret_cast<Variant *>(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<T>::get(reinterpret_cast<Variant *>(p_variant))));
}
};