summaryrefslogtreecommitdiff
path: root/modules/mono/mono_gd
diff options
context:
space:
mode:
Diffstat (limited to 'modules/mono/mono_gd')
-rw-r--r--modules/mono/mono_gd/gd_mono.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.cpp31
-rw-r--r--modules/mono/mono_gd/gd_mono_assembly.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_class.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_class.h8
-rw-r--r--modules/mono/mono_gd/gd_mono_field.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.cpp16
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h1
-rw-r--r--modules/mono/mono_gd/gd_mono_property.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp99
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h34
11 files changed, 176 insertions, 47 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index d4df7e0cb2..f5febd415b 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -226,7 +226,7 @@ void GDMono::initialize() {
mono_install_unhandled_exception_hook(gdmono_unhandled_exception_hook, NULL);
- OS::get_singleton()->print("Mono: ALL IS GOOD\n");
+ OS::get_singleton()->print("Mono: INITIALIZED\n");
}
#ifndef MONO_GLUE_DISABLED
@@ -696,11 +696,13 @@ bool _GodotSharp::is_domain_loaded() {
return GDMono::get_singleton()->get_scripts_domain() != NULL;
}
-#define ENQUEUE_FOR_DISPOSAL(m_queue, m_inst) \
- m_queue.push_back(m_inst); \
- if (queue_empty) { \
- queue_empty = false; \
- call_deferred("_dispose_callback"); \
+#define ENQUEUE_FOR_DISPOSAL(m_queue, m_inst) \
+ m_queue.push_back(m_inst); \
+ if (queue_empty) { \
+ queue_empty = false; \
+ if (!is_finalizing_domain()) { /* call_deferred may not be safe here */ \
+ call_deferred("_dispose_callback"); \
+ } \
}
void _GodotSharp::queue_dispose(MonoObject *p_mono_object, Object *p_object) {
diff --git a/modules/mono/mono_gd/gd_mono_assembly.cpp b/modules/mono/mono_gd/gd_mono_assembly.cpp
index ba56ed6ed5..ef39b8549d 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.cpp
+++ b/modules/mono/mono_gd/gd_mono_assembly.cpp
@@ -116,6 +116,37 @@ MonoAssembly *GDMonoAssembly::_preload_hook(MonoAssemblyName *aname, char **asse
}
}
+ String name = mono_assembly_name_get_name(aname);
+ bool has_extension = name.ends_with(".dll");
+
+ if (has_extension ? name == "mscorlib.dll" : name == "mscorlib") {
+ GDMonoAssembly **stored_assembly = GDMono::get_singleton()->get_loaded_assembly(has_extension ? name.get_basename() : name);
+ if (stored_assembly) return (*stored_assembly)->get_assembly();
+
+ String path;
+ MonoAssembly *res = NULL;
+
+ for (int i = 0; i < search_dirs.size(); i++) {
+ const String &search_dir = search_dirs[i];
+
+ if (has_extension) {
+ path = search_dir.plus_file(name);
+ if (FileAccess::exists(path)) {
+ res = _load_assembly_from(name.get_basename(), path);
+ break;
+ }
+ } else {
+ path = search_dir.plus_file(name + ".dll");
+ if (FileAccess::exists(path)) {
+ res = _load_assembly_from(name, path);
+ break;
+ }
+ }
+ }
+
+ if (res) return res;
+ }
+
return NULL;
}
diff --git a/modules/mono/mono_gd/gd_mono_assembly.h b/modules/mono/mono_gd/gd_mono_assembly.h
index 8e7aa701bf..8a5fa19626 100644
--- a/modules/mono/mono_gd/gd_mono_assembly.h
+++ b/modules/mono/mono_gd/gd_mono_assembly.h
@@ -110,7 +110,7 @@ public:
_FORCE_INLINE_ String get_path() const { return path; }
_FORCE_INLINE_ uint64_t get_modified_time() const { return modified_time; }
- GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_class);
+ GDMonoClass *get_class(const StringName &p_namespace, const StringName &p_name);
GDMonoClass *get_class(MonoClass *p_mono_class);
GDMonoClass *get_object_derived_class(const StringName &p_class);
diff --git a/modules/mono/mono_gd/gd_mono_class.cpp b/modules/mono/mono_gd/gd_mono_class.cpp
index d3315568cb..b826352f02 100644
--- a/modules/mono/mono_gd/gd_mono_class.cpp
+++ b/modules/mono/mono_gd/gd_mono_class.cpp
@@ -89,11 +89,6 @@ Vector<MonoClassField *> GDMonoClass::get_enum_fields() {
}
#endif
-bool GDMonoClass::has_method(const StringName &p_name) {
-
- return get_method(p_name) != NULL;
-}
-
bool GDMonoClass::has_attribute(GDMonoClass *p_attr_class) {
#ifdef DEBUG_ENABLED
@@ -225,7 +220,7 @@ void GDMonoClass::fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base
methods_fetched = true;
}
-GDMonoMethod *GDMonoClass::get_method(const StringName &p_name) {
+GDMonoMethod *GDMonoClass::get_fetched_method_unknown_params(const StringName &p_name) {
ERR_FAIL_COND_V(!methods_fetched, NULL);
@@ -239,6 +234,11 @@ GDMonoMethod *GDMonoClass::get_method(const StringName &p_name) {
return NULL;
}
+bool GDMonoClass::has_fetched_method_unknown_params(const StringName &p_name) {
+
+ return get_fetched_method_unknown_params(p_name) != NULL;
+}
+
GDMonoMethod *GDMonoClass::get_method(const StringName &p_name, int p_params_count) {
MethodKey key = MethodKey(p_name, p_params_count);
@@ -303,6 +303,8 @@ 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);
+ ERR_FAIL_COND_V(mono_method_get_class(method) != mono_class, NULL);
+
return get_method(method);
}
diff --git a/modules/mono/mono_gd/gd_mono_class.h b/modules/mono/mono_gd/gd_mono_class.h
index b6052ac0ed..afccf2fc63 100644
--- a/modules/mono/mono_gd/gd_mono_class.h
+++ b/modules/mono/mono_gd/gd_mono_class.h
@@ -112,7 +112,8 @@ public:
Vector<MonoClassField *> get_enum_fields();
#endif
- bool has_method(const StringName &p_name);
+ GDMonoMethod *get_fetched_method_unknown_params(const StringName &p_name);
+ bool has_fetched_method_unknown_params(const StringName &p_name);
bool has_attribute(GDMonoClass *p_attr_class);
MonoObject *get_attribute(GDMonoClass *p_attr_class);
@@ -120,12 +121,11 @@ public:
void fetch_attributes();
void fetch_methods_with_godot_api_checks(GDMonoClass *p_native_base);
- GDMonoMethod *get_method(const StringName &p_name);
- GDMonoMethod *get_method(const StringName &p_name, int p_params_count);
+ GDMonoMethod *get_method(const StringName &p_name, int p_params_count = 0);
GDMonoMethod *get_method(MonoMethod *p_raw_method);
GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name);
GDMonoMethod *get_method(MonoMethod *p_raw_method, const StringName &p_name, int p_params_count);
- GDMonoMethod *get_method_with_desc(const String &p_description, bool p_includes_namespace);
+ GDMonoMethod *get_method_with_desc(const String &p_description, bool p_include_namespace);
GDMonoField *get_field(const StringName &p_name);
const Vector<GDMonoField *> &get_all_fields();
diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h
index bf73975bfe..a6b368c4d6 100644
--- a/modules/mono/mono_gd/gd_mono_field.h
+++ b/modules/mono/mono_gd/gd_mono_field.h
@@ -63,7 +63,7 @@ public:
void set_value_raw(MonoObject *p_object, void *p_ptr);
void set_value_from_variant(MonoObject *p_object, const Variant &p_value);
- _FORCE_INLINE_ MonoObject *get_value(MonoObject *p_object);
+ MonoObject *get_value(MonoObject *p_object);
bool get_bool_value(MonoObject *p_object);
int get_int_value(MonoObject *p_object);
diff --git a/modules/mono/mono_gd/gd_mono_marshal.cpp b/modules/mono/mono_gd/gd_mono_marshal.cpp
index 1ec8f41c91..aa1a8e39c7 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.cpp
+++ b/modules/mono/mono_gd/gd_mono_marshal.cpp
@@ -459,11 +459,7 @@ Variant mono_object_to_variant(MonoObject *p_obj) {
type.type_encoding = mono_type_get_type(raw_type);
type.type_class = tclass;
- return mono_object_to_variant(p_obj, type);
-}
-
-Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
- switch (p_type.type_encoding) {
+ switch (type.type_encoding) {
case MONO_TYPE_BOOLEAN:
return (bool)unbox<MonoBoolean>(p_obj);
@@ -497,7 +493,7 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
} break;
case MONO_TYPE_VALUETYPE: {
- GDMonoClass *tclass = p_type.type_class;
+ GDMonoClass *tclass = type.type_class;
if (tclass == CACHED_CLASS(Vector2))
RETURN_UNBOXED_STRUCT(Vector2, p_obj);
@@ -535,7 +531,7 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
case MONO_TYPE_ARRAY:
case MONO_TYPE_SZARRAY: {
- MonoArrayType *array_type = mono_type_get_array_type(GDMonoClass::get_raw_type(p_type.type_class));
+ MonoArrayType *array_type = mono_type_get_array_type(GDMonoClass::get_raw_type(type.type_class));
if (array_type->eklass == CACHED_CLASS_RAW(MonoObject))
return mono_array_to_Array((MonoArray *)p_obj);
@@ -566,7 +562,7 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
} break;
case MONO_TYPE_CLASS: {
- GDMonoClass *type_class = p_type.type_class;
+ GDMonoClass *type_class = type.type_class;
// GodotObject
if (CACHED_CLASS(GodotObject)->is_assignable_from(type_class)) {
@@ -586,14 +582,14 @@ Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type) {
} break;
case MONO_TYPE_GENERICINST: {
- if (CACHED_RAW_MONO_CLASS(Dictionary) == p_type.type_class->get_mono_ptr()) {
+ if (CACHED_RAW_MONO_CLASS(Dictionary) == type.type_class->get_mono_ptr()) {
return mono_object_to_Dictionary(p_obj);
}
} break;
}
ERR_EXPLAIN(String() + "Attempted to convert an unmarshallable managed type to Variant. Name: \'" +
- p_type.type_class->get_name() + "\' Encoding: " + itos(p_type.type_encoding));
+ type.type_class->get_name() + "\' Encoding: " + itos(type.type_encoding));
ERR_FAIL_V(Variant());
}
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 727b9fa230..6572408ab5 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -102,7 +102,6 @@ _FORCE_INLINE_ MonoObject *variant_to_mono_object(Variant p_var) {
}
Variant mono_object_to_variant(MonoObject *p_obj);
-Variant mono_object_to_variant(MonoObject *p_obj, const ManagedType &p_type);
// Array
diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp
index bc5a1d3a39..0fe527b199 100644
--- a/modules/mono/mono_gd/gd_mono_property.cpp
+++ b/modules/mono/mono_gd/gd_mono_property.cpp
@@ -139,7 +139,7 @@ bool GDMonoProperty::has_setter() {
}
void GDMonoProperty::set_value(MonoObject *p_object, MonoObject *p_value, MonoObject **r_exc) {
- MonoMethod *prop_method = mono_property_get_get_method(mono_property);
+ MonoMethod *prop_method = mono_property_get_set_method(mono_property);
MonoArray *params = mono_array_new(mono_domain_get(), CACHED_CLASS_RAW(MonoObject), 1);
mono_array_set(params, MonoObject *, 0, p_value);
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index ff999b36f2..a2f0819a72 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -31,6 +31,7 @@
#include "gd_mono_utils.h"
#include "os/dir_access.h"
+#include "os/os.h"
#include "project_settings.h"
#include "reference.h"
@@ -43,16 +44,20 @@ namespace GDMonoUtils {
MonoCache mono_cache;
-#define CACHE_AND_CHECK(m_var, m_val) \
- { \
- m_var = m_val; \
- if (!m_var) ERR_PRINT("Mono Cache: Member " #m_var " is null. This is really bad!"); \
+#define CACHE_AND_CHECK(m_var, m_val) \
+ { \
+ m_var = m_val; \
+ if (!m_var) { \
+ ERR_EXPLAIN("Mono Cache: Member " #m_var " is null"); \
+ ERR_FAIL(); \
+ } \
}
#define CACHE_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_class, m_val)
#define CACHE_NS_CLASS_AND_CHECK(m_ns, m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.class_##m_ns##_##m_class, m_val)
#define CACHE_RAW_MONO_CLASS_AND_CHECK(m_class, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.rawclass_##m_class, m_val)
#define CACHE_FIELD_AND_CHECK(m_class, m_field, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.field_##m_class##_##m_field, m_val)
+#define CACHE_METHOD_AND_CHECK(m_class, m_method, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.method_##m_class##_##m_method, m_val)
#define CACHE_METHOD_THUNK_AND_CHECK(m_class, m_method, m_val) CACHE_AND_CHECK(GDMonoUtils::mono_cache.methodthunk_##m_class##_##m_method, m_val)
void MonoCache::clear_members() {
@@ -72,6 +77,13 @@ void MonoCache::clear_members() {
class_String = NULL;
class_IntPtr = NULL;
+#ifdef DEBUG_ENABLED
+ class_System_Diagnostics_StackTrace = NULL;
+ methodthunk_System_Diagnostics_StackTrace_GetFrames = NULL;
+ method_System_Diagnostics_StackTrace_ctor_bool = NULL;
+ method_System_Diagnostics_StackTrace_ctor_Exception_bool = NULL;
+#endif
+
rawclass_Dictionary = NULL;
class_Vector2 = NULL;
@@ -94,6 +106,11 @@ void MonoCache::clear_members() {
class_WeakRef = NULL;
class_MarshalUtils = NULL;
+#ifdef DEBUG_ENABLED
+ class_DebuggingUtils = NULL;
+ methodthunk_DebuggingUtils_GetStackFrameInfo = NULL;
+#endif
+
class_ExportAttribute = NULL;
field_ExportAttribute_hint = NULL;
field_ExportAttribute_hintString = NULL;
@@ -119,6 +136,12 @@ void MonoCache::clear_members() {
task_scheduler_handle = Ref<MonoGCHandle>();
}
+void MonoCache::cleanup() {
+
+ corlib_cache_updated = false;
+ godot_api_cache_updated = false;
+}
+
#define GODOT_API_CLASS(m_class) (GDMono::get_singleton()->get_api_assembly()->get_class(BINDINGS_NAMESPACE, #m_class))
void update_corlib_cache() {
@@ -137,6 +160,15 @@ void update_corlib_cache() {
CACHE_CLASS_AND_CHECK(double, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_double_class()));
CACHE_CLASS_AND_CHECK(String, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_string_class()));
CACHE_CLASS_AND_CHECK(IntPtr, GDMono::get_singleton()->get_corlib_assembly()->get_class(mono_get_intptr_class()));
+
+#ifdef DEBUG_ENABLED
+ CACHE_CLASS_AND_CHECK(System_Diagnostics_StackTrace, GDMono::get_singleton()->get_corlib_assembly()->get_class("System.Diagnostics", "StackTrace"));
+ CACHE_METHOD_THUNK_AND_CHECK(System_Diagnostics_StackTrace, GetFrames, (StackTrace_GetFrames)CACHED_CLASS(System_Diagnostics_StackTrace)->get_method("GetFrames")->get_thunk());
+ CACHE_METHOD_AND_CHECK(System_Diagnostics_StackTrace, ctor_bool, CACHED_CLASS(System_Diagnostics_StackTrace)->get_method_with_desc("System.Diagnostics.StackTrace:.ctor(bool)", true));
+ 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
+
+ mono_cache.corlib_cache_updated = true;
}
void update_godot_api_cache() {
@@ -152,7 +184,7 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(Color, GODOT_API_CLASS(Color));
CACHE_CLASS_AND_CHECK(Plane, GODOT_API_CLASS(Plane));
CACHE_CLASS_AND_CHECK(NodePath, GODOT_API_CLASS(NodePath));
- CACHE_CLASS_AND_CHECK(RID, GODOT_API_CLASS(NodePath));
+ CACHE_CLASS_AND_CHECK(RID, GODOT_API_CLASS(RID));
CACHE_CLASS_AND_CHECK(GodotObject, GODOT_API_CLASS(Object));
CACHE_CLASS_AND_CHECK(GodotReference, GODOT_API_CLASS(Reference));
CACHE_CLASS_AND_CHECK(Node, GODOT_API_CLASS(Node));
@@ -161,6 +193,10 @@ void update_godot_api_cache() {
CACHE_CLASS_AND_CHECK(WeakRef, GODOT_API_CLASS(WeakRef));
CACHE_CLASS_AND_CHECK(MarshalUtils, GODOT_API_CLASS(MarshalUtils));
+#ifdef DEBUG_ENABLED
+ CACHE_CLASS_AND_CHECK(DebuggingUtils, GODOT_API_CLASS(DebuggingUtils));
+#endif
+
// Attributes
CACHE_CLASS_AND_CHECK(ExportAttribute, GODOT_API_CLASS(ExportAttribute));
CACHE_FIELD_AND_CHECK(ExportAttribute, hint, CACHED_CLASS(ExportAttribute)->get_field("hint"));
@@ -183,6 +219,10 @@ void update_godot_api_cache() {
CACHE_METHOD_THUNK_AND_CHECK(SignalAwaiter, FailureCallback, (SignalAwaiter_FailureCallback)GODOT_API_CLASS(SignalAwaiter)->get_method("FailureCallback", 0)->get_thunk());
CACHE_METHOD_THUNK_AND_CHECK(GodotTaskScheduler, Activate, (GodotTaskScheduler_Activate)GODOT_API_CLASS(GodotTaskScheduler)->get_method("Activate", 0)->get_thunk());
+#ifdef DEBUG_ENABLED
+ CACHE_METHOD_THUNK_AND_CHECK(DebuggingUtils, GetStackFrameInfo, (DebugUtils_StackFrameInfo)GODOT_API_CLASS(DebuggingUtils)->get_method("GetStackFrameInfo", 4)->get_thunk());
+#endif
+
{
/*
* TODO Right now we only support Dictionary<object, object>.
@@ -202,6 +242,8 @@ void update_godot_api_cache() {
MonoObject *task_scheduler = mono_object_new(SCRIPTS_DOMAIN, GODOT_API_CLASS(GodotTaskScheduler)->get_mono_ptr());
mono_runtime_object_init(task_scheduler);
mono_cache.task_scheduler_handle = MonoGCHandle::create_strong(task_scheduler);
+
+ mono_cache.corlib_cache_updated = true;
}
void clear_cache() {
@@ -366,9 +408,50 @@ String get_exception_name_and_message(MonoObject *p_ex) {
return res;
}
-void print_unhandled_exception(MonoObject *p_ex) {
- ERR_PRINT(GDMonoUtils::get_exception_name_and_message(p_ex).utf8());
- mono_print_unhandled_exception(p_ex);
+void print_unhandled_exception(MonoObject *p_exc) {
+ print_unhandled_exception(p_exc, false);
+}
+
+void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution) {
+ mono_print_unhandled_exception(p_exc);
+#ifdef DEBUG_ENABLED
+ if (!ScriptDebugger::get_singleton())
+ return;
+
+ GDMonoClass *st_klass = CACHED_CLASS(System_Diagnostics_StackTrace);
+ MonoObject *stack_trace = mono_object_new(mono_domain_get(), st_klass->get_mono_ptr());
+
+ MonoBoolean need_file_info = true;
+ void *ctor_args[2] = { p_exc, &need_file_info };
+
+ MonoObject *unexpected_exc = NULL;
+ CACHED_METHOD(System_Diagnostics_StackTrace, ctor_Exception_bool)->invoke_raw(stack_trace, ctor_args, &unexpected_exc);
+
+ if (unexpected_exc != NULL) {
+ mono_print_unhandled_exception(unexpected_exc);
+
+ if (p_recursion_caution) {
+ // Called from CSharpLanguage::get_current_stack_info,
+ // so printing an error here could result in endless recursion
+ OS::get_singleton()->printerr("Mono: Method GDMonoUtils::print_unhandled_exception failed");
+ return;
+ } else {
+ ERR_FAIL();
+ }
+ }
+
+ Vector<ScriptLanguage::StackInfo> si;
+ if (stack_trace != NULL && !p_recursion_caution)
+ si = CSharpLanguage::get_singleton()->stack_trace_get_info(stack_trace);
+
+ String file = si.size() ? si[0].file : __FILE__;
+ String func = si.size() ? si[0].func : FUNCTION_STR;
+ int line = si.size() ? si[0].line : __LINE__;
+ String error_msg = "Unhandled exception";
+ String exc_msg = GDMonoUtils::get_exception_name_and_message(p_exc);
+
+ ScriptDebugger::get_singleton()->send_error(func, file, line, error_msg, exc_msg, ERR_HANDLER_ERROR, si);
+#endif
}
} // namespace GDMonoUtils
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index 284585856e..259da46c31 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -43,16 +43,13 @@ namespace GDMonoUtils {
typedef MonoObject *(*MarshalUtils_DictToArrays)(MonoObject *, MonoArray **, MonoArray **, MonoObject **);
typedef MonoObject *(*MarshalUtils_ArraysToDict)(MonoArray *, MonoArray *, MonoObject **);
-typedef MonoObject *(*SignalAwaiter_SignalCallback)(MonoObject *, MonoArray **, MonoObject **);
+typedef MonoObject *(*SignalAwaiter_SignalCallback)(MonoObject *, MonoArray *, MonoObject **);
typedef MonoObject *(*SignalAwaiter_FailureCallback)(MonoObject *, MonoObject **);
typedef MonoObject *(*GodotTaskScheduler_Activate)(MonoObject *, MonoObject **);
+typedef MonoArray *(*StackTrace_GetFrames)(MonoObject *, MonoObject **);
+typedef void (*DebugUtils_StackFrameInfo)(MonoObject *, MonoString **, int *, MonoString **, MonoObject **);
struct MonoCache {
- // Format for cached classes in the Godot namespace: class_<Class>
- // Macro: CACHED_CLASS(<Class>)
-
- // Format for cached classes in a different namespace: class_<Namespace>_<Class>
- // Macro: CACHED_NS_CLASS(<Namespace>, <Class>)
// -----------------------------------------------
// corlib classes
@@ -73,6 +70,13 @@ struct MonoCache {
GDMonoClass *class_String;
GDMonoClass *class_IntPtr;
+#ifdef DEBUG_ENABLED
+ GDMonoClass *class_System_Diagnostics_StackTrace;
+ StackTrace_GetFrames methodthunk_System_Diagnostics_StackTrace_GetFrames;
+ GDMonoMethod *method_System_Diagnostics_StackTrace_ctor_bool;
+ GDMonoMethod *method_System_Diagnostics_StackTrace_ctor_Exception_bool;
+#endif
+
MonoClass *rawclass_Dictionary;
// -----------------------------------------------
@@ -96,6 +100,11 @@ struct MonoCache {
GDMonoClass *class_WeakRef;
GDMonoClass *class_MarshalUtils;
+#ifdef DEBUG_ENABLED
+ GDMonoClass *class_DebuggingUtils;
+ DebugUtils_StackFrameInfo methodthunk_DebuggingUtils_GetStackFrameInfo;
+#endif
+
GDMonoClass *class_ExportAttribute;
GDMonoField *field_ExportAttribute_hint;
GDMonoField *field_ExportAttribute_hintString;
@@ -120,10 +129,16 @@ struct MonoCache {
Ref<MonoGCHandle> task_scheduler_handle;
+ bool corlib_cache_updated;
+ bool godot_api_cache_updated;
+
void clear_members();
- void cleanup() {}
+ void cleanup();
MonoCache() {
+ corlib_cache_updated = false;
+ godot_api_cache_updated = false;
+
clear_members();
}
};
@@ -167,7 +182,8 @@ MonoDomain *create_domain(const String &p_friendly_name);
String get_exception_name_and_message(MonoObject *p_ex);
-void print_unhandled_exception(MonoObject *p_ex);
+void print_unhandled_exception(MonoObject *p_exc);
+void print_unhandled_exception(MonoObject *p_exc, bool p_recursion_caution);
} // namespace GDMonoUtils
@@ -175,9 +191,9 @@ void print_unhandled_exception(MonoObject *p_ex);
#define CACHED_CLASS(m_class) (GDMonoUtils::mono_cache.class_##m_class)
#define CACHED_CLASS_RAW(m_class) (GDMonoUtils::mono_cache.class_##m_class->get_mono_ptr())
-#define CACHED_NS_CLASS(m_ns, m_class) (GDMonoUtils::mono_cache.class_##m_ns##_##m_class)
#define CACHED_RAW_MONO_CLASS(m_class) (GDMonoUtils::mono_cache.rawclass_##m_class)
#define CACHED_FIELD(m_class, m_field) (GDMonoUtils::mono_cache.field_##m_class##_##m_field)
+#define CACHED_METHOD(m_class, m_method) (GDMonoUtils::mono_cache.method_##m_class##_##m_method)
#define CACHED_METHOD_THUNK(m_class, m_method) (GDMonoUtils::mono_cache.methodthunk_##m_class##_##m_method)
#ifdef REAL_T_IS_DOUBLE