⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cdinit.c

📁 Open Watcom 的 C 编译器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
*
*                            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 "i64.h"
#include "cvars.h"
#include <limits.h>


local unsigned long BitMask[] = {
        0x00000001,
        0x00000003,
        0x00000007,
        0x0000000F,
        0x0000001F,
        0x0000003F,
        0x0000007F,
        0x000000FF,
        0x000001FF,
        0x000003FF,
        0x000007FF,
        0x00000FFF,
        0x00001FFF,
        0x00003FFF,
        0x00007FFF,
        0x0000FFFF,
        0x0001FFFF,
        0x0003FFFF,
        0x0007FFFF,
        0x000FFFFF,
        0x001FFFFF,
        0x003FFFFF,
        0x007FFFFF,
        0x00FFFFFF,
        0x01FFFFFF,
        0x03FFFFFF,
        0x07FFFFFF,
        0x0FFFFFFF,
        0x1FFFFFFF,
        0x3FFFFFFF,
        0x7FFFFFFF,
        0xFFFFFFFF
 };


#define DATA_QUAD_SEG_SIZE      (16*1024)
#define DATA_QUADS_PER_SEG      (DATA_QUAD_SEG_SIZE/sizeof(DATA_QUAD))

#define MAX_DATA_QUAD_SEGS (LARGEST_DATA_QUAD_INDEX/DATA_QUADS_PER_SEG + 1)

static DATA_QUAD       *DataQuadSegs[MAX_DATA_QUAD_SEGS];/* segments for data quads*/
static int             LastDataQuadSegIndex;
static DATA_QUAD       *DataQuadPtr;
static int             DataQuadIndex;
static int             LastDataQuadIndex;

local int CharArray( TYPEPTR typ );
local int WCharArray( TYPEPTR typ );
local void InitCharArray( TYPEPTR typ );
local void InitWCharArray( TYPEPTR typ );
local void StoreFloat( int float_type );
local void StoreInt64( TYPEPTR typ );

void InitDataQuads()
{
    DataQuadIndex = DATA_QUADS_PER_SEG;
    DataQuadSegIndex = -1;
    memset( DataQuadSegs, 0, MAX_DATA_QUAD_SEGS * sizeof(DATA_QUAD *) );
}

void FreeDataQuads()
{
    unsigned    i;

    for( i = 0; i < MAX_DATA_QUAD_SEGS; i++ ) {
        if( DataQuadSegs[i] == NULL ) break;
        FEfree( DataQuadSegs[i] );
    }
    InitDataQuads();
}

int StartDataQuadAccess()
{
    if( DataQuadSegIndex != -1 ) {
        DataQuadSegIndex = 0;
        DataQuadIndex = 0;
        DataQuadPtr = DataQuadSegs[ 0 ];
        return( 1 );                    // indicate data quads exist
    }
    return( 0 );                        // indicate no data quads
}

DATA_QUAD *NextDataQuad()
{
    DATA_QUAD   *dq_ptr;

    if( DataQuadIndex >= (DATA_QUADS_PER_SEG-1) ) {
        ++DataQuadSegIndex;
        DataQuadIndex = 0;
        DataQuadPtr = DataQuadSegs[ DataQuadSegIndex ];
    }
    ++DataQuadIndex;
    dq_ptr = DataQuadPtr;
    ++DataQuadPtr;
    return( dq_ptr );
}

void GenDataQuad( DATA_QUAD *dq )
{
    if( DataQuadIndex >= (DATA_QUADS_PER_SEG-1) ) {
        if( DataQuadSegIndex == MAX_DATA_QUAD_SEGS ) {
            CErr1( ERR_INTERNAL_LIMIT_EXCEEDED );
            CSuicide();
        }
        ++DataQuadSegIndex;
        DataQuadIndex = 0;
        DataQuadPtr = (DATA_QUAD *)FEmalloc( DATA_QUAD_SEG_SIZE );
        DataQuadSegs[ DataQuadSegIndex ] = DataQuadPtr;
    }
    memcpy( DataQuadPtr, dq, sizeof(DATA_QUAD) );
    ++DataQuadIndex;
    ++DataQuadPtr;
    DataQuadPtr->opr = T_EOF;
}


local void ZeroBytes( long n )
{
    auto DATA_QUAD dq;

    dq.opr = T_CONSTANT;
    dq.flags = Q_DATA;
    dq.u.long_values[0] = n;
    dq.u.long_values[1] = 0;
    GenDataQuad( &dq );
}

