Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

553 lines
12 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1989-1999 Microsoft Corporation
  3. Module Name:
  4. ptrana.cxx
  5. Abstract:
  6. Contains implementations of analysis routines for pointer types.
  7. Notes:
  8. History:
  9. Oct-10-1993 VibhasC Created
  10. ----------------------------------------------------------------------------*/
  11. /****************************************************************************
  12. * include files
  13. ***************************************************************************/
  14. #include "allana.hxx"
  15. #pragma hdrstop
  16. /****************************************************************************
  17. * local definitions
  18. ***************************************************************************/
  19. /****************************************************************************
  20. * local data
  21. ***************************************************************************/
  22. /****************************************************************************
  23. * externs
  24. ***************************************************************************/
  25. /****************************************************************************/
  26. CG_STATUS
  27. CG_POINTER::UnMarshallAnalysis(
  28. ANALYSIS_INFO * pAna )
  29. {
  30. CG_STATUS Status;
  31. // Unmarshall the pointer body first. If the pointer needs to be deferred,
  32. // then dont perform the pointee unmarshall analysis. Just indicate that
  33. // there is a pointee that needs to be unmarshalled later.
  34. Status = PtrUnMarshallAnalysis( pAna );
  35. if( pAna->IsPointeeDeferred() )
  36. {
  37. pAna->SetHasAtLeastOneDeferredPointee();
  38. }
  39. else
  40. Status = PteUnMarshallAnalysis( pAna );
  41. return Status;
  42. }
  43. CG_STATUS
  44. CG_POINTER::PtrUnMarshallAnalysis(
  45. ANALYSIS_INFO * pAna )
  46. {
  47. // Perform the analysis for the pointer body. For a [ref] pointer, nothing
  48. // needs to be done.
  49. if( IsRef() && !pAna->IsMemoryAllocDone() )
  50. {
  51. SetUAction( RecommendUAction( pAna->GetCurrentSide(),
  52. pAna->IsMemoryAllocDone(),
  53. pAna->IsRefAllocDone(),
  54. FALSE, // no buffer re-use for ref.
  55. UAFLAGS_NONE
  56. ));
  57. }
  58. return CG_OK;
  59. }
  60. CG_STATUS
  61. CG_POINTER::PteUnMarshallAnalysis(
  62. ANALYSIS_INFO * pAna )
  63. {
  64. CG_STATUS Status;
  65. pAna->PushIndirectionLevel();
  66. Status = CorePteUnMarshallAnalysis( pAna );
  67. pAna->PopIndirectionLevel();
  68. return Status;
  69. }
  70. CG_STATUS
  71. CG_POINTER::MarshallAnalysis(
  72. ANALYSIS_INFO * pAna )
  73. {
  74. CG_STATUS Status;
  75. short EmbedLevel;
  76. // Marshall the pointer body first. If the pointee needs to be deferred,
  77. // dont perform marshall analysis on the pointee. Just indicate that a
  78. // pointee needs to be marshalled later.
  79. Status = PtrMarshallAnalysis( pAna );
  80. if( pAna->IsPointeeDeferred() )
  81. {
  82. pAna->SetHasAtLeastOneDeferredPointee();
  83. }
  84. else
  85. {
  86. EmbedLevel = pAna->GetCurrentEmbeddingLevel();
  87. pAna->ResetEmbeddingLevel();
  88. Status = PteMarshallAnalysis( pAna );
  89. pAna->SetCurrentEmbeddingLevel( EmbedLevel );
  90. }
  91. return Status;
  92. }
  93. CG_STATUS
  94. CG_POINTER::PtrMarshallAnalysis(
  95. ANALYSIS_INFO * pAna )
  96. {
  97. pAna;
  98. return CG_OK;
  99. }
  100. CG_STATUS
  101. CG_POINTER::PteMarshallAnalysis(
  102. ANALYSIS_INFO * pAna )
  103. {
  104. CG_STATUS Status;
  105. pAna->PushIndirectionLevel();
  106. pAna->SetMemoryAllocDone(); // Needed ?
  107. Status = CorePteMarshallAnalysis( pAna );
  108. pAna->PopIndirectionLevel();
  109. return Status;
  110. }
  111. CG_STATUS
  112. CG_POINTER::FollowerMarshallAnalysis(
  113. ANALYSIS_INFO * pAna )
  114. {
  115. return PteMarshallAnalysis( pAna );
  116. }
  117. CG_STATUS
  118. CG_POINTER::FollowerUnMarshallAnalysis(
  119. ANALYSIS_INFO * pAna )
  120. {
  121. return PteUnMarshallAnalysis( pAna );
  122. }
  123. CG_STATUS
  124. CG_POINTER::S_OutLocalAnalysis(
  125. ANALYSIS_INFO * pAna )
  126. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  127. Routine Description:
  128. Perform analysis for [out] params that need to be allocated as locals
  129. on server stub.
  130. Arguments:
  131. pAna - The analysis block.
  132. Return Value:
  133. CG_OK if all is well
  134. error otherwise.
  135. Notes:
  136. ----------------------------------------------------------------------------*/
  137. {
  138. CG_STATUS Status = CG_OK;
  139. CG_NDR * pC = (CG_NDR *)GetNonGenericHandleChild();
  140. if( !pAna->IsMemoryAllocDone() )
  141. {
  142. if( pAna->GetCurrentSide() != C_SIDE )
  143. {
  144. PNAME pName = pAna->GenTempResourceName( 0 );
  145. SetResource( pAna->AddLocalResource( pName,
  146. MakeIDNode( pName, GetType() )
  147. ));
  148. }
  149. SetAllocatedOnStack( 1 );
  150. }
  151. // If it is a ref pointer, chase it further.
  152. if( IsRef() && !IsQualifiedPointer() )
  153. {
  154. pAna->ResetMemoryAllocDone();
  155. pAna->SetRefAllocDone();
  156. Status = pC->S_OutLocalAnalysis( pAna );
  157. // If this is the server side, and the pointee is allocated on stack,
  158. // then dont free the pointee, else free it.
  159. if( pC->IsAllocatedOnStack() )
  160. {
  161. SetPointerShouldFree( 0 );
  162. }
  163. }
  164. return Status;
  165. }
  166. CG_STATUS
  167. CG_POINTER::InLocalAnalysis(
  168. ANALYSIS_INFO * pAna )
  169. {
  170. if( IsRef() && GetChild() )
  171. {
  172. ((CG_NDR *)GetChild())->InLocalAnalysis( pAna );
  173. }
  174. return CG_OK;
  175. }
  176. /****************************************************************************
  177. * CG_QUALIFIED_POINTER
  178. ***************************************************************************/
  179. CG_STATUS
  180. CG_QUALIFIED_POINTER::CorePteMarshallAnalysis(
  181. ANALYSIS_INFO * pAna )
  182. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  183. Routine Description:
  184. Perform the core pointee marshall analysis for a conformant string
  185. Arguments:
  186. pAna - The analysis block pointer.
  187. Return Value:
  188. CG_OK if all is well, error otherwise.
  189. Notes:
  190. The ndr for a conformant string (eg typedef [string] char *p ) is:
  191. - MaxCount
  192. - Offset from start of the valid character
  193. - Actual Count.
  194. We need to declare a local variable which will hold the length of the
  195. string, so that the length can be used in the actual marshall for memcopy.
  196. ----------------------------------------------------------------------------*/
  197. {
  198. node_skl * pType;
  199. PNAME pResName;
  200. BOOL fNeedsCount;
  201. BOOL fNeedsFirstAndLength;
  202. if( pAna->IsArrayContext() )
  203. {
  204. SetUsedInArray();
  205. }
  206. if ( ( fNeedsCount = NeedsMaxCountMarshall() ) == TRUE )
  207. {
  208. if( !GetSizeResource() )
  209. {
  210. GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
  211. pResName = pAna->GenTempResourceName(0);
  212. pType = MakeIDNode( pResName, pType );
  213. SetSizeResource( pAna->AddTransientResource( pResName, pType ) );
  214. }
  215. else
  216. {
  217. pAna->AddTransientResource( GetSizeResource()->GetResourceName(),
  218. GetSizeResource()->GetType()
  219. );
  220. }
  221. }
  222. if ( ( fNeedsFirstAndLength = NeedsFirstAndLengthMarshall() ) == TRUE )
  223. {
  224. if( !GetLengthResource() )
  225. {
  226. GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
  227. pResName = pAna->GenTempResourceName(0);
  228. pType = MakeIDNode( pResName, pType );
  229. SetLengthResource( pAna->AddTransientResource( pResName, pType ) );
  230. }
  231. else
  232. {
  233. pAna->AddTransientResource( GetLengthResource()->GetResourceName(),
  234. GetLengthResource()->GetType()
  235. );
  236. }
  237. if( NeedsExplicitFirst() )
  238. {
  239. if( !GetFirstResource() )
  240. {
  241. GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
  242. pResName = pAna->GenTempResourceName(0);
  243. pType = MakeIDNode( pResName, pType );
  244. SetFirstResource( pAna->AddTransientResource( pResName, pType ) );
  245. }
  246. else
  247. {
  248. pAna->AddTransientResource(GetLengthResource()->GetResourceName(),
  249. GetLengthResource()->GetType()
  250. );
  251. }
  252. }
  253. }
  254. return CG_OK;
  255. }
  256. CG_STATUS
  257. CG_QUALIFIED_POINTER::CorePteUnMarshallAnalysis(
  258. ANALYSIS_INFO * pAna )
  259. {
  260. node_skl * pType;
  261. PNAME pResName;
  262. BOOL fNeedsMaxCount;
  263. BOOL fNeedsFirstAndLength;
  264. // If a resource for the length has not already been allocated, allocate
  265. // one.
  266. if ( ( fNeedsMaxCount = NeedsMaxCountMarshall() ) == TRUE )
  267. {
  268. if( !GetSizeResource() )
  269. {
  270. GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
  271. pResName = pAna->GenTempResourceName(0);
  272. pType = MakeIDNode( pResName, pType );
  273. SetSizeResource( pAna->AddTransientResource( pResName, pType ) );
  274. }
  275. else
  276. pAna->AddTransientResource( GetSizeResource()->GetResourceName(),
  277. GetSizeResource()->GetType()
  278. );
  279. }
  280. if ( ( fNeedsFirstAndLength = NeedsFirstAndLengthMarshall() ) == TRUE )
  281. {
  282. if( !GetLengthResource() )
  283. {
  284. GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
  285. pResName = pAna->GenTempResourceName(0);
  286. pType = MakeIDNode( pResName, pType );
  287. SetLengthResource( pAna->AddTransientResource( pResName, pType ) );
  288. }
  289. else
  290. pAna->AddTransientResource( GetLengthResource()->GetResourceName(),
  291. GetLengthResource()->GetType()
  292. );
  293. if( NeedsExplicitFirst() )
  294. {
  295. if( !GetFirstResource() )
  296. {
  297. GetBaseTypeNode( &pType, SIGN_UNSIGNED, SIZE_LONG, TYPE_INT );
  298. pResName = pAna->GenTempResourceName(0);
  299. pType = MakeIDNode( pResName, pType );
  300. SetFirstResource( pAna->AddTransientResource( pResName, pType ) );
  301. }
  302. else
  303. pAna->AddTransientResource(GetFirstResource()->GetResourceName(),
  304. GetFirstResource()->GetType()
  305. );
  306. }
  307. }
  308. return CG_OK;
  309. }
  310. CG_STATUS
  311. CG_INTERFACE_POINTER::S_OutLocalAnalysis(
  312. ANALYSIS_INFO * pAna )
  313. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  314. Routine Description:
  315. Perform analysis for out params, allocated as locals on the server side.
  316. Arguments:
  317. pAna - A pointer to the analysis block.
  318. Return Value:
  319. CG_OK if all is well
  320. error otherwise.
  321. Notes:
  322. ----------------------------------------------------------------------------*/
  323. {
  324. if( pAna->IsRefAllocDone() )
  325. {
  326. if( pAna->GetCurrentSide() != C_SIDE )
  327. {
  328. PNAME pName = pAna->GenTempResourceName( 0 );
  329. node_skl * pType = GetType();
  330. node_skl * pActualType;
  331. if ( pType->NodeKind() == NODE_DEF )
  332. pActualType = MakeIDNode( pName, pType );
  333. else
  334. pActualType = MakePtrIDNode( pName, pType );
  335. SetResource( pAna->AddLocalResource( pName,
  336. pActualType ));
  337. }
  338. SetAllocatedOnStack( 1 );
  339. }
  340. return CG_OK;
  341. }
  342. CG_STATUS
  343. CG_INTERFACE_POINTER::MarshallAnalysis(
  344. ANALYSIS_INFO * pAna )
  345. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  346. Routine Description:
  347. Perform marshall analysis for interface ptr.
  348. Arguments:
  349. pCCB - The code gen controller block.
  350. Return Value:
  351. CG_OK
  352. Notes:
  353. ----------------------------------------------------------------------------*/
  354. {
  355. pAna;
  356. return CG_OK;
  357. }
  358. CG_STATUS
  359. CG_IIDIS_INTERFACE_POINTER::S_OutLocalAnalysis(
  360. ANALYSIS_INFO * pAna )
  361. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  362. Routine Description:
  363. Perform analysis for out params, allocated as locals on the server side.
  364. Arguments:
  365. pAna - A pointer to the analysis block.
  366. Return Value:
  367. CG_OK if all is well
  368. error otherwise.
  369. Notes:
  370. ----------------------------------------------------------------------------*/
  371. {
  372. if( pAna->IsRefAllocDone() )
  373. {
  374. if( pAna->GetCurrentSide() != C_SIDE )
  375. {
  376. PNAME pName = pAna->GenTempResourceName( 0 );
  377. node_skl * pType = GetType();
  378. node_skl * pActualType;
  379. if ( pType->NodeKind() == NODE_DEF )
  380. pActualType = MakeIDNode( pName, pType );
  381. else
  382. pActualType = MakePtrIDNode( pName, pType );
  383. SetResource( pAna->AddLocalResource( pName,
  384. pActualType ));
  385. }
  386. SetAllocatedOnStack( 1 );
  387. }
  388. return CG_OK;
  389. }
  390. CG_STATUS
  391. CG_IIDIS_INTERFACE_POINTER::MarshallAnalysis(
  392. ANALYSIS_INFO * pAna )
  393. /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  394. Routine Description:
  395. Perform marshall analysis for interface ptr.
  396. Arguments:
  397. pCCB - The code gen controller block.
  398. Return Value:
  399. CG_OK
  400. Notes:
  401. ----------------------------------------------------------------------------*/
  402. {
  403. pAna;
  404. return CG_OK;
  405. }
  406. /****************************************************************************
  407. * utility functions
  408. ***************************************************************************/
  409. U_ACTION
  410. CG_POINTER::RecommendUAction(
  411. SIDE CurrentSide,
  412. BOOL fMemoryAllocated,
  413. BOOL fRefAllocated,
  414. BOOL fBufferReUsePossible,
  415. UAFLAGS AdditionalFlags )
  416. {
  417. U_ACTION UAction = CG_NDR::RecommendUAction( CurrentSide,
  418. fMemoryAllocated,
  419. fRefAllocated,
  420. fBufferReUsePossible,
  421. AdditionalFlags );
  422. return UAction;
  423. }