dbgexpr.c

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

C
806
字号
/****************************************************************************
*
*                            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:  Top layer of expression evaluator.
*
****************************************************************************/


#include <string.h>
#include <limits.h>
#include "dbgdefn.h"
#include "dbglit.h"
#include "dbgtoken.h"
#include "dbgreg.h"
#include "dbgstk.h"
#include "dbgerr.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbginfo.h"
#include "ldsupp.h"
#include "mad.h"
#include "i64.h"


extern void             *DupType( void * );
extern void             FreeType( void * );
extern void             BinOp( stack_entry *, stack_entry * );
extern int              AddrComp( address , address );
extern void             RValue( stack_entry * );
extern void             LValue( stack_entry * );
extern sym_list         *ExprGetSymList( stack_entry *, bool );
extern void             PurgeSymHandles( void );
extern void             ConvertTo( stack_entry *,type_kind, type_modifier, unsigned );
extern void             ClassNum( stack_entry * );
extern void             DoXor( void );
extern void             DoPlus( void );
extern void             DoMinus( void );
extern void             DoMul( void );
extern void             DoPoints( type_kind );
extern void             DoConvert( void );
extern void             AddrFloat( address * );
extern void             AddrFix( address * );
extern void             LocationCreate( location_list *, location_type, void * );
extern void             ClassifyEntry( stack_entry *, type_info * );
extern void             ExprSymbol( stack_entry *, sym_handle * );
extern address          GetRegIP( void );
extern address          GetRegSP( void );
extern address          GetRegBP( void );
extern void             GetMADTypeDefaultAt( address, mad_type_kind, mad_type_info * );

extern address          NilAddr;
extern machine_state    *DbgRegs;
extern char             *StringStart;
extern unsigned         StringLength;
extern unsigned         NestedCallLevel;
extern int              PgmStackUsage[ MAX_NESTED_CALL ];

static stack_entry ExprBOS = {
    NULL, NULL,
    NULL,
    { 0 },
    SF_END_PURGE
};

stack_entry *ExprSP = &ExprBOS;

void InitLC( location_context *new, bool use_real_regs )
{
    memset( new, 0, sizeof( *new ) );
    new->regs = DbgRegs;
    new->have_stack = TRUE;
    new->maybe_have_frame = TRUE;
    new->maybe_have_object = TRUE;
    new->use = 1;
    if( use_real_regs ) {
        new->execution = GetRegIP();
        new->frame = GetRegBP();
        new->stack = GetRegSP();
    } else {
        if( Context.up_stack_level ) new->regs = NULL;
        new->execution = Context.execution;
        new->frame = Context.frame;
        new->stack = Context.stack;
        new->maybe_have_frame = Context.maybe_have_frame;
        new->have_frame = Context.have_frame;
    }
}

void CreateLC( stack_entry *entry )
{
    location_context    *new;

    if( entry->lc == NULL ) {
        _ChkAlloc( new, sizeof( *new ), LIT( ERR_NO_MEMORY_FOR_EXPR ) );
        InitLC( new, FALSE );
        entry->lc = new;
    }
}

void FreeLC( stack_entry *entry )
{
    if( entry->lc != NULL ) {
        entry->lc->use--;
        if( entry->lc->use == 0 ) {
            _Free( entry->lc );
            entry->lc = NULL;
        }
    }
}

void MoveLC( stack_entry *src, stack_entry *dst )
{
    if( src != dst ) {
        FreeLC( dst );
        dst->lc = src->lc;
        src->lc = NULL;
    }
}

void DupLC( stack_entry *entry )
{
    if( entry->lc != NULL ) {
        entry->lc->use++;
    }
}

/*
 * CreateEntry - create a new stack entry
 */

void CreateEntry( void )
{
    stack_entry *new;
    unsigned    size;

    size = sizeof( stack_entry ) + type_SIZE + sym_SIZE;
    _ChkAlloc( new, size, LIT( ERR_NO_MEMORY_FOR_EXPR ) );
    memset( new, 0, size );
    new->up = ExprSP;
    new->dn = ExprSP->dn;
    if( new->dn != NULL ) new->dn->up = new;
    if( new->up != NULL ) new->up->dn = new;
    ExprSP = new;
}

bool AllocatedString( stack_entry *stk )
{
    if( stk->info.kind != TK_STRING ) return( FALSE );
    if( stk->flags & SF_LOCATION ) return( FALSE );
    return( stk->v.string.allocated != 0 );
}


static void FreeEntry( stack_entry *old )
{
    if( AllocatedString( old ) ) _Free( old->v.string.allocated );
    FreeLC( old );
    _Free( old );
}


/*
 * DeleteEntry - delete a stack entry
 */

void DeleteEntry( stack_entry *old )
{
    if( old == ExprSP ) ExprSP = old->up;
    if( old->up != NULL ) old->up->dn = old->dn;
    if( old->dn != NULL ) old->dn->up = old->up;
    FreeEntry( old );
}


/*
 * StkEntry - find a given stack entry
 */

