summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorreduz <reduzio@gmail.com>2022-02-11 12:30:49 +0100
committerreduz <reduzio@gmail.com>2022-02-11 12:30:49 +0100
commit3ad3a430638af0b64511d90d367e3b35245d9b48 (patch)
tree4536dfcd2f0929cb6e848b1fdff4fb08577430c5 /core
parent3aa7b7eaf2c24cc3e91d6a4155c0d6bdce88d91b (diff)
Fix Variant Ref<> assignment.
-Creating from object pointer via funcptr API was missing reference initialization. -Supersedes https://github.com/godotengine/godot-cpp/pull/662 -Fixes several crashes in GDExtension
Diffstat (limited to 'core')
-rw-r--r--core/variant/variant.cpp7
-rw-r--r--core/variant/variant.h1
-rw-r--r--core/variant/variant_internal.h17
3 files changed, 21 insertions, 4 deletions
diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp
index fcfa530388..3d11ed6303 100644
--- a/core/variant/variant.cpp
+++ b/core/variant/variant.cpp
@@ -1023,6 +1023,13 @@ bool Variant::is_null() const {
}
}
+bool Variant::initialize_ref(Object *p_object) {
+ RefCounted *ref_counted = const_cast<RefCounted *>(static_cast<const RefCounted *>(p_object));
+ if (!ref_counted->init_ref()) {
+ return false;
+ }
+ return true;
+}
void Variant::reference(const Variant &p_variant) {
switch (type) {
case NIL:
diff --git a/core/variant/variant.h b/core/variant/variant.h
index b75882a87c..836a67d942 100644
--- a/core/variant/variant.h
+++ b/core/variant/variant.h
@@ -216,6 +216,7 @@ private:
} _data alignas(8);
void reference(const Variant &p_variant);
+ static bool initialize_ref(Object *p_object);
void _clear_internal();
diff --git a/core/variant/variant_internal.h b/core/variant/variant_internal.h
index aaafa2f6b6..3696ffae60 100644
--- a/core/variant/variant_internal.h
+++ b/core/variant/variant_internal.h
@@ -111,6 +111,10 @@ public:
}
}
+ _FORCE_INLINE_ static bool initialize_ref(Object *object) {
+ return Variant::initialize_ref(object);
+ }
+
// Atomic types.
_FORCE_INLINE_ static bool *get_bool(Variant *v) { return &v->_data._bool; }
_FORCE_INLINE_ static const bool *get_bool(const Variant *v) { return &v->_data._bool; }
@@ -1430,10 +1434,15 @@ struct VariantTypeConstructor<Object *> {
_FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) {
Variant *variant = reinterpret_cast<Variant *>(p_variant);
VariantInitializer<Object *>::init(variant);
- Object *value = *(reinterpret_cast<Object **>(p_value));
- if (value) {
- VariantInternalAccessor<Object *>::set(variant, value);
- VariantInternalAccessor<ObjectID>::set(variant, value->get_instance_id());
+ Object *object = *(reinterpret_cast<Object **>(p_value));
+ if (object) {
+ if (object->is_ref_counted()) {
+ if (!VariantInternal::initialize_ref(object)) {
+ return;
+ }
+ }
+ VariantInternalAccessor<Object *>::set(variant, object);
+ VariantInternalAccessor<ObjectID>::set(variant, object->get_instance_id());
}
}