/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Copyright (c) 1989-1999 Microsoft Corporation Module Name: ilctxt.cxx Abstract: Intermediate Language translator context management routines Notes: Author: GregJen Jun-11-1993 Created. Notes: ----------------------------------------------------------------------------*/ /**************************************************************************** * include files ***************************************************************************/ #include "becls.hxx" #pragma hdrstop #include "nodeskl.hxx" #include "ilxlat.hxx" #include "cmdana.hxx" #include "optprop.hxx" #include "ilreg.hxx" #include "ndrcls.hxx" /**************************************************************************** * externs ***************************************************************************/ extern CMD_ARG * pCommand; /**************************************************************************** * definitions ***************************************************************************/ // #define trace_cg //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::XLAT_SIZE_INFO // // Notes: // // // //-------------------------------------------------------------------- XLAT_SIZE_INFO::XLAT_SIZE_INFO( CG_NDR * pCG ) { ZeePee = pCommand->GetZeePee(); MemAlign = pCG->GetMemoryAlignment(); WireAlign = pCG->GetWireAlignment(); MemSize = pCG->GetMemorySize(); WireSize = pCG->GetWireSize(); MemOffset = 0; WireOffset = 0; MustAlign = false; } //-------------------------------------------------------------------- // // ::RoundToAlignment // // Helper round-up routine // // Notes: // // // //-------------------------------------------------------------------- inline unsigned long RoundToAlignment( unsigned long & Offset, unsigned short Alignment ) { unsigned long AlignFactor = Alignment - 1; return (Offset = (Offset + AlignFactor) & ~AlignFactor ); } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::BaseTypeSizes // // Notes: // // Merges attributes for a base type with the given context. // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::BaseTypeSizes( node_skl * pNode ) { unsigned short MS, WS; switch( pNode->NodeKind() ) { case NODE_DOUBLE: case NODE_HYPER: case NODE_INT64: case NODE_LONGLONG: { MS=8; WS=8; break; }; case NODE_INT128: case NODE_FLOAT80: //BUG, BUG double check this once VC supports case NODE_FLOAT128: { MS=16; WS = 16; break; } case NODE_POINTER: case NODE_HANDLE_T: { MS = (unsigned short) SIZEOF_MEM_PTR(); WS = (unsigned short) SIZEOF_WIRE_PTR(); break; }; case NODE_INT3264: { MS = (unsigned short) SIZEOF_MEM_INT3264(); WS = (unsigned short) SIZEOF_WIRE_INT3264(); break; }; case NODE_FLOAT: case NODE_LONG: case NODE_INT32: case NODE_INT: case NODE_E_STATUS_T: { MS=4; WS=4; break; }; case NODE_SHORT: case NODE_WCHAR_T: { MS=2; WS=2; break; }; case NODE_SMALL: case NODE_CHAR: case NODE_BOOLEAN: case NODE_BYTE: { MS=1; WS=1; break; }; default: { MS=0; WS=0; break; } } GetMemSize() = MS; GetMemAlign() = __max(MS,GetMemAlign()); GetWireSize() = WS; GetWireAlign() = __max(WS,GetWireAlign()); }; //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::EnumTypeSizes // // Notes: // // Merges in the sizes for an enum. // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::EnumTypeSizes( node_skl*, BOOL Enum32 ) /* Called when xlating node_enum: Enum32 means [enum_v1] used. */ { unsigned short MS, WS; // note - this needs to check environment WS = unsigned short( ( Enum32 ) ? 4 : 2 ); MS = 4; GetMemSize() = MS; GetMemAlign() = __max(MS, GetMemAlign()); GetWireSize() = WS; GetWireAlign() = __max(WS, GetWireAlign()); }; //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::ContextHandleSizes // // Notes: // // // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::ContextHandleSizes( node_skl * pNode ) { FixMemSizes( pNode ); GetWireSize() = 20; GetWireAlign() = 4; }; //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::ArraySize // // Notes: // // // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::ArraySize( node_skl*, FIELD_ATTR_INFO * pFA ) { // if conformant, set sizes to 0 and return if ( pFA->Kind & FA_CONFORMANT ) { MemSize = WireSize = 0; return; } // round up element size to alignment boundary // Element is already rounded up. // RoundToAlignment( MemSize, MemAlign ); // RoundToAlignment( WireSize, WireAlign ); // compute number of elements and multiply... unsigned long ElementCount; ElementCount = (ulong) pFA->pSizeIsExpr->GetValue(); MemSize *= ElementCount; WireSize *= ElementCount; } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::GetOffset // // Notes: // For use only by field nodes !! // // Fetch the offsets from another size info block // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::GetOffset( XLAT_SIZE_INFO & pInfo ) { MemOffset = pInfo.MemOffset; WireOffset = pInfo.WireOffset; } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::AlignOffset // // Notes: // For use only by field and struct/union nodes!! // // Round the offsets up to the corresponding alignments. // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::AlignOffset() { RoundToAlignment( MemOffset, MemAlign ); RoundToAlignment( WireOffset, WireAlign ); } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::AlignEmbeddedUnion // // Notes: // For use only by field and struct/union nodes!! // // Round the offsets up to the corresponding alignments. // don't round up the wire offset // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::AlignEmbeddedUnion() { RoundToAlignment( MemOffset, MemAlign ); RoundToAlignment( MemSize, MemAlign ); // RoundToAlignment( WireOffset, WireAlign ); } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::AlignConfOffset // // Notes: // For use only by field and struct/union nodes!! // // Round the offsets up to the corresponding alignments. // // the Mem offset passed down from the parent // of the conformant field is aligned // the Wire offset passed down from the parent is advanced by // the wire size and then aligned // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::AlignConfOffset() { RoundToAlignment( MemOffset, MemAlign ); //WireSize += WireOffset; WireOffset += WireSize; RoundToAlignment( WireOffset, WireAlign ); } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::AdjustForZP // // Notes: // For use only by field and struct/union nodes!! // // Round the offsets up to the corresponding alignments. // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::AdjustForZP() { if ( ( MemAlign > ZeePee ) && !MustAlign ) MemAlign = ZeePee; } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::AdjustSize // // Notes: // For use only by field and struct nodes!! // // Add current offsets to current sizes // pad MemSize out to ZeePee // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::AdjustSize() { MemSize += MemOffset; MemOffset = MemSize; WireSize += WireOffset; WireOffset = WireSize; } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::AdjustConfSize // // Notes: // For use only by field and struct nodes!! // // Add current offsets to current sizes // pad MemSize out to ZeePee // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::AdjustConfSize() { MemSize += MemOffset; MemOffset = MemSize; // don't count padding before the conformance (in case it has size 0) /***** WireSize += WireOffset; WireOffset = WireSize; ******/ } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::AdjustTotalSize // // Notes: // For use only by field and struct/union nodes!! // // Add current offsets to current sizes // pad MemSize out to ZeePee // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::AdjustTotalSize() { RoundToAlignment( MemSize, MemAlign ); } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::Ndr64AdjustTotalStructSize // // Notes: // For use only by field and struct nodes!! // // Add current offsets to current sizes // pad MemSize and BuffSize out to ZeePee // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::Ndr64AdjustTotalStructSize() { RoundToAlignment( WireSize, WireAlign ); RoundToAlignment( MemSize, MemAlign ); } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::FixMemSizes // // Notes: // // This routine fixes up mem sizes when they are different from what // the IL translate of children generated // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::FixMemSizes( node_skl * pNode ) { FRONT_MEMORY_INFO MemInfo = pNode->GetMemoryInfo(); MemSize = MemInfo.Size; MemAlign = MemInfo.Align; MustAlign = MemInfo.IsMustAlign; } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::IgnoredPointerSizes // // Notes: // // This routine fixes up sizes for an ignored pointer // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::IgnoredPtrSizes() { MemSize = SIZEOF_MEM_PTR(); MemAlign = (unsigned short) SIZEOF_MEM_PTR(); } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::ReturnSize // // Notes: // // Copy the size information up into the parent. // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::ReturnSize( XLAT_SIZE_INFO & pCtxt ) { if ( pCtxt.MemAlign > MemAlign ) MemAlign = pCtxt.MemAlign; MemSize = pCtxt.MemSize; if ( pCtxt.WireAlign > WireAlign ) WireAlign = pCtxt.WireAlign; WireSize = pCtxt.WireSize; MustAlign = MustAlign || pCtxt.MustAlign; // note: ZeePee is NOT propogated up, only down // note: offsets are propogated up specially } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::ReturnConfSize // // Notes: // // Copy the size information up into the parent. // Don't overwrite the wire size the parent already has // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::ReturnConfSize( XLAT_SIZE_INFO & pCtxt ) { if ( pCtxt.MemAlign > MemAlign ) MemAlign = pCtxt.MemAlign; MemSize = pCtxt.MemSize; if ( pCtxt.WireAlign > WireAlign ) WireAlign = pCtxt.WireAlign; // WireSize = pCtxt.WireSize; MustAlign = MustAlign || pCtxt.MustAlign; // note: ZeePee is NOT propogated up, only down // note: offsets are propogated up specially } //-------------------------------------------------------------------- // // XLAT_SIZE_INFO::ReturnUnionSize // // Notes: // // Copy the size information up into the parent. // //-------------------------------------------------------------------- void XLAT_SIZE_INFO::ReturnUnionSize( XLAT_SIZE_INFO & pCtxt ) { if ( pCtxt.MemAlign > MemAlign ) MemAlign = pCtxt.MemAlign; if ( pCtxt.MemSize > MemSize ) MemSize = pCtxt.MemSize; if ( pCtxt.WireAlign > WireAlign ) WireAlign = pCtxt.WireAlign; if ( pCtxt.WireSize > WireSize ) WireSize = pCtxt.WireSize; MustAlign = MustAlign || pCtxt.MustAlign; // note: ZeePee is NOT propogated up, only down // note: offsets are propogated up specially }