InterpreterModule.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605
  1. #include "InterpreterModule.h"
  2. #include "Interpreter.h"
  3. #include <unordered_map>
  4. #include "Baselib.h"
  5. #include "vm/GlobalMetadata.h"
  6. #include "vm/MetadataCache.h"
  7. #include "vm/MetadataLock.h"
  8. #include "vm/Class.h"
  9. #include "vm/Object.h"
  10. #include "vm/Method.h"
  11. #include "../metadata/MetadataModule.h"
  12. #include "../metadata/MetadataUtil.h"
  13. #include "../metadata/InterpreterImage.h"
  14. #include "../transform/Transform.h"
  15. #include "MethodBridge.h"
  16. #include "InterpreterUtil.h"
  17. namespace hybridclr
  18. {
  19. namespace interpreter
  20. {
  21. il2cpp::os::ThreadLocalValue InterpreterModule::s_machineState;
  22. static Il2CppHashMap<const char*, Managed2NativeCallMethod, CStringHash, CStringEqualTo> s_managed2natives;
  23. static Il2CppHashMap<const char*, Il2CppMethodPointer, CStringHash, CStringEqualTo> s_native2manageds;
  24. static Il2CppHashMap<const char*, Il2CppMethodPointer, CStringHash, CStringEqualTo> s_adjustThunks;
  25. static Il2CppHashMap<const char*, const char*, CStringHash, CStringEqualTo> s_fullName2signature;
  26. static Il2CppHashMap<const MethodInfo*, const ReversePInvokeInfo*, il2cpp::utils::PointerHash<MethodInfo>> s_methodInfo2ReverseInfos;
  27. static Il2CppHashMap<Il2CppMethodPointer, const ReversePInvokeInfo*, il2cpp::utils::PassThroughHash<Il2CppMethodPointer>> s_methodPointer2ReverseInfos;
  28. static Il2CppHashMap<const char*, int32_t, CStringHash, CStringEqualTo> s_methodSig2Indexs;
  29. static std::vector<ReversePInvokeInfo> s_reverseInfos;
  30. static baselib::ReentrantLock s_reversePInvokeMethodLock;
  31. const MethodInfo* InterpreterModule::GetMethodInfoByReversePInvokeWrapperIndex(int32_t index)
  32. {
  33. return s_reverseInfos[index].methodInfo;
  34. }
  35. const MethodInfo* InterpreterModule::GetMethodInfoByReversePInvokeWrapperMethodPointer(Il2CppMethodPointer methodPointer)
  36. {
  37. auto it = s_methodPointer2ReverseInfos.find(methodPointer);
  38. return it != s_methodPointer2ReverseInfos.end() ? it->second->methodInfo : nullptr;
  39. }
  40. int32_t InterpreterModule::GetWrapperIndexByReversePInvokeWrapperMethodPointer(Il2CppMethodPointer methodPointer)
  41. {
  42. auto it = s_methodPointer2ReverseInfos.find(methodPointer);
  43. return it != s_methodPointer2ReverseInfos.end() ? it->second->index : -1;
  44. }
  45. static void InitReversePInvokeInfo()
  46. {
  47. for (int32_t i = 0; ; i++)
  48. {
  49. const ReversePInvokeMethodData& data = g_reversePInvokeMethodStub[i];
  50. if (data.methodPointer == nullptr)
  51. {
  52. break;
  53. }
  54. s_reverseInfos.push_back({ i, data.methodPointer, nullptr });
  55. auto it = s_methodSig2Indexs.find(data.methodSig);
  56. if (it == s_methodSig2Indexs.end())
  57. {
  58. s_methodSig2Indexs.insert({ data.methodSig, i });
  59. }
  60. }
  61. s_methodInfo2ReverseInfos.resize(s_reverseInfos.size() * 2);
  62. s_methodPointer2ReverseInfos.resize(s_reverseInfos.size() * 2);
  63. for (ReversePInvokeInfo& rpi : s_reverseInfos)
  64. {
  65. s_methodPointer2ReverseInfos.insert({ rpi.methodPointer, &rpi });
  66. }
  67. }
  68. Il2CppMethodPointer InterpreterModule::GetReversePInvokeWrapper(const Il2CppImage* image, const MethodInfo* method, Il2CppCallConvention callConvention)
  69. {
  70. if (!hybridclr::metadata::IsStaticMethod(method))
  71. {
  72. return nullptr;
  73. }
  74. {
  75. il2cpp::os::FastAutoLock lock(&s_reversePInvokeMethodLock);
  76. auto it = s_methodInfo2ReverseInfos.find(method);
  77. if (it != s_methodInfo2ReverseInfos.end())
  78. {
  79. return it->second->methodPointer;
  80. }
  81. }
  82. char sigName[1000];
  83. sigName[0] = 'A' + callConvention;
  84. ComputeSignature(method, false, sigName + 1, sizeof(sigName) - 2);
  85. il2cpp::os::FastAutoLock lock(&s_reversePInvokeMethodLock);
  86. auto it = s_methodInfo2ReverseInfos.find(method);
  87. if (it != s_methodInfo2ReverseInfos.end())
  88. {
  89. return it->second->methodPointer;
  90. }
  91. auto it2 = s_methodSig2Indexs.find(sigName);
  92. if (it2 == s_methodSig2Indexs.end())
  93. {
  94. TEMP_FORMAT(methodSigBuf, "GetReversePInvokeWrapper fail. not find wrapper of method:%s", GetMethodNameWithSignature(method).c_str());
  95. RaiseExecutionEngineException(methodSigBuf);
  96. }
  97. int32_t wrapperIndex = it2->second;
  98. const ReversePInvokeMethodData& data = g_reversePInvokeMethodStub[wrapperIndex];
  99. if (data.methodPointer == nullptr || std::strcmp(data.methodSig, sigName))
  100. {
  101. TEMP_FORMAT(methodSigBuf, "GetReversePInvokeWrapper fail. exceed max wrapper num of method:%s", GetMethodNameWithSignature(method).c_str());
  102. RaiseExecutionEngineException(methodSigBuf);
  103. }
  104. s_methodSig2Indexs[sigName] = wrapperIndex + 1;
  105. ReversePInvokeInfo& rpi = s_reverseInfos[wrapperIndex];
  106. rpi.methodInfo = method;
  107. s_methodInfo2ReverseInfos.insert({ method, &rpi });
  108. return rpi.methodPointer;
  109. }
  110. static void InitMethodBridge()
  111. {
  112. for (size_t i = 0; ; i++)
  113. {
  114. const Managed2NativeMethodInfo& method = g_managed2nativeStub[i];
  115. if (!method.signature)
  116. {
  117. break;
  118. }
  119. s_managed2natives.insert({ method.signature, method.method });
  120. }
  121. for (size_t i = 0; ; i++)
  122. {
  123. const Native2ManagedMethodInfo& method = g_native2managedStub[i];
  124. if (!method.signature)
  125. {
  126. break;
  127. }
  128. s_native2manageds.insert({ method.signature, method.method });
  129. }
  130. for (size_t i = 0; ; i++)
  131. {
  132. const NativeAdjustThunkMethodInfo& method = g_adjustThunkStub[i];
  133. if (!method.signature)
  134. {
  135. break;
  136. }
  137. s_adjustThunks.insert({ method.signature, method.method });
  138. }
  139. for (size_t i = 0; ; i++)
  140. {
  141. const FullName2Signature& nameSig = g_fullName2SignatureStub[i];
  142. if (!nameSig.fullName)
  143. {
  144. break;
  145. }
  146. s_fullName2signature.insert({ nameSig.fullName, nameSig.signature });
  147. }
  148. }
  149. void InterpreterModule::Initialize()
  150. {
  151. InitMethodBridge();
  152. InitReversePInvokeInfo();
  153. }
  154. void InterpreterModule::NotSupportNative2Managed()
  155. {
  156. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetExecutionEngineException("NotSupportNative2Managed"));
  157. }
  158. void InterpreterModule::NotSupportAdjustorThunk()
  159. {
  160. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetExecutionEngineException("NotSupportAdjustorThunk"));
  161. }
  162. const char* InterpreterModule::GetValueTypeSignature(const char* fullName)
  163. {
  164. auto it = s_fullName2signature.find(fullName);
  165. return it != s_fullName2signature.end() ? it->second : "$";
  166. }
  167. static void* NotSupportInvoke(Il2CppMethodPointer, const MethodInfo* method, void*, void**)
  168. {
  169. char sigName[1000];
  170. ComputeSignature(method, true, sigName, sizeof(sigName) - 1);
  171. TEMP_FORMAT(errMsg, "Invoke method missing. sinature:%s %s.%s::%s", sigName, method->klass->namespaze, method->klass->name, method->name);
  172. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetExecutionEngineException(errMsg));
  173. return nullptr;
  174. }
  175. template<typename T>
  176. const Managed2NativeCallMethod GetManaged2NativeMethod(const T* method, bool forceStatic)
  177. {
  178. char sigName[1000];
  179. ComputeSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);
  180. auto it = s_managed2natives.find(sigName);
  181. return it != s_managed2natives.end() ? it->second : nullptr;
  182. }
  183. template<typename T>
  184. const Il2CppMethodPointer GetNative2ManagedMethod(const T* method, bool forceStatic)
  185. {
  186. char sigName[1000];
  187. ComputeSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);
  188. auto it = s_native2manageds.find(sigName);
  189. return it != s_native2manageds.end() ? it->second : InterpreterModule::NotSupportNative2Managed;
  190. }
  191. template<typename T>
  192. const Il2CppMethodPointer GetNativeAdjustMethodMethod(const T* method, bool forceStatic)
  193. {
  194. char sigName[1000];
  195. ComputeSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);
  196. auto it = s_adjustThunks.find(sigName);
  197. return it != s_adjustThunks.end() ? it->second : InterpreterModule::NotSupportAdjustorThunk;
  198. }
  199. static void RaiseMethodNotSupportException(const MethodInfo* method, const char* desc)
  200. {
  201. TEMP_FORMAT(errMsg, "%s. %s.%s::%s", desc, method->klass->namespaze, method->klass->name, method->name);
  202. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetExecutionEngineException(errMsg));
  203. }
  204. static void RaiseMethodNotSupportException(const Il2CppMethodDefinition* method, const char* desc)
  205. {
  206. Il2CppClass* klass = il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeDefinitionIndex(method->declaringType);
  207. TEMP_FORMAT(errMsg, "%s. %s.%s::%s", desc, klass->namespaze, klass->name, il2cpp::vm::GlobalMetadata::GetStringFromIndex(method->nameIndex));
  208. il2cpp::vm::Exception::Raise(il2cpp::vm::Exception::GetExecutionEngineException(errMsg));
  209. }
  210. Il2CppMethodPointer InterpreterModule::GetMethodPointer(const Il2CppMethodDefinition* method)
  211. {
  212. Il2CppMethodPointer ncm = GetNative2ManagedMethod(method, false);
  213. return ncm ? ncm : (Il2CppMethodPointer)NotSupportNative2Managed;
  214. }
  215. Il2CppMethodPointer InterpreterModule::GetMethodPointer(const MethodInfo* method)
  216. {
  217. Il2CppMethodPointer ncm = GetNative2ManagedMethod(method, false);
  218. return ncm ? ncm : (Il2CppMethodPointer)NotSupportNative2Managed;
  219. }
  220. Il2CppMethodPointer InterpreterModule::GetAdjustThunkMethodPointer(const Il2CppMethodDefinition* method)
  221. {
  222. return GetNativeAdjustMethodMethod(method, false);
  223. }
  224. Il2CppMethodPointer InterpreterModule::GetAdjustThunkMethodPointer(const MethodInfo* method)
  225. {
  226. return GetNativeAdjustMethodMethod(method, false);
  227. }
  228. void InterpreterModule::Managed2NativeCallByReflectionInvoke(const MethodInfo* method, uint16_t* argVarIndexs, StackObject* localVarBase, void* ret)
  229. {
  230. if (hybridclr::metadata::IsInterpreterImplement(method))
  231. {
  232. Interpreter::Execute(method, localVarBase + argVarIndexs[0], ret);
  233. return;
  234. }
  235. if (method->invoker_method == nullptr)
  236. {
  237. char sigName[1000];
  238. ComputeSignature(method, true, sigName, sizeof(sigName) - 1);
  239. TEMP_FORMAT(errMsg, "GetManaged2NativeMethodPointer. sinature:%s not support.", sigName);
  240. RaiseMethodNotSupportException(method, errMsg);
  241. }
  242. if (!InitAndGetInterpreterDirectlyCallMethodPointer(method))
  243. {
  244. RaiseAOTGenericMethodNotInstantiatedException(method);
  245. }
  246. void* thisPtr;
  247. uint16_t* argVarIndexBase;
  248. if (hybridclr::metadata::IsInstanceMethod(method))
  249. {
  250. thisPtr = localVarBase[argVarIndexs[0]].obj;
  251. argVarIndexBase = argVarIndexs + 1;
  252. }
  253. else
  254. {
  255. thisPtr = nullptr;
  256. argVarIndexBase = argVarIndexs;
  257. }
  258. void* invokeParams[256];
  259. for (uint8_t i = 0; i < method->parameters_count; i++)
  260. {
  261. const Il2CppType* argType = GET_METHOD_PARAMETER_TYPE(method->parameters[i]);
  262. StackObject* argValue = localVarBase + argVarIndexBase[i];
  263. if (!argType->byref && hybridclr::metadata::IsValueType(argType))
  264. {
  265. invokeParams[i] = argValue;
  266. }
  267. else
  268. {
  269. invokeParams[i] = argValue->ptr;
  270. }
  271. }
  272. #if HYBRIDCLR_UNITY_2021_OR_NEW
  273. method->invoker_method(method->methodPointerCallByInterp, method, thisPtr, invokeParams, ret);
  274. #else
  275. void* retObj = method->invoker_method(method->methodPointerCallByInterp, method, thisPtr, invokeParams);
  276. if (ret)
  277. {
  278. const Il2CppType* returnType = method->return_type;
  279. if (hybridclr::metadata::IsValueType(returnType))
  280. {
  281. Il2CppClass* returnKlass = il2cpp::vm::Class::FromIl2CppType(returnType);
  282. if (il2cpp::vm::Class::IsNullable(returnKlass))
  283. {
  284. il2cpp::vm::Object::UnboxNullable((Il2CppObject*)retObj, returnKlass->element_class, ret);
  285. }
  286. else
  287. {
  288. std::memcpy(ret, il2cpp::vm::Object::Unbox((Il2CppObject*)retObj), il2cpp::vm::Class::GetValueSize(returnKlass, nullptr));
  289. }
  290. }
  291. else
  292. {
  293. *(void**)ret = retObj;
  294. }
  295. }
  296. #endif
  297. }
  298. Managed2NativeCallMethod InterpreterModule::GetManaged2NativeMethodPointer(const MethodInfo* method, bool forceStatic)
  299. {
  300. if (method->methodPointerCallByInterp == NotSupportNative2Managed
  301. #if HYBRIDCLR_UNITY_2021_OR_NEW
  302. || method->has_full_generic_sharing_signature
  303. #endif
  304. )
  305. {
  306. return Managed2NativeCallByReflectionInvoke;
  307. }
  308. char sigName[1000];
  309. ComputeSignature(method, !forceStatic, sigName, sizeof(sigName) - 1);
  310. auto it = s_managed2natives.find(sigName);
  311. return it != s_managed2natives.end() ? it->second : Managed2NativeCallByReflectionInvoke;
  312. }
  313. Managed2NativeCallMethod InterpreterModule::GetManaged2NativeMethodPointer(const metadata::ResolveStandAloneMethodSig& method)
  314. {
  315. char sigName[1000];
  316. ComputeSignature(method.returnType, method.params, metadata::IsPrologHasThis(method.flags), sigName, sizeof(sigName) - 1);
  317. auto it = s_managed2natives.find(sigName);
  318. return it != s_managed2natives.end() ? it->second : Managed2NativeCallByReflectionInvoke;
  319. }
  320. static void RaiseExecutionEngineExceptionMethodIsNotFound(const MethodInfo* method)
  321. {
  322. if (il2cpp::vm::Method::GetClass(method))
  323. RaiseExecutionEngineException(il2cpp::vm::Method::GetFullName(method).c_str());
  324. else
  325. RaiseExecutionEngineException(il2cpp::vm::Method::GetNameWithGenericTypes(method).c_str());
  326. }
  327. #ifdef HYBRIDCLR_UNITY_2021_OR_NEW
  328. static void InterpreterInvoke(Il2CppMethodPointer methodPointer, const MethodInfo* method, void* __this, void** __args, void* __ret)
  329. {
  330. InterpMethodInfo* imi = method->interpData ? (InterpMethodInfo*)method->interpData : InterpreterModule::GetInterpMethodInfo(method);
  331. bool isInstanceMethod = metadata::IsInstanceMethod(method);
  332. StackObject* args = (StackObject*)alloca(sizeof(StackObject) * imi->argStackObjectSize);
  333. if (isInstanceMethod)
  334. {
  335. if (IS_CLASS_VALUE_TYPE(method->klass))
  336. {
  337. __this = (Il2CppObject*)__this + (methodPointer != method->methodPointerCallByInterp);
  338. }
  339. args[0].ptr = __this;
  340. }
  341. MethodArgDesc* argDescs = imi->args + isInstanceMethod;
  342. ConvertInvokeArgs(args + isInstanceMethod, method, argDescs, __args);
  343. Interpreter::Execute(method, args, __ret);
  344. }
  345. static void InterpreterDelegateInvoke(Il2CppMethodPointer, const MethodInfo* method, void* __this, void** __args, void* __ret)
  346. {
  347. Il2CppMulticastDelegate* del = (Il2CppMulticastDelegate*)__this;
  348. Il2CppDelegate** firstSubDel;
  349. int32_t subDelCount;
  350. if (del->delegates)
  351. {
  352. firstSubDel = (Il2CppDelegate**)il2cpp::vm::Array::GetFirstElementAddress(del->delegates);
  353. subDelCount = il2cpp::vm::Array::GetLength(del->delegates);
  354. }
  355. else
  356. {
  357. firstSubDel = (Il2CppDelegate**)&del;
  358. subDelCount = 1;
  359. }
  360. for (int32_t i = 0; i < subDelCount; i++)
  361. {
  362. Il2CppDelegate* cur = firstSubDel[i];
  363. const MethodInfo* curMethod = cur->method;
  364. Il2CppObject* curTarget = cur->target;
  365. if (curMethod->invoker_method == nullptr)
  366. {
  367. RaiseExecutionEngineExceptionMethodIsNotFound(curMethod);
  368. }
  369. if (!InitAndGetInterpreterDirectlyCallMethodPointer(curMethod))
  370. {
  371. RaiseAOTGenericMethodNotInstantiatedException(curMethod);
  372. }
  373. switch ((int)(method->parameters_count - curMethod->parameters_count))
  374. {
  375. case 0:
  376. {
  377. if (metadata::IsInstanceMethod(curMethod) && !curTarget)
  378. {
  379. il2cpp::vm::Exception::RaiseNullReferenceException();
  380. }
  381. curTarget += (IS_CLASS_VALUE_TYPE(curMethod->klass));
  382. curMethod->invoker_method(curMethod->methodPointerCallByInterp, curMethod, curTarget, __args, __ret);
  383. break;
  384. }
  385. case -1:
  386. {
  387. IL2CPP_ASSERT(!hybridclr::metadata::IsInstanceMethod(curMethod));
  388. void** newArgs = (void**)alloca(sizeof(void*) * (size_t)(curMethod->parameters_count + 1));
  389. newArgs[0] = curTarget;
  390. for (int k = 0, endK = curMethod->parameters_count; k < endK; k++)
  391. {
  392. newArgs[k + 1] = __args[k];
  393. }
  394. curMethod->invoker_method(curMethod->methodPointerCallByInterp, curMethod, nullptr, newArgs, __ret);
  395. break;
  396. }
  397. case 1:
  398. {
  399. IL2CPP_ASSERT(hybridclr::metadata::IsInstanceMethod(curMethod) && curMethod->parameters_count);
  400. curTarget = (Il2CppObject*)__args[0];
  401. if (!curTarget)
  402. {
  403. il2cpp::vm::Exception::RaiseNullReferenceException();
  404. }
  405. curMethod->invoker_method(curMethod->methodPointerCallByInterp, curMethod, curTarget, __args + 1, __ret);
  406. break;
  407. }
  408. default:
  409. {
  410. RaiseExecutionEngineException("bad delegate method");
  411. break;
  412. }
  413. }
  414. }
  415. }
  416. #else
  417. static void* InterpreterInvoke(Il2CppMethodPointer methodPointer, const MethodInfo* method, void* __this, void** __args)
  418. {
  419. InterpMethodInfo* imi = method->interpData ? (InterpMethodInfo*)method->interpData : InterpreterModule::GetInterpMethodInfo(method);
  420. StackObject* args = (StackObject*)alloca(sizeof(StackObject) * imi->argStackObjectSize);
  421. bool isInstanceMethod = metadata::IsInstanceMethod(method);
  422. if (isInstanceMethod)
  423. {
  424. if (IS_CLASS_VALUE_TYPE(method->klass))
  425. {
  426. __this = (Il2CppObject*)__this + (methodPointer != method->methodPointerCallByInterp);
  427. }
  428. args[0].ptr = __this;
  429. }
  430. MethodArgDesc* argDescs = imi->args + isInstanceMethod;
  431. ConvertInvokeArgs(args + isInstanceMethod, method, argDescs, __args);
  432. if (method->return_type->type == IL2CPP_TYPE_VOID)
  433. {
  434. Interpreter::Execute(method, args, nullptr);
  435. return nullptr;
  436. }
  437. else
  438. {
  439. StackObject* ret = (StackObject*)alloca(sizeof(StackObject) * imi->retStackObjectSize);
  440. Interpreter::Execute(method, args, ret);
  441. return TranslateNativeValueToBoxValue(method->return_type, ret);
  442. }
  443. }
  444. static void* InterpreterDelegateInvoke(Il2CppMethodPointer, const MethodInfo* method, void* __this, void** __args)
  445. {
  446. Il2CppMulticastDelegate* del = (Il2CppMulticastDelegate*)__this;
  447. Il2CppDelegate** firstSubDel;
  448. int32_t subDelCount;
  449. if (del->delegates)
  450. {
  451. firstSubDel = (Il2CppDelegate**)il2cpp::vm::Array::GetFirstElementAddress(del->delegates);
  452. subDelCount = il2cpp::vm::Array::GetLength(del->delegates);
  453. }
  454. else
  455. {
  456. firstSubDel = (Il2CppDelegate**)&del;
  457. subDelCount = 1;
  458. }
  459. void* ret = nullptr;
  460. for (int32_t i = 0; i < subDelCount; i++)
  461. {
  462. Il2CppDelegate* cur = firstSubDel[i];
  463. const MethodInfo* curMethod = cur->method;
  464. Il2CppObject* curTarget = cur->target;
  465. if (curMethod->invoker_method == nullptr)
  466. {
  467. RaiseExecutionEngineExceptionMethodIsNotFound(curMethod);
  468. }
  469. if (!InitAndGetInterpreterDirectlyCallMethodPointer(curMethod))
  470. {
  471. RaiseAOTGenericMethodNotInstantiatedException(curMethod);
  472. }
  473. switch ((int)(method->parameters_count - curMethod->parameters_count))
  474. {
  475. case 0:
  476. {
  477. if (metadata::IsInstanceMethod(curMethod) && !curTarget)
  478. {
  479. il2cpp::vm::Exception::RaiseNullReferenceException();
  480. }
  481. curTarget += (IS_CLASS_VALUE_TYPE(curMethod->klass));
  482. ret = curMethod->invoker_method(curMethod->methodPointerCallByInterp, curMethod, curTarget, __args);
  483. break;
  484. }
  485. case -1:
  486. {
  487. IL2CPP_ASSERT(!hybridclr::metadata::IsInstanceMethod(curMethod));
  488. void** newArgs = (void**)alloca(sizeof(void*) * (size_t)(curMethod->parameters_count + 1));
  489. newArgs[0] = curTarget;
  490. for (int k = 0, endK = curMethod->parameters_count; k < endK; k++)
  491. {
  492. newArgs[k + 1] = __args[k];
  493. }
  494. ret = curMethod->invoker_method(curMethod->methodPointerCallByInterp, curMethod, nullptr, newArgs);
  495. break;
  496. }
  497. case 1:
  498. {
  499. IL2CPP_ASSERT(hybridclr::metadata::IsInstanceMethod(curMethod) && curMethod->parameters_count);
  500. curTarget = (Il2CppObject*)__args[0];
  501. if (!curTarget)
  502. {
  503. il2cpp::vm::Exception::RaiseNullReferenceException();
  504. }
  505. ret = curMethod->invoker_method(curMethod->methodPointerCallByInterp, curMethod, curTarget, __args + 1);
  506. break;
  507. }
  508. default:
  509. {
  510. RaiseExecutionEngineException("bad delegate method");
  511. break;
  512. }
  513. }
  514. }
  515. return ret;
  516. }
  517. #endif
  518. InvokerMethod InterpreterModule::GetMethodInvoker(const Il2CppMethodDefinition* method)
  519. {
  520. Il2CppClass* klass = il2cpp::vm::GlobalMetadata::GetTypeInfoFromTypeDefinitionIndex(method->declaringType);
  521. const char* methodName = il2cpp::vm::GlobalMetadata::GetStringFromIndex(method->nameIndex);
  522. // special for Delegate::DynamicInvoke
  523. return !klass || !metadata::IsChildTypeOfMulticastDelegate(klass) || strcmp(methodName, "Invoke") ? InterpreterInvoke : InterpreterDelegateInvoke;
  524. }
  525. InvokerMethod InterpreterModule::GetMethodInvoker(const MethodInfo* method)
  526. {
  527. Il2CppClass* klass = method->klass;
  528. return !klass || !metadata::IsChildTypeOfMulticastDelegate(klass) || strcmp(method->name, "Invoke") ? InterpreterInvoke : InterpreterDelegateInvoke;
  529. }
  530. bool InterpreterModule::IsImplementsByInterpreter(const MethodInfo* method)
  531. {
  532. return method->invoker_method == InterpreterDelegateInvoke || method->invoker_method == InterpreterInvoke;
  533. }
  534. InterpMethodInfo* InterpreterModule::GetInterpMethodInfo(const MethodInfo* methodInfo)
  535. {
  536. RuntimeInitClassCCtor(methodInfo);
  537. il2cpp::os::FastAutoLock lock(&il2cpp::vm::g_MetadataLock);
  538. if (methodInfo->interpData)
  539. {
  540. return (InterpMethodInfo*)methodInfo->interpData;
  541. }
  542. IL2CPP_ASSERT(methodInfo->isInterpterImpl);
  543. InterpMethodInfo* imi = transform::HiTransform::Transform(methodInfo);
  544. il2cpp::os::Atomic::FullMemoryBarrier();
  545. const_cast<MethodInfo*>(methodInfo)->interpData = imi;
  546. return imi;
  547. }
  548. }
  549. }