eval.c

来自「CC386 is a general-purpose 32-bit C comp」· C语言 代码 · 共 1,500 行 · 第 1/4 页

C
1,500
字号
                return 0;
            v->constant = 1;
            v->ival = ival;
            v->type = lastst == IVAL ? T_INT8 : T_UINT8;
            return v;
        }
        return 0;
    }
    static void EvalBasicType(VARINFO *var, int *signedtype)
    {
        char data[12];
        int type = HintBasicType(var, signedtype, data);
        var->constant = TRUE;
        switch (type)
        {
            case T_INT8:
                #ifndef BORLANDC
                    var->ival = *(LLONG_TYPE*)data;
                    break;
                #endif 
            default:
                var->ival = 0;
                var->fval = 0;
                var->fvali = 0;
                break;
            case T_INT4:
                if (signedtype)
                    var->ival = *(int*)data;
                else
                    var->ival = *(unsigned*)data;
                break;
            case T_BOOL08:
                var->ival = data[0];
                break;
            case T_REAL32:
            case T_IMAGINARY32:
                var->fval = *(float*)data;
                break;
            case T_REAL80:
            case T_IMAGINARY80:
                var->fval = *(long double*)data;
                break;
            case T_REAL64:
            case T_IMAGINARY64:
                var->fval = *(double*)data;
                break;
            case T_CPLX32:
                var->fval = *(float*)data;
                var->fvali = *(float*)(data+4);
                break ;
            case T_CPLX64:
                var->fval = *(double*)data;
                var->fvali = *(double*)(data+8);
                break ;
            case T_CPLX80:
                var->fval = *(long double*)data;
                var->fvali = *(long double*)(data+10);
                break ;
        }

    }
    static VARINFO *makeconst(VARINFO *var)
    {
        int signedtype;
        if (var->constant)
            return var;
        if (CV_IS_PRIMITIVE(var->type) && !var->array)
        {
            EvalBasicType(var, &signedtype);
            if (var->bitfield)
            {
                if (signedtype)
                {
                    var->ival <<= 32-var->bitstart - var->bitlength;
                    var->ival >>= 32-var->bitlength;
                }
                else
                {
                    var->ival >>= var->bitstart;
                    var->ival &= bitmask[var->bitlength - 1];
                }
            }
        }
        else
        {
            var->constant = TRUE;
            var->type = T_UINT4;
            if (var->pointer)
            {
                var->ival = 0;
                ReadValue(var->ival, &var->address, 4, &var->thread->regs);
                var->pointer = FALSE;
            }
            else
                var->ival = var->address;
            FreeVarInfo(var->subtype);
            var->subtype = 0;
        }
        return var;
    }
    static void truncateconst(VARINFO *var1, VARINFO *var2)
    {
        // nop
    }
    static VARINFO *lookupsym(char **text, char **typetab, char **symtab,
        DEBUG_INFO **dbg, int offset1, int *offset)
    {
        char buf[256],  *p = buf;
        VARINFO *var;
        THREAD *thread;
        int ebp;
        int level;
        int offset2 = findStackedFunction(offset1, &ebp, &level, &thread);
        while (isalnum(**text) ||  **text == '_')
            *p++ = *(*text)++;
        *p = 0;
        if (!offset2)
            offset2 = offset1;
        if (FindSymbol(dbg, typetab, symtab, offset, offset2, *offset, (char*)
            buf))
        {
            var = GetVarInfo(*dbg,  *typetab,  *symtab,  *offset, (char*)buf,
                ebp, thread);
            if (var->udt)
                return ieerr(text, var, 0, "Can't use type here");
            return var;
        }
        return ieerr(text, 0, 0, "Undefined symbol");
    }
    typedef struct
    {
        char *str;
        int type;
    } CASTTYPE;

    static CASTTYPE regs[] = 
    {
        {
            "al", CV_REG_AL
        }
        , 
        {
            "ah", CV_REG_AH
        }
        , 
        {
            "bl", CV_REG_BL
        }
        , 
        {
            "bh", CV_REG_BH
        }
        , 
        {
            "cl", CV_REG_CL
        }
        , 
        {
            "ch", CV_REG_CH
        }
        , 
        {
            "dl", CV_REG_DL
        }
        , 
        {
            "dh", CV_REG_DH
        }
        , 
        {
            "ax", CV_REG_AX
        }
        , 
        {
            "bx", CV_REG_BX
        }
        , 
        {
            "cx", CV_REG_CX
        }
        , 
        {
            "dx", CV_REG_DX
        }
        , 
        {
            "sp", CV_REG_SP
        }
        , 
        {
            "bp", CV_REG_BP
        }
        , 
        {
            "si", CV_REG_SI
        }
        , 
        {
            "di", CV_REG_DI
        }
        , 
        {
            "eax", CV_REG_EAX
        }
        , 
        {
            "ebx", CV_REG_EBX
        }
        , 
        {
            "ecx", CV_REG_ECX
        }
        , 
        {
            "edx", CV_REG_EDX
        }
        , 
        {
            "esp", CV_REG_ESP
        }
        , 
        {
            "ebp", CV_REG_EBP
        }
        , 
        {
            "esi", CV_REG_ESI
        }
        , 
        {
            "edi", CV_REG_EDI
        }
        , 
    };
    static VARINFO *regnode(char **text)
    {
        int i, l;
        VARINFO *var1;
        char *p =  *text;
        skipspace(&p);
        for (i = 0; i < sizeof(regs) / sizeof(regs[0]); i++)
            if (!strncmp(p, regs[i].str, l = strlen(regs[i].str)) && !isalnum
                (p[l]) && p[l] != '_')
                break;
        if (i >= sizeof(regs) / sizeof(regs[0]))
            return 0;
        *text += strlen(regs[i].str);
        var1 = calloc(sizeof(VARINFO), 1);
        if (!var1)
            return 0;
        var1->type = T_INT4;
        var1->address = regs[i].type;
        var1->explicitreg = 1;
        return var1;
    }
    static CASTTYPE casts[] = 
    {
        {
            "int", T_INT4
        }
        , 
        {
            "long", T_INT4
        }
        , 
        {
            "long long", T_INT8
        }
        , 
        {
            "unsigned", T_UINT4
        }
        , 
        {
            "unsigned long", T_UINT4
        }
        , 
        {
            "unsigned long long", T_UINT8
        }
        , 
        {
            "short", T_SHORT
        }
        , 
        {
            "unsigned short", T_USHORT
        }
        , 
        {
            "char", T_CHAR
        }
        , 
        {
            "unsigned char", T_UCHAR
        }
        , 
        {
            "bool", T_BOOL08
        }
        , 
        {
            "float", T_REAL32
        }
        , 
        {
            "double", T_REAL64
        }
        , 
        {
            "long double", T_REAL80
        }
        , 
        {
            "float imaginary", T_IMAGINARY32
        }
        , 
        {
            "double imaginary", T_IMAGINARY64
        }
        , 
        {
            "long double imaginary", T_IMAGINARY80
        }
    };
    static VARINFO *castnode(char **text, char **typetab, char **symtab,
        DEBUG_INFO **dbg, int offset1, int *offset)
    {
        VARINFO *var1 = 0;
        int tp, i;
        int indir = 0, l;
        char *p = (*text) + 1;
        char buf[256],  *q = buf;
        UDTSYM *s = 0;

        skipspace(&p);
        for (i = 0; i < sizeof(casts) / sizeof(casts[0]); i++)
            if (!strncmp(p, casts[i].str, l = strlen(casts[i].str)) && !isalnum
                (p[l]) && p[l] != '_')
                break;
        if (i >= sizeof(casts) / sizeof(casts[0]))
        {
            // IF they type in struct or union, it is a nop, we are keying
            // only off the type name
            if (!strncmp(p, "struct ", 7))
                p += 7;
            else if (!strncmp(p, "union ", 6))
                p += 6;
            if (isalpha(*p) ||  *p == '_')
            {
                while (isalnum(*p) ||  *p == '_')
                    *q++ =  *p++;
                *q = 0;
                if (!FindSymbol(dbg, typetab, symtab, offset, StoppedThread
                    ->regs.Eip,  *offset, (char*)buf))
                    return 0;
                s = (UDTSYM*)(*symtab +  *offset);
                if (s->rectyp != S_UDT)
                    return 0;
                tp = s->typind;
            }
        }
        else
        {
            p += strlen(casts[i].str);
            tp = casts[i].type;
        }
        if (!isspace(*p) &&  *p != ')' &&  *p != '*')
            return 0;

        skipspace(&p);
        while (*p == '*')
        {
            p++;
            indir++;

⌨️ 快捷键说明

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