dbgsem.c

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

C
1,388
字号
/****************************************************************************
*
*                            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:  Semantic actions for SSL-driven grammars.
*
****************************************************************************/


#include <string.h>
#include <stdio.h>
#include <limits.h>
#include "dbglit.h"
#include "dbgdefn.h"
#include "dbginfo.h"
#include "dbgstk.h"
#include "dbgtoken.h"
#include "dbgreg.h"
#include "dbgerr.h"
#include "dbgtoggl.h"
#include "dipwv.h"
#include "dip.h"
#include "i64.h"


#define         SSL_VERSION_MAJOR_CURR  0x0100
#define         SSL_VERSION_MINOR_CURR  0x0000

#define         SSL_VERSION_MAJOR_MASK  0xff00
#define         SSL_VERSION_MINOR_MASK  0x00ff

#define         TI_KIND_EXTRACT( ti )   (((ti) >> 12) & 0xf)
#define         TI_MOD_EXTRACT( ti )    (((ti) >>  8) & 0xf)
#define         TI_SIZE_EXTRACT( ti )   ((ti) & 0xff)
#define         TI_CREATE( tk, tm, ts ) (((tk) << 12) | ((tm) << 8) | (ts))

enum {
    SEM_MISC        = 0x00,
    SEM_DO          = 0x20,
    SEM_PUSH_N_POP  = 0x40,
    SEM_STACK       = 0x60,
    SEM_NUM         = 0x80,
    SEM_BITS        = 0xa0,
    SEM_GET         = 0xc0,
    SEM_SELECTOR    = 0x1f,
    SEM_MECHANISM   = 0xe0,
};

extern void             DoPlus( void );
extern void             DoMinus( void );
extern void             DoMul( void );
extern void             DoDiv( void );
extern void             DoMod( void );
extern void             DoAnd( void );
extern void             DoOr( void );
extern void             DoXor( void );
extern void             DoShift( void );
extern void             DoAddr( void );
extern void             DoFAddr( void );
extern void             DoPoints( type_kind );
extern void             DoConvert( void );
extern void             DoLConvert( void );
extern void             DoMakeComplex( void );
extern void             DoStringConcat( void );
extern void             DoField( void );
extern void             DoScope( void );
extern void             DoAssign( void );
extern void             DoCall( unsigned int, bool );
extern void             DupStack( void );
extern void             SwapStack( int );
extern unsigned         TstEQ( unsigned int );
extern unsigned         TstLT( unsigned int );
extern unsigned         TstTrue( unsigned int );
extern unsigned         TstExist( unsigned int );
extern void             PushName( lookup_item * );
extern void             PushNum( long );
extern void             PushNum64( unsigned_64 );
extern void             PushRealNum( xreal );
extern void             PushAddr( address );
extern void             PushLocation( location_list *, type_info * );
extern void             PushString( void );
extern void             PushType( type_handle * );
extern void             PushInt( int );
extern void             PopEntry( void );
extern void             MakeAddr( void );
extern void             ExprValue( stack_entry * );
extern bool             NameResolve( stack_entry *, bool );
extern void             LValue( stack_entry * );
extern void             RValue( stack_entry * );
extern void             LRValue( stack_entry * );
extern void             ParseRegSet( bool, location_list *, type_info * );
extern void             Recog( unsigned int );
extern bool             ScanQuote( char **, unsigned * );
extern void             Scan( void );
extern char             *ScanPos( void );
extern unsigned         ScanLen( void );
extern char             *NamePos( void );
extern unsigned         NameLen( void );
extern unsigned_64      IntNumVal( void );
extern xreal            RealNumVal( void );
extern void             MoveSP( int );
extern stack_entry      *StkEntry( int );
extern char             *ReScan( char * );
extern mod_handle       LookupModName( mod_handle, char *, int );
extern unsigned         SetCurrRadix( unsigned int );
extern void             AddChar( void );
extern void             AddCEscapeChar( void );
extern void             AddActualChar( char );
extern void             ConvertTo( stack_entry *, type_kind, type_modifier, unsigned );
extern void             FreePgmStack( bool );
extern void             MarkArrayOrder( bool );
extern void             StartSubscript( void );
extern void             AddSubscript( void );
extern void             EndSubscript( void );
extern address          GetDotAddr( void );
extern sym_list         *LookupSymList( symbol_source, void *, bool, lookup_item * );
extern void             PurgeSymHandles( void );
extern void             LocationAdd( location_list *, long );
extern bool             IsInternalMod( mod_handle );
extern sym_list         *Disambiguate( sym_list * );
extern void             FreeSymHandle( sym_list * );
extern image_entry      *ImagePrimary( void );
extern mod_handle       LookupImageName( char *, unsigned );
extern void             GetMADTypeDefault( mad_type_kind, mad_type_info * );


