diff options
Diffstat (limited to 'modules/mono/mono_gd')
24 files changed, 525 insertions, 422 deletions
diff --git a/modules/mono/mono_gd/android_mono_config.h b/modules/mono/mono_gd/android_mono_config.h index 93f708bba0..9e304939b2 100644 --- a/modules/mono/mono_gd/android_mono_config.h +++ b/modules/mono/mono_gd/android_mono_config.h @@ -33,7 +33,7 @@ #ifdef ANDROID_ENABLED -#include "core/ustring.h" +#include "core/string/ustring.h" // This function is defined in an auto-generated source file String get_godot_android_mono_config(); diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 39c3bd8934..772961291c 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -37,12 +37,12 @@ #include <mono/metadata/mono-gc.h> #include <mono/metadata/profiler.h> +#include "core/config/project_settings.h" #include "core/debugger/engine_debugger.h" #include "core/os/dir_access.h" #include "core/os/file_access.h" #include "core/os/os.h" #include "core/os/thread.h" -#include "core/project_settings.h" #include "../csharp_script.h" #include "../godotsharp_dirs.h" @@ -144,8 +144,9 @@ void gd_mono_debug_init() { if (Engine::get_singleton()->is_editor_hint() || ProjectSettings::get_singleton()->get_resource_path().empty() || Main::is_project_manager()) { - if (da_args.size() == 0) + if (da_args.size() == 0) { return; + } } if (da_args.length() == 0) { @@ -200,7 +201,6 @@ MonoDomain *gd_initialize_mono_runtime() { return mono_jit_init_version("GodotEngine.RootDomain", runtime_version); } #endif - } // namespace void GDMono::add_mono_shared_libs_dir_to_path() { @@ -423,24 +423,27 @@ void GDMono::initialize_load_assemblies() { bool tool_assemblies_loaded = _load_tools_assemblies(); CRASH_COND_MSG(!tool_assemblies_loaded, "Mono: Failed to load '" TOOLS_ASM_NAME "' assemblies."); - if (Main::is_project_manager()) + if (Main::is_project_manager()) { return; + } #endif // Load the project's main assembly. This doesn't necessarily need to succeed. // The game may not be using .NET at all, or if the project does use .NET and // we're running in the editor, it may just happen to be it wasn't built yet. if (!_load_project_assembly()) { - if (OS::get_singleton()->is_stdout_verbose()) + if (OS::get_singleton()->is_stdout_verbose()) { print_error("Mono: Failed to load project assembly"); + } } } bool GDMono::_are_api_assemblies_out_of_sync() { bool out_of_sync = core_api_assembly.assembly && (core_api_assembly.out_of_sync || !GDMonoCache::cached_data.godot_api_cache_updated); #ifdef TOOLS_ENABLED - if (!out_of_sync) + if (!out_of_sync) { out_of_sync = editor_api_assembly.assembly && editor_api_assembly.out_of_sync; + } #endif return out_of_sync; } @@ -512,16 +515,17 @@ void GDMono::_init_exception_policy() { } } -void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) { +void GDMono::add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly) { assemblies[p_domain_id][p_assembly->get_name()] = p_assembly; } GDMonoAssembly *GDMono::get_loaded_assembly(const String &p_name) { - if (p_name == "mscorlib" && corlib_assembly) + if (p_name == "mscorlib" && corlib_assembly) { return corlib_assembly; + } MonoDomain *domain = mono_domain_get(); - uint32_t domain_id = domain ? mono_domain_get_id(domain) : 0; + int32_t domain_id = domain ? mono_domain_get_id(domain) : 0; GDMonoAssembly **result = assemblies[domain_id].getptr(p_name); return result ? *result : nullptr; } @@ -556,8 +560,9 @@ bool GDMono::load_assembly(const String &p_name, MonoAssemblyName *p_aname, GDMo GDMonoAssembly *assembly = GDMonoAssembly::load(p_name, p_aname, p_refonly, p_search_dirs); - if (!assembly) + if (!assembly) { return false; + } *r_assembly = assembly; @@ -573,8 +578,9 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo GDMonoAssembly *assembly = GDMonoAssembly::load_from(p_name, p_path, p_refonly); - if (!assembly) + if (!assembly) { return false; + } *r_assembly = assembly; @@ -594,16 +600,19 @@ ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMo if (nativecalls_klass) { GDMonoField *api_hash_field = nativecalls_klass->get_field("godot_api_hash"); - if (api_hash_field) + if (api_hash_field) { api_assembly_version.godot_api_hash = GDMonoMarshal::unbox<uint64_t>(api_hash_field->get_value(nullptr)); + } GDMonoField *binds_ver_field = nativecalls_klass->get_field("bindings_version"); - if (binds_ver_field) + if (binds_ver_field) { api_assembly_version.bindings_version = GDMonoMarshal::unbox<uint32_t>(binds_ver_field->get_value(nullptr)); + } GDMonoField *cs_glue_ver_field = nativecalls_klass->get_field("cs_glue_version"); - if (cs_glue_ver_field) + if (cs_glue_ver_field) { api_assembly_version.cs_glue_version = GDMonoMarshal::unbox<uint32_t>(cs_glue_ver_field->get_value(nullptr)); + } } return api_assembly_version; @@ -614,13 +623,15 @@ String ApiAssemblyInfo::to_string(ApiAssemblyInfo::Type p_type) { } bool GDMono::_load_corlib_assembly() { - if (corlib_assembly) + if (corlib_assembly) { return true; + } bool success = load_assembly("mscorlib", &corlib_assembly); - if (success) + if (success) { GDMonoCache::update_corlib_cache(); + } return success; } @@ -647,12 +658,14 @@ bool GDMono::copy_prebuilt_api_assembly(ApiAssemblyInfo::Type p_api_type, const DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); String xml_file = assembly_name + ".xml"; - if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) + if (da->copy(src_dir.plus_file(xml_file), dst_dir.plus_file(xml_file)) != OK) { WARN_PRINT("Failed to copy '" + xml_file + "'."); + } String pdb_file = assembly_name + ".pdb"; - if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) + if (da->copy(src_dir.plus_file(pdb_file), dst_dir.plus_file(pdb_file)) != OK) { WARN_PRINT("Failed to copy '" + pdb_file + "'."); + } String assembly_file = assembly_name + ".dll"; if (da->copy(src_dir.plus_file(assembly_file), dst_dir.plus_file(assembly_file)) != OK) { @@ -667,13 +680,15 @@ static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool String core_api_assembly_path = p_api_assemblies_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); String editor_api_assembly_path = p_api_assemblies_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); - if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) + if (!FileAccess::exists(core_api_assembly_path) || !FileAccess::exists(editor_api_assembly_path)) { return false; + } String cached_api_hash_path = p_api_assemblies_dir.plus_file("api_hash_cache.cfg"); - if (!FileAccess::exists(cached_api_hash_path)) + if (!FileAccess::exists(cached_api_hash_path)) { return false; + } Ref<ConfigFile> cfg; cfg.instance(); @@ -766,8 +781,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const // Note: Even if only one of the assemblies if missing or out of sync, we update both - if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) + if (!api_assemblies_out_of_sync && FileAccess::exists(core_assembly_path) && FileAccess::exists(editor_assembly_path)) { return String(); // No update needed + } print_verbose("Updating '" + p_config + "' API assemblies"); @@ -795,8 +811,9 @@ String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const #endif bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { - if (r_loaded_api_assembly.assembly) + if (r_loaded_api_assembly.assembly) { return true; + } #ifdef TOOLS_ENABLED // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date @@ -828,8 +845,9 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c #ifdef TOOLS_ENABLED bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, const String &p_config, bool p_refonly) { - if (r_loaded_api_assembly.assembly) + if (r_loaded_api_assembly.assembly) { return true; + } // For the editor and the editor player we want to load it from a specific path to make sure we can keep it up to date @@ -859,30 +877,35 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, LoadedApiAssembly &r_editor_api_assembly, const String &p_config, bool p_refonly, CoreApiAssemblyLoadedCallback p_callback) { if (!_load_core_api_assembly(r_core_api_assembly, p_config, p_refonly)) { - if (OS::get_singleton()->is_stdout_verbose()) + if (OS::get_singleton()->is_stdout_verbose()) { print_error("Mono: Failed to load Core API assembly"); + } return false; } #ifdef TOOLS_ENABLED if (!_load_editor_api_assembly(r_editor_api_assembly, p_config, p_refonly)) { - if (OS::get_singleton()->is_stdout_verbose()) + if (OS::get_singleton()->is_stdout_verbose()) { print_error("Mono: Failed to load Editor API assembly"); + } return false; } - if (r_editor_api_assembly.out_of_sync) + if (r_editor_api_assembly.out_of_sync) { return false; + } #endif // Check if the core API assembly is out of sync only after trying to load the // editor API assembly. Otherwise, if both assemblies are out of sync, we would // only update the former as we won't know the latter also needs to be updated. - if (r_core_api_assembly.out_of_sync) + if (r_core_api_assembly.out_of_sync) { return false; + } - if (p_callback) + if (p_callback) { return p_callback(); + } return true; } @@ -890,8 +913,9 @@ bool GDMono::_try_load_api_assemblies(LoadedApiAssembly &r_core_api_assembly, Lo bool GDMono::_on_core_api_assembly_loaded() { GDMonoCache::update_godot_api_cache(); - if (!GDMonoCache::cached_data.godot_api_cache_updated) + if (!GDMonoCache::cached_data.godot_api_cache_updated) { return false; + } get_singleton()->_install_trace_listener(); @@ -956,8 +980,9 @@ void GDMono::_load_api_assemblies() { #ifdef TOOLS_ENABLED bool GDMono::_load_tools_assemblies() { - if (tools_assembly && tools_project_editor_assembly) + if (tools_assembly && tools_project_editor_assembly) { return true; + } bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) && load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly); @@ -967,8 +992,9 @@ bool GDMono::_load_tools_assemblies() { #endif bool GDMono::_load_project_assembly() { - if (project_assembly) + if (project_assembly) { return true; + } String appname = ProjectSettings::get_singleton()->get("application/config/name"); String appname_safe = OS::get_singleton()->get_safe_dir_name(appname); @@ -1020,8 +1046,9 @@ Error GDMono::_unload_scripts_domain() { print_verbose("Mono: Finalizing scripts domain..."); - if (mono_domain_get() != root_domain) + if (mono_domain_get() != root_domain) { mono_domain_set(root_domain, true); + } finalizing_scripts_domain = true; @@ -1111,8 +1138,9 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { print_verbose("Mono: Unloading domain '" + domain_name + "'..."); - if (mono_domain_get() == p_domain) + if (mono_domain_get() == p_domain) { mono_domain_set(root_domain, true); + } if (!mono_domain_finalize(p_domain, 2000)) { ERR_PRINT("Mono: Domain finalization timeout."); @@ -1138,10 +1166,11 @@ Error GDMono::finalize_and_unload_domain(MonoDomain *p_domain) { GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { MonoImage *image = mono_class_get_image(p_raw_class); - if (image == corlib_assembly->get_image()) + if (image == corlib_assembly->get_image()) { return corlib_assembly->get_class(p_raw_class); + } - uint32_t domain_id = mono_domain_get_id(mono_domain_get()); + int32_t domain_id = mono_domain_get_id(mono_domain_get()); HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; const String *k = nullptr; @@ -1149,9 +1178,9 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { GDMonoAssembly *assembly = domain_assemblies.get(*k); if (assembly->get_image() == image) { GDMonoClass *klass = assembly->get_class(p_raw_class); - - if (klass) + if (klass) { return klass; + } } } @@ -1160,24 +1189,26 @@ GDMonoClass *GDMono::get_class(MonoClass *p_raw_class) { GDMonoClass *GDMono::get_class(const StringName &p_namespace, const StringName &p_name) { GDMonoClass *klass = corlib_assembly->get_class(p_namespace, p_name); - if (klass) + if (klass) { return klass; + } - uint32_t domain_id = mono_domain_get_id(mono_domain_get()); + int32_t domain_id = mono_domain_get_id(mono_domain_get()); HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[domain_id]; const String *k = nullptr; while ((k = domain_assemblies.next(k))) { GDMonoAssembly *assembly = domain_assemblies.get(*k); klass = assembly->get_class(p_namespace, p_name); - if (klass) + if (klass) { return klass; + } } return nullptr; } -void GDMono::_domain_assemblies_cleanup(uint32_t p_domain_id) { +void GDMono::_domain_assemblies_cleanup(int32_t p_domain_id) { HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies[p_domain_id]; const String *k = nullptr; @@ -1195,8 +1226,9 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) { #ifdef DEBUG_ENABLED GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc); - if (EngineDebugger::is_active()) + if (EngineDebugger::is_active()) { EngineDebugger::get_singleton()->poll_events(false); + } #endif exit(mono_environment_exitcode_get()); @@ -1271,7 +1303,7 @@ GDMono::~GDMono() { // Leave the rest to 'mono_jit_cleanup' #endif - const uint32_t *k = nullptr; + const int32_t *k = nullptr; while ((k = assemblies.next(k))) { HashMap<String, GDMonoAssembly *> &domain_assemblies = assemblies.get(*k); @@ -1295,8 +1327,9 @@ GDMono::~GDMono() { gdmono::android::support::cleanup(); #endif - if (gdmono_log) + if (gdmono_log) { memdelete(gdmono_log); + } singleton = nullptr; } @@ -1313,37 +1346,44 @@ void _GodotSharp::detach_thread() { int32_t _GodotSharp::get_domain_id() { MonoDomain *domain = mono_domain_get(); - CRASH_COND(!domain); // User must check if runtime is initialized before calling this method + ERR_FAIL_NULL_V(domain, -1); return mono_domain_get_id(domain); } int32_t _GodotSharp::get_scripts_domain_id() { + ERR_FAIL_NULL_V_MSG(GDMono::get_singleton(), + -1, "The Mono runtime is not initialized"); MonoDomain *domain = GDMono::get_singleton()->get_scripts_domain(); - CRASH_COND(!domain); // User must check if scripts domain is loaded before calling this method + ERR_FAIL_NULL_V(domain, -1); return mono_domain_get_id(domain); } bool _GodotSharp::is_scripts_domain_loaded() { - return GDMono::get_singleton()->is_runtime_initialized() && GDMono::get_singleton()->get_scripts_domain() != nullptr; + return GDMono::get_singleton() != nullptr && + GDMono::get_singleton()->is_runtime_initialized() && + GDMono::get_singleton()->get_scripts_domain() != nullptr; } bool _GodotSharp::_is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(p_domain_id); } -bool _GodotSharp::is_domain_finalizing_for_unload() { - return is_domain_finalizing_for_unload(mono_domain_get()); -} - bool _GodotSharp::is_domain_finalizing_for_unload(int32_t p_domain_id) { return is_domain_finalizing_for_unload(mono_domain_get_by_id(p_domain_id)); } bool _GodotSharp::is_domain_finalizing_for_unload(MonoDomain *p_domain) { - if (!p_domain) - return true; - if (p_domain == GDMono::get_singleton()->get_scripts_domain() && GDMono::get_singleton()->is_finalizing_scripts_domain()) + GDMono *gd_mono = GDMono::get_singleton(); + + ERR_FAIL_COND_V_MSG(!gd_mono || !gd_mono->is_runtime_initialized(), + false, "The Mono runtime is not initialized"); + + ERR_FAIL_NULL_V(p_domain, true); + + if (p_domain == gd_mono->get_scripts_domain() && gd_mono->is_finalizing_scripts_domain()) { return true; + } + return mono_domain_is_unloading(p_domain); } @@ -1352,15 +1392,17 @@ bool _GodotSharp::is_runtime_shutting_down() { } bool _GodotSharp::is_runtime_initialized() { - return GDMono::get_singleton()->is_runtime_initialized(); + return GDMono::get_singleton() != nullptr && GDMono::get_singleton()->is_runtime_initialized(); } void _GodotSharp::_reload_assemblies(bool p_soft_reload) { #ifdef GD_MONO_HOT_RELOAD + CRASH_COND(CSharpLanguage::get_singleton() == nullptr); // This method may be called more than once with `call_deferred`, so we need to check // again if reloading is needed to avoid reloading multiple times unnecessarily. - if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) + if (CSharpLanguage::get_singleton()->is_assembly_reloading_needed()) { CSharpLanguage::get_singleton()->reload_assemblies(p_soft_reload); + } #endif } diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 833855b371..969296c44d 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -97,7 +97,7 @@ private: MonoDomain *root_domain; MonoDomain *scripts_domain; - HashMap<uint32_t, HashMap<String, GDMonoAssembly *>> assemblies; + HashMap<int32_t, HashMap<String, GDMonoAssembly *>> assemblies; GDMonoAssembly *corlib_assembly; GDMonoAssembly *project_assembly; @@ -141,7 +141,7 @@ private: Error _unload_scripts_domain(); #endif - void _domain_assemblies_cleanup(uint32_t p_domain_id); + void _domain_assemblies_cleanup(int32_t p_domain_id); uint64_t api_core_hash; #ifdef TOOLS_ENABLED @@ -165,14 +165,16 @@ protected: public: #ifdef DEBUG_METHODS_ENABLED uint64_t get_api_core_hash() { - if (api_core_hash == 0) + if (api_core_hash == 0) { api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE); + } return api_core_hash; } #ifdef TOOLS_ENABLED uint64_t get_api_editor_hash() { - if (api_editor_hash == 0) + if (api_editor_hash == 0) { api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR); + } return api_editor_hash; } #endif // TOOLS_ENABLED @@ -202,7 +204,7 @@ public: UnhandledExceptionPolicy get_unhandled_exception_policy() const { return unhandled_exception_policy; } // Do not use these, unless you know what you're doing - void add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly); + void add_assembly(int32_t p_domain_id, GDMonoAssembly *p_assembly); GDMonoAssembly *get_loaded_assembly(const String &p_name); _FORCE_INLINE_ bool is_runtime_initialized() const { return runtime_initialized && !mono_runtime_is_shutting_down() /* stays true after shutdown finished */; } @@ -252,18 +254,18 @@ class ScopeDomain { public: ScopeDomain(MonoDomain *p_domain) { - MonoDomain *prev_domain = mono_domain_get(); + prev_domain = mono_domain_get(); if (prev_domain != p_domain) { - this->prev_domain = prev_domain; mono_domain_set(p_domain, false); } else { - this->prev_domain = nullptr; + prev_domain = nullptr; } } ~ScopeDomain() { - if (prev_domain) + if (prev_domain) { mono_domain_set(prev_domain, false); + } } }; @@ -276,11 +278,11 @@ public: } ~ScopeExitDomainUnload() { - if (domain) + if (domain) { GDMono::get_singleton()->finalize_and_unload_domain(domain); + } } }; - } // namespace gdmono #define _GDMONO_SCOPE_DOMAIN_(m_mono_domain) \ @@ -298,9 +300,6 @@ class _GodotSharp : public Object { bool _is_domain_finalizing_for_unload(int32_t p_domain_id); - List<NodePath *> np_delete_queue; - List<RID *> rid_delete_queue; - void _reload_assemblies(bool p_soft_reload); protected: @@ -318,7 +317,6 @@ public: bool is_scripts_domain_loaded(); - bool is_domain_finalizing_for_unload(); bool is_domain_finalizing_for_unload(int32_t p_domain_id); bool is_domain_finalizing_for_unload(MonoDomain *p_domain); diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp index 073c9a5214..33628b3ce3 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.cpp +++ b/modules/mono/mono_gd/gd_mono_assembly.cpp @@ -33,11 +33,11 @@ #include <mono/metadata/mono-debug.h> #include <mono/metadata/tokentype.h> +#include "core/config/project_settings.h" #include "core/io/file_access_pack.h" -#include "core/list.h" #include "core/os/file_access.h" #include "core/os/os.h" -#include "core/project_settings.h" +#include "core/templates/list.h" #include "../godotsharp_dirs.h" #include "gd_mono_cache.h" @@ -107,9 +107,10 @@ void GDMonoAssembly::assembly_load_hook(MonoAssembly *assembly, [[maybe_unused]] GDMonoAssembly *gdassembly = memnew(GDMonoAssembly(name, image, assembly)); #ifdef GD_MONO_HOT_RELOAD - const char *path = mono_image_get_filename(image); - if (FileAccess::exists(path)) + String path = String::utf8(mono_image_get_filename(image)); + if (FileAccess::exists(path)) { gdassembly->modified_time = FileAccess::get_modified_time(path); + } #endif MonoDomain *domain = mono_domain_get(); @@ -137,8 +138,9 @@ MonoAssembly *GDMonoAssembly::_search_hook(MonoAssemblyName *aname, [[maybe_unus bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); - if (loaded_asm) + if (loaded_asm) { return loaded_asm->get_assembly(); + } return nullptr; } @@ -161,22 +163,25 @@ MonoAssembly *GDMonoAssembly::_load_assembly_search(const String &p_name, MonoAs path = search_dir.plus_file(p_name); if (FileAccess::exists(path)) { res = _real_load_assembly_from(path, p_refonly, p_aname); - if (res != nullptr) + if (res != nullptr) { return res; + } } } else { path = search_dir.plus_file(p_name + ".dll"); if (FileAccess::exists(path)) { res = _real_load_assembly_from(path, p_refonly, p_aname); - if (res != nullptr) + if (res != nullptr) { return res; + } } path = search_dir.plus_file(p_name + ".exe"); if (FileAccess::exists(path)) { res = _real_load_assembly_from(path, p_refonly, p_aname); - if (res != nullptr) + if (res != nullptr) { return res; + } } } } @@ -194,16 +199,19 @@ String GDMonoAssembly::find_assembly(const String &p_name) { if (has_extension) { path = search_dir.plus_file(p_name); - if (FileAccess::exists(path)) + if (FileAccess::exists(path)) { return path; + } } else { path = search_dir.plus_file(p_name + ".dll"); - if (FileAccess::exists(path)) + if (FileAccess::exists(path)) { return path; + } path = search_dir.plus_file(p_name + ".exe"); - if (FileAccess::exists(path)) + if (FileAccess::exists(path)) { return path; + } } } @@ -279,8 +287,9 @@ MonoAssembly *GDMonoAssembly::_real_load_assembly_from(const String &p_path, boo if (!FileAccess::exists(pdb_path)) { pdb_path = p_path.get_basename() + ".pdb"; // without .dll - if (!FileAccess::exists(pdb_path)) + if (!FileAccess::exists(pdb_path)) { goto no_pdb; + } } pdb_data = FileAccess::get_file_as_array(pdb_path); @@ -307,8 +316,9 @@ no_pdb: String name = String::utf8(mono_assembly_name_get_name(mono_assembly_get_name(assembly))); bool has_extension = name.ends_with(".dll") || name.ends_with(".exe"); GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name); - if (!loaded_asm) + if (!loaded_asm) { assembly_load_hook(assembly, nullptr); + } } // Decrement refcount which was previously incremented by mono_image_open_from_data_with_name @@ -342,13 +352,15 @@ GDMonoClass *GDMonoAssembly::get_class(const StringName &p_namespace, const Stri GDMonoClass **match = cached_classes.getptr(key); - if (match) + if (match) { return *match; + } MonoClass *mono_class = mono_class_from_name(image, String(p_namespace).utf8(), String(p_name).utf8()); - if (!mono_class) + if (!mono_class) { return nullptr; + } GDMonoClass *wrapped_class = memnew(GDMonoClass(p_namespace, p_name, mono_class, this)); @@ -363,8 +375,9 @@ GDMonoClass *GDMonoAssembly::get_class(MonoClass *p_mono_class) { Map<MonoClass *, GDMonoClass *>::Element *match = cached_raw.find(p_mono_class); - if (match) + if (match) { return match->value(); + } StringName namespace_name = mono_class_get_namespace(p_mono_class); StringName class_name = mono_class_get_name(p_mono_class); @@ -383,8 +396,9 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) if (gdobject_class_cache_updated) { Map<StringName, GDMonoClass *>::Element *result = gdobject_class_cache.find(p_class); - if (result) + if (result) { match = result->get(); + } } else { List<GDMonoClass *> nested_classes; @@ -393,30 +407,34 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) for (int i = 1; i < rows; i++) { MonoClass *mono_class = mono_class_get(image, (i + 1) | MONO_TOKEN_TYPE_DEF); - if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) + if (!mono_class_is_assignable_from(CACHED_CLASS_RAW(GodotObject), mono_class)) { continue; + } GDMonoClass *current = get_class(mono_class); - if (!current) + if (!current) { continue; + } nested_classes.push_back(current); - if (!match && current->get_name() == p_class) + if (!match && current->get_name() == p_class) { match = current; + } while (!nested_classes.empty()) { GDMonoClass *current_nested = nested_classes.front()->get(); - nested_classes.pop_back(); + nested_classes.pop_front(); void *iter = nullptr; while (true) { MonoClass *raw_nested = mono_class_get_nested_types(current_nested->get_mono_ptr(), &iter); - if (!raw_nested) + if (!raw_nested) { break; + } GDMonoClass *nested_class = get_class(raw_nested); @@ -437,15 +455,18 @@ GDMonoClass *GDMonoAssembly::get_object_derived_class(const StringName &p_class) } GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_aname, bool p_refonly, const Vector<String> &p_search_dirs) { - if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) + if (GDMono::get_singleton()->get_corlib_assembly() && (p_name == "mscorlib" || p_name == "mscorlib.dll")) { return GDMono::get_singleton()->get_corlib_assembly(); + } // We need to manually call the search hook in this case, as it won't be called in the next step MonoAssembly *assembly = mono_assembly_invoke_search_hook(p_aname); if (!assembly) { assembly = _load_assembly_search(p_name, p_aname, p_refonly, p_search_dirs); - ERR_FAIL_NULL_V(assembly, nullptr); + if (!assembly) { + return nullptr; + } } GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name); @@ -456,8 +477,9 @@ GDMonoAssembly *GDMonoAssembly::load(const String &p_name, MonoAssemblyName *p_a } GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_path, bool p_refonly) { - if (p_name == "mscorlib" || p_name == "mscorlib.dll") + if (p_name == "mscorlib" || p_name == "mscorlib.dll") { return GDMono::get_singleton()->get_corlib_assembly(); + } // We need to manually call the search hook in this case, as it won't be called in the next step MonoAssemblyName *aname = mono_assembly_name_new(p_name.utf8()); @@ -467,7 +489,9 @@ GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_ if (!assembly) { assembly = _real_load_assembly_from(p_path, p_refonly); - ERR_FAIL_NULL_V(assembly, nullptr); + if (!assembly) { + return nullptr; + } } GDMonoAssembly *loaded_asm = GDMono::get_singleton()->get_loaded_assembly(p_name); @@ -477,6 +501,7 @@ GDMonoAssembly *GDMonoAssembly::load_from(const String &p_name, const String &p_ } GDMonoAssembly::~GDMonoAssembly() { - if (image) + if (image) { unload(); + } } diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h index 63899dc9be..fc10480e07 100644 --- a/modules/mono/mono_gd/gd_mono_assembly.h +++ b/modules/mono/mono_gd/gd_mono_assembly.h @@ -34,9 +34,9 @@ #include <mono/jit/jit.h> #include <mono/metadata/assembly.h> -#include "core/hash_map.h" -#include "core/map.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/hash_map.h" +#include "core/templates/map.h" #include "gd_mono_utils.h" class GDMonoAssembly { diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index c002ad2139..3f51c6523b 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -217,7 +217,7 @@ void update_corlib_cache() { CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_Exception_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(System.Exception,bool)", true)); #endif - CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", 1)); + CACHE_METHOD_THUNK_AND_CHECK(Delegate, Equals, GDMono::get_singleton()->get_corlib_assembly()->get_class("System", "Delegate")->get_method_with_desc("System.Delegate:Equals(object)", true)); CACHE_CLASS_AND_CHECK(KeyNotFoundException, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Collections.Generic", "KeyNotFoundException")); @@ -316,5 +316,4 @@ void update_godot_api_cache() { cached_data.godot_api_cache_updated = true; } - } // namespace GDMonoCache diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index a7bbc763a7..9dfa5769be 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -181,7 +181,6 @@ inline void clear_corlib_cache() { inline void clear_godot_api_cache() { cached_data.clear_godot_api_cache(); } - } // namespace GDMonoCache #define CACHED_CLASS(m_class) (GDMonoCache::cached_data.class_##m_class) diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 691da55b10..6575cbc1c8 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -81,15 +81,17 @@ bool GDMonoClass::is_assignable_from(GDMonoClass *p_from) const { StringName GDMonoClass::get_namespace() const { GDMonoClass *nesting_class = get_nesting_class(); - if (!nesting_class) + if (!nesting_class) { return namespace_name; + } return nesting_class->get_namespace(); } String GDMonoClass::get_name_for_lookup() const { GDMonoClass *nesting_class = get_nesting_class(); - if (!nesting_class) + if (!nesting_class) { return class_name; + } return nesting_class->get_name_for_lookup() + "/" + class_name; } @@ -131,11 +133,13 @@ bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); #endif - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -145,11 +149,13 @@ MonoObject *GDMonoClass::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); #endif - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -164,8 +170,9 @@ void GDMonoClass::fetch_attributes() { void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base) { CRASH_COND(!CACHED_CLASS(GodotObject)->is_assignable_from(this)); - if (methods_fetched) + if (methods_fetched) { return; + } void *iter = nullptr; MonoMethod *raw_method = nullptr; @@ -202,8 +209,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base break; } - if (native_top == CACHED_CLASS(GodotObject)) + if (native_top == CACHED_CLASS(GodotObject)) { break; + } native_top = native_top->get_parent_class(); } @@ -212,8 +220,9 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base uint32_t flags = mono_method_get_flags(method->mono_method, nullptr); - if (!(flags & MONO_METHOD_ATTR_VIRTUAL)) + if (!(flags & MONO_METHOD_ATTR_VIRTUAL)) { continue; + } // Virtual method of Godot Object derived type, let's try to find GodotMethod attribute @@ -235,15 +244,17 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base #endif MethodKey key = MethodKey(godot_method_name, method->get_parameters_count()); GDMonoMethod **existing_method = methods.getptr(key); - if (existing_method) + if (existing_method) { memdelete(*existing_method); // Must delete old one + } methods.set(key, method); break; } - if (top == CACHED_CLASS(GodotObject)) + if (top == CACHED_CLASS(GodotObject)) { break; + } top = top->get_parent_class(); } @@ -258,8 +269,9 @@ GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p const MethodKey *k = nullptr; while ((k = methods.next(k))) { - if (k->name == p_name) + if (k->name == p_name) { return methods.get(*k); + } } return nullptr; @@ -283,11 +295,13 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_cou GDMonoMethod **match = methods.getptr(key); - if (match) + if (match) { return *match; + } - if (methods_fetched) + if (methods_fetched) { return nullptr; + } MonoMethod *raw_method = mono_class_get_method_from_name(mono_class, String(p_name).utf8().get_data(), p_params_count); @@ -323,8 +337,9 @@ GDMonoMethod *GDMonoClass::get_method(MonoMethod *p_raw_method, const StringName GDMonoMethod **match = methods.getptr(key); - if (match) + if (match) { return *match; + } GDMonoMethod *method = memnew(GDMonoMethod(p_name, p_raw_method)); methods.set(key, method); @@ -337,8 +352,9 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo MonoMethod *method = mono_method_desc_search_in_class(desc, mono_class); mono_method_desc_free(desc); - if (!method) + if (!method) { return nullptr; + } ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, nullptr); @@ -348,11 +364,13 @@ GDMonoMethod *GDMonoClass::get_method_with_desc(const String &p_description, boo GDMonoField *GDMonoClass::get_field(const StringName &p_name) { Map<StringName, GDMonoField *>::Element *result = fields.find(p_name); - if (result) + if (result) { return result->value(); + } - if (fields_fetched) + if (fields_fetched) { return nullptr; + } MonoClassField *raw_field = mono_class_get_field_from_name(mono_class, String(p_name).utf8().get_data()); @@ -367,8 +385,9 @@ GDMonoField *GDMonoClass::get_field(const StringName &p_name) { } const Vector<GDMonoField *> &GDMonoClass::get_all_fields() { - if (fields_fetched) + if (fields_fetched) { return fields_list; + } void *iter = nullptr; MonoClassField *raw_field = nullptr; @@ -394,11 +413,13 @@ const Vector<GDMonoField *> &GDMonoClass::get_all_fields() { GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) { Map<StringName, GDMonoProperty *>::Element *result = properties.find(p_name); - if (result) + if (result) { return result->value(); + } - if (properties_fetched) + if (properties_fetched) { return nullptr; + } MonoProperty *raw_property = mono_class_get_property_from_name(mono_class, String(p_name).utf8().get_data()); @@ -413,8 +434,9 @@ GDMonoProperty *GDMonoClass::get_property(const StringName &p_name) { } const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() { - if (properties_fetched) + if (properties_fetched) { return properties_list; + } void *iter = nullptr; MonoProperty *raw_property = nullptr; @@ -438,8 +460,9 @@ const Vector<GDMonoProperty *> &GDMonoClass::get_all_properties() { } const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { - if (delegates_fetched) + if (delegates_fetched) { return delegates_list; + } void *iter = nullptr; MonoClass *raw_class = nullptr; diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h index 44b146b87c..87db2fa033 100644 --- a/modules/mono/mono_gd/gd_mono_class.h +++ b/modules/mono/mono_gd/gd_mono_class.h @@ -31,8 +31,8 @@ #ifndef GD_MONO_CLASS_H #define GD_MONO_CLASS_H -#include "core/map.h" -#include "core/ustring.h" +#include "core/string/ustring.h" +#include "core/templates/map.h" #include "gd_mono_field.h" #include "gd_mono_header.h" diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp index 948170f51c..00a1e1e507 100644 --- a/modules/mono/mono_gd/gd_mono_field.cpp +++ b/modules/mono/mono_gd/gd_mono_field.cpp @@ -355,7 +355,7 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ } if (CACHED_CLASS(RID) == type_class) { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID()); + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator ::RID()); mono_field_set_value(p_object, mono_field, managed); break; } @@ -450,8 +450,8 @@ void GDMonoField::set_value_from_variant(MonoObject *p_object, const Variant &p_ MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator NodePath()); mono_field_set_value(p_object, mono_field, managed); } break; - case Variant::_RID: { - MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator RID()); + case Variant::RID: { + MonoObject *managed = GDMonoUtils::create_managed_from(p_value.operator ::RID()); mono_field_set_value(p_object, mono_field, managed); } break; case Variant::OBJECT: { @@ -597,11 +597,13 @@ String GDMonoField::get_string_value(MonoObject *p_object) { bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -609,11 +611,13 @@ bool GDMonoField::has_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoField::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h index 0f4f888546..ffb56e7cec 100644 --- a/modules/mono/mono_gd/gd_mono_header.h +++ b/modules/mono/mono_gd/gd_mono_header.h @@ -31,7 +31,7 @@ #ifndef GD_MONO_HEADER_H #define GD_MONO_HEADER_H -#include "core/int_types.h" +#include <cstdint> #ifdef WIN32 #define GD_MONO_STDCALL __stdcall diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp index abb2761909..82f916e8c5 100644 --- a/modules/mono/mono_gd/gd_mono_internals.cpp +++ b/modules/mono/mono_gd/gd_mono_internals.cpp @@ -109,8 +109,6 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) { CSharpInstance *csharp_instance = CSharpInstance::create_for_managed_type(unmanaged, script.ptr(), gchandle); unmanaged->set_script_and_instance(script, csharp_instance); - - csharp_instance->connect_event_signals(); } void unhandled_exception(MonoException *p_exc) { @@ -122,11 +120,11 @@ void unhandled_exception(MonoException *p_exc) { GD_UNREACHABLE(); } else { #ifdef DEBUG_ENABLED - GDMonoUtils::debug_send_unhandled_exception_error((MonoException *)p_exc); - if (EngineDebugger::is_active()) + GDMonoUtils::debug_send_unhandled_exception_error(p_exc); + if (EngineDebugger::is_active()) { EngineDebugger::get_singleton()->poll_events(false); + } #endif } } - } // namespace GDMonoInternals diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h index 038d17f782..0fd6250785 100644 --- a/modules/mono/mono_gd/gd_mono_internals.h +++ b/modules/mono/mono_gd/gd_mono_internals.h @@ -35,7 +35,7 @@ #include "../utils/macros.h" -#include "core/object.h" +#include "core/object/class_db.h" namespace GDMonoInternals { @@ -46,7 +46,6 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged); * Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead. */ void unhandled_exception(MonoException *p_exc); - } // namespace GDMonoInternals #endif // GD_MONO_INTERNALS_H diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index 04728be725..b8ee0204c4 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -55,33 +55,41 @@ static int get_log_level_id(const char *p_log_level) { int i = 0; while (valid_log_levels[i]) { - if (!strcmp(valid_log_levels[i], p_log_level)) + if (!strcmp(valid_log_levels[i], p_log_level)) { return i; + } i++; } return -1; } +static String make_text(const char *log_domain, const char *log_level, const char *message) { + String text(message); + text += " (in domain "; + text += log_domain; + if (log_level) { + text += ", "; + text += log_level; + } + text += ")"; + return text; +} + void GDMonoLog::mono_log_callback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *) { FileAccess *f = GDMonoLog::get_singleton()->log_file; if (GDMonoLog::get_singleton()->log_level_id >= get_log_level_id(log_level)) { - String text(message); - text += " (in domain "; - text += log_domain; - if (log_level) { - text += ", "; - text += log_level; - } - text += ")\n"; + String text = make_text(log_domain, log_level, message); + text += "\n"; f->seek_end(); f->store_string(text); } if (fatal) { - ERR_PRINT("Mono: FATAL ERROR, ABORTING! Logfile: '" + GDMonoLog::get_singleton()->log_file_path + "'."); + String text = make_text(log_domain, log_level, message); + ERR_PRINT("Mono: FATAL ERROR '" + text + "', ABORTING! Logfile: '" + GDMonoLog::get_singleton()->log_file_path + "'."); // Make sure to flush before aborting f->flush(); f->close(); @@ -115,10 +123,12 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) { String current; while ((current = da->get_next()).length()) { - if (da->current_is_dir()) + if (da->current_is_dir()) { continue; - if (!current.ends_with(".txt")) + } + if (!current.ends_with(".txt")) { continue; + } uint64_t modified_time = FileAccess::get_modified_time(da->get_current_dir().plus_file(current)); diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index 92734a0792..eee880ba60 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -72,92 +72,119 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ case MONO_TYPE_VALUETYPE: { GDMonoClass *vtclass = p_type.type_class; - if (vtclass == CACHED_CLASS(Vector2)) + if (vtclass == CACHED_CLASS(Vector2)) { return Variant::VECTOR2; + } - if (vtclass == CACHED_CLASS(Vector2i)) + if (vtclass == CACHED_CLASS(Vector2i)) { return Variant::VECTOR2I; + } - if (vtclass == CACHED_CLASS(Rect2)) + if (vtclass == CACHED_CLASS(Rect2)) { return Variant::RECT2; + } - if (vtclass == CACHED_CLASS(Rect2i)) + if (vtclass == CACHED_CLASS(Rect2i)) { return Variant::RECT2I; + } - if (vtclass == CACHED_CLASS(Transform2D)) + if (vtclass == CACHED_CLASS(Transform2D)) { return Variant::TRANSFORM2D; + } - if (vtclass == CACHED_CLASS(Vector3)) + if (vtclass == CACHED_CLASS(Vector3)) { return Variant::VECTOR3; + } - if (vtclass == CACHED_CLASS(Vector3i)) + if (vtclass == CACHED_CLASS(Vector3i)) { return Variant::VECTOR3I; + } - if (vtclass == CACHED_CLASS(Basis)) + if (vtclass == CACHED_CLASS(Basis)) { return Variant::BASIS; + } - if (vtclass == CACHED_CLASS(Quat)) + if (vtclass == CACHED_CLASS(Quat)) { return Variant::QUAT; + } - if (vtclass == CACHED_CLASS(Transform)) + if (vtclass == CACHED_CLASS(Transform)) { return Variant::TRANSFORM; + } - if (vtclass == CACHED_CLASS(AABB)) + if (vtclass == CACHED_CLASS(AABB)) { return Variant::AABB; + } - if (vtclass == CACHED_CLASS(Color)) + if (vtclass == CACHED_CLASS(Color)) { return Variant::COLOR; + } - if (vtclass == CACHED_CLASS(Plane)) + if (vtclass == CACHED_CLASS(Plane)) { return Variant::PLANE; + } - if (vtclass == CACHED_CLASS(Callable)) + if (vtclass == CACHED_CLASS(Callable)) { return Variant::CALLABLE; + } - if (vtclass == CACHED_CLASS(SignalInfo)) + if (vtclass == CACHED_CLASS(SignalInfo)) { return Variant::SIGNAL; + } - if (mono_class_is_enum(vtclass->get_mono_ptr())) + if (mono_class_is_enum(vtclass->get_mono_ptr())) { return Variant::INT; + } } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) + if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { return Variant::ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) + if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { return Variant::PACKED_BYTE_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { return Variant::PACKED_INT32_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { return Variant::PACKED_INT64_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(float)) + if (array_type->eklass == CACHED_CLASS_RAW(float)) { return Variant::PACKED_FLOAT32_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(double)) + if (array_type->eklass == CACHED_CLASS_RAW(double)) { return Variant::PACKED_FLOAT64_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(String)) + if (array_type->eklass == CACHED_CLASS_RAW(String)) { return Variant::PACKED_STRING_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { return Variant::PACKED_VECTOR2_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { return Variant::PACKED_VECTOR3_ARRAY; + } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) + if (array_type->eklass == CACHED_CLASS_RAW(Color)) { return Variant::PACKED_COLOR_ARRAY; + } GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return Variant::ARRAY; + } } break; case MONO_TYPE_CLASS: { @@ -177,7 +204,7 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ } if (CACHED_CLASS(RID) == type_class) { - return Variant::_RID; + return Variant::RID; } if (CACHED_CLASS(Dictionary) == type_class) { @@ -201,8 +228,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ } break; case MONO_TYPE_OBJECT: { - if (r_nil_is_variant) + if (r_nil_is_variant) { *r_nil_is_variant = true; + } return Variant::NIL; } break; @@ -244,8 +272,9 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ } break; } - if (r_nil_is_variant) + if (r_nil_is_variant) { *r_nil_is_variant = false; + } // Unknown return Variant::NIL; @@ -282,68 +311,6 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_ return false; } -bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type) { - switch (p_dictionary_type.type_encoding) { - case MONO_TYPE_GENERICINST: { - MonoReflectionType *dict_reftype = mono_type_get_object(mono_domain_get(), p_dictionary_type.type_class->get_mono_type()); - - if (GDMonoUtils::Marshal::type_is_generic_dictionary(dict_reftype) || - GDMonoUtils::Marshal::type_is_system_generic_dictionary(dict_reftype) || - GDMonoUtils::Marshal::type_is_generic_idictionary(dict_reftype)) { - MonoReflectionType *key_reftype; - MonoReflectionType *value_reftype; - - GDMonoUtils::Marshal::dictionary_get_key_value_types(dict_reftype, &key_reftype, &value_reftype); - - r_key_type = ManagedType::from_reftype(key_reftype); - r_value_type = ManagedType::from_reftype(value_reftype); - return true; - } - } break; - default: { - } break; - } - - return false; -} - -String mono_to_utf8_string(MonoString *p_mono_string) { - MonoError error; - char *utf8 = mono_string_to_utf8_checked(p_mono_string, &error); - - if (!mono_error_ok(&error)) { - ERR_PRINT(String() + "Failed to convert MonoString* to UTF-8: '" + mono_error_get_message(&error) + "'."); - mono_error_cleanup(&error); - return String(); - } - - String ret = String::utf8(utf8); - - mono_free(utf8); - - return ret; -} - -String mono_to_utf16_string(MonoString *p_mono_string) { - int len = mono_string_length(p_mono_string); - String ret; - - if (len == 0) - return ret; - - ret.resize(len + 1); - ret.set(len, 0); - - CharType *src = (CharType *)mono_string_chars(p_mono_string); - CharType *dst = ret.ptrw(); - - for (int i = 0; i < len; i++) { - dst[i] = src[i]; - } - - return ret; -} - MonoObject *variant_to_mono_object(const Variant *p_var) { ManagedType type; @@ -409,8 +376,9 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty } case MONO_TYPE_STRING: { - if (p_var->get_type() == Variant::NIL) + if (p_var->get_type() == Variant::NIL) { return nullptr; // Otherwise, Variant -> String would return the string "Null" + } return (MonoObject *)mono_string_from_godot(p_var->operator String()); } break; @@ -547,39 +515,50 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) + if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { return (MonoObject *)Array_to_mono_array(p_var->operator Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) + if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { return (MonoObject *)PackedByteArray_to_mono_array(p_var->operator PackedByteArray()); + } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { return (MonoObject *)PackedInt32Array_to_mono_array(p_var->operator PackedInt32Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { return (MonoObject *)PackedInt64Array_to_mono_array(p_var->operator PackedInt64Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(float)) + if (array_type->eklass == CACHED_CLASS_RAW(float)) { return (MonoObject *)PackedFloat32Array_to_mono_array(p_var->operator PackedFloat32Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(double)) + if (array_type->eklass == CACHED_CLASS_RAW(double)) { return (MonoObject *)PackedFloat64Array_to_mono_array(p_var->operator PackedFloat64Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(String)) + if (array_type->eklass == CACHED_CLASS_RAW(String)) { return (MonoObject *)PackedStringArray_to_mono_array(p_var->operator PackedStringArray()); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { return (MonoObject *)PackedVector2Array_to_mono_array(p_var->operator PackedVector2Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { return (MonoObject *)PackedVector3Array_to_mono_array(p_var->operator PackedVector3Array()); + } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) + if (array_type->eklass == CACHED_CLASS_RAW(Color)) { return (MonoObject *)PackedColorArray_to_mono_array(p_var->operator PackedColorArray()); + } GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return (MonoObject *)Array_to_mono_array(p_var->operator Array(), array_type_class); + } ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to a managed array of unmarshallable element type."); } break; @@ -601,7 +580,7 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty } if (CACHED_CLASS(RID) == type_class) { - return GDMonoUtils::create_managed_from(p_var->operator RID()); + return GDMonoUtils::create_managed_from(p_var->operator ::RID()); } // Godot.Collections.Dictionary or IDictionary @@ -694,8 +673,8 @@ MonoObject *variant_to_mono_object(const Variant *p_var, const ManagedType &p_ty return GDMonoUtils::create_managed_from(p_var->operator StringName()); case Variant::NODE_PATH: return GDMonoUtils::create_managed_from(p_var->operator NodePath()); - case Variant::_RID: - return GDMonoUtils::create_managed_from(p_var->operator RID()); + case Variant::RID: + return GDMonoUtils::create_managed_from(p_var->operator ::RID()); case Variant::OBJECT: return GDMonoUtils::unmanaged_get_managed(p_var->operator Object *()); case Variant::CALLABLE: { @@ -820,100 +799,128 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return unbox<double>(p_obj); case MONO_TYPE_STRING: { - if (p_obj == nullptr) + if (p_obj == nullptr) { return Variant(); // NIL + } return mono_string_to_godot_not_null((MonoString *)p_obj); } break; case MONO_TYPE_VALUETYPE: { GDMonoClass *vtclass = p_type.type_class; - if (vtclass == CACHED_CLASS(Vector2)) + if (vtclass == CACHED_CLASS(Vector2)) { return MARSHALLED_IN(Vector2, unbox_addr<GDMonoMarshal::M_Vector2>(p_obj)); + } - if (vtclass == CACHED_CLASS(Vector2i)) + if (vtclass == CACHED_CLASS(Vector2i)) { return MARSHALLED_IN(Vector2i, unbox_addr<GDMonoMarshal::M_Vector2i>(p_obj)); + } - if (vtclass == CACHED_CLASS(Rect2)) + if (vtclass == CACHED_CLASS(Rect2)) { return MARSHALLED_IN(Rect2, unbox_addr<GDMonoMarshal::M_Rect2>(p_obj)); + } - if (vtclass == CACHED_CLASS(Rect2i)) + if (vtclass == CACHED_CLASS(Rect2i)) { return MARSHALLED_IN(Rect2i, unbox_addr<GDMonoMarshal::M_Rect2i>(p_obj)); + } - if (vtclass == CACHED_CLASS(Transform2D)) + if (vtclass == CACHED_CLASS(Transform2D)) { return MARSHALLED_IN(Transform2D, unbox_addr<GDMonoMarshal::M_Transform2D>(p_obj)); + } - if (vtclass == CACHED_CLASS(Vector3)) + if (vtclass == CACHED_CLASS(Vector3)) { return MARSHALLED_IN(Vector3, unbox_addr<GDMonoMarshal::M_Vector3>(p_obj)); + } - if (vtclass == CACHED_CLASS(Vector3i)) + if (vtclass == CACHED_CLASS(Vector3i)) { return MARSHALLED_IN(Vector3i, unbox_addr<GDMonoMarshal::M_Vector3i>(p_obj)); + } - if (vtclass == CACHED_CLASS(Basis)) + if (vtclass == CACHED_CLASS(Basis)) { return MARSHALLED_IN(Basis, unbox_addr<GDMonoMarshal::M_Basis>(p_obj)); + } - if (vtclass == CACHED_CLASS(Quat)) + if (vtclass == CACHED_CLASS(Quat)) { return MARSHALLED_IN(Quat, unbox_addr<GDMonoMarshal::M_Quat>(p_obj)); + } - if (vtclass == CACHED_CLASS(Transform)) + if (vtclass == CACHED_CLASS(Transform)) { return MARSHALLED_IN(Transform, unbox_addr<GDMonoMarshal::M_Transform>(p_obj)); + } - if (vtclass == CACHED_CLASS(AABB)) + if (vtclass == CACHED_CLASS(AABB)) { return MARSHALLED_IN(AABB, unbox_addr<GDMonoMarshal::M_AABB>(p_obj)); + } - if (vtclass == CACHED_CLASS(Color)) + if (vtclass == CACHED_CLASS(Color)) { return MARSHALLED_IN(Color, unbox_addr<GDMonoMarshal::M_Color>(p_obj)); + } - if (vtclass == CACHED_CLASS(Plane)) + if (vtclass == CACHED_CLASS(Plane)) { return MARSHALLED_IN(Plane, unbox_addr<GDMonoMarshal::M_Plane>(p_obj)); + } - if (vtclass == CACHED_CLASS(Callable)) + if (vtclass == CACHED_CLASS(Callable)) { return managed_to_callable(unbox<GDMonoMarshal::M_Callable>(p_obj)); + } - if (vtclass == CACHED_CLASS(SignalInfo)) + if (vtclass == CACHED_CLASS(SignalInfo)) { return managed_to_signal_info(unbox<GDMonoMarshal::M_SignalInfo>(p_obj)); + } - if (mono_class_is_enum(vtclass->get_mono_ptr())) + if (mono_class_is_enum(vtclass->get_mono_ptr())) { return unbox<int32_t>(p_obj); + } } break; case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) + if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { return mono_array_to_Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) + if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { return mono_array_to_PackedByteArray((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { return mono_array_to_PackedInt32Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) + if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { return mono_array_to_PackedInt64Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(float)) + if (array_type->eklass == CACHED_CLASS_RAW(float)) { return mono_array_to_PackedFloat32Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(double)) + if (array_type->eklass == CACHED_CLASS_RAW(double)) { return mono_array_to_PackedFloat64Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(String)) + if (array_type->eklass == CACHED_CLASS_RAW(String)) { return mono_array_to_PackedStringArray((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { return mono_array_to_PackedVector2Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) + if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { return mono_array_to_PackedVector3Array((MonoArray *)p_obj); + } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) + if (array_type->eklass == CACHED_CLASS_RAW(Color)) { return mono_array_to_PackedColorArray((MonoArray *)p_obj); + } GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) + if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return mono_array_to_Array((MonoArray *)p_obj); + } if (p_fail_with_err) { ERR_FAIL_V_MSG(Variant(), "Attempted to convert a managed array of unmarshallable element type to Variant."); @@ -1012,8 +1019,9 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type } Variant mono_object_to_variant(MonoObject *p_obj) { - if (!p_obj) + if (!p_obj) { return Variant(); + } ManagedType type = ManagedType::from_class(mono_object_get_class(p_obj)); @@ -1021,15 +1029,17 @@ Variant mono_object_to_variant(MonoObject *p_obj) { } Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) { - if (!p_obj) + if (!p_obj) { return Variant(); + } return mono_object_to_variant_impl(p_obj, p_type); } Variant mono_object_to_variant_no_err(MonoObject *p_obj, const ManagedType &p_type) { - if (!p_obj) + if (!p_obj) { return Variant(); + } return mono_object_to_variant_impl(p_obj, p_type, /* fail_with_err: */ false); } @@ -1048,8 +1058,9 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { MonoString *mono_str = GDMonoUtils::object_to_string(p_obj, &exc); if (exc) { - if (r_exc) + if (r_exc) { *r_exc = exc; + } return String(); } @@ -1159,8 +1170,9 @@ MonoArray *Array_to_mono_array(const Array &p_array, GDMonoClass *p_array_type_c Array mono_array_to_Array(MonoArray *p_array) { Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); @@ -1178,22 +1190,23 @@ MonoArray *PackedInt32Array_to_mono_array(const PackedInt32Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int32_t), length); - int32_t *dst = (int32_t *)mono_array_addr(ret, int32_t, 0); - memcpy(dst, src, length); + int32_t *dst = mono_array_addr(ret, int32_t, 0); + memcpy(dst, src, length * sizeof(int32_t)); return ret; } PackedInt32Array mono_array_to_PackedInt32Array(MonoArray *p_array) { PackedInt32Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); int32_t *dst = ret.ptrw(); - const int32_t *src = (const int32_t *)mono_array_addr(p_array, int32_t, 0); - memcpy(dst, src, length); + const int32_t *src = mono_array_addr(p_array, int32_t, 0); + memcpy(dst, src, length * sizeof(int32_t)); return ret; } @@ -1204,22 +1217,23 @@ MonoArray *PackedInt64Array_to_mono_array(const PackedInt64Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(int64_t), length); - int64_t *dst = (int64_t *)mono_array_addr(ret, int64_t, 0); - memcpy(dst, src, length); + int64_t *dst = mono_array_addr(ret, int64_t, 0); + memcpy(dst, src, length * sizeof(int64_t)); return ret; } PackedInt64Array mono_array_to_PackedInt64Array(MonoArray *p_array) { PackedInt64Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); int64_t *dst = ret.ptrw(); - const int64_t *src = (const int64_t *)mono_array_addr(p_array, int64_t, 0); - memcpy(dst, src, length); + const int64_t *src = mono_array_addr(p_array, int64_t, 0); + memcpy(dst, src, length * sizeof(int64_t)); return ret; } @@ -1230,22 +1244,23 @@ MonoArray *PackedByteArray_to_mono_array(const PackedByteArray &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(uint8_t), length); - uint8_t *dst = (uint8_t *)mono_array_addr(ret, uint8_t, 0); - memcpy(dst, src, length); + uint8_t *dst = mono_array_addr(ret, uint8_t, 0); + memcpy(dst, src, length * sizeof(uint8_t)); return ret; } PackedByteArray mono_array_to_PackedByteArray(MonoArray *p_array) { PackedByteArray ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); uint8_t *dst = ret.ptrw(); - const uint8_t *src = (const uint8_t *)mono_array_addr(p_array, uint8_t, 0); - memcpy(dst, src, length); + const uint8_t *src = mono_array_addr(p_array, uint8_t, 0); + memcpy(dst, src, length * sizeof(uint8_t)); return ret; } @@ -1256,22 +1271,23 @@ MonoArray *PackedFloat32Array_to_mono_array(const PackedFloat32Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(float), length); - float *dst = (float *)mono_array_addr(ret, float, 0); - memcpy(dst, src, length); + float *dst = mono_array_addr(ret, float, 0); + memcpy(dst, src, length * sizeof(float)); return ret; } PackedFloat32Array mono_array_to_PackedFloat32Array(MonoArray *p_array) { PackedFloat32Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); float *dst = ret.ptrw(); - const float *src = (const float *)mono_array_addr(p_array, float, 0); - memcpy(dst, src, length); + const float *src = mono_array_addr(p_array, float, 0); + memcpy(dst, src, length * sizeof(float)); return ret; } @@ -1282,22 +1298,23 @@ MonoArray *PackedFloat64Array_to_mono_array(const PackedFloat64Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(double), length); - double *dst = (double *)mono_array_addr(ret, double, 0); - memcpy(dst, src, length); + double *dst = mono_array_addr(ret, double, 0); + memcpy(dst, src, length * sizeof(double)); return ret; } PackedFloat64Array mono_array_to_PackedFloat64Array(MonoArray *p_array) { PackedFloat64Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); double *dst = ret.ptrw(); - const double *src = (const double *)mono_array_addr(p_array, double, 0); - memcpy(dst, src, length); + const double *src = mono_array_addr(p_array, double, 0); + memcpy(dst, src, length * sizeof(double)); return ret; } @@ -1318,8 +1335,9 @@ MonoArray *PackedStringArray_to_mono_array(const PackedStringArray &p_array) { PackedStringArray mono_array_to_PackedStringArray(MonoArray *p_array) { PackedStringArray ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); String *w = ret.ptrw(); @@ -1339,8 +1357,8 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Color), length); if constexpr (InteropLayout::MATCHES_Color) { - Color *dst = (Color *)mono_array_addr(ret, Color, 0); - memcpy(dst, src, length); + Color *dst = mono_array_addr(ret, Color, 0); + memcpy(dst, src, length * sizeof(Color)); } else { for (int i = 0; i < length; i++) { M_Color *raw = (M_Color *)mono_array_addr_with_size(ret, sizeof(M_Color), i); @@ -1353,15 +1371,16 @@ MonoArray *PackedColorArray_to_mono_array(const PackedColorArray &p_array) { PackedColorArray mono_array_to_PackedColorArray(MonoArray *p_array) { PackedColorArray ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); Color *dst = ret.ptrw(); if constexpr (InteropLayout::MATCHES_Color) { - const Color *src = (const Color *)mono_array_addr(p_array, Color, 0); - memcpy(dst, src, length); + const Color *src = mono_array_addr(p_array, Color, 0); + memcpy(dst, src, length * sizeof(Color)); } else { for (int i = 0; i < length; i++) { dst[i] = MARSHALLED_IN(Color, (M_Color *)mono_array_addr_with_size(p_array, sizeof(M_Color), i)); @@ -1378,8 +1397,8 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector2), length); if constexpr (InteropLayout::MATCHES_Vector2) { - Vector2 *dst = (Vector2 *)mono_array_addr(ret, Vector2, 0); - memcpy(dst, src, length); + Vector2 *dst = mono_array_addr(ret, Vector2, 0); + memcpy(dst, src, length * sizeof(Vector2)); } else { for (int i = 0; i < length; i++) { M_Vector2 *raw = (M_Vector2 *)mono_array_addr_with_size(ret, sizeof(M_Vector2), i); @@ -1392,15 +1411,16 @@ MonoArray *PackedVector2Array_to_mono_array(const PackedVector2Array &p_array) { PackedVector2Array mono_array_to_PackedVector2Array(MonoArray *p_array) { PackedVector2Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); Vector2 *dst = ret.ptrw(); if constexpr (InteropLayout::MATCHES_Vector2) { - const Vector2 *src = (const Vector2 *)mono_array_addr(p_array, Vector2, 0); - memcpy(dst, src, length); + const Vector2 *src = mono_array_addr(p_array, Vector2, 0); + memcpy(dst, src, length * sizeof(Vector2)); } else { for (int i = 0; i < length; i++) { dst[i] = MARSHALLED_IN(Vector2, (M_Vector2 *)mono_array_addr_with_size(p_array, sizeof(M_Vector2), i)); @@ -1417,8 +1437,8 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) { MonoArray *ret = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(Vector3), length); if constexpr (InteropLayout::MATCHES_Vector3) { - Vector3 *dst = (Vector3 *)mono_array_addr(ret, Vector3, 0); - memcpy(dst, src, length); + Vector3 *dst = mono_array_addr(ret, Vector3, 0); + memcpy(dst, src, length * sizeof(Vector3)); } else { for (int i = 0; i < length; i++) { M_Vector3 *raw = (M_Vector3 *)mono_array_addr_with_size(ret, sizeof(M_Vector3), i); @@ -1431,15 +1451,16 @@ MonoArray *PackedVector3Array_to_mono_array(const PackedVector3Array &p_array) { PackedVector3Array mono_array_to_PackedVector3Array(MonoArray *p_array) { PackedVector3Array ret; - if (!p_array) + if (!p_array) { return ret; + } int length = mono_array_length(p_array); ret.resize(length); Vector3 *dst = ret.ptrw(); if constexpr (InteropLayout::MATCHES_Vector3) { - const Vector3 *src = (const Vector3 *)mono_array_addr(p_array, Vector3, 0); - memcpy(dst, src, length); + const Vector3 *src = mono_array_addr(p_array, Vector3, 0); + memcpy(dst, src, length * sizeof(Vector3)); } else { for (int i = 0; i < length; i++) { dst[i] = MARSHALLED_IN(Vector3, (M_Vector3 *)mono_array_addr_with_size(p_array, sizeof(M_Vector3), i)); @@ -1515,5 +1536,4 @@ M_SignalInfo signal_info_to_managed(const Signal &p_signal) { MonoObject *name_string_name_managed = GDMonoUtils::create_managed_from(p_signal.get_name()); return { owner_managed, name_string_name_managed }; } - } // namespace GDMonoMarshal diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index f2d887e6d6..d1d5f1f202 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -31,7 +31,7 @@ #ifndef GDMONOMARSHAL_H #define GDMONOMARSHAL_H -#include "core/variant.h" +#include "core/variant/variant.h" #include "../managed_callable.h" #include "gd_mono.h" @@ -66,40 +66,26 @@ T *unbox_addr(MonoObject *p_obj) { Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_variant = nullptr); bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_elem_type); -bool try_get_dictionary_key_value_types(const ManagedType &p_dictionary_type, ManagedType &r_key_type, ManagedType &r_value_type); // String -String mono_to_utf8_string(MonoString *p_mono_string); -String mono_to_utf16_string(MonoString *p_mono_string); - _FORCE_INLINE_ String mono_string_to_godot_not_null(MonoString *p_mono_string) { - if (sizeof(CharType) == 2) - return mono_to_utf16_string(p_mono_string); - - return mono_to_utf8_string(p_mono_string); + char32_t *utf32 = (char32_t *)mono_string_to_utf32(p_mono_string); + String ret = String(utf32); + mono_free(utf32); + return ret; } _FORCE_INLINE_ String mono_string_to_godot(MonoString *p_mono_string) { - if (p_mono_string == nullptr) + if (p_mono_string == nullptr) { return String(); + } return mono_string_to_godot_not_null(p_mono_string); } -_FORCE_INLINE_ MonoString *mono_from_utf8_string(const String &p_string) { - return mono_string_new(mono_domain_get(), p_string.utf8().get_data()); -} - -_FORCE_INLINE_ MonoString *mono_from_utf16_string(const String &p_string) { - return mono_string_from_utf16((mono_unichar2 *)p_string.c_str()); -} - _FORCE_INLINE_ MonoString *mono_string_from_godot(const String &p_string) { - if (sizeof(CharType) == 2) - return mono_from_utf16_string(p_string); - - return mono_from_utf8_string(p_string); + return mono_string_from_utf32((mono_unichar4 *)(p_string.get_data())); } // Variant @@ -285,7 +271,6 @@ static_assert(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES MATCHES_Plane && MATCHES_Vector2i && MATCHES_Rect2i && MATCHES_Vector3i); /* clang-format on */ #endif - } // namespace InteropLayout #pragma pack(push, 1) @@ -531,7 +516,6 @@ DECL_TYPE_MARSHAL_TEMPLATES(Plane) #define MARSHALLED_IN(m_type, m_from_ptr) (GDMonoMarshal::marshalled_in_##m_type(m_from_ptr)) #define MARSHALLED_OUT(m_type, m_from) (GDMonoMarshal::marshalled_out_##m_type(m_from)) - } // namespace GDMonoMarshal #endif // GDMONOMARSHAL_H diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp index e601bb12ad..04f3b25a70 100644 --- a/modules/mono/mono_gd/gd_mono_method.cpp +++ b/modules/mono/mono_gd/gd_mono_method.cpp @@ -155,11 +155,13 @@ MonoObject *GDMonoMethod::invoke_raw(MonoObject *p_object, void **p_params, Mono bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -167,11 +169,13 @@ bool GDMonoMethod::has_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoMethod::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -250,8 +254,9 @@ const MethodInfo &GDMonoMethod::get_method_info() { bool nil_is_variant = false; method_info.return_val = PropertyInfo(GDMonoMarshal::managed_to_variant_type(return_type, &nil_is_variant), ""); - if (method_info.return_val.type == Variant::NIL && nil_is_variant) + if (method_info.return_val.type == Variant::NIL && nil_is_variant) { method_info.return_val.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } Vector<StringName> names; get_parameter_names(names); @@ -259,8 +264,9 @@ const MethodInfo &GDMonoMethod::get_method_info() { for (int i = 0; i < params_count; ++i) { nil_is_variant = false; PropertyInfo arg_info = PropertyInfo(GDMonoMarshal::managed_to_variant_type(param_types[i], &nil_is_variant), names[i]); - if (arg_info.type == Variant::NIL && nil_is_variant) + if (arg_info.type == Variant::NIL && nil_is_variant) { arg_info.usage |= PROPERTY_USAGE_NIL_IS_VARIANT; + } method_info.arguments.push_back(arg_info); } diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp index c3e7598f2d..bc3be97102 100644 --- a/modules/mono/mono_gd/gd_mono_property.cpp +++ b/modules/mono/mono_gd/gd_mono_property.cpp @@ -77,15 +77,17 @@ GDMonoProperty::~GDMonoProperty() { bool GDMonoProperty::is_static() { MonoMethod *prop_method = mono_property_get_get_method(mono_property); - if (prop_method == nullptr) + if (prop_method == nullptr) { prop_method = mono_property_get_set_method(mono_property); + } return mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_STATIC; } IMonoClassMember::Visibility GDMonoProperty::get_visibility() { MonoMethod *prop_method = mono_property_get_get_method(mono_property); - if (prop_method == nullptr) + if (prop_method == nullptr) { prop_method = mono_property_get_set_method(mono_property); + } switch (mono_method_get_flags(prop_method, nullptr) & MONO_METHOD_ATTR_ACCESS_MASK) { case MONO_METHOD_ATTR_PRIVATE: @@ -106,11 +108,13 @@ IMonoClassMember::Visibility GDMonoProperty::get_visibility() { bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, false); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return false; + } return mono_custom_attrs_has_attr(attributes, p_attr_class->get_mono_ptr()); } @@ -118,11 +122,13 @@ bool GDMonoProperty::has_attribute(GDMonoClass *p_attr_class) { MonoObject *GDMonoProperty::get_attribute(GDMonoClass *p_attr_class) { ERR_FAIL_NULL_V(p_attr_class, nullptr); - if (!attrs_fetched) + if (!attrs_fetched) { fetch_attributes(); + } - if (!attributes) + if (!attributes) { return nullptr; + } return mono_custom_attrs_get_attr(attributes, p_attr_class->get_mono_ptr()); } diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 332744ae6e..97fc4c57f9 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -35,11 +35,10 @@ #include "core/debugger/engine_debugger.h" #include "core/debugger/script_debugger.h" +#include "core/object/reference.h" #include "core/os/dir_access.h" #include "core/os/mutex.h" #include "core/os/os.h" -#include "core/project_settings.h" -#include "core/reference.h" #ifdef TOOLS_ENABLED #include "editor/debugger/editor_debugger_node.h" @@ -51,13 +50,13 @@ #include "gd_mono_cache.h" #include "gd_mono_class.h" #include "gd_mono_marshal.h" -#include "gd_mono_method_thunk.h" namespace GDMonoUtils { MonoObject *unmanaged_get_managed(Object *unmanaged) { - if (!unmanaged) + if (!unmanaged) { return nullptr; + } if (unmanaged->get_script_instance()) { CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance()); @@ -90,8 +89,9 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { MonoObject *target = gchandle.get_target(); - if (target) + if (target) { return target; + } CSharpLanguage::get_singleton()->release_script_gchandle(gchandle); @@ -196,8 +196,9 @@ GDMonoClass *get_object_class(MonoObject *p_object) { GDMonoClass *type_get_proxy_class(const StringName &p_type) { String class_name = p_type; - if (class_name[0] == '_') + if (class_name[0] == '_') { class_name = class_name.substr(1, class_name.length()); + } GDMonoClass *klass = GDMono::get_singleton()->get_core_api_assembly()->get_class(BINDINGS_NAMESPACE, class_name); @@ -220,11 +221,14 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) { do { const GDMonoAssembly *assembly = klass->get_assembly(); - if (assembly == GDMono::get_singleton()->get_core_api_assembly()) + + if (assembly == GDMono::get_singleton()->get_core_api_assembly()) { return klass; + } #ifdef TOOLS_ENABLED - if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) + if (assembly == GDMono::get_singleton()->get_editor_api_assembly()) { return klass; + } #endif } while ((klass = klass->get_parent_class()) != nullptr); @@ -385,14 +389,6 @@ String get_exception_name_and_message(MonoException *p_exc) { return res; } -void set_exception_message(MonoException *p_exc, String message) { - MonoClass *klass = mono_object_get_class((MonoObject *)p_exc); - MonoProperty *prop = mono_class_get_property_from_name(klass, "Message"); - MonoString *msg = GDMonoMarshal::mono_string_from_godot(message); - void *params[1] = { msg }; - property_set_value(prop, (MonoObject *)p_exc, params, nullptr); -} - void debug_print_unhandled_exception(MonoException *p_exc) { print_unhandled_exception(p_exc); debug_send_unhandled_exception_error(p_exc); @@ -410,8 +406,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { } static thread_local bool _recursion_flag_ = false; - if (_recursion_flag_) + if (_recursion_flag_) { return; + } _recursion_flag_ = true; SCOPE_EXIT { _recursion_flag_ = false; }; @@ -441,8 +438,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { Vector<ScriptLanguage::StackInfo> _si; if (stack_trace != nullptr) { _si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace); - for (int i = _si.size() - 1; i >= 0; i--) + for (int i = _si.size() - 1; i >= 0; i--) { si.insert(0, _si[i]); + } } exc_msg += (exc_msg.length() > 0 ? " ---> " : "") + GDMonoUtils::get_exception_name_and_message(p_exc); @@ -452,8 +450,9 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { CRASH_COND(inner_exc_prop == nullptr); MonoObject *inner_exc = inner_exc_prop->get_value((MonoObject *)p_exc); - if (inner_exc != nullptr) + if (inner_exc != nullptr) { si.insert(0, separator); + } p_exc = (MonoException *)inner_exc; } @@ -660,7 +659,6 @@ GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, Mon UNHANDLED_EXCEPTION(exc); return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype))); } - } // namespace Marshal ScopeThreadAttach::ScopeThreadAttach() { @@ -680,5 +678,4 @@ StringName get_native_godot_class_name(GDMonoClass *p_class) { StringName *ptr = GDMonoMarshal::unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(native_name_obj)); return ptr ? *ptr : StringName(); } - } // namespace GDMonoUtils diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index a7ca46f012..71c131f77c 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -37,14 +37,15 @@ #include "../utils/macros.h" #include "gd_mono_header.h" -#include "core/object.h" -#include "core/reference.h" +#include "core/object/class_db.h" +#include "core/object/reference.h" #define UNHANDLED_EXCEPTION(m_exc) \ if (unlikely(m_exc != nullptr)) { \ GDMonoUtils::debug_unhandled_exception(m_exc); \ GD_UNREACHABLE(); \ - } + } else \ + ((void)0) namespace GDMonoUtils { @@ -63,7 +64,6 @@ void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoRefl GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype); GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype); - } // namespace Marshal _FORCE_INLINE_ void hash_combine(uint32_t &p_hash, const uint32_t &p_with_hash) { @@ -84,10 +84,6 @@ void detach_current_thread(MonoThread *p_mono_thread); MonoThread *get_current_thread(); bool is_thread_attached(); -_FORCE_INLINE_ bool is_main_thread() { - return mono_domain_get() != nullptr && mono_thread_get_main() == mono_thread_current(); -} - uint32_t new_strong_gchandle(MonoObject *p_object); uint32_t new_strong_gchandle_pinned(MonoObject *p_object); uint32_t new_weak_gchandle(MonoObject *p_object); @@ -115,7 +111,6 @@ String get_type_desc(MonoType *p_type); String get_type_desc(MonoReflectionType *p_reftype); String get_exception_name_and_message(MonoException *p_exc); -void set_exception_message(MonoException *p_exc, String message); void debug_print_unhandled_exception(MonoException *p_exc); void debug_send_unhandled_exception_error(MonoException *p_exc); @@ -160,27 +155,30 @@ private: }; StringName get_native_godot_class_name(GDMonoClass *p_class); - } // namespace GDMonoUtils #define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoUtils::get_native_godot_class_name(m_class)) #define GD_MONO_BEGIN_RUNTIME_INVOKE \ int &_runtime_invoke_count_ref = GDMonoUtils::get_runtime_invoke_count_ref(); \ - _runtime_invoke_count_ref += 1; + _runtime_invoke_count_ref += 1; \ + ((void)0) -#define GD_MONO_END_RUNTIME_INVOKE \ - _runtime_invoke_count_ref -= 1; +#define GD_MONO_END_RUNTIME_INVOKE \ + _runtime_invoke_count_ref -= 1; \ + ((void)0) #define GD_MONO_SCOPE_THREAD_ATTACH \ GDMonoUtils::ScopeThreadAttach __gdmono__scope__thread__attach__; \ - (void)__gdmono__scope__thread__attach__; + (void)__gdmono__scope__thread__attach__; \ + ((void)0) #ifdef DEBUG_ENABLED -#define GD_MONO_ASSERT_THREAD_ATTACHED \ - { CRASH_COND(!GDMonoUtils::is_thread_attached()); } +#define GD_MONO_ASSERT_THREAD_ATTACHED \ + CRASH_COND(!GDMonoUtils::is_thread_attached()); \ + ((void)0) #else -#define GD_MONO_ASSERT_THREAD_ATTACHED +#define GD_MONO_ASSERT_THREAD_ATTACHED ((void)0) #endif #endif // GD_MONOUTILS_H diff --git a/modules/mono/mono_gd/support/android_support.cpp b/modules/mono/mono_gd/support/android_support.cpp index 8bcdeec9dd..18daf859b5 100644 --- a/modules/mono/mono_gd/support/android_support.cpp +++ b/modules/mono/mono_gd/support/android_support.cpp @@ -44,7 +44,7 @@ #endif #include "core/os/os.h" -#include "core/ustring.h" +#include "core/string/ustring.h" #include "platform/android/java_godot_wrapper.h" #include "platform/android/os_android.h" #include "platform/android/thread_jandroid.h" @@ -387,7 +387,6 @@ void cleanup() { certStore = nullptr; } } - } // namespace support } // namespace android } // namespace gdmono diff --git a/modules/mono/mono_gd/support/android_support.h b/modules/mono/mono_gd/support/android_support.h index dc2e6c95ed..df51100bef 100755 --- a/modules/mono/mono_gd/support/android_support.h +++ b/modules/mono/mono_gd/support/android_support.h @@ -33,7 +33,7 @@ #if defined(ANDROID_ENABLED) -#include "core/ustring.h" +#include "core/string/ustring.h" namespace gdmono { namespace android { @@ -45,7 +45,6 @@ void initialize(); void cleanup(); void register_internal_calls(); - } // namespace support } // namespace android } // namespace gdmono diff --git a/modules/mono/mono_gd/support/ios_support.h b/modules/mono/mono_gd/support/ios_support.h index e28af120e3..48cef890d6 100755 --- a/modules/mono/mono_gd/support/ios_support.h +++ b/modules/mono/mono_gd/support/ios_support.h @@ -33,7 +33,7 @@ #if defined(IPHONE_ENABLED) -#include "core/ustring.h" +#include "core/string/ustring.h" namespace gdmono { namespace ios { @@ -41,7 +41,6 @@ namespace support { void initialize(); void cleanup(); - } // namespace support } // namespace ios } // namespace gdmono diff --git a/modules/mono/mono_gd/support/ios_support.mm b/modules/mono/mono_gd/support/ios_support.mm index e3d1a647fd..e6e09c4146 100644 --- a/modules/mono/mono_gd/support/ios_support.mm +++ b/modules/mono/mono_gd/support/ios_support.mm @@ -72,7 +72,6 @@ void initialize() { void cleanup() { } - } // namespace support } // namespace ios } // namespace gdmono @@ -131,8 +130,7 @@ GD_PINVOKE_EXPORT void *xamarin_timezone_get_data(const char *p_name, uint32_t * NSTimeZone *tz = nil; if (p_name) { NSString *n = [[NSString alloc] initWithUTF8String:p_name]; - tz = [[[NSTimeZone alloc] initWithName:n] autorelease]; - [n release]; + tz = [[NSTimeZone alloc] initWithName:n]; } else { tz = [NSTimeZone localTimeZone]; } |