BsMonoMethod.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "BsMonoMethod.h"
  4. #include "BsMonoManager.h"
  5. #include "BsMonoUtil.h"
  6. #include "BsMonoClass.h"
  7. namespace BansheeEngine
  8. {
  9. MonoMethod::MonoMethod(::MonoMethod* method)
  10. :mMethod(method), mCachedReturnType(nullptr), mCachedParameters(nullptr),
  11. mCachedNumParameters(0), mIsStatic(false), mHasCachedSignature(false)
  12. {
  13. }
  14. MonoMethod::~MonoMethod()
  15. {
  16. if (mCachedParameters != nullptr)
  17. bs_free(mCachedParameters);
  18. }
  19. MonoObject* MonoMethod::invoke(MonoObject* instance, void** params)
  20. {
  21. MonoObject* exception = nullptr;
  22. MonoObject* retVal = mono_runtime_invoke(mMethod, instance, params, &exception);
  23. MonoUtil::throwIfException(exception);
  24. return retVal;
  25. }
  26. MonoObject* MonoMethod::invokeVirtual(MonoObject* instance, void** params)
  27. {
  28. ::MonoMethod* virtualMethod = mono_object_get_virtual_method(instance, mMethod);
  29. MonoObject* exception = nullptr;
  30. MonoObject* retVal = mono_runtime_invoke(virtualMethod, instance, params, &exception);
  31. MonoUtil::throwIfException(exception);
  32. return retVal;
  33. }
  34. void* MonoMethod::getThunk() const
  35. {
  36. return mono_method_get_unmanaged_thunk(mMethod);
  37. }
  38. String MonoMethod::getName() const
  39. {
  40. return String(mono_method_get_name(mMethod));
  41. }
  42. MonoClass* MonoMethod::getReturnType() const
  43. {
  44. if (!mHasCachedSignature)
  45. cacheSignature();
  46. return mCachedReturnType;
  47. }
  48. UINT32 MonoMethod::getNumParameters() const
  49. {
  50. if (!mHasCachedSignature)
  51. cacheSignature();
  52. return mCachedNumParameters;
  53. }
  54. MonoClass* MonoMethod::getParameterType(UINT32 paramIdx) const
  55. {
  56. if (!mHasCachedSignature)
  57. cacheSignature();
  58. if (paramIdx >= mCachedNumParameters)
  59. BS_EXCEPT(InvalidParametersException, "Parameter index out of range. Valid range is [0, " + toString(mCachedNumParameters - 1) + "]");
  60. return mCachedParameters[paramIdx];
  61. }
  62. bool MonoMethod::isStatic() const
  63. {
  64. if (!mHasCachedSignature)
  65. cacheSignature();
  66. return mIsStatic;
  67. }
  68. bool MonoMethod::hasAttribute(MonoClass* monoClass) const
  69. {
  70. // TODO - Consider caching custom attributes or just initializing them all at load
  71. MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(mMethod);
  72. if (attrInfo == nullptr)
  73. return false;
  74. bool hasAttr = mono_custom_attrs_has_attr(attrInfo, monoClass->_getInternalClass()) != 0;
  75. mono_custom_attrs_free(attrInfo);
  76. return hasAttr;
  77. }
  78. MonoObject* MonoMethod::getAttribute(MonoClass* monoClass) const
  79. {
  80. // TODO - Consider caching custom attributes or just initializing them all at load
  81. MonoCustomAttrInfo* attrInfo = mono_custom_attrs_from_method(mMethod);
  82. if (attrInfo == nullptr)
  83. return nullptr;
  84. MonoObject* foundAttr = mono_custom_attrs_get_attr(attrInfo, monoClass->_getInternalClass());
  85. mono_custom_attrs_free(attrInfo);
  86. return foundAttr;
  87. }
  88. void MonoMethod::cacheSignature() const
  89. {
  90. MonoMethodSignature* methodSignature = mono_method_signature(mMethod);
  91. MonoType* returnType = mono_signature_get_return_type(methodSignature);
  92. if (returnType != nullptr)
  93. {
  94. ::MonoClass* returnClass = mono_class_from_mono_type(returnType);
  95. if (returnClass != nullptr)
  96. mCachedReturnType = MonoManager::instance().findClass(returnClass);
  97. }
  98. mCachedNumParameters = (UINT32)mono_signature_get_param_count(methodSignature);
  99. if (mCachedParameters != nullptr)
  100. {
  101. bs_free(mCachedParameters);
  102. mCachedParameters = nullptr;
  103. }
  104. if (mCachedNumParameters > 0)
  105. {
  106. mCachedParameters = (MonoClass**)bs_alloc(mCachedNumParameters * sizeof(MonoClass*));
  107. void* iter = nullptr;
  108. for (UINT32 i = 0; i < mCachedNumParameters; i++)
  109. {
  110. MonoType* curParamType = mono_signature_get_params(methodSignature, &iter);
  111. ::MonoClass* rawClass = mono_class_from_mono_type(curParamType);
  112. mCachedParameters[i] = MonoManager::instance().findClass(rawClass);
  113. }
  114. }
  115. mIsStatic = !mono_signature_is_instance(methodSignature);
  116. mHasCachedSignature = true;
  117. }
  118. }