[quake3-commits] r1693 - trunk/code/qcommon

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Thu Oct 22 23:02:08 EDT 2009


Author: thilo
Date: 2009-10-22 23:02:08 -0400 (Thu, 22 Oct 2009)
New Revision: 1693

Modified:
   trunk/code/qcommon/vm_interpreted.c
Log:
Fix uninitialized words in VM interpreter, reported by Patrick Baggett (4281)


Modified: trunk/code/qcommon/vm_interpreted.c
===================================================================
--- trunk/code/qcommon/vm_interpreted.c	2009-10-21 10:18:46 UTC (rev 1692)
+++ trunk/code/qcommon/vm_interpreted.c	2009-10-23 03:02:08 UTC (rev 1693)
@@ -169,7 +169,8 @@
 */
 void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) {
 	int		op;
-	int		pc;
+	int		byte_pc;
+	int		int_pc;
 	byte	*code;
 	int		instruction;
 	int		*codeBase;
@@ -179,22 +180,24 @@
 
 	// we don't need to translate the instructions, but we still need
 	// to find each instructions starting point for jumps
-	pc = 0;
+	int_pc = byte_pc = 0;
 	instruction = 0;
 	code = (byte *)header + header->codeOffset;
 	codeBase = (int *)vm->codeBase;
 
+	// Copy and expand instructions to words while building instruction table
 	while ( instruction < header->instructionCount ) {
-		vm->instructionPointers[ instruction ] = pc;
+		vm->instructionPointers[ instruction ] = int_pc;
 		instruction++;
 
-		op = code[ pc ];
-		codeBase[pc] = op;
-		if ( pc > header->codeLength ) {
+		op = (int)code[ byte_pc ];
+		codeBase[int_pc] = op;
+		if ( byte_pc > header->codeLength ) {
 			Com_Error( ERR_FATAL, "VM_PrepareInterpreter: pc > header->codeLength" );
 		}
 
-		pc++;
+		byte_pc++;
+		int_pc++;
 
 		// these are the only opcodes that aren't a single byte
 		switch ( op ) {
@@ -219,32 +222,33 @@
 		case OP_GTF:
 		case OP_GEF:
 		case OP_BLOCK_COPY:
-			codeBase[pc+0] = loadWord(&code[pc]);
-			pc += 4;
+			codeBase[int_pc] = loadWord(&code[byte_pc]);
+			byte_pc += 4;
+			int_pc++;
 			break;
 		case OP_ARG:
-			codeBase[pc+0] = code[pc];
-			pc += 1;
+			codeBase[int_pc] = (int)code[byte_pc];
+			byte_pc++;
+			int_pc++;
 			break;
 		default:
 			break;
 		}
 
 	}
-	pc = 0;
+	int_pc = 0;
 	instruction = 0;
 	code = (byte *)header + header->codeOffset;
-	codeBase = (int *)vm->codeBase;
-
+	
+	// Now that the code has been expanded to int-sized opcodes, we'll translate instruction index
+	//into an index into codeBase[], which contains opcodes and operands.
 	while ( instruction < header->instructionCount ) {
-		op = code[ pc ];
+		op = codeBase[ int_pc ];
 		instruction++;
-		pc++;
+		int_pc++;
+		
 		switch ( op ) {
-		case OP_ENTER:
-		case OP_CONST:
-		case OP_LOCAL:
-		case OP_LEAVE:
+		// These ops need to translate addresses in jumps from instruction index to int index
 		case OP_EQ:
 		case OP_NE:
 		case OP_LTI:
@@ -261,34 +265,22 @@
 		case OP_LEF:
 		case OP_GTF:
 		case OP_GEF:
-		case OP_BLOCK_COPY:
-			switch(op) {
-				case OP_EQ:
-				case OP_NE:
-				case OP_LTI:
-				case OP_LEI:
-				case OP_GTI:
-				case OP_GEI:
-				case OP_LTU:
-				case OP_LEU:
-				case OP_GTU:
-				case OP_GEU:
-				case OP_EQF:
-				case OP_NEF:
-				case OP_LTF:
-				case OP_LEF:
-				case OP_GTF:
-				case OP_GEF:
-				codeBase[pc] = vm->instructionPointers[codeBase[pc]];
-				break;
-			default:
-				break;
-			}
-			pc += 4;
+			// codeBase[pc] is the instruction index. Convert that into an offset into
+			//the int-aligned codeBase[] by the lookup table.
+			codeBase[int_pc] = vm->instructionPointers[codeBase[int_pc]];
+			int_pc++;
 			break;
+
+		// These opcodes have an operand that isn't an instruction index
+		case OP_ENTER:
+		case OP_CONST:
+		case OP_LOCAL:
+		case OP_LEAVE:
+		case OP_BLOCK_COPY:
 		case OP_ARG:
-			pc += 1;
+			int_pc++;
 			break;
+
 		default:
 			break;
 		}
@@ -432,14 +424,14 @@
 			r1 = r0;
 			r0 = *opStack = r2;
 			
-			programCounter += 4;
+			programCounter += 1;
 			goto nextInstruction2;
 		case OP_LOCAL:
 			opStack++;
 			r1 = r0;
 			r0 = *opStack = r2+programStack;
 
-			programCounter += 4;
+			programCounter += 1;
 			goto nextInstruction2;
 
 		case OP_LOAD4:
@@ -493,7 +485,7 @@
 				dest = (int *)&image[ desti ];
 				
 				memcpy(dest, src, count);
-				programCounter += 4;
+				programCounter += 1;
 				opStack -= 2;
 			}
 			goto nextInstruction;
@@ -578,7 +570,7 @@
 			// get size of stack frame
 			v1 = r2;
 
-			programCounter += 4;
+			programCounter += 1;
 			programStack -= v1;
 #ifdef DEBUG_VM
 			// save old stack frame for debugging traces
@@ -636,7 +628,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -646,7 +638,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -656,7 +648,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -666,7 +658,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -676,7 +668,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -686,7 +678,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -696,7 +688,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -706,7 +698,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -716,7 +708,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -726,7 +718,7 @@
 				programCounter = r2;	//vm->instructionPointers[r2];
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				goto nextInstruction;
 			}
 
@@ -736,7 +728,7 @@
 				opStack -= 2;
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				opStack -= 2;
 				goto nextInstruction;
 			}
@@ -747,7 +739,7 @@
 				opStack -= 2;
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				opStack -= 2;
 				goto nextInstruction;
 			}
@@ -758,7 +750,7 @@
 				opStack -= 2;
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				opStack -= 2;
 				goto nextInstruction;
 			}
@@ -769,7 +761,7 @@
 				opStack -= 2;
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				opStack -= 2;
 				goto nextInstruction;
 			}
@@ -780,7 +772,7 @@
 				opStack -= 2;
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				opStack -= 2;
 				goto nextInstruction;
 			}
@@ -791,7 +783,7 @@
 				opStack -= 2;
 				goto nextInstruction;
 			} else {
-				programCounter += 4;
+				programCounter += 1;
 				opStack -= 2;
 				goto nextInstruction;
 			}



More information about the quake3-commits mailing list