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

📄 vm_interpreted.c

📁 quakeIII源码这个不用我多说吧
💻 C
📖 第 1 页 / 共 2 页
字号:
			goto nextInstruction2;

		case OP_STORE4:
			*(int *)&image[ r1&(dataMask & ~3) ] = r0;
			opStack -= 2;
			goto nextInstruction;
		case OP_STORE2:
			*(short *)&image[ r1&(dataMask & ~1) ] = r0;
			opStack -= 2;
			goto nextInstruction;
		case OP_STORE1:
			image[ r1&dataMask ] = r0;
			opStack -= 2;
			goto nextInstruction;

		case OP_ARG:
			// single byte offset from programStack
			*(int *)&image[ codeImage[programCounter] + programStack ] = r0;
			opStack--;
			programCounter += 1;
			goto nextInstruction;

		case OP_BLOCK_COPY:
			{
				int		*src, *dest;
				int		i, count, srci, desti;

				count = r2;
				// MrE: copy range check
				srci = r0 & dataMask;
				desti = r1 & dataMask;
				count = ((srci + count) & dataMask) - srci;
				count = ((desti + count) & dataMask) - desti;

				src = (int *)&image[ r0&dataMask ];
				dest = (int *)&image[ r1&dataMask ];
				if ( ( (int)src | (int)dest | count ) & 3 ) {
					Com_Error( ERR_DROP, "OP_BLOCK_COPY not dword aligned" );
				}
				count >>= 2;
				for ( i = count-1 ; i>= 0 ; i-- ) {
					dest[i] = src[i];
				}
				programCounter += 4;
				opStack -= 2;
			}
			goto nextInstruction;

		case OP_CALL:
			// save current program counter
			*(int *)&image[ programStack ] = programCounter;
			
			// jump to the location on the stack
			programCounter = r0;
			opStack--;
			if ( programCounter < 0 ) {
				// system call
				int		r;
				int		temp;
#ifdef DEBUG_VM
				int		stomped;

				if ( vm_debugLevel ) {
					Com_Printf( "%s---> systemcall(%i)\n", DEBUGSTR, -1 - programCounter );
				}
#endif
				// save the stack to allow recursive VM entry
				temp = vm->callLevel;
				vm->programStack = programStack - 4;
#ifdef DEBUG_VM
				stomped = *(int *)&image[ programStack + 4 ];
#endif
				*(int *)&image[ programStack + 4 ] = -1 - programCounter;

//VM_LogSyscalls( (int *)&image[ programStack + 4 ] );
				r = vm->systemCall( (int *)&image[ programStack + 4 ] );

#ifdef DEBUG_VM
				// this is just our stack frame pointer, only needed
				// for debugging
				*(int *)&image[ programStack + 4 ] = stomped;
#endif

				// save return value
				opStack++;
				*opStack = r;
				programCounter = *(int *)&image[ programStack ];
				vm->callLevel = temp;
#ifdef DEBUG_VM
				if ( vm_debugLevel ) {
					Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
				}
#endif
			} else {
				programCounter = vm->instructionPointers[ programCounter ];
			}
			goto nextInstruction;

		// push and pop are only needed for discarded or bad function return values
		case OP_PUSH:
			opStack++;
			goto nextInstruction;
		case OP_POP:
			opStack--;
			goto nextInstruction;

		case OP_ENTER:
#ifdef DEBUG_VM
			profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter );
#endif
			// get size of stack frame
			v1 = r2;

			programCounter += 4;
			programStack -= v1;
#ifdef DEBUG_VM
			// save old stack frame for debugging traces
			*(int *)&image[programStack+4] = programStack + v1;
			if ( vm_debugLevel ) {
				Com_Printf( "%s---> %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter - 5 ) );
				if ( vm->breakFunction && programCounter - 5 == vm->breakFunction ) {
					// this is to allow setting breakpoints here in the debugger
					vm->breakCount++;
//					vm_debugLevel = 2;
//					VM_StackTrace( vm, programCounter, programStack );
				}
				vm->callLevel++;
			}
#endif
			goto nextInstruction;
		case OP_LEAVE:
			// remove our stack frame
			v1 = r2;

			programStack += v1;

			// grab the saved program counter
			programCounter = *(int *)&image[ programStack ];
#ifdef DEBUG_VM
			profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter );
			if ( vm_debugLevel ) {
				vm->callLevel--;
				Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
			}