local void ChkConstant( unsigned long value, unsigned long max_value )
{
    if( value > max_value ) {                   /* 13-sep-91 */
        if( (value | (max_value >> 1)) != ~0UL ) {
            CWarn1( WARN_CONSTANT_TOO_BIG, ERR_CONSTANT_TOO_BIG );
        }
    }
}

local void StoreIValue( TOKEN int_type, unsigned long value )
{
    DATA_QUAD           *dq_ptr;
    auto DATA_QUAD      dq;

    dq.flags = 0;
    dq.opr = 0;
    dq_ptr = &dq;
    if( LastDataQuadIndex == DataQuadIndex  &&
        LastDataQuadSegIndex == DataQuadSegIndex ) {
        dq_ptr = DataQuadPtr - 1;
    }
    if( dq_ptr->opr == int_type  &&             /* 06-apr-92 */
        dq_ptr->flags == (Q_DATA | Q_REPEATED_DATA)  &&
        dq_ptr->u.long_values[0] == value ) {
        dq_ptr->u.long_values[1]++;             /* increment repeat count */
    } else if( dq_ptr->opr == int_type  &&  dq_ptr->flags == Q_DATA ) {
        if( dq_ptr->u.long_values[0] == value ) {
            dq_ptr->flags |= Q_REPEATED_DATA;
            dq_ptr->u.long_values[1] = 2;       /* repeat count */
        } else {
            dq_ptr->flags |= Q_2_INTS_IN_ONE;
            dq_ptr->u.long_values[1] = value;
        }
    } else {
        dq.opr = int_type;
        dq.flags = Q_DATA;
        dq.u.long_values[0] = value;
        if( value != 0 ) CompFlags.non_zero_data = 1;
        GenDataQuad( &dq );
        LastDataQuadIndex = DataQuadIndex;
        LastDataQuadSegIndex = DataQuadSegIndex;
    }
}

local void StoreIValue64( uint64 value )
{
    DATA_QUAD           *dq_ptr;
    auto DATA_QUAD      dq;

    dq.opr = T___INT64;
    dq.flags = Q_DATA;
    dq_ptr = &dq;
    dq.u.long64 = value;
    CompFlags.non_zero_data = 1;
    GenDataQuad( &dq );
}


typedef struct {
    long                       offset;
    union {
        STR_HANDLE       str_h;
        SYM_HANDLE       sym_h;
    };
    bool                      is_str;
    bool                      addr_set;
    bool                      is_error;
    enum { IS_VALUE, IS_ADDR } state;
} addrfold_info;

