InterpreterModule.cpp 18 KB

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