extern tokens           CurrToken;
extern stack_entry      *ExprSP;
extern unsigned         SkipCount;
extern mod_handle       CodeAddrMod;
extern bool             scan_string;
extern unsigned         StringLength;
extern unsigned         ScanCCharNum;
extern unsigned         NestedCallLevel;
extern int              PgmStackUsage[ MAX_NESTED_CALL ];
extern unsigned         ExprAddrDepth;


#define type_bitsII     int

/* SSL Table Variables */
static type_bitsII      Bits;
static unsigned         Num;
static unsigned         EvalSubstring;
static struct {
    lookup_item         li;
    unsigned            multi_module    : 1;
    unsigned            any_image       : 1;
    enum { GET_NAME, GET_OPERATOR, GET_LNUM }   kind;
}                       CurrGet;

#define MAX_SCANSAVE_PTRS 20
static  char           *CurrScan[MAX_SCANSAVE_PTRS];
        int             ScanSavePtr;


enum { false=0, true=1 };  /* values for bools from the parse table */


//NYI: begin temp until SSL files can be updated
typedef enum {
    STK_VOID     = 0x0000,
    STK_BOOL     = 0x0001,
    STK_ENUM     = 0x0002,
    STK_CHAR     = 0x0003,
    STK_INT      = 0x0004,
    STK_NEAR_PTR = 0x0005,
    STK_FAR_PTR  = 0x0006,
    STK_ADDR     = 0x0007, /* just a raw address */
    STK_REAL     = 0x0008,
    STK_STRUCT   = 0x0009,
    STK_ARRAY    = 0x000a,
    STK_FUNC     = 0x000b,
    STK_TYPE     = 0x000c, /* have a type name */
    STK_NAME     = 0x000d, /* have a symbol name */
    STK_COMPLEX  = 0x000f,
    STK_STRING   = 0x0010,
    STK_OPERATOR = 0x0011,
    STK_END_PURGE= 0x003f,
#define BASE_TYPE 0x003f
    STK_UNSIGNED = 0x0100, /* meaningful for int & char only */
    STK_LONG     = 0x0200, /*   int (short/long);
                                real (float/double),
                                complex (single/double precision)
                                addresses (286 / 386)
                            */
} stack_class;

static stack_class TypeInfoToClass( type_info *ti )
{
    stack_class         c;

    c = STK_VOID;
    switch( ti->kind ) {
    case TK_INTEGER:
        c = STK_INT;
        if( ti->modifier == TM_UNSIGNED ) c |= STK_UNSIGNED;
        if( ti->size == 4 ) c |= STK_LONG;
        break;
    case TK_POINTER:
        c = STK_FAR_PTR;
        if( ti->size == 6 ) c |= STK_LONG;
        break;
    case TK_ADDRESS:
        c = STK_ADDR;
        if( ti->size == 6 ) c |= STK_LONG;
        break;
    case TK_ARRAY:
        c = STK_ARRAY;
        break;
    case TK_STRING:
        c = STK_STRING;
        break;
    case TK_FUNCTION:
        c = STK_FUNC;
        break;
    }
    return( c );
}

static void ClassToTypeInfo( stack_class c, type_info *ti )
{
    switch( c ) {
    case STK_INT | STK_UNSIGNED:
        ti->kind = TK_INTEGER;
        ti->modifier = TM_UNSIGNED;
        ti->size = 2;
        break;
    case STK_INT | STK_UNSIGNED | STK_LONG:
        ti->kind = TK_INTEGER;
        ti->modifier = TM_UNSIGNED;
        ti->size = 4;
        break;
    case STK_FAR_PTR:
        ti->kind = TK_POINTER;
        ti->modifier = TM_FAR;
        ti->size = 4;
        break;
    case STK_FAR_PTR | STK_LONG:
        ti->kind = TK_POINTER;
        ti->modifier = TM_FAR;
        ti->size = 6;
        break;
    case STK_ADDR:
        ti->kind = TK_ADDRESS;
        ti->modifier = TM_FAR;
        ti->size = 4;
        break;
    case STK_ADDR | STK_LONG:
        ti->kind = TK_ADDRESS;
        ti->modifier = TM_FAR;
        ti->size = 6;
        break;
    case STK_ARRAY:
        ti->kind = TK_ARRAY;
        ti->modifier = TM_NONE;
        ti->size = 0;
        break;
    case STK_FUNC:
        ti->kind = TK_FUNCTION;
        ti->modifier = TM_NONE;
        ti->size = 0;
        break;
    case STK_STRING:
        ti->kind = TK_STRING;
        ti->modifier = TM_NONE;
        ti->size = 0;
        break;
    }
}
#define SSL_CASE_SENSITIVE      0x00000001UL // must be 0x01 - see dbgintr.ssl
#define SSL_SIDE_EFFECT         0x00000002UL // must be 0x02 - see dbgintr.ssl
#define SSL_32_BIT              0x00000004UL // must be 0x04 - see dbgintr.ssl

//NYI: end temp

