summaryrefslogtreecommitdiff
path: root/Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h
diff options
context:
space:
mode:
authorchai <chaifix@163.com>2019-08-14 22:50:43 +0800
committerchai <chaifix@163.com>2019-08-14 22:50:43 +0800
commit15740faf9fe9fe4be08965098bbf2947e096aeeb (patch)
treea730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h
+Unity Runtime codeHEADmaster
Diffstat (limited to 'Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h')
-rw-r--r--Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h83
1 files changed, 83 insertions, 0 deletions
diff --git a/Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h b/Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h
new file mode 100644
index 0000000..a7519f8
--- /dev/null
+++ b/Runtime/Scripting/Backend/Mono/ScriptingMethodFactory_Mono.h
@@ -0,0 +1,83 @@
+#ifndef _SCRIPTINGMETHODFACTORY_MONO_
+#define _SCRIPTINGMETHODFACTORY_MONO_
+
+#include "../ScriptingMethodFactory.h"
+#include "Runtime/Mono/MonoIncludes.h"
+#include "../ScriptingMethodRegistry.h"
+#if ENABLE_MONO
+
+
+// Flag defined in mono, when AOT libraries are built with -ficall option
+// But that is not available in mono/consoles
+extern "C" int mono_ficall_flag;
+
+FastMonoMethod FastMonoMethodPtrFor(MonoMethod* method)
+{
+#if USE_MONO_AOT && !(UNITY_XENON || UNITY_PS3)
+ return mono_ficall_flag && method ? (FastMonoMethod) mono_aot_get_method(mono_domain_get(), method) : NULL;
+#else
+ return NULL;
+#endif
+}
+
+static bool MethodMatchesSearchFilter(MonoMethod* method, int searchFilter)
+{
+ MonoMethodSignature* sig = mono_method_signature(method);
+ return MethodDescriptionMatchesSearchFilter(searchFilter, mono_signature_is_instance(sig), mono_signature_get_param_count(sig));
+}
+
+class ScriptingMethodFactory_Mono : public IScriptingMethodFactory
+{
+public:
+ virtual ScriptingMethodPtr Produce(ScriptingTypePtr klass, const char* name, int searchFilter)
+ {
+ void* iterator = NULL;
+ while (MonoMethod* method = mono_class_get_methods(klass, &iterator))
+ {
+ if (!method)
+ return NULL;
+
+ if (strcmp(mono_method_get_name(method), name)!=0)
+ continue;
+
+ if (MethodMatchesSearchFilter(method,searchFilter))
+ return Produce(method);
+ }
+ return NULL;
+ }
+
+ virtual ScriptingMethodPtr Produce(BackendNativeMethod nativeMethod)
+ {
+ ScriptingMethodPtr result = new ScriptingMethod();
+ result->monoMethod = nativeMethod;
+ MonoMethodSignature* sig = mono_method_signature(nativeMethod);
+#if UNITY_EDITOR
+ if (!sig) {
+ // Loader error - usually missing reference
+ Scripting::LogException(mono_loader_error_prepare_exception (mono_loader_get_last_error ()), 0);
+ return NULL;
+ }
+#endif
+ result->isInstance = mono_signature_is_instance(sig);
+ result->fastMonoMethod = IsSignatureSupportedForFastAotCalls(sig) ? FastMonoMethodPtrFor(nativeMethod) : NULL;
+ return result;
+ }
+
+ virtual void Release(ScriptingMethodPtr method)
+ {
+ delete method;
+ }
+
+private:
+ bool IsSignatureSupportedForFastAotCalls(MonoMethodSignature* sig)
+ {
+ if (!mono_signature_is_instance(sig))
+ return false;
+
+ return mono_signature_get_param_count(sig) == 0;
+ }
+};
+
+#endif
+
+#endif