diff --git a/modules/gdscript/gdscript.h b/modules/gdscript/gdscript.h index 006a09debbb..0486e1f7dec 100644 --- a/modules/gdscript/gdscript.h +++ b/modules/gdscript/gdscript.h @@ -110,11 +110,13 @@ class GDScript : public Script { HashMap _signals; Dictionary rpc_config; +public: struct LambdaInfo { int capture_count; bool use_self; }; +private: HashMap lambda_info; public: @@ -163,10 +165,11 @@ private: void _add_doc(const DocData::ClassDoc &p_inner_class); #endif - GDScriptFunction *implicit_initializer = nullptr; - GDScriptFunction *initializer = nullptr; //direct pointer to new , faster to locate - GDScriptFunction *implicit_ready = nullptr; - GDScriptFunction *static_initializer = nullptr; + GDScriptFunction *initializer = nullptr; // Direct pointer to `new()`/`_init()` member function, faster to locate. + + GDScriptFunction *implicit_initializer = nullptr; // `@implicit_new()` special function. + GDScriptFunction *implicit_ready = nullptr; // `@implicit_ready()` special function. + GDScriptFunction *static_initializer = nullptr; // `@static_initializer()` special function. Error _static_init(); void _static_default_init(); // Initialize static variables with default values based on their types. @@ -257,9 +260,15 @@ public: CRASH_COND(!member_indices.has(p_member)); return member_indices[p_member].data_type; } - const HashMap &get_member_functions() const { return member_functions; } const Ref &get_native() const { return native; } + _FORCE_INLINE_ const HashMap &get_member_functions() const { return member_functions; } + _FORCE_INLINE_ const HashMap &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 get_dependencies(); HashMap> get_all_dependencies(); RBSet get_must_clear_dependencies(); diff --git a/modules/gdscript/gdscript_compiler.cpp b/modules/gdscript/gdscript_compiler.cpp index f4f445e0966..49e71b43198 100644 --- a/modules/gdscript/gdscript_compiler.cpp +++ b/modules/gdscript/gdscript_compiler.cpp @@ -2266,7 +2266,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ return_type = _gdtype_from_datatype(p_func->get_datatype(), p_script); } else { if (p_for_ready) { - func_name = SceneStringName(_ready); + func_name = "@implicit_ready"; } else { func_name = "@implicit_new"; } @@ -2351,7 +2351,7 @@ GDScriptFunction *GDScriptCompiler::_parse_function(Error &r_error, GDScript *p_ } if (field->onready != is_implicit_ready) { - // Only initialize in @implicit_ready. + // Only initialize in `@implicit_ready()`. continue; } @@ -2953,7 +2953,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; _parse_function(err, p_script, p_class, nullptr); if (err) { @@ -2962,7 +2962,7 @@ Error GDScriptCompiler::_compile_class(GDScript *p_script, const GDScriptParser: } if (p_class->onready_used) { - // Create an implicit_ready constructor. + // Create `@implicit_ready()` special function. Error err = OK; _parse_function(err, p_script, p_class, nullptr, true); if (err) { diff --git a/modules/gdscript/gdscript_disassembler.cpp b/modules/gdscript/gdscript_disassembler.cpp index d94a6dfda29..5618053d839 100644 --- a/modules/gdscript/gdscript_disassembler.cpp +++ b/modules/gdscript/gdscript_disassembler.cpp @@ -362,7 +362,12 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { incr += 3; } break; case OPCODE_SET_STATIC_VARIABLE: { - Ref gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK); + Ref gdscript; + if (_code_ptr[ip + 2] == ADDR_CLASS) { + gdscript = Ref(_script); + } else { + gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK); + } text += "set_static_variable script("; text += GDScript::debug_get_script_name(gdscript); @@ -378,7 +383,12 @@ void GDScriptFunction::disassemble(const Vector &p_code_lines) const { incr += 4; } break; case OPCODE_GET_STATIC_VARIABLE: { - Ref gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK); + Ref gdscript; + if (_code_ptr[ip + 2] == ADDR_CLASS) { + gdscript = Ref(_script); + } else { + gdscript = get_constant(_code_ptr[ip + 2] & ADDR_MASK); + } text += "get_static_variable "; text += DADDR(1); diff --git a/modules/gdscript/tests/test_gdscript.cpp b/modules/gdscript/tests/test_gdscript.cpp index fbc72a05089..7e93569e390 100644 --- a/modules/gdscript/tests/test_gdscript.cpp +++ b/modules/gdscript/tests/test_gdscript.cpp @@ -38,11 +38,8 @@ #include "core/config/project_settings.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/string/string_builder.h" -#include "scene/resources/packed_scene.h" #ifdef TOOLS_ENABLED #include "editor/editor_settings.h" @@ -182,32 +179,57 @@ static void test_parser(const String &p_code, const String &p_script_path, const #endif } -static void recursively_disassemble_functions(const Ref script, const Vector &p_lines) { - for (const KeyValue &E : script->get_member_functions()) { - const GDScriptFunction *func = E.value; +static void disassemble_function(const GDScriptFunction *p_func, const Vector &p_lines) { + ERR_FAIL_NULL(p_func); - const MethodInfo &mi = func->get_method_info(); - String signature = "Disassembling " + mi.name + "("; - for (List::ConstIterator arg_itr = mi.arguments.begin(); arg_itr != mi.arguments.end(); ++arg_itr) { - if (arg_itr != mi.arguments.begin()) { - signature += ", "; - } - signature += arg_itr->name; + String arg_string; + bool is_first_arg = true; + for (const PropertyInfo &arg_info : p_func->get_method_info().arguments) { + if (!is_first_arg) { + arg_string += ", "; } - print_line(signature + ")"); -#ifdef TOOLS_ENABLED - func->disassemble(p_lines); -#endif - print_line(""); - print_line(""); + arg_string += arg_info.name; + is_first_arg = false; } - for (const KeyValue> &F : script->get_subclasses()) { - const Ref inner_script = F.value; - print_line(""); - print_line(vformat("Inner Class: %s", inner_script->get_local_name())); - print_line(""); - recursively_disassemble_functions(inner_script, p_lines); + print_line(vformat("Function %s(%s)", p_func->get_name(), arg_string)); +#ifdef TOOLS_ENABLED + p_func->disassemble(p_lines); +#endif + print_line(""); + print_line(""); +} + +static void recursively_disassemble_functions(const Ref p_script, const Vector &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 &E : p_script->get_lambda_info()) { + disassemble_function(E.key, p_lines); + } + + for (const KeyValue &E : p_script->get_member_functions()) { + disassemble_function(E.value, p_lines); + } + + for (const KeyValue> &E : p_script->get_subclasses()) { + recursively_disassemble_functions(E.value, p_lines); } }