Browse Source

Merge pull request #44105 from neikeq/mono-wasm-m2n-hook

Mono: Make Godot provide its own WASM m2n trampolines
Rémi Verschelde 4 years ago
parent
commit
b07a3f503b

+ 2 - 1
modules/mono/build_scripts/mono_configure.py

@@ -263,7 +263,8 @@ def configure(env, env_mono):
             env_mono.Append(CPPDEFINES=["_REENTRANT"])
             env_mono.Append(CPPDEFINES=["_REENTRANT"])
 
 
             if mono_static:
             if mono_static:
-                env.Append(LINKFLAGS=["-rdynamic"])
+                if not is_javascript:
+                    env.Append(LINKFLAGS=["-rdynamic"])
 
 
                 mono_lib_file = os.path.join(mono_lib_path, "lib" + mono_lib + ".a")
                 mono_lib_file = os.path.join(mono_lib_path, "lib" + mono_lib + ".a")
 
 

+ 14 - 57
modules/mono/editor/bindings_generator.cpp

@@ -97,7 +97,7 @@
 #define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable"
 #define C_METHOD_MANAGED_TO_SIGNAL C_NS_MONOMARSHAL "::signal_info_to_callable"
 #define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info"
 #define C_METHOD_MANAGED_FROM_SIGNAL C_NS_MONOMARSHAL "::callable_to_signal_info"
 
 
-#define BINDINGS_GENERATOR_VERSION UINT32_C(12)
+#define BINDINGS_GENERATOR_VERSION UINT32_C(13)
 
 
 const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
 const char *BindingsGenerator::TypeInterface::DEFAULT_VARARG_C_IN("\t%0 %1_in = %1;\n");
 
 
@@ -1999,12 +1999,12 @@ Error BindingsGenerator::generate_glue(const String &p_output_dir) {
 
 
 #define ADD_INTERNAL_CALL_REGISTRATION(m_icall)                                                              \
 #define ADD_INTERNAL_CALL_REGISTRATION(m_icall)                                                              \
 	{                                                                                                        \
 	{                                                                                                        \
-		output.append("\tmono_add_internal_call(");                                                          \
+		output.append("\tGDMonoUtils::add_internal_call(");                                                  \
 		output.append("\"" BINDINGS_NAMESPACE ".");                                                          \
 		output.append("\"" BINDINGS_NAMESPACE ".");                                                          \
 		output.append(m_icall.editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS); \
 		output.append(m_icall.editor_only ? BINDINGS_CLASS_NATIVECALLS_EDITOR : BINDINGS_CLASS_NATIVECALLS); \
 		output.append("::");                                                                                 \
 		output.append("::");                                                                                 \
 		output.append(m_icall.name);                                                                         \
 		output.append(m_icall.name);                                                                         \
-		output.append("\", (void*)");                                                                        \
+		output.append("\", ");                                                                               \
 		output.append(m_icall.name);                                                                         \
 		output.append(m_icall.name);                                                                         \
 		output.append(");\n");                                                                               \
 		output.append(");\n");                                                                               \
 	}
 	}
@@ -3100,44 +3100,11 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
 		INSERT_INT_TYPE("sbyte", int8_t, int64_t);
 		INSERT_INT_TYPE("sbyte", int8_t, int64_t);
 		INSERT_INT_TYPE("short", int16_t, int64_t);
 		INSERT_INT_TYPE("short", int16_t, int64_t);
 		INSERT_INT_TYPE("int", int32_t, int64_t);
 		INSERT_INT_TYPE("int", int32_t, int64_t);
+		INSERT_INT_TYPE("long", int64_t, int64_t);
 		INSERT_INT_TYPE("byte", uint8_t, int64_t);
 		INSERT_INT_TYPE("byte", uint8_t, int64_t);
 		INSERT_INT_TYPE("ushort", uint16_t, int64_t);
 		INSERT_INT_TYPE("ushort", uint16_t, int64_t);
 		INSERT_INT_TYPE("uint", uint32_t, int64_t);
 		INSERT_INT_TYPE("uint", uint32_t, int64_t);
-
-		itype = TypeInterface::create_value_type(String("long"));
-		{
-			itype.c_out = "\treturn (%0)%1;\n";
-			itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
-			itype.c_out = "\t*%3 = (%0)%1;\n";
-			itype.c_type = "int64_t";
-			itype.c_arg_in = "&%s_in";
-		}
-		itype.c_type_in = "int64_t*";
-		itype.c_type_out = "int64_t";
-		itype.im_type_in = "ref " + itype.name;
-		itype.im_type_out = "out " + itype.name;
-		itype.cs_in = "ref %0";
-		/* in cs_out, im_type_out (%3) includes the 'out ' part */
-		itype.cs_out = "%0(%1, %3 argRet); return argRet;";
-		itype.ret_as_byref_arg = true;
-		builtin_types.insert(itype.cname, itype);
-
-		itype = TypeInterface::create_value_type(String("ulong"));
-		{
-			itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
-			itype.c_out = "\t*%3 = (%0)%1;\n";
-			itype.c_type = "int64_t";
-			itype.c_arg_in = "&%s_in";
-		}
-		itype.c_type_in = "uint64_t*";
-		itype.c_type_out = "uint64_t";
-		itype.im_type_in = "ref " + itype.name;
-		itype.im_type_out = "out " + itype.name;
-		itype.cs_in = "ref %0";
-		/* in cs_out, im_type_out (%3) includes the 'out ' part */
-		itype.cs_out = "%0(%1, %3 argRet); return argRet;";
-		itype.ret_as_byref_arg = true;
-		builtin_types.insert(itype.cname, itype);
+		INSERT_INT_TYPE("ulong", uint64_t, int64_t);
 	}
 	}
 
 
 	// Floating point types
 	// Floating point types
@@ -3149,20 +3116,16 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
 		itype.proxy_name = "float";
 		itype.proxy_name = "float";
 		{
 		{
 			// The expected type for 'float' in ptrcall is 'double'
 			// The expected type for 'float' in ptrcall is 'double'
-			itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
-			itype.c_out = "\t*%3 = (%0)%1;\n";
+			itype.c_in = "\t%0 %1_in = (%0)%1;\n";
+			itype.c_out = "\treturn (%0)%1;\n";
 			itype.c_type = "double";
 			itype.c_type = "double";
-			itype.c_type_in = "float*";
+			itype.c_type_in = "float";
 			itype.c_type_out = "float";
 			itype.c_type_out = "float";
 			itype.c_arg_in = "&%s_in";
 			itype.c_arg_in = "&%s_in";
 		}
 		}
 		itype.cs_type = itype.proxy_name;
 		itype.cs_type = itype.proxy_name;
-		itype.im_type_in = "ref " + itype.proxy_name;
-		itype.im_type_out = "out " + itype.proxy_name;
-		itype.cs_in = "ref %0";
-		/* in cs_out, im_type_out (%3) includes the 'out ' part */
-		itype.cs_out = "%0(%1, %3 argRet); return argRet;";
-		itype.ret_as_byref_arg = true;
+		itype.im_type_in = itype.proxy_name;
+		itype.im_type_out = itype.proxy_name;
 		builtin_types.insert(itype.cname, itype);
 		builtin_types.insert(itype.cname, itype);
 
 
 		// double
 		// double
@@ -3171,20 +3134,14 @@ void BindingsGenerator::_populate_builtin_type_interfaces() {
 		itype.cname = itype.name;
 		itype.cname = itype.name;
 		itype.proxy_name = "double";
 		itype.proxy_name = "double";
 		{
 		{
-			itype.c_in = "\t%0 %1_in = (%0)*%1;\n";
-			itype.c_out = "\t*%3 = (%0)%1;\n";
 			itype.c_type = "double";
 			itype.c_type = "double";
-			itype.c_type_in = "double*";
+			itype.c_type_in = "double";
 			itype.c_type_out = "double";
 			itype.c_type_out = "double";
-			itype.c_arg_in = "&%s_in";
+			itype.c_arg_in = "&%s";
 		}
 		}
 		itype.cs_type = itype.proxy_name;
 		itype.cs_type = itype.proxy_name;
-		itype.im_type_in = "ref " + itype.proxy_name;
-		itype.im_type_out = "out " + itype.proxy_name;
-		itype.cs_in = "ref %0";
-		/* in cs_out, im_type_out (%3) includes the 'out ' part */
-		itype.cs_out = "%0(%1, %3 argRet); return argRet;";
-		itype.ret_as_byref_arg = true;
+		itype.im_type_in = itype.proxy_name;
+		itype.im_type_out = itype.proxy_name;
 		builtin_types.insert(itype.cname, itype);
 		builtin_types.insert(itype.cname, itype);
 	}
 	}
 
 

+ 50 - 89
modules/mono/editor/editor_internal_calls.cpp

@@ -47,7 +47,6 @@
 #include "../godotsharp_dirs.h"
 #include "../godotsharp_dirs.h"
 #include "../mono_gd/gd_mono_marshal.h"
 #include "../mono_gd/gd_mono_marshal.h"
 #include "../utils/osx_utils.h"
 #include "../utils/osx_utils.h"
-#include "bindings_generator.h"
 #include "code_completion.h"
 #include "code_completion.h"
 #include "godotsharp_export.h"
 #include "godotsharp_export.h"
 #include "script_class_parser.h"
 #include "script_class_parser.h"
@@ -173,35 +172,6 @@ MonoBoolean godot_icall_EditorProgress_Step(MonoString *p_task, MonoString *p_st
 	return EditorNode::progress_task_step(task, state, p_step, (bool)p_force_refresh);
 	return EditorNode::progress_task_step(task, state, p_step, (bool)p_force_refresh);
 }
 }
 
 
-BindingsGenerator *godot_icall_BindingsGenerator_Ctor() {
-	return memnew(BindingsGenerator);
-}
-
-void godot_icall_BindingsGenerator_Dtor(BindingsGenerator *p_handle) {
-	memdelete(p_handle);
-}
-
-MonoBoolean godot_icall_BindingsGenerator_LogPrintEnabled(BindingsGenerator *p_handle) {
-	return p_handle->is_log_print_enabled();
-}
-
-void godot_icall_BindingsGenerator_SetLogPrintEnabled(BindingsGenerator p_handle, MonoBoolean p_enabled) {
-	p_handle.set_log_print_enabled(p_enabled);
-}
-
-int32_t godot_icall_BindingsGenerator_GenerateCsApi(BindingsGenerator *p_handle, MonoString *p_output_dir) {
-	String output_dir = GDMonoMarshal::mono_string_to_godot(p_output_dir);
-	return p_handle->generate_cs_api(output_dir);
-}
-
-uint32_t godot_icall_BindingsGenerator_Version() {
-	return BindingsGenerator::get_version();
-}
-
-uint32_t godot_icall_BindingsGenerator_CsGlueVersion() {
-	return CS_GLUE_VERSION;
-}
-
 int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObject *p_classes, MonoString **r_error_str) {
 int32_t godot_icall_ScriptClassParser_ParseFile(MonoString *p_filepath, MonoObject *p_classes, MonoString **r_error_str) {
 	*r_error_str = nullptr;
 	*r_error_str = nullptr;
 
 
@@ -400,75 +370,66 @@ MonoBoolean godot_icall_Utils_OS_UnixFileHasExecutableAccess(MonoString *p_file_
 
 
 void register_editor_internal_calls() {
 void register_editor_internal_calls() {
 	// GodotSharpDirs
 	// GodotSharpDirs
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResDataDir", (void *)godot_icall_GodotSharpDirs_ResDataDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResMetadataDir", (void *)godot_icall_GodotSharpDirs_ResMetadataDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesBaseDir", (void *)godot_icall_GodotSharpDirs_ResAssembliesBaseDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesDir", (void *)godot_icall_GodotSharpDirs_ResAssembliesDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResConfigDir", (void *)godot_icall_GodotSharpDirs_ResConfigDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempDir", (void *)godot_icall_GodotSharpDirs_ResTempDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesBaseDir", (void *)godot_icall_GodotSharpDirs_ResTempAssembliesBaseDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesDir", (void *)godot_icall_GodotSharpDirs_ResTempAssembliesDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoUserDir", (void *)godot_icall_GodotSharpDirs_MonoUserDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoLogsDir", (void *)godot_icall_GodotSharpDirs_MonoLogsDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoSolutionsDir", (void *)godot_icall_GodotSharpDirs_MonoSolutionsDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_BuildLogsDirs", (void *)godot_icall_GodotSharpDirs_BuildLogsDirs);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectSlnPath", (void *)godot_icall_GodotSharpDirs_ProjectSlnPath);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectCsProjPath", (void *)godot_icall_GodotSharpDirs_ProjectCsProjPath);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorToolsDir", (void *)godot_icall_GodotSharpDirs_DataEditorToolsDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorPrebuiltApiDir", (void *)godot_icall_GodotSharpDirs_DataEditorPrebuiltApiDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoEtcDir", (void *)godot_icall_GodotSharpDirs_DataMonoEtcDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoLibDir", (void *)godot_icall_GodotSharpDirs_DataMonoLibDir);
-	mono_add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoBinDir", (void *)godot_icall_GodotSharpDirs_DataMonoBinDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResDataDir", godot_icall_GodotSharpDirs_ResDataDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResMetadataDir", godot_icall_GodotSharpDirs_ResMetadataDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesBaseDir", godot_icall_GodotSharpDirs_ResAssembliesBaseDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResAssembliesDir", godot_icall_GodotSharpDirs_ResAssembliesDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResConfigDir", godot_icall_GodotSharpDirs_ResConfigDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempDir", godot_icall_GodotSharpDirs_ResTempDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesBaseDir", godot_icall_GodotSharpDirs_ResTempAssembliesBaseDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ResTempAssembliesDir", godot_icall_GodotSharpDirs_ResTempAssembliesDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoUserDir", godot_icall_GodotSharpDirs_MonoUserDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoLogsDir", godot_icall_GodotSharpDirs_MonoLogsDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_MonoSolutionsDir", godot_icall_GodotSharpDirs_MonoSolutionsDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_BuildLogsDirs", godot_icall_GodotSharpDirs_BuildLogsDirs);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectSlnPath", godot_icall_GodotSharpDirs_ProjectSlnPath);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_ProjectCsProjPath", godot_icall_GodotSharpDirs_ProjectCsProjPath);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorToolsDir", godot_icall_GodotSharpDirs_DataEditorToolsDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataEditorPrebuiltApiDir", godot_icall_GodotSharpDirs_DataEditorPrebuiltApiDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoEtcDir", godot_icall_GodotSharpDirs_DataMonoEtcDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoLibDir", godot_icall_GodotSharpDirs_DataMonoLibDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.GodotSharpDirs::internal_DataMonoBinDir", godot_icall_GodotSharpDirs_DataMonoBinDir);
 
 
 	// EditorProgress
 	// EditorProgress
