⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bterp.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 5 页
字号:
	*((long*)&pth[4]) = (long)ft;
	*((long*)&pth[9]) = (long)iv;
	*((long*)&pth[14]) = (long)base_stack;
	*((long*)&pth[22]) = (long)_bterp_handle_callbacks;

	return pth;
}
static void
ensure_strrets(Piv iv)
{
	if(iv->strretcnt+1 >= iv->slcnt) {
		iv->slcnt += 128;
		iv->struclist = realloc(iv->struclist, iv->slcnt * sizeof(void *));
	}
}
static void
prune_structs(Piv iv)
{
	while(iv->strretcnt > 0)
	{
		free(iv->struclist[--iv->strretcnt]);
	}
}
static int
mover(Piv iv, unsigned char *dp, int opcode, int size, char *src, char *dst)
{
char *s, *d;
int bump;

	switch(opcode)
	{
		case S1|D1:
			s = src+(G1(dp)<<2);
			d = dst+(G1(dp+1)<<2);
			bump = 3;
			break;
		case S1|D2:
			s = src+(G1(dp)<<2);
			d = dst+(G2(dp+1)<<2);
			bump = 4;
			break;
		case S1|D3:
			s = src+(G1(dp)<<2);
			d = dst+(G3(dp+1)<<0);
			bump = 5;
			break;
		case S1|D4:
			s = src+(G1(dp)<<2);
			d = (void*)G4(dp+1);
			bump = 6;
			break;
		case S2|D1:
			s = src+(G2(dp)<<2);
			d = dst+G1(dp+2);
			bump = 4;
			break;
		case S2|D2:
			s = src+(G2(dp)<<2);
			d = dst+(G2(dp+2)<<2);
			bump = 5;
			break;
		case S2|D3:
			s = src+(G2(dp)<<2);
			d = dst+(G3(dp+2)<<0);
			bump = 6;
			break;
		case S2|D4:
			s = src+(G2(dp)<<2);
			d = (void*)G4(dp+2);
			bump = 7;
			break;
		case S3|D1:
			s = src+(G3(dp)<<0);
			d = dst+(G1(dp+3)<<2);
			bump = 5;
			break;
		case S3|D2:
			s = src+(G3(dp)<<0);
			d = dst+(G2(dp+3)<<2);
			bump = 6;
			break;
		case S3|D3:
			s = src+(G3(dp)<<0);
			d = dst+(G3(dp+3)<<0);
			bump = 7;
			break;
		case S3|D4:
			s = src+(G3(dp)<<0);
			d = (void*)G4(dp+3);
			bump = 8;
			break;
		case S4|D1:
			s = (void*)G4(dp);
			d = dst+(G1(dp+4)<<2);
			bump = 6;
			break;
		case S4|D2:
			s = (void*)G4(dp);
			d = dst+(G2(dp+4)<<2);
			bump = 7;
			break;
		case S4|D3:
			s = (void*)G4(dp);
			d = dst+(G3(dp+4)<<0);
			bump = 8;
			break;
		case S4|D4:
			s = (void*)G4(dp);
			d = (void*)G4(dp+4);
			bump = 9;
			break;
		default:
			printf("bterp:ERROR: bad opcode for `mover' at pc=%lx\n",
				((char*)dp - iv->text_base) - 1);
			longjmp(iv->jb, 1);			
	}
	if(size == B1)
		*((char*)d) = *((char*)s);
	else if(size == B2)
		*((short*)d) = *((short*)s);
	else if(size == B4)
		*((long*)d) = *((long*)s);
	else if(size == B8)
		*((double*)d) = *((double*)s);
	else
		memcpy(d,s,XSZ);
	return bump;
}
static void
load_efunc(Piv iv, Pft ft)
{
void *e_faddr;
	if(!(e_faddr = oxlink_find_bare_func((void*)ft->funcaddr)))
	{/* not in core, load the file */
		if(!(e_faddr = oxlink_load_bare_symb((void*)ft->funcaddr, 1)))
		{
			printf("bterp:ERROR: Can't load function `%s'\n", (char*)ft->funcaddr);
			exit(1);
		}
	}
	ft->funcaddr = (long)e_faddr;
	ft->fmods |= Fthunked;
}
/* MOST OF THESE BUILTINS ARE UNNECESSARY DEMOS */
/* PUT ANYTHING THAT COULD BE CALLED THROUGH A FUNCPTR HERE */
static int
do_builtin(Piv iv, unsigned char code, char **pes)
{/* NOTE: builtins with no args and void return must leave a pseudo ret on stack */
char *es, *oes;
	es = *pes;
	oes = es-SZ;

	switch(code)
	{
		case ALLOCA:
		{
		char *abuf = malloc(*((unsigned*)es)+sizeof(void*));
			*((void**)es) = abuf+sizeof(void*);
			*((void**)abuf) = iv->allocalist;
			iv->allocalist = abuf;
			return 1;
		}
		case STRLEN:
		{
			*((unsigned*)es) = strlen(*((const char**)es));
			return 1;
		}
		case STRCPY:
		{
			*((void**)oes) = strcpy(*((char**)oes),*((const char**)es));
			*pes = oes;
			return 1;
		}
		case STRCAT:
		{
			*((void**)oes) = strcat(*((char**)oes),*((const char**)es));
			*pes = oes;
			return 1;
		}
		case MEMCPY:
		{
			*((void**)(oes-SZ)) = memcpy(*((void**)(oes-SZ)),*((const void**)oes),*((unsigned*)es));
			*pes -= 2*SZ;
			return 1;
		}
		case MEMMOVE:
		{
			*((void**)(oes-SZ)) = memmove(*((void**)(oes-SZ)),*((const void**)oes),*((unsigned*)es));
			*pes -= 2*SZ;
			return 1;
		}
		case MEMSET:
		{
			*((void**)(oes-SZ)) = 
				memset(*((void**)(oes-SZ)),*((int*)oes),*((long*)es));
			*pes -= 2*SZ;
			return 1;
		}
		case BZERO:
		{
			memset(*((void**)oes),0,*((unsigned*)es));
			*pes = oes;
			return 0;
		}
		case DEBUG:
		{
			iv->debug=1;
			printf("DEBUG ON\n");
			fflush(stdout);
			*pes = es+SZ;	/* pseudo ret */
			return 0;
		}
		case NODEBUG:
		{
			iv->debug=0;
			printf("DEBUG OFF\n");
			fflush(stdout);
			*pes = es+SZ;	/* pseudo ret */
			return 0;
		}
		case MALLOC:
		{
			*((void**)es) = malloc(*((unsigned*)es));
			return 1;
		}
		case CALLOC:
		{
			*((void**)oes) = calloc(*((unsigned*)oes),*((unsigned*)es));
			*pes = oes;
			return 1;
		}
		case REALLOC:
		{
			*((void**)oes) = realloc(*((void**)oes),*((unsigned*)es));
			*pes = oes;
			return 1;
		}
	}	
	return 0;
}
static void *
bterp_eval(Piv iv, long pc_offset, void *base_stack, char *es, char *eb)
{
char *dd, *fs;
unsigned char *pc, *np;
char *oes, *nes, *bes;
long first_loc = -100;
long last_loc = 0;

  dd = iv->dd;
  fs = base_stack + sizeof(SB);
  pc = iv->text_base + pc_offset;
  bes = es;

if(iv->debug) {
printf("FUNCTION ofs=%lx pc=%p bs=%p fs=%p es=%p dd=%p eb=%p\n", 
pc_offset, pc, base_stack, fs, es, dd, eb);
fflush(stdout);
}
  for(;;++pc)
  {
	np = pc+1;
	oes = es-SZ;
	nes = es+SZ;

if(iv->debug) {
printf("ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
((char*)pc) - iv->text_base, *pc, es, 
*((long*)es), *((long*)oes), *((long*)nes));
fflush(stdout);
}
if(es < bes) {
printf("bterp:ERROR: STACK UNDERFLOW ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
((char*)pc) - iv->text_base, *pc, es, *((long*)es), *((long*)oes), *((long*)nes));
fflush(stdout);
longjmp(iv->jb, (int)es);
}
if(es >= eb) {
printf("bterp:ERROR: STACK OVERFLOW ofs:%lx op=%x es=%p val=%lx oval=%lx nval=%lx\n",
((char*)pc) - iv->text_base, *pc, es, *((long*)es), *((long*)oes), *((long*)nes));
fflush(stdout);
longjmp(iv->jb, (int)es);
}
	switch(*pc)
	{
		case LOCATE|J1:
		{
			last_loc = ((char*)(pc + GP1(np))) - iv->text_base;
			if(first_loc == -100) first_loc = last_loc; 			
			++pc;
			break;
		}
		case LOCATE|J2:
		{
			last_loc = ((char*)(pc + GP2(np))) - iv->text_base;
			if(first_loc == -100) first_loc = last_loc; 			
			pc += 2;
			break;
		}
		case LOCATE|J3:
		{
			last_loc = ((char*)(pc + GP3(np))) - iv->text_base;
			if(first_loc == -100) first_loc = last_loc; 			
			pc += 3;
			break;
		}
		case LOCATE|J4:
		{
			last_loc = ((char*)(pc + GP4(np))) - iv->text_base;
			if(first_loc == -100) first_loc = last_loc; 			
			pc += 4;
			break;
		}
		case LS|A1|B1:
			LOADSTK1(char);
		case LS|A1|B2:
			LOADSTK1(short);
		case LS|A1|B4:
			LOADSTK1(long);
		case LS|A1|B8:
			LOADSTK1(double);
		case LS|A2|B1:
			LOADSTK2(char);
		case LS|A2|B2:
			LOADSTK2(short);
		case LS|A2|B4:
			LOADSTK2(long);
		case LS|A2|B8:
			LOADSTK2(double);
		case LS|A3|B1:
			LOADSTK3(char);
		case LS|A3|B2:
			LOADSTK3(short);
		case LS|A3|B4:
			LOADSTK3(long);
		case LS|A3|B8:
			LOADSTK3(double);

		case NEG|BYTE:
			NEG_ES(char);
		case NEG|SHORT:
			NEG_ES(short);
		case NEG|LONG:
			NEG_ES(long);
		case NEG|UBYTE:
			NEG_ES(unsigned char);
		case NEG|USHORT:
			NEG_ES(unsigned short);
		case NEG|ULONG:
			NEG_ES(unsigned long);
		case NEG|FLOAT:
			NEG_ES(float);
		case NEG|DOUBLE:
			NEG_ES(double);

		case LM|A1|B1:
			LOADMEM1(char);
		case LM|A1|B2:
			LOADMEM1(short);
		case LM|A1|B4:
			LOADMEM1(long);
		case LM|A1|B8:
			LOADMEM1(double);
		case LM|A2|B1:
			LOADMEM2(char);
		case LM|A2|B2:
			LOADMEM2(short);
		case LM|A2|B4:
			LOADMEM2(long);
		case LM|A2|B8:
			LOADMEM2(double);
		case LM|A3|B1:
			LOADMEM3(char);
		case LM|A3|B2:
			LOADMEM3(short);
		case LM|A3|B4:
			LOADMEM3(long);
		case LM|A3|B8:
			LOADMEM3(double);
		case LM|A4|B1:
			LOADMEM4(char);
		case LM|A4|B2:
			LOADMEM4(short);
		case LM|A4|B4:
			LOADMEM4(long);
		case LM|A4|B8:
			LOADMEM4(double);

		case COMP|B1:
			COMP_ES(char);
		case COMP|B2:
			COMP_ES(short);
		case COMP|B4:
			COMP_ES(long);
#if SUPPORT_LONG_LONG
		case COMP|B8:
			COMP_ES(long long);
#else
#endif
		case JMP|J1:
			pc += GP1(np)-1;
			break;
		case JMP|J2:
			pc += GP2(np)-1;
			break;
		case JMP|J3:
			pc += GP3(np)-1;
			break;
		case JMP|J4:
			pc += GP4(np)-1;
			break;

		case LJMPT|J1:
			if(*(es)) pc += GP1(np)-1;
			else {pc += 1; es=oes;}
			break;
		case LJMPT|J2:
			if(*(es)) pc += GP2(np)-1;
			else {pc += 2; es=oes;}
			break;
		case LJMPT|J3:
			if(*(es)) pc += GP3(np)-1;
			else {pc += 3; es=oes;}
			break;
		case LJMPT|J4:
			if(*(es)) pc += GP4(np)-1;
			else {pc += 4; es=oes;}
			break;

		case JMPT|J1:
			if(*(es)) pc += GP1(np)-1;
			else pc += 1;
			es = oes;
			break;
		case JMPT|J2:
			if(*(es)) pc += GP2(np)-1;
			else pc += 2;
			es = oes;
			break;
		case JMPT|J3:
			if(*(es)) pc += GP3(np)-1;
			else pc += 3;
			es = oes;
			break;
		case JMPT|J4:
			if(*(es)) pc += GP4(np)-1;
			else pc += 4;
			es = oes;
			break;

		case LJMPF|J1:
			if(!*(es)) pc += GP1(np)-1;
			else {pc += 1; es=oes;}
			break;
		case LJMPF|J2:
			if(!*(es)) pc += GP2(np)-1;
			else {pc += 2; es=oes;};
			break;
		case LJMPF|J3:
			if(!*(es)) pc += GP3(np)-1;
			else {pc += 3; es=oes;}
			break;
		case LJMPF|J4:
			if(!*(es)) pc += GP4(np)-1;
			else {pc +=4; es=oes;}
			break;

		case JMPF|J1:
			if(!*(es)) pc += GP1(np)-1;
			else pc += 1;
			es = oes;
			break;
		case JMPF|J2:
			if(!*(es)) pc += GP2(np)-1;
			else pc += 2;
			es = oes;
			break;
		case JMPF|J3:
			if(!*(es)) pc += GP3(np)-1;
			else pc += 3;
			es = oes;
			break;
		case JMPF|J4:
			if(!*(es)) pc += GP4(np)-1;
			else pc +=4;
			es = oes;
			break;

		case NOT|B1:
			NOT_ES(char);
		case NOT|B2:
			NOT_ES(short);
		case NOT|B4:	/* also FLOAT */
			NOT_ES(long);
		case NOT|B8:	/* also DOUBLE */
#if SUPPORT_LONG_LONG
			NOT_ES(long long);
#else
			NOT_ES1;
#endif
		case SS|A1|B1:
			STORSTK1(char);
		case SS|A1|B2:
			STORSTK1(short);
		case SS|A1|B4:
			STORSTK1(long);
		case SS|A1|B8:
			STORSTK1(double);
		case SS|A2|B1:
			STORSTK2(char);
		case SS|A2|B2:
			STORSTK2(short);
		case SS|A2|B4:
			STORSTK2(long);
		case SS|A2|B8:
			STORSTK2(double);
		case SS|A3|B1:
			STORSTK3(char);
		case SS|A3|B2:
			STORSTK3(short);
		case SS|A3|B4:
			STORSTK3(long);
		case SS|A3|B8:
			STORSTK3(double);

		case TRUTHOF|B2:
			TRUTH_ES(short);
		case TRUTHOF|B4:		/* also FLOAT */
			TRUTH_ES(long);
		case TRUTHOF|B8:		/* also DOUBLE */
#if SUPPORT_LONG_LONG
			TRUTH_ES(long long);
#else

⌨️ 快捷键说明

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