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 + -
显示快捷键?