#endif
			// check for leaving the VM
			if ( programCounter == -1 ) {
				goto done;
			}
			goto nextInstruction;

		/*
		===================================================================
		BRANCHES
		===================================================================
		*/

		case OP_JUMP:
			programCounter = r0;
			programCounter = vm->instructionPointers[ programCounter ];
			opStack--;
			goto nextInstruction;

		case OP_EQ:
			opStack -= 2;
			if ( r1 == r0 ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_NE:
			opStack -= 2;
			if ( r1 != r0 ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_LTI:
			opStack -= 2;
			if ( r1 < r0 ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_LEI:
			opStack -= 2;
			if ( r1 <= r0 ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_GTI:
			opStack -= 2;
			if ( r1 > r0 ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_GEI:
			opStack -= 2;
			if ( r1 >= r0 ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_LTU:
			opStack -= 2;
			if ( ((unsigned)r1) < ((unsigned)r0) ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_LEU:
			opStack -= 2;
			if ( ((unsigned)r1) <= ((unsigned)r0) ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_GTU:
			opStack -= 2;
			if ( ((unsigned)r1) > ((unsigned)r0) ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_GEU:
			opStack -= 2;
			if ( ((unsigned)r1) >= ((unsigned)r0) ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				goto nextInstruction;
			} else {
				programCounter += 4;
				goto nextInstruction;
			}

		case OP_EQF:
			if ( ((float *)opStack)[-1] == *(float *)opStack ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				opStack -= 2;
				goto nextInstruction;
			} else {
				programCounter += 4;
				opStack -= 2;
				goto nextInstruction;
			}

		case OP_NEF:
			if ( ((float *)opStack)[-1] != *(float *)opStack ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				opStack -= 2;
				goto nextInstruction;
			} else {
				programCounter += 4;
				opStack -= 2;
				goto nextInstruction;
			}

		case OP_LTF:
			if ( ((float *)opStack)[-1] < *(float *)opStack ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				opStack -= 2;
				goto nextInstruction;
			} else {
				programCounter += 4;
				opStack -= 2;
				goto nextInstruction;
			}

		case OP_LEF:
			if ( ((float *)opStack)[-1] <= *(float *)opStack ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				opStack -= 2;
				goto nextInstruction;
			} else {
				programCounter += 4;
				opStack -= 2;
				goto nextInstruction;
			}

		case OP_GTF:
			if ( ((float *)opStack)[-1] > *(float *)opStack ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				opStack -= 2;
				goto nextInstruction;
			} else {
				programCounter += 4;
				opStack -= 2;
				goto nextInstruction;
			}

		case OP_GEF:
			if ( ((float *)opStack)[-1] >= *(float *)opStack ) {
				programCounter = r2;	//vm->instructionPointers[r2];
				opStack -= 2;
				goto nextInstruction;
			} else {
				programCounter += 4;
				opStack -= 2;
				goto nextInstruction;
			}


		//===================================================================

		case OP_NEGI:
			*opStack = -r0;
			goto nextInstruction;
		case OP_ADD:
			opStack[-1] = r1 + r0;
			opStack--;
			goto nextInstruction;
		case OP_SUB:
			opStack[-1] = r1 - r0;
			opStack--;
			goto nextInstruction;
		case OP_DIVI:
			opStack[-1] = r1 / r0;
			opStack--;
			goto nextInstruction;
		case OP_DIVU:
			opStack[-1] = ((unsigned)r1) / ((unsigned)r0);
			opStack--;
			goto nextInstruction;
		case OP_MODI:
			opStack[-1] = r1 % r0;
			opStack--;
			goto nextInstruction;
		case OP_MODU:
			opStack[-1] = ((unsigned)r1) % (unsigned)r0;
			opStack--;
			goto nextInstruction;
		case OP_MULI:
			opStack[-1] = r1 * r0;
			opStack--;
			goto nextInstruction;
		case OP_MULU:
			opStack[-1] = ((unsigned)r1) * ((unsigned)r0);
			opStack--;
			goto nextInstruction;

		case OP_BAND:
			opStack[-1] = ((unsigned)r1) & ((unsigned)r0);
			opStack--;
			goto nextInstruction;
		case OP_BOR:
			opStack[-1] = ((unsigned)r1) | ((unsigned)r0);
			opStack--;
			goto nextInstruction;
		case OP_BXOR:
			opStack[-1] = ((unsigned)r1) ^ ((unsigned)r0);
			opStack--;
			goto nextInstruction;
		case OP_BCOM:
			opStack[-1] = ~ ((unsigned)r0);
			goto nextInstruction;

		case OP_LSH:
			opStack[-1] = r1 << r0;
			opStack--;
			goto nextInstruction;
		case OP_RSHI:
			opStack[-1] = r1 >> r0;
			opStack--;
			goto nextInstruction;
		case OP_RSHU:
			opStack[-1] = ((unsigned)r1) >> r0;
			opStack--;
			goto nextInstruction;

		case OP_NEGF:
			*(float *)opStack =  -*(float *)opStack;
			goto nextInstruction;
		case OP_ADDF:
			*(float *)(opStack-1) = *(float *)(opStack-1) + *(float *)opStack;
			opStack--;
			goto nextInstruction;
		case OP_SUBF:
			*(float *)(opStack-1) = *(float *)(opStack-1) - *(float *)opStack;
			opStack--;
			goto nextInstruction;
		case OP_DIVF:
			*(float *)(opStack-1) = *(float *)(opStack-1) / *(float *)opStack;
			opStack--;
			goto nextInstruction;
		case OP_MULF:
			*(float *)(opStack-1) = *(float *)(opStack-1) * *(float *)opStack;
			opStack--;
			goto nextInstruction;

		case OP_CVIF:
			*(float *)opStack =  (float)*opStack;
			goto nextInstruction;
		case OP_CVFI:
			*opStack = (int) *(float *)opStack;
			goto nextInstruction;
		case OP_SEX8:
			*opStack = (signed char)*opStack;
			goto nextInstruction;
		case OP_SEX16:
			*opStack = (short)*opStack;
			goto nextInstruction;
		}
	}

done:
	vm->currentlyInterpreting = qfalse;

	if ( opStack != &stack[1] ) {
		Com_Error( ERR_DROP, "Interpreter error: opStack = %i", opStack - stack );
	}

	vm->programStack = stackOnEntry;

	// return the result
	return *opStack;
}

⌨️ 快捷键说明

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