diff options
Diffstat (limited to 'modules/mono/mono_gd/gd_mono_utils.cpp')
-rw-r--r-- | modules/mono/mono_gd/gd_mono_utils.cpp | 114 |
1 files changed, 67 insertions, 47 deletions
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp index 1b32f1126e..5987fa8ebb 100644 --- a/modules/mono/mono_gd/gd_mono_utils.cpp +++ b/modules/mono/mono_gd/gd_mono_utils.cpp @@ -125,6 +125,7 @@ void MonoCache::clear_godot_api_cache() { class_Array = NULL; class_Dictionary = NULL; class_MarshalUtils = NULL; + class_ISerializationListener = NULL; #ifdef DEBUG_ENABLED class_DebuggingUtils = NULL; @@ -242,6 +243,7 @@ void update_godot_api_cache() { CACHE_CLASS_AND_CHECK(Array, GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Array)); CACHE_CLASS_AND_CHECK(Dictionary, GODOT_API_NS_CLAS(BINDINGS_NAMESPACE_COLLECTIONS, Dictionary)); CACHE_CLASS_AND_CHECK(MarshalUtils, GODOT_API_CLASS(MarshalUtils)); + CACHE_CLASS_AND_CHECK(ISerializationListener, GODOT_API_CLASS(ISerializationListener)); #ifdef DEBUG_ENABLED CACHE_CLASS_AND_CHECK(DebuggingUtils, GODOT_API_CLASS(DebuggingUtils)); @@ -302,7 +304,7 @@ void update_godot_api_cache() { #endif // TODO Move to CSharpLanguage::init() and do handle disposal - MonoObject *task_scheduler = mono_object_new(SCRIPTS_DOMAIN, GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); + MonoObject *task_scheduler = mono_object_new(mono_domain_get(), GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr()); GDMonoUtils::runtime_object_init(task_scheduler, GODOT_API_CLASS(GodotTaskScheduler)); mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler); @@ -371,7 +373,6 @@ MonoObject *unmanaged_get_managed(Object *unmanaged) { // This way if the unmanaged world has no references to our owner // but the managed instance is alive, the refcount will be 1 instead of 0. // See: godot_icall_Reference_Dtor(MonoObject *p_obj, Object *p_ptr) - ref->reference(); } @@ -384,7 +385,7 @@ void set_main_thread(MonoThread *p_thread) { void attach_current_thread() { ERR_FAIL_COND(!GDMono::get_singleton()->is_runtime_initialized()); - MonoThread *mono_thread = mono_thread_attach(SCRIPTS_DOMAIN); + MonoThread *mono_thread = mono_thread_attach(mono_domain_get()); ERR_FAIL_NULL(mono_thread); } @@ -448,17 +449,12 @@ GDMonoClass *get_class_native_base(GDMonoClass *p_class) { } MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringName &p_native, Object *p_object) { - String object_type = p_object->get_class_name(); - - if (object_type[0] == '_') - object_type = object_type.substr(1, object_type.length()); - - if (!ClassDB::is_parent_class(object_type, p_native)) { + if (!ClassDB::is_parent_class(p_object->get_class_name(), p_native)) { ERR_EXPLAIN("Type inherits from native type '" + p_native + "', so it can't be instanced in object of type: '" + p_object->get_class() + "'"); ERR_FAIL_V(NULL); } - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, NULL); CACHED_FIELD(GodotObject, ptr)->set_value_raw(mono_object, p_object); @@ -470,7 +466,7 @@ MonoObject *create_managed_for_godot_object(GDMonoClass *p_class, const StringNa } MonoObject *create_managed_from(const NodePath &p_from) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(NodePath)); + MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(NodePath)); ERR_FAIL_NULL_V(mono_object, NULL); // Construct @@ -482,7 +478,7 @@ MonoObject *create_managed_from(const NodePath &p_from) { } MonoObject *create_managed_from(const RID &p_from) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, CACHED_CLASS_RAW(RID)); + MonoObject *mono_object = mono_object_new(mono_domain_get(), CACHED_CLASS_RAW(RID)); ERR_FAIL_NULL_V(mono_object, NULL); // Construct @@ -494,7 +490,7 @@ MonoObject *create_managed_from(const RID &p_from) { } MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, NULL); // Search constructor that takes a pointer as parameter @@ -518,13 +514,13 @@ MonoObject *create_managed_from(const Array &p_from, GDMonoClass *p_class) { MonoException *exc = NULL; GDMonoUtils::runtime_invoke(m, mono_object, args, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return mono_object; } MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) { - MonoObject *mono_object = mono_object_new(SCRIPTS_DOMAIN, p_class->get_mono_ptr()); + MonoObject *mono_object = mono_object_new(mono_domain_get(), p_class->get_mono_ptr()); ERR_FAIL_NULL_V(mono_object, NULL); // Search constructor that takes a pointer as parameter @@ -548,7 +544,7 @@ MonoObject *create_managed_from(const Dictionary &p_from, GDMonoClass *p_class) MonoException *exc = NULL; GDMonoUtils::runtime_invoke(m, mono_object, args, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return mono_object; } @@ -667,7 +663,10 @@ void print_unhandled_exception(MonoException *p_exc) { } void set_pending_exception(MonoException *p_exc) { -#ifdef HAS_PENDING_EXCEPTIONS +#ifdef NO_PENDING_EXCEPTIONS + debug_unhandled_exception(p_exc); + GD_UNREACHABLE(); +#else if (get_runtime_invoke_count() == 0) { debug_unhandled_exception(p_exc); GD_UNREACHABLE(); @@ -677,9 +676,6 @@ void set_pending_exception(MonoException *p_exc) { ERR_PRINTS("Exception thrown from managed code, but it could not be set as pending:"); GDMonoUtils::debug_print_unhandled_exception(p_exc); } -#else - debug_unhandled_exception(p_exc); - GD_UNREACHABLE(); #endif } @@ -755,113 +751,137 @@ void dispose(MonoObject *p_mono_object, MonoException **r_exc) { namespace Marshal { -MonoBoolean type_is_generic_array(MonoReflectionType *p_reftype) { +#ifdef MONO_GLUE_ENABLED +#ifdef TOOLS_ENABLED +#define NO_GLUE_RET(m_ret) \ + { \ + if (!mono_cache.godot_api_cache_updated) return m_ret; \ + } +#else +#define NO_GLUE_RET(m_ret) \ + {} +#endif +#else +#define NO_GLUE_RET(m_ret) \ + { return m_ret; } +#endif + +bool type_is_generic_array(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); TypeIsGenericArray thunk = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericArray); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean type_is_generic_dictionary(MonoReflectionType *p_reftype) { +bool type_is_generic_dictionary(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); TypeIsGenericDictionary thunk = CACHED_METHOD_THUNK(MarshalUtils, TypeIsGenericDictionary); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } void array_get_element_type(MonoReflectionType *p_array_reftype, MonoReflectionType **r_elem_reftype) { ArrayGetElementType thunk = CACHED_METHOD_THUNK(MarshalUtils, ArrayGetElementType); MonoException *exc = NULL; invoke_method_thunk(thunk, p_array_reftype, r_elem_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); } void dictionary_get_key_value_types(MonoReflectionType *p_dict_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { DictionaryGetKeyValueTypes thunk = CACHED_METHOD_THUNK(MarshalUtils, DictionaryGetKeyValueTypes); MonoException *exc = NULL; invoke_method_thunk(thunk, p_dict_reftype, r_key_reftype, r_value_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); } -MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) { +bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); GenericIEnumerableIsAssignableFromType thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) { +bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype) { + NO_GLUE_RET(false); GenericIDictionaryIsAssignableFromType thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) { +bool generic_ienumerable_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_elem_reftype) { + NO_GLUE_RET(false); GenericIEnumerableIsAssignableFromType_with_info thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIEnumerableIsAssignableFromType_with_info); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, r_elem_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } -MonoBoolean generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { +bool generic_idictionary_is_assignable_from(MonoReflectionType *p_reftype, MonoReflectionType **r_key_reftype, MonoReflectionType **r_value_reftype) { + NO_GLUE_RET(false); GenericIDictionaryIsAssignableFromType_with_info thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryIsAssignableFromType_with_info); MonoException *exc = NULL; MonoBoolean res = invoke_method_thunk(thunk, p_reftype, r_key_reftype, r_value_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); - return res; + UNHANDLED_EXCEPTION(exc); + return (bool)res; } Array enumerable_to_array(MonoObject *p_enumerable) { + NO_GLUE_RET(Array()); Array result; EnumerableToArray thunk = CACHED_METHOD_THUNK(MarshalUtils, EnumerableToArray); MonoException *exc = NULL; invoke_method_thunk(thunk, p_enumerable, &result, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return result; } Dictionary idictionary_to_dictionary(MonoObject *p_idictionary) { + NO_GLUE_RET(Dictionary()); Dictionary result; IDictionaryToDictionary thunk = CACHED_METHOD_THUNK(MarshalUtils, IDictionaryToDictionary); MonoException *exc = NULL; invoke_method_thunk(thunk, p_idictionary, &result, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return result; } Dictionary generic_idictionary_to_dictionary(MonoObject *p_generic_idictionary) { + NO_GLUE_RET(Dictionary()); Dictionary result; GenericIDictionaryToDictionary thunk = CACHED_METHOD_THUNK(MarshalUtils, GenericIDictionaryToDictionary); MonoException *exc = NULL; invoke_method_thunk(thunk, p_generic_idictionary, &result, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return result; } GDMonoClass *make_generic_array_type(MonoReflectionType *p_elem_reftype) { + NO_GLUE_RET(NULL); MakeGenericArrayType thunk = CACHED_METHOD_THUNK(MarshalUtils, MakeGenericArrayType); MonoException *exc = NULL; MonoReflectionType *reftype = invoke_method_thunk(thunk, p_elem_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype))); } GDMonoClass *make_generic_dictionary_type(MonoReflectionType *p_key_reftype, MonoReflectionType *p_value_reftype) { + NO_GLUE_RET(NULL); MakeGenericDictionaryType thunk = CACHED_METHOD_THUNK(MarshalUtils, MakeGenericDictionaryType); MonoException *exc = NULL; MonoReflectionType *reftype = invoke_method_thunk(thunk, p_key_reftype, p_value_reftype, &exc); - UNLIKELY_UNHANDLED_EXCEPTION(exc); + UNHANDLED_EXCEPTION(exc); return GDMono::get_singleton()->get_class(mono_class_from_mono_type(mono_reflection_type_get_type(reftype))); } } // namespace Marshal -// namespace Marshal - } // namespace GDMonoUtils |