subsect.cpp

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 429 行 · 第 1/2 页

CPP
429
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
*               DESCRIBE IT HERE!
*
****************************************************************************/


#include <assert.h>
#include <wcstack.h>
#include <string.hpp>
#include "common.hpp"
#include "cverror.hpp"
#include "subsect.hpp"

WCStack< SymbolStruct*, WCPtrSList<SymbolStruct> > SstAlignSym::symStack;

/*SstGlobalTypes::~SstGlobalTypes()
{
    for ( unsigned_16 i = ToTypeIndex(0);
          i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
        delete */

void SstGlobalTypes::FixUpTypes( const type_index startIndex )
/************************************************************/
{
    for ( uint i = startIndex;
          i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
        _globalTypingInfo[i] -> FixTypeIndex();
    }
}

void SstGlobalTypes::ProcessTypes( LFLocalTypeRecord* target )
/************************************************************/
{
    WCPtrSListIter<LFTypeRecord> iter(_globalTypingInfo.Find(target));
    while ( ++iter ) {
        if ( iter.current() -> IsEquivalent( *target ) ) {
            return;
        }
    }
    InsertNewType(target);
}

bool SstGlobalTypes::LoadTypes( Retriever& retriever, const module mod )
/**********************************************************************/
{
    char*       buffer;
    unsigned_32 length;
    if ( ! retriever.ReadSubsection(buffer,length,sstTypes,mod) ) {
        return FALSE;
    }
    char*       end = &buffer[length];
    if ( * (unsigned_32 *) buffer != CV4_HEADER ) {
        ::Warning("invalid header dectected in types.");
    }
    // skip the header.
    buffer += LONG_WORD;
    // if it is the first module, just load the types into the global
    // table without packing.
    if ( mod == 1 ) {
        while ( buffer < end ) {
            _globalTypingInfo.Insert( new LFGlobalTypeRecord(ToTypeIndex(_globalTypingInfo.Entries()),buffer));
            buffer += WORD + * (unsigned_16 *) buffer;
        }
        TypeMap.Set( CV_FIRST_NONPRIM + _globalTypingInfo.Entries() );
        return TRUE;
    } else {
        while ( buffer < end ) {
            _localTypingInfo.Insert( new LFLocalTypeRecord(ToTypeIndex(_localTypingInfo.Entries()),buffer));
            buffer += WORD + * (unsigned_16 *) buffer;
        }
        TypeMap.Reset(_localTypingInfo.Entries());
    }
    uint oldCount = _globalTypingInfo.Entries();

    // Full type packing is not implemented due to its long running time
    // when input is relatively big.  Here only packs records that can be
    // hashed, these records are structs, unions, enums, class.  And they
    // will likely reference a lot of other records, so partial packing
    // is not that bad after all.

    WCPtrSListIter<LFTypeRecord> iter(_localTypingInfo._hashRecords);
    while ( ++iter ) {
        if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) {
            ProcessTypes( iter.current() );
        }
    }
    // Anything that is left will be inserted as a new type into the global
    // table.
    iter.reset(_localTypingInfo._otherRecords);
    while ( ++iter ) {
        if ( ! TypeMap.IsDone( iter.current() -> TypeIndex() ) ) {
            InsertNewType( iter.current() );
        }
    }
    FixUpTypes(ToTypeIndex(oldCount));

    // Selectively destruct the types in the local table.  If the type is
    // a new type, then only release the memory of a bare LFLocalTypeRecord.
    // Otherwise, release the memory of a bare record plus the pointer to
    // LFLeafStruct.  This is bad style, but can boost performance by not
    // having to create a constructor and do a pointer copy only when
    // transfer types from the local table to the global table.  See the
    // LFGlobalTypeRecord declaration for more details.

    for ( uint i = CV_FIRST_NONPRIM;
          i < ToTypeIndex(_localTypingInfo.Entries()); i++ ) {
        if ( ! TypeMap.IsNewType(i) ) {
        // If not a new type, release pointer memory as well.
            _localTypingInfo[i]->ManualDestruct();
        }
        // release bare LFLocalTypeRecord memory.
        delete _localTypingInfo[i];
    }
    _localTypingInfo.Clear();
    return TRUE;
}

void SstGlobalTypes::Append( LFLocalTypeRecord* typeRecord )
/**********************************************************/
{
    _globalTypingInfo.Insert( new LFGlobalTypeRecord (typeRecord));
}

void SstGlobalTypes::Put( ExeMaker& eMaker ) const
{
    unsigned_32 offset = 0;
    uint        i;

    eMaker.DumpToExe( (unsigned_32) 0 );
    eMaker.DumpToExe( (unsigned_32) _globalTypingInfo.Entries() );
    for ( i = ToTypeIndex(0); i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
        eMaker.DumpToExe( offset );
        offset += _globalTypingInfo[i] -> Length();
    }
    for ( i = ToTypeIndex(0); i < ToTypeIndex(_globalTypingInfo.Entries()); i++ ) {
        _globalTypingInfo[i] -> Put( eMaker );
    }
}

uint SymbolSubsection::DumpPageAlign( ExeMaker&         eMaker,
                                      const uint        padCount,
                                      const unsigned_8  padVal )
/**************************************************************/
{
    eMaker.DumpToExe((unsigned_16) (padCount+WORD));
    eMaker.DumpToExe((unsigned_16) S_ALIGN);
    for ( uint i = 0; i < padCount; i++ ) {
        eMaker.DumpToExe(padVal);
    }
    return ( LONG_WORD + padCount );
}

uint SymbolSubsection::PageAlign( ExeMaker&         eMaker,
                                  const uint        length,
                                  const unsigned_32 offset )
/*****************************************************************/
{
    uint pad = SymbolSubsection::PadCount(length,offset);
    if ( pad > 0 ) {
        return SymbolSubsection::DumpPageAlign(eMaker,pad);
    }
    return 0;
}

uint SymbolSubsection::PadCount( const uint        length,
                                 const unsigned_32 offset )
/***************************************************************/
{
    uint pad = ALIGN_LENGTH - offset % ALIGN_LENGTH;
    if ( length > pad ) {
        return pad;
    }
    return 0;
}

void SstAlignSym::InsertOneRecord( SymbolStruct* sym )
/****************************************************/
{
    uint pad = SymbolSubsection::PadCount(sym->Length(),_currentOffset);
    if ( pad > 0 ) {
        _symbolInfo.append( new CSPageAlign(pad) );
        _currentOffset += pad + LONG_WORD;
    }
    sym -> SetOffset( _currentOffset );
    _currentOffset += sym -> Length();
    _symbolInfo.append( sym );
}

void SstAlignSym::Insert( SymbolStruct* sym )

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?