JITManager.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  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. #ifdef USE_RPC_HANDLE_MARSHALLING
  263. HANDLE processHandle;
  264. if (!DuplicateHandle(GetCurrentProcess(), GetCurrentProcess(), GetCurrentProcess(), &processHandle, 0, false, DUPLICATE_SAME_ACCESS))
  265. {
  266. return HRESULT_FROM_WIN32(GetLastError());
  267. }
  268. #endif
  269. HRESULT hr = E_FAIL;
  270. RpcTryExcept
  271. {
  272. hr = ClientConnectProcess(
  273. rpcBindingHandle,
  274. #ifdef USE_RPC_HANDLE_MARSHALLING
  275. processHandle,
  276. #endif
  277. (intptr_t)AutoSystemInfo::Data.GetChakraBaseAddr(),
  278. (intptr_t)AutoSystemInfo::Data.GetCRTHandle());
  279. }
  280. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  281. {
  282. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  283. }
  284. RpcEndExcept;
  285. #ifdef USE_RPC_HANDLE_MARSHALLING
  286. CloseHandle(processHandle);
  287. #endif
  288. return hr;
  289. }
  290. HRESULT
  291. JITManager::InitializeThreadContext(
  292. __in ThreadContextDataIDL * data,
  293. __out PPTHREADCONTEXT_HANDLE threadContextInfoAddress,
  294. __out intptr_t * prereservedRegionAddr,
  295. __out intptr_t * jitThunkAddr)
  296. {
  297. Assert(IsOOPJITEnabled());
  298. HRESULT hr = E_FAIL;
  299. RpcTryExcept
  300. {
  301. hr = ClientInitializeThreadContext(
  302. m_rpcBindingHandle,
  303. data,
  304. threadContextInfoAddress,
  305. prereservedRegionAddr,
  306. jitThunkAddr);
  307. }
  308. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  309. {
  310. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  311. }
  312. RpcEndExcept;
  313. return hr;
  314. }
  315. HRESULT
  316. JITManager::CleanupThreadContext(
  317. __inout PPTHREADCONTEXT_HANDLE threadContextInfoAddress)
  318. {
  319. Assert(IsOOPJITEnabled());
  320. HRESULT hr = E_FAIL;
  321. RpcTryExcept
  322. {
  323. hr = ClientCleanupThreadContext(m_rpcBindingHandle, threadContextInfoAddress);
  324. }
  325. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  326. {
  327. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  328. }
  329. RpcEndExcept;
  330. return hr;
  331. }
  332. HRESULT
  333. JITManager::AddDOMFastPathHelper(
  334. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  335. __in intptr_t funcInfoAddr,
  336. __in int helper)
  337. {
  338. Assert(IsOOPJITEnabled());
  339. HRESULT hr = E_FAIL;
  340. RpcTryExcept
  341. {
  342. hr = ClientAddDOMFastPathHelper(m_rpcBindingHandle, scriptContextInfoAddress, funcInfoAddr, helper);
  343. }
  344. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  345. {
  346. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  347. }
  348. RpcEndExcept;
  349. return hr;
  350. }
  351. HRESULT
  352. JITManager::SetIsPRNGSeeded(
  353. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  354. __in boolean value)
  355. {
  356. HRESULT hr = E_FAIL;
  357. RpcTryExcept
  358. {
  359. hr = ClientSetIsPRNGSeeded(m_rpcBindingHandle, scriptContextInfoAddress, value);
  360. }
  361. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  362. {
  363. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  364. }
  365. RpcEndExcept;
  366. return hr;
  367. }
  368. HRESULT
  369. JITManager::DecommitInterpreterBufferManager(
  370. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  371. __in boolean asmJsThunk)
  372. {
  373. Assert(IsOOPJITEnabled());
  374. HRESULT hr = E_FAIL;
  375. RpcTryExcept
  376. {
  377. hr = ClientDecommitInterpreterBufferManager(m_rpcBindingHandle, scriptContextInfoAddress, asmJsThunk);
  378. }
  379. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  380. {
  381. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  382. }
  383. RpcEndExcept;
  384. return hr;
  385. }
  386. HRESULT
  387. JITManager::NewInterpreterThunkBlock(
  388. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  389. __in InterpreterThunkInputIDL * thunkInput,
  390. __out InterpreterThunkOutputIDL * thunkOutput)
  391. {
  392. Assert(IsOOPJITEnabled());
  393. HRESULT hr = E_FAIL;
  394. RpcTryExcept
  395. {
  396. hr = ClientNewInterpreterThunkBlock(m_rpcBindingHandle, scriptContextInfoAddress, thunkInput, thunkOutput);
  397. }
  398. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  399. {
  400. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  401. }
  402. RpcEndExcept;
  403. return hr;
  404. }
  405. HRESULT
  406. JITManager::AddModuleRecordInfo(
  407. /* [in] */ PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  408. /* [in] */ unsigned int moduleId,
  409. /* [in] */ intptr_t localExportSlotsAddr)
  410. {
  411. Assert(IsOOPJITEnabled());
  412. HRESULT hr = E_FAIL;
  413. RpcTryExcept
  414. {
  415. hr = ClientAddModuleRecordInfo(m_rpcBindingHandle, scriptContextInfoAddress, moduleId, localExportSlotsAddr);
  416. }
  417. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  418. {
  419. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  420. }
  421. RpcEndExcept;
  422. return hr;
  423. }
  424. HRESULT
  425. JITManager::SetWellKnownHostTypeId(
  426. __in PTHREADCONTEXT_HANDLE threadContextRoot,
  427. __in int typeId)
  428. {
  429. Assert(IsOOPJITEnabled());
  430. HRESULT hr = E_FAIL;
  431. RpcTryExcept
  432. {
  433. hr = ClientSetWellKnownHostTypeId(m_rpcBindingHandle, threadContextRoot, typeId);
  434. }
  435. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  436. {
  437. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  438. }
  439. RpcEndExcept;
  440. return hr;
  441. }
  442. HRESULT
  443. JITManager::UpdatePropertyRecordMap(
  444. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  445. __in_opt BVSparseNodeIDL * updatedPropsBVHead)
  446. {
  447. Assert(IsOOPJITEnabled());
  448. HRESULT hr = E_FAIL;
  449. RpcTryExcept
  450. {
  451. hr = ClientUpdatePropertyRecordMap(m_rpcBindingHandle, threadContextInfoAddress, updatedPropsBVHead);
  452. }
  453. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  454. {
  455. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  456. }
  457. RpcEndExcept;
  458. return hr;
  459. }
  460. HRESULT
  461. JITManager::InitializeScriptContext(
  462. __in ScriptContextDataIDL * data,
  463. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  464. __out PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  465. {
  466. Assert(IsOOPJITEnabled());
  467. HRESULT hr = E_FAIL;
  468. RpcTryExcept
  469. {
  470. hr = ClientInitializeScriptContext(m_rpcBindingHandle, data, threadContextInfoAddress, scriptContextInfoAddress);
  471. }
  472. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  473. {
  474. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  475. }
  476. RpcEndExcept;
  477. return hr;
  478. }
  479. HRESULT
  480. JITManager::CleanupScriptContext(
  481. __inout PPSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  482. {
  483. Assert(IsOOPJITEnabled());
  484. HRESULT hr = E_FAIL;
  485. RpcTryExcept
  486. {
  487. hr = ClientCleanupScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
  488. }
  489. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  490. {
  491. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  492. }
  493. RpcEndExcept;
  494. return hr;
  495. }
  496. HRESULT
  497. JITManager::CloseScriptContext(
  498. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress)
  499. {
  500. Assert(IsOOPJITEnabled());
  501. HRESULT hr = E_FAIL;
  502. RpcTryExcept
  503. {
  504. hr = ClientCloseScriptContext(m_rpcBindingHandle, scriptContextInfoAddress);
  505. }
  506. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  507. {
  508. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  509. }
  510. RpcEndExcept;
  511. return hr;
  512. }
  513. HRESULT
  514. JITManager::FreeAllocation(
  515. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  516. __in intptr_t codeAddress)
  517. {
  518. Assert(IsOOPJITEnabled());
  519. HRESULT hr = E_FAIL;
  520. RpcTryExcept
  521. {
  522. hr = ClientFreeAllocation(m_rpcBindingHandle, scriptContextInfoAddress, codeAddress);
  523. }
  524. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  525. {
  526. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  527. }
  528. RpcEndExcept;
  529. return hr;
  530. }
  531. HRESULT
  532. JITManager::IsNativeAddr(
  533. __in PTHREADCONTEXT_HANDLE threadContextInfoAddress,
  534. __in intptr_t address,
  535. __out boolean * result)
  536. {
  537. Assert(IsOOPJITEnabled());
  538. HRESULT hr = E_FAIL;
  539. RpcTryExcept
  540. {
  541. hr = ClientIsNativeAddr(m_rpcBindingHandle, threadContextInfoAddress, address, result);
  542. }
  543. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  544. {
  545. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  546. }
  547. RpcEndExcept;
  548. return hr;
  549. }
  550. HRESULT
  551. JITManager::RemoteCodeGenCall(
  552. __in CodeGenWorkItemIDL *workItemData,
  553. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  554. __out JITOutputIDL *jitData)
  555. {
  556. Assert(IsOOPJITEnabled());
  557. HRESULT hr = E_FAIL;
  558. RpcTryExcept
  559. {
  560. hr = ClientRemoteCodeGen(m_rpcBindingHandle, scriptContextInfoAddress, workItemData, jitData);
  561. }
  562. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  563. {
  564. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  565. }
  566. RpcEndExcept;
  567. return hr;
  568. }
  569. #if DBG
  570. HRESULT
  571. JITManager::IsInterpreterThunkAddr(
  572. __in PSCRIPTCONTEXT_HANDLE scriptContextInfoAddress,
  573. __in intptr_t address,
  574. __in boolean asmjsThunk,
  575. __out boolean * result)
  576. {
  577. Assert(IsOOPJITEnabled());
  578. HRESULT hr = E_FAIL;
  579. RpcTryExcept
  580. {
  581. hr = ClientIsInterpreterThunkAddr(m_rpcBindingHandle, scriptContextInfoAddress, address, asmjsThunk, result);
  582. }
  583. RpcExcept(RpcExceptionFilter(RpcExceptionCode()))
  584. {
  585. hr = HRESULT_FROM_WIN32(RpcExceptionCode());
  586. }
  587. RpcEndExcept;
  588. return hr;
  589. }
  590. #endif
  591. #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
  592. HRESULT
  593. JITManager::DeserializeRPCData(
  594. _In_reads_(bufferSize) const byte* buffer,
  595. _In_ uint bufferSize,
  596. _Out_ CodeGenWorkItemIDL **workItemData
  597. )
  598. {
  599. RPC_STATUS status = RPC_S_OK;
  600. handle_t marshalHandle = nullptr;
  601. *workItemData = nullptr;
  602. __try
  603. {
  604. RpcTryExcept
  605. {
  606. status = MesDecodeBufferHandleCreate((char*)buffer, bufferSize, &marshalHandle);
  607. if (status != RPC_S_OK)
  608. {
  609. return HRESULT_FROM_WIN32(status);
  610. }
  611. pCodeGenWorkItemIDL_Decode(
  612. marshalHandle,
  613. workItemData);
  614. }
  615. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  616. {
  617. status = RpcExceptionCode();
  618. }
  619. RpcEndExcept;
  620. }
  621. __finally
  622. {
  623. MesHandleFree(marshalHandle);
  624. }
  625. return HRESULT_FROM_WIN32(status);
  626. }
  627. HRESULT
  628. JITManager::SerializeRPCData(_In_ CodeGenWorkItemIDL *workItemData, _Out_ size_t* bufferSize, _Outptr_result_buffer_(*bufferSize) const byte** outBuffer)
  629. {
  630. handle_t marshalHandle = nullptr;
  631. *bufferSize = 0;
  632. *outBuffer = nullptr;
  633. RPC_STATUS status = RPC_S_OK;
  634. __try
  635. {
  636. RpcTryExcept
  637. {
  638. char* data = nullptr;
  639. unsigned long encodedSize;
  640. status = MesEncodeDynBufferHandleCreate(
  641. &data,
  642. &encodedSize,
  643. &marshalHandle);
  644. if (status != RPC_S_OK)
  645. {
  646. return HRESULT_FROM_WIN32(status);
  647. }
  648. MIDL_ES_CODE encodeType = MES_ENCODE;
  649. #if TARGET_64
  650. encodeType = MES_ENCODE_NDR64;
  651. // We only support encode syntax NDR64, however MesEncodeDynBufferHandleCreate doesn't allow to specify it
  652. status = MesBufferHandleReset(
  653. marshalHandle,
  654. MES_DYNAMIC_BUFFER_HANDLE,
  655. encodeType,
  656. &data,
  657. 0,
  658. &encodedSize
  659. );
  660. if (status != RPC_S_OK)
  661. {
  662. return HRESULT_FROM_WIN32(status);
  663. }
  664. #endif
  665. // Calculate how big we need to create the buffer
  666. size_t tmpBufSize = pCodeGenWorkItemIDL_AlignSize(marshalHandle, &workItemData);
  667. size_t alignedBufSize = Math::Align<size_t>(tmpBufSize, 16);
  668. data = HeapNewNoThrowArray(char, alignedBufSize);
  669. if (!data)
  670. {
  671. // Ran out of memory
  672. return E_OUTOFMEMORY;
  673. }
  674. // Reset the buffer handle to a fixed buffer
  675. status = MesBufferHandleReset(
  676. marshalHandle,
  677. MES_FIXED_BUFFER_HANDLE,
  678. encodeType,
  679. &data,
  680. (unsigned long)alignedBufSize,
  681. &encodedSize
  682. );
  683. if (status != RPC_S_OK)
  684. {
  685. return HRESULT_FROM_WIN32(status);
  686. }
  687. pCodeGenWorkItemIDL_Encode(
  688. marshalHandle,
  689. &workItemData);
  690. *bufferSize = alignedBufSize;
  691. *outBuffer = (byte*)data;
  692. }
  693. RpcExcept(I_RpcExceptionFilter(RpcExceptionCode()))
  694. {
  695. status = RpcExceptionCode();
  696. }
  697. RpcEndExcept;
  698. }
  699. __finally
  700. {
  701. MesHandleFree(marshalHandle);
  702. }
  703. return HRESULT_FROM_WIN32(status);
  704. }
  705. #endif