diff --git a/core/variant/variant.cpp b/core/variant/variant.cpp index fcfa5303889..3d11ed63032 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(static_cast(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 b75882a87c4..836a67d9420 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 aaafa2f6b6b..3696ffae609 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 { _FORCE_INLINE_ static void variant_from_type(void *p_variant, void *p_value) { Variant *variant = reinterpret_cast(p_variant); VariantInitializer::init(variant); - Object *value = *(reinterpret_cast(p_value)); - if (value) { - VariantInternalAccessor::set(variant, value); - VariantInternalAccessor::set(variant, value->get_instance_id()); + Object *object = *(reinterpret_cast(p_value)); + if (object) { + if (object->is_ref_counted()) { + if (!VariantInternal::initialize_ref(object)) { + return; + } + } + VariantInternalAccessor::set(variant, object); + VariantInternalAccessor::set(variant, object->get_instance_id()); } }