stack_entry *StkEntry( int amount )
{
    stack_entry *new;

    new = ExprSP;
    for( ; amount > 0; --amount ) {
        if( new == &ExprBOS ) Error( ERR_LOC+ERR_INTERNAL, LIT( ERR_STK_OVERFL ) );
        new = new->up;
    }
    for( ; amount < 0; ++amount ) {
        new = new->dn;
        if( new == NULL ) Error( ERR_LOC+ERR_INTERNAL, LIT( ERR_STK_UNDERFL ) );
    }
    return( new );
}

/*
 * MoveSP - change expression stack pointer
 */

void MoveSP( int amount )
{
    ExprSP = StkEntry( amount );
}


/*
 * SwapStack - exchange two stack elements
 */

void SwapStack( int entry )
{
    stack_entry *other, *temp;

    other = StkEntry( entry );

    if( (temp = ExprSP->up) == other ) temp = ExprSP;
    ExprSP->up = other->up;
    other->up = temp;

    if( (temp = other->dn) == ExprSP ) temp = other;
    other->dn = ExprSP->dn;
    ExprSP->dn = temp;

    if( ExprSP->up != NULL ) ExprSP->up->dn = ExprSP;
    if( ExprSP->dn != NULL ) ExprSP->dn->up = ExprSP;

    if( other->up != NULL ) other->up->dn = other;
    if( other->dn != NULL ) other->dn->up = other;

    ExprSP = other;
}


void FreezeStack( void )
{
    stack_entry *save_sp;

    save_sp = ExprSP;
    while( ExprSP->dn != NULL ) {
        ExprSP = ExprSP->dn;
    }
    CreateEntry();
    ExprSP->flags = SF_END_PURGE;
    ExprSP->v.save_sp = save_sp;
}


void UnFreezeStack( bool nuke_top )
{
    stack_entry *sp;
    if( nuke_top ) {
        while( ExprSP->dn != NULL ) {
            ExprSP = ExprSP->dn;
        }
        while( !( ExprSP->flags & SF_END_PURGE ) ) {
            DeleteEntry( ExprSP );
        }
        sp = ExprSP->v.save_sp;
        DeleteEntry( ExprSP );
        ExprSP = sp;
    } else {
        sp = ExprSP;
        if( sp->flags & SF_END_PURGE ) {
            ExprSP = ExprSP->v.save_sp;
        }
        while( !(sp->flags & SF_END_PURGE) ) {
            sp = sp->up;
        }
        DeleteEntry( sp );
    }
}


char *DupStringVal( stack_entry *stk )
{
    char *dest;

    if( stk->info.size == 0 ) return( NULL );
    if( stk->info.size >= UINT_MAX ) Error( ERR_NONE, LIT( ERR_NO_MEMORY_FOR_EXPR ) );
    _ChkAlloc( dest, stk->info.size, LIT( ERR_NO_MEMORY_FOR_EXPR ) );
    memcpy( dest, stk->v.string.loc.e[0].u.p, stk->info.size );
    return( dest );
}


/*
 * DupStack - duplicate a stack entry
 */

void DupStack( void )
{
    stack_entry *old, *down, *link;

    old = link = ExprSP;
    while( old->flags & SF_END_PURGE ) old = old->up;
    CreateEntry();
    down = ExprSP->dn;
    memcpy( ExprSP, old, sizeof( *old ) + type_SIZE + sym_SIZE );
    ExprSP->up = link;
    ExprSP->dn = down;
    DupLC( ExprSP );
    if( old->th != NULL ) SET_TH( ExprSP );
    if( old->flags & SF_SYM ) SET_SH( ExprSP );
    if( AllocatedString( old ) ) {
        ExprSP->v.string.allocated = DupStringVal( old );
        ExprSP->v.string.loc.e[0].u.p = ExprSP->v.string.allocated;
    }
}


/*
 * PushName -- push a name onto the stack
 */

void PushName( lookup_item *name )
{
    CreateEntry();
    ExprSP->flags  = SF_NAME;
    ExprSP->v.name = *name;
}


/*
 * PushNum -- push an integer number
 */

void PushNum( long val )
{
    CreateEntry();
    I32ToI64( val, &ExprSP->v.sint );
    ClassNum( ExprSP );
}


/*
 * PushNum64 -- push an 64-bit integer number
 */

void PushNum64( unsigned_64 val )
{
    CreateEntry();
    ExprSP->v.sint = val;
    ClassNum( ExprSP );
}


/*
 * PushRealNum -- push a real number
 */

void PushRealNum( xreal val )
{
    CreateEntry();
    ExprSP->v.real = val;
    ExprSP->info.kind = TK_REAL;
    ExprSP->info.size = sizeof( xreal );
    ExprSP->flags = SF_CONST;
}

/*
 * PushSymHandle -- push a symbol handle
 */

void PushSymHandle( sym_handle *sh )
{
    CreateEntry();
    CreateLC( ExprSP );
    ExprSymbol( ExprSP, sh );
}


void ExprSetAddrInfo( stack_entry *stk, bool trunc )
{
    mad_type_info mti;

    stk->info.kind = TK_ADDRESS;
    stk->info.modifier = TM_FAR;
    GetMADTypeDefaultAt( stk->v.addr, MTK_ADDRESS, &mti );
    stk->info.size = mti.b.bits / BITS_PER_BYTE;
    if( trunc ) {
        stk->v.addr.mach.offset &=

⌨️ 快捷键说明

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