mirror of https://github.com/tongzx/nt5src
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.
903 lines
21 KiB
903 lines
21 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1989-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
procana.cxx
|
|
|
|
Abstract:
|
|
|
|
This file provides analysis routines for a procedure code generation
|
|
class.
|
|
|
|
Notes:
|
|
|
|
History:
|
|
|
|
|
|
Aug-31-1993 VibhasC Created.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
/****************************************************************************
|
|
* include files
|
|
***************************************************************************/
|
|
#include "allana.hxx"
|
|
#pragma hdrstop
|
|
|
|
#pragma warning ( disable : 4701 )
|
|
|
|
/****************************************************************************
|
|
Implementation of the proc code generator class.
|
|
****************************************************************************/
|
|
|
|
CG_STATUS
|
|
CG_PROC::C_BindingAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform the binding analysis for the client side.
|
|
|
|
Arguments:
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
If it is an auto handle procedure, make sure the global auto handle is
|
|
registered as a global resource.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
node_id * pID;
|
|
|
|
if( IsAutoHandle() )
|
|
{
|
|
pAna->AddStandardResource( ST_RES_AUTO_BH_VARIABLE );
|
|
}
|
|
else
|
|
{
|
|
SetBindingResource( pAna->AddStandardResource( ST_RES_BH_VARIABLE ) );
|
|
|
|
// Initialize the binding resource to 0, so it gets printed out.
|
|
|
|
pID = (node_id *)GetBindingResource()->GetType();
|
|
|
|
pID->SetExpr( new expr_constant( 0L ) );
|
|
|
|
}
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_PROC::MarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
ITERATOR I;
|
|
CG_PARAM * pCG = 0;
|
|
CG_PARAM * pS;
|
|
CG_RETURN * pRT;
|
|
SIDE Side = pAna->GetCurrentSide();
|
|
expr_node * pSE = 0;
|
|
BOOL fReturnNeedsMarshall = FALSE;
|
|
|
|
if( Side == C_SIDE )
|
|
GetInParamList( I );
|
|
else
|
|
GetOutParamList( I );
|
|
|
|
pRT = GetReturnType();
|
|
if ( Side == S_SIDE && pRT != 0 )
|
|
fReturnNeedsMarshall = TRUE;
|
|
|
|
if( ITERATOR_GETCOUNT( I ) )
|
|
{
|
|
ITERATOR_INIT( I );
|
|
|
|
while( ITERATOR_GETNEXT( I, pCG ) )
|
|
{
|
|
// The "invisible" fault or comm status param doesn't marshal.
|
|
|
|
pS = (CG_PARAM *)ITERATOR_PEEKTHIS( I );
|
|
|
|
if ( pCG->IsExtraStatusParam() )
|
|
continue;
|
|
|
|
pCG->MarshallAnalysis( pAna );
|
|
|
|
// Add to the sizing expression.
|
|
|
|
if( pSE )
|
|
pSE = new expr_b_arithmetic( OP_PLUS,
|
|
pSE,
|
|
pCG->GetSizeExpression()
|
|
);
|
|
else
|
|
pSE = pCG->GetSizeExpression();
|
|
}
|
|
}
|
|
|
|
if(fReturnNeedsMarshall)
|
|
{
|
|
|
|
pRT->MarshallAnalysis( pAna );
|
|
|
|
if( pSE )
|
|
pSE = new expr_b_arithmetic( OP_PLUS,
|
|
pSE,
|
|
pRT->GetSizeExpression()
|
|
);
|
|
else
|
|
pSE = pRT->GetSizeExpression();
|
|
}
|
|
|
|
if( pSE )
|
|
SetSizeExpression( pSE );
|
|
else
|
|
SetSizeExpression( new expr_constant( 0L,VALUE_TYPE_NUMERIC_U ));
|
|
|
|
if ( HasExtraStatusParam() )
|
|
{
|
|
GetMembers(I);
|
|
|
|
while ( ITERATOR_GETNEXT( I, pCG ) )
|
|
if ( pCG->IsExtraStatusParam() )
|
|
break;
|
|
|
|
node_skl *pType = pCG->GetType();
|
|
|
|
pCG->SetResource( new RESOURCE( pType->GetSymName(), pType ) );
|
|
}
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_PROC::UnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
ITERATOR I;
|
|
CG_PARAM * pCG = 0;
|
|
CG_PARAM * pS;
|
|
CG_RETURN * pRT = 0;
|
|
SIDE Side = pAna->GetCurrentSide();
|
|
BOOL fReturnNeedsUnMarshall = FALSE;
|
|
|
|
if( Side == C_SIDE )
|
|
GetOutParamList( I );
|
|
else
|
|
GetInParamList( I );
|
|
|
|
if( (Side == C_SIDE ) && (pRT = GetReturnType() ) != 0 )
|
|
fReturnNeedsUnMarshall = TRUE;
|
|
|
|
if( ITERATOR_GETCOUNT(I) )
|
|
{
|
|
while( ITERATOR_GETNEXT( I, pCG ) )
|
|
{
|
|
// The "invisible" fault/comm status param doesn't unmarshal.
|
|
|
|
pS = (CG_PARAM *)ITERATOR_PEEKTHIS( I );
|
|
|
|
if ( pCG->IsExtraStatusParam() )
|
|
continue;
|
|
|
|
pCG->UnMarshallAnalysis( pAna );
|
|
}
|
|
|
|
}
|
|
|
|
if( fReturnNeedsUnMarshall )
|
|
{
|
|
pRT->UnMarshallAnalysis( pAna );
|
|
}
|
|
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
|
|
CG_STATUS
|
|
CG_PROC::S_OutLocalAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform analysis for all params which may be allocated as locals for
|
|
the server side stubs.
|
|
|
|
Arguments:
|
|
|
|
pAna - The analysis block.
|
|
|
|
|
|
Return Value:
|
|
|
|
CG_OK if all is well,
|
|
error otherwise.
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
ITERATOR I;
|
|
CG_PARAM * pParam = 0;
|
|
|
|
GetOutParamList( I );
|
|
|
|
while( ITERATOR_GETNEXT( I, pParam ) )
|
|
{
|
|
pParam->S_OutLocalAnalysis( pAna );
|
|
}
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
|
|
void
|
|
CG_PROC::RpcSsPackageAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform analysis for the need to invoke RpcSsm package at server.
|
|
|
|
Arguments:
|
|
|
|
pAna - The analysis block.
|
|
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
Note that we perform both sides analysis at once as the format string
|
|
is generated usually at the client pass.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
//
|
|
// In ms_ext mode:
|
|
// only if Enable allocate is specified
|
|
// In osf mode:
|
|
// if( RpcSS is recommended by analysis || enable allocate specified )
|
|
//
|
|
SetMustInvokeRpcSSAllocate( 0 );
|
|
|
|
if ( IsRpcSSSpecified() )
|
|
SetMustInvokeRpcSSAllocate( 1 );
|
|
|
|
if ( MustInvokeRpcSSAllocate() || pAna->GetMode() != 0 )
|
|
return;
|
|
|
|
// We analyze parameters in osf to boost performance by skipping
|
|
// unnecessary enable and disable operations.
|
|
//
|
|
|
|
ITERATOR ParamList;
|
|
CG_PARAM * pParam = 0;
|
|
|
|
GetMembers( ParamList );
|
|
|
|
if( ITERATOR_GETCOUNT( ParamList ) )
|
|
{
|
|
ITERATOR_INIT( ParamList );
|
|
|
|
while( ITERATOR_GETNEXT( ParamList, pParam ) )
|
|
{
|
|
pParam->RpcSsPackageAnalysis( pAna );
|
|
}
|
|
}
|
|
|
|
CG_RETURN * pReturn = GetReturnType();
|
|
|
|
if ( pReturn )
|
|
{
|
|
if ( (pAna->GetOptimOption() & OPTIMIZE_INTERPRETER) ||
|
|
(pReturn->GetChild() &&
|
|
( ((CG_NDR *)pReturn->GetChild())->IsPointer() ||
|
|
((CG_NDR *)pReturn->GetChild())->HasPointer() ||
|
|
((CG_NDR *)pReturn->GetChild())->GetCGID() == ID_CG_ENCAP_STRUCT ) )
|
|
)
|
|
{
|
|
// We could do a better job for Oi2 if we watched its stack.
|
|
// Encapsulated union is there as it was a hassle to make it
|
|
// know about its pointers.
|
|
|
|
pAna->SetRpcSSAllocateRecommended( 1 );
|
|
}
|
|
}
|
|
|
|
if ( pAna->IsRpcSSAllocateRecommended() )
|
|
SetMustInvokeRpcSSAllocate( 1 );
|
|
}
|
|
|
|
|
|
CG_STATUS
|
|
CG_PROC::RefCheckAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform ref pointer check analysis.
|
|
|
|
Arguments:
|
|
|
|
pAna - The analysis info block.
|
|
|
|
Return Value:
|
|
|
|
CG_OK
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
ITERATOR I;
|
|
CG_PARAM * pCG = 0;
|
|
CG_RETURN * pRT = 0;
|
|
SIDE Side = pAna->GetCurrentSide();
|
|
BOOL fReturnNeedsMarshall = FALSE;
|
|
|
|
// generate ref check resources for both in and out params.
|
|
GetMembers( I );
|
|
if( (Side == S_SIDE ) && (pRT = GetReturnType() ) != 0 )
|
|
fReturnNeedsMarshall = TRUE;
|
|
|
|
if( ITERATOR_GETCOUNT( I ) )
|
|
{
|
|
ITERATOR_INIT( I );
|
|
|
|
while( ITERATOR_GETNEXT( I, pCG ) )
|
|
{
|
|
pCG->RefCheckAnalysis( pAna );
|
|
}
|
|
}
|
|
|
|
if(fReturnNeedsMarshall)
|
|
{
|
|
pRT->RefCheckAnalysis( pAna );
|
|
}
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_PROC::InLocalAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform analysis for [in] params allocated as locals on server.
|
|
|
|
Arguments:
|
|
|
|
pAna - The analysis info block.
|
|
|
|
Return Value:
|
|
|
|
CG_OK
|
|
|
|
Notes:
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
ITERATOR I;
|
|
CG_PARAM * pCG = 0;
|
|
|
|
GetInParamList( I );
|
|
|
|
if( ITERATOR_GETCOUNT( I ) )
|
|
{
|
|
ITERATOR_INIT( I );
|
|
|
|
while( ITERATOR_GETNEXT( I, pCG ) )
|
|
{
|
|
pCG->InLocalAnalysis( pAna );
|
|
}
|
|
}
|
|
return CG_OK;
|
|
}
|
|
|
|
/****************************************************************************
|
|
Implementation of the parameter code generator class.
|
|
****************************************************************************/
|
|
CG_STATUS
|
|
CG_PARAM::MarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
CG_STATUS Status;
|
|
|
|
//
|
|
// Initialize the analysis block and the parameter for the current side
|
|
// and analysis phase.
|
|
//
|
|
|
|
InitParamMarshallAnalysis( pAna );
|
|
|
|
// Send the message to the lower cg nodes.
|
|
|
|
Status = ((CG_NDR *)GetChild())->MarshallAnalysis( pAna );
|
|
|
|
if( pAna->HasAtLeastOneDeferredPointee() )
|
|
{
|
|
pAna->ResetDeferPointee();
|
|
((CG_NDR *)GetChild())->FollowerMarshallAnalysis( pAna );
|
|
}
|
|
|
|
|
|
ConsolidateParamMarshallAnalysis( pAna );
|
|
|
|
|
|
// The analysis block will now have properties which are a combo of the
|
|
// properties before this param and the properties of this param.
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_PARAM::UnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
|
|
InitParamUnMarshallAnalysis( pAna );
|
|
|
|
// Send the message to the child to perform the same analysis for us
|
|
// and then consolidate the results on return.
|
|
|
|
((CG_NDR *)GetChild())->UnMarshallAnalysis( pAna );
|
|
|
|
if( pAna->HasAtLeastOneDeferredPointee() )
|
|
{
|
|
pAna->ResetDeferPointee();
|
|
((CG_NDR *)GetChild())->FollowerUnMarshallAnalysis( pAna );
|
|
}
|
|
|
|
// Consolidate the results of analysis from the lower nodes.
|
|
|
|
ConsolidateParamUnMarshallAnalysis( pAna );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
void
|
|
CG_PARAM::InitParamMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
|
|
node_skl * pType = GetType();
|
|
PNAME pName = pType->GetSymName();
|
|
CG_NDR * pC = (CG_NDR *)GetChild();
|
|
|
|
// For all cases of generic handles, where the CG_GENERIC_HANDLE will
|
|
// sit below the param, we want to bypass the generic handle class during
|
|
// marshall analysis.
|
|
|
|
if( pC->GetCGID() == ID_CG_GENERIC_HDL )
|
|
{
|
|
pC = (CG_NDR *)pC->GetChild();
|
|
}
|
|
|
|
//
|
|
// Allocate the resource for this parameter. On the client side, this
|
|
// parameter is a param resource, while on the server, this param is a local
|
|
// resource. One the client side, the param has already been added to the
|
|
// resource dictionary.
|
|
|
|
if( pAna->GetCurrentSide() == C_SIDE )
|
|
{
|
|
if( (pC->IsArray()) &&
|
|
(pAna->GetOptimOption() & OPTIMIZE_INTERPRETER )
|
|
)
|
|
{
|
|
pType = MakePtrIDNode( pName, pType->GetChild() );
|
|
}
|
|
SetResource( new RESOURCE( pName, pType) );
|
|
}
|
|
else
|
|
{
|
|
node_skl * pActualType = pType->GetChild();
|
|
|
|
if( (pC->GetCGID() == ID_CG_CONTEXT_HDL ) ||
|
|
(pC->GetChild() && (pC->GetChild()->GetCGID() == ID_CG_CONTEXT_HDL)))
|
|
{
|
|
pActualType = MakeIDNode( pName, new node_def ("NDR_SCONTEXT" ) );
|
|
}
|
|
else if( pC->IsArray() )
|
|
pActualType = MakePtrIDNode( pName, pActualType);
|
|
else
|
|
pActualType = MakeIDNode( pName, pActualType );
|
|
|
|
SetResource( pAna->AddLocalResource( pName, pActualType ));
|
|
}
|
|
|
|
SetSizeResource( 0 );
|
|
SetLengthResource( 0 );
|
|
SetFirstResource( 0 );
|
|
|
|
pAna->SetMemoryAllocDone();
|
|
pAna->ResetRefAllocDone();
|
|
pAna->ResetEmbeddingLevel();
|
|
pAna->ResetIndirectionLevel();
|
|
pAna->SetRefChainIntact();
|
|
pAna->ResetDeferPointee();
|
|
pAna->ResetHasAtLeastOneDeferredPointee();
|
|
pAna->SetLastPlaceholderClass( (CG_NDR *)this );
|
|
}
|
|
|
|
void
|
|
CG_PARAM::ConsolidateParamMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
expr_node * pSE = 0;
|
|
|
|
|
|
// Consolidate the result of the analysis from lower nodes, first into
|
|
// this node, and then into the analysis block.
|
|
|
|
pSE = new expr_constant( (long)0U, VALUE_TYPE_NUMERIC_U );
|
|
|
|
SetSizeExpression( pSE );
|
|
|
|
if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
|
|
{
|
|
pAna->ClearTransientResourceDict();
|
|
}
|
|
}
|
|
|
|
void
|
|
CG_PARAM::InitParamUnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
|
|
node_skl * pType = GetType();
|
|
node_skl * pActualType = pType->GetBasicType();
|
|
PNAME pName = pType->GetSymName();
|
|
CG_NDR * pC = (CG_NDR *)GetChild();
|
|
|
|
// For all cases of generic handles, where the CG_GENERIC_HANDLE will
|
|
// sit below the param, we want to bypass the generic handle class during
|
|
// marshall analysis.
|
|
|
|
if( pC->GetCGID() == ID_CG_GENERIC_HDL )
|
|
{
|
|
pC = (CG_NDR *)pC->GetChild();
|
|
}
|
|
|
|
//
|
|
// Allocate resources. On the client side, a parameter resource is allocated
|
|
// and on the server, a local resource is allocated.
|
|
//
|
|
|
|
SetSubstitutePtrResource( 0 );
|
|
|
|
if( pAna->GetCurrentSide() == C_SIDE )
|
|
{
|
|
pAna->SetDontReUseBuffer();
|
|
if( (pC->IsArray()) &&
|
|
(pAna->GetOptimOption() & OPTIMIZE_INTERPRETER )
|
|
)
|
|
{
|
|
pType = MakePtrIDNode( pName, pType->GetChild() /* GetBasicType() ????????? */ );
|
|
}
|
|
SetResource( new RESOURCE( pName, pType) ) ;
|
|
}
|
|
else if ( ! IsOmittedParam() )
|
|
{
|
|
pC->SetAllocatedOnStack( 1 );
|
|
|
|
if( (pC->GetCGID() == ID_CG_CONTEXT_HDL ) ||
|
|
(pC->GetChild() && (pC->GetChild()->GetCGID() == ID_CG_CONTEXT_HDL)))
|
|
{
|
|
pActualType = MakeIDNode( pName, new node_def ("NDR_SCONTEXT" ) );
|
|
}
|
|
else if( pC->IsArray() )
|
|
{
|
|
pActualType = MakePtrIDNode( pName, pType->GetChild() );
|
|
}
|
|
else
|
|
pActualType = MakeIDNode( pName, pType->GetChild() );
|
|
|
|
pAna->ResetDontReUseBuffer();
|
|
SetResource( pAna->AddLocalResource( pName, pActualType ) );
|
|
}
|
|
|
|
SetSizeResource( 0 );
|
|
SetLengthResource( 0 );
|
|
SetFirstResource( 0 );
|
|
|
|
// Reset for analysis.
|
|
|
|
|
|
pAna->SetMemoryAllocDone();
|
|
pAna->ResetRefAllocDone();
|
|
pAna->ResetEmbeddingLevel();
|
|
pAna->ResetIndirectionLevel();
|
|
pAna->SetRefChainIntact();
|
|
pAna->ResetDeferPointee();
|
|
pAna->ResetHasAtLeastOneDeferredPointee();
|
|
pAna->SetLastPlaceholderClass( (CG_NDR *)this );
|
|
}
|
|
|
|
void
|
|
CG_PARAM::ConsolidateParamUnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
|
|
// Consolidate the result of the analysis from lower nodes, first into
|
|
// this node, and then into the analysis block.
|
|
|
|
if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
|
|
{
|
|
pAna->ClearTransientResourceDict();
|
|
}
|
|
}
|
|
CG_STATUS
|
|
CG_PARAM::S_OutLocalAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform analysis for all params which may be allocated as locals for
|
|
server stub
|
|
|
|
Arguments:
|
|
|
|
pAna - A pointer to the analysis block.
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
Ignore [in, out], since that would be done by the Unmarshall analysis.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
// If the param is [out] only, determine if there is a need for local
|
|
// variables and if they need to be inited.
|
|
|
|
if( IsParamOut() && !IsParamIn() )
|
|
{
|
|
InitParamMarshallAnalysis( pAna );
|
|
|
|
((CG_NDR *)GetChild())->S_OutLocalAnalysis( pAna );
|
|
|
|
}
|
|
return CG_OK;
|
|
}
|
|
|
|
|
|
void
|
|
CG_PARAM::RpcSsPackageAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform analysis for rpcss package enabling.
|
|
|
|
Arguments:
|
|
|
|
pAna - A pointer to the analysis block.
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
This routine should be called only in the osf mode.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
//
|
|
// Package needs to be enabled (only is OSF mode) when the NDR engine
|
|
// is going to do any allocations whatsoever at the server side.
|
|
//
|
|
// In Os this may happen on
|
|
// - anything other than simple type or pointer to simple type
|
|
// - with simple type, if this happens to be enum16
|
|
// In Oi this may happen on
|
|
// - anything [out]
|
|
// - [in] like Os
|
|
// In Oi2 this may happen on
|
|
// - anything [out] when lack of space on -Oi2 stack
|
|
// - [in] like Os
|
|
// (simple types and pointers to simple types are usually on
|
|
// the interpreter stack, if there is space there).
|
|
// However, this cannot be guaranteed.
|
|
|
|
if( IsParamOut() &&
|
|
( pAna->GetOptimOption() & OPTIMIZE_INTERPRETER) )
|
|
{
|
|
// We could do a better job for Oi2 if we watched the its stack.
|
|
|
|
pAna->SetRpcSSAllocateRecommended( 1 );
|
|
return;
|
|
}
|
|
|
|
// We are here with
|
|
// [in] or [in,out] for Oi?
|
|
// any for Os
|
|
// See if this is one of the simple cases mentioned above.
|
|
// This is really a check for the buffer reusage.
|
|
|
|
CG_NDR * pChild = (CG_NDR *)GetChild();
|
|
|
|
if ( pChild->IsSimpleType() &&
|
|
( pChild->GetCGID() != ID_CG_ENUM ||
|
|
pChild->GetCGID() == ID_CG_ENUM &&
|
|
((CG_ENUM*)pChild)->IsEnumLong() )
|
|
&& pChild->GetCGID() != ID_CG_INT3264
|
|
)
|
|
{
|
|
// An [in] arg in the buffer.
|
|
|
|
return;
|
|
}
|
|
|
|
// Note that we don't have to check for allocate(allnodes) etc.
|
|
// as this is not an osf attribute.
|
|
// Also note that we handle top level pointers here.
|
|
|
|
if ( pChild->IsPointer() && ((CG_POINTER *)pChild)->IsRef() )
|
|
{
|
|
// In args would stay in the buffer,
|
|
// out args would be on the Os stack.
|
|
|
|
CG_NDR * pPointee = (CG_NDR *)pChild->GetChild();
|
|
|
|
if ( ( pChild->GetCGID() == ID_CG_PTR ||
|
|
pChild->GetCGID() == ID_CG_STRING_PTR ||
|
|
pChild->GetCGID() == ID_CG_SIZE_PTR )
|
|
&&
|
|
pPointee->IsSimpleType()
|
|
&&
|
|
( pPointee->GetCGID() != ID_CG_ENUM ||
|
|
pPointee->GetCGID() == ID_CG_ENUM &&
|
|
((CG_ENUM*)pPointee)->IsEnumLong() )
|
|
&&
|
|
pPointee->GetCGID() != ID_CG_INT3264
|
|
)
|
|
return;
|
|
}
|
|
|
|
pAna->SetRpcSSAllocateRecommended( 1 );
|
|
}
|
|
|
|
|
|
|
|
/****************************************************************************
|
|
Implementation of the return type node.
|
|
****************************************************************************/
|
|
CG_STATUS
|
|
CG_RETURN::MarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform the size analysis for the return type.
|
|
|
|
Arguments:
|
|
|
|
pAna - A pointer to the analysis block.
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
For the return type, the size analysis contributes nothing on the
|
|
client side, yet we must declare a local variable for the return.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
node_skl * pType = GetType();
|
|
PNAME pName = RETURN_VALUE_VAR_NAME;
|
|
CG_STATUS Status;
|
|
CG_NDR * pC = (CG_NDR *)GetChild();
|
|
|
|
//
|
|
// Always allocate a local resource for the return type.
|
|
//
|
|
|
|
if( (pC->GetCGID() == ID_CG_CONTEXT_HDL ) ||
|
|
(pC->GetChild() && (pC->GetChild()->GetCGID() == ID_CG_CONTEXT_HDL)))
|
|
{
|
|
node_skl * pActualType = pType->GetBasicType();
|
|
pActualType = MakeIDNode( pName, new node_def ("NDR_SCONTEXT" ) );
|
|
SetResource( pAna->AddLocalResource( pName, pActualType ));
|
|
}
|
|
else
|
|
{
|
|
pType = MakeIDNode( pName, pType );
|
|
SetResource( pAna->AddLocalResource( pName, pType ));
|
|
}
|
|
|
|
|
|
SetSizeResource( 0 );
|
|
|
|
// Reset the analysis block for marshalling.
|
|
|
|
pAna->SetMemoryAllocDone();
|
|
pAna->ResetRefAllocDone();
|
|
pAna->ResetEmbeddingLevel();
|
|
pAna->SetRefChainIntact();
|
|
pAna->SetDontReUseBuffer();
|
|
|
|
pAna->SetReturnContext();
|
|
pAna->SetLastPlaceholderClass( (CG_NDR *)this );
|
|
|
|
// Send the analysis message to the child nodes.
|
|
|
|
Status = ((CG_NDR *)GetChild())->MarshallAnalysis( pAna );
|
|
|
|
|
|
SetSizeExpression(
|
|
new expr_constant( 0L, VALUE_TYPE_NUMERIC_U ) );
|
|
|
|
pAna->ResetReturnContext();
|
|
|
|
if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
|
|
{
|
|
pAna->ClearTransientResourceDict();
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_RETURN::UnMarshallAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Perform the buffer analysis for the return type.
|
|
|
|
Arguments:
|
|
|
|
pAna - A pointer to the analysis block.
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
For the return type, the size analysis contributes nothing on the
|
|
client side, yet we must declare a local variable for the return.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
node_skl * pType = GetType();
|
|
PNAME pName = RETURN_VALUE_VAR_NAME;
|
|
CG_STATUS Status;
|
|
|
|
//
|
|
// Always allocate a local resource for the return type.
|
|
//
|
|
|
|
pType = MakeIDNode( pName, pType );
|
|
SetResource( pAna->AddLocalResource( pName, pType ));
|
|
|
|
pAna->SetMemoryAllocDone();
|
|
pAna->ResetRefAllocDone();
|
|
pAna->ResetEmbeddingLevel();
|
|
pAna->SetRefChainIntact();
|
|
pAna->SetDontReUseBuffer();
|
|
|
|
pAna->SetReturnContext();
|
|
pAna->SetLastPlaceholderClass( (CG_NDR *)this );
|
|
|
|
Status = ((CG_NDR *)GetChild())->UnMarshallAnalysis( pAna );
|
|
|
|
pAna->ResetReturnContext();
|
|
|
|
if( pAna->GetOptimOption() & OPTIMIZE_SIZE )
|
|
{
|
|
pAna->ClearTransientResourceDict();
|
|
}
|
|
|
|
return Status;
|
|
}
|