static void FillInDefaults( type_info *info )
{
    mad_type_info       mti;

    switch( info->kind ) {
    case TK_INTEGER:
        if( info->modifier == TM_NONE ) info->modifier = TM_SIGNED;
        if( info->size == 0 ) {
            if( ModDefault( CodeAddrMod, DK_INT, info ) != DS_OK ) {
                GetMADTypeDefault( MTK_INTEGER, &mti );
                info->size = mti.b.bits / BITS_PER_BYTE;
            }
        }
        break;
    case TK_POINTER:
    case TK_CODE:
    case TK_DATA:
        if( info->modifier == TM_NONE ) {
            if( ModDefault( CodeAddrMod, (info->kind == TK_CODE) ? DK_CODE_PTR : DK_DATA_PTR, info ) != DS_OK ) {
                info->modifier = TM_NONE;
                info->size = 0;
            }
        }
        if( info->modifier == TM_NONE || info->size == 0 ) {
            GetMADTypeDefault( MTK_ADDRESS, &mti );
            if( info->modifier == TM_NONE ) {
                if( mti.a.seg.bits != 0 ) {
                    info->modifier = TM_FAR;
                } else {
                    info->modifier = TM_NEAR;
                }
            }
            if( info->size == 0 ) {
                if( info->modifier == TM_NEAR ) mti.b.bits -= mti.a.seg.bits;
                info->size = mti.b.bits / BITS_PER_BYTE;
            }
        }
        break;
    }
}

static unsigned MechMisc( unsigned select, unsigned parm )
{
    long                value;
    unsigned            result;
    mad_type_info       mti;

    switch( select ) {
    case 0:
        ExprAddrDepth += parm;
        result = ExprAddrDepth;
        break;
    case 1:
        if( _IsOn( SW_EXPR_IS_CALL ) && ExprAddrDepth == 0 ) {
            result = TRUE;
        } else {
            result = FALSE;
        }
        break;
    case 2:
        SkipCount += parm;
        break;
    case 3:
        result = SkipCount;
        break;
    case 4:
        //never called
        break;
    case 5:
        if( ScanSavePtr >= MAX_SCANSAVE_PTRS )
            Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANSAVE ) );
        CurrScan[ScanSavePtr++] = ScanPos();
        break;
    case 6:
        if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
        ReScan( CurrScan[--ScanSavePtr] );
        break;
    case 7:
        if( ScanSavePtr <= 0 ) Error( ERR_INTERNAL, LIT( ERR_TOO_MANY_SCANRESTORE ) );
        --ScanSavePtr;
        break;
    case 8:
        if( parm ) {        /* start scan string */
            scan_string = TRUE;
            ReScan( ScanPos() );
        } else {            /* end scan string */
            scan_string = FALSE;
            ReScan( ScanPos() );
        }
        break;
    case 9:
        ReScan( ScanPos() + (int)parm );
        break;
    case 10:
        AddChar();
        break;
    case 11:
        AddCEscapeChar();
        break;
    case 12:
        AddActualChar( '\0' );
        break;
    case 13:
        ScanCCharNum = parm;
        break;
    case 14:
        if( NestedCallLevel == MAX_NESTED_CALL - 1 ) {
            Error( ERR_NONE, LIT( ERR_TOO_MANY_CALLS ) );
        } else {
            PgmStackUsage[ ++NestedCallLevel ] = 0;
        }
        break;
    case 15:
        RValue( ExprSP );
        ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
        value = U32FetchTrunc( ExprSP->v.uint ) - 1;
        PopEntry();
        if( ExprSP->info.kind == TK_STRING ) {
            if( value < 0 || value >= ExprSP->info.size ) {
                Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
            }
            LocationAdd( &ExprSP->v.string.loc, value*8 );
            ExprSP->info.size -= value;
            ExprSP->v.string.ss_offset = value;
        } else {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
        break;
    case 16:
        RValue( ExprSP );
        ConvertTo( ExprSP, TK_INTEGER, TM_SIGNED, 4 );
        value = U32FetchTrunc( ExprSP->v.sint ) - 1;
        PopEntry();
        if( ExprSP->info.kind == TK_STRING ) {
            value -= ExprSP->v.string.ss_offset;
            if( value < 0 || value >= ExprSP->info.size ) {
                Error( ERR_NONE, LIT( ERR_BAD_SUBSTRING_INDEX ) );
            }
            ExprSP->info.size = value;
        } else {
            Error( ERR_NONE, LIT( ERR_ILL_TYPE ) );
        }
        break;
    case 17:
        EvalSubstring = parm;
        if( parm ) ExprSP->v.string.ss_offset = 0;
        break;
    case 18:
        result = EvalSubstring;
        break;
    case 19:
        FreePgmStack( TRUE );
        break;
    case 20:
        switch( parm ) { // nyi - begin temp
        case SSL_CASE_SENSITIVE:
            _SwitchOn( SW_CASE_SENSITIVE );
            break;
        case SSL_SIDE_EFFECT:
            _SwitchOn( SW_SIDE_EFFECT );
            break;
        //case SSL_32_BIT:
        //    _SwitchOn( SW_32_BIT );
        //    break;
        }

⌨️ 快捷键说明

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