-	mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Create", (void *)godot_icall_EditorProgress_Create);
-	mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Dispose", (void *)godot_icall_EditorProgress_Dispose);
-	mono_add_internal_call("GodotTools.Internals.EditorProgress::internal_Step", (void *)godot_icall_EditorProgress_Step);
-
-	// BiningsGenerator
-	mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Ctor", (void *)godot_icall_BindingsGenerator_Ctor);
-	mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Dtor", (void *)godot_icall_BindingsGenerator_Dtor);
-	mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_LogPrintEnabled", (void *)godot_icall_BindingsGenerator_LogPrintEnabled);
-	mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_SetLogPrintEnabled", (void *)godot_icall_BindingsGenerator_SetLogPrintEnabled);
-	mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_GenerateCsApi", (void *)godot_icall_BindingsGenerator_GenerateCsApi);
-	mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_Version", (void *)godot_icall_BindingsGenerator_Version);
-	mono_add_internal_call("GodotTools.Internals.BindingsGenerator::internal_CsGlueVersion", (void *)godot_icall_BindingsGenerator_CsGlueVersion);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Create", godot_icall_EditorProgress_Create);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Dispose", godot_icall_EditorProgress_Dispose);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.EditorProgress::internal_Step", godot_icall_EditorProgress_Step);
 
 
 	// ScriptClassParser
 	// ScriptClassParser
-	mono_add_internal_call("GodotTools.Internals.ScriptClassParser::internal_ParseFile", (void *)godot_icall_ScriptClassParser_ParseFile);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.ScriptClassParser::internal_ParseFile", godot_icall_ScriptClassParser_ParseFile);
 
 
 	// ExportPlugin
 	// ExportPlugin
-	mono_add_internal_call("GodotTools.Export.ExportPlugin::internal_GetExportedAssemblyDependencies", (void *)godot_icall_ExportPlugin_GetExportedAssemblyDependencies);
+	GDMonoUtils::add_internal_call("GodotTools.Export.ExportPlugin::internal_GetExportedAssemblyDependencies", godot_icall_ExportPlugin_GetExportedAssemblyDependencies);
 
 
 	// Internals
 	// Internals
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", (void *)godot_icall_Internal_UpdateApiAssembliesFromPrebuilt);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", (void *)godot_icall_Internal_FullTemplatesDir);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", (void *)godot_icall_Internal_SimplifyGodotPath);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", (void *)godot_icall_Internal_IsOsxAppBundleInstalled);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", (void *)godot_icall_Internal_GodotIs32Bits);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", (void *)godot_icall_Internal_GodotIsRealTDouble);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", (void *)godot_icall_Internal_GodotMainIteration);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_GetCoreApiHash", (void *)godot_icall_Internal_GetCoreApiHash);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_GetEditorApiHash", (void *)godot_icall_Internal_GetEditorApiHash);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_IsAssembliesReloadingNeeded", (void *)godot_icall_Internal_IsAssembliesReloadingNeeded);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_ReloadAssemblies", (void *)godot_icall_Internal_ReloadAssemblies);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorDebuggerNodeReloadScripts", (void *)godot_icall_Internal_EditorDebuggerNodeReloadScripts);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", (void *)godot_icall_Internal_ScriptEditorEdit);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", (void *)godot_icall_Internal_EditorNodeShowScriptScreen);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", (void *)godot_icall_Internal_GetScriptsMetadataOrNothing);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", (void *)godot_icall_Internal_MonoWindowsInstallRoot);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", (void *)godot_icall_Internal_EditorRunPlay);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", (void *)godot_icall_Internal_EditorRunStop);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", (void *)godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
-	mono_add_internal_call("GodotTools.Internals.Internal::internal_CodeCompletionRequest", (void *)godot_icall_Internal_CodeCompletionRequest);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_UpdateApiAssembliesFromPrebuilt", godot_icall_Internal_UpdateApiAssembliesFromPrebuilt);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_FullTemplatesDir", godot_icall_Internal_FullTemplatesDir);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_SimplifyGodotPath", godot_icall_Internal_SimplifyGodotPath);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsOsxAppBundleInstalled", godot_icall_Internal_IsOsxAppBundleInstalled);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIs32Bits", godot_icall_Internal_GodotIs32Bits);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotIsRealTDouble", godot_icall_Internal_GodotIsRealTDouble);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GodotMainIteration", godot_icall_Internal_GodotMainIteration);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GetCoreApiHash", godot_icall_Internal_GetCoreApiHash);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GetEditorApiHash", godot_icall_Internal_GetEditorApiHash);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_IsAssembliesReloadingNeeded", godot_icall_Internal_IsAssembliesReloadingNeeded);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_ReloadAssemblies", godot_icall_Internal_ReloadAssemblies);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorDebuggerNodeReloadScripts", godot_icall_Internal_EditorDebuggerNodeReloadScripts);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorEdit", godot_icall_Internal_ScriptEditorEdit);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorNodeShowScriptScreen", godot_icall_Internal_EditorNodeShowScriptScreen);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_GetScriptsMetadataOrNothing", godot_icall_Internal_GetScriptsMetadataOrNothing);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_MonoWindowsInstallRoot", godot_icall_Internal_MonoWindowsInstallRoot);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorRunPlay", godot_icall_Internal_EditorRunPlay);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_EditorRunStop", godot_icall_Internal_EditorRunStop);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_ScriptEditorDebugger_ReloadScripts", godot_icall_Internal_ScriptEditorDebugger_ReloadScripts);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Internal::internal_CodeCompletionRequest", godot_icall_Internal_CodeCompletionRequest);
 
 
 	// Globals
 	// Globals
-	mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", (void *)godot_icall_Globals_EditorScale);
-	mono_add_internal_call("GodotTools.Internals.Globals::internal_GlobalDef", (void *)godot_icall_Globals_GlobalDef);
-	mono_add_internal_call("GodotTools.Internals.Globals::internal_EditorDef", (void *)godot_icall_Globals_EditorDef);
-	mono_add_internal_call("GodotTools.Internals.Globals::internal_TTR", (void *)godot_icall_Globals_TTR);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_EditorScale", godot_icall_Globals_EditorScale);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_GlobalDef", godot_icall_Globals_GlobalDef);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_EditorDef", godot_icall_Globals_EditorDef);
+	GDMonoUtils::add_internal_call("GodotTools.Internals.Globals::internal_TTR", godot_icall_Globals_TTR);
 
 
 	// Utils.OS
 	// Utils.OS
-	mono_add_internal_call("GodotTools.Utils.OS::GetPlatformName", (void *)godot_icall_Utils_OS_GetPlatformName);
-	mono_add_internal_call("GodotTools.Utils.OS::UnixFileHasExecutableAccess", (void *)godot_icall_Utils_OS_UnixFileHasExecutableAccess);
+	GDMonoUtils::add_internal_call("GodotTools.Utils.OS::GetPlatformName", godot_icall_Utils_OS_GetPlatformName);
+	GDMonoUtils::add_internal_call("GodotTools.Utils.OS::UnixFileHasExecutableAccess", godot_icall_Utils_OS_UnixFileHasExecutableAccess);
 }
 }

+ 14 - 14
modules/mono/glue/base_object_glue.cpp

@@ -163,9 +163,9 @@ MonoObject *godot_icall_Object_weakref(Object *p_ptr) {
 	return GDMonoUtils::unmanaged_get_managed(wref.ptr());
 	return GDMonoUtils::unmanaged_get_managed(wref.ptr());
 }
 }
 
 
