📄 bterp.c
字号:
case OR|B4:
OR_ES(unsigned long);
case XOR|B1:
XOR_ES(unsigned char);
case XOR|B2:
XOR_ES(unsigned short);
case XOR|B4:
XOR_ES(unsigned long);
case AND|B1:
AND_ES(unsigned char);
case AND|B2:
AND_ES(unsigned short);
case AND|B4:
AND_ES(unsigned long);
#if SUPPORT_LONG_LONG
case OR|B8:
OR_ES(unsigned long long);
case AND|B8:
AND_ES(unsigned long long);
case XOR|B8:
XOR_ES(unsigned long long);
#else
#endif
case MOD|BYTE:
MOD_ES(char);
case MOD|SHORT:
MOD_ES(short);
case MOD|LONG:
MOD_ES(long);
case MOD|UBYTE:
MOD_ES(unsigned char);
case MOD|USHORT:
MOD_ES(unsigned short);
case MOD|ULONG:
MOD_ES(unsigned long);
case XTD:
{
++pc;
++np;
switch(*pc)
{
case LSH|B1:
LSH_ES(char);
case LSH|B2:
LSH_ES(short);
case LSH|B4:
LSH_ES(long);
case LSH|B8:
LSH_ES(long long);
case LSHI|B1:
LSHI_ES(char);
case LSHI|B2:
LSHI_ES(short);
case LSHI|B4:
LSHI_ES(long);
case LSHI|B8:
LSHI_ES(long long);
case RSH|BYTE:
RSH_ES(char);
case RSH|SHORT:
RSH_ES(short);
case RSH|LONG:
RSH_ES(long);
case RSH|UBYTE:
RSH_ES(unsigned char);
case RSH|USHORT:
RSH_ES(unsigned short);
case RSH|ULONG:
RSH_ES(unsigned long);
case RSHI|BYTE:
RSHI_ES(char);
case RSHI|SHORT:
RSHI_ES(short);
case RSHI|LONG:
RSHI_ES(long);
case RSHI|UBYTE:
RSHI_ES(unsigned char);
case RSHI|USHORT:
RSHI_ES(unsigned short);
case RSHI|ULONG:
RSHI_ES(unsigned long);
case BUILTIN:
{
++pc;
++np;
switch(*pc)
{/* THESE BUILTINS CANNOT BE CALLED THROUGH A FUNCPTR */
case SETJMP:
{
long *jb;
jb = *((void**)es);
*((long*)es) = 0;
jb[0] = (long)iv->allocalist;
jb[1] = (long)pc;
if((jb = (long*)setjmp(((void*)&jb[4]))))
{
void *bs,*qs;
pc = (void*)jb[1];
*((long*)es) = jb[2];
bs = (void*)jb[3];
while(bs != base_stack)
{
qs = ((PSB)bs)->backlink;
free(bs);
bs = qs;
}
purge_allocas(iv, (void*)jb[0]);
prune_structs(iv);
}
break;
}
case LONGJMP:
{
long *jb;
jb = *((void**)oes);
jb[2] = *((long*)es);
jb[3] = (long)base_stack;
longjmp(((void*)&jb[4]), (long)jb);
break;
}
case ABORT:
printf("bterp: user program called abort.\n");
case EXIT:
{
void *bs, *qs;
bs = base_stack;
while(bs != iv->base_stack)
{
qs = ((PSB)bs)->backlink;
free(bs);
bs = qs;
}
purge_allocas(iv, 0);
longjmp(iv->jb, (int)es);
break;
}
default:
do_builtin(iv, *pc, &es);
break;
}
break;
} /* END: XTD BUILTIN */
case CLRDAT:
{
memset(*((void**)oes), 0, *((long*)es));
es -= 2*SZ;
break;
}
case SWITCH:
{
unsigned long key[2];
unsigned char **result;
key[0] = *((unsigned short*)np)<<11;
key[1] = *((long*)es);
if(findswitch(iv, key, &result))
{
pc = *result - 1;
}
else
{
pc += 2;
}
es = oes;
break;
}
case CALLSETUP:
{
PCB cb = (PCB)es;
Pft ft = cb->loc;
int hidden;
long stksiz, maxes;
long argsiz, strucsiz;
int flags = 0;
if(ft->fmods & Fbuiltin)
{/* This only happens if the programmer uses a function
pointer which points to a builtin function. */
flags = 0x80;
}
cb->argsiz = argsiz = G4(np);
if((hidden = ft->fmods & Fretstr))
{/* function returning a structure */
strucsiz = ft->retsiz<<2;
}
stksiz = ft->stksiz<<2;
maxes = ft->maxes;
if(ft->fmods & Fnested)
{/* Calling nested function */
cb->argofs = (ft->stkbeg+(stksiz-(ft->argsiz<<2)-hidden)) >> 2;
if(ft->funcaddr >= first_loc && ft->funcaddr <= last_loc)
{/* call from enclosing function */
cb->base_stack = base_stack;
cb->es = es;
cb->flags = 0x10 + hidden;
}
else
{/* callback from another function */
PSB prev = (PSB)(fs - sizeof(SB));
long floc = prev->first_loc;
long lloc = prev->last_loc;
while((prev = prev->backlink))
{
if( ft->funcaddr >= floc
&& ft->funcaddr <= lloc)
{/* This is the container of the nested func */
cb->base_stack = (char*)prev;
cb->es = prev->cbes;
break;
}
floc = prev->first_loc;
lloc = prev->last_loc;
}
cb->flags = 0x20 + hidden;
}
}
else if(ft->fmods & Fextern)
{/* Calling external function */
/* Dynamic link it */
if(!(ft->fmods & Fthunked))
load_efunc(iv, ft);
cb->base_stack = calloc(1, sizeof(SB)+argsiz+hidden);
cb->argsiz = argsiz+hidden;
cb->argofs = 0;
cb->flags = 0x40 + hidden;
}
else
{/* Calling interpreted function */
if(flags & 0x80)
{
cb->flags = flags;
cb->es = cb->base_stack = calloc(1, 128);
}
else
{
long es_beg;
long fs_size;
PSB sp;
es_beg = stksiz+hidden+argsiz;
fs_size = es_beg + ((maxes+6)*SZ);
cb->base_stack = calloc(1, fs_size+sizeof(SB));
sp = (PSB)cb->base_stack;
cb->es = cb->base_stack + sizeof(SB) + es_beg;
cb->argofs = stksiz >> 2;
cb->flags = flags + hidden;
sp->first_loc = first_loc;
sp->last_loc = last_loc;
sp->backlink = base_stack;
sp->stksize = fs_size+sizeof(SB);
}
}
if(hidden)
{/* function returning a structure */
void *strucptr = malloc(strucsiz);
*((void**)(cb->base_stack+sizeof(SB)+(cb->argofs<<2))) = strucptr;
ensure_strrets(iv);
iv->struclist[iv->strretcnt++] = strucptr;
}
pc += 4;
break;
}
case RETSTRUCT:
{
long size = G2(np)<<2;
long offset = G2(np+2)<<2;
void *dst;
dst = fs + offset;
dst = *((void**)dst);
memcpy(dst, *((void**)es), size);
if(iv->debug) {
printf("RETSTRUCT ofs=%lx es=%p val=0x%lx\n", pc_offset, es, *((long*)es));
fflush(stdout);
}
return es;
}
case PRUNESTRUCT:
{
prune_structs(iv);
break;
}
case GETBITFIELD:
{
if(pc[1] + pc[2] <= 32)
{
*((long*)es) >>= pc[1];
*((long*)es) &= bfields[pc[2]];
if(pc[3])
{/* sign extend */
if(*((long*)es) & tsfields[pc[2]])
{
*((long*)es) |= sfields[pc[2]];
((long*)es)[1] = 0xffffffff;
}
else ((long*)es)[1] = 0;
}
}
else
{
#if SUPPORT_LONG_LONG
*((long long*)es) >>= pc[1];
*((long long*)es) &= lbfields[pc[2]];
if(pc[3])
{
if(*((long long*)es) & ltsfields[pc[2]])
*((long long*)es) |= lsfields[pc[2]];
}
#else
#endif
}
pc += 3;
break;
}
case PUTBITFIELD:
{
if(pc[1] + pc[2] <= 32)
{
unsigned long mask = bfields[pc[2]];
void *dst = *((void **)oes);
unsigned long dat = *((long*)es);
dat &= mask;
dat <<= pc[1];
mask <<= pc[1];
switch(pc[3])
{
case 1:
*((char*)dst) &= ~mask;
*((char*)dst) |= dat;
break;
case 2:
*((short*)dst) &= ~mask;
*((short*)dst) |= dat;
break;
case 4:
*((long*)dst) &= ~mask;
*((long*)dst) |= dat;
break;
default:
break;
}
}
else
{
#if SUPPORT_LONG_LONG
unsigned long long mask = lbfields[pc[2]];
void *dst = *((void **)oes);
unsigned long long dat = *((unsigned long long *)es);
dat &= mask;
dat <<= pc[1];
mask <<= pc[1];
switch(pc[3])
{
case 1:
*((char*)dst) &= ~mask;
*((char*)dst) |= dat;
break;
case 2:
*((short*)dst) &= ~mask;
*((short*)dst) |= dat;
break;
case 4:
*((long*)dst) &= ~mask;
*((long*)dst) |= dat;
break;
case 8:
*((long long*)dst) &= ~mask;
*((long long*)dst) |= dat;
break;
default:
break;
}
#else
#endif
}
pc += 3;
es -= 2*SZ;
break;
}
#if SUPPORT_LONG_DOUBLE
case LI:
LOADIX();
#endif
case IMMED:
{
++pc;
++np;
switch(*pc)
{
#if SUPPORT_LONG_DOUBLE
case SMI|A1:
STORMEMI1(long double);
case SMI|A2:
STORMEMI2(long double);
case SMI|A3:
STORMEMI3(long double);
case SMI|A4:
STORMEMI4(long double);
case SSI|A1:
STORSTKI1(long double);
case SSI|A2:
STORSTKI2(long double);
case SSI|A3:
STORSTKI3(long double);
case DEREF|LONGDOUBLE:
FDEREF_ES(long double);
case DEREF1|LONGDOUBLE:
FDEREF1_ES(long double);
#endif
#if SUPPORT_LONG_LONG
case DEREF|LONGLONG:
case DEREF|ULONGLONG:
FDEREF_ES(long long);
case DEREF1|LONGLONG:
case DEREF1|ULONGLONG:
FDEREF1_ES(long long);
case MODI|LONGLONG:
MODI_ES(long long);
case MODI|ULONGLONG:
MODI_ES(unsigned long long);
#endif
}
break;
}/* END: XTD IMMED */
#if SUPPORT_LONG_LONG
case ADD|LONGLONG:
ADD_ES(long long);
case ADD|ULONGLONG:
ADD_ES(unsigned long long);
case SUB|LONGLONG:
SUB_ES(long long);
case SUB|ULONGLONG:
SUB_ES(unsigned long long);
case MUL|LONGLONG:
MUL_ES(long long);
case MUL|ULONGLONG:
MUL_ES(unsigned long long);
case DIV|LONGLONG:
DIV_ES(long long);
case DIV|ULONGLONG:
DIV_ES(unsigned long long);
case NEG|LONGLONG:
NEG_ES(long long);
case NEG|ULONGLONG:
NEG_ES(unsigned long long);
case LT|LONGLONG:
LT_ES(long long);
case LT|ULONGLONG:
LT_ES(unsigned long long);
case GT|LONGLONG:
GT_ES(long long);
case GT|ULONGLONG:
GT_ES(unsigned long long);
case LE|LONGLONG:
LE_ES(long long);
case LE|ULONGLONG:
LE_ES(unsigned long long);
case GE|LONGLONG:
GE_ES(long long);
case GE|ULONGLONG:
GE_ES(unsigned long long);
case NE|LONGLONG:
NE_ES(long long);
case NE|ULONGLONG:
NE_ES(unsigned long long);
case EQ|LONGLONG:
EQ_ES(long long);
case EQ|ULONGLONG:
EQ_ES(unsigned long long);
case RSH|SLONGLONG:
RSH_ES(long long);
case RSH|SULONGLONG:
RSH_ES(unsigned long long);
case MOD|LONGLONG:
MODL_ES(long long);
case MOD|ULONGLONG:
MODL_ES(unsigned long long);
case RSHI|SLONGLONG:
RSHI_ES(long long);
case RSHI|SULONGLONG:
RSHI_ES(unsigned long long);
#endif
#if SUPPORT_LONG_DOUBLE
case ADD|LONGDOUBLE:
ADD_ES(long double);
case SUB|LONGDOUBLE:
SUB_ES(long double);
case MUL|LONGDOUBLE:
MUL_ES(long double);
case DIV|LONGDOUBLE:
DIV_ES(long double);
case TRUTHOF|BX:
TRUTH_ES(long double);
case NOT|BX:
NOT_ES(long double);
case NEG|LONGDOUBLE:
NEG_ES(long double);
case LT|LONGDOUBLE:
LT_ES(long double);
case GT|LONGDOUBLE:
GT_ES(long double);
case LE|LONGDOUBLE:
LE_ES(long double);
case GE|LONGDOUBLE:
GE_ES(long double);
case NE|LONGDOUBLE:
NE_ES(long double);
case EQ|LONGDOUBLE:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -