diff options
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r-- | modules/mono/mono_gd/gd_mono.cpp | 62 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono.h | 4 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.cpp | 12 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_cache.h | 6 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_class.cpp | 15 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_log.cpp | 11 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.cpp | 155 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_marshal.h | 56 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_property.cpp | 30 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_property.h | 5 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.cpp | 8 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.h | 2 | ||||
-rw-r--r-- | modules/mono/mono_gd/gd_mono_wasm_m2n.h | 2 |
13 files changed, 219 insertions, 149 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp index 1b1349a3a3..52447bc59b 100644 --- a/modules/mono/mono_gd/gd_mono.cpp +++ b/modules/mono/mono_gd/gd_mono.cpp @@ -151,7 +151,7 @@ void gd_mono_debug_init() { if (da_args.length() == 0) { da_args = String("--debugger-agent=transport=dt_socket,address=127.0.0.1:" + itos(da_port) + - ",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n")) + ",embedding=1,server=y,suspend=" + (da_suspend ? "y,timeout=" + itos(da_timeout) : "n")) .utf8(); } #else @@ -504,7 +504,7 @@ void GDMono::_init_godot_api_hashes() { } void GDMono::_init_exception_policy() { - PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/unhandled_exception_policy", PROPERTY_HINT_ENUM, + PropertyInfo exc_policy_prop = PropertyInfo(Variant::INT, "mono/runtime/unhandled_exception_policy", PROPERTY_HINT_ENUM, vformat("Terminate Application:%s,Log Error:%s", (int)POLICY_TERMINATE_APP, (int)POLICY_LOG_ERROR)); unhandled_exception_policy = (UnhandledExceptionPolicy)(int)GLOBAL_DEF(exc_policy_prop.name, (int)POLICY_TERMINATE_APP); ProjectSettings::get_singleton()->set_custom_property_info(exc_policy_prop.name, exc_policy_prop); @@ -592,9 +592,9 @@ bool GDMono::load_assembly_from(const String &p_name, const String &p_path, GDMo ApiAssemblyInfo::Version ApiAssemblyInfo::Version::get_from_loaded_assembly(GDMonoAssembly *p_api_assembly, ApiAssemblyInfo::Type p_api_type) { ApiAssemblyInfo::Version api_assembly_version; - const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE ? - BINDINGS_CLASS_NATIVECALLS : - BINDINGS_CLASS_NATIVECALLS_EDITOR; + const char *nativecalls_name = p_api_type == ApiAssemblyInfo::API_CORE + ? BINDINGS_CLASS_NATIVECALLS + : BINDINGS_CLASS_NATIVECALLS_EDITOR; GDMonoClass *nativecalls_klass = p_api_assembly->get_class(BINDINGS_NAMESPACE, nativecalls_name); @@ -702,11 +702,11 @@ static bool try_get_cached_api_hash_for(const String &p_api_assemblies_dir, bool } r_out_of_sync = GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("core", "bindings_version") || - GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("core", "cs_glue_version") || - GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("editor", "bindings_version") || - GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("editor", "cs_glue_version") || - GodotSharpBindings::get_core_api_hash() != (uint64_t)cfg->get_value("core", "api_hash") || - GodotSharpBindings::get_editor_api_hash() != (uint64_t)cfg->get_value("editor", "api_hash"); + GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("core", "cs_glue_version") || + GodotSharpBindings::get_bindings_version() != (uint32_t)cfg->get_value("editor", "bindings_version") || + GodotSharpBindings::get_cs_glue_version() != (uint32_t)cfg->get_value("editor", "cs_glue_version") || + GodotSharpBindings::get_core_api_hash() != (uint64_t)cfg->get_value("core", "api_hash") || + GodotSharpBindings::get_editor_api_hash() != (uint64_t)cfg->get_value("editor", "api_hash"); return true; } @@ -754,14 +754,10 @@ bool GDMono::_temp_domain_load_are_assemblies_out_of_sync(const String &p_config } String GDMono::update_api_assemblies_from_prebuilt(const String &p_config, const bool *p_core_api_out_of_sync, const bool *p_editor_api_out_of_sync) { -#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \ - ( \ - (m_out_of_sync ? \ - String("The assembly is invalidated ") : \ - String("The assembly was not found ")) + \ - (m_prebuilt_exists ? \ - String("and the prebuilt assemblies are missing.") : \ - String("and we failed to copy the prebuilt assemblies."))) +#define FAIL_REASON(m_out_of_sync, m_prebuilt_exists) \ + ( \ + (m_out_of_sync ? String("The assembly is invalidated ") : String("The assembly was not found ")) + \ + (m_prebuilt_exists ? String("and the prebuilt assemblies are missing.") : String("and we failed to copy the prebuilt assemblies."))) String dst_assemblies_dir = GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config); @@ -819,14 +815,14 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c // 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 // If running the project manager, load it from the prebuilt API directory - String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); + String assembly_dir = !Main::is_project_manager() + ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) + : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(CORE_API_ASSEMBLY_NAME ".dll"); bool success = FileAccess::exists(assembly_path) && - load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); + load_assembly_from(CORE_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); #else bool success = load_assembly(CORE_API_ASSEMBLY_NAME, &r_loaded_api_assembly.assembly, p_refonly); #endif @@ -834,8 +830,8 @@ bool GDMono::_load_core_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, c if (success) { ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_CORE); r_loaded_api_assembly.out_of_sync = GodotSharpBindings::get_core_api_hash() != api_assembly_ver.godot_api_hash || - GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; } else { r_loaded_api_assembly.out_of_sync = false; } @@ -852,20 +848,20 @@ bool GDMono::_load_editor_api_assembly(LoadedApiAssembly &r_loaded_api_assembly, // 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 // If running the project manager, load it from the prebuilt API directory - String assembly_dir = !Main::is_project_manager() ? - GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) : - GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); + String assembly_dir = !Main::is_project_manager() + ? GodotSharpDirs::get_res_assemblies_base_dir().plus_file(p_config) + : GodotSharpDirs::get_data_editor_prebuilt_api_dir().plus_file(p_config); String assembly_path = assembly_dir.plus_file(EDITOR_API_ASSEMBLY_NAME ".dll"); bool success = FileAccess::exists(assembly_path) && - load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); + load_assembly_from(EDITOR_API_ASSEMBLY_NAME, assembly_path, &r_loaded_api_assembly.assembly, p_refonly); if (success) { ApiAssemblyInfo::Version api_assembly_ver = ApiAssemblyInfo::Version::get_from_loaded_assembly(r_loaded_api_assembly.assembly, ApiAssemblyInfo::API_EDITOR); r_loaded_api_assembly.out_of_sync = GodotSharpBindings::get_editor_api_hash() != api_assembly_ver.godot_api_hash || - GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || - GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; + GodotSharpBindings::get_bindings_version() != api_assembly_ver.bindings_version || + GodotSharpBindings::get_cs_glue_version() != api_assembly_ver.cs_glue_version; } else { r_loaded_api_assembly.out_of_sync = false; } @@ -985,7 +981,7 @@ bool GDMono::_load_tools_assemblies() { } bool success = load_assembly(TOOLS_ASM_NAME, &tools_assembly) && - load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly); + load_assembly(TOOLS_PROJECT_EDITOR_ASM_NAME, &tools_project_editor_assembly); return success; } @@ -1363,8 +1359,8 @@ int32_t GodotSharp::get_scripts_domain_id() { bool GodotSharp::is_scripts_domain_loaded() { return GDMono::get_singleton() != nullptr && - GDMono::get_singleton()->is_runtime_initialized() && - GDMono::get_singleton()->get_scripts_domain() != 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) { diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h index 4170e5053f..a18fa6c6b4 100644 --- a/modules/mono/mono_gd/gd_mono.h +++ b/modules/mono/mono_gd/gd_mono.h @@ -54,8 +54,8 @@ struct Version { bool operator==(const Version &p_other) const { return godot_api_hash == p_other.godot_api_hash && - bindings_version == p_other.bindings_version && - cs_glue_version == p_other.cs_glue_version; + bindings_version == p_other.bindings_version && + cs_glue_version == p_other.cs_glue_version; } Version() {} diff --git a/modules/mono/mono_gd/gd_mono_cache.cpp b/modules/mono/mono_gd/gd_mono_cache.cpp index 8b215a66c2..60277e0652 100644 --- a/modules/mono/mono_gd/gd_mono_cache.cpp +++ b/modules/mono/mono_gd/gd_mono_cache.cpp @@ -140,8 +140,8 @@ void CachedData::clear_godot_api_cache() { field_ExportAttribute_hintString = nullptr; class_SignalAttribute = nullptr; class_ToolAttribute = nullptr; - class_RemoteAttribute = nullptr; - class_PuppetAttribute = nullptr; + class_AnyPeerAttribute = nullptr; + class_AuthorityAttribute = nullptr; class_GodotMethodAttribute = nullptr; field_GodotMethodAttribute_methodName = nullptr; class_ScriptPathAttribute = nullptr; @@ -177,6 +177,8 @@ void CachedData::clear_godot_api_cache() { methodthunk_MarshalUtils_TypeIsGenericICollection.nullify(); methodthunk_MarshalUtils_TypeIsGenericIDictionary.nullify(); + methodthunk_MarshalUtils_GetGenericTypeDefinition.nullify(); + methodthunk_MarshalUtils_ArrayGetElementType.nullify(); methodthunk_MarshalUtils_DictionaryGetKeyValueTypes.nullify(); @@ -265,8 +267,8 @@ void update_godot_api_cache() { CACHE_FIELD_AND_CHECK(ExportAttribute, hintString, CACHED_CLASS(ExportAttribute)->get_field("hintString")); CACHE_CLASS_AND_CHECK(SignalAttribute, GODOT_API_CLASS(SignalAttribute)); CACHE_CLASS_AND_CHECK(ToolAttribute, GODOT_API_CLASS(ToolAttribute)); - CACHE_CLASS_AND_CHECK(RemoteAttribute, GODOT_API_CLASS(RemoteAttribute)); - CACHE_CLASS_AND_CHECK(PuppetAttribute, GODOT_API_CLASS(PuppetAttribute)); + CACHE_CLASS_AND_CHECK(AnyPeerAttribute, GODOT_API_CLASS(AnyPeerAttribute)); + CACHE_CLASS_AND_CHECK(AuthorityAttribute, GODOT_API_CLASS(AuthorityAttribute)); CACHE_CLASS_AND_CHECK(GodotMethodAttribute, GODOT_API_CLASS(GodotMethodAttribute)); CACHE_FIELD_AND_CHECK(GodotMethodAttribute, methodName, CACHED_CLASS(GodotMethodAttribute)->get_field("methodName")); CACHE_CLASS_AND_CHECK(ScriptPathAttribute, GODOT_API_CLASS(ScriptPathAttribute)); @@ -299,6 +301,8 @@ void update_godot_api_cache() { CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericICollection, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericICollection", 1)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, TypeIsGenericIDictionary, GODOT_API_CLASS(MarshalUtils)->get_method("TypeIsGenericIDictionary", 1)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, GetGenericTypeDefinition, GODOT_API_CLASS(MarshalUtils)->get_method("GetGenericTypeDefinition", 2)); + CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, ArrayGetElementType, GODOT_API_CLASS(MarshalUtils)->get_method("ArrayGetElementType", 2)); CACHE_METHOD_THUNK_AND_CHECK(MarshalUtils, DictionaryGetKeyValueTypes, GODOT_API_CLASS(MarshalUtils)->get_method("DictionaryGetKeyValueTypes", 3)); diff --git a/modules/mono/mono_gd/gd_mono_cache.h b/modules/mono/mono_gd/gd_mono_cache.h index fd28bbda14..5101907bd6 100644 --- a/modules/mono/mono_gd/gd_mono_cache.h +++ b/modules/mono/mono_gd/gd_mono_cache.h @@ -111,8 +111,8 @@ struct CachedData { GDMonoField *field_ExportAttribute_hintString; GDMonoClass *class_SignalAttribute; GDMonoClass *class_ToolAttribute; - GDMonoClass *class_RemoteAttribute; - GDMonoClass *class_PuppetAttribute; + GDMonoClass *class_AnyPeerAttribute; + GDMonoClass *class_AuthorityAttribute; GDMonoClass *class_GodotMethodAttribute; GDMonoField *field_GodotMethodAttribute_methodName; GDMonoClass *class_ScriptPathAttribute; @@ -148,6 +148,8 @@ struct CachedData { GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericICollection; GDMonoMethodThunkR<MonoBoolean, MonoReflectionType *> methodthunk_MarshalUtils_TypeIsGenericIDictionary; + GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_GetGenericTypeDefinition; + GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **> methodthunk_MarshalUtils_ArrayGetElementType; GDMonoMethodThunk<MonoReflectionType *, MonoReflectionType **, MonoReflectionType **> methodthunk_MarshalUtils_DictionaryGetKeyValueTypes; diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp index 27b4ac7fa7..520568071e 100644 --- a/modules/mono/mono_gd/gd_mono_class.cpp +++ b/modules/mono/mono_gd/gd_mono_class.cpp @@ -187,7 +187,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base #ifdef DEBUG_ENABLED String fullname = method->get_ret_type_full_name() + " " + name + "(" + method->get_signature_desc(true) + ")"; WARN_PRINT("Method '" + fullname + "' is hidden by Godot API method. Should be '" + - method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'."); + method->get_full_name_no_class() + "'. In class '" + namespace_name + "." + class_name + "'."); #endif continue; } @@ -205,7 +205,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base // found String fullname = m->get_ret_type_full_name() + " " + name + "(" + m->get_signature_desc(true) + ")"; WARN_PRINT("Method '" + fullname + "' should be '" + m->get_full_name_no_class() + - "'. In class '" + namespace_name + "." + class_name + "'."); + "'. In class '" + namespace_name + "." + class_name + "'."); break; } @@ -464,9 +464,18 @@ const Vector<GDMonoClass *> &GDMonoClass::get_all_delegates() { return delegates_list; } + // If the class is generic we must use the generic type definition. + MonoClass *klass = mono_class; + if (mono_type_get_type(get_mono_type()) == MONO_TYPE_GENERICINST) { + MonoReflectionType *reftype = mono_type_get_object(mono_domain_get(), get_mono_type()); + GDMonoUtils::Marshal::get_generic_type_definition(reftype, &reftype); + MonoType *type = mono_reflection_type_get_type(reftype); + klass = mono_class_from_mono_type(type); + } + void *iter = nullptr; MonoClass *raw_class = nullptr; - while ((raw_class = mono_class_get_nested_types(mono_class, &iter)) != nullptr) { + while ((raw_class = mono_class_get_nested_types(klass, &iter)) != nullptr) { if (mono_class_is_delegate(raw_class)) { StringName name = String::utf8(mono_class_get_name(raw_class)); diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp index 179bbfb40c..bcdcd6623b 100644 --- a/modules/mono/mono_gd/gd_mono_log.cpp +++ b/modules/mono/mono_gd/gd_mono_log.cpp @@ -121,12 +121,10 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) { ERR_FAIL_COND(da->list_dir_begin() != OK); - String current; - while ((current = da->get_next()).length()) { - if (da->current_is_dir()) { - continue; - } - if (!current.ends_with(".txt")) { + String current = da->get_next(); + while (!current.is_empty()) { + if (da->current_is_dir() || !current.ends_with(".txt")) { + current = da->get_next(); continue; } @@ -135,6 +133,7 @@ void GDMonoLog::_delete_old_log_files(const String &p_logs_dir) { if (OS::get_singleton()->get_unix_time() - modified_time > MAX_SECS) { da->remove(current); } + current = da->get_next(); } da->list_dir_end(); diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp index c9789bf270..6b395303dd 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.cpp +++ b/modules/mono/mono_gd/gd_mono_marshal.cpp @@ -139,49 +139,65 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { - MonoArrayType *array_type = mono_type_get_array_type(p_type.type_class->get_mono_type()); + MonoClass *elem_class = mono_class_get_element_class(p_type.type_class->get_mono_ptr()); - if (array_type->eklass == CACHED_CLASS_RAW(MonoObject)) { + if (elem_class == CACHED_CLASS_RAW(MonoObject)) { return Variant::ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(uint8_t)) { + if (elem_class == CACHED_CLASS_RAW(uint8_t)) { return Variant::PACKED_BYTE_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(int32_t)) { + if (elem_class == CACHED_CLASS_RAW(int32_t)) { return Variant::PACKED_INT32_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(int64_t)) { + if (elem_class == CACHED_CLASS_RAW(int64_t)) { return Variant::PACKED_INT64_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(float)) { + if (elem_class == CACHED_CLASS_RAW(float)) { return Variant::PACKED_FLOAT32_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(double)) { + if (elem_class == CACHED_CLASS_RAW(double)) { return Variant::PACKED_FLOAT64_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(String)) { + if (elem_class == CACHED_CLASS_RAW(String)) { return Variant::PACKED_STRING_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(Vector2)) { + if (elem_class == CACHED_CLASS_RAW(Vector2)) { return Variant::PACKED_VECTOR2_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(Vector3)) { + if (elem_class == CACHED_CLASS_RAW(Vector3)) { return Variant::PACKED_VECTOR3_ARRAY; } - if (array_type->eklass == CACHED_CLASS_RAW(Color)) { + if (elem_class == CACHED_CLASS_RAW(Color)) { return Variant::PACKED_COLOR_ARRAY; } - GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); + if (elem_class == CACHED_CLASS_RAW(StringName)) { + return Variant::ARRAY; + } + + if (elem_class == CACHED_CLASS_RAW(NodePath)) { + return Variant::ARRAY; + } + + if (elem_class == CACHED_CLASS_RAW(RID)) { + return Variant::ARRAY; + } + + if (mono_class_is_enum(elem_class)) { + return Variant::ARRAY; + } + + GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(elem_class); if (CACHED_CLASS(GodotObject)->is_assignable_from(array_type_class)) { return Variant::ARRAY; } @@ -266,6 +282,12 @@ Variant::Type managed_to_variant_type(const ManagedType &p_type, bool *r_nil_is_ if (GDMonoUtils::Marshal::type_is_generic_icollection(reftype) || GDMonoUtils::Marshal::type_is_generic_ienumerable(reftype)) { return Variant::ARRAY; } + + // GodotObject + GDMonoClass *type_class = p_type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + return Variant::OBJECT; + } } break; default: { @@ -284,9 +306,8 @@ bool try_get_array_element_type(const ManagedType &p_array_type, ManagedType &r_ switch (p_array_type.type_encoding) { case MONO_TYPE_ARRAY: case MONO_TYPE_SZARRAY: { - MonoArrayType *array_type = mono_type_get_array_type(p_array_type.type_class->get_mono_type()); - GDMonoClass *array_type_class = GDMono::get_singleton()->get_class(array_type->eklass); - r_elem_type = ManagedType::from_class(array_type_class); + MonoClass *elem_class = mono_class_get_element_class(p_array_type.type_class->get_mono_ptr()); + r_elem_type = ManagedType::from_class(elem_class); return true; } break; case MONO_TYPE_GENERICINST: { @@ -361,12 +382,23 @@ MonoArray *variant_to_mono_array(const Variant &p_var, GDMonoClass *p_type_class return PackedColorArray_to_mono_array(p_var.operator PackedColorArray()); } + if (array_type->eklass == CACHED_CLASS_RAW(StringName)) { + return Array_to_mono_array(p_var.operator Array()); + } + + if (array_type->eklass == CACHED_CLASS_RAW(NodePath)) { + return Array_to_mono_array(p_var.operator Array()); + } + + if (array_type->eklass == CACHED_CLASS_RAW(RID)) { + return Array_to_mono_array(p_var.operator Array()); + } + if (mono_class_is_assignable_from(CACHED_CLASS(GodotObject)->get_mono_ptr(), array_type->eklass)) { return Array_to_mono_array(p_var.operator ::Array(), array_type->eklass); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to array of unsupported element type:" + - GDMonoClass::get_full_name(array_type->eklass) + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to array of unsupported element type:" + GDMonoClass::get_full_name(array_type->eklass) + "'."); } MonoObject *variant_to_mono_object_of_class(const Variant &p_var, GDMonoClass *p_type_class) { @@ -399,8 +431,7 @@ MonoObject *variant_to_mono_object_of_class(const Variant &p_var, GDMonoClass *p return GDMonoUtils::create_managed_from(p_var.operator Array(), CACHED_CLASS(Array)); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type: '" + - p_type_class->get_full_name() + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type: '" + p_type_class->get_full_name() + "'."); } MonoObject *variant_to_mono_object_of_genericinst(const Variant &p_var, GDMonoClass *p_type_class) { @@ -450,8 +481,12 @@ MonoObject *variant_to_mono_object_of_genericinst(const Variant &p_var, GDMonoCl return GDMonoUtils::create_managed_from(p_var.operator Array(), godot_array_class); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported generic type: '" + - p_type_class->get_full_name() + "'."); + // GodotObject + if (CACHED_CLASS(GodotObject)->is_assignable_from(p_type_class)) { + return GDMonoUtils::unmanaged_get_managed(p_var.operator Object *()); + } + + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported generic type: '" + p_type_class->get_full_name() + "'."); } MonoObject *variant_to_mono_object(const Variant &p_var) { @@ -786,14 +821,12 @@ void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type RETURN_TYPE_VAL(uint64_t, val); } default: { - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + - GDMonoClass::get_full_name(mono_class_from_mono_type(enum_basetype)) + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + GDMonoClass::get_full_name(mono_class_from_mono_type(enum_basetype)) + "'."); } } } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + - p_type.type_class->get_full_name() + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + p_type.type_class->get_full_name() + "'."); } break; #undef RETURN_TYPE_VAL case MONO_TYPE_STRING: @@ -809,8 +842,7 @@ void *variant_to_managed_unboxed(const Variant &p_var, const ManagedType &p_type return variant_to_mono_object(p_var); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + - itos(p_type.type_encoding) + "."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + itos(p_type.type_encoding) + "."); } MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_type) { @@ -943,14 +975,12 @@ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_ty return BOX_ENUM(enum_baseclass, val); } default: { - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + - GDMonoClass::get_full_name(enum_baseclass) + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to enum value of unsupported base type: '" + GDMonoClass::get_full_name(enum_baseclass) + "'."); } } } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + - p_type.type_class->get_full_name() + "'."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported value type: '" + p_type.type_class->get_full_name() + "'."); } break; case MONO_TYPE_STRING: return (MonoObject *)variant_to_mono_string(p_var); @@ -965,8 +995,7 @@ MonoObject *variant_to_mono_object(const Variant &p_var, const ManagedType &p_ty return variant_to_mono_object(p_var); } - ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + - itos(p_type.type_encoding) + "."); + ERR_FAIL_V_MSG(nullptr, "Attempted to convert Variant to unsupported type with encoding: " + itos(p_type.type_encoding) + "."); } Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type, bool p_fail_with_err = true) { @@ -1118,6 +1147,18 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type return mono_array_to_PackedColorArray((MonoArray *)p_obj); } + if (array_type->eklass == CACHED_CLASS_RAW(StringName)) { + return mono_array_to_Array((MonoArray *)p_obj); + } + + if (array_type->eklass == CACHED_CLASS_RAW(NodePath)) { + return mono_array_to_Array((MonoArray *)p_obj); + } + + if (array_type->eklass == CACHED_CLASS_RAW(RID)) { + return mono_array_to_Array((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)) { return mono_array_to_Array((MonoArray *)p_obj); @@ -1206,12 +1247,22 @@ Variant mono_object_to_variant_impl(MonoObject *p_obj, const ManagedType &p_type GDMonoUtils::Marshal::array_get_element_type(reftype, &elem_reftype); return system_generic_list_to_Array_variant(p_obj, p_type.type_class, elem_reftype); } + + // GodotObject + GDMonoClass *type_class = p_type.type_class; + if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) { + Object *ptr = unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_obj)); + if (ptr != nullptr) { + RefCounted *rc = Object::cast_to<RefCounted>(ptr); + return rc ? Variant(Ref<RefCounted>(rc)) : Variant(ptr); + } + return Variant(); + } } break; } if (p_fail_with_err) { - ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" + - p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + "."); + ERR_FAIL_V_MSG(Variant(), "Attempted to convert an unmarshallable managed type to Variant. Name: '" + p_type.type_class->get_name() + "' Encoding: " + itos(p_type.type_encoding) + "."); } else { return Variant(); } @@ -1271,7 +1322,7 @@ String mono_object_to_variant_string(MonoObject *p_obj, MonoException **r_exc) { MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + - ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); CRASH_COND(ctor == nullptr); @@ -1293,7 +1344,7 @@ MonoObject *Dictionary_to_system_generic_dict(const Dictionary &p_dict, GDMonoCl Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] GDMonoClass *p_class, MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { GDMonoClass *godot_dict_class = GDMonoUtils::Marshal::make_generic_dictionary_type(p_key_reftype, p_value_reftype); String ctor_desc = ":.ctor(System.Collections.Generic.IDictionary`2<" + GDMonoUtils::get_type_desc(p_key_reftype) + - ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; + ", " + GDMonoUtils::get_type_desc(p_value_reftype) + ">)"; GDMonoMethod *godot_dict_ctor = godot_dict_class->get_method_with_desc(ctor_desc, true); CRASH_COND(godot_dict_ctor == nullptr); @@ -1315,7 +1366,6 @@ Dictionary system_generic_dict_to_Dictionary(MonoObject *p_obj, [[maybe_unused]] MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_class, MonoReflectionType *p_elem_reftype) { MonoType *elem_type = mono_reflection_type_get_type(p_elem_reftype); - MonoClass *elem_class = mono_class_from_mono_type(elem_type); String ctor_desc = ":.ctor(System.Collections.Generic.IEnumerable`1<" + GDMonoUtils::get_type_desc(elem_type) + ">)"; GDMonoMethod *ctor = p_class->get_method_with_desc(ctor_desc, true); @@ -1324,7 +1374,10 @@ MonoObject *Array_to_system_generic_list(const Array &p_array, GDMonoClass *p_cl MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, nullptr); - void *ctor_args[1] = { Array_to_mono_array(p_array, elem_class) }; + GDMonoClass *godot_array_class = GDMonoUtils::Marshal::make_generic_array_type(p_elem_reftype); + MonoObject *godot_array = GDMonoUtils::create_managed_from(p_array, godot_array_class); + + void *ctor_args[1] = { godot_array }; MonoException *exc = nullptr; ctor->invoke_raw(mono_object, ctor_args, &exc); @@ -1683,12 +1736,12 @@ Callable managed_to_callable(const M_Callable &p_managed_callable) { CallableCustom *managed_callable = memnew(ManagedCallable(p_managed_callable.delegate)); return Callable(managed_callable); } else { - Object *target = p_managed_callable.target ? - unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) : - nullptr; - StringName *method_ptr = p_managed_callable.method_string_name ? - unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)) : - nullptr; + Object *target = p_managed_callable.target + ? unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_callable.target)) + : nullptr; + StringName *method_ptr = p_managed_callable.method_string_name + ? unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_callable.method_string_name)) + : nullptr; StringName method = method_ptr ? *method_ptr : StringName(); return Callable(target, method); } @@ -1731,12 +1784,12 @@ M_Callable callable_to_managed(const Callable &p_callable) { } Signal managed_to_signal_info(const M_SignalInfo &p_managed_signal) { - Object *owner = p_managed_signal.owner ? - unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) : - nullptr; - StringName *name_ptr = p_managed_signal.name_string_name ? - unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)) : - nullptr; + Object *owner = p_managed_signal.owner + ? unbox<Object *>(CACHED_FIELD(GodotObject, ptr)->get_value(p_managed_signal.owner)) + : nullptr; + StringName *name_ptr = p_managed_signal.name_string_name + ? unbox<StringName *>(CACHED_FIELD(StringName, ptr)->get_value(p_managed_signal.name_string_name)) + : nullptr; StringName name = name_ptr ? *name_ptr : StringName(); return Signal(owner, name); } diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h index 88afc7ebc5..2f4b619b61 100644 --- a/modules/mono/mono_gd/gd_mono_marshal.h +++ b/modules/mono/mono_gd/gd_mono_marshal.h @@ -234,58 +234,58 @@ enum { #endif MATCHES_Vector2 = (MATCHES_real_t && (sizeof(Vector2) == (sizeof(real_t) * 2)) && - offsetof(Vector2, x) == (sizeof(real_t) * 0) && - offsetof(Vector2, y) == (sizeof(real_t) * 1)), + offsetof(Vector2, x) == (sizeof(real_t) * 0) && + offsetof(Vector2, y) == (sizeof(real_t) * 1)), MATCHES_Vector2i = (MATCHES_int && (sizeof(Vector2i) == (sizeof(int32_t) * 2)) && - offsetof(Vector2i, x) == (sizeof(int32_t) * 0) && - offsetof(Vector2i, y) == (sizeof(int32_t) * 1)), + offsetof(Vector2i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector2i, y) == (sizeof(int32_t) * 1)), MATCHES_Rect2 = (MATCHES_Vector2 && (sizeof(Rect2) == (sizeof(Vector2) * 2)) && - offsetof(Rect2, position) == (sizeof(Vector2) * 0) && - offsetof(Rect2, size) == (sizeof(Vector2) * 1)), + offsetof(Rect2, position) == (sizeof(Vector2) * 0) && + offsetof(Rect2, size) == (sizeof(Vector2) * 1)), MATCHES_Rect2i = (MATCHES_Vector2i && (sizeof(Rect2i) == (sizeof(Vector2i) * 2)) && - offsetof(Rect2i, position) == (sizeof(Vector2i) * 0) && - offsetof(Rect2i, size) == (sizeof(Vector2i) * 1)), + offsetof(Rect2i, position) == (sizeof(Vector2i) * 0) && + offsetof(Rect2i, size) == (sizeof(Vector2i) * 1)), MATCHES_Transform2D = (MATCHES_Vector2 && (sizeof(Transform2D) == (sizeof(Vector2) * 3))), // No field offset required, it stores an array MATCHES_Vector3 = (MATCHES_real_t && (sizeof(Vector3) == (sizeof(real_t) * 3)) && - offsetof(Vector3, x) == (sizeof(real_t) * 0) && - offsetof(Vector3, y) == (sizeof(real_t) * 1) && - offsetof(Vector3, z) == (sizeof(real_t) * 2)), + offsetof(Vector3, x) == (sizeof(real_t) * 0) && + offsetof(Vector3, y) == (sizeof(real_t) * 1) && + offsetof(Vector3, z) == (sizeof(real_t) * 2)), MATCHES_Vector3i = (MATCHES_int && (sizeof(Vector3i) == (sizeof(int32_t) * 3)) && - offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && - offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && - offsetof(Vector3i, z) == (sizeof(int32_t) * 2)), + offsetof(Vector3i, x) == (sizeof(int32_t) * 0) && + offsetof(Vector3i, y) == (sizeof(int32_t) * 1) && + offsetof(Vector3i, z) == (sizeof(int32_t) * 2)), MATCHES_Basis = (MATCHES_Vector3 && (sizeof(Basis) == (sizeof(Vector3) * 3))), // No field offset required, it stores an array MATCHES_Quaternion = (MATCHES_real_t && (sizeof(Quaternion) == (sizeof(real_t) * 4)) && - offsetof(Quaternion, x) == (sizeof(real_t) * 0) && - offsetof(Quaternion, y) == (sizeof(real_t) * 1) && - offsetof(Quaternion, z) == (sizeof(real_t) * 2) && - offsetof(Quaternion, w) == (sizeof(real_t) * 3)), + offsetof(Quaternion, x) == (sizeof(real_t) * 0) && + offsetof(Quaternion, y) == (sizeof(real_t) * 1) && + offsetof(Quaternion, z) == (sizeof(real_t) * 2) && + offsetof(Quaternion, w) == (sizeof(real_t) * 3)), MATCHES_Transform3D = (MATCHES_Basis && MATCHES_Vector3 && (sizeof(Transform3D) == (sizeof(Basis) + sizeof(Vector3))) && - offsetof(Transform3D, basis) == 0 && - offsetof(Transform3D, origin) == sizeof(Basis)), + offsetof(Transform3D, basis) == 0 && + offsetof(Transform3D, origin) == sizeof(Basis)), MATCHES_AABB = (MATCHES_Vector3 && (sizeof(AABB) == (sizeof(Vector3) * 2)) && - offsetof(AABB, position) == (sizeof(Vector3) * 0) && - offsetof(AABB, size) == (sizeof(Vector3) * 1)), + offsetof(AABB, position) == (sizeof(Vector3) * 0) && + offsetof(AABB, size) == (sizeof(Vector3) * 1)), MATCHES_Color = (MATCHES_float && (sizeof(Color) == (sizeof(float) * 4)) && - offsetof(Color, r) == (sizeof(float) * 0) && - offsetof(Color, g) == (sizeof(float) * 1) && - offsetof(Color, b) == (sizeof(float) * 2) && - offsetof(Color, a) == (sizeof(float) * 3)), + offsetof(Color, r) == (sizeof(float) * 0) && + offsetof(Color, g) == (sizeof(float) * 1) && + offsetof(Color, b) == (sizeof(float) * 2) && + offsetof(Color, a) == (sizeof(float) * 3)), MATCHES_Plane = (MATCHES_Vector3 && MATCHES_real_t && (sizeof(Plane) == (sizeof(Vector3) + sizeof(real_t))) && - offsetof(Plane, normal) == 0 && - offsetof(Plane, d) == sizeof(Vector3)) + offsetof(Plane, normal) == 0 && + offsetof(Plane, d) == sizeof(Vector3)) }; // In the future we may force this if we want to ref return these structs diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp index 5391b7775e..5c7cf29e88 100644 --- a/modules/mono/mono_gd/gd_mono_property.cpp +++ b/modules/mono/mono_gd/gd_mono_property.cpp @@ -65,6 +65,8 @@ GDMonoProperty::GDMonoProperty(MonoProperty *p_mono_property, GDMonoClass *p_own type.type_class = GDMono::get_singleton()->get_class(param_type_class); } + param_buffer_size = GDMonoMarshal::variant_get_managed_unboxed_size(type); + attrs_fetched = false; attributes = nullptr; } @@ -147,24 +149,20 @@ bool GDMonoProperty::has_setter() { return mono_property_get_set_method(mono_property) != nullptr; } -void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc) { - MonoMethod *prop_method = mono_property_get_set_method(mono_property); - void *params[1] = { p_value }; - MonoException *exc = nullptr; - GDMonoUtils::runtime_invoke(prop_method, p_object, params, &exc); - if (exc) { - if (r_exc) { - *r_exc = exc; - } else { - GDMonoUtils::set_pending_exception(exc); - } - } -} +void GDMonoProperty::set_value_from_variant(MonoObject *p_object, const Variant &p_value, MonoException **r_exc) { + uint8_t *buffer = (uint8_t *)alloca(param_buffer_size); + unsigned int offset = 0; -void GDMonoProperty::set_value(MonoObject *p_object, void **p_params, MonoException **r_exc) { - MonoException *exc = nullptr; - GDMonoUtils::property_set_value(mono_property, p_object, p_params, &exc); + void *params[1] = { + GDMonoMarshal::variant_to_managed_unboxed(p_value, type, buffer, offset) + }; + +#ifdef DEBUG_ENABLED + CRASH_COND(offset != param_buffer_size); +#endif + MonoException *exc = nullptr; + GDMonoUtils::property_set_value(mono_property, p_object, params, &exc); if (exc) { if (r_exc) { *r_exc = exc; diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h index af7a2c02e5..9bb1caa759 100644 --- a/modules/mono/mono_gd/gd_mono_property.h +++ b/modules/mono/mono_gd/gd_mono_property.h @@ -45,6 +45,8 @@ class GDMonoProperty : public IMonoClassMember { bool attrs_fetched; MonoCustomAttrInfo *attributes; + unsigned int param_buffer_size; + public: virtual GDMonoClass *get_enclosing_class() const final { return owner; } @@ -64,8 +66,7 @@ public: _FORCE_INLINE_ ManagedType get_type() const { return type; } - void set_value(MonoObject *p_object, MonoObject *p_value, MonoException **r_exc = nullptr); - void set_value(MonoObject *p_object, void **p_params, MonoException **r_exc = nullptr); + void set_value_from_variant(MonoObject *p_object, const Variant &p_value, MonoException **r_exc = nullptr); MonoObject *get_value(MonoObject *p_object, MonoException **r_exc = nullptr); bool get_bool_value(MonoObject *p_object); diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 13939bd014..505c637af9 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -450,7 +450,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) { int line = si.size() ? si[0].line : __LINE__; String error_msg = "Unhandled exception"; - EngineDebugger::get_script_debugger()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si); + EngineDebugger::get_script_debugger()->send_error(func, file, line, error_msg, exc_msg, true, ERR_HANDLER_ERROR, si); #endif } @@ -614,6 +614,12 @@ bool type_is_generic_idictionary(MonoReflectionType *p_reftype) { return (bool)res; } +void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype) { + MonoException *exc = nullptr; + CACHED_METHOD_THUNK(MarshalUtils, GetGenericTypeDefinition).invoke(p_reftype, r_generic_reftype, &exc); + UNHANDLED_EXCEPTION(exc); +} + void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { MonoException *exc = nullptr; CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType).invoke(p_array_reftype, r_elem_reftype, &exc); diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h index 773501e93d..3162ef198d 100644 --- a/modules/mono/mono_gd/gd_mono_utils.h +++ b/modules/mono/mono_gd/gd_mono_utils.h @@ -62,6 +62,8 @@ bool type_is_generic_ienumerable(MonoReflectionType *p_reftype); bool type_is_generic_icollection(MonoReflectionType *p_reftype); bool type_is_generic_idictionary(MonoReflectionType *p_reftype); +void get_generic_type_definition(MonoReflectionType *p_reftype, MonoReflectionType **r_generic_reftype); + void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype); void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype); diff --git a/modules/mono/mono_gd/gd_mono_wasm_m2n.h b/modules/mono/mono_gd/gd_mono_wasm_m2n.h index 366662ff81..c49a62a632 100644 --- a/modules/mono/mono_gd/gd_mono_wasm_m2n.h +++ b/modules/mono/mono_gd/gd_mono_wasm_m2n.h @@ -158,7 +158,7 @@ T m2n_arg_cast(Mono_InterpMethodArguments *p_margs, size_t p_idx) { return (T)(size_t)p_margs->iargs[p_idx]; } else if constexpr (cookie == 'L') { static_assert(std::is_same_v<T, int64_t> || std::is_same_v<T, uint64_t> || - (sizeof(void *) == 8 && std::is_pointer_v<T>), + (sizeof(void *) == 8 && std::is_pointer_v<T>), "Invalid type for cookie 'L'."); union { |