-Error godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter) {
+int32_t godot_icall_SignalAwaiter_connect(Object *p_source, StringName *p_signal, Object *p_target, MonoObject *p_awaiter) {
 	StringName signal = p_signal ? *p_signal : StringName();
 	StringName signal = p_signal ? *p_signal : StringName();
-	return gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
+	return (int32_t)gd_mono_connect_signal_awaiter(p_source, signal, p_target, p_awaiter);
 }
 }
 
 
 MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
 MonoArray *godot_icall_DynamicGodotObject_SetMemberList(Object *p_ptr) {
@@ -240,18 +240,18 @@ MonoString *godot_icall_Object_ToString(Object *p_ptr) {
 }
 }
 
 
 void godot_register_object_icalls() {
 void godot_register_object_icalls() {
-	mono_add_internal_call("Godot.Object::godot_icall_Object_Ctor", (void *)godot_icall_Object_Ctor);
-	mono_add_internal_call("Godot.Object::godot_icall_Object_Disposed", (void *)godot_icall_Object_Disposed);
-	mono_add_internal_call("Godot.Object::godot_icall_Reference_Disposed", (void *)godot_icall_Reference_Disposed);
-	mono_add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", (void *)godot_icall_Object_ConnectEventSignals);
-	mono_add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", (void *)godot_icall_Object_ClassDB_get_method);
-	mono_add_internal_call("Godot.Object::godot_icall_Object_ToString", (void *)godot_icall_Object_ToString);
-	mono_add_internal_call("Godot.Object::godot_icall_Object_weakref", (void *)godot_icall_Object_weakref);
-	mono_add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", (void *)godot_icall_SignalAwaiter_connect);
-	mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", (void *)godot_icall_DynamicGodotObject_SetMemberList);
-	mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", (void *)godot_icall_DynamicGodotObject_InvokeMember);
-	mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", (void *)godot_icall_DynamicGodotObject_GetMember);
-	mono_add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", (void *)godot_icall_DynamicGodotObject_SetMember);
+	GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Ctor", godot_icall_Object_Ctor);
+	GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_Disposed", godot_icall_Object_Disposed);
+	GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Reference_Disposed", godot_icall_Reference_Disposed);
+	GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ConnectEventSignals", godot_icall_Object_ConnectEventSignals);
+	GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ClassDB_get_method", godot_icall_Object_ClassDB_get_method);
+	GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_ToString", godot_icall_Object_ToString);
+	GDMonoUtils::add_internal_call("Godot.Object::godot_icall_Object_weakref", godot_icall_Object_weakref);
+	GDMonoUtils::add_internal_call("Godot.SignalAwaiter::godot_icall_SignalAwaiter_connect", godot_icall_SignalAwaiter_connect);
+	GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMemberList", godot_icall_DynamicGodotObject_SetMemberList);
+	GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_InvokeMember", godot_icall_DynamicGodotObject_InvokeMember);
+	GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_GetMember", godot_icall_DynamicGodotObject_GetMember);
+	GDMonoUtils::add_internal_call("Godot.DynamicGodotObject::godot_icall_DynamicGodotObject_SetMember", godot_icall_DynamicGodotObject_SetMember);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 53 - 53
modules/mono/glue/collections_glue.cpp

@@ -47,7 +47,7 @@ void godot_icall_Array_Dtor(Array *ptr) {
 	memdelete(ptr);
 	memdelete(ptr);
 }
 }
 
 
-MonoObject *godot_icall_Array_At(Array *ptr, int index) {
+MonoObject *godot_icall_Array_At(Array *ptr, int32_t index) {
 	if (index < 0 || index >= ptr->size()) {
 	if (index < 0 || index >= ptr->size()) {
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		return nullptr;
 		return nullptr;
@@ -55,7 +55,7 @@ MonoObject *godot_icall_Array_At(Array *ptr, int index) {
 	return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index));
 	return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index));
 }
 }
 
 
-MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_encoding, GDMonoClass *type_class) {
+MonoObject *godot_icall_Array_At_Generic(Array *ptr, int32_t index, uint32_t type_encoding, GDMonoClass *type_class) {
 	if (index < 0 || index >= ptr->size()) {
 	if (index < 0 || index >= ptr->size()) {
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		return nullptr;
 		return nullptr;
@@ -63,7 +63,7 @@ MonoObject *godot_icall_Array_At_Generic(Array *ptr, int index, uint32_t type_en
 	return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index), ManagedType(type_encoding, type_class));
 	return GDMonoMarshal::variant_to_mono_object(ptr->operator[](index), ManagedType(type_encoding, type_class));
 }
 }
 
 
-void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value) {
+void godot_icall_Array_SetAt(Array *ptr, int32_t index, MonoObject *value) {
 	if (index < 0 || index >= ptr->size()) {
 	if (index < 0 || index >= ptr->size()) {
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		return;
 		return;
@@ -71,11 +71,11 @@ void godot_icall_Array_SetAt(Array *ptr, int index, MonoObject *value) {
 	ptr->operator[](index) = GDMonoMarshal::mono_object_to_variant(value);
 	ptr->operator[](index) = GDMonoMarshal::mono_object_to_variant(value);
 }
 }
 
 
-int godot_icall_Array_Count(Array *ptr) {
+int32_t godot_icall_Array_Count(Array *ptr) {
 	return ptr->size();
 	return ptr->size();
 }
 }
 
 
-int godot_icall_Array_Add(Array *ptr, MonoObject *item) {
+int32_t godot_icall_Array_Add(Array *ptr, MonoObject *item) {
 	ptr->append(GDMonoMarshal::mono_object_to_variant(item));
 	ptr->append(GDMonoMarshal::mono_object_to_variant(item));
 	return ptr->size();
 	return ptr->size();
 }
 }
@@ -88,7 +88,7 @@ MonoBoolean godot_icall_Array_Contains(Array *ptr, MonoObject *item) {
 	return ptr->find(GDMonoMarshal::mono_object_to_variant(item)) != -1;
 	return ptr->find(GDMonoMarshal::mono_object_to_variant(item)) != -1;
 }
 }
 
 
-void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int array_index) {
+void godot_icall_Array_CopyTo(Array *ptr, MonoArray *array, int32_t array_index) {
 	unsigned int count = ptr->size();
 	unsigned int count = ptr->size();
 
 
 	if (mono_array_length(array) < (array_index + count)) {
 	if (mono_array_length(array) < (array_index + count)) {
@@ -129,11 +129,11 @@ Array *godot_icall_Array_Concatenate(Array *left, Array *right) {
 	return new_array;
 	return new_array;
 }
 }
 
 
-int godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
+int32_t godot_icall_Array_IndexOf(Array *ptr, MonoObject *item) {
 	return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
 	return ptr->find(GDMonoMarshal::mono_object_to_variant(item));
 }
 }
 
 
-void godot_icall_Array_Insert(Array *ptr, int index, MonoObject *item) {
+void godot_icall_Array_Insert(Array *ptr, int32_t index, MonoObject *item) {
 	if (index < 0 || index > ptr->size()) {
 	if (index < 0 || index > ptr->size()) {
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		return;
 		return;
@@ -150,7 +150,7 @@ MonoBoolean godot_icall_Array_Remove(Array *ptr, MonoObject *item) {
 	return false;
 	return false;
 }
 }
 
 
-void godot_icall_Array_RemoveAt(Array *ptr, int index) {
+void godot_icall_Array_RemoveAt(Array *ptr, int32_t index) {
 	if (index < 0 || index >= ptr->size()) {
 	if (index < 0 || index >= ptr->size()) {
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		GDMonoUtils::set_pending_exception(mono_get_exception_index_out_of_range());
 		return;
 		return;
@@ -158,8 +158,8 @@ void godot_icall_Array_RemoveAt(Array *ptr, int index) {
 	ptr->remove(index);
 	ptr->remove(index);
 }
 }
 
 
-Error godot_icall_Array_Resize(Array *ptr, int new_size) {
-	return ptr->resize(new_size);
+int32_t godot_icall_Array_Resize(Array *ptr, int32_t new_size) {
+	return (int32_t)ptr->resize(new_size);
 }
 }
 
 
 void godot_icall_Array_Shuffle(Array *ptr) {
 void godot_icall_Array_Shuffle(Array *ptr) {
@@ -226,7 +226,7 @@ Array *godot_icall_Dictionary_Values(Dictionary *ptr) {
 	return memnew(Array(ptr->values()));
 	return memnew(Array(ptr->values()));
 }
 }
 
 
-int godot_icall_Dictionary_Count(Dictionary *ptr) {
+int32_t godot_icall_Dictionary_Count(Dictionary *ptr) {
 	return ptr->size();
 	return ptr->size();
 }
 }
 
 
@@ -308,47 +308,47 @@ MonoString *godot_icall_Dictionary_ToString(Dictionary *ptr) {
 }
 }
 
 
 void godot_register_collections_icalls() {
 void godot_register_collections_icalls() {
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", (void *)godot_icall_Array_Ctor);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor_MonoArray", (void *)godot_icall_Array_Ctor_MonoArray);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Dtor", (void *)godot_icall_Array_Dtor);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At", (void *)godot_icall_Array_At);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_At_Generic", (void *)godot_icall_Array_At_Generic);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_SetAt", (void *)godot_icall_Array_SetAt);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", (void *)godot_icall_Array_Count);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", (void *)godot_icall_Array_Add);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", (void *)godot_icall_Array_Clear);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Concatenate", (void *)godot_icall_Array_Concatenate);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", (void *)godot_icall_Array_Contains);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", (void *)godot_icall_Array_CopyTo);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", (void *)godot_icall_Array_Duplicate);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_IndexOf", (void *)godot_icall_Array_IndexOf);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", (void *)godot_icall_Array_Insert);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", (void *)godot_icall_Array_Remove);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", (void *)godot_icall_Array_RemoveAt);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Resize", (void *)godot_icall_Array_Resize);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Shuffle", (void *)godot_icall_Array_Shuffle);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_Generic_GetElementTypeInfo", (void *)godot_icall_Array_Generic_GetElementTypeInfo);
-	mono_add_internal_call("Godot.Collections.Array::godot_icall_Array_ToString", (void *)godot_icall_Array_ToString);
-
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Ctor", (void *)godot_icall_Dictionary_Ctor);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Dtor", (void *)godot_icall_Dictionary_Dtor);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue", (void *)godot_icall_Dictionary_GetValue);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue_Generic", (void *)godot_icall_Dictionary_GetValue_Generic);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_SetValue", (void *)godot_icall_Dictionary_SetValue);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Keys", (void *)godot_icall_Dictionary_Keys);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", (void *)godot_icall_Dictionary_Values);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Count", (void *)godot_icall_Dictionary_Count);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Add", (void *)godot_icall_Dictionary_Add);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", (void *)godot_icall_Dictionary_Clear);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", (void *)godot_icall_Dictionary_Contains);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ContainsKey", (void *)godot_icall_Dictionary_ContainsKey);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Duplicate", (void *)godot_icall_Dictionary_Duplicate);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", (void *)godot_icall_Dictionary_RemoveKey);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", (void *)godot_icall_Dictionary_Remove);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", (void *)godot_icall_Dictionary_TryGetValue);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue_Generic", (void *)godot_icall_Dictionary_TryGetValue_Generic);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Generic_GetValueTypeInfo", (void *)godot_icall_Dictionary_Generic_GetValueTypeInfo);
-	mono_add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ToString", (void *)godot_icall_Dictionary_ToString);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor", godot_icall_Array_Ctor);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Ctor_MonoArray", godot_icall_Array_Ctor_MonoArray);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Dtor", godot_icall_Array_Dtor);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_At", godot_icall_Array_At);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_At_Generic", godot_icall_Array_At_Generic);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_SetAt", godot_icall_Array_SetAt);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Count", godot_icall_Array_Count);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Add", godot_icall_Array_Add);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Clear", godot_icall_Array_Clear);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Concatenate", godot_icall_Array_Concatenate);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Contains", godot_icall_Array_Contains);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_CopyTo", godot_icall_Array_CopyTo);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Duplicate", godot_icall_Array_Duplicate);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_IndexOf", godot_icall_Array_IndexOf);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Insert", godot_icall_Array_Insert);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Remove", godot_icall_Array_Remove);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_RemoveAt", godot_icall_Array_RemoveAt);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Resize", godot_icall_Array_Resize);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Shuffle", godot_icall_Array_Shuffle);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_Generic_GetElementTypeInfo", godot_icall_Array_Generic_GetElementTypeInfo);
+	GDMonoUtils::add_internal_call("Godot.Collections.Array::godot_icall_Array_ToString", godot_icall_Array_ToString);
+
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Ctor", godot_icall_Dictionary_Ctor);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Dtor", godot_icall_Dictionary_Dtor);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue", godot_icall_Dictionary_GetValue);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_GetValue_Generic", godot_icall_Dictionary_GetValue_Generic);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_SetValue", godot_icall_Dictionary_SetValue);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Keys", godot_icall_Dictionary_Keys);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Values", godot_icall_Dictionary_Values);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Count", godot_icall_Dictionary_Count);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Add", godot_icall_Dictionary_Add);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Clear", godot_icall_Dictionary_Clear);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Contains", godot_icall_Dictionary_Contains);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ContainsKey", godot_icall_Dictionary_ContainsKey);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Duplicate", godot_icall_Dictionary_Duplicate);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_RemoveKey", godot_icall_Dictionary_RemoveKey);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Remove", godot_icall_Dictionary_Remove);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue", godot_icall_Dictionary_TryGetValue);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_TryGetValue_Generic", godot_icall_Dictionary_TryGetValue_Generic);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_Generic_GetValueTypeInfo", godot_icall_Dictionary_Generic_GetValueTypeInfo);
+	GDMonoUtils::add_internal_call("Godot.Collections.Dictionary::godot_icall_Dictionary_ToString", godot_icall_Dictionary_ToString);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 25 - 25
modules/mono/glue/gd_glue.cpp

