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.cpp110
-rw-r--r--modules/mono/mono_gd/gd_mono.h28
-rw-r--r--modules/mono/mono_gd/gd_mono_class_member.h4
-rw-r--r--modules/mono/mono_gd/gd_mono_field.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_field.h14
-rw-r--r--modules/mono/mono_gd/gd_mono_header.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.cpp2
-rw-r--r--modules/mono/mono_gd/gd_mono_internals.h2
-rw-r--r--modules/mono/mono_gd/gd_mono_log.cpp4
-rw-r--r--modules/mono/mono_gd/gd_mono_marshal.h7
-rw-r--r--modules/mono/mono_gd/gd_mono_method.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_method.h16
-rw-r--r--modules/mono/mono_gd/gd_mono_property.cpp14
-rw-r--r--modules/mono/mono_gd/gd_mono_property.h14
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.cpp87
-rw-r--r--modules/mono/mono_gd/gd_mono_utils.h4
16 files changed, 183 insertions, 153 deletions
diff --git a/modules/mono/mono_gd/gd_mono.cpp b/modules/mono/mono_gd/gd_mono.cpp
index a422224fcb..ca1ff9f9ff 100644
--- a/modules/mono/mono_gd/gd_mono.cpp
+++ b/modules/mono/mono_gd/gd_mono.cpp
@@ -54,17 +54,6 @@
#include "main/main.h"
#endif
-#ifdef MONO_PRINT_HANDLER_ENABLED
-void gdmono_MonoPrintCallback(const char *string, mono_bool is_stdout) {
-
- if (is_stdout) {
- OS::get_singleton()->print(string);
- } else {
- OS::get_singleton()->printerr(string);
- }
-}
-#endif
-
GDMono *GDMono::singleton = NULL;
namespace {
@@ -130,9 +119,14 @@ void gdmono_debug_init() {
}
#endif
- CharString 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"))
- .utf8();
+ CharString da_args = OS::get_singleton()->get_environment("GODOT_MONO_DEBUGGER_AGENT").utf8();
+
+ 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"))
+ .utf8();
+ }
+
// --debugger-agent=help
const char *options[] = {
"--soft-breakpoints",
@@ -145,6 +139,40 @@ void gdmono_debug_init() {
} // namespace
+void GDMono::add_mono_shared_libs_dir_to_path() {
+ // By default Mono seems to search shared libraries in the following directories:
+ // Current working directory, @executable_path@ and PATH
+ // The parent directory of the image file (assembly where the dllimport method is declared)
+ // @executable_path@/../lib
+ // @executable_path@/../Libraries (__MACH__ only)
+
+ // This does not work when embedding Mono unless we use the same directory structure.
+ // To fix this we append the directory containing our shared libraries to PATH.
+
+#if defined(WINDOWS_ENABLED) || defined(UNIX_ENABLED)
+ String path_var("PATH");
+ String path_value = OS::get_singleton()->get_environment(path_var);
+
+#ifdef WINDOWS_ENABLED
+ path_value += ';';
+
+ String bundled_bin_dir = GodotSharpDirs::get_data_mono_bin_dir();
+ path_value += DirAccess::exists(bundled_bin_dir) ? bundled_bin_dir : mono_reg_info.bin_dir;
+#else
+ path_value += ':';
+
+ String bundled_lib_dir = GodotSharpDirs::get_data_mono_lib_dir();
+ if (DirAccess::exists(bundled_lib_dir)) {
+ path_value += bundled_lib_dir;
+ } else {
+ // TODO: Do we need to add the lib dir when using the system installed Mono on Unix platforms?
+ }
+#endif
+
+ OS::get_singleton()->set_environment(path_var, path_value);
+#endif
+}
+
void GDMono::initialize() {
ERR_FAIL_NULL(Engine::get_singleton());
@@ -157,11 +185,6 @@ void GDMono::initialize() {
GDMonoLog::get_singleton()->initialize();
-#ifdef MONO_PRINT_HANDLER_ENABLED
- mono_trace_set_print_handler(gdmono_MonoPrintCallback);
- mono_trace_set_printerr_handler(gdmono_MonoPrintCallback);
-#endif
-
String assembly_rootdir;
String config_dir;
@@ -218,6 +241,8 @@ void GDMono::initialize() {
mono_set_dirs(assembly_rootdir.length() ? assembly_rootdir.utf8().get_data() : NULL,
config_dir.length() ? config_dir.utf8().get_data() : NULL);
+ add_mono_shared_libs_dir_to_path();
+
GDMonoAssembly::initialize();
#ifdef DEBUG_ENABLED
@@ -322,7 +347,7 @@ namespace GodotSharpBindings {
uint64_t get_core_api_hash();
#ifdef TOOLS_ENABLED
uint64_t get_editor_api_hash();
-#endif // TOOLS_ENABLED
+#endif
uint32_t get_bindings_version();
void register_generated_icalls();
@@ -339,29 +364,20 @@ void GDMono::_register_internal_calls() {
#endif
}
-#ifdef DEBUG_METHODS_ENABLED
void GDMono::_initialize_and_check_api_hashes() {
- api_core_hash = ClassDB::get_api_hash(ClassDB::API_CORE);
-
#ifdef MONO_GLUE_ENABLED
- if (api_core_hash != GodotSharpBindings::get_core_api_hash()) {
+ if (get_api_core_hash() != GodotSharpBindings::get_core_api_hash()) {
ERR_PRINT("Mono: Core API hash mismatch!");
}
-#endif
#ifdef TOOLS_ENABLED
- api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
-
-#ifdef MONO_GLUE_ENABLED
- if (api_editor_hash != GodotSharpBindings::get_editor_api_hash()) {
+ if (get_api_editor_hash() != GodotSharpBindings::get_editor_api_hash()) {
ERR_PRINT("Mono: Editor API hash mismatch!");
}
-#endif
-
#endif // TOOLS_ENABLED
+#endif // MONO_GLUE_ENABLED
}
-#endif // DEBUG_METHODS_ENABLED
void GDMono::add_assembly(uint32_t p_domain_id, GDMonoAssembly *p_assembly) {
@@ -726,7 +742,9 @@ Error GDMono::_unload_scripts_domain() {
#endif
core_api_assembly_out_of_sync = false;
+#ifdef TOOLS_ENABLED
editor_api_assembly_out_of_sync = false;
+#endif
MonoDomain *domain = scripts_domain;
scripts_domain = NULL;
@@ -759,7 +777,7 @@ Error GDMono::_load_tools_domain() {
}
#endif
-#ifdef TOOLS_ENABLED
+#ifdef GD_MONO_HOT_RELOAD
Error GDMono::reload_scripts_domain() {
ERR_FAIL_COND_V(!runtime_initialized, ERR_BUG);
@@ -780,8 +798,12 @@ Error GDMono::reload_scripts_domain() {
#ifdef MONO_GLUE_ENABLED
if (!_load_api_assemblies()) {
- if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated)) ||
- (editor_api_assembly && editor_api_assembly_out_of_sync)) {
+ if ((core_api_assembly && (core_api_assembly_out_of_sync || !GDMonoUtils::mono_cache.godot_api_cache_updated))
+#ifdef TOOLS_ENABLED
+ || (editor_api_assembly && editor_api_assembly_out_of_sync)
+#endif
+ ) {
+#ifdef TOOLS_ENABLED
// The assembly was successfully loaded, but the full api could not be cached.
// This is most likely an outdated assembly loaded because of an invalid version in the
// metadata, so we invalidate the version in the metadata and unload the script domain.
@@ -805,6 +827,10 @@ Error GDMono::reload_scripts_domain() {
}
return ERR_CANT_RESOLVE;
+#else
+ ERR_PRINT("The loaded API assembly is invalid");
+ CRASH_NOW();
+#endif
} else {
return ERR_CANT_OPEN;
}
@@ -900,7 +926,7 @@ void GDMono::unhandled_exception_hook(MonoObject *p_exc, void *) {
ScriptDebugger::get_singleton()->idle_poll();
#endif
abort();
- _UNREACHABLE_();
+ GD_UNREACHABLE();
}
GDMono::GDMono() {
@@ -919,7 +945,9 @@ GDMono::GDMono() {
#endif
core_api_assembly_out_of_sync = false;
+#ifdef TOOLS_ENABLED
editor_api_assembly_out_of_sync = false;
+#endif
corlib_assembly = NULL;
core_api_assembly = NULL;
@@ -929,12 +957,10 @@ GDMono::GDMono() {
editor_tools_assembly = NULL;
#endif
-#ifdef DEBUG_METHODS_ENABLED
api_core_hash = 0;
#ifdef TOOLS_ENABLED
api_editor_hash = 0;
#endif
-#endif
}
GDMono::~GDMono() {
@@ -1057,17 +1083,9 @@ void _GodotSharp::_bind_methods() {
_GodotSharp::_GodotSharp() {
singleton = this;
- queue_empty = true;
-#ifndef NO_THREADS
- queue_mutex = Mutex::create();
-#endif
}
_GodotSharp::~_GodotSharp() {
singleton = NULL;
-
- if (queue_mutex) {
- memdelete(queue_mutex);
- }
}
diff --git a/modules/mono/mono_gd/gd_mono.h b/modules/mono/mono_gd/gd_mono.h
index 6a00b287b0..785b65ce13 100644
--- a/modules/mono/mono_gd/gd_mono.h
+++ b/modules/mono/mono_gd/gd_mono.h
@@ -95,7 +95,9 @@ class GDMono {
#endif
bool core_api_assembly_out_of_sync;
+#ifdef TOOLS_ENABLED
bool editor_api_assembly_out_of_sync;
+#endif
GDMonoAssembly *corlib_assembly;
GDMonoAssembly *core_api_assembly;
@@ -132,13 +134,11 @@ class GDMono {
Error _load_tools_domain();
#endif
-#ifdef DEBUG_METHODS_ENABLED
uint64_t api_core_hash;
#ifdef TOOLS_ENABLED
uint64_t api_editor_hash;
#endif
void _initialize_and_check_api_hashes();
-#endif
GDMonoLog *gdmono_log;
@@ -146,15 +146,23 @@ class GDMono {
MonoRegInfo mono_reg_info;
#endif
+ void add_mono_shared_libs_dir_to_path();
+
protected:
static GDMono *singleton;
public:
-#ifdef DEBUG_METHODS_ENABLED
- uint64_t get_api_core_hash() { return api_core_hash; }
+ uint64_t get_api_core_hash() {
+ 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() { return api_editor_hash; }
-#endif
+ uint64_t get_api_editor_hash() {
+ if (api_editor_hash == 0)
+ api_editor_hash = ClassDB::get_api_hash(ClassDB::API_EDITOR);
+ return api_editor_hash;
+ }
#endif
#ifdef TOOLS_ENABLED
@@ -193,7 +201,7 @@ public:
GDMonoClass *get_class(MonoClass *p_raw_class);
-#ifdef TOOLS_ENABLED
+#ifdef GD_MONO_HOT_RELOAD
Error reload_scripts_domain();
#endif
@@ -266,12 +274,6 @@ class _GodotSharp : public Object {
List<NodePath *> np_delete_queue;
List<RID *> rid_delete_queue;
- bool queue_empty;
-
-#ifndef NO_THREADS
- Mutex *queue_mutex;
-#endif
-
protected:
static _GodotSharp *singleton;
static void _bind_methods();
diff --git a/modules/mono/mono_gd/gd_mono_class_member.h b/modules/mono/mono_gd/gd_mono_class_member.h
index 5bd21178ba..3058b18c05 100644
--- a/modules/mono/mono_gd/gd_mono_class_member.h
+++ b/modules/mono/mono_gd/gd_mono_class_member.h
@@ -35,7 +35,7 @@
#include <mono/metadata/object.h>
-class GDMonoClassMember {
+class IMonoClassMember {
public:
enum Visibility {
PRIVATE,
@@ -51,7 +51,7 @@ public:
MEMBER_TYPE_METHOD
};
- virtual ~GDMonoClassMember() {}
+ virtual ~IMonoClassMember() {}
virtual MemberType get_member_type() = 0;
diff --git a/modules/mono/mono_gd/gd_mono_field.cpp b/modules/mono/mono_gd/gd_mono_field.cpp
index a9d993412e..48fa380456 100644
--- a/modules/mono/mono_gd/gd_mono_field.cpp
+++ b/modules/mono/mono_gd/gd_mono_field.cpp
@@ -505,20 +505,20 @@ bool GDMonoField::is_static() {
return mono_field_get_flags(mono_field) & MONO_FIELD_ATTR_STATIC;
}
-GDMonoClassMember::Visibility GDMonoField::get_visibility() {
+IMonoClassMember::Visibility GDMonoField::get_visibility() {
switch (mono_field_get_flags(mono_field) & MONO_FIELD_ATTR_FIELD_ACCESS_MASK) {
case MONO_FIELD_ATTR_PRIVATE:
- return GDMonoClassMember::PRIVATE;
+ return IMonoClassMember::PRIVATE;
case MONO_FIELD_ATTR_FAM_AND_ASSEM:
- return GDMonoClassMember::PROTECTED_AND_INTERNAL;
+ return IMonoClassMember::PROTECTED_AND_INTERNAL;
case MONO_FIELD_ATTR_ASSEMBLY:
- return GDMonoClassMember::INTERNAL;
+ return IMonoClassMember::INTERNAL;
case MONO_FIELD_ATTR_FAMILY:
- return GDMonoClassMember::PROTECTED;
+ return IMonoClassMember::PROTECTED;
case MONO_FIELD_ATTR_PUBLIC:
- return GDMonoClassMember::PUBLIC;
+ return IMonoClassMember::PUBLIC;
default:
- ERR_FAIL_V(GDMonoClassMember::PRIVATE);
+ ERR_FAIL_V(IMonoClassMember::PRIVATE);
}
}
diff --git a/modules/mono/mono_gd/gd_mono_field.h b/modules/mono/mono_gd/gd_mono_field.h
index 319e895ab9..a3244101d8 100644
--- a/modules/mono/mono_gd/gd_mono_field.h
+++ b/modules/mono/mono_gd/gd_mono_field.h
@@ -35,7 +35,7 @@
#include "gd_mono_class_member.h"
#include "gd_mono_header.h"
-class GDMonoField : public GDMonoClassMember {
+class GDMonoField : public IMonoClassMember {
GDMonoClass *owner;
MonoClassField *mono_field;
@@ -47,15 +47,15 @@ class GDMonoField : public GDMonoClassMember {
MonoCustomAttrInfo *attributes;
public:
- virtual MemberType get_member_type() { return MEMBER_TYPE_FIELD; }
+ virtual MemberType get_member_type() GD_FINAL { return MEMBER_TYPE_FIELD; }
- virtual StringName get_name() { return name; }
+ virtual StringName get_name() GD_FINAL { return name; }
- virtual bool is_static();
- virtual Visibility get_visibility();
+ virtual bool is_static() GD_FINAL;
+ virtual Visibility get_visibility() GD_FINAL;
- virtual bool has_attribute(GDMonoClass *p_attr_class);
- virtual MonoObject *get_attribute(GDMonoClass *p_attr_class);
+ virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL;
+ virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL;
void fetch_attributes();
_FORCE_INLINE_ ManagedType get_type() const { return type; }
diff --git a/modules/mono/mono_gd/gd_mono_header.h b/modules/mono/mono_gd/gd_mono_header.h
index 23306d11b9..dd8c047386 100644
--- a/modules/mono/mono_gd/gd_mono_header.h
+++ b/modules/mono/mono_gd/gd_mono_header.h
@@ -35,7 +35,7 @@
class GDMonoAssembly;
class GDMonoClass;
-class GDMonoClassMember;
+class IMonoClassMember;
class GDMonoField;
class GDMonoProperty;
class GDMonoMethod;
diff --git a/modules/mono/mono_gd/gd_mono_internals.cpp b/modules/mono/mono_gd/gd_mono_internals.cpp
index 0574b0025d..0daa394e63 100644
--- a/modules/mono/mono_gd/gd_mono_internals.cpp
+++ b/modules/mono/mono_gd/gd_mono_internals.cpp
@@ -72,7 +72,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged) {
void unhandled_exception(MonoException *p_exc) {
mono_unhandled_exception((MonoObject *)p_exc); // prints the exception as well
abort();
- _UNREACHABLE_();
+ GD_UNREACHABLE();
}
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_internals.h b/modules/mono/mono_gd/gd_mono_internals.h
index 09cb59ee6b..2d77bde27c 100644
--- a/modules/mono/mono_gd/gd_mono_internals.h
+++ b/modules/mono/mono_gd/gd_mono_internals.h
@@ -45,7 +45,7 @@ void tie_managed_to_unmanaged(MonoObject *managed, Object *unmanaged);
* Do not call this function directly.
* Use GDMonoUtils::debug_unhandled_exception(MonoException *) instead.
*/
-_NO_RETURN_ void unhandled_exception(MonoException *p_exc);
+GD_NORETURN void unhandled_exception(MonoException *p_exc);
} // namespace GDMonoInternals
diff --git a/modules/mono/mono_gd/gd_mono_log.cpp b/modules/mono/mono_gd/gd_mono_log.cpp
index fa4850ca8c..ec89df1959 100644
--- a/modules/mono/mono_gd/gd_mono_log.cpp
+++ b/modules/mono/mono_gd/gd_mono_log.cpp
@@ -52,7 +52,7 @@ static int log_level_get_id(const char *p_log_level) {
return -1;
}
-void gdmono_MonoLogCallback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) {
+static void mono_log_callback(const char *log_domain, const char *log_level, const char *message, mono_bool fatal, void *user_data) {
FileAccess *f = GDMonoLog::get_singleton()->get_log_file();
@@ -153,7 +153,7 @@ void GDMonoLog::initialize() {
if (log_file) {
print_verbose("Mono: Logfile is " + log_file_path);
- mono_trace_set_log_handler(gdmono_MonoLogCallback, this);
+ mono_trace_set_log_handler(mono_log_callback, this);
} else {
OS::get_singleton()->printerr("Mono: No log file, using default log handler\n");
}
diff --git a/modules/mono/mono_gd/gd_mono_marshal.h b/modules/mono/mono_gd/gd_mono_marshal.h
index 5e2deea43c..4f86e02f87 100644
--- a/modules/mono/mono_gd/gd_mono_marshal.h
+++ b/modules/mono/mono_gd/gd_mono_marshal.h
@@ -206,9 +206,10 @@ enum {
// In the future we may force this if we want to ref return these structs
#ifdef GD_MONO_FORCE_INTEROP_STRUCT_COPY
-// Sometimes clang-format can be an ass
-GD_STATIC_ASSERT(MATCHES_Vector2 &&MATCHES_Rect2 &&MATCHES_Transform2D &&MATCHES_Vector3 &&
- MATCHES_Basis &&MATCHES_Quat &&MATCHES_Transform &&MATCHES_AABB &&MATCHES_Color &&MATCHES_Plane);
+/* clang-format off */
+GD_STATIC_ASSERT(MATCHES_Vector2 && MATCHES_Rect2 && MATCHES_Transform2D && MATCHES_Vector3 &&
+ MATCHES_Basis && MATCHES_Quat && MATCHES_Transform && MATCHES_AABB && MATCHES_Color &&MATCHES_Plane);
+/* clang-format on */
#endif
} // namespace InteropLayout
diff --git a/modules/mono/mono_gd/gd_mono_method.cpp b/modules/mono/mono_gd/gd_mono_method.cpp
index 071d852ce7..7f11e4671d 100644
--- a/modules/mono/mono_gd/gd_mono_method.cpp
+++ b/modules/mono/mono_gd/gd_mono_method.cpp
@@ -78,20 +78,20 @@ bool GDMonoMethod::is_static() {
return mono_method_get_flags(mono_method, NULL) & MONO_METHOD_ATTR_STATIC;
}
-GDMonoClassMember::Visibility GDMonoMethod::get_visibility() {
+IMonoClassMember::Visibility GDMonoMethod::get_visibility() {
switch (mono_method_get_flags(mono_method, NULL) & MONO_METHOD_ATTR_ACCESS_MASK) {
case MONO_METHOD_ATTR_PRIVATE:
- return GDMonoClassMember::PRIVATE;
+ return IMonoClassMember::PRIVATE;
case MONO_METHOD_ATTR_FAM_AND_ASSEM:
- return GDMonoClassMember::PROTECTED_AND_INTERNAL;
+ return IMonoClassMember::PROTECTED_AND_INTERNAL;
case MONO_METHOD_ATTR_ASSEM:
- return GDMonoClassMember::INTERNAL;
+ return IMonoClassMember::INTERNAL;
case MONO_METHOD_ATTR_FAMILY:
- return GDMonoClassMember::PROTECTED;
+ return IMonoClassMember::PROTECTED;
case MONO_METHOD_ATTR_PUBLIC:
- return GDMonoClassMember::PUBLIC;
+ return IMonoClassMember::PUBLIC;
default:
- ERR_FAIL_V(GDMonoClassMember::PRIVATE);
+ ERR_FAIL_V(IMonoClassMember::PRIVATE);
}
}
diff --git a/modules/mono/mono_gd/gd_mono_method.h b/modules/mono/mono_gd/gd_mono_method.h
index c4a994177e..fc035d387c 100644
--- a/modules/mono/mono_gd/gd_mono_method.h
+++ b/modules/mono/mono_gd/gd_mono_method.h
@@ -35,7 +35,7 @@
#include "gd_mono_class_member.h"
#include "gd_mono_header.h"
-class GDMonoMethod : public GDMonoClassMember {
+class GDMonoMethod : public IMonoClassMember {
StringName name;
@@ -57,17 +57,17 @@ class GDMonoMethod : public GDMonoClassMember {
MonoMethod *mono_method;
public:
- virtual MemberType get_member_type() { return MEMBER_TYPE_METHOD; }
+ virtual MemberType get_member_type() GD_FINAL { return MEMBER_TYPE_METHOD; }
- virtual StringName get_name() { return name; }
+ virtual StringName get_name() GD_FINAL { return name; }
- virtual bool is_static();
+ virtual bool is_static() GD_FINAL;
- virtual Visibility get_visibility();
+ virtual Visibility get_visibility() GD_FINAL;
- virtual bool has_attribute(GDMonoClass *p_attr_class);
- virtual MonoObject *get_attribute(GDMonoClass *p_attr_class);
- virtual void fetch_attributes();
+ virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL;
+ virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL;
+ void fetch_attributes();
_FORCE_INLINE_ int get_parameters_count() { return params_count; }
_FORCE_INLINE_ ManagedType get_return_type() { return return_type; }
diff --git a/modules/mono/mono_gd/gd_mono_property.cpp b/modules/mono/mono_gd/gd_mono_property.cpp
index 04fd8b8e63..5842e26241 100644
--- a/modules/mono/mono_gd/gd_mono_property.cpp
+++ b/modules/mono/mono_gd/gd_mono_property.cpp
@@ -80,24 +80,24 @@ bool GDMonoProperty::is_static() {
return mono_method_get_flags(prop_method, NULL) & MONO_METHOD_ATTR_STATIC;
}
-GDMonoClassMember::Visibility GDMonoProperty::get_visibility() {
+IMonoClassMember::Visibility GDMonoProperty::get_visibility() {
MonoMethod *prop_method = mono_property_get_get_method(mono_property);
if (prop_method == NULL)
prop_method = mono_property_get_set_method(mono_property);
switch (mono_method_get_flags(prop_method, NULL) & MONO_METHOD_ATTR_ACCESS_MASK) {
case MONO_METHOD_ATTR_PRIVATE:
- return GDMonoClassMember::PRIVATE;
+ return IMonoClassMember::PRIVATE;
case MONO_METHOD_ATTR_FAM_AND_ASSEM:
- return GDMonoClassMember::PROTECTED_AND_INTERNAL;
+ return IMonoClassMember::PROTECTED_AND_INTERNAL;
case MONO_METHOD_ATTR_ASSEM:
- return GDMonoClassMember::INTERNAL;
+ return IMonoClassMember::INTERNAL;
case MONO_METHOD_ATTR_FAMILY:
- return GDMonoClassMember::PROTECTED;
+ return IMonoClassMember::PROTECTED;
case MONO_METHOD_ATTR_PUBLIC:
- return GDMonoClassMember::PUBLIC;
+ return IMonoClassMember::PUBLIC;
default:
- ERR_FAIL_V(GDMonoClassMember::PRIVATE);
+ ERR_FAIL_V(IMonoClassMember::PRIVATE);
}
}
diff --git a/modules/mono/mono_gd/gd_mono_property.h b/modules/mono/mono_gd/gd_mono_property.h
index 934ce68904..d8a9f69ffb 100644
--- a/modules/mono/mono_gd/gd_mono_property.h
+++ b/modules/mono/mono_gd/gd_mono_property.h
@@ -35,7 +35,7 @@
#include "gd_mono_class_member.h"
#include "gd_mono_header.h"
-class GDMonoProperty : public GDMonoClassMember {
+class GDMonoProperty : public IMonoClassMember {
GDMonoClass *owner;
MonoProperty *mono_property;
@@ -47,15 +47,15 @@ class GDMonoProperty : public GDMonoClassMember {
MonoCustomAttrInfo *attributes;
public:
- virtual MemberType get_member_type() { return MEMBER_TYPE_PROPERTY; }
+ virtual MemberType get_member_type() GD_FINAL { return MEMBER_TYPE_PROPERTY; }
- virtual StringName get_name() { return name; }
+ virtual StringName get_name() GD_FINAL { return name; }
- virtual bool is_static();
- virtual Visibility get_visibility();
+ virtual bool is_static() GD_FINAL;
+ virtual Visibility get_visibility() GD_FINAL;
- virtual bool has_attribute(GDMonoClass *p_attr_class);
- virtual MonoObject *get_attribute(GDMonoClass *p_attr_class);
+ virtual bool has_attribute(GDMonoClass *p_attr_class) GD_FINAL;
+ virtual MonoObject *get_attribute(GDMonoClass *p_attr_class) GD_FINAL;
void fetch_attributes();
bool has_getter();
diff --git a/modules/mono/mono_gd/gd_mono_utils.cpp b/modules/mono/mono_gd/gd_mono_utils.cpp
index 97a00a504d..ac6ccac3a7 100644
--- a/modules/mono/mono_gd/gd_mono_utils.cpp
+++ b/modules/mono/mono_gd/gd_mono_utils.cpp
@@ -265,61 +265,70 @@ void clear_cache() {
}
MonoObject *unmanaged_get_managed(Object *unmanaged) {
- if (unmanaged) {
- if (unmanaged->get_script_instance()) {
- CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance());
- if (cs_instance) {
- return cs_instance->get_mono_object();
- }
+ if (!unmanaged)
+ return NULL;
+
+ if (unmanaged->get_script_instance()) {
+ CSharpInstance *cs_instance = CAST_CSHARP_INSTANCE(unmanaged->get_script_instance());
+
+ if (cs_instance) {
+ return cs_instance->get_mono_object();
}
+ }
+
+ // If the owner does not have a CSharpInstance...
+
+ void *data = unmanaged->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
+
+ if (!data)
+ return NULL;
- // If the owner does not have a CSharpInstance...
+ CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
- void *data = unmanaged->get_script_instance_binding(CSharpLanguage::get_singleton()->get_language_index());
+ if (!script_binding.inited) {
+ // Already had a binding that needs to be setup
+ CSharpLanguage::get_singleton()->setup_csharp_script_binding(script_binding, unmanaged);
- if (data) {
- CSharpScriptBinding &script_binding = ((Map<Object *, CSharpScriptBinding>::Element *)data)->value();
+ if (!script_binding.inited)
+ return NULL;
+ }
- Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
- ERR_FAIL_COND_V(gchandle.is_null(), NULL);
+ Ref<MonoGCHandle> &gchandle = script_binding.gchandle;
+ ERR_FAIL_COND_V(gchandle.is_null(), NULL);
- MonoObject *target = gchandle->get_target();
+ MonoObject *target = gchandle->get_target();
- if (target)
- return target;
+ if (target)
+ return target;
- CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
+ CSharpLanguage::get_singleton()->release_script_gchandle(gchandle);
- // Create a new one
+ // Create a new one
#ifdef DEBUG_ENABLED
- CRASH_COND(script_binding.type_name == StringName());
- CRASH_COND(script_binding.wrapper_class == NULL);
+ CRASH_COND(script_binding.type_name == StringName());
+ CRASH_COND(script_binding.wrapper_class == NULL);
#endif
- MonoObject *mono_object = GDMonoUtils::create_managed_for_godot_object(script_binding.wrapper_class, script_binding.type_name, unmanaged);
- ERR_FAIL_NULL_V(mono_object, NULL);
-
- gchandle->set_handle(MonoGCHandle::new_strong_handle(mono_object), MonoGCHandle::STRONG_HANDLE);
+ MonoObject *mono_object = GDMonoUtils::create_managed_for_godot_object(script_binding.wrapper_class, script_binding.type_name, unmanaged);
+ ERR_FAIL_NULL_V(mono_object, NULL);
- // Tie managed to unmanaged
- Reference *ref = Object::cast_to<Reference>(unmanaged);
+ gchandle->set_handle(MonoGCHandle::new_strong_handle(mono_object), MonoGCHandle::STRONG_HANDLE);
- if (ref) {
- // Unsafe refcount increment. The managed instance also counts as a reference.
- // 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)
+ // Tie managed to unmanaged
+ Reference *ref = Object::cast_to<Reference>(unmanaged);
- ref->reference();
- }
+ if (ref) {
+ // Unsafe refcount increment. The managed instance also counts as a reference.
+ // 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)
- return mono_object;
- }
+ ref->reference();
}
- return NULL;
+ return mono_object;
}
void set_main_thread(MonoThread *p_thread) {
@@ -565,7 +574,7 @@ void debug_send_unhandled_exception_error(MonoException *p_exc) {
if (unexpected_exc) {
GDMonoInternals::unhandled_exception(unexpected_exc);
- _UNREACHABLE_();
+ GD_UNREACHABLE();
}
Vector<ScriptLanguage::StackInfo> _si;
@@ -604,7 +613,7 @@ void debug_unhandled_exception(MonoException *p_exc) {
ScriptDebugger::get_singleton()->idle_poll();
#endif
GDMonoInternals::unhandled_exception(p_exc); // prints the exception as well
- _UNREACHABLE_();
+ GD_UNREACHABLE();
}
void print_unhandled_exception(MonoException *p_exc) {
@@ -615,7 +624,7 @@ void set_pending_exception(MonoException *p_exc) {
#ifdef HAS_PENDING_EXCEPTIONS
if (get_runtime_invoke_count() == 0) {
debug_unhandled_exception(p_exc);
- _UNREACHABLE_();
+ GD_UNREACHABLE();
}
if (!mono_runtime_set_pending_exception(p_exc, false)) {
@@ -624,7 +633,7 @@ void set_pending_exception(MonoException *p_exc) {
}
#else
debug_unhandled_exception(p_exc);
- _UNREACHABLE_();
+ GD_UNREACHABLE();
#endif
}
diff --git a/modules/mono/mono_gd/gd_mono_utils.h b/modules/mono/mono_gd/gd_mono_utils.h
index 6febc50a5f..e88bf1ced9 100644
--- a/modules/mono/mono_gd/gd_mono_utils.h
+++ b/modules/mono/mono_gd/gd_mono_utils.h
@@ -44,7 +44,7 @@
#define UNLIKELY_UNHANDLED_EXCEPTION(m_exc) \
if (unlikely(m_exc != NULL)) { \
GDMonoUtils::debug_unhandled_exception(m_exc); \
- _UNREACHABLE_(); \
+ GD_UNREACHABLE(); \
}
namespace GDMonoUtils {
@@ -214,7 +214,7 @@ 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);
-_NO_RETURN_ void debug_unhandled_exception(MonoException *p_exc);
+GD_NORETURN void debug_unhandled_exception(MonoException *p_exc);
void print_unhandled_exception(MonoException *p_exc);
/**