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