@@ -289,33 +289,33 @@ MonoObject *godot_icall_DefaultGodotTaskScheduler() {
 }
 }
 
 
 void godot_register_gd_icalls() {
 void godot_register_gd_icalls() {
-	mono_add_internal_call("Godot.GD::godot_icall_GD_bytes2var", (void *)godot_icall_GD_bytes2var);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_convert", (void *)godot_icall_GD_convert);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_hash", (void *)godot_icall_GD_hash);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_instance_from_id", (void *)godot_icall_GD_instance_from_id);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_pusherror", (void *)godot_icall_GD_pusherror);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_pushwarning", (void *)godot_icall_GD_pushwarning);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_print", (void *)godot_icall_GD_print);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_printerr", (void *)godot_icall_GD_printerr);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_printraw", (void *)godot_icall_GD_printraw);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_prints", (void *)godot_icall_GD_prints);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_printt", (void *)godot_icall_GD_printt);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_randf", (void *)godot_icall_GD_randf);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_randi", (void *)godot_icall_GD_randi);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_randomize", (void *)godot_icall_GD_randomize);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_randf_range", (void *)godot_icall_GD_randf_range);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_randi_range", (void *)godot_icall_GD_randi_range);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_rand_seed", (void *)godot_icall_GD_rand_seed);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_seed", (void *)godot_icall_GD_seed);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_str", (void *)godot_icall_GD_str);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_str2var", (void *)godot_icall_GD_str2var);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_type_exists", (void *)godot_icall_GD_type_exists);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_var2bytes", (void *)godot_icall_GD_var2bytes);
-	mono_add_internal_call("Godot.GD::godot_icall_GD_var2str", (void *)godot_icall_GD_var2str);
-	mono_add_internal_call("Godot.GD::godot_icall_TypeToVariantType", (void *)godot_icall_TypeToVariantType);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_bytes2var", godot_icall_GD_bytes2var);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_convert", godot_icall_GD_convert);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_hash", godot_icall_GD_hash);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_instance_from_id", godot_icall_GD_instance_from_id);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_pusherror", godot_icall_GD_pusherror);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_pushwarning", godot_icall_GD_pushwarning);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_print", godot_icall_GD_print);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printerr", godot_icall_GD_printerr);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printraw", godot_icall_GD_printraw);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_prints", godot_icall_GD_prints);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_printt", godot_icall_GD_printt);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf", godot_icall_GD_randf);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi", godot_icall_GD_randi);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randomize", godot_icall_GD_randomize);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randf_range", godot_icall_GD_randf_range);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_randi_range", godot_icall_GD_randi_range);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_rand_seed", godot_icall_GD_rand_seed);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_seed", godot_icall_GD_seed);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_str", godot_icall_GD_str);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_str2var", godot_icall_GD_str2var);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_type_exists", godot_icall_GD_type_exists);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_var2bytes", godot_icall_GD_var2bytes);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_GD_var2str", godot_icall_GD_var2str);
+	GDMonoUtils::add_internal_call("Godot.GD::godot_icall_TypeToVariantType", godot_icall_TypeToVariantType);
 
 
 	// Dispatcher
 	// Dispatcher
-	mono_add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", (void *)godot_icall_DefaultGodotTaskScheduler);
+	GDMonoUtils::add_internal_call("Godot.Dispatcher::godot_icall_DefaultGodotTaskScheduler", godot_icall_DefaultGodotTaskScheduler);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 11 - 11
modules/mono/glue/nodepath_glue.cpp

@@ -81,17 +81,17 @@ MonoBoolean godot_icall_NodePath_is_empty(NodePath *p_ptr) {
 }
 }
 
 
 void godot_register_nodepath_icalls() {
 void godot_register_nodepath_icalls() {
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_Ctor", (void *)godot_icall_NodePath_Ctor);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_Dtor", (void *)godot_icall_NodePath_Dtor);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_operator_String", (void *)godot_icall_NodePath_operator_String);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_as_property_path", (void *)godot_icall_NodePath_get_as_property_path);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_subnames", (void *)godot_icall_NodePath_get_concatenated_subnames);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name", (void *)godot_icall_NodePath_get_name);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name_count", (void *)godot_icall_NodePath_get_name_count);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname", (void *)godot_icall_NodePath_get_subname);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname_count", (void *)godot_icall_NodePath_get_subname_count);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_is_absolute", (void *)godot_icall_NodePath_is_absolute);
-	mono_add_internal_call("Godot.NodePath::godot_icall_NodePath_is_empty", (void *)godot_icall_NodePath_is_empty);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_Ctor", godot_icall_NodePath_Ctor);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_Dtor", godot_icall_NodePath_Dtor);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_operator_String", godot_icall_NodePath_operator_String);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_as_property_path", godot_icall_NodePath_get_as_property_path);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_concatenated_subnames", godot_icall_NodePath_get_concatenated_subnames);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name", godot_icall_NodePath_get_name);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_name_count", godot_icall_NodePath_get_name_count);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname", godot_icall_NodePath_get_subname);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_get_subname_count", godot_icall_NodePath_get_subname_count);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_is_absolute", godot_icall_NodePath_is_absolute);
+	GDMonoUtils::add_internal_call("Godot.NodePath::godot_icall_NodePath_is_empty", godot_icall_NodePath_is_empty);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 3 - 3
modules/mono/glue/rid_glue.cpp

@@ -56,9 +56,9 @@ uint32_t godot_icall_RID_get_id(RID *p_ptr) {
 }
 }
 
 
 void godot_register_rid_icalls() {
 void godot_register_rid_icalls() {
-	mono_add_internal_call("Godot.RID::godot_icall_RID_Ctor", (void *)godot_icall_RID_Ctor);
-	mono_add_internal_call("Godot.RID::godot_icall_RID_Dtor", (void *)godot_icall_RID_Dtor);
-	mono_add_internal_call("Godot.RID::godot_icall_RID_get_id", (void *)godot_icall_RID_get_id);
+	GDMonoUtils::add_internal_call("Godot.RID::godot_icall_RID_Ctor", godot_icall_RID_Ctor);
+	GDMonoUtils::add_internal_call("Godot.RID::godot_icall_RID_Dtor", godot_icall_RID_Dtor);
+	GDMonoUtils::add_internal_call("Godot.RID::godot_icall_RID_get_id", godot_icall_RID_get_id);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 1 - 1
modules/mono/glue/scene_tree_glue.cpp

@@ -80,7 +80,7 @@ Array *godot_icall_SceneTree_get_nodes_in_group_Generic(SceneTree *ptr, StringNa
 }
 }
 
 
 void godot_register_scene_tree_icalls() {
 void godot_register_scene_tree_icalls() {
-	mono_add_internal_call("Godot.SceneTree::godot_icall_SceneTree_get_nodes_in_group_Generic", (void *)godot_icall_SceneTree_get_nodes_in_group_Generic);
+	GDMonoUtils::add_internal_call("Godot.SceneTree::godot_icall_SceneTree_get_nodes_in_group_Generic", godot_icall_SceneTree_get_nodes_in_group_Generic);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 6 - 6
modules/mono/glue/string_glue.cpp

@@ -68,12 +68,12 @@ MonoString *godot_icall_String_sha256_text(MonoString *p_str) {
 }
 }
 
 
 void godot_register_string_icalls() {
 void godot_register_string_icalls() {
-	mono_add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", (void *)godot_icall_String_md5_buffer);
-	mono_add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", (void *)godot_icall_String_md5_text);
-	mono_add_internal_call("Godot.StringExtensions::godot_icall_String_rfind", (void *)godot_icall_String_rfind);
-	mono_add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", (void *)godot_icall_String_rfindn);
-	mono_add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", (void *)godot_icall_String_sha256_buffer);
-	mono_add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", (void *)godot_icall_String_sha256_text);
+	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_buffer", godot_icall_String_md5_buffer);
+	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_md5_text", godot_icall_String_md5_text);
+	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfind", godot_icall_String_rfind);
+	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_rfindn", godot_icall_String_rfindn);
+	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_buffer", godot_icall_String_sha256_buffer);
+	GDMonoUtils::add_internal_call("Godot.StringExtensions::godot_icall_String_sha256_text", godot_icall_String_sha256_text);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 4 - 4
modules/mono/glue/string_name_glue.cpp

@@ -53,10 +53,10 @@ MonoBoolean godot_icall_StringName_is_empty(StringName *p_ptr) {
 }
 }
 
 
 void godot_register_string_name_icalls() {
 void godot_register_string_name_icalls() {
-	mono_add_internal_call("Godot.StringName::godot_icall_StringName_Ctor", (void *)godot_icall_StringName_Ctor);
-	mono_add_internal_call("Godot.StringName::godot_icall_StringName_Dtor", (void *)godot_icall_StringName_Dtor);
-	mono_add_internal_call("Godot.StringName::godot_icall_StringName_operator_String", (void *)godot_icall_StringName_operator_String);
-	mono_add_internal_call("Godot.StringName::godot_icall_StringName_is_empty", (void *)godot_icall_StringName_is_empty);
+	GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_Ctor", godot_icall_StringName_Ctor);
+	GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_Dtor", godot_icall_StringName_Dtor);
+	GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_operator_String", godot_icall_StringName_operator_String);
+	GDMonoUtils::add_internal_call("Godot.StringName::godot_icall_StringName_is_empty", godot_icall_StringName_is_empty);
 }
 }
 
 
 #endif // MONO_GLUE_ENABLED
 #endif // MONO_GLUE_ENABLED

+ 19 - 0
modules/mono/mono_gd/gd_mono_utils.h

@@ -36,6 +36,9 @@
 #include "../mono_gc_handle.h"
 #include "../mono_gc_handle.h"
 #include "../utils/macros.h"
 #include "../utils/macros.h"
 #include "gd_mono_header.h"
 #include "gd_mono_header.h"
+#ifdef JAVASCRIPT_ENABLED
+#include "gd_mono_wasm_m2n.h"
+#endif
 
 
 #include "core/object/class_db.h"
 #include "core/object/class_db.h"
 #include "core/object/reference.h"
 #include "core/object/reference.h"
@@ -154,6 +157,22 @@ private:
 };
 };
 
 
 StringName get_native_godot_class_name(GDMonoClass *p_class);
 StringName get_native_godot_class_name(GDMonoClass *p_class);
+
+template <typename... P>
+void add_internal_call(const char *p_name, void (*p_func)(P...)) {
+#ifdef JAVASCRIPT_ENABLED
+	GDMonoWasmM2n::ICallTrampolines<P...>::add();
+#endif
+	mono_add_internal_call(p_name, (void *)p_func);
+}
+
+template <typename R, typename... P>
+void add_internal_call(const char *p_name, R (*p_func)(P...)) {
+#ifdef JAVASCRIPT_ENABLED
+	GDMonoWasmM2n::ICallTrampolinesR<R, P...>::add();
+#endif
+	mono_add_internal_call(p_name, (void *)p_func);
+}
 } // namespace GDMonoUtils
 } // namespace GDMonoUtils
 
 
 #define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoUtils::get_native_godot_class_name(m_class))
 #define NATIVE_GDMONOCLASS_NAME(m_class) (GDMonoUtils::get_native_godot_class_name(m_class))

