From e360dc9a79703add684bc7e36f35a198cf2c6043 Mon Sep 17 00:00:00 2001 From: George Marques Date: Wed, 19 Feb 2020 09:15:16 -0300 Subject: [PATCH 1/3] GDScript: Remove self static reference and create one on calls This is needed because of the new changes to Variant. The reference counter is increased by adding it to a Variant, which means no GDScript will be freed (or will be double freed if manually freed somewhere). (cherry picked from commit 4d960efafc64f0f94f68158ca49ed7f3dd9742dc) --- modules/gdscript/gdscript.cpp | 1 - modules/gdscript/gdscript.h | 1 - modules/gdscript/gdscript_function.cpp | 15 ++++++++------- modules/gdscript/gdscript_function.h | 2 +- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/gdscript/gdscript.cpp b/modules/gdscript/gdscript.cpp index 51a5584920fa..f020b46866c2 100644 --- a/modules/gdscript/gdscript.cpp +++ b/modules/gdscript/gdscript.cpp @@ -914,7 +914,6 @@ void GDScript::get_script_signal_list(List *r_signals) const { GDScript::GDScript() : script_list(this) { - _static_ref = this; valid = false; subclass_count = 0; initializer = NULL; diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 029a5ba9b803..e51134fc9959 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -73,7 +73,6 @@ class GDScript : public Script { friend class GDScriptFunctions; friend class GDScriptLanguage; - Variant _static_ref; //used for static call Ref native; Ref base; GDScript *_base; //fast pointer access diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 82829856dfaf..92c0f7e5ce96 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -34,7 +34,7 @@ #include "gdscript.h" #include "gdscript_functions.h" -Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const { +Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const { int address = p_address & ADDR_MASK; @@ -52,7 +52,7 @@ Variant *GDScriptFunction::_get_variant(int p_address, GDScriptInstance *p_insta } break; case ADDR_TYPE_CLASS: { - return &p_script->_static_ref; + return &static_ref; } break; case ADDR_TYPE_MEMBER: { #ifdef DEBUG_ENABLED @@ -269,6 +269,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a r_err.error = Variant::CallError::CALL_OK; Variant self; + Variant static_ref; Variant retvalue; Variant *stack = NULL; Variant **call_args; @@ -403,10 +404,10 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define CHECK_SPACE(m_space) \ GD_ERR_BREAK((ip + m_space) > _code_size) -#define GET_VARIANT_PTR(m_v, m_code_ofs) \ - Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); \ - if (unlikely(!m_v)) \ +#define GET_VARIANT_PTR(m_v, m_code_ofs) \ + Variant *m_v; \ + m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text); \ + if (unlikely(!m_v)) \ OPCODE_BREAK; #else @@ -414,7 +415,7 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a #define CHECK_SPACE(m_space) #define GET_VARIANT_PTR(m_v, m_code_ofs) \ Variant *m_v; \ - m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, stack, err_text); + m_v = _get_variant(_code_ptr[ip + m_code_ofs], p_instance, script, self, static_ref, stack, err_text); #endif diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index c2084d6a51d5..979c35ef0746 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -267,7 +267,7 @@ class GDScriptFunction { List stack_debug; - _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant *p_stack, String &r_error) const; + _FORCE_INLINE_ Variant *_get_variant(int p_address, GDScriptInstance *p_instance, GDScript *p_script, Variant &self, Variant &static_ref, Variant *p_stack, String &r_error) const; _FORCE_INLINE_ String _get_call_error(const Variant::CallError &p_err, const String &p_where, const Variant **argptrs) const; friend class GDScriptLanguage; From 798ee982ac3539e12745b9273a7b52e5ca20168c Mon Sep 17 00:00:00 2001 From: George Marques Date: Fri, 29 May 2020 10:58:46 -0300 Subject: [PATCH 2/3] Actually set GDScript static reference (cherry picked from commit 0f1da724924fc494bfd316c57757e0e1d7b90143) --- modules/gdscript/gdscript_function.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/gdscript/gdscript_function.cpp b/modules/gdscript/gdscript_function.cpp index 92c0f7e5ce96..f35f858b198e 100644 --- a/modules/gdscript/gdscript_function.cpp +++ b/modules/gdscript/gdscript_function.cpp @@ -386,6 +386,8 @@ Variant GDScriptFunction::call(GDScriptInstance *p_instance, const Variant **p_a } } + static_ref = script; + String err_text; #ifdef DEBUG_ENABLED From 1e9a774ac24ecbbec9b0aa4b903f3f1525f4d525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pedro=20J=2E=20Est=C3=A9banez?= Date: Sat, 24 Oct 2020 13:50:58 +0200 Subject: [PATCH 3/3] Make Variant aware that an Object may be a Reference --- core/variant.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/core/variant.cpp b/core/variant.cpp index 1a2b4d934b7d..3a7b08fd0ea7 100644 --- a/core/variant.cpp +++ b/core/variant.cpp @@ -2338,12 +2338,20 @@ Variant::Variant(const RID &p_rid) { Variant::Variant(const Object *p_object) { type = OBJECT; + Object *obj = const_cast(p_object); memnew_placement(_data._mem, ObjData); + Reference *ref = Object::cast_to(obj); + if (unlikely(ref)) { + *reinterpret_cast *>(_get_obj().ref.get_data()) = Ref(ref); #ifdef DEBUG_ENABLED - _get_obj().rc = p_object ? const_cast(p_object)->_use_rc() : NULL; -#else - _get_obj().obj = const_cast(p_object); + _get_obj().rc = NULL; + } else { + _get_obj().rc = likely(obj) ? obj->_use_rc() : NULL; +#endif + } +#if !defined(DEBUG_ENABLED) + _get_obj().obj = obj; #endif }