GDScript: Fix crash in disassembler
This commit is contained in:
parent
080d471e98
commit
5d3f5e8cf2
1 changed files with 48 additions and 25 deletions
|
@ -35,6 +35,22 @@
|
||||||
|
|
||||||
#include "core/string/string_builder.h"
|
#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) {
|
static String _get_variant_string(const Variant &p_variant) {
|
||||||
String txt;
|
String txt;
|
||||||
if (p_variant.get_type() == Variant::STRING) {
|
if (p_variant.get_type() == Variant::STRING) {
|
||||||
|
@ -50,12 +66,17 @@ static String _get_variant_string(const Variant &p_variant) {
|
||||||
} else {
|
} else {
|
||||||
GDScriptNativeClass *cls = Object::cast_to<GDScriptNativeClass>(obj);
|
GDScriptNativeClass *cls = Object::cast_to<GDScriptNativeClass>(obj);
|
||||||
if (cls) {
|
if (cls) {
|
||||||
txt += cls->get_name();
|
txt = "class(" + cls->get_name() + ")";
|
||||||
txt += " (class)";
|
|
||||||
} else {
|
} else {
|
||||||
txt = obj->get_class();
|
Script *script = Object::cast_to<Script>(obj);
|
||||||
if (obj->get_script_instance()) {
|
if (script) {
|
||||||
txt += "(" + obj->get_script_instance()->get_script()->get_path() + ")";
|
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;
|
int addr = p_address & GDScriptFunction::ADDR_MASK;
|
||||||
|
|
||||||
switch (p_address >> GDScriptFunction::ADDR_BITS) {
|
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: {
|
case GDScriptFunction::ADDR_TYPE_STACK: {
|
||||||
switch (addr) {
|
switch (addr) {
|
||||||
case GDScriptFunction::ADDR_STACK_SELF:
|
case GDScriptFunction::ADDR_STACK_SELF:
|
||||||
|
@ -87,6 +102,12 @@ static String _disassemble_address(const GDScript *p_script, const GDScriptFunct
|
||||||
return "stack(" + itos(addr) + ")";
|
return "stack(" + itos(addr) + ")";
|
||||||
}
|
}
|
||||||
} break;
|
} 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>";
|
return "<err>";
|
||||||
|
@ -152,12 +173,14 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||||
text += DADDR(2);
|
text += DADDR(2);
|
||||||
text += " is Array[";
|
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];
|
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + 4];
|
||||||
StringName native_type = get_global_name(_code_ptr[ip + 5]);
|
StringName native_type = get_global_name(_code_ptr[ip + 5]);
|
||||||
|
|
||||||
if (script_type.is_valid() && script_type->is_valid()) {
|
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()) {
|
} else if (native_type != StringName()) {
|
||||||
text += native_type;
|
text += native_type;
|
||||||
} else {
|
} else {
|
||||||
|
@ -313,9 +336,10 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||||
incr += 3;
|
incr += 3;
|
||||||
} break;
|
} break;
|
||||||
case OPCODE_SET_STATIC_VARIABLE: {
|
case OPCODE_SET_STATIC_VARIABLE: {
|
||||||
|
Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
|
||||||
|
|
||||||
text += "set_static_variable script(";
|
text += "set_static_variable script(";
|
||||||
Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & GDScriptFunction::ADDR_MASK);
|
text += _get_script_name(gdscript);
|
||||||
text += gdscript.is_valid() ? gdscript->get_fully_qualified_name().get_file() : "<unknown script>";
|
|
||||||
text += ")";
|
text += ")";
|
||||||
if (gdscript.is_valid()) {
|
if (gdscript.is_valid()) {
|
||||||
text += "[\"" + gdscript->debug_get_static_var_by_index(_code_ptr[ip + 3]) + "\"]";
|
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;
|
incr += 4;
|
||||||
} break;
|
} break;
|
||||||
case OPCODE_GET_STATIC_VARIABLE: {
|
case OPCODE_GET_STATIC_VARIABLE: {
|
||||||
|
Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
|
||||||
|
|
||||||
text += "get_static_variable ";
|
text += "get_static_variable ";
|
||||||
text += DADDR(1);
|
text += DADDR(1);
|
||||||
text += " = script(";
|
text += " = script(";
|
||||||
Ref<GDScript> gdscript = get_constant(_code_ptr[ip + 2] & GDScriptFunction::ADDR_MASK);
|
text += _get_script_name(gdscript);
|
||||||
text += gdscript.is_valid() ? gdscript->get_fully_qualified_name().get_file() : "<unknown script>";
|
|
||||||
text += ")";
|
text += ")";
|
||||||
if (gdscript.is_valid()) {
|
if (gdscript.is_valid()) {
|
||||||
text += "[\"" + gdscript->debug_get_static_var_by_index(_code_ptr[ip + 3]) + "\"]";
|
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;
|
incr += 4;
|
||||||
} break;
|
} break;
|
||||||
case OPCODE_ASSIGN_TYPED_SCRIPT: {
|
case OPCODE_ASSIGN_TYPED_SCRIPT: {
|
||||||
Variant script = _constants_ptr[_code_ptr[ip + 3]];
|
Ref<Script> script = get_constant(_code_ptr[ip + 3] & ADDR_MASK);
|
||||||
Script *sc = Object::cast_to<Script>(script.operator Object *());
|
|
||||||
|
|
||||||
text += "assign typed script (";
|
text += "assign typed script (";
|
||||||
text += sc->get_path();
|
text += _get_script_name(script);
|
||||||
text += ") ";
|
text += ") ";
|
||||||
text += DADDR(1);
|
text += DADDR(1);
|
||||||
text += " = ";
|
text += " = ";
|
||||||
|
@ -497,13 +521,13 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||||
int instr_var_args = _code_ptr[++ip];
|
int instr_var_args = _code_ptr[++ip];
|
||||||
int argc = _code_ptr[ip + 1 + instr_var_args];
|
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];
|
Variant::Type builtin_type = (Variant::Type)_code_ptr[ip + argc + 4];
|
||||||
StringName native_type = get_global_name(_code_ptr[ip + argc + 5]);
|
StringName native_type = get_global_name(_code_ptr[ip + argc + 5]);
|
||||||
|
|
||||||
String type_name;
|
String type_name;
|
||||||
if (script_type.is_valid() && script_type->is_valid()) {
|
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()) {
|
} else if (native_type != StringName()) {
|
||||||
type_name = native_type;
|
type_name = native_type;
|
||||||
} else {
|
} else {
|
||||||
|
@ -967,11 +991,10 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||||
incr += 3;
|
incr += 3;
|
||||||
} break;
|
} break;
|
||||||
case OPCODE_RETURN_TYPED_SCRIPT: {
|
case OPCODE_RETURN_TYPED_SCRIPT: {
|
||||||
Variant script = _constants_ptr[_code_ptr[ip + 2]];
|
Ref<Script> script = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
|
||||||
Script *sc = Object::cast_to<Script>(script.operator Object *());
|
|
||||||
|
|
||||||
text += "return typed script (";
|
text += "return typed script (";
|
||||||
text += sc->get_path();
|
text += _get_script_name(script);
|
||||||
text += ") ";
|
text += ") ";
|
||||||
text += DADDR(1);
|
text += DADDR(1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue