1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-23 15:16:17 +00:00

Merge pull request #78489 from dalexeev/gds-add-disassembling-implicit-funcs

GDScript: Add disassembling implicit and lambda functions
This commit is contained in:
Thaddeus Crews
2024-12-19 19:59:36 -06:00
4 changed files with 77 additions and 36 deletions

View File

@@ -110,11 +110,13 @@ class GDScript : public Script {
HashMap<StringName, MethodInfo> _signals; HashMap<StringName, MethodInfo> _signals;
Dictionary rpc_config; Dictionary rpc_config;
public:
struct LambdaInfo { struct LambdaInfo {
int capture_count; int capture_count;
bool use_self; bool use_self;
}; };
private:
HashMap<GDScriptFunction *, LambdaInfo> lambda_info; HashMap<GDScriptFunction *, LambdaInfo> lambda_info;
public: public:
@@ -164,10 +166,11 @@ private:
void _clear_doc(); void _clear_doc();
#endif #endif
GDScriptFunction *implicit_initializer = nullptr; GDScriptFunction *initializer = nullptr; // Direct pointer to `new()`/`_init()` member function, faster to locate.
GDScriptFunction *initializer = nullptr; //direct pointer to new , faster to locate
GDScriptFunction *implicit_ready = nullptr; GDScriptFunction *implicit_initializer = nullptr; // `@implicit_new()` special function.
GDScriptFunction *static_initializer = nullptr; GDScriptFunction *implicit_ready = nullptr; // `@implicit_ready()` special function.
GDScriptFunction *static_initializer = nullptr; // `@static_initializer()` special function.
Error _static_init(); Error _static_init();
void _static_default_init(); // Initialize static variables with default values based on their types. void _static_default_init(); // Initialize static variables with default values based on their types.
@@ -258,9 +261,15 @@ public:
CRASH_COND(!member_indices.has(p_member)); CRASH_COND(!member_indices.has(p_member));
return member_indices[p_member].data_type; return member_indices[p_member].data_type;
} }
const HashMap<StringName, GDScriptFunction *> &get_member_functions() const { return member_functions; }
const Ref<GDScriptNativeClass> &get_native() const { return native; } const Ref<GDScriptNativeClass> &get_native() const { return native; }
_FORCE_INLINE_ const HashMap<StringName, GDScriptFunction *> &get_member_functions() const { return member_functions; }
_FORCE_INLINE_ const HashMap<GDScriptFunction *, LambdaInfo> &get_lambda_info() const { return lambda_info; }
_FORCE_INLINE_ const GDScriptFunction *get_implicit_initializer() const { return implicit_initializer; }
_FORCE_INLINE_ const GDScriptFunction *get_implicit_ready() const { return implicit_ready; }
_FORCE_INLINE_ const GDScriptFunction *get_static_initializer() const { return static_initializer; }
RBSet<GDScript *> get_dependencies(); RBSet<GDScript *> get_dependencies();
HashMap<GDScript *, RBSet<GDScript *>> get_all_dependencies(); HashMap<GDScript *, RBSet<GDScript *>> get_all_dependencies();
RBSet<GDScript *> get_must_clear_dependencies(); RBSet<GDScript *> get_must_clear_dependencies();

View File

