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.
2227 lines
51 KiB
2227 lines
51 KiB
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Copyright (c) 1989 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
proccls.hxx
|
|
|
|
Abstract:
|
|
|
|
Contains definitions for procedure related code gen class definitions.
|
|
|
|
Notes:
|
|
|
|
|
|
History:
|
|
|
|
VibhasC Jul-29-1993 Created.
|
|
----------------------------------------------------------------------------*/
|
|
#ifndef __PROCCLS_HXX__
|
|
#define __PROCCLS_HXX__
|
|
|
|
#include "nulldefs.h"
|
|
|
|
extern "C"
|
|
{
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
}
|
|
|
|
#include "ndrcls.hxx"
|
|
#include "bindcls.hxx"
|
|
#include "sdesc.hxx"
|
|
|
|
class CG_PARAM;
|
|
class CG_RETURN;
|
|
class CG_ENCODE_PROC;
|
|
class CG_TYPE_ENCODE_PROC;
|
|
class CG_INTERFACE;
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// the procedure code generation class.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
// This structure stores information corresponding to the procedure class
|
|
// after analysis has been performed. This structure is specific to the proc
|
|
// code generation class.
|
|
//
|
|
|
|
typedef struct
|
|
{
|
|
|
|
//
|
|
// This field indicates the rpc buffer size property.
|
|
//
|
|
|
|
RPC_BUF_SIZE_PROPERTY fRpcBufSize : 3;
|
|
|
|
//
|
|
// This field indicates the rpc buffer size. If the buffer size property
|
|
// was BSIZE_FIXED, then this is the exact number of bytes needed for the
|
|
// rpc buffer. If the property is BSIZE_UPPER_BOUND, then this is the worst
|
|
// case size of the rpc buffer needed. If this property is BSIZE_UNKNOWN
|
|
// then the value of this field is the fixed part of the rpc buffer size
|
|
// that can be determined at compile time.
|
|
//
|
|
|
|
RPC_BUFFER_SIZE RpcBufferSize;
|
|
|
|
|
|
} PROC_OP_INFO;
|
|
|
|
|
|
enum PROCKIND {
|
|
PROC_VIRTUAL,
|
|
PROC_PUREVIRTUAL,
|
|
PROC_NONVIRTUAL,
|
|
PROC_STATIC,
|
|
PROC_DISPATCH,
|
|
};
|
|
|
|
//
|
|
// This class corresponds to a procedure specified for remoting. This class
|
|
// is responsible for gathering all the information relating to code gen for
|
|
// a procedure and generating code for it. There are 2 kinds of procedures
|
|
// known to mankind. Call and callback procedures. This class provides the
|
|
// basis for both those procedure types. Most of the functionality of the
|
|
// call and callback procedures is the same. The main difference is the side
|
|
// that the code will be generated in.
|
|
//
|
|
|
|
class CG_PROC : public CG_NDR
|
|
{
|
|
private:
|
|
|
|
//
|
|
// Flags storing information about in and out params. The fHasShippedParam
|
|
// field specifies that at least one param exists that is shipped. This
|
|
// is different from fHasIn, because the proc may have an [in] handle_t
|
|
// param which does not get shipped, so no buffer allocation for that is
|
|
// necessary, yet such a param must be generated and initialized in the
|
|
// server stub.
|
|
//
|
|
|
|
unsigned long fHasIn : 1;
|
|
unsigned long fHasOut : 1;
|
|
unsigned long fHasShippedParam : 1;
|
|
unsigned long fHasStatuses : 1;
|
|
unsigned long fNoCode : 1;
|
|
unsigned long fOutLocalAnalysisDone : 1;
|
|
unsigned long fHasFullPtr : 1;
|
|
unsigned long fHasNotify : 1;
|
|
unsigned long fHasNotifyFlag : 1;
|
|
unsigned long fRpcSSSpecified : 1;
|
|
unsigned long fMustRpcSSAllocate : 1;
|
|
unsigned long fReturnsHRESULT : 1;
|
|
unsigned long fHasPipes : 1;
|
|
unsigned long fHookOleLocal : 1;
|
|
unsigned long fSupressHeader : 1;
|
|
|
|
//
|
|
// This is used by type info generation to determine what the FUNKIND should be
|
|
//
|
|
unsigned uProckind;
|
|
|
|
//
|
|
// This field specifies the usage of the handle. This information really
|
|
// needs to be kept only with the cg_proc since the proc is entity
|
|
// responsible for the binding.
|
|
//
|
|
|
|
HANDLE_USAGE HandleUsage : 1;
|
|
|
|
|
|
//
|
|
// This is the optimisation information for all phases of the code
|
|
// generator. The assumption is that code generation will be performed
|
|
// immediately after the analysis, so there is no need for per phase
|
|
// information.
|
|
//
|
|
|
|
PROC_OP_INFO OptimInfo[ CGPHASE_COUNT ];
|
|
|
|
//
|
|
// This field keeps track of the binding handle. Refer to the binding
|
|
// handle class definition for more info on how it is used.
|
|
// If the handle is explicit, then this is a pointer to a cg class which
|
|
// will be part of the param list anyhow. If the handle is implicit, then
|
|
// this is a pointer to a separately allocated binding handle class.
|
|
// Also, this field is used in conjunction with the HandleUsage field,
|
|
// which specifies the usage of the binding: explicit or implicit.
|
|
|
|
CG_HANDLE * pHDLClass;
|
|
|
|
//
|
|
// This field specifies the usage of the handle. This information really
|
|
// needs to be kept only with the cg_proc since the proc is entity
|
|
// responsible for the binding.
|
|
//
|
|
|
|
CG_PARAM * pHandleUsage;
|
|
|
|
|
|
//
|
|
// This field specifies the procedure number. The proc num is the lexical
|
|
// sequence number of the proc specified in the idl file, not counting the
|
|
// callback procedures which have their own lexical sequence. This field
|
|
// is an unsigned int to match the declaration in the rpc message.
|
|
//
|
|
|
|
unsigned int ProcNum;
|
|
|
|
//
|
|
// This field specifies the return type.
|
|
// This is NULL if there is no return type. Otherwise, it points to a
|
|
// CG_RETURN node which in turn points to the CG nodes for the return
|
|
// type.
|
|
//
|
|
|
|
CG_RETURN * pReturn;
|
|
|
|
// the optimization flags to use for this procedure
|
|
|
|
OPTIM_OPTION OptimizationFlags;
|
|
|
|
// The generated size expression generated out of the sizing pass of the
|
|
// code generator.
|
|
|
|
expr_node * pSizeExpr;
|
|
|
|
RESOURCE * pBindingResource;
|
|
|
|
RESOURCE * pStatusResource;
|
|
|
|
// The stub descriptor for the procedure.
|
|
|
|
SDESC * pSStubDescriptor;
|
|
SDESC * pCStubDescriptor;
|
|
|
|
long FormatStringParamStart;
|
|
|
|
// the operation flags such as BROADCAST, IDEMPOTENT, etc in internal format
|
|
unsigned int OperationBits;
|
|
|
|
// the call_as name, if any
|
|
char * pCallAsName;
|
|
|
|
// pointer to MY interface node
|
|
CG_INTERFACE * pMyInterfaceCG;
|
|
|
|
short ContextHandleCount;
|
|
|
|
FORMAT_STRING * pSavedFormatString;
|
|
|
|
FORMAT_STRING * pSavedProcFormatString;
|
|
|
|
short cRefSaved;
|
|
|
|
CG_PROC * pCallAsType;
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor.
|
|
//
|
|
CG_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
CG_HANDLE * pBH,
|
|
CG_PARAM * pHU,
|
|
BOOL fAtLeastOneIn,
|
|
BOOL fAtLeastOneOut,
|
|
BOOL fAtLeastOneShipped,
|
|
BOOL fHasStatuses,
|
|
BOOL fHasFullPtr,
|
|
CG_RETURN * pReturn,
|
|
OPTIM_OPTION OptimFlags,
|
|
unsigned short OpBits );
|
|
|
|
virtual
|
|
unsigned GetProckind()
|
|
{
|
|
return uProckind;
|
|
}
|
|
|
|
virtual
|
|
unsigned SetProckind(unsigned uKind)
|
|
{
|
|
return (uProckind = uKind);
|
|
}
|
|
|
|
CG_PROC * SetCallAsCG(CG_PROC * p)
|
|
{
|
|
return (pCallAsType = p);
|
|
}
|
|
|
|
CG_PROC * GetCallAsCG()
|
|
{
|
|
return (pCallAsType);
|
|
}
|
|
//
|
|
// Generate typeinfo
|
|
//
|
|
virtual
|
|
CG_STATUS GenTypeInfo( CCB * pCCB);
|
|
|
|
void SetRpcSSSpecified( unsigned long f )
|
|
{
|
|
fRpcSSSpecified = f;
|
|
}
|
|
|
|
BOOL IsRpcSSSpecified()
|
|
{
|
|
return (BOOL)( fRpcSSSpecified == 1 );
|
|
}
|
|
|
|
void SetMustInvokeRpcSSAllocate( unsigned long f )
|
|
{
|
|
fMustRpcSSAllocate = f;
|
|
}
|
|
|
|
BOOL MustInvokeRpcSSAllocate()
|
|
{
|
|
return (BOOL)fMustRpcSSAllocate;
|
|
}
|
|
|
|
void SetOutLocalAnalysisDone()
|
|
{
|
|
fOutLocalAnalysisDone = 1;
|
|
}
|
|
BOOL IsOutLocalAnalysisDone()
|
|
{
|
|
return (BOOL)( fOutLocalAnalysisDone == 1);
|
|
}
|
|
|
|
RESOURCE * SetStatusResource( RESOURCE * pR )
|
|
{
|
|
return (pStatusResource = pR);
|
|
}
|
|
|
|
RESOURCE * GetStatusResource()
|
|
{
|
|
return pStatusResource;
|
|
}
|
|
RESOURCE * SetBindingResource( RESOURCE * pR )
|
|
{
|
|
return (pBindingResource = pR);
|
|
}
|
|
|
|
RESOURCE * GetBindingResource()
|
|
{
|
|
return pBindingResource;
|
|
}
|
|
|
|
SDESC * SetSStubDescriptor( SDESC * pSD )
|
|
{
|
|
return (pSStubDescriptor = pSD );
|
|
}
|
|
|
|
SDESC * GetSStubDescriptor()
|
|
{
|
|
return pSStubDescriptor;
|
|
}
|
|
|
|
SDESC * SetCStubDescriptor( SDESC * pSD )
|
|
{
|
|
return (pCStubDescriptor = pSD );
|
|
}
|
|
|
|
SDESC * GetCStubDescriptor()
|
|
{
|
|
return pCStubDescriptor;
|
|
}
|
|
|
|
OPTIM_OPTION SetOptimizationFlags( OPTIM_OPTION Opt )
|
|
{
|
|
return (OptimizationFlags = Opt );
|
|
}
|
|
|
|
OPTIM_OPTION GetOptimizationFlags()
|
|
{
|
|
return OptimizationFlags;
|
|
}
|
|
|
|
unsigned int SetOperationBits( unsigned int OpBits )
|
|
{
|
|
return (OperationBits = OpBits );
|
|
}
|
|
|
|
unsigned int GetOperationBits()
|
|
{
|
|
return OperationBits;
|
|
}
|
|
|
|
void GetCommAndFaultOffset( CCB * pCCB,
|
|
long CommOffset[5],
|
|
long FaultOffset[5] );
|
|
|
|
void SetNoCode()
|
|
{
|
|
fNoCode = TRUE;
|
|
}
|
|
|
|
BOOL IsNoCode()
|
|
{
|
|
return fNoCode;
|
|
}
|
|
|
|
void SetHasNotify()
|
|
{
|
|
fHasNotify = TRUE;
|
|
}
|
|
|
|
void SetHasNotifyFlag()
|
|
{
|
|
fHasNotifyFlag = TRUE;
|
|
}
|
|
|
|
BOOL HasNotify()
|
|
{
|
|
return fHasNotify;
|
|
}
|
|
|
|
BOOL HasNotifyFlag()
|
|
{
|
|
return fHasNotifyFlag;
|
|
}
|
|
|
|
void SetReturnsHRESULT()
|
|
{
|
|
fReturnsHRESULT = TRUE;
|
|
}
|
|
|
|
BOOL ReturnsHRESULT()
|
|
{
|
|
return fReturnsHRESULT;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS Pass1( ANALYSIS_INFO *pAna )
|
|
{
|
|
UNUSED( pAna );
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_PROC;
|
|
}
|
|
|
|
virtual
|
|
BOOL IsProc()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
virtual
|
|
BOOL IsInherited()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
virtual
|
|
BOOL IsDelegated()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Get and set methods.
|
|
//
|
|
|
|
void SetFormatStringParamStart( long Offset )
|
|
{
|
|
FormatStringParamStart = Offset;
|
|
}
|
|
|
|
long GetFormatStringParamStart()
|
|
{
|
|
return FormatStringParamStart;
|
|
}
|
|
|
|
expr_node * SetSizeExpression( expr_node * pE )
|
|
{
|
|
return ( pSizeExpr = pE );
|
|
}
|
|
|
|
expr_node * GetSizeExpression()
|
|
{
|
|
return pSizeExpr;
|
|
}
|
|
|
|
unsigned int SetProcNum( unsigned int ProcNumber )
|
|
{
|
|
return (ProcNum = ProcNumber);
|
|
}
|
|
|
|
virtual
|
|
unsigned int GetProcNum()
|
|
{
|
|
return ProcNum;
|
|
}
|
|
|
|
void SetContextHandleCount( short c )
|
|
{
|
|
ContextHandleCount = c;
|
|
}
|
|
|
|
short GetContextHandleCount()
|
|
{
|
|
return ContextHandleCount;
|
|
}
|
|
|
|
RPC_BUF_SIZE_PROPERTY SetRpcBufSizeProperty(
|
|
RPC_BUF_SIZE_PROPERTY Prop,
|
|
CGPHASE Phase )
|
|
{
|
|
return (OptimInfo[ Phase ].fRpcBufSize = Prop);
|
|
}
|
|
|
|
RPC_BUF_SIZE_PROPERTY GetRpcBufSizeProperty( CGPHASE Phase )
|
|
{
|
|
return OptimInfo[ Phase ].fRpcBufSize;
|
|
}
|
|
|
|
RPC_BUFFER_SIZE SetRpcBufferSize( RPC_BUFFER_SIZE Size,
|
|
CGPHASE Phase
|
|
)
|
|
{
|
|
return (OptimInfo[ Phase ].RpcBufferSize = Size);
|
|
}
|
|
|
|
RPC_BUFFER_SIZE GetRpcBufferSize( CGPHASE Phase )
|
|
{
|
|
return OptimInfo[ Phase ].RpcBufferSize;
|
|
}
|
|
|
|
CG_HANDLE * SetHandleClassPtr( CG_HANDLE * pHC )
|
|
{
|
|
return (pHDLClass = pHC);
|
|
}
|
|
|
|
CG_HANDLE * GetHandleClassPtr()
|
|
{
|
|
return pHDLClass;
|
|
}
|
|
|
|
CG_PARAM * SetHandleUsagePtr( CG_PARAM * pHU )
|
|
{
|
|
return (pHandleUsage = pHU);
|
|
}
|
|
|
|
CG_PARAM * GetHandleUsagePtr()
|
|
{
|
|
return pHandleUsage;
|
|
}
|
|
|
|
HANDLE_USAGE GetHandleUsage()
|
|
{
|
|
return (pHandleUsage)
|
|
? HU_EXPLICIT
|
|
: HU_IMPLICIT;
|
|
}
|
|
|
|
CG_RETURN * SetReturnType( CG_RETURN * pRT )
|
|
{
|
|
return (pReturn = pRT);
|
|
}
|
|
|
|
CG_RETURN * GetReturnType()
|
|
{
|
|
return pReturn;
|
|
}
|
|
|
|
CG_INTERFACE * SetInterfaceNode( CG_INTERFACE * pIntf )
|
|
{
|
|
return (pMyInterfaceCG = pIntf);
|
|
}
|
|
|
|
CG_INTERFACE * GetInterfaceNode()
|
|
{
|
|
return pMyInterfaceCG;
|
|
}
|
|
|
|
char * GetInterfaceName();
|
|
|
|
char * SetCallAsName( char * pName );
|
|
|
|
char * GetCallAsName()
|
|
{
|
|
return pCallAsName;
|
|
}
|
|
|
|
char * GenMangledCallAsName( CCB * pCCB )
|
|
{
|
|
char * pName = new char[62];
|
|
|
|
strcpy( pName, pCCB->GetInterfaceName() );
|
|
strcat( pName, pCCB->GenMangledName() );
|
|
strcat( pName, "_" );
|
|
strcat( pName, pCallAsName );
|
|
return pName;
|
|
}
|
|
|
|
void SetHasAtLeastOneShipped()
|
|
{
|
|
fHasShippedParam = 1;
|
|
}
|
|
|
|
void ResetHasAtLeastOneShipped()
|
|
{
|
|
fHasShippedParam = 0;
|
|
}
|
|
|
|
void SetHasAtLeastOneIn()
|
|
{
|
|
fHasIn = 1;
|
|
}
|
|
|
|
void SetHasAtLeastOneOut()
|
|
{
|
|
fHasOut = 1;
|
|
}
|
|
|
|
void ResetHasAtLeastOneIn()
|
|
{
|
|
fHasIn = 0;
|
|
}
|
|
|
|
void ResetHasAtLeastOneOut()
|
|
{
|
|
fHasOut = 0;
|
|
}
|
|
|
|
BOOL HasAtLeastOneShipped()
|
|
{
|
|
return (BOOL)(fHasShippedParam == 1);
|
|
}
|
|
|
|
BOOL HasAtLeastOneIn()
|
|
{
|
|
return (BOOL)(fHasIn == 1);
|
|
}
|
|
|
|
BOOL HasAtLeastOneOut()
|
|
{
|
|
return (BOOL)(fHasOut == 1);
|
|
}
|
|
|
|
BOOL HasPipes()
|
|
{
|
|
return (BOOL)(fHasPipes == 1);
|
|
}
|
|
|
|
BOOL SetHasPipes(BOOL f);
|
|
|
|
BOOL IsHookOleLocal()
|
|
{
|
|
return (BOOL)(1 == fHookOleLocal);
|
|
}
|
|
|
|
BOOL SupressHeader()
|
|
{
|
|
return (BOOL)(1 == fSupressHeader);
|
|
}
|
|
|
|
void SetHookOleLocal()
|
|
{
|
|
fHookOleLocal = TRUE;
|
|
}
|
|
|
|
void SetSupressHeader()
|
|
{
|
|
fSupressHeader = TRUE;
|
|
}
|
|
|
|
virtual
|
|
BOOL HasStatuses()
|
|
{
|
|
return (BOOL)(fHasStatuses);
|
|
}
|
|
|
|
BOOL HasFullPtr()
|
|
{
|
|
return ( fHasFullPtr );
|
|
}
|
|
|
|
BOOL SetHasFullPtr( BOOL f )
|
|
{
|
|
return ( fHasFullPtr = f );
|
|
}
|
|
|
|
BOOL HasReturn()
|
|
{
|
|
return (BOOL)(pReturn != NULL);
|
|
}
|
|
|
|
BOOL HasOuts()
|
|
{
|
|
return (HasAtLeastOneOut() || HasReturn());
|
|
}
|
|
|
|
BOOL HasInterpreterDeferredFree();
|
|
|
|
BOOL IsNullCall()
|
|
{
|
|
return (!HasAtLeastOneIn() &&
|
|
!HasAtLeastOneOut()&&
|
|
!HasReturn()
|
|
);
|
|
}
|
|
|
|
virtual
|
|
BOOL HasEncode()
|
|
{
|
|
return FALSE;
|
|
}
|
|
virtual
|
|
BOOL HasDecode()
|
|
{
|
|
return FALSE;
|
|
}
|
|
virtual
|
|
BOOL HasAPicklingAttribute()
|
|
{
|
|
return FALSE;
|
|
}
|
|
//
|
|
// Queries.
|
|
//
|
|
|
|
virtual
|
|
BOOL IsAutoHandle()
|
|
{
|
|
return (GetHandleClassPtr() == 0);
|
|
}
|
|
|
|
virtual
|
|
BOOL IsPrimitiveHandle()
|
|
{
|
|
return (!IsAutoHandle()) && GetHandleClassPtr()->IsPrimitiveHandle();
|
|
}
|
|
|
|
virtual
|
|
BOOL IsGenericHandle()
|
|
{
|
|
return (!IsAutoHandle()) && GetHandleClassPtr()->IsGenericHandle();
|
|
}
|
|
|
|
virtual
|
|
BOOL IsContextHandle()
|
|
{
|
|
return (!IsAutoHandle()) && GetHandleClassPtr()->IsContextHandle();
|
|
}
|
|
|
|
//
|
|
// Generate the client and server stubs.
|
|
//
|
|
|
|
virtual
|
|
CG_STATUS GenClientStub( CCB * pCCB );
|
|
|
|
//
|
|
// This method does size calculation analysis for the client side
|
|
// marshalling.
|
|
//
|
|
|
|
//
|
|
// This method performs binding related analysis on the client side.
|
|
//
|
|
|
|
virtual
|
|
CG_STATUS C_BindingAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS RefCheckAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
//
|
|
// Unmarshalling analysis for the server side.
|
|
//
|
|
|
|
// This pair of methods generates the prolog and epilog for the client
|
|
// side marshall.
|
|
//
|
|
|
|
virtual
|
|
CG_STATUS C_GenProlog( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenBind( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenSizing( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenGetBuffer( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitMarshall( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenMarshall( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenSendReceive( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenUnMarshall( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenUnBind( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenFree( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenFreeBuffer( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenEpilog( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenServerStub( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitOutLocals( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitTopLevelStuff( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenProlog( CCB * pCCB );
|
|
|
|
//
|
|
// Format string routines for generating the format string and
|
|
// the NDR calls.
|
|
//
|
|
|
|
virtual
|
|
void GenNdrFormat( CCB * pCCB );
|
|
|
|
void GenNdrFormatV1( CCB * pCCB );
|
|
|
|
void SetupFormatStrings( CCB * pCCB );
|
|
|
|
void UnsetupFormatStrings( CCB * pCCB );
|
|
|
|
void GenNdrFormatProcInfo( CCB * pCCB );
|
|
|
|
//
|
|
// This routine generates the code for the "one call" Ndr case on the
|
|
// client side.
|
|
//
|
|
virtual
|
|
void GenNdrSingleClientCall( CCB * pCCB );
|
|
|
|
expr_node * GenCoreNdrSingleClientCall( CCB * pCCB,
|
|
int WhichRisc );
|
|
|
|
//
|
|
// This routine generates the code for the "one call" Ndr case on the
|
|
// server side. It's actually 3 calls, but who's counting.
|
|
//
|
|
virtual
|
|
void GenNdrSingleServerCall( CCB * pCCB );
|
|
|
|
//
|
|
// Outputs an old style "three call" server stub.
|
|
//
|
|
void GenNdrOldInterpretedServerStub( CCB * pCCB );
|
|
|
|
//
|
|
// Outputs a thunk stub to call the server routine. Thunk stub is called
|
|
// from the interpreter, not the rpc runtime.
|
|
//
|
|
void GenNdrThunkInterpretedServerStub( CCB * pCCB );
|
|
|
|
//
|
|
// Outputs the locals for interpreted server stubs.
|
|
//
|
|
void GenNdrInterpretedServerLocals( CCB * pCCB );
|
|
|
|
//
|
|
// Outputs the param struct for interpreted server stubs.
|
|
//
|
|
void GenNdrInterpreterParamStruct(
|
|
CCB * pCCB,
|
|
BOOL fForAlpha = FALSE );
|
|
|
|
//
|
|
// Outputs the call to the manager routine for interpreted server stubs.
|
|
//
|
|
virtual
|
|
void GenNdrInterpretedManagerCall( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_XFormToProperFormat( CCB * pCCB )
|
|
{
|
|
UNUSED( pCCB );
|
|
return CG_OK;
|
|
}
|
|
virtual
|
|
CG_STATUS S_XFormToProperFormat( CCB * pCCB )
|
|
{
|
|
UNUSED( pCCB );
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS S_GenCallManager( CCB * pCCB );
|
|
|
|
|
|
//
|
|
// Queries.
|
|
//
|
|
|
|
BOOL IsSizingCodeNeeded();
|
|
|
|
BOOL MustUseSingleEngineCall( CCB * pCCB );
|
|
|
|
BOOL UseOldInterpreterMode( CCB * pCCB );
|
|
|
|
BOOL NeedsServerThunk( CCB * pCCB,
|
|
CGSIDE Side );
|
|
|
|
//
|
|
// miscellaneous methods.
|
|
//
|
|
|
|
// Oi stack size, includes the return type.
|
|
|
|
void GetTotalStackSize( CCB * pCCB,
|
|
long * pSize,
|
|
long * pAlphaSize,
|
|
long * pMipsSize,
|
|
long * pPpcSize,
|
|
long * pMacSize );
|
|
|
|
//
|
|
// This method registers pre-allocated stub resources like the params,
|
|
// standard local variables etc, with the corresponding resource dictionary
|
|
// in the analysis block.
|
|
//
|
|
|
|
void C_PreAllocateResources( ANALYSIS_INFO * );
|
|
|
|
virtual
|
|
void S_PreAllocateResources( ANALYSIS_INFO * );
|
|
|
|
virtual
|
|
expr_node * GenBindOrUnBindExpression( CCB * pCCB, BOOL fBind );
|
|
|
|
|
|
short GetInParamList( ITERATOR& );
|
|
|
|
|
|
short GetOutParamList( ITERATOR& );
|
|
|
|
|
|
CG_PARAM * SearchForBindingParam()
|
|
{
|
|
return (CG_PARAM *)GetHandleUsagePtr();
|
|
}
|
|
|
|
|
|
virtual
|
|
CG_STATUS BufferAnalysis( ANALYSIS_INFO * pAna )
|
|
{
|
|
UNUSED( pAna );
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS SizeAnalysis( ANALYSIS_INFO * pAna )
|
|
{
|
|
UNUSED( pAna );
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS S_OutLocalAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
void RpcSsPackageAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
CG_STATUS C_GenMapCommAndFaultStatus( CCB * pCCB );
|
|
|
|
CG_STATUS C_GenMapHRESULT( CCB * pCCB );
|
|
|
|
CG_STATUS C_GenClearOutParams( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenRefChecks( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS InLocalAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitInLocals( CCB * pCCB );
|
|
|
|
unsigned int TranslateOpBitsIntoUnsignedInt();
|
|
|
|
void GetCorrectAllocFreeRoutines(
|
|
CCB * pCCB,
|
|
BOOL fServer,
|
|
char ** pAllocRtnName,
|
|
char ** pFreeRtnName );
|
|
|
|
CG_STATUS GenNotify( CCB * pCCB, BOOL fHasFlag );
|
|
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// the callback proc code generation class.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// this is derived from the regular proc class
|
|
|
|
class CG_CALLBACK_PROC: public CG_PROC
|
|
{
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor. Just call the proc constructor
|
|
//
|
|
CG_CALLBACK_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
CG_HANDLE * pBH,
|
|
CG_PARAM * pHU,
|
|
BOOL fAtLeastOneIn,
|
|
BOOL fAtLeastOneOut,
|
|
BOOL fAtLeastOneShipped,
|
|
BOOL fHasStatuses,
|
|
BOOL fHasFullPtr,
|
|
CG_RETURN * pRT,
|
|
OPTIM_OPTION OptimFlags,
|
|
unsigned short OpBits )
|
|
: CG_PROC( ProcNum,
|
|
pProc,
|
|
pBH,
|
|
pHU,
|
|
fAtLeastOneIn,
|
|
fAtLeastOneOut,
|
|
fAtLeastOneShipped,
|
|
fHasStatuses,
|
|
fHasFullPtr,
|
|
pRT,
|
|
OptimFlags,
|
|
OpBits )
|
|
{
|
|
}
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_CALLBACK_PROC;
|
|
}
|
|
|
|
CG_STATUS GenClientStub( CCB * pCCB );
|
|
|
|
CG_STATUS GenServerStub( CCB * pCCB );
|
|
|
|
|
|
virtual
|
|
BOOL IsAutoHandle()
|
|
{
|
|
return FALSE;
|
|
}
|
|
virtual
|
|
BOOL IsPrimitiveHandle()
|
|
{
|
|
return FALSE;
|
|
}
|
|
virtual
|
|
BOOL IsGenericHandle()
|
|
{
|
|
return FALSE;
|
|
}
|
|
virtual
|
|
BOOL IsContextHandle()
|
|
{
|
|
return FALSE;
|
|
}
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// the object proc code generation classes.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// this is derived from the regular proc class
|
|
|
|
class CG_OBJECT_PROC: public CG_PROC
|
|
{
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor. Just call the proc constructor
|
|
//
|
|
CG_OBJECT_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
CG_HANDLE * pBH,
|
|
CG_PARAM * pHU,
|
|
BOOL fAtLeastOneIn,
|
|
BOOL fAtLeastOneOut,
|
|
BOOL fAtLeastOneShipped,
|
|
BOOL fHasStatuses,
|
|
BOOL fHasFullPtr,
|
|
CG_RETURN * pRT,
|
|
OPTIM_OPTION OptimFlags,
|
|
unsigned short OpBits )
|
|
: CG_PROC( ProcNum,
|
|
pProc,
|
|
pBH,
|
|
pHU,
|
|
fAtLeastOneIn,
|
|
fAtLeastOneOut,
|
|
fAtLeastOneShipped,
|
|
fHasStatuses,
|
|
fHasFullPtr,
|
|
pRT,
|
|
OptimFlags,
|
|
OpBits )
|
|
{
|
|
}
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_OBJECT_PROC;
|
|
}
|
|
|
|
|
|
virtual
|
|
BOOL IsObject()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
virtual
|
|
BOOL IsLocal()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// miscellaneous methods.
|
|
//
|
|
|
|
//
|
|
// This method registers pre-allocated stub resources like the params,
|
|
// standard local variables etc, with the corresponding resource dictionary
|
|
// in the analysis block.
|
|
//
|
|
|
|
|
|
virtual
|
|
CG_STATUS C_GenProlog( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenBind( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenGetBuffer( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenSendReceive( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenFreeBuffer( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS C_GenUnBind( CCB * pCCB );
|
|
|
|
virtual
|
|
void S_PreAllocateResources( ANALYSIS_INFO * );
|
|
|
|
virtual
|
|
CG_STATUS S_GenProlog( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenCallManager( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitMarshall( CCB * pCCB );
|
|
|
|
//
|
|
// Outputs the call to the manager routine for interpreted server stubs.
|
|
//
|
|
virtual
|
|
void GenNdrInterpretedManagerCall( CCB * pCCB );
|
|
|
|
CG_STATUS PrintVtableEntry( CCB * pCCB);
|
|
|
|
void Out_ServerStubProlog( CCB * pCCB,
|
|
ITERATOR& LocalsList,
|
|
ITERATOR& TransientList );
|
|
|
|
void Out_ProxyFunctionPrototype(CCB *pCCB, PRTFLAGS F );
|
|
|
|
void Out_StubFunctionPrototype(CCB *pCCB);
|
|
|
|
CG_STATUS GenCMacro(CCB * pCCB );
|
|
|
|
CG_STATUS GenComClassMemberFunction( CCB * pCCB );
|
|
|
|
CG_STATUS ReGenComClassMemberFunction( CCB * pCCB );
|
|
|
|
virtual
|
|
BOOL IsDelegated()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
void OutProxyRoutineName( ISTREAM * pStream,
|
|
BOOL fForcesDelegation );
|
|
|
|
void OutStubRoutineName( ISTREAM * pStream );
|
|
|
|
};
|
|
|
|
// the class for inherited object procs
|
|
|
|
class CG_INHERITED_OBJECT_PROC: public CG_OBJECT_PROC
|
|
{
|
|
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor. Just call the proc constructor
|
|
//
|
|
CG_INHERITED_OBJECT_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
CG_HANDLE * pBH,
|
|
CG_PARAM * pHU,
|
|
BOOL fAtLeastOneIn,
|
|
BOOL fAtLeastOneOut,
|
|
BOOL fAtLeastOneShipped,
|
|
BOOL fHasStatuses,
|
|
BOOL fHasFullPtr,
|
|
CG_RETURN * pRT,
|
|
OPTIM_OPTION OptimFlags,
|
|
unsigned short OpBits )
|
|
: CG_OBJECT_PROC( ProcNum,
|
|
pProc,
|
|
pBH,
|
|
pHU,
|
|
fAtLeastOneIn,
|
|
fAtLeastOneOut,
|
|
fAtLeastOneShipped,
|
|
fHasStatuses,
|
|
fHasFullPtr,
|
|
pRT,
|
|
OptimFlags,
|
|
OpBits )
|
|
{
|
|
}
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_INHERITED_OBJECT_PROC;
|
|
}
|
|
|
|
|
|
//
|
|
// miscellaneous methods.
|
|
//
|
|
|
|
virtual
|
|
BOOL IsInherited()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
virtual
|
|
BOOL IsDelegated()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
//
|
|
// This method registers pre-allocated stub resources like the params,
|
|
// standard local variables etc, with the corresponding resource dictionary
|
|
// in the analysis block.
|
|
//
|
|
|
|
};
|
|
|
|
// the class for local object procs, whether inherited or not
|
|
|
|
class CG_LOCAL_OBJECT_PROC: public CG_OBJECT_PROC
|
|
{
|
|
|
|
BOOL fInherited;
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor. Just call the proc constructor
|
|
//
|
|
CG_LOCAL_OBJECT_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
BOOL fInh,
|
|
OPTIM_OPTION OptimFlags )
|
|
: CG_OBJECT_PROC( ProcNum,
|
|
pProc,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
NULL,
|
|
OptimFlags,
|
|
0 )
|
|
{
|
|
fInherited = fInh;
|
|
}
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_LOCAL_OBJECT_PROC;
|
|
}
|
|
|
|
|
|
//
|
|
// miscellaneous methods.
|
|
//
|
|
virtual
|
|
BOOL IsInherited()
|
|
{
|
|
return fInherited;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS GenClientStub( CCB * pCCB )
|
|
{
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS GenServerStub( CCB * pCCB )
|
|
{
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
BOOL IsDelegated()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
virtual
|
|
BOOL IsLocal()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
};
|
|
|
|
class CG_IUNKNOWN_OBJECT_PROC : public CG_LOCAL_OBJECT_PROC
|
|
{
|
|
|
|
public:
|
|
//
|
|
// The constructor. Just call the proc constructor
|
|
//
|
|
CG_IUNKNOWN_OBJECT_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
BOOL fInh,
|
|
OPTIM_OPTION OptimFlags )
|
|
: CG_LOCAL_OBJECT_PROC( ProcNum,
|
|
pProc,
|
|
fInh,
|
|
OptimFlags )
|
|
{
|
|
}
|
|
|
|
virtual
|
|
BOOL IsDelegated()
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// the encode proc code generation class.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// this is derived from the regular proc class
|
|
|
|
class CG_ENCODE_PROC: public CG_PROC
|
|
{
|
|
|
|
BOOL fHasEncode;
|
|
BOOL fHasDecode;
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor. Just call the proc constructor
|
|
//
|
|
CG_ENCODE_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
CG_HANDLE * pBH,
|
|
CG_PARAM * pHU,
|
|
BOOL fAtLeastOneIn,
|
|
BOOL fAtLeastOneOut,
|
|
BOOL fAtLeastOneShipped,
|
|
BOOL fHasStatuses,
|
|
BOOL fHasFullPtr,
|
|
CG_RETURN * pRT,
|
|
OPTIM_OPTION OptimFlags,
|
|
unsigned short OpBits,
|
|
BOOL fEncode,
|
|
BOOL fDecode )
|
|
: CG_PROC( ProcNum,
|
|
pProc,
|
|
pBH,
|
|
pHU,
|
|
fAtLeastOneIn,
|
|
fAtLeastOneOut,
|
|
fAtLeastOneShipped,
|
|
fHasStatuses,
|
|
fHasFullPtr,
|
|
pRT,
|
|
OptimFlags,
|
|
OpBits )
|
|
{
|
|
fHasEncode = fEncode;
|
|
fHasDecode = fDecode;
|
|
}
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_ENCODE_PROC;
|
|
}
|
|
|
|
virtual
|
|
BOOL HasEncode()
|
|
{
|
|
return fHasEncode;
|
|
}
|
|
virtual
|
|
BOOL HasDecode()
|
|
{
|
|
return fHasDecode;
|
|
}
|
|
virtual
|
|
BOOL HasAPicklingAttribute()
|
|
{
|
|
return TRUE;
|
|
}
|
|
|
|
// Generate the client side (the only side) of the encoding stub.
|
|
|
|
virtual
|
|
CG_STATUS GenClientStub( CCB * pCCB );
|
|
|
|
|
|
CG_STATUS GenMesProcEncodeDecodeCall( CCB * pCCB,
|
|
BOOL fAlpha );
|
|
|
|
virtual
|
|
CG_STATUS GenServerStub( CCB * pCCB )
|
|
{
|
|
UNUSED( pCCB );
|
|
return CG_OK;
|
|
}
|
|
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// the type encode code generation class.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// this is derived from the regular proc class
|
|
|
|
class CG_TYPE_ENCODE_PROC: public CG_PROC
|
|
{
|
|
public:
|
|
|
|
//
|
|
// The constructor. Just call the proc constructor
|
|
//
|
|
CG_TYPE_ENCODE_PROC(
|
|
unsigned int ProcNum,
|
|
node_skl * pProc,
|
|
CG_HANDLE * pBH,
|
|
CG_PARAM * pHU,
|
|
BOOL fAtLeastOneIn,
|
|
BOOL fAtLeastOneOut,
|
|
BOOL fAtLeastOneShipped,
|
|
BOOL fHasStatuses,
|
|
BOOL fHasFullPtr,
|
|
CG_RETURN * pRT,
|
|
OPTIM_OPTION OptimFlags,
|
|
unsigned short OpBits )
|
|
: CG_PROC( ProcNum,
|
|
pProc,
|
|
pBH,
|
|
pHU,
|
|
fAtLeastOneIn,
|
|
fAtLeastOneOut,
|
|
fAtLeastOneShipped,
|
|
fHasStatuses,
|
|
fHasFullPtr,
|
|
pRT,
|
|
OptimFlags,
|
|
OpBits )
|
|
{
|
|
}
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_TYPE_ENCODE_PROC;
|
|
}
|
|
|
|
// Generate the client side (the only side) of the encoding stub.
|
|
|
|
virtual
|
|
CG_STATUS GenClientStub( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenServerStub( CCB * pCCB )
|
|
{
|
|
UNUSED( pCCB );
|
|
return CG_OK;
|
|
}
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// the parameter code generation class.
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef unsigned long PARAM_DIR_FLAGS;
|
|
|
|
#define IN_PARAM 0x1
|
|
#define OUT_PARAM 0x2
|
|
#define IN_OUT_PARAM (IN_PARAM | OUT_PARAM)
|
|
|
|
#define I386_STACK_SIZING 0x0
|
|
#define ALPHA_STACK_SIZING 0x1
|
|
#define MIPS_STACK_SIZING 0x2
|
|
#define PPC_STACK_SIZING 0x4
|
|
#define MAC_STACK_SIZING 0x8
|
|
|
|
//
|
|
// This structure stores information derived as a result of the analysis
|
|
// pass, for use by the code generator. This structure is specific to a
|
|
// parameter cg class.
|
|
//
|
|
|
|
typedef struct
|
|
{
|
|
|
|
//
|
|
// Note the params buffer size property. Useful for various optimisations,
|
|
// especially during server side unmarshall.
|
|
//
|
|
|
|
RPC_BUF_SIZE_PROPERTY fRpcBufSize : 3;
|
|
|
|
//
|
|
// The field tells whether the offset of this parameter on the wire is
|
|
// fixed relative to the last known good location of the (un)marshalling
|
|
// pointer. This can be used to do away with incrementing the buffer
|
|
// pointer after the (un)marshall if it is not necessary. It is useful
|
|
// to know the exact offset in the rpc buffer where the parameter will
|
|
// reside. During marshalling, the destination pointer can then be derived
|
|
// from a fixed offset w.r.t say the start of the marshalling buffer. The
|
|
// code generator may find that it does not need to keep track of postion
|
|
// within the rpc buffer and hence can do away with the need to increment
|
|
// the rpc buffer pointer at all. On the server side, it can pick up the
|
|
// parameters from known locations in the rpc buffer itself instead of
|
|
// explicitly unmarshalling into local variables and therefore needing to
|
|
// increment the rpc buffer pointer.
|
|
//
|
|
|
|
OFFSET_WRT_PTR_PROPERTY fOffsetWRTPtr : 1;
|
|
|
|
//
|
|
// This field specifies the offset w.r.t the last (param) property.
|
|
// Useful for the code generator to determine if it needs to update the
|
|
// buffer pointer during marshalling / unmarshalling. The actual value
|
|
// of offset wrt the end is not useful since we always generate code
|
|
// for offsert wrt the last known good position.
|
|
//
|
|
|
|
OFFSET_WRT_LAST_PROPERTY fOffsetWRTLast : 1;
|
|
|
|
|
|
//
|
|
// This field is the offset from the last known good location of the
|
|
// (un)marshalling buffer pointer.
|
|
//
|
|
|
|
OFFSET_WRT_PTR OffsetWRTPtr;
|
|
|
|
// Also keep the buffer size requirements for this parameter. If the
|
|
// parameter is fixed size, then this is the total buffer size needed
|
|
// else this is the worst case size. This field is useful on the
|
|
// marshalling side.
|
|
|
|
RPC_BUFFER_SIZE RpcBufferSize;
|
|
|
|
} PARAM_OP_INFO;
|
|
|
|
//
|
|
// The following defines the code generation class for the parameter.
|
|
//
|
|
|
|
class CG_PARAM : public CG_NDR
|
|
{
|
|
private:
|
|
|
|
//
|
|
// quick reference for finding the directional attributes on the
|
|
// parameter.
|
|
//
|
|
|
|
PARAM_DIR_FLAGS fDirAttrs : 2;
|
|
|
|
//
|
|
// A parameters buffer re-use property.
|
|
//
|
|
|
|
BUFFER_REUSE_PROPERTY fBufferReUse : 1;
|
|
|
|
//
|
|
// a flag to indicate that free inst rouitnes shouldn't be called.
|
|
//
|
|
|
|
unsigned long fDontCallFreeInst : 1;
|
|
|
|
//
|
|
// Does the interpreter have to size the param.
|
|
//
|
|
unsigned long fInterpreterMustSize : 1;
|
|
|
|
// Specifies the Engine-Ability of the param.
|
|
|
|
ENGINE_PROPERTY EngineProperty;
|
|
|
|
//
|
|
// Permanently stored optimisation information.
|
|
//
|
|
|
|
PARAM_OP_INFO OptimInfo[ CGPHASE_COUNT ];
|
|
|
|
//
|
|
// Final Expression to be passed to the server side stub procedure.
|
|
//
|
|
|
|
expr_node * pFinalExpression;
|
|
|
|
// The sizing expression.
|
|
|
|
expr_node * pSizeExpression;
|
|
|
|
// Resource for size / length if necessary.
|
|
|
|
RESOURCE * pSizeResource;
|
|
|
|
RESOURCE * pLengthResource;
|
|
|
|
RESOURCE * pFirstResource;
|
|
|
|
RESOURCE * pSubstitutePtrResource;
|
|
|
|
// The marshalling weight.
|
|
|
|
unsigned long MarshallWeight;
|
|
|
|
// the switch_is expression (if we have a non-encap union below)
|
|
|
|
expr_node * pSwitchExpr;
|
|
|
|
// For unions only.
|
|
long UnionFormatStringOffset;
|
|
|
|
// any comm/fault statuses we may have
|
|
|
|
unsigned short Statuses;
|
|
|
|
short ParamNumber;
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor.
|
|
//
|
|
CG_PARAM( node_skl * pParam,
|
|
PARAM_DIR_FLAGS Dir,
|
|
XLAT_SIZE_INFO & Info ,
|
|
expr_node * pSw,
|
|
unsigned short Stat );
|
|
|
|
//
|
|
// TYPEDESC generation routine
|
|
//
|
|
virtual
|
|
CG_STATUS GetTypeDesc(TYPEDESC * &ptd, CCB * pCCB);
|
|
|
|
//
|
|
// get and set methods.
|
|
//
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_PARAM;
|
|
}
|
|
|
|
void SetParamNumber( short pn )
|
|
{
|
|
ParamNumber = pn;
|
|
}
|
|
|
|
short GetParamNumber()
|
|
{
|
|
assert( ParamNumber != -1 );
|
|
return ParamNumber;
|
|
}
|
|
|
|
long GetStackOffset( CCB * pCCB,
|
|
long Platform );
|
|
|
|
long GetStackSize();
|
|
|
|
expr_node * SetSwitchExpr( expr_node * pE )
|
|
{
|
|
return (pSwitchExpr = pE);
|
|
}
|
|
|
|
expr_node * GetSwitchExpr()
|
|
{
|
|
return pSwitchExpr;
|
|
}
|
|
|
|
void SetUnionFormatStringOffset( long offset )
|
|
{
|
|
UnionFormatStringOffset = offset;
|
|
}
|
|
|
|
|
|
long GetUnionFormatStringOffset()
|
|
{
|
|
return UnionFormatStringOffset;
|
|
}
|
|
|
|
virtual
|
|
unsigned short GetStatuses()
|
|
{
|
|
return Statuses;
|
|
}
|
|
|
|
virtual
|
|
BOOL HasStatuses()
|
|
{
|
|
return (BOOL)( Statuses != STATUS_NONE );
|
|
}
|
|
|
|
virtual
|
|
RESOURCE * SetSubstitutePtrResource( RESOURCE * pSR )
|
|
{
|
|
return pSubstitutePtrResource = pSR;
|
|
}
|
|
|
|
virtual
|
|
RESOURCE * GetSubstitutePtrResource()
|
|
{
|
|
return pSubstitutePtrResource;
|
|
}
|
|
|
|
|
|
virtual
|
|
RESOURCE * SetSizeResource( RESOURCE * pSR )
|
|
{
|
|
return pSizeResource = pSR;
|
|
}
|
|
|
|
virtual
|
|
RESOURCE * SetLengthResource( RESOURCE * pLR )
|
|
{
|
|
return pLengthResource = pLR;
|
|
}
|
|
|
|
virtual
|
|
RESOURCE * GetSizeResource()
|
|
{
|
|
return pSizeResource;
|
|
}
|
|
|
|
virtual
|
|
RESOURCE * GetLengthResource()
|
|
{
|
|
return pLengthResource;
|
|
}
|
|
|
|
virtual
|
|
RESOURCE * SetFirstResource( RESOURCE * pR)
|
|
{
|
|
return (pFirstResource = pR);
|
|
}
|
|
|
|
virtual
|
|
RESOURCE * GetFirstResource()
|
|
{
|
|
return pFirstResource;
|
|
}
|
|
|
|
unsigned long SetMarshallWeight( unsigned long W )
|
|
{
|
|
return (MarshallWeight = W);
|
|
}
|
|
|
|
unsigned long GetMarshallWeight()
|
|
{
|
|
return MarshallWeight;
|
|
}
|
|
|
|
ENGINE_PROPERTY InitEngineProperty( ENGINE_PROPERTY E )
|
|
{
|
|
return (EngineProperty &= E);
|
|
}
|
|
|
|
ENGINE_PROPERTY SetEngineProperty( ENGINE_PROPERTY E )
|
|
{
|
|
return (EngineProperty |= E);
|
|
}
|
|
|
|
BOOL GetDontCallFreeInst()
|
|
{
|
|
return (BOOL) fDontCallFreeInst;
|
|
}
|
|
|
|
void SetDontCallFreeInst( BOOL fDontCall )
|
|
{
|
|
fDontCallFreeInst = fDontCall ? 1 : 0;
|
|
}
|
|
|
|
BOOL IsEngineSizingPossible()
|
|
{
|
|
return
|
|
!((EngineProperty & (ENGINE_PROPERTY) E_SIZING_NOT_POSSIBLE) == (ENGINE_PROPERTY) E_SIZING_NOT_POSSIBLE);
|
|
}
|
|
|
|
BOOL IsEngineMarshallPossible()
|
|
{
|
|
return
|
|
!((EngineProperty & (ENGINE_PROPERTY) E_MARSHALL_NOT_POSSIBLE) == (ENGINE_PROPERTY) E_MARSHALL_NOT_POSSIBLE);
|
|
}
|
|
|
|
BOOL IsEngineUnMarshallPossible()
|
|
{
|
|
return
|
|
!((EngineProperty & (ENGINE_PROPERTY) E_UNMARSHALL_NOT_POSSIBLE) == (ENGINE_PROPERTY) E_UNMARSHALL_NOT_POSSIBLE);
|
|
}
|
|
|
|
BOOL IsOptional()
|
|
{
|
|
return(((node_param *)GetType())->IsOptional());
|
|
}
|
|
|
|
BOOL IsRetval()
|
|
{
|
|
return(((node_param *)GetType())->IsRetval());
|
|
}
|
|
|
|
expr_node * SetFinalExpression( expr_node * pR )
|
|
{
|
|
return (pFinalExpression = pR );
|
|
}
|
|
|
|
expr_node * GetFinalExpression()
|
|
{
|
|
return pFinalExpression;
|
|
}
|
|
|
|
expr_node * SetSizeExpression( expr_node * pR )
|
|
{
|
|
return (pSizeExpression = pR );
|
|
}
|
|
|
|
expr_node * GetSizeExpression()
|
|
{
|
|
return pSizeExpression;
|
|
}
|
|
|
|
|
|
BUFFER_REUSE_PROPERTY SetBufferReUseProperty( BUFFER_REUSE_PROPERTY R )
|
|
{
|
|
return (fBufferReUse = R);
|
|
}
|
|
|
|
BUFFER_REUSE_PROPERTY GetBufferReUseProperty()
|
|
{
|
|
return fBufferReUse;
|
|
}
|
|
|
|
OFFSET_WRT_PTR_PROPERTY SetOWRTPtrProperty(
|
|
OFFSET_WRT_PTR_PROPERTY P,
|
|
CGPHASE Phase )
|
|
{
|
|
return (OptimInfo[ Phase ].fOffsetWRTPtr = P );
|
|
}
|
|
|
|
OFFSET_WRT_PTR_PROPERTY GetOWRTPtrProperty(CGPHASE Phase)
|
|
{
|
|
return OptimInfo[ Phase ].fOffsetWRTPtr;
|
|
}
|
|
|
|
RPC_BUF_SIZE_PROPERTY SetRpcBufSizeProperty(
|
|
RPC_BUF_SIZE_PROPERTY P,
|
|
CGPHASE Phase )
|
|
{
|
|
return (OptimInfo[ Phase ].fRpcBufSize = P );
|
|
}
|
|
|
|
RPC_BUF_SIZE_PROPERTY GetRpcBufSizeProperty(CGPHASE Phase)
|
|
{
|
|
return OptimInfo[ Phase ].fRpcBufSize;
|
|
}
|
|
|
|
|
|
OFFSET_WRT_LAST_PROPERTY SetOWRTLastProperty(
|
|
OFFSET_WRT_LAST_PROPERTY P,
|
|
CGPHASE Phase )
|
|
{
|
|
return (OptimInfo[ Phase ].fOffsetWRTLast = P );
|
|
}
|
|
|
|
RPC_BUFFER_SIZE SetRpcBufferSize( RPC_BUFFER_SIZE S,
|
|
CGPHASE Phase )
|
|
{
|
|
return (OptimInfo[ Phase ].RpcBufferSize = S);
|
|
}
|
|
|
|
RPC_BUFFER_SIZE GetRpcBufferSize( CGPHASE Phase )
|
|
{
|
|
return OptimInfo[ Phase ].RpcBufferSize;
|
|
}
|
|
|
|
OFFSET_WRT_LAST_PROPERTY GetOWRTLastProperty(CGPHASE Phase)
|
|
{
|
|
return OptimInfo[ Phase ].fOffsetWRTLast;
|
|
}
|
|
|
|
|
|
OFFSET_WRT_PTR SetOffsetWRTPtr(
|
|
OFFSET_WRT_PTR O,
|
|
CGPHASE Phase )
|
|
{
|
|
return (OptimInfo[ Phase ].OffsetWRTPtr = O);
|
|
}
|
|
|
|
OFFSET_WRT_PTR GetOffsetWRTPtr( CGPHASE Phase )
|
|
{
|
|
return OptimInfo[ Phase ].OffsetWRTPtr;
|
|
}
|
|
//
|
|
// Queries
|
|
//
|
|
|
|
BOOL ShouldUseEngineSizing( CCB * pCCB )
|
|
{
|
|
return (pCCB->GetOptimOption() & OPTIMIZE_SIZE);
|
|
// return (BOOL) ((EngineProperty & E_USE_ENGINE_SIZING) != 0);
|
|
}
|
|
|
|
BOOL ShouldUseEngineMarshall( CCB * pCCB )
|
|
{
|
|
return (pCCB->GetOptimOption() & OPTIMIZE_SIZE);
|
|
// return (BOOL) ((EngineProperty & E_USE_ENGINE_MARSHALL) != 0);
|
|
}
|
|
|
|
BOOL ShouldUseEngineUnMarshall( CCB * pCCB )
|
|
{
|
|
return (pCCB->GetOptimOption() & OPTIMIZE_SIZE);
|
|
// return (BOOL) ((EngineProperty & E_USE_ENGINE_UNMARSHALL) != 0);
|
|
}
|
|
|
|
BOOL ShouldUseEngineFree( CCB * pCCB )
|
|
{
|
|
return (pCCB->GetOptimOption() & OPTIMIZE_SIZE);
|
|
// return (BOOL) ((EngineProperty & E_USE_ENGINE_UNMARSHALL) != 0);
|
|
}
|
|
|
|
//
|
|
// This method performs binding related analysis on the client side.
|
|
//
|
|
|
|
virtual
|
|
CG_STATUS C_BindingAnalysis( ANALYSIS_INFO * pAna )
|
|
{
|
|
UNUSED( pAna );
|
|
return CG_OK;
|
|
}
|
|
|
|
//
|
|
// Generate the client side marshalling code.
|
|
//
|
|
|
|
virtual
|
|
CG_STATUS GenMarshall( CCB * pCCB );
|
|
|
|
|
|
virtual
|
|
CG_STATUS GenUnMarshall( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenSizing( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenFree( CCB * pCCB );
|
|
|
|
CG_STATUS GenTypeEncodingStub( CCB * pCCB );
|
|
|
|
//
|
|
// Generate the server side unmarshalling code.
|
|
//
|
|
|
|
OFFSET_WRT_LAST_PROPERTY S_SetupOffsetWRTLast( CGPHASE Phase );
|
|
|
|
OFFSET_WRT_LAST_PROPERTY C_SetupOffsetWRTLast( CGPHASE Phase );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitOutLocals( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitTopLevelStuff( CCB * pCCB );
|
|
|
|
//
|
|
// Format string routines for generating the format string and
|
|
// the NDR calls for a parameter.
|
|
//
|
|
|
|
virtual
|
|
void GenNdrFormat( CCB * pCCB );
|
|
|
|
void GenNdrFormatOld( CCB * pCCB );
|
|
|
|
void GenNdrMarshallCall( CCB * pCCB );
|
|
|
|
void GenNdrUnmarshallCall( CCB * pCCB );
|
|
|
|
void GenNdrBufferSizeCall( CCB * pCCB );
|
|
|
|
void GenNdrFreeCall( CCB * pCCB );
|
|
|
|
void GenNdrTopLevelAttributeSupport(
|
|
CCB * pCCB,
|
|
BOOL fForClearOut = FALSE );
|
|
|
|
//
|
|
// Queries.
|
|
//
|
|
|
|
BOOL IsParamIn()
|
|
{
|
|
return (BOOL)
|
|
((fDirAttrs & IN_PARAM) == IN_PARAM);
|
|
}
|
|
|
|
BOOL IsParamOut()
|
|
{
|
|
return (BOOL)
|
|
((fDirAttrs & OUT_PARAM) == OUT_PARAM);
|
|
}
|
|
|
|
//
|
|
// Should we use the new NDR engine to marshall/unmarshall a parameter.
|
|
// For now we pass the CCB since it contains optimization information.
|
|
// Later the analyzer will put optimization information in the CG_PARAM
|
|
// class.
|
|
//
|
|
|
|
BOOL UseNdrEngine( CCB * pCCB )
|
|
{
|
|
return (pCCB->GetOptimOption() & OPTIMIZE_SIZE);
|
|
}
|
|
|
|
//
|
|
// miscellaneous methods.
|
|
//
|
|
|
|
ALIGNMENT_PROPERTY GetExpectedAlignment();
|
|
|
|
virtual
|
|
expr_node * GenBindOrUnBindExpression( CCB * pCCB, BOOL fBind );
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
virtual
|
|
CG_STATUS BufferAnalysis( ANALYSIS_INFO * pAna )
|
|
{
|
|
UNUSED( pAna );
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS SizeAnalysis( ANALYSIS_INFO * pAna )
|
|
{
|
|
UNUSED( pAna );
|
|
return CG_OK;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS S_OutLocalAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
void RpcSsPackageAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
void InitParamMarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
void InitParamUnMarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
void ConsolidateParamMarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
void ConsolidateParamUnMarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
void FinalizeEngineUsage( ANALYSIS_INFO * pAna,
|
|
BOOL fMarshall );
|
|
|
|
virtual
|
|
CG_STATUS GenRefChecks( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitInLocals( CCB * pCCB );
|
|
|
|
void SetInterpreterMustSize( BOOL f )
|
|
{
|
|
fInterpreterMustSize = f ? 1 : 0;
|
|
}
|
|
|
|
BOOL GetInterpreterMustSize()
|
|
{
|
|
return fInterpreterMustSize;
|
|
}
|
|
};
|
|
|
|
|
|
//
|
|
// The return-type code generation class
|
|
//
|
|
// This is a place-holder node for the return type, much like the param
|
|
// and field nodes. This way, info about marshalling/unmarshalling the
|
|
// return type doesn't need to clutter up the proc node.
|
|
//
|
|
// If the function has no return (or returns "void") then no CG_RETURN
|
|
// is generated for the function.
|
|
//
|
|
|
|
class CG_RETURN : public CG_PARAM
|
|
{
|
|
private:
|
|
|
|
// The rpc buffer size property.
|
|
|
|
RPC_BUF_SIZE_PROPERTY fRpcBufSize : 4;
|
|
|
|
// The buffer size.
|
|
|
|
RPC_BUFFER_SIZE RpcBufferSize;
|
|
|
|
public:
|
|
|
|
//
|
|
// The constructor.
|
|
//
|
|
CG_RETURN( node_skl * pRetType,
|
|
XLAT_SIZE_INFO & Info,
|
|
unsigned short Stat )
|
|
: CG_PARAM( pRetType,
|
|
OUT_PARAM,
|
|
Info,
|
|
NULL,
|
|
Stat )
|
|
{
|
|
}
|
|
|
|
//
|
|
// get and set methods.
|
|
//
|
|
|
|
virtual
|
|
ID_CG GetCGID()
|
|
{
|
|
return ID_CG_RETURN;
|
|
}
|
|
|
|
|
|
RPC_BUFFER_SIZE SetRpcBufferSize( RPC_BUFFER_SIZE Size,
|
|
CGPHASE Phase
|
|
)
|
|
{
|
|
UNUSED( Phase );
|
|
return (RpcBufferSize = Size);
|
|
}
|
|
|
|
RPC_BUFFER_SIZE GetRpcBufferSize( CGPHASE Phase )
|
|
{
|
|
UNUSED( Phase );
|
|
return RpcBufferSize;
|
|
}
|
|
|
|
virtual
|
|
CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS UnMarshallAnalysis( ANALYSIS_INFO * pAna );
|
|
|
|
virtual
|
|
CG_STATUS GenMarshall( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenUnMarshall( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenSizing( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS GenFree( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitOutLocals( CCB * pCCB );
|
|
|
|
virtual
|
|
CG_STATUS S_GenInitTopLevelStuff( CCB * pCCB );
|
|
|
|
void FinalizeEngineUsage( ANALYSIS_INFO * pAna,
|
|
BOOL fMarshall );
|
|
|
|
expr_node * GetFinalExpression();
|
|
};
|
|
|
|
#endif // __PROCCLS_HXX__
|
|
|