Fix uninitialized words in VM interpreter, reported by Patrick Baggett (4281)

This commit is contained in:
Thilo Schulz 2009-10-23 03:02:08 +00:00
parent 6fb304619b
commit c05d9c9f0c

View file

@ -169,7 +169,8 @@ VM_PrepareInterpreter
*/ */
void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) { void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) {
int op; int op;
int pc; int byte_pc;
int int_pc;
byte *code; byte *code;
int instruction; int instruction;
int *codeBase; int *codeBase;
@ -179,22 +180,24 @@ void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) {
// we don't need to translate the instructions, but we still need // we don't need to translate the instructions, but we still need
// to find each instructions starting point for jumps // to find each instructions starting point for jumps
pc = 0; int_pc = byte_pc = 0;
instruction = 0; instruction = 0;
code = (byte *)header + header->codeOffset; code = (byte *)header + header->codeOffset;
codeBase = (int *)vm->codeBase; codeBase = (int *)vm->codeBase;
// Copy and expand instructions to words while building instruction table
while ( instruction < header->instructionCount ) { while ( instruction < header->instructionCount ) {
vm->instructionPointers[ instruction ] = pc; vm->instructionPointers[ instruction ] = int_pc;
instruction++; instruction++;
op = code[ pc ]; op = (int)code[ byte_pc ];
codeBase[pc] = op; codeBase[int_pc] = op;
if ( pc > header->codeLength ) { if ( byte_pc > header->codeLength ) {
Com_Error( ERR_FATAL, "VM_PrepareInterpreter: 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 // these are the only opcodes that aren't a single byte
switch ( op ) { switch ( op ) {
@ -219,76 +222,65 @@ void VM_PrepareInterpreter( vm_t *vm, vmHeader_t *header ) {
case OP_GTF: case OP_GTF:
case OP_GEF: case OP_GEF:
case OP_BLOCK_COPY: case OP_BLOCK_COPY:
codeBase[pc+0] = loadWord(&code[pc]); codeBase[int_pc] = loadWord(&code[byte_pc]);
pc += 4; byte_pc += 4;
int_pc++;
break; break;
case OP_ARG: case OP_ARG:
codeBase[pc+0] = code[pc]; codeBase[int_pc] = (int)code[byte_pc];
pc += 1; byte_pc++;
int_pc++;
break; break;
default: default:
break; break;
} }
} }
pc = 0; int_pc = 0;
instruction = 0; instruction = 0;
code = (byte *)header + header->codeOffset; 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 ) { while ( instruction < header->instructionCount ) {
op = code[ pc ]; op = codeBase[ int_pc ];
instruction++; instruction++;
pc++; int_pc++;
switch ( op ) { switch ( op ) {
// These ops need to translate addresses in jumps from instruction index to int index
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] 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_ENTER:
case OP_CONST: case OP_CONST:
case OP_LOCAL: case OP_LOCAL:
case OP_LEAVE: case OP_LEAVE:
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:
case OP_BLOCK_COPY: 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;
break;
case OP_ARG: case OP_ARG:
pc += 1; int_pc++;
break; break;
default: default:
break; break;
} }
@ -432,14 +424,14 @@ nextInstruction2:
r1 = r0; r1 = r0;
r0 = *opStack = r2; r0 = *opStack = r2;
programCounter += 4; programCounter += 1;
goto nextInstruction2; goto nextInstruction2;
case OP_LOCAL: case OP_LOCAL:
opStack++; opStack++;
r1 = r0; r1 = r0;
r0 = *opStack = r2+programStack; r0 = *opStack = r2+programStack;
programCounter += 4; programCounter += 1;
goto nextInstruction2; goto nextInstruction2;
case OP_LOAD4: case OP_LOAD4:
@ -493,7 +485,7 @@ nextInstruction2:
dest = (int *)&image[ desti ]; dest = (int *)&image[ desti ];
memcpy(dest, src, count); memcpy(dest, src, count);
programCounter += 4; programCounter += 1;
opStack -= 2; opStack -= 2;
} }
goto nextInstruction; goto nextInstruction;
@ -578,7 +570,7 @@ nextInstruction2:
// get size of stack frame // get size of stack frame
v1 = r2; v1 = r2;
programCounter += 4; programCounter += 1;
programStack -= v1; programStack -= v1;
#ifdef DEBUG_VM #ifdef DEBUG_VM
// save old stack frame for debugging traces // save old stack frame for debugging traces
@ -636,7 +628,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -646,7 +638,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -656,7 +648,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -666,7 +658,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -676,7 +668,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -686,7 +678,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -696,7 +688,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -706,7 +698,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -716,7 +708,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -726,7 +718,7 @@ nextInstruction2:
programCounter = r2; //vm->instructionPointers[r2]; programCounter = r2; //vm->instructionPointers[r2];
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
goto nextInstruction; goto nextInstruction;
} }
@ -736,7 +728,7 @@ nextInstruction2:
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} }
@ -747,7 +739,7 @@ nextInstruction2:
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} }
@ -758,7 +750,7 @@ nextInstruction2:
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} }
@ -769,7 +761,7 @@ nextInstruction2:
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} }
@ -780,7 +772,7 @@ nextInstruction2:
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} }
@ -791,7 +783,7 @@ nextInstruction2:
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} else { } else {
programCounter += 4; programCounter += 1;
opStack -= 2; opStack -= 2;
goto nextInstruction; goto nextInstruction;
} }