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.
This commit is contained in:
parent
9937915ad7
commit
80e06b29e7
@ -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<Address> &p_arguments) {
|
||||
void GDScriptByteCodeGenerator::write_call_gdscript_utility(const Address &p_target, const StringName &p_function, const Vector<Address> &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<Address> &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<Address> &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;
|
||||
}
|
||||
}
|
||||
|
@ -95,6 +95,24 @@ class GDScriptByteCodeGenerator : public GDScriptCodeGenerator {
|
||||
RBMap<MethodBind *, int> method_bind_map;
|
||||
RBMap<GDScriptFunction *, int> lambdas_map;
|
||||
|
||||
#if DEBUG_ENABLED
|
||||
// Keep method and property names for pointer and validated operations.
|
||||
// Used when disassembling the bytecode.
|
||||
Vector<String> operator_names;
|
||||
Vector<String> setter_names;
|
||||
Vector<String> getter_names;
|
||||
Vector<String> builtin_methods_names;
|
||||
Vector<String> constructors_names;
|
||||
Vector<String> utilities_names;
|
||||
Vector<String> gds_utilities_names;
|
||||
void add_debug_name(Vector<String> &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<int> if_jmp_addrs;
|
||||
List<int> for_jmp_addrs;
|
||||
@ -468,8 +486,8 @@ public:
|
||||
virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
|
||||
virtual void write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) override;
|
||||
virtual void write_call_utility(const Address &p_target, const StringName &p_function, const Vector<Address> &p_arguments) override;
|
||||
virtual void write_call_gdscript_utility(const Address &p_target, GDScriptUtilityFunctions::FunctionPtr p_function, const Vector<Address> &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<Address> &p_arguments);
|
||||
virtual void write_call_gdscript_utility(const Address &p_target, const StringName &p_function, const Vector<Address> &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<Address> &p_arguments) override;
|
||||
virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
||||
virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) override;
|
||||
|
@ -121,7 +121,7 @@ public:
|
||||
virtual void write_super_call(const Address &p_target, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
|
||||
virtual void write_call_async(const Address &p_target, const Address &p_base, const StringName &p_function_name, const Vector<Address> &p_arguments) = 0;
|
||||
virtual void write_call_utility(const Address &p_target, const StringName &p_function, const Vector<Address> &p_arguments) = 0;
|
||||
virtual void write_call_gdscript_utility(const Address &p_target, GDScriptUtilityFunctions::FunctionPtr p_function, const Vector<Address> &p_arguments) = 0;
|
||||
virtual void write_call_gdscript_utility(const Address &p_target, const StringName &p_function, const Vector<Address> &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<Address> &p_arguments) = 0;
|
||||
virtual void write_call_builtin_type_static(const Address &p_target, Variant::Type p_type, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
||||
virtual void write_call_native_static(const Address &p_target, const StringName &p_class, const StringName &p_method, const Vector<Address> &p_arguments) = 0;
|
||||
|
@ -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<GDScriptCodeGenerator::Address> 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<GDScriptCodeGenerator::Address> 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;
|
||||
|
@ -128,7 +128,9 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||
text += DADDR(3);
|
||||
text += " = ";
|
||||
text += DADDR(1);
|
||||
text += " <operator function> ";
|
||||
text += " ";
|
||||
text += operator_names[_code_ptr[ip + 4]];
|
||||
text += " ";
|
||||
text += DADDR(2);
|
||||
|
||||
incr += 5;
|
||||
@ -230,7 +232,7 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||
text += "set_named validated ";
|
||||
text += DADDR(1);
|
||||
text += "[\"";
|
||||
text += "<unknown name>";
|
||||
text += setter_names[_code_ptr[ip + 3]];
|
||||
text += "\"] = ";
|
||||
text += DADDR(2);
|
||||
|
||||
@ -253,7 +255,7 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||
text += " = ";
|
||||
text += DADDR(1);
|
||||
text += "[\"";
|
||||
text += "<unknown name>";
|
||||
text += getter_names[_code_ptr[ip + 3]];
|
||||
text += "\"]";
|
||||
|
||||
incr += 4;
|
||||
@ -398,7 +400,8 @@ void GDScriptFunction::disassemble(const Vector<String> &p_code_lines) const {
|
||||
text += DADDR(1 + argc);
|
||||
text += " = ";
|
||||
|
||||
text += "<unknown type>(";
|
||||
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<String> &p_code_lines) const {
|
||||
text += DADDR(2 + argc) + " = ";
|
||||
|
||||
text += DADDR(1) + ".";
|
||||
text += "<unknown method>";
|
||||
text += builtin_methods_names[_code_ptr[ip + 4 + argc]];
|
||||
|
||||
text += "(";
|
||||
|
||||
@ -725,12 +728,12 @@ void GDScriptFunction::disassemble(const Vector<String> &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 += "<unknown function>";
|
||||
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<String> &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 += "<unknown function>";
|
||||
text += gds_utilities_names[_code_ptr[ip + 3 + argc]];
|
||||
text += "(";
|
||||
|
||||
for (int i = 0; i < argc; i++) {
|
||||
|
@ -505,6 +505,16 @@ private:
|
||||
Vector<Variant> default_arg_values;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
Vector<String> operator_names;
|
||||
Vector<String> setter_names;
|
||||
Vector<String> getter_names;
|
||||
Vector<String> builtin_methods_names;
|
||||
Vector<String> constructors_names;
|
||||
Vector<String> utilities_names;
|
||||
Vector<String> gds_utilities_names;
|
||||
#endif
|
||||
|
||||
List<StackDebug> stack_debug;
|
||||
|
||||
Variant _get_default_variant_for_data_type(const GDScriptDataType &p_data_type);
|
||||
|
Loading…
Reference in New Issue
Block a user