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.
253 lines
5.7 KiB
253 lines
5.7 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
stgen.cxx
|
|
|
|
Abstract:
|
|
|
|
structure marshalling / unmarshalling stuff.
|
|
|
|
Notes:
|
|
|
|
|
|
History:
|
|
|
|
Dec-15-1993 VibhasC Created.
|
|
|
|
----------------------------------------------------------------------------*/
|
|
|
|
/****************************************************************************
|
|
* include files
|
|
***************************************************************************/
|
|
|
|
#include "becls.hxx"
|
|
#pragma hdrstop
|
|
/****************************************************************************
|
|
* local definitions
|
|
***************************************************************************/
|
|
/****************************************************************************
|
|
* local data
|
|
***************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* externs
|
|
***************************************************************************/
|
|
/****************************************************************************/
|
|
|
|
CG_STATUS
|
|
CG_STRUCT::GenMarshall(
|
|
CCB * pCCB )
|
|
{
|
|
expr_node * pSrc = pCCB->GetSourceExpression();
|
|
expr_node * pDest = pCCB->GetDestExpression();
|
|
STM_ACTION Action;
|
|
CG_NDR * pCG;
|
|
|
|
if( !pCCB->IsRefAllocDone() )
|
|
{
|
|
pSrc = MakeAddressExpressionNoMatterWhat( pSrc );
|
|
}
|
|
|
|
if( IsOffline() )
|
|
{
|
|
|
|
// Generate a call to the structure marshall off line rtn.
|
|
|
|
expr_node * pStubMsg = pCCB->GetStandardResource(
|
|
ST_RES_STUB_MESSAGE_VARIABLE );
|
|
|
|
pStubMsg = MakeAddressExpressionNoMatterWhat( pStubMsg );
|
|
PNAME pProcName = MakeRtnName(
|
|
0, GetType()->GetSymName(), NC_MARSHALL_RTN_NAME );
|
|
|
|
expr_proc_call * pProc = new expr_proc_call( pProcName, 0 );
|
|
|
|
// Make the call.
|
|
|
|
pCCB->GetStream()->NewLine();
|
|
pProc->SetParam( new expr_param( pStubMsg ) );
|
|
pProc->SetParam( new expr_param( pSrc ));
|
|
pProc->PrintCall( pCCB->GetStream(), 0, 0);
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
pCCB->Position( GetWireAlignment(), &Action );
|
|
|
|
Out_AlignmentOrAddAction( pCCB, pDest, Action );
|
|
|
|
Out_Copy( pCCB,
|
|
pDest,
|
|
pSrc,
|
|
new expr_constant( GetMemorySize() ),
|
|
pDest );
|
|
|
|
// Get to the actual final alignment by walking thru each of the fields
|
|
// of the structure.
|
|
|
|
pCG = (CG_NDR *) GetChild();
|
|
|
|
while( pCG )
|
|
{
|
|
pCCB->Advance( pCG->GetWireAlignment(),0,0,0 );
|
|
pCG = (CG_NDR *)pCG->GetSibling();
|
|
}
|
|
|
|
// FOR NOW:: The state machine needs to be modified to recognize
|
|
// an intermediate align by 2, which the machine will enter when
|
|
// current alignment is 4 and next marshall is a 2. For now, A
|
|
// structure will result in worst case alignment state.
|
|
|
|
pCCB->SetCurAlignmentState( MAKE_WC_ALIGNMENT( AL_1 ) );
|
|
}
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_STRUCT::GenSizing(
|
|
CCB * pCCB )
|
|
{
|
|
char * pProcName;
|
|
|
|
// if the structure needs to be sized off line, call the sizing
|
|
// routine.
|
|
|
|
if( IsOffline() )
|
|
{
|
|
expr_node * pSrc = pCCB->GetSourceExpression();
|
|
expr_node * pLengthResource =
|
|
pCCB->GetStandardResource( ST_RES_LENGTH_VARIABLE );
|
|
|
|
// If a pointer to the structure is not avlbl, make an address
|
|
// expression.
|
|
|
|
if( !pCCB->IsRefAllocDone() )
|
|
{
|
|
pSrc = MakeAddressExpressionNoMatterWhat( pSrc );
|
|
}
|
|
|
|
// Generate a procedure call for the aux routine.
|
|
|
|
pProcName = MakeRtnName( 0, GetType()->GetSymName(), NC_SIZE_RTN_NAME );
|
|
|
|
expr_proc_call * pProc = new expr_proc_call( pProcName, 0 );
|
|
|
|
pProc->SetParam( new expr_param( pSrc) );
|
|
pProc->SetParam( new expr_param( pLengthResource ) );
|
|
Out_PlusEquals( pCCB, pLengthResource, pProc );
|
|
|
|
}
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_STRUCT::GenFree(
|
|
CCB * pCCB )
|
|
{
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_STRUCT::GenUnMarshall(
|
|
CCB * pCCB )
|
|
{
|
|
return CG_OK;
|
|
}
|
|
|
|
CG_STATUS
|
|
CG_COMP::S_GenInitOutLocals(
|
|
CCB * pCCB )
|
|
{
|
|
|
|
char Buffer[ 256 ];
|
|
RESOURCE * pResource;
|
|
PNAME p;
|
|
CG_NDR * pLPC = pCCB->GetLastPlaceholderClass();
|
|
|
|
sprintf( Buffer, "%s", pLPC->GetType()->GetSymName() );
|
|
|
|
p = pCCB->GenTRNameOffLastParam( Buffer );
|
|
|
|
pResource = pCCB->GetLocalResource( p );
|
|
|
|
// There is a pointer for the top level structure.
|
|
|
|
Out_Assign( pCCB,
|
|
pCCB->GetSourceExpression(),
|
|
MakeAddressExpressionNoMatterWhat( pResource )
|
|
);
|
|
|
|
// Go zero out the pointers in the structure, for now.
|
|
|
|
if( HasPointer() )
|
|
{
|
|
ITERATOR I;
|
|
CG_FIELD * pCG;
|
|
expr_node * pSrc = pCCB->GetSourceExpression();
|
|
|
|
// Get all the members in the struct which contain pointers. If the
|
|
// structure has been unrolled by the format string generator, the
|
|
// print prefix contains the proper prefixed part of the unrolled path,
|
|
// we just have to add the field name to it.
|
|
|
|
GetPointerMembers( I );
|
|
|
|
while( ITERATOR_GETNEXT( I, pCG ) )
|
|
{
|
|
char * pVarName =
|
|
new char[ strlen( ((CG_FIELD *)pCG)->GetPrintPrefix())+
|
|
strlen( pCG->GetType()->GetSymName()) +
|
|
1
|
|
];
|
|
|
|
strcpy( pVarName, ((CG_FIELD *)pCG)->GetPrintPrefix() );
|
|
strcat( pVarName, pCG->GetType()->GetSymName() );
|
|
|
|
expr_node * pExpr = new expr_pointsto(
|
|
pSrc,
|
|
new expr_variable( pVarName, 0 ));
|
|
expr_node * pAss = new expr_assign(pExpr, new expr_constant(0L));
|
|
|
|
pCCB->GetStream()->NewLine();
|
|
pAss->PrintCall( pCCB->GetStream(), 0, 0 );
|
|
pCCB->GetStream()->Write(';');
|
|
|
|
// this memory area is no longer useful.
|
|
delete pVarName;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
return CG_OK;
|
|
}
|
|
|
|
short
|
|
CG_COMP::GetPointerMembers(
|
|
ITERATOR& I )
|
|
{
|
|
CG_ITERATOR M;
|
|
CG_FIELD * pField;
|
|
short Count = 0;
|
|
|
|
if( HasPointer() )
|
|
{
|
|
GetMembers( M );
|
|
|
|
while( ITERATOR_GETNEXT( M, pField ) )
|
|
{
|
|
if( pField->GetChild()->IsPointer() )
|
|
{
|
|
ITERATOR_INSERT( I, pField );
|
|
Count++;
|
|
}
|
|
}
|
|
}
|
|
return Count;
|
|
}
|
|
|