local void AddrFold( TREEPTR tree, addrfold_info *info ){
// Assume tree has been const folded
    SYM_ENTRY           sym;
    long                offset = 0;

    switch( tree->op.opr ) {
    case OPR_PUSHINT:
        info->state = IS_ADDR;
        info->offset = tree->op.long_value;
        if( info->offset != 0 ) CompFlags.non_zero_data = 1;
        break;
    case OPR_PUSHFLOAT:
        info->state = IS_ADDR;
        if( tree->op.float_value->len != 0 ) {
            info->offset = (long)atof( tree->op.float_value->string );
        } else {
        #ifdef _LONG_DOUBLE_
            long_double ld;
            double d;

            ld = tree->op.float_value->ld;
            __LDFD( (long_double near *)&ld,
                   (double near *)&d );
            info->offset = (long)d;
        #else
            info->offset = (long)tree->op.float_value->ld.value;
        #endif
        }
        if( info->offset != 0 ) CompFlags.non_zero_data = 1;
        break;
    case OPR_PUSHSTRING:
        info->state = IS_ADDR;
        if( info->addr_set ){
            info->is_error = TRUE;
        }
        info->addr_set = TRUE;
        info->is_str = TRUE;
        info->str_h = tree->op.string_handle;
        tree->op.string_handle->ref_count++;
        CompFlags.non_zero_data = 1;
        break;
    case OPR_PUSHADDR:
        info->state = IS_ADDR;
    case OPR_PUSHSYM:
        if( info->addr_set ){
            info->is_error = TRUE;
        }
        info->addr_set = TRUE;
        info->is_str = FALSE;
        SymGet( &sym, tree->op.sym_handle );
        info->sym_h = tree->op.sym_handle;
        CompFlags.non_zero_data = 1;
        if( sym.stg_class == SC_AUTO ){
            info->is_error = TRUE;
        }
        break;
    case OPR_INDEX:
        if(  tree->right->op.opr == OPR_PUSHINT ){
            AddrFold( tree->left, info );
            offset = tree->right->op.long_value;
        }else if( tree->left->op.opr == OPR_PUSHINT ){
            AddrFold( tree->right, info );
            offset = tree->left->op.long_value;
        }else{
            info->is_error = TRUE;
        }
        if( info->state == IS_VALUE ){ // must be foldable
            info->is_error = TRUE;
        }
        info->offset +=  offset * SizeOfArg( tree->expr_type );
        if( tree->op.flags & OPFLAG_RVALUE ) {
            info->state = IS_VALUE;
        }
        break;
    case OPR_ADD:
    case OPR_SUB:
        if(  tree->right->op.opr == OPR_PUSHINT ){
            AddrFold( tree->left, info );
            if( tree->op.opr == OPR_ADD ) {
                info->offset = info->offset+tree->right->op.long_value;
            } else {
                info->offset = info->offset-tree->right->op.long_value;
            }
        }else if( tree->left->op.opr == OPR_PUSHINT ){
            AddrFold( tree->right, info );
            if( tree->op.opr == OPR_ADD ) {
                info->offset = tree->left->op.long_value+info->offset;
            } else {
                info->offset = tree->left->op.long_value-info->offset;
            }
        }else{
            info->is_error = TRUE;
        }
        if( info->state == IS_VALUE ){ // must be foldable
            info->is_error = TRUE;
        }
        break;
    case OPR_ADDROF:
        AddrFold( tree->right, info );
        info->state = IS_ADDR;
        CompFlags.non_zero_data = 1;
        break;
    case OPR_ARROW:
        AddrFold( tree->left, info );
        if( info->state == IS_VALUE ){ // must be foldable
            info->is_error = TRUE;
        }
        info->offset += tree->right->op.long_value;
        if( tree->op.flags & OPFLAG_RVALUE ) {
            info->state = IS_VALUE;
        }
        break;
    case OPR_POINTS:
        AddrFold( tree->left, info );
        if( info->state == IS_VALUE ){ // must be foldable
            info->is_error = TRUE;
        }
        if( tree->op.flags & OPFLAG_RVALUE ) {
            info->state = IS_VALUE;
        }
        break;
    case OPR_DOT:
        AddrFold( tree->left, info );
        info->offset += tree->right->op.long_value;
        CompFlags.non_zero_data = 1;
        if( tree->op.flags & OPFLAG_RVALUE ) {
            info->state = IS_VALUE;
        }
        break;
    case OPR_CONVERT:  //should check for pointer to smaller
    case OPR_CONVERT_PTR:
        AddrFold( tree->right, info );
        break;
    case OPR_ERROR:                 // error has already been issued
        break;
    default:
        info->is_error = TRUE;
        break;
    }
}

local void StorePointer( TYPEPTR typ, TOKEN int_type )
{
    int                 flags;
    TREEPTR             tree;
    TYPEPTR             typ2;
    int                 address_wanted;
    auto DATA_QUAD      dq;
    addrfold_info       info;

    dq.flags = Q_DATA;
    flags = 0;
    if( CompFlags.strings_in_code_segment ) flags = FLAG_CONST;/*01-sep-89*/
    if( typ->decl_type == TYPE_POINTER ) {
        if( typ->u.p.decl_flags & (FLAG_FAR|FLAG_HUGE) ) {
            dq.flags |= Q_FAR_POINTER;
            flags = FLAG_FAR;
        } else if( typ->u.p.decl_flags & FLAG_NEAR ) {
            dq.flags |= Q_NEAR_POINTER;
            flags = 0;
        } else {
            typ2 = typ->object;
            while( typ2->decl_type == TYPE_TYPEDEF ) typ2 = typ2->object;
            if( typ2->decl_type == TYPE_FUNCTION ) {
                dq.flags |= Q_CODE_POINTER;
            } else if( TypeSize( typ ) == TARGET_FAR_POINTER ) {
                dq.flags |= Q_FAR_POINTER;
            }
        }
    }

    address_wanted = 0;
    if( CurToken == T_RIGHT_BRACE) { // t some x = {}
        dq.opr = T_ID;
        dq.u.var.sym_handle = 0;
        dq.u.var.offset = 0;
    }else{
        tree = AddrExpr();
        tree = InitAsgn( typ, tree ); // as if we are assigning
        info.offset = 0;
        info.sym_h = 0;
        info.addr_set = FALSE;
        info.state = IS_VALUE;
        info.is_str = FALSE;
        info.is_error = FALSE;
        AddrFold( tree, &info );
        FreeExprTree( tree );

⌨️ 快捷键说明

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