Browse Source

Merge pull request #38257 from RandomShaper/imvu/fix_variantrc_gdnative

Fix GDNative compat breakage due to dangling Variants fix
Rémi Verschelde 5 năm trước cách đây
mục cha
commit
78f0cf40cb
5 tập tin đã thay đổi với 22 bổ sung25 xóa
  1. 7 1
      core/object_rc.h
  2. 2 5
      core/variant.cpp
  3. 0 6
      core/variant.h
  4. 4 4
      core/variant_call.cpp
  5. 9 9
      core/variant_op.cpp

+ 7 - 1
core/object_rc.h

@@ -46,6 +46,11 @@ class ObjectRC {
 	std::atomic<uint32_t> _users;
 
 public:
+	// This is for allowing debug builds to check for instance ID validity,
+	// so warnings are shown in debug builds when a stray Variant (one pointing
+	// to a released Object) would have happened.
+	const ObjectID instance_id;
+
 	_FORCE_INLINE_ void increment() {
 		_users.fetch_add(1, std::memory_order_relaxed);
 	}
@@ -63,7 +68,8 @@ public:
 		return _ptr.load(std::memory_order_acquire);
 	}
 
-	_FORCE_INLINE_ ObjectRC(Object *p_object) {
+	_FORCE_INLINE_ ObjectRC(Object *p_object) :
+			instance_id(p_object->get_instance_id()) {
 		// 1 (the Object) + 1 (the first user)
 		_users.store(2, std::memory_order_relaxed);
 		_ptr.store(p_object, std::memory_order_release);

+ 2 - 5
core/variant.cpp

@@ -1125,7 +1125,6 @@ void Variant::clear() {
 				if (_get_obj().rc->decrement()) {
 					memfree(_get_obj().rc);
 				}
-				_get_obj().instance_id = 0;
 			} else {
 				_get_obj().ref.unref();
 			}
@@ -1602,7 +1601,7 @@ String Variant::stringify(List<const void *> &stack) const {
 				return obj->to_string();
 			} else {
 #ifdef DEBUG_ENABLED
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					return "[Deleted Object]";
 				}
 #endif
@@ -1765,7 +1764,7 @@ Variant::operator RID() const {
 #ifdef DEBUG_ENABLED
 			Object *obj = _get_obj().rc->get_ptr();
 			if (unlikely(!obj)) {
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted get RID on a deleted object.");
 				}
 			}
@@ -2318,7 +2317,6 @@ Variant::Variant(const RefPtr &p_resource) {
 	memnew_placement(_data._mem, ObjData);
 #ifdef DEBUG_ENABLED
 	_get_obj().rc = NULL;
-	_get_obj().instance_id = 0;
 #else
 	REF *ref = reinterpret_cast<REF *>(p_resource.get_data());
 	_get_obj().obj = ref->ptr();
@@ -2339,7 +2337,6 @@ Variant::Variant(const Object *p_object) {
 	memnew_placement(_data._mem, ObjData);
 #ifdef DEBUG_ENABLED
 	_get_obj().rc = p_object ? const_cast<Object *>(p_object)->_use_rc() : NULL;
-	_get_obj().instance_id = p_object ? p_object->get_instance_id() : 0;
 #else
 	_get_obj().obj = const_cast<Object *>(p_object);
 #endif

+ 0 - 6
core/variant.h

@@ -139,12 +139,6 @@ private:
 		// Will be null for every type deriving from Reference as they have their
 		// own reference count mechanism
 		ObjectRC *rc;
-		// This is for allowing debug build to check for instance ID validity,
-		// so warnings are shown in debug builds when a stray Variant (one pointing
-		// to a released Object) would have happened.
-		// If it's zero, that means the Variant is has a legit null object value,
-		// thus not needing instance id validation.
-		ObjectID instance_id;
 #else
 		Object *obj;
 #endif

+ 4 - 4
core/variant_call.cpp

@@ -1098,8 +1098,8 @@ void Variant::call_ptr(const StringName &p_method, const Variant **p_args, int p
 		Object *obj = _OBJ_PTR(*this);
 		if (!obj) {
 #ifdef DEBUG_ENABLED
-			if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
-				WARN_PRINT("Attempted call on stray pointer object.");
+			if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
+				WARN_PRINT("Attempted call on a deleted object.");
 			}
 #endif
 			r_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
@@ -1275,8 +1275,8 @@ bool Variant::has_method(const StringName &p_method) const {
 		Object *obj = _OBJ_PTR(*this);
 		if (!obj) {
 #ifdef DEBUG_ENABLED
-			if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
-				WARN_PRINT("Attempted method check on stray pointer object.");
+			if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
+				WARN_PRINT("Attempted method check on a deleted object.");
 			}
 #endif
 			return false;

+ 9 - 9
core/variant_op.cpp

@@ -1516,7 +1516,7 @@ void Variant::set_named(const StringName &p_index, const Variant &p_value, bool
 			Object *obj = _OBJ_PTR(*this);
 #ifdef DEBUG_ENABLED
 			if (unlikely(!obj)) {
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted set on a deleted object.");
 				}
 				break;
@@ -1684,7 +1684,7 @@ Variant Variant::get_named(const StringName &p_index, bool *r_valid) const {
 			if (unlikely(!obj)) {
 				if (r_valid)
 					*r_valid = false;
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted get on a deleted object.");
 				}
 				return Variant();
@@ -2169,7 +2169,7 @@ void Variant::set(const Variant &p_index, const Variant &p_value, bool *r_valid)
 			if (unlikely(!obj)) {
 #ifdef DEBUG_ENABLED
 				valid = false;
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted set on a deleted object.");
 				}
 #endif
@@ -2539,7 +2539,7 @@ Variant Variant::get(const Variant &p_index, bool *r_valid) const {
 			if (unlikely(!obj)) {
 #ifdef DEBUG_ENABLED
 				valid = false;
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted get on a deleted object.");
 				}
 #endif
@@ -2602,7 +2602,7 @@ bool Variant::in(const Variant &p_index, bool *r_valid) const {
 				if (r_valid) {
 					*r_valid = false;
 				}
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted 'in' on a deleted object.");
 				}
 #endif
@@ -2865,7 +2865,7 @@ void Variant::get_property_list(List<PropertyInfo> *p_list) const {
 			Object *obj = _OBJ_PTR(*this);
 			if (unlikely(!obj)) {
 #ifdef DEBUG_ENABLED
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted get property list on a deleted object.");
 				}
 #endif
@@ -2943,7 +2943,7 @@ bool Variant::iter_init(Variant &r_iter, bool &valid) const {
 #ifdef DEBUG_ENABLED
 			if (unlikely(!obj)) {
 				valid = false;
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted iteration start on a deleted object.");
 				}
 				return false;
@@ -3110,7 +3110,7 @@ bool Variant::iter_next(Variant &r_iter, bool &valid) const {
 #ifdef DEBUG_ENABLED
 			if (unlikely(!obj)) {
 				valid = false;
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted iteration check next on a deleted object.");
 				}
 				return false;
@@ -3268,7 +3268,7 @@ Variant Variant::iter_get(const Variant &r_iter, bool &r_valid) const {
 #ifdef DEBUG_ENABLED
 			if (unlikely(!obj)) {
 				r_valid = false;
-				if (ScriptDebugger::get_singleton() && _get_obj().instance_id != 0 && !ObjectDB::get_instance(_get_obj().instance_id)) {
+				if (ScriptDebugger::get_singleton() && _get_obj().rc && !ObjectDB::get_instance(_get_obj().rc->instance_id)) {
 					WARN_PRINT("Attempted iteration get next on a deleted object.");
 				}
 				return Variant();