|
|
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Copyright (c) 1989-2000 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 "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.
/////////////////////////////////////////////////////////////////////////////
enum PROCKIND { PROC_VIRTUAL, PROC_PUREVIRTUAL, PROC_NONVIRTUAL, PROC_STATIC, PROC_DISPATCH, };
// Platforms for interpreter call flavors
typedef enum { PROC_PLATFORM_X86, PROC_PLATFORM_V1_INTERPRETER, PROC_PLATFORM_IA64 } PROC_CALL_PLATFORM;
//
// 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 fHasExtraStatusParam : 1; // the invisible one
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 fSupressHeader : 1; unsigned long fHasAsyncHandle : 1; unsigned long fHasDeny : 1; unsigned long fHasAsyncUUID : 1; unsigned long fHasServerCorr : 1; unsigned long fHasClientCorr : 1; unsigned long fIsBeginProc : 1; unsigned long fIsFinishProc : 1; unsigned long fHasComplexReturn : 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 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;
unsigned short uNotifyTableOffset;
CG_PROC * pCallAsType;
CG_PROC * pAsyncRelative;
//
// Specifies the international character tag-setting routine to be used
// for this proc. If the proc doesn't use international characters
// it will be NULL.
//
node_proc * pCSTagRoutine;
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, BOOL fDeny );
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, long & FaultOffset );
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; }
void SetHasAsyncHandle() { fHasAsyncHandle = TRUE; }
BOOL HasAsyncHandle() { return fHasAsyncHandle; }
void SetHasAsyncUUID() { fHasAsyncUUID = TRUE; }
BOOL HasAsyncUUID() { return fHasAsyncUUID; }
void SetHasServerCorr() { fHasServerCorr = TRUE; }
BOOL HasServerCorr() { return fHasServerCorr; }
void SetHasClientCorr() { fHasClientCorr = TRUE; }
BOOL HasClientCorr() { return fHasClientCorr; }
void SetHasDeny() { fHasDeny = TRUE; }
BOOL HasDeny() { return fHasDeny; }
virtual CG_STATUS Pass1( ANALYSIS_INFO * ) { return CG_OK; }
virtual ID_CG GetCGID() { return ID_CG_PROC; }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
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; }
short GetFloatArgMask( CCB * pCCB );
void SetContextHandleCount( short c ) { ContextHandleCount = c; }
short GetContextHandleCount() { return ContextHandleCount; }
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; }
void SetHasComplexReturnType() { fHasComplexReturn = 1; }
BOOL HasComplexReturnType() { return fHasComplexReturn; }
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 SupressHeader() { return (BOOL)(1 == fSupressHeader); } void SetSupressHeader() { fSupressHeader = TRUE; }
virtual BOOL HasStatuses() { return (BOOL)(fHasStatuses); }
BOOL HasExtraStatusParam() { return ( fHasExtraStatusParam ); }
void SetHasExtraStatusParam() { fHasExtraStatusParam = TRUE; }
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; }
void SetAsyncRelative( CG_PROC *pAsync ) { pAsyncRelative = pAsync; } CG_PROC * GetAsyncRelative() { return pAsyncRelative; } void SetIsBeginProc() { fIsBeginProc = TRUE; } BOOL IsBeginProc() { return fIsBeginProc; }
void SetIsFinishProc() { fIsFinishProc = TRUE; } BOOL IsFinishProc() { return fIsFinishProc; }
void SetCSTagRoutine( node_proc *p ) { pCSTagRoutine = p; }
node_proc * GetCSTagRoutine() { return pCSTagRoutine; }
unsigned short GetNotifyTableOffset( CCB *pCCB ) { uNotifyTableOffset = pCCB->RegisterNotify(this); return uNotifyTableOffset; } //
// 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, PROC_CALL_PLATFORM Platform );
//
// 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);
void GenNdrInterpreterParamStruct32( CCB * pCCB );
void GenNdrInterpreterParamStruct64( CCB * pCCB);
//
// Outputs the call to the manager routine for interpreted server stubs.
//
virtual void GenNdrInterpretedManagerCall( CCB * pCCB );
virtual CG_STATUS C_XFormToProperFormat( CCB * ) { return CG_OK; } virtual CG_STATUS S_XFormToProperFormat( CCB * ) { return CG_OK; }
virtual CG_STATUS S_GenCallManager( CCB * pCCB );
//
// Queries.
//
BOOL MustUseSingleEngineCall( CCB * pCCB );
BOOL UseOldInterpreterMode( CCB * pCCB );
BOOL NeedsServerThunk( CCB * pCCB, CGSIDE Side );
//
// miscellaneous methods.
//
// Oi stack size, includes the return type.
long GetTotalStackSize( CCB * pCCB );
//
// 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 MarshallAnalysis( ANALYSIS_INFO * pAna );
virtual CG_STATUS SizeAnalysis( ANALYSIS_INFO * ) { 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, BOOL fDeny ) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { }
virtual ID_CG GetCGID() { return ID_CG_CALLBACK_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
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, BOOL fDeny) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { }
virtual ID_CG GetCGID() { return ID_CG_OBJECT_PROC; }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } 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 );
BOOL IsStublessProxy();
};
// 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, BOOL fDeny ) : CG_OBJECT_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { }
virtual ID_CG GetCGID() { return ID_CG_INHERITED_OBJECT_PROC; }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
//
// 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, BOOL fDeny ) : CG_OBJECT_PROC( ProcNum, pProc, NULL, NULL, 0, 0, 0, 0, 0, NULL, OptimFlags, 0, fDeny ) { fInherited = fInh; }
virtual ID_CG GetCGID() { return ID_CG_LOCAL_OBJECT_PROC; }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } //
// miscellaneous methods.
//
virtual BOOL IsInherited() { return fInherited; }
virtual CG_STATUS GenClientStub( CCB * ) { return CG_OK; }
virtual CG_STATUS GenServerStub( CCB * ) { 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, BOOL fDeny ) : CG_LOCAL_OBJECT_PROC( ProcNum, pProc, fInh, OptimFlags, fDeny ) { }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } 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, BOOL fDeny ) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ), fHasEncode( fEncode ), fHasDecode( fDecode ) { }
virtual ID_CG GetCGID() { return ID_CG_ENCODE_PROC; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
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 GenClientStubV1( CCB * pCCB );
CG_STATUS GenMesProcEncodeDecodeCall( CCB * pCCB, PROC_CALL_PLATFORM Platform );
virtual CG_STATUS GenServerStub( CCB * ) { 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, BOOL fDeny ) : CG_PROC( ProcNum, pProc, pBH, pHU, fAtLeastOneIn, fAtLeastOneOut, fAtLeastOneShipped, fHasStatuses, fHasFullPtr, pRT, OptimFlags, OpBits, fDeny ) { }
virtual ID_CG GetCGID() { return ID_CG_TYPE_ENCODE_PROC; }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
// Generate the client side (the only side) of the encoding stub.
virtual CG_STATUS GenClientStub( CCB * pCCB );
virtual CG_STATUS GenServerStub( CCB * ) { 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 PARTIAL_IGNORE_PARAM (IN_PARAM | OUT_PARAM | 0x4 )
#define I386_STACK_SIZING 0x1
struct StackOffsets { union { // Historically x86 was overloaded to mean ia64
long x86; // in 64bit.
long ia64; }; };
//
// The following defines the code generation class for the parameter.
//
class CG_PARAM : public CG_NDR { private:
PARAM_DIR_FLAGS fDirAttrs : 3; // directional info
unsigned long fDontCallFreeInst : 1; // as the name says
unsigned long fInterpreterMustSize: 1; // interpreter has to size
unsigned long fIsExtraStatusParam : 1; // invisible fault/comm
unsigned long fIsAsyncHandle : 1; unsigned long fIsCSSTag : 1; // is cs sending tag
unsigned long fIsCSDRTag : 1; // is cs desired recv tag
unsigned long fIsCSRTag : 1; // is cs receiving tag
unsigned long fIsOmitted : 1; // is not in param list
unsigned long fIsForceAllocate : 1; // is forced to allocate flag set
unsigned short Statuses; // comm/fault statuses
short ParamNumber;
expr_node * pFinalExpression; // for the server stub
expr_node * pSizeExpression; // sizing expression
// For unions only.
expr_node * pSwitchExpr; // the switch_is expression
// (if a non-encap union below)
long UnionFormatStringOffset;
// Resource for size / length if necessary.
RESOURCE * pSizeResource; RESOURCE * pLengthResource; RESOURCE * pFirstResource; RESOURCE * pSubstitutePtrResource;
unsigned long MarshallWeight; // the marshaling weight
bool fSaveForAsyncFinish;
long SavedFixedBufferSize;
public: //
// The constructor.
//
CG_PARAM( node_skl * pParam, PARAM_DIR_FLAGS Dir, XLAT_SIZE_INFO & Info , expr_node * pSw, unsigned short Stat );
virtual void SaveForAsyncFinish() { fSaveForAsyncFinish = true; }; virtual bool IsSaveForAsyncFinish() { return fSaveForAsyncFinish; }; //
// TYPEDESC generation routine
//
virtual CG_STATUS GetTypeDesc(TYPEDESC * &ptd, CCB * pCCB);
//
// get and set methods.
//
virtual ID_CG GetCGID() { return ID_CG_PARAM; } virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); }
void SetParamNumber( short pn ) { ParamNumber = pn; }
short GetParamNumber() { MIDL_ASSERT( ParamNumber != -1 ); return ParamNumber; }
long GetStackOffset( CCB * pCCB, long Platform );
void GetStackOffsets( CCB * pCCB, StackOffsets *p ) { // x86 is a synonym for ia64 in 64bit
p->x86 = GetStackOffset( pCCB, I386_STACK_SIZING ); }
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 ); }
BOOL IsExtraStatusParam() { return fIsExtraStatusParam; } void SetIsExtraStatusParam() { fIsExtraStatusParam = TRUE; } virtual RESOURCE * SetSubstitutePtrResource( RESOURCE * pSR ) { return pSubstitutePtrResource = pSR; } BOOL IsAsyncHandleParam() { return fIsAsyncHandle; } void SetIsAsyncHandleParam() { fIsAsyncHandle = TRUE; }
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; }
BOOL GetDontCallFreeInst() { return (BOOL) fDontCallFreeInst; }
void SetDontCallFreeInst( BOOL fDontCall ) { fDontCallFreeInst = fDontCall ? 1 : 0; }
void SetForceAllocate( ) { fIsForceAllocate = TRUE; }
BOOL IsForceAllocate() { return fIsForceAllocate; } 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; }
void SetIsCSSTag(BOOL f) { fIsCSSTag = f; }
BOOL IsCSSTag() { return fIsCSSTag; }
void SetIsCSDRTag(BOOL f) { fIsCSDRTag = f; }
BOOL IsCSDRTag() { return fIsCSDRTag; }
void SetIsCSRTag(BOOL f) { fIsCSRTag = f; }
BOOL IsCSRTag() { return fIsCSRTag; }
BOOL IsSomeCSTag() { return IsCSSTag() || IsCSDRTag() || IsCSRTag(); }
BOOL IsOmittedParam() { return fIsOmitted; }
void SetIsOmittedParam( BOOL f = TRUE ) { fIsOmitted = f; }
long GetFixedBufferSize() { return SavedFixedBufferSize; }
void SetFixedBufferSize(long NewBufferSize) { SavedFixedBufferSize = NewBufferSize; }
long FixedBufferSize( CCB * pCCB ) { return ((CG_NDR *)GetChild())->FixedBufferSize( pCCB ); }
//
// This method performs binding related analysis on the client side.
//
virtual CG_STATUS C_BindingAnalysis( ANALYSIS_INFO * ) { 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 );
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); } BOOL IsParamPartialIgnore() { return (BOOL) ((fDirAttrs & PARTIAL_IGNORE_PARAM ) == PARTIAL_IGNORE_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.
//
virtual expr_node * GenBindOrUnBindExpression( CCB * pCCB, BOOL fBind );
////////////////////////////////////////////////////////////////////////////
virtual CG_STATUS BufferAnalysis( ANALYSIS_INFO * ) { return CG_OK; }
virtual CG_STATUS MarshallAnalysis( ANALYSIS_INFO * pAna );
virtual CG_STATUS SizeAnalysis( ANALYSIS_INFO * ) { 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 );
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:
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; }
virtual void Visit( CG_VISITOR *pVisitor ) { pVisitor->Visit( this ); } 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 );
expr_node * GetFinalExpression(); };
#endif // __PROCCLS_HXX__
|