mirror of https://github.com/lianthony/NT4.0
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.
381 lines
10 KiB
381 lines
10 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
ndrcls.cxx
|
|
|
|
Abstract:
|
|
|
|
Routines for the ndrcls code generation class.
|
|
|
|
Notes:
|
|
|
|
|
|
History:
|
|
|
|
Aug-31-1993 VibhasC Created.
|
|
----------------------------------------------------------------------------*/
|
|
|
|
/****************************************************************************
|
|
* include files
|
|
***************************************************************************/
|
|
#include "becls.hxx"
|
|
#pragma hdrstop
|
|
|
|
/****************************************************************************
|
|
* local definitions
|
|
***************************************************************************/
|
|
/****************************************************************************
|
|
* local data
|
|
***************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* externs
|
|
***************************************************************************/
|
|
/****************************************************************************/
|
|
|
|
|
|
ALIGNMENT_PROPERTY
|
|
CG_NDR::GetNextWireAlignment()
|
|
/*++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
Routine Description:
|
|
|
|
Get the next expected wire alignment.
|
|
|
|
Arguments:
|
|
|
|
None.
|
|
|
|
Return Value:
|
|
|
|
Notes:
|
|
|
|
If this cg entity has a sibling then the next expected alignment is the
|
|
wire alignment of the sibling, else the next wire alignment is treated
|
|
as a dont care (aligned by 1). The absence of a sibling means nothing
|
|
goes on the wire after this entity is marshalled.
|
|
----------------------------------------------------------------------------*/
|
|
{
|
|
|
|
CG_NDR * pS = (CG_NDR *)GetSibling();
|
|
|
|
if( pS )
|
|
{
|
|
return pS->GetWireAlignment();
|
|
}
|
|
return AL_1;
|
|
}
|
|
|
|
expr_node *
|
|
CG_NDR::PresentedLengthExpression(
|
|
CCB * pCCB )
|
|
{
|
|
expr_sizeof * pExpr = new expr_sizeof( GetType() );
|
|
return pExpr;
|
|
}
|
|
|
|
expr_node *
|
|
CG_NDR::PresentedSizeExpression(
|
|
CCB * pCCB )
|
|
{
|
|
expr_sizeof * pExpr = new expr_sizeof( GetType() );
|
|
return pExpr;
|
|
}
|
|
|
|
expr_node *
|
|
CG_NDR::PresentedFirstExpression(
|
|
CCB * pCCB )
|
|
{
|
|
return new expr_constant(0L);
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
utility functions
|
|
****************************************************************************/
|
|
CG_STATUS
|
|
CG_NDR::SizeAnalysis( ANALYSIS_INFO * pAna )
|
|
|
|
{
|
|
pAna->SetEngineProperty( E_SIZING_POSSIBLE |
|
|
E_MARSHALL_POSSIBLE |
|
|
E_UNMARSHALL_POSSIBLE );
|
|
pAna->AddMarshallWeight( 2 );
|
|
return CG_OK;
|
|
}
|
|
CG_STATUS
|
|
CG_NDR::MarshallAnalysis( ANALYSIS_INFO * pAna )
|
|
{
|
|
pAna->SetRpcBufSizeProperty( BSIZE_UNKNOWN );
|
|
pAna->SetCurAlignmentState( MAKE_WC_ALIGNMENT( GetWireAlignment() ) );
|
|
return CG_OK;
|
|
}
|
|
|
|
node_skl *
|
|
CG_NDR::GetBasicType()
|
|
{
|
|
node_skl * pT = GetType();
|
|
|
|
switch (pT->NodeKind())
|
|
{
|
|
case NODE_ID:
|
|
case NODE_FIELD:
|
|
case NODE_PARAM:
|
|
case NODE_DEF:
|
|
return pT->GetBasicType();
|
|
}
|
|
return pT;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_NDR::RefCheckAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
CG_NDR * pC = (CG_NDR *)GetChild();
|
|
|
|
if( pC )
|
|
pC->RefCheckAnalysis( pAna );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_NDR::InLocalAnalysis(
|
|
ANALYSIS_INFO * pAna )
|
|
{
|
|
CG_NDR * pC = (CG_NDR *)GetChild();
|
|
|
|
if( pC )
|
|
pC->InLocalAnalysis( pAna );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_NDR::S_GenInitInLocals(
|
|
CCB * pCCB )
|
|
{
|
|
CG_NDR * pC = (CG_NDR *)GetChild();
|
|
|
|
if( pC )
|
|
pC->S_GenInitInLocals( pCCB );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_NDR::GenRefChecks(
|
|
CCB * pCCB )
|
|
{
|
|
CG_NDR * pC = (CG_NDR *)GetChild();
|
|
|
|
if( pC )
|
|
pC->GenRefChecks( pCCB );
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
extern CMD_ARG * pCommand;
|
|
|
|
void
|
|
CG_NDR::GenNdrParamDescription( CCB * pCCB )
|
|
{
|
|
FORMAT_STRING * pProcFormatString;
|
|
CG_PARAM * pParam;
|
|
CG_NDR * pChild;
|
|
PARAM_ATTRIBUTES Attributes;
|
|
long FormatStringOffset;
|
|
|
|
pChild = (CG_NDR *) GetChild();
|
|
|
|
if ( pChild && (pChild->GetCGID() == ID_CG_GENERIC_HDL) )
|
|
pChild = (CG_NDR *) pChild->GetChild();
|
|
|
|
pProcFormatString = pCCB->GetProcFormatString();
|
|
|
|
pParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
|
|
|
|
if ( IsPipeOrPipeReference() )
|
|
{
|
|
// Pipe parameters are never sized.
|
|
|
|
Attributes.MustSize = 0;
|
|
}
|
|
else
|
|
Attributes.MustSize = pParam->GetInterpreterMustSize();
|
|
|
|
Attributes.IsIn = pParam->IsParamIn();
|
|
Attributes.IsOut = pParam->IsParamOut();
|
|
Attributes.IsReturn = (pParam->GetCGID() == ID_CG_RETURN);
|
|
Attributes.IsBasetype = 0;
|
|
Attributes.IsByValue =
|
|
IsStruct() ||
|
|
IsUnion() ||
|
|
(GetCGID() == ID_CG_TRANSMIT_AS) ||
|
|
(GetCGID() == ID_CG_REPRESENT_AS) ||
|
|
(GetCGID() == ID_CG_USER_MARSHAL);
|
|
Attributes.IsSimpleRef =
|
|
(pParam->GetCGID() != ID_CG_RETURN) &&
|
|
IsPointer() &&
|
|
((CG_POINTER *)this)->IsBasicRefPointer();
|
|
Attributes.IsDontCallFreeInst = pParam->GetDontCallFreeInst();
|
|
Attributes.IsPipe = IsPipeOrPipeReference();
|
|
Attributes.Unused = 0;
|
|
|
|
if ( (Attributes.IsPipe) || (GetCGID() == ID_CG_CONTEXT_HDL) ||
|
|
(IsPointer() && pChild && (pChild->GetCGID() == ID_CG_CONTEXT_HDL)))
|
|
Attributes.MustFree = 0;
|
|
else
|
|
Attributes.MustFree = 1;
|
|
|
|
Attributes.ServerAllocSize = 0;
|
|
|
|
if ( GetCGID() == ID_CG_PTR )
|
|
{
|
|
long Size = 0;
|
|
|
|
(void)
|
|
((CG_POINTER *)this)->InterpreterAllocatesOnStack( pCCB,
|
|
pParam,
|
|
&Size );
|
|
|
|
Attributes.ServerAllocSize = Size / 8;
|
|
}
|
|
|
|
//
|
|
// Now make a final check for a simple ref pointer to a basetype and for
|
|
// a ref pointer to pointer.
|
|
//
|
|
// We mark pointers to basetypes as being both a basetype and a simple
|
|
// ref pointer. Kind of an anomoly, but it works out well in the
|
|
// interpreter.
|
|
//
|
|
// For both of these cases the pointer must have no allocate attributes
|
|
// and can not be a return value.
|
|
//
|
|
if (
|
|
IsPointer() &&
|
|
(((CG_POINTER *)this)->GetPtrType() == PTR_REF) &&
|
|
|
|
! IS_ALLOCATE( ((CG_POINTER *)this)->GetAllocateDetails(),
|
|
ALLOCATE_ALL_NODES ) &&
|
|
! IS_ALLOCATE( ((CG_POINTER *)this)->GetAllocateDetails(),
|
|
ALLOCATE_DONT_FREE ) &&
|
|
|
|
(pParam->GetCGID() != ID_CG_RETURN)
|
|
)
|
|
{
|
|
//
|
|
// Now make sure it's a pointer to basetype and that it is either
|
|
// [in] or [in,out] (in which case we use the buffer to hold it) or
|
|
// that it is [out] and there is room for it on the interpreter's
|
|
// stack. We don't mark enum16s as SimpleRef-Basetype because of
|
|
// their special handling (i.e. wire size != memory size).
|
|
//
|
|
if ( ((CG_POINTER *)this)->IsPointerToBaseType() &&
|
|
( pParam->IsParamIn() ||
|
|
(((CG_POINTER *)this)->GetFormatAttr() & FC_ALLOCED_ON_STACK) ) )
|
|
{
|
|
if ( ((CG_BASETYPE *)pChild)->GetFormatChar() != FC_ENUM16 )
|
|
{
|
|
Attributes.IsBasetype = 1;
|
|
Attributes.IsSimpleRef = 1;
|
|
}
|
|
Attributes.MustFree = 0;
|
|
}
|
|
}
|
|
|
|
// Attributes.
|
|
pProcFormatString->PushShort( *((short *)&Attributes) );
|
|
|
|
// Stack offset as number of ints.
|
|
pProcFormatString->PushShortStackOffset(
|
|
pParam->GetStackOffset( pCCB, I386_STACK_SIZING ),
|
|
pParam->GetStackOffset( pCCB, ALPHA_STACK_SIZING ),
|
|
pParam->GetStackOffset( pCCB, MIPS_STACK_SIZING ),
|
|
pParam->GetStackOffset( pCCB, PPC_STACK_SIZING ),
|
|
pParam->GetStackOffset( pCCB, MAC_STACK_SIZING ) );
|
|
|
|
//
|
|
// If we found a pointer to a basetype, make sure and emit the basetype's
|
|
// param format.
|
|
//
|
|
if ( Attributes.IsSimpleRef && Attributes.IsBasetype )
|
|
{
|
|
pProcFormatString->PushFormatChar(
|
|
((CG_BASETYPE *)pChild)->GetFormatChar() );
|
|
pProcFormatString->PushByte( 0 );
|
|
return;
|
|
}
|
|
|
|
if ( Attributes.IsSimpleRef )
|
|
{
|
|
CG_POINTER * pPointer;
|
|
|
|
pPointer = (CG_POINTER *) this;
|
|
|
|
switch ( pPointer->GetCGID() )
|
|
{
|
|
case ID_CG_STRING_PTR :
|
|
if ( ((CG_STRING_POINTER *)pPointer)->IsStringableStruct() )
|
|
FormatStringOffset = GetFormatStringOffset();
|
|
else
|
|
FormatStringOffset = pPointer->GetFormatStringOffset() + 2;
|
|
break;
|
|
|
|
case ID_CG_SIZE_STRING_PTR :
|
|
if ( ((CG_STRING_POINTER *)pPointer)->IsStringableStruct() )
|
|
FormatStringOffset = GetFormatStringOffset();
|
|
else
|
|
FormatStringOffset = pPointer->GetPointeeFormatStringOffset();
|
|
break;
|
|
|
|
case ID_CG_STRUCT_STRING_PTR :
|
|
FormatStringOffset = GetFormatStringOffset();
|
|
break;
|
|
|
|
default :
|
|
FormatStringOffset = pPointer->GetPointeeFormatStringOffset();
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FormatStringOffset = GetFormatStringOffset();
|
|
}
|
|
|
|
//
|
|
// Push the offset in the type format string to the param's description.
|
|
//
|
|
pProcFormatString->PushShortTypeOffset( (short) FormatStringOffset );
|
|
}
|
|
|
|
void
|
|
CG_NDR::GenNdrParamDescriptionOld( CCB * pCCB )
|
|
{
|
|
FORMAT_STRING * pProcFormatString;
|
|
CG_PARAM * pParam;
|
|
long StackSize;
|
|
long StackElem;
|
|
|
|
pProcFormatString = pCCB->GetProcFormatString();
|
|
|
|
pParam = (CG_PARAM *) pCCB->GetLastPlaceholderClass();
|
|
|
|
StackElem = ( pCommand->GetEnv() == ENV_DOS ||
|
|
pCommand->GetEnv() == ENV_WIN16 ) ? 2 : 4;
|
|
|
|
StackSize = pParam->GetStackSize();
|
|
|
|
StackSize = (StackSize + StackElem - 1) & ~ (StackElem - 1);
|
|
|
|
pProcFormatString->PushSmallStackSize( (char) (StackSize / StackElem) );
|
|
|
|
//
|
|
// Push the offset in the type format string to the param's description.
|
|
//
|
|
pProcFormatString->PushShortTypeOffset( (short) GetFormatStringOffset() );
|
|
}
|
|
|