+ 79 - 0
modules/mono/mono_gd/gd_mono_wasm_m2n.cpp

@@ -0,0 +1,79 @@
+/*************************************************************************/
+/*  gd_mono_wasm_m2n.cpp                                                 */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#include "gd_mono_wasm_m2n.h"
+
+#ifdef JAVASCRIPT_ENABLED
+
+#include "core/templates/oa_hash_map.h"
+
+typedef mono_bool (*GodotMonoM2nIcallTrampolineDispatch)(const char *cookie, void *target_func, Mono_InterpMethodArguments *margs);
+
+// This extern function is implemented in our patched version of Mono
+MONO_API void godot_mono_register_m2n_icall_trampoline_dispatch_hook(GodotMonoM2nIcallTrampolineDispatch hook);
+
+namespace GDMonoWasmM2n {
+
+struct HashMapCookieComparator {
+	static bool compare(const char *p_lhs, const char *p_rhs) {
+		return strcmp(p_lhs, p_rhs) == 0;
+	}
+};
+
+// The default hasher supports 'const char *' C Strings, but we need a custom comparator
+OAHashMap<const char *, TrampolineFunc, HashMapHasherDefault, HashMapCookieComparator> trampolines;
+
+void set_trampoline(const char *cookies, GDMonoWasmM2n::TrampolineFunc trampoline_func) {
+	trampolines.set(cookies, trampoline_func);
+}
+
+mono_bool trampoline_dispatch_hook(const char *cookie, void *target_func, Mono_InterpMethodArguments *margs) {
+	TrampolineFunc *trampoline_func = trampolines.lookup_ptr(cookie);
+
+	if (!trampoline_func) {
+		return false;
+	}
+
+	(*trampoline_func)(target_func, margs);
+	return true;
+}
+
+bool initialized = false;
+
+void lazy_initialize() {
+	// Doesn't need to be thread safe
+	if (!initialized) {
+		initialized = true;
+		godot_mono_register_m2n_icall_trampoline_dispatch_hook(&trampoline_dispatch_hook);
+	}
+}
+} // namespace GDMonoWasmM2n
+
+#endif

+ 263 - 0
modules/mono/mono_gd/gd_mono_wasm_m2n.h