@@ -2278,7 +2278,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script); return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script);
} else { } else {
if (p_for_ready) { if (p_for_ready) {
func_name = SceneStringName(_ready); func_name = "@implicit_ready";
} else { } else {
func_name = "@implicit_new"; func_name = "@implicit_new";
} }
@@ -2363,7 +2363,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_
} }
if (field->onready != is_implicit_ready) { if (field->onready != is_implicit_ready) {
// Only initialize in @implicit_ready. // Only initialize in `@implicit_ready()`.
continue; continue;
} }
@@ -2972,7 +2972,7 @@ Error GDScriptCompiler::_compile_class(GDScript *p_script, const GDScriptParser:
} }
{ {
// Create an implicit constructor in any case. // Create `@implicit_new()` special function in any case.
Error err = OK; Error err = OK;
_parse_function(err, p_script, p_class, nullptr); _parse_function(err, p_script, p_class, nullptr);
if (err) { if (err) {
@@ -2981,7 +2981,7 @@ Error GDScriptCompiler::_compile_class(GDScript *p_script, const GDScriptParser:
} }
if (p_class->onready_used) { if (p_class->onready_used) {
// Create an implicit_ready constructor. // Create `@implicit_ready()` special function.
Error err = OK; Error err = OK;
_parse_function(err, p_script, p_class, nullptr, true); _parse_function(err, p_script, p_class, nullptr, true);
if (err) { if (err) {

View File

@@ -362,7 +362,12 @@ 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); Ref<GDScript> gdscript;
if (_code_ptr[ip + 2] == ADDR_CLASS) {
gdscript = Ref<GDScript>(_script);
} else {
gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
}
text += "set_static_variable script("; text += "set_static_variable script(";
text += GDScript::debug_get_script_name(gdscript); text += GDScript::debug_get_script_name(gdscript);
@@ -378,7 +383,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); Ref<GDScript> gdscript;
if (_code_ptr[ip + 2] == ADDR_CLASS) {
gdscript = Ref<GDScript>(_script);
} else {
gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK);
}
text += "get_static_variable "; text += "get_static_variable ";
text += DADDR(1); text += DADDR(1);

View File

@@ -38,11 +38,8 @@
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
#include "core/io/file_access.h" #include "core/io/file_access.h"
#include "core/io/file_access_pack.h"
#include "core/os/main_loop.h"
#include "core/os/os.h" #include "core/os/os.h"
#include "core/string/string_builder.h" #include "core/string/string_builder.h"
#include "scene/resources/packed_scene.h"
#ifdef TOOLS_ENABLED #ifdef TOOLS_ENABLED
#include "editor/editor_settings.h" #include "editor/editor_settings.h"
@@ -182,32 +179,57 @@ static void test_parser(const String &p_code, const String &p_script_path, const
#endif #endif
} }
static void recursively_disassemble_functions(const Ref<GDScript> script, const Vector<String> &p_lines) { static void disassemble_function(const GDScriptFunction *p_func, const Vector<String> &p_lines) {
for (const KeyValue<StringName, GDScriptFunction *> &E : script->get_member_functions()) { ERR_FAIL_NULL(p_func);
const GDScriptFunction *func = E.value;
const MethodInfo &mi = func->get_method_info(); String arg_string;
String signature = "Disassembling " + mi.name + "("; bool is_first_arg = true;
for (List<PropertyInfo>::ConstIterator arg_itr = mi.arguments.begin(); arg_itr != mi.arguments.end(); ++arg_itr) { for (const PropertyInfo &arg_info : p_func->get_method_info().arguments) {
if (arg_itr != mi.arguments.begin()) { if (!is_first_arg) {
signature += ", "; arg_string += ", ";
}
signature += arg_itr->name;
} }
print_line(signature + ")"); arg_string += arg_info.name;
#ifdef TOOLS_ENABLED is_first_arg = false;
func->disassemble(p_lines);
#endif
print_line("");
print_line("");
} }
for (const KeyValue<StringName, Ref<GDScript>> &F : script->get_subclasses()) { print_line(vformat("Function %s(%s)", p_func->get_name(), arg_string));
const Ref<GDScript> inner_script = F.value; #ifdef TOOLS_ENABLED
print_line(""); p_func->disassemble(p_lines);
print_line(vformat("Inner Class: %s", inner_script->get_local_name())); #endif
print_line(""); print_line("");
recursively_disassemble_functions(inner_script, p_lines); print_line("");
}
static void recursively_disassemble_functions(const Ref<GDScript> p_script, const Vector<String> &p_lines) {
print_line(vformat("Class %s", p_script->get_fully_qualified_name()));
print_line("");
print_line("");
const GDScriptFunction *implicit_initializer = p_script->get_implicit_initializer();
if (implicit_initializer != nullptr) {
disassemble_function(implicit_initializer, p_lines);
}
const GDScriptFunction *implicit_ready = p_script->get_implicit_ready();
if (implicit_ready != nullptr) {
disassemble_function(implicit_ready, p_lines);
}
const GDScriptFunction *static_initializer = p_script->get_static_initializer();
if (static_initializer != nullptr) {
disassemble_function(static_initializer, p_lines);
}
for (const KeyValue<GDScriptFunction *, GDScript::LambdaInfo> &E : p_script->get_lambda_info()) {
disassemble_function(E.key, p_lines);
}
for (const KeyValue<StringName, GDScriptFunction *> &E : p_script->get_member_functions()) {
disassemble_function(E.value, p_lines);
}
for (const KeyValue<StringName, Ref<GDScript>> &E : p_script->get_subclasses()) {
recursively_disassemble_functions(E.value, p_lines);
} }
} }