JITManager.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. //-------------------------------------------------------------------------------------------------------
  2. // Copyright (C) Microsoft. All rights reserved.
  3. // Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
  4. //-------------------------------------------------------------------------------------------------------
  5. #include "JITClientPch.h"
  6. _Must_inspect_result_
  7. _Ret_maybenull_ _Post_writable_byte_size_(size)
  8. void * __RPC_USER midl_user_allocate(
  9. #if defined(_WIN32_WINNT_WIN10)
  10. _In_ // starting win10, _In_ is in the signature
  11. #endif
  12. size_t size)
  13. {
  14. return (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size));
  15. }
  16. void __RPC_USER midl_user_free(_Pre_maybenull_ _Post_invalid_ void * ptr)
  17. {
  18. if (ptr != NULL)
  19. {
  20. HeapFree(GetProcessHeap(), NULL, ptr);
  21. }
  22. }
  23. JITManager JITManager::s_jitManager = JITManager();
  24. JITManager::JITManager() :
  25. m_rpcBindingHandle(nullptr),
  26. m_oopJitEnabled(false),
  27. m_isJITServer(false),
  28. m_failingHRESULT(S_OK),
  29. m_jitConnectionId()
  30. {
  31. }
  32. JITManager::~JITManager()
  33. {
  34. if (m_rpcBindingHandle)
  35. {
  36. RpcBindingFree(&m_rpcBindingHandle);
  37. }
  38. }
  39. /* static */
  40. JITManager *
  41. JITManager::GetJITManager()
  42. {
  43. return &s_jitManager;
  44. }
  45. typedef struct _CHAKRA_RPC_SECURITY_QOS_V5 {
  46. unsigned long Version;
  47. unsigned long Capabilities;
  48. unsigned long IdentityTracking;
  49. unsigned long ImpersonationType;
  50. unsigned long AdditionalSecurityInfoType;
  51. union
  52. {
  53. RPC_HTTP_TRANSPORT_CREDENTIALS_W* HttpCredentials;
  54. } u;
  55. void* Sid;
  56. unsigned int EffectiveOnly;
  57. void* ServerSecurityDescriptor;
  58. } CHAKRA_RPC_SECURITY_QOS_V5;
  59. // This routine creates a binding with the server.
  60. HRESULT
  61. JITManager::CreateBinding(
  62. __in HANDLE serverProcessHandle,
  63. __in_opt void * serverSecurityDescriptor,
  64. __in UUID * connectionUuid,
  65. __out RPC_BINDING_HANDLE * bindingHandle)
  66. {
  67. Assert(IsOOPJITEnabled());
  68. RPC_STATUS status;
  69. DWORD attemptCount = 0;
  70. DWORD sleepInterval = 100; // in milliseconds
  71. RPC_BINDING_HANDLE localBindingHandle;
  72. RPC_BINDING_HANDLE_TEMPLATE_V1 bindingTemplate;
  73. RPC_BINDING_HANDLE_SECURITY_V1_W bindingSecurity;
  74. CHAKRA_RPC_SECURITY_QOS_V5 securityQOS;
  75. ZeroMemory(&securityQOS, sizeof(CHAKRA_RPC_SECURITY_QOS_V5));
  76. securityQOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT;
  77. securityQOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC;
  78. securityQOS.ImpersonationType = RPC_C_IMP_LEVEL_IDENTIFY;
  79. securityQOS.Version = AutoSystemInfo::Data.IsWin8OrLater() ? 5 : 4;
  80. securityQOS.ServerSecurityDescriptor = serverSecurityDescriptor;
  81. ZeroMemory(&bindingTemplate, sizeof(bindingTemplate));
  82. bindingTemplate.Version = 1;
  83. bindingTemplate.ProtocolSequence = RPC_PROTSEQ_LRPC;
  84. bindingTemplate.StringEndpoint = NULL;
  85. memcpy_s(&bindingTemplate.ObjectUuid, sizeof(UUID), connectionUuid, sizeof(UUID));
  86. bindingTemplate.Flags |= RPC_BHT_OBJECT_UUID_VALID;
  87. ZeroMemory(&bindingSecurity, sizeof(bindingSecurity));
  88. bindingSecurity.Version = 1;
  89. bindingSecurity.AuthnLevel = RPC_C_AUTHN_LEVEL_PKT_PRIVACY;
  90. bindingSecurity.AuthnSvc = RPC_C_AUTHN_KERNEL;
  91. bindingSecurity.SecurityQos = (RPC_SECURITY_QOS*)&securityQOS;
  92. status = RpcBindingCreate(&bindingTemplate, &bindingSecurity, NULL, &localBindingHandle);
  93. if (status != RPC_S_OK)
  94. {
  95. return HRESULT_FROM_WIN32(status);
  96. }
  97. // We keep attempting to connect to the server with increasing wait intervals in between.
  98. // This will wait close to 5 minutes before it finally gives up.
  99. do
  100. {
  101. DWORD waitStatus;
  102. status = RpcBindingBind(NULL, localBindingHandle, ClientIChakraJIT_v0_0_c_ifspec);
  103. if (status == RPC_S_OK)
  104. {
  105. break;
  106. }
  107. else if (status == EPT_S_NOT_REGISTERED)
  108. {
  109. // The Server side has not finished registering the RPC Server yet.
  110. // We should only breakout if we have reached the max attempt count.
  111. if (attemptCount > 600)
  112. {
  113. break;
  114. }
  115. }
  116. else
  117. {
  118. // Some unknown error occurred. We are not going to retry for arbitrary errors.
  119. break;
  120. }
  121. // When we come to this point, it means the server has not finished registration yet.
  122. // We should wait for a while and then reattempt to bind.
  123. waitStatus = WaitForSingleObject(serverProcessHandle, sleepInterval);
  124. if (waitStatus == WAIT_OBJECT_0)
  125. {
  126. // The server process died for some reason. No need to reattempt.
  127. status = RPC_S_SERVER_UNAVAILABLE;
  128. break;
  129. }
  130. else if (waitStatus == WAIT_TIMEOUT)
  131. {
  132. // Not an error. the server is still alive and we should reattempt.
  133. }
  134. else
  135. {
  136. Assert(waitStatus == WAIT_FAILED);
  137. #ifdef DBG
  138. LPWSTR messageBuffer = nullptr;
  139. DWORD errorNumber = GetLastError();
  140. FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
  141. NULL, errorNumber, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&messageBuffer, 0, NULL);
  142. Output::Print(_u("Last error was 0x%x (%s)"), errorNumber, messageBuffer);
  143. LocalFree(messageBuffer);
  144. #endif
  145. // wait operation failed for an unknown reason.
  146. Assert(false);
  147. status = HRESULT_FROM_WIN32(waitStatus);
  148. break;
  149. }
  150. attemptCount++;
  151. if (sleepInterval < 500)
  152. {
  153. sleepInterval += 100;
  154. }
  155. } while (status != RPC_S_OK); // redundant check, but compiler would not allow true here.
  156. *bindingHandle = localBindingHandle;
  157. return HRESULT_FROM_WIN32(status);
  158. }
  159. bool
  160. JITManager::IsJITServer() const
  161. {
  162. return m_isJITServer;
  163. }
  164. void
  165. JITManager::SetIsJITServer()
  166. {
  167. m_isJITServer = true;
  168. m_oopJitEnabled = true;
  169. }
  170. bool
  171. JITManager::IsConnected() const
  172. {
  173. Assert(IsOOPJITEnabled());
  174. return m_rpcBindingHandle != nullptr && !HasJITFailed();
  175. }
  176. void
  177. JITManager::EnableOOPJIT()
  178. {
  179. m_oopJitEnabled = true;
  180. if (CONFIG_FLAG(OOPCFGRegistration))
  181. {
  182. // Since this client has enabled OOPJIT, perform the one-way policy update
  183. // that will disable SetProcessValidCallTargets from being invoked.
  184. GlobalSecurityPolicy::DisableSetProcessValidCallTargets();
  185. }
  186. }
  187. void
  188. JITManager::SetJITFailed(HRESULT hr)
  189. {
  190. Assert(hr != S_OK);
  191. m_failingHRESULT = hr;
  192. }
  193. bool
  194. JITManager::HasJITFailed() const
  195. {
  196. return m_failingHRESULT != S_OK;
  197. }
  198. bool
  199. JITManager::IsOOPJITEnabled() const
  200. {
  201. return m_oopJitEnabled;
  202. }
  203. #pragma prefast(push)
  204. #pragma prefast(disable:__WARNING_RELEASING_UNHELD_LOCK_MEDIUM_CONFIDENCE, "Lock is correctly acquired and released by RAII class AutoCriticalSection")
  205. #pragma prefast(disable:__WARNING_CALLER_FAILING_TO_HOLD, "Lock is correctly acquired and released by RAII class AutoCriticalSection")
  206. HRESULT
  207. JITManager::ConnectRpcServer(__in HANDLE jitProcessHandle, __in_opt void* serverSecurityDescriptor, __in UUID connectionUuid)
  208. {
  209. // We might be trying to connect from multiple threads simultaneously
  210. AutoCriticalSection cs(&m_cs);
  211. Assert(IsOOPJITEnabled());
  212. if (m_rpcBindingHandle != nullptr)
  213. {
  214. return S_OK;
  215. }
  216. HRESULT hr = E_FAIL;
  217. RPC_BINDING_HANDLE bindingHandle;
  218. hr = CreateBinding(jitProcessHandle, serverSecurityDescriptor, &connectionUuid, &bindingHandle);
  219. if (FAILED(hr))
  220. {
  221. goto FailureCleanup;
  222. }
  223. hr = ConnectProcess(bindingHandle);
  224. HandleServerCallResult(hr, RemoteCallType::StateUpdate);
  225. // Only store the binding handle after JIT handshake, so other threads do not prematurely think we are ready to JIT
  226. m_rpcBindingHandle = bindingHandle;
  227. m_jitConnectionId = connectionUuid;
  228. return hr;
  229. FailureCleanup:
  230. if (m_rpcBindingHandle)
  231. {
  232. RpcBindingFree(&m_rpcBindingHandle);
  233. m_rpcBindingHandle = nullptr;
  234. }
  235. return hr;
  236. }
  237. #pragma prefast(pop)
  238. HRESULT
  239. JITManager::Shutdown()
  240. {
  241. // this is special case of shutdown called when runtime process is a parent of the server process
  242. // used for console host type scenarios
  243. HRESULT hr = S_OK;
  244. Assert(IsOOPJITEnabled());
  245. Assert(m_rpcBindingHandle != nullptr);
  246. RpcTryExcept
  247. {
  248. ClientShutdown(m_rpcBindingHandle);
  249. }
  250. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  251. {
  252. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  253. }
  254. RpcEndExcept;
  255. m_rpcBindingHandle = nullptr;
  256. return hr;
  257. }
  258. HRESULT
  259. JITManager::ConnectProcess(RPC_BINDING_HANDLE rpcBindingHandle)
  260. {
  261. Assert(IsOOPJITEnabled());
  262. HRESULT hr = E_FAIL;
  263. if (AutoSystemInfo::Data.IsWin8Point1OrLater())
  264. {
  265. HANDLE processHandle = nullptr;
  266. // RPC handle marshalling is only available on 8.1+
  267. if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &processHandle, 0, false, DUPLICATE_SAME_ACCESS))
  268. {
  269. return HRESULT_FROM_WIN32(GetLastError());
  270. }
  271. RpcTryExcept
  272. {
  273. hr = ClientConnectProcessWithProcessHandle(
  274. rpcBindingHandle,
  275. processHandle,
  276. (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
  277. (intptr_t)AutoSystemInfo::Data.GetCRTHandle());
  278. }
  279. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  280. {
  281. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  282. }
  283. RpcEndExcept;
  284. if (processHandle)
  285. {
  286. CloseHandle(processHandle);
  287. }
  288. }
  289. else
  290. {
  291. #if (WINVER >= _WIN32_WINNT_WINBLUE)
  292. AssertOrFailFast(UNREACHED);
  293. #else
  294. RpcTryExcept
  295. {
  296. hr = ClientConnectProcess(
  297. rpcBindingHandle,
  298. (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
  299. (intptr_t)AutoSystemInfo::Data.GetCRTHandle());
  300. }
  301. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  302. {
  303. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  304. }
  305. RpcEndExcept;
  306. #endif
  307. }
  308. return hr;
  309. }
  310. HRESULT
  311. JITManager::InitializeThreadContext(
  312. __in ThreadContextDataIDL * data,
  313. __out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
  314. __out intptr_t * prereservedRegionAddr,
  315. __out intptr_t * jitThunkAddr)
  316. {
  317. Assert(IsOOPJITEnabled());
  318. HRESULT hr = E_FAIL;
  319. RpcTryExcept
  320. {
  321. hr = ClientInitializeThreadContext(
  322. m_rpcBindingHandle,
  323. data,
  324. threadContextInfoAddress,
  325. prereservedRegionAddr,
  326. jitThunkAddr);
  327. }
  328. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  329. {
  330. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  331. }
  332. RpcEndExcept;
  333. return hr;
  334. }
  335. HRESULT
  336. JITManager::CleanupThreadContext(
  337. __inout PPTHREADCONTEXT_HANDLE threadContextInfoAddress)
  338. {
  339. Assert(IsOOPJITEnabled());
  340. HRESULT hr = E_FAIL;
  341. RpcTryExcept
  342. {
  343. hr = ClientCleanupThreadContext(m_rpcBindingHandle, threadContextInfoAddress);
  344. }
  345. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  346. {
  347. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  348. }
  349. RpcEndExcept;
  350. return hr;
  351. }
  352. HRESULT
  353. JITManager::SetIsPRNGSeeded(
  354. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  355. __in boolean value)
  356. {
  357. HRESULT hr = E_FAIL;
  358. RpcTryExcept
  359. {
  360. hr = ClientSetIsPRNGSeeded(m_rpcBindingHandle, scriptContextInfoAddress, value);
  361. }
  362. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  363. {
  364. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  365. }
  366. RpcEndExcept;
  367. return hr;
  368. }
  369. HRESULT
  370. JITManager::DecommitInterpreterBufferManager(
  371. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  372. __in boolean asmJsThunk)
  373. {
  374. Assert(IsOOPJITEnabled());
  375. HRESULT hr = E_FAIL;
  376. RpcTryExcept
  377. {
  378. hr = ClientDecommitInterpreterBufferManager(m_rpcBindingHandle, scriptContextInfoAddress, asmJsThunk);
  379. }
  380. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  381. {
  382. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  383. }
  384. RpcEndExcept;
  385. return hr;
  386. }
  387. HRESULT
  388. JITManager::NewInterpreterThunkBlock(
  389. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  390. __in InterpreterThunkInputIDL * thunkInput,
  391. __out InterpreterThunkOutputIDL * thunkOutput)
  392. {
  393. Assert(IsOOPJITEnabled());
  394. HRESULT hr = E_FAIL;
  395. RpcTryExcept
  396. {
  397. hr = ClientNewInterpreterThunkBlock(m_rpcBindingHandle, scriptContextInfoAddress, thunkInput, thunkOutput);
  398. }
  399. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  400. {
  401. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  402. }
  403. RpcEndExcept;
  404. return hr;
  405. }
  406. HRESULT
  407. JITManager::AddModuleRecordInfo(
  408. /* [in] */ PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  409. /* [in] */ unsigned int moduleId,
  410. /* [in] */ intptr_t localExportSlotsAddr)
  411. {
  412. Assert(IsOOPJITEnabled());
  413. HRESULT hr = E_FAIL;
  414. RpcTryExcept
  415. {
  416. hr = ClientAddModuleRecordInfo(m_rpcBindingHandle, scriptContextInfoAddress, moduleId, localExportSlotsAddr);
  417. }
  418. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  419. {
  420. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  421. }
  422. RpcEndExcept;
  423. return hr;
  424. }
  425. HRESULT
  426. JITManager::SetWellKnownHostTypeId(
  427. __in PTHREADCONTEXT_HANDLE threadContextRoot,
  428. __in int typeId)
  429. {
  430. Assert(IsOOPJITEnabled());
  431. HRESULT hr = E_FAIL;
  432. RpcTryExcept
  433. {
  434. hr = ClientSetWellKnownHostTypeId(m_rpcBindingHandle, threadContextRoot, typeId);
  435. }
  436. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  437. {
  438. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  439. }
  440. RpcEndExcept;
  441. return hr;
  442. }
  443. HRESULT
  444. JITManager::UpdatePropertyRecordMap(
  445. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  446. __in_opt BVSparseNodeIDL * updatedPropsBVHead)
  447. {
  448. Assert(IsOOPJITEnabled());
  449. HRESULT hr = E_FAIL;
  450. RpcTryExcept
  451. {
  452. hr = ClientUpdatePropertyRecordMap(m_rpcBindingHandle, threadContextInfoAddress, updatedPropsBVHead);
  453. }
  454. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  455. {
  456. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  457. }
  458. RpcEndExcept;
  459. return hr;
  460. }
  461. HRESULT
  462. JITManager::InitializeScriptContext(
  463. __in ScriptContextDataIDL * data,
  464. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  465. __out PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  466. {
  467. Assert(IsOOPJITEnabled());
  468. HRESULT hr = E_FAIL;
  469. RpcTryExcept
  470. {
  471. hr = ClientInitializeScriptContext(m_rpcBindingHandle, data, threadContextInfoAddress, scriptContextInfoAddress);
  472. }
  473. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  474. {
  475. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  476. }
  477. RpcEndExcept;
  478. return hr;
  479. }
  480. HRESULT
  481. JITManager::CleanupScriptContext(
  482. __inout PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  483. {
  484. Assert(IsOOPJITEnabled());
  485. HRESULT hr = E_FAIL;
  486. RpcTryExcept
  487. {
  488. hr = ClientCleanupScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
  489. }
  490. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  491. {
  492. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  493. }
  494. RpcEndExcept;
  495. return hr;
  496. }
  497. HRESULT
  498. JITManager::CloseScriptContext(
  499. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  500. {
  501. Assert(IsOOPJITEnabled());
  502. HRESULT hr = E_FAIL;
  503. RpcTryExcept
  504. {
  505. hr = ClientCloseScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
  506. }
  507. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  508. {
  509. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  510. }
  511. RpcEndExcept;
  512. return hr;
  513. }
  514. HRESULT
  515. JITManager::FreeAllocation(
  516. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  517. __in intptr_t codeAddress)
  518. {
  519. Assert(IsOOPJITEnabled());
  520. HRESULT hr = E_FAIL;
  521. RpcTryExcept
  522. {
  523. hr = ClientFreeAllocation(m_rpcBindingHandle, scriptContextInfoAddress, codeAddress);
  524. }
  525. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  526. {
  527. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  528. }
  529. RpcEndExcept;
  530. return hr;
  531. }
  532. HRESULT
  533. JITManager::IsNativeAddr(
  534. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  535. __in intptr_t address,
  536. __out boolean * result)
  537. {
  538. Assert(IsOOPJITEnabled());
  539. HRESULT hr = E_FAIL;
  540. RpcTryExcept
  541. {
  542. hr = ClientIsNativeAddr(m_rpcBindingHandle, threadContextInfoAddress, address, result);
  543. }
  544. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  545. {
  546. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  547. }
  548. RpcEndExcept;
  549. return hr;
  550. }
  551. HRESULT
  552. JITManager::RemoteCodeGenCall(
  553. __in CodeGenWorkItemIDL *workItemData,
  554. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  555. __out JITOutputIDL *jitData)
  556. {
  557. Assert(IsOOPJITEnabled());
  558. HRESULT hr = E_FAIL;
  559. RpcTryExcept
  560. {
  561. hr = ClientRemoteCodeGen(m_rpcBindingHandle, scriptContextInfoAddress, workItemData, jitData);
  562. }
  563. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  564. {
  565. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  566. }
  567. RpcEndExcept;
  568. return hr;
  569. }
  570. #if DBG
  571. HRESULT
  572. JITManager::IsInterpreterThunkAddr(
  573. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  574. __in intptr_t address,
  575. __in boolean asmjsThunk,
  576. __out boolean * result)
  577. {
  578. Assert(IsOOPJITEnabled());
  579. HRESULT hr = E_FAIL;
  580. RpcTryExcept
  581. {
  582. hr = ClientIsInterpreterThunkAddr(m_rpcBindingHandle, scriptContextInfoAddress, address, asmjsThunk, result);
  583. }
  584. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  585. {
  586. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  587. }
  588. RpcEndExcept;
  589. return hr;
  590. }
  591. #endif
  592. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  593. HRESULT
  594. JITManager::DeserializeRPCData(
  595. _In_reads_(bufferSize) const byte* buffer,
  596. _In_ uint bufferSize,
  597. _Out_ CodeGenWorkItemIDL **workItemData
  598. )
  599. {
  600. RPC_STATUS status = RPC_S_OK;
  601. handle_t marshalHandle = nullptr;
  602. *workItemData = nullptr;
  603. __try
  604. {
  605. RpcTryExcept
  606. {
  607. status = MesDecodeBufferHandleCreate((char*)buffer, bufferSize, &marshalHandle);
  608. if (status != RPC_S_OK)
  609. {
  610. return HRESULT_FROM_WIN32(status);
  611. }
  612. pCodeGenWorkItemIDL_Decode(
  613. marshalHandle,
  614. workItemData);
  615. }
  616. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  617. {
  618. status = RpcExceptionCode();
  619. }
  620. RpcEndExcept;
  621. }
  622. __finally
  623. {
  624. MesHandleFree(marshalHandle);
  625. }
  626. return HRESULT_FROM_WIN32(status);
  627. }
  628. HRESULT
  629. JITManager::SerializeRPCData(_In_ CodeGenWorkItemIDL *workItemData, _Out_ size_t* bufferSize, _Outptr_result_buffer_(*bufferSize) const byte** outBuffer)
  630. {
  631. handle_t marshalHandle = nullptr;
  632. *bufferSize = 0;
  633. *outBuffer = nullptr;
  634. RPC_STATUS status = RPC_S_OK;
  635. __try
  636. {
  637. RpcTryExcept
  638. {
  639. char* data = nullptr;
  640. unsigned long encodedSize;
  641. status = MesEncodeDynBufferHandleCreate(
  642. &data,
  643. &encodedSize,
  644. &marshalHandle);
  645. if (status != RPC_S_OK)
  646. {
  647. return HRESULT_FROM_WIN32(status);
  648. }
  649. MIDL_ES_CODE encodeType = MES_ENCODE;
  650. #if TARGET_64
  651. encodeType = MES_ENCODE_NDR64;
  652. // We only support encode syntax NDR64, however MesEncodeDynBufferHandleCreate doesn't allow to specify it
  653. status = MesBufferHandleReset(
  654. marshalHandle,
  655. MES_DYNAMIC_BUFFER_HANDLE,
  656. encodeType,
  657. &data,
  658. 0,
  659. &encodedSize
  660. );
  661. if (status != RPC_S_OK)
  662. {
  663. return HRESULT_FROM_WIN32(status);
  664. }
  665. #endif
  666. // Calculate how big we need to create the buffer
  667. size_t tmpBufSize = pCodeGenWorkItemIDL_AlignSize(marshalHandle, &workItemData);
  668. size_t alignedBufSize = Math::Align<size_t>(tmpBufSize, 16);
  669. data = HeapNewNoThrowArray(char, alignedBufSize);
  670. if (!data)
  671. {
  672. // Ran out of memory
  673. return E_OUTOFMEMORY;
  674. }
  675. // Reset the buffer handle to a fixed buffer
  676. status = MesBufferHandleReset(
  677. marshalHandle,
  678. MES_FIXED_BUFFER_HANDLE,
  679. encodeType,
  680. &data,
  681. (unsigned long)alignedBufSize,
  682. &encodedSize
  683. );
  684. if (status != RPC_S_OK)
  685. {
  686. return HRESULT_FROM_WIN32(status);
  687. }
  688. pCodeGenWorkItemIDL_Encode(
  689. marshalHandle,
  690. &workItemData);
  691. *bufferSize = alignedBufSize;
  692. *outBuffer = (byte*)data;
  693. }
  694. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  695. {
  696. status = RpcExceptionCode();
  697. }
  698. RpcEndExcept;
  699. }
  700. __finally
  701. {
  702. MesHandleFree(marshalHandle);
  703. }
  704. return HRESULT_FROM_WIN32(status);
  705. }
  706. #endif