Browse Source

Fix base script not initialized properly in some cases

Storing script references to pointer only in result.script_type could
lead to losing the last reference, causing further conversions from
Script* to Ref<Script> to fail.

Now result.script_type_ref is always set first, and then cleared in the
specific case of the script being the owner, to avoid cyclic reference
issues.
PouleyKetchoupp 4 years ago
parent
commit
87d73faa66
1 changed files with 8 additions and 5 deletions
  1. 8 5
      modules/gdscript/gdscript_compiler.cpp

+ 8 - 5
modules/gdscript/gdscript_compiler.cpp

@@ -98,7 +98,8 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
 		} break;
 		} break;
 		case GDScriptParser::DataType::SCRIPT: {
 		case GDScriptParser::DataType::SCRIPT: {
 			result.kind = GDScriptDataType::SCRIPT;
 			result.kind = GDScriptDataType::SCRIPT;
-			result.script_type = Ref<Script>(p_datatype.script_type).ptr();
+			result.script_type_ref = Ref<Script>(p_datatype.script_type);
+			result.script_type = result.script_type_ref.ptr();
 			result.native_type = result.script_type->get_instance_base_type();
 			result.native_type = result.script_type->get_instance_base_type();
 		} break;
 		} break;
 		case GDScriptParser::DataType::CLASS: {
 		case GDScriptParser::DataType::CLASS: {
@@ -124,11 +125,13 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
 						names.pop_back();
 						names.pop_back();
 					}
 					}
 					result.kind = GDScriptDataType::GDSCRIPT;
 					result.kind = GDScriptDataType::GDSCRIPT;
-					result.script_type = script.ptr();
+					result.script_type_ref = script;
+					result.script_type = result.script_type_ref.ptr();
 					result.native_type = script->get_instance_base_type();
 					result.native_type = script->get_instance_base_type();
 				} else {
 				} else {
 					result.kind = GDScriptDataType::GDSCRIPT;
 					result.kind = GDScriptDataType::GDSCRIPT;
-					result.script_type = GDScriptCache::get_shallow_script(p_datatype.script_path, main_script->path).ptr();
+					result.script_type_ref = GDScriptCache::get_shallow_script(p_datatype.script_path, main_script->path);
+					result.script_type = result.script_type_ref.ptr();
 					result.native_type = p_datatype.native_type;
 					result.native_type = p_datatype.native_type;
 				}
 				}
 			}
 			}
@@ -151,8 +154,8 @@ GDScriptDataType GDScriptCompiler::_gdtype_from_datatype(const GDScriptParser::D
 
 
 	// Only hold strong reference to the script if it's not the owner of the
 	// Only hold strong reference to the script if it's not the owner of the
 	// element qualified with this type, to avoid cyclic references (leaks).
 	// element qualified with this type, to avoid cyclic references (leaks).
-	if (result.script_type && result.script_type != p_owner) {
-		result.script_type_ref = Ref<Script>(result.script_type);
+	if (result.script_type && result.script_type == p_owner) {
+		result.script_type_ref = Ref<Script>();
 	}
 	}
 
 
 	return result;
 	return result;