@@ -0,0 +1,263 @@
+/*************************************************************************/
+/*  gd_mono_wasm_m2n.h                                                   */
+/*************************************************************************/
+/*                       This file is part of:                           */
+/*                           GODOT ENGINE                                */
+/*                      https://godotengine.org                          */
+/*************************************************************************/
+/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
+/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
+/*                                                                       */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the       */
+/* "Software"), to deal in the Software without restriction, including   */
+/* without limitation the rights to use, copy, modify, merge, publish,   */
+/* distribute, sublicense, and/or sell copies of the Software, and to    */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions:                                             */
+/*                                                                       */
+/* The above copyright notice and this permission notice shall be        */
+/* included in all copies or substantial portions of the Software.       */
+/*                                                                       */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
+/*************************************************************************/
+
+#ifndef GD_MONO_WASM_M2N_H
+#define GD_MONO_WASM_M2N_H
+
+#ifdef JAVASCRIPT_ENABLED
+
+#include "core/string/ustring.h"
+#include "core/typedefs.h"
+
+#include <mono/metadata/loader.h>
+#include <mono/utils/mono-publib.h>
+#include <stdexcept>
+#include <type_traits>
+
+extern "C" {
+
+struct Mono_InterpMethodArguments {
+	size_t ilen;
+	void **iargs;
+	size_t flen;
+	double *fargs;
+	void **retval;
+	size_t is_float_ret;
+	//#ifdef TARGET_WASM
+	void *sig;
+	//#endif
+};
+} // extern "C"
+
+namespace GDMonoWasmM2n {
+
+template <typename T, size_t Size>
+struct array {
+	T elems[Size];
+};
+
+template <typename T>
+constexpr char get_m2n_cookie_impl() {
+#define M2N_REG_COOKIE(m_type, m_cookie)       \
+	if constexpr (std::is_same_v<m_type, T>) { \
+		return m_cookie;                       \
+	}
+
+	M2N_REG_COOKIE(MonoBoolean, 'I');
+	M2N_REG_COOKIE(int8_t, 'I');
+	M2N_REG_COOKIE(uint8_t, 'I');
+	M2N_REG_COOKIE(int16_t, 'I');
+	M2N_REG_COOKIE(uint16_t, 'I');
+	M2N_REG_COOKIE(int32_t, 'I');
+	M2N_REG_COOKIE(uint32_t, 'I');
+	M2N_REG_COOKIE(int64_t, 'L');
+	M2N_REG_COOKIE(uint64_t, 'L');
+	M2N_REG_COOKIE(float, 'F');
+	M2N_REG_COOKIE(double, 'D');
+
+	if constexpr (std::is_pointer_v<T>) {
+		if constexpr (sizeof(void *) == 4) {
+			return 'I';
+		} else {
+			return 'L';
+		}
+	}
+
+	if constexpr (std::is_void_v<T>) {
+		return 'V';
+	}
+
+	return 'X';
+
+#undef M2N_REG_COOKIE
+}
+
+template <typename T>
+constexpr char get_m2n_cookie() {
+	constexpr char cookie = get_m2n_cookie_impl<T>();
+	static_assert(cookie != 'X', "Type not supported in internal call signature.");
+	return cookie;
+}
+
+template <typename... T>
+constexpr array<const char, sizeof...(T) + 2> get_m2n_cookies() {
+	return array<const char, sizeof...(T) + 2>{ 'V', get_m2n_cookie<T>()..., '\0' };
+}
+
+template <typename R, typename... T>
+constexpr array<const char, sizeof...(T) + 2> get_m2n_cookies_r() {
+	return array<const char, sizeof...(T) + 2>{ get_m2n_cookie<R>(), get_m2n_cookie<T>()..., '\0' };
+}
+
+template <typename T>
+constexpr size_t calc_m2n_index(size_t &r_int_idx, size_t &r_float_idx) {
+	constexpr char cookie = get_m2n_cookie<T>();
+
+	static_assert(cookie == 'I' || cookie == 'L' || cookie == 'F' || cookie == 'D');
+
+	if constexpr (cookie == 'I' || cookie == 'L') {
+		size_t ret = r_int_idx;
+		r_int_idx += cookie == 'I' ? 1 : 2;
+		return ret;
+	} else {
+		size_t ret = r_float_idx;
+		r_float_idx += cookie == 'F' ? 1 : 2;
+		return ret;
+	}
+}
+
+template <typename... P>
+constexpr array<size_t, sizeof...(P)> get_indices_for_type() {
+	size_t int_idx = 0;
+	size_t float_idx = 0;
+	return array<size_t, sizeof...(P)>{ calc_m2n_index<P>(int_idx, float_idx)... };
+}
+
+constexpr size_t fidx(size_t p_x) {
+	if constexpr (sizeof(void *) == 4) {
+		return p_x * 2;
+	} else {
+		return p_x;
+	}
+}
+
+template <typename T>
+T m2n_arg_cast(Mono_InterpMethodArguments *p_margs, size_t p_idx) {
+	constexpr char cookie = get_m2n_cookie<T>();
+
+	static_assert(cookie == 'I' || cookie == 'L' || cookie == 'F' || cookie == 'D');
+
+	if constexpr (cookie == 'I') {
+		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>),
+				"Invalid type for cookie 'L'.");
+
+		union {
+			T l;
+			struct {
+				int32_t lo;
+				int32_t hi;
+			} pair;
+		} p;
+
+		p.pair.lo = (int32_t)(size_t)p_margs->iargs[p_idx];
+		p.pair.hi = (int32_t)(size_t)p_margs->iargs[p_idx + 1];
+
+		return p.l;
+	} else if constexpr (cookie == 'F') {
+		return *reinterpret_cast<float *>(&p_margs->fargs[fidx(p_idx)]);
+	} else if constexpr (cookie == 'D') {
+		return (T)(size_t)p_margs->fargs[p_idx];
+	}
+}
+
+template <typename... P, size_t... Is>
+void m2n_trampoline_with_idx_seq(void *p_target_func, Mono_InterpMethodArguments *p_margs, IndexSequence<Is...>) {
+	constexpr array<size_t, sizeof...(P)> indices = get_indices_for_type<P...>();
+	typedef void (*Func)(P...);
+	Func func = (Func)p_target_func;
+	func(m2n_arg_cast<P>(p_margs, indices.elems[Is])...);
+}
+
+template <typename R, typename... P, size_t... Is>
+void m2n_trampoline_with_idx_seq_r(void *p_target_func, Mono_InterpMethodArguments *p_margs, IndexSequence<Is...>) {
+	constexpr array<size_t, sizeof...(P)> indices = get_indices_for_type<P...>();
+	typedef R (*Func)(P...);
+	Func func = (Func)p_target_func;
+	R res = func(m2n_arg_cast<P>(p_margs, indices.elems[Is])...);
+	*reinterpret_cast<R *>(p_margs->retval) = res;
+}
+
+inline void m2n_trampoline_with_idx_seq_0(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+	typedef void (*Func)();
+	Func func = (Func)p_target_func;
+	func();
+}
+
+template <typename R>
+void m2n_trampoline_with_idx_seq_r0(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+	typedef R (*Func)();
+	Func func = (Func)p_target_func;
+	R res = func();
+	*reinterpret_cast<R *>(p_margs->retval) = res;
+}
+
+template <typename... P>
+void m2n_trampoline(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+	if constexpr (sizeof...(P) == 0) {
+		m2n_trampoline_with_idx_seq_0(p_target_func, p_margs);
+	} else {
+		m2n_trampoline_with_idx_seq<P...>(p_target_func, p_margs, BuildIndexSequence<sizeof...(P)>{});
+	}
+}
+
+template <typename R, typename... P>
+void m2n_trampoline_r(void *p_target_func, Mono_InterpMethodArguments *p_margs) {
+	if constexpr (sizeof...(P) == 0) {
+		m2n_trampoline_with_idx_seq_r0<R>(p_target_func, p_margs);
+	} else {
+		m2n_trampoline_with_idx_seq_r<R, P...>(p_target_func, p_margs, BuildIndexSequence<sizeof...(P)>{});
+	}
+}
+
+typedef void (*TrampolineFunc)(void *p_target_func, Mono_InterpMethodArguments *p_margs);
+
+void set_trampoline(const char *cookies, TrampolineFunc trampoline_func);
+
+void lazy_initialize();
+
+template <typename... P>
+struct ICallTrampolines {
+	static constexpr auto cookies = get_m2n_cookies<P...>();
+
+	static void add() {
+		lazy_initialize();
+		set_trampoline(cookies.elems, &m2n_trampoline<P...>);
+	}
+};
+
+template <typename R, typename... P>
+struct ICallTrampolinesR {
+	static constexpr auto cookies = get_m2n_cookies_r<R, P...>();
+
+	static void add() {
+		lazy_initialize();
+		set_trampoline(cookies.elems, &m2n_trampoline_r<R, P...>);
+	}
+};
+
+void initialize();
+} // namespace GDMonoWasmM2n
+
+#endif
+
+#endif // GD_MONO_WASM_M2N_H

+ 2 - 2
modules/mono/mono_gd/support/android_support.cpp

@@ -355,8 +355,8 @@ MonoArray *_gd_mono_android_cert_store_lookup(MonoString *p_alias) {
 }
 }
 
 
 void register_internal_calls() {
 void register_internal_calls() {
-	mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_init_cert_store", (void *)_gd_mono_init_cert_store);
-	mono_add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_android_cert_store_lookup", (void *)_gd_mono_android_cert_store_lookup);
+	GDMonoUtils::add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_init_cert_store", _gd_mono_init_cert_store);
+	GDMonoUtils::add_internal_call("Android.Runtime.AndroidEnvironment::_gd_mono_android_cert_store_lookup", _gd_mono_android_cert_store_lookup);
 }
 }
 
 
 void initialize() {
 void initialize() {