From 80e06b29e7a245dab024a7a3b6a0692913b05bcc Mon Sep 17 00:00:00 2001 From: George Marques Date: Thu, 29 Dec 2022 10:47:53 -0300 Subject: GDScript: Add names for disassembling function pointers When instructions use function pointers, it's not possible to retrieve their original names in the disassembly. This stores the names in vectors (in debug builds) so they can be shown. --- modules/gdscript/gdscript_byte_codegen.cpp | 39 ++++++++++++++++++++++++++++-- modules/gdscript/gdscript_byte_codegen.h | 20 ++++++++++++++- modules/gdscript/gdscript_codegen.h | 2 +- modules/gdscript/gdscript_compiler.cpp | 6 ++--- modules/gdscript/gdscript_disassembler.cpp | 21 +++++++++------- modules/gdscript/gdscript_function.h | 10 ++++++++ 6 files changed, 82 insertions(+), 16 deletions(-) (limited to 'modules') diff --git a/modules/gdscript/gdscript_byte_codegen.cpp b/modules/gdscript/gdscript_byte_codegen.cpp index 6c80fb7665..0d2c56488d 100644 --- a/modules/gdscript/gdscript_byte_codegen.cpp +++ b/modules/gdscript/gdscript_byte_codegen.cpp @@ -401,6 +401,16 @@ GDScriptFunction *GDScriptByteCodeGenerator::write_end() { function->_instruction_args_size = instr_args_max; function->_ptrcall_args_size = ptrcall_max; +#ifdef DEBUG_ENABLED + function->operator_names = operator_names; + function->setter_names = setter_names; + function->getter_names = getter_names; + function->builtin_methods_names = builtin_methods_names; + function->constructors_names = constructors_names; + function->utilities_names = utilities_names; + function->gds_utilities_names = gds_utilities_names; +#endif + ended = true; return function; } @@ -551,6 +561,9 @@ void GDScriptByteCodeGenerator::write_unary_operator(const Address &p_target, Va append(Address()); append(p_target); append(op_func); +#ifdef DEBUG_ENABLED + add_debug_name(operator_names, get_operation_pos(op_func), Variant::get_operator_name(p_operator)); +#endif return; } @@ -580,6 +593,9 @@ void GDScriptByteCodeGenerator::write_binary_operator(const Address &p_target, V append(p_right_operand); append(p_target); append(op_func); +#ifdef DEBUG_ENABLED + add_debug_name(operator_names, get_operation_pos(op_func), Variant::get_operator_name(p_operator)); +#endif return; } @@ -765,6 +781,9 @@ void GDScriptByteCodeGenerator::write_set_named(const Address &p_target, const S append(p_target); append(p_source); append(setter); +#ifdef DEBUG_ENABLED + add_debug_name(setter_names, get_setter_pos(setter), p_name); +#endif return; } append_opcode(GDScriptFunction::OPCODE_SET_NAMED); @@ -780,6 +799,9 @@ void GDScriptByteCodeGenerator::write_get_named(const Address &p_target, const S append(p_source); append(p_target); append(getter); +#ifdef DEBUG_ENABLED + add_debug_name(getter_names, get_getter_pos(getter), p_name); +#endif return; } append_opcode(GDScriptFunction::OPCODE_GET_NAMED); @@ -972,14 +994,18 @@ void GDScriptByteCodeGenerator::write_call_async(const Address &p_target, const append(p_function_name); } -void GDScriptByteCodeGenerator::write_call_gdscript_utility(const Address &p_target, GDScriptUtilityFunctions::FunctionPtr p_function, const Vector
&p_arguments) { +void GDScriptByteCodeGenerator::write_call_gdscript_utility(const Address &p_target, const StringName &p_function, const Vector
&p_arguments) { append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_GDSCRIPT_UTILITY, 1 + p_arguments.size()); + GDScriptUtilityFunctions::FunctionPtr gds_function = GDScriptUtilityFunctions::get_function(p_function); for (int i = 0; i < p_arguments.size(); i++) { append(p_arguments[i]); } append(get_call_target(p_target)); append(p_arguments.size()); - append(p_function); + append(gds_function); +#ifdef DEBUG_ENABLED + add_debug_name(gds_utilities_names, get_gds_utility_pos(gds_function), p_function); +#endif } void GDScriptByteCodeGenerator::write_call_utility(const Address &p_target, const StringName &p_function, const Vector
&p_arguments) { @@ -1012,6 +1038,9 @@ void GDScriptByteCodeGenerator::write_call_utility(const Address &p_target, cons append(target); append(p_arguments.size()); append(Variant::get_validated_utility_function(p_function)); +#ifdef DEBUG_ENABLED + add_debug_name(utilities_names, get_utility_pos(Variant::get_validated_utility_function(p_function)), p_function); +#endif } else { append_opcode_and_argcount(GDScriptFunction::OPCODE_CALL_UTILITY, 1 + p_arguments.size()); for (int i = 0; i < p_arguments.size(); i++) { @@ -1074,6 +1103,9 @@ void GDScriptByteCodeGenerator::write_call_builtin_type(const Address &p_target, append(target); append(p_arguments.size()); append(Variant::get_validated_builtin_method(p_type, p_method)); +#ifdef DEBUG_ENABLED + add_debug_name(builtin_methods_names, get_builtin_method_pos(Variant::get_validated_builtin_method(p_type, p_method)), p_method); +#endif } void GDScriptByteCodeGenerator::write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector
&p_arguments) { @@ -1263,6 +1295,9 @@ void GDScriptByteCodeGenerator::write_construct(const Address &p_target, Variant append(get_call_target(p_target)); append(p_arguments.size()); append(Variant::get_validated_constructor(p_type, valid_constructor)); +#ifdef DEBUG_ENABLED + add_debug_name(constructors_names, get_constructor_pos(Variant::get_validated_constructor(p_type, valid_constructor)), Variant::get_type_name(p_type)); +#endif return; } } diff --git a/modules/gdscript/gdscript_byte_codegen.h b/modules/gdscript/gdscript_byte_codegen.h index 171c505116..1a20d7cb3e 100644 --- a/modules/gdscript/gdscript_byte_codegen.h +++ b/modules/gdscript/gdscript_byte_codegen.h @@ -95,6 +95,24 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator { RBMap method_bind_map; RBMap lambdas_map; +#if DEBUG_ENABLED + // Keep method and property names for pointer and validated operations. + // Used when disassembling the bytecode. + Vector operator_names; + Vector setter_names; + Vector getter_names; + Vector builtin_methods_names; + Vector constructors_names; + Vector utilities_names; + Vector gds_utilities_names; + void add_debug_name(Vector &vector, int index, const String &name) { + if (index >= vector.size()) { + vector.resize(index + 1); + } + vector.write[index] = name; + } +#endif + // Lists since these can be nested. List if_jmp_addrs; List for_jmp_addrs; @@ -468,8 +486,8 @@ public: virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector
&p_arguments) override; virtual void write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector
&p_arguments) override; virtual void write_call_utility(const Address &p_target, const StringName &p_function, const Vector
&p_arguments) override; - virtual void write_call_gdscript_utility(const Address &p_target, GDScriptUtilityFunctions::FunctionPtr p_function, const Vector
&p_arguments) override; void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, bool p_is_static, const Vector
&p_arguments); + virtual void write_call_gdscript_utility(const Address &p_target, const StringName &p_function, const Vector
&p_arguments) override; virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector
&p_arguments) override; virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector
&p_arguments) override; virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector
&p_arguments) override; diff --git a/modules/gdscript/gdscript_codegen.h b/modules/gdscript/gdscript_codegen.h index e885938eba..ef47009a3e 100644 --- a/modules/gdscript/gdscript_codegen.h +++ b/modules/gdscript/gdscript_codegen.h @@ -121,7 +121,7 @@ public: virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector
&p_arguments) = 0; virtual void write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector
&p_arguments) = 0; virtual void write_call_utility(const Address &p_target, const StringName &p_function, const Vector
&p_arguments) = 0; - virtual void write_call_gdscript_utility(const Address &p_target, GDScriptUtilityFunctions::FunctionPtr p_function, const Vector
&p_arguments) = 0; + virtual void write_call_gdscript_utility(const Address &p_target, const StringName &p_function, const Vector
&p_arguments) = 0; virtual void write_call_builtin_type(const Address &p_target, const Address &p_base, Variant::Type p_type, const StringName &p_method, const Vector
&p_arguments) = 0; virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector
&p_arguments) = 0; virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector
&p_arguments) = 0; diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index d63a1b4536..da9a917e42 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -546,7 +546,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_expression(CodeGen &code gen->write_call_utility(result, call->function_name, arguments); } else if (!call->is_super && call->callee->type == GDScriptParser::Node::IDENTIFIER && GDScriptUtilityFunctions::function_exists(call->function_name)) { // GDScript utility function. - gen->write_call_gdscript_utility(result, GDScriptUtilityFunctions::get_function(call->function_name), arguments); + gen->write_call_gdscript_utility(result, call->function_name, arguments); } else { // Regular function. const GDScriptParser::ExpressionNode *callee = call->callee; @@ -1410,7 +1410,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c GDScriptCodeGenerator::Address value_length_addr = codegen.add_temporary(temp_type); Vector len_args; len_args.push_back(p_value_addr); - codegen.generator->write_call_gdscript_utility(value_length_addr, GDScriptUtilityFunctions::get_function("len"), len_args); + codegen.generator->write_call_gdscript_utility(value_length_addr, "len", len_args); // Test length compatibility. temp_type.builtin_type = Variant::BOOL; @@ -1508,7 +1508,7 @@ GDScriptCodeGenerator::Address GDScriptCompiler::_parse_match_pattern(CodeGen &c GDScriptCodeGenerator::Address value_length_addr = codegen.add_temporary(temp_type); Vector func_args; func_args.push_back(p_value_addr); - codegen.generator->write_call_gdscript_utility(value_length_addr, GDScriptUtilityFunctions::get_function("len"), func_args); + codegen.generator->write_call_gdscript_utility(value_length_addr, "len", func_args); // Test length compatibility. temp_type.builtin_type = Variant::BOOL; diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index 4edabdcb40..b5c8a6f478 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -128,7 +128,9 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { text += DADDR(3); text += " = "; text += DADDR(1); - text += " "; + text += " "; + text += operator_names[_code_ptr[ip + 4]]; + text += " "; text += DADDR(2); incr += 5; @@ -230,7 +232,7 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { text += "set_named validated "; text += DADDR(1); text += "[\""; - text += ""; + text += setter_names[_code_ptr[ip + 3]]; text += "\"] = "; text += DADDR(2); @@ -253,7 +255,7 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { text += " = "; text += DADDR(1); text += "[\""; - text += ""; + text += getter_names[_code_ptr[ip + 3]]; text += "\"]"; incr += 4; @@ -398,7 +400,8 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { text += DADDR(1 + argc); text += " = "; - text += "("; + text += constructors_names[_code_ptr[ip + 3 + argc]]; + text += "("; for (int i = 0; i < argc; i++) { if (i > 0) { text += ", "; @@ -687,7 +690,7 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { text += DADDR(2 + argc) + " = "; text += DADDR(1) + "."; - text += ""; + text += builtin_methods_names[_code_ptr[ip + 4 + argc]]; text += "("; @@ -725,12 +728,12 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { case OPCODE_CALL_UTILITY_VALIDATED: { int instr_var_args = _code_ptr[++ip]; - text += "call-utility "; + text += "call-utility validated "; int argc = _code_ptr[ip + 1 + instr_var_args]; text += DADDR(1 + argc) + " = "; - text += ""; + text += utilities_names[_code_ptr[ip + 3 + argc]]; text += "("; for (int i = 0; i < argc; i++) { @@ -746,12 +749,12 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { case OPCODE_CALL_GDSCRIPT_UTILITY: { int instr_var_args = _code_ptr[++ip]; - text += "call-gscript-utility "; + text += "call-gdscript-utility "; int argc = _code_ptr[ip + 1 + instr_var_args]; text += DADDR(1 + argc) + " = "; - text += ""; + text += gds_utilities_names[_code_ptr[ip + 3 + argc]]; text += "("; for (int i = 0; i < argc; i++) { diff --git a/modules/gdscript/gdscript_function.h b/modules/gdscript/gdscript_function.h index 76214f3482..37416a734d 100644 --- a/modules/gdscript/gdscript_function.h +++ b/modules/gdscript/gdscript_function.h @@ -505,6 +505,16 @@ private: Vector default_arg_values; #endif +#ifdef DEBUG_ENABLED + Vector operator_names; + Vector setter_names; + Vector getter_names; + Vector builtin_methods_names; + Vector constructors_names; + Vector utilities_names; + Vector gds_utilities_names; +#endif + List stack_debug; Variant _get_default_variant_for_data_type(const GDScriptDataType &p_data_type); -- cgit v1.2.3