Pārlūkot izejas kodu

GDScript: Fix crash in disassembler

Danil Alexeev 2 gadi atpakaļ
vecāks
revīzija
5d3f5e8cf2
1 mainītis faili ar 48 papildinājumiem un 25 dzēšanām
  1. 48 25
      modules/gdscript/gdscript_disassembler.cpp

+ 48 - 25
modules/gdscript/gdscript_disassembler.cpp

@@ -35,6 +35,22 @@
 
 #include "core/string/string_builder.h"
 
+static String _get_script_name(const Ref<Script> &p_script) {
+	if (p_script.is_valid()) {
+		if (p_script->get_global_name() != StringName()) {
+			return p_script->get_global_name();
+		}
+		GDScript *gdscript = Object::cast_to<GDScript>(p_script.ptr());
+		if (gdscript) {
+			return gdscript->get_fully_qualified_name().get_file();
+		}
+		if (!p_script->get_path().is_empty()) {
+			return p_script->get_path().get_file();
+		}
+	}
+	return "<unknown script>";
+}
+
 static String _get_variant_string(const Variant &p_variant) {
 	String txt;
 	if (p_variant.get_type() == Variant::STRING) {
@@ -50,12 +66,17 @@ static String _get_variant_string(const Variant &p_variant) {
 		} else {
 			GDScriptNativeClass *cls = Object::cast_to<GDScriptNativeClass>(obj);
 			if (cls) {
-				txt += cls->get_name();
-				txt += " (class)";
+				txt = "class(" + cls->get_name() + ")";
 			} else {
-				txt = obj->get_class();
-				if (obj->get_script_instance()) {
-					txt += "(" + obj->get_script_instance()->get_script()->get_path() + ")";
+				Script *script = Object::cast_to<Script>(obj);
+				if (script) {
+					txt = "script(" + _get_script_name(script) + ")";
+				} else {
+					txt = "object(" + obj->get_class();
+					if (obj->get_script_instance()) {
+						txt += ", " + _get_script_name(obj->get_script_instance()->get_script());
+					}
+					txt += ")";
 				}
 			}
 		}
@@ -69,12 +90,6 @@ static String _disassemble_address(const GDScript *p_script, const GDScriptFunct
 	int addr = p_address & GDScriptFunction::ADDR_MASK;
 
 	switch (p_address >> GDScriptFunction::ADDR_BITS) {
-		case GDScriptFunction::ADDR_TYPE_MEMBER: {
-			return "member(" + p_script->debug_get_member_by_index(addr) + ")";
-		} break;
-		case GDScriptFunction::ADDR_TYPE_CONSTANT: {
-			return "const(" + _get_variant_string(p_function.get_constant(addr)) + ")";
-		} break;
 		case GDScriptFunction::ADDR_TYPE_STACK: {
 			switch (addr) {
 				case GDScriptFunction::ADDR_STACK_SELF:
@@ -87,6 +102,12 @@ static String _disassemble_address(const GDScript *p_script, const GDScriptFunct
 					return "stack(" + itos(addr) + ")";
 			}
 		} break;
+		case GDScriptFunction::ADDR_TYPE_CONSTANT: {
+			return "const(" + _get_variant_string(p_function.get_constant(addr)) + ")";
+		} break;
+		case GDScriptFunction::ADDR_TYPE_MEMBER: {
+			return "member(" + p_script->debug_get_member_by_index(addr) + ")";
+		} break;
 	}
 
 	return "<err>";
@@ -152,12 +173,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
 				text += DADDR(2);
 				text += " is Array[";
 
-				Ref<Script> script_type = get_constant(_code_ptr[ip + 3] & GDScriptFunction::ADDR_MASK);
+				Ref<Script> script_type = get_constant(_code_ptr[ip + 3] & ADDR_MASK);
 				Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 4];
 				StringName native_type = get_global_name(_code_ptr[ip + 5]);
 
 				if (script_type.is_valid() && script_type->is_valid()) {
-					text += script_type->get_path();
+					text += "script(";
+					text += _get_script_name(script_type);
+					text += ")";
 				} else if (native_type != StringName()) {
 					text += native_type;
 				} else {
@@ -313,9 +336,10 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
 				incr += 3;
 			} break;
 			case OPCODE_SET_STATIC_VARIABLE: {
+				Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
+
 				text += "set_static_variable script(";
-				Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & GDScriptFunction::ADDR_MASK);
-				text += gdscript.is_valid() ? gdscript->get_fully_qualified_name().get_file() : "<unknown script>";
+				text += _get_script_name(gdscript);
 				text += ")";
 				if (gdscript.is_valid()) {
 					text += "[\"" + gdscript->debug_get_static_var_by_index(_code_ptr[ip + 3]) + "\"]";
@@ -328,11 +352,12 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
 				incr += 4;
 			} break;
 			case OPCODE_GET_STATIC_VARIABLE: {
+				Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
+
 				text += "get_static_variable ";
 				text += DADDR(1);
 				text += " = script(";
-				Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & GDScriptFunction::ADDR_MASK);
-				text += gdscript.is_valid() ? gdscript->get_fully_qualified_name().get_file() : "<unknown script>";
+				text += _get_script_name(gdscript);
 				text += ")";
 				if (gdscript.is_valid()) {
 					text += "[\"" + gdscript->debug_get_static_var_by_index(_code_ptr[ip + 3]) + "\"]";
@@ -393,11 +418,10 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
 				incr += 4;
 			} break;
 			case OPCODE_ASSIGN_TYPED_SCRIPT: {
-				Variant script = _constants_ptr[_code_ptr[ip + 3]];
-				Script *sc = Object::cast_to<Script>(script.operator Object *());
+				Ref<Script> script = get_constant(_code_ptr[ip + 3] & ADDR_MASK);
 
 				text += "assign typed script (";
-				text += sc->get_path();
+				text += _get_script_name(script);
 				text += ") ";
 				text += DADDR(1);
 				text += " = ";
@@ -497,13 +521,13 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
 				int instr_var_args = _code_ptr[++ip];
 				int argc = _code_ptr[ip + 1 + instr_var_args];
 
-				Ref<Script> script_type = get_constant(_code_ptr[ip + argc + 2] & GDScriptFunction::ADDR_MASK);
+				Ref<Script> script_type = get_constant(_code_ptr[ip + argc + 2] & ADDR_MASK);
 				Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + argc + 4];
 				StringName native_type = get_global_name(_code_ptr[ip + argc + 5]);
 
 				String type_name;
 				if (script_type.is_valid() && script_type->is_valid()) {
-					type_name = script_type->get_path();
+					type_name = "script(" + _get_script_name(script_type) + ")";
 				} else if (native_type != StringName()) {
 					type_name = native_type;
 				} else {
@@ -967,11 +991,10 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
 				incr += 3;
 			} break;
 			case OPCODE_RETURN_TYPED_SCRIPT: {
-				Variant script = _constants_ptr[_code_ptr[ip + 2]];
-				Script *sc = Object::cast_to<Script>(script.operator Object *());
+				Ref<Script> script = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
 
 				text += "return typed script (";
-				text += sc->get_path();
+				text += _get_script_name(script);
 				text += ") ";
 				text += DADDR(1);