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

📄 bterp.c

📁 OXCC is a multipass, interpreting C compiler with several language extensions. It generates an Archi
💻 C
📖 第 1 页 / 共 5 页
字号:
		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 + -