use vm->callLevel to count recursive calls to VM_Call

Throw an error if vm->callLevel is set and VM_Free is called.
This commit is contained in:
Ludwig Nussel 2008-03-24 21:20:55 +00:00
parent 6c5211c0d3
commit 7a5243a3b2
4 changed files with 18 additions and 16 deletions

View file

@ -608,6 +608,15 @@ VM_Free
*/ */
void VM_Free( vm_t *vm ) { void VM_Free( vm_t *vm ) {
if(!vm) {
return;
}
if(vm->callLevel) {
Com_Error( ERR_FATAL, "VM_Free(%s) on running vm", vm->name );
return;
}
if(vm->destroy) if(vm->destroy)
vm->destroy(vm); vm->destroy(vm);
@ -635,13 +644,8 @@ void VM_Free( vm_t *vm ) {
void VM_Clear(void) { void VM_Clear(void) {
int i; int i;
for (i=0;i<MAX_VM; i++) { for (i=0;i<MAX_VM; i++) {
if ( vmTable[i].dllHandle ) { VM_Free(&vmTable[i]);
Sys_UnloadDll( vmTable[i].dllHandle );
}
Com_Memset( &vmTable[i], 0, sizeof( vm_t ) );
} }
currentVM = NULL;
lastVM = NULL;
} }
void *VM_ArgPtr( intptr_t intValue ) { void *VM_ArgPtr( intptr_t intValue ) {
@ -722,6 +726,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) {
Com_Printf( "VM_Call( %d )\n", callnum ); Com_Printf( "VM_Call( %d )\n", callnum );
} }
++vm->callLevel;
// if we have a dll loaded, call it directly // if we have a dll loaded, call it directly
if ( vm->entryPoint ) { if ( vm->entryPoint ) {
//rcg010207 - see dissertation at top of VM_DllSyscall() in this file. //rcg010207 - see dissertation at top of VM_DllSyscall() in this file.
@ -765,6 +770,7 @@ intptr_t QDECL VM_Call( vm_t *vm, int callnum, ... ) {
r = VM_CallInterpreted( vm, &a.callnum ); r = VM_CallInterpreted( vm, &a.callnum );
#endif #endif
} }
--vm->callLevel;
if ( oldVM != NULL ) if ( oldVM != NULL )
currentVM = oldVM; currentVM = oldVM;

View file

@ -376,8 +376,6 @@ int VM_CallInterpreted( vm_t *vm, int *args ) {
*(int *)&image[ programStack + 4 ] = 0; // return stack *(int *)&image[ programStack + 4 ] = 0; // return stack
*(int *)&image[ programStack ] = -1; // will terminate the loop on return *(int *)&image[ programStack ] = -1; // will terminate the loop on return
vm->callLevel = 0;
VM_Debug(0); VM_Debug(0);
// vm_debugLevel=2; // vm_debugLevel=2;
@ -516,7 +514,7 @@ nextInstruction2:
if ( programCounter < 0 ) { if ( programCounter < 0 ) {
// system call // system call
int r; int r;
int temp; // int temp;
#ifdef DEBUG_VM #ifdef DEBUG_VM
int stomped; int stomped;
@ -525,7 +523,7 @@ nextInstruction2:
} }
#endif #endif
// save the stack to allow recursive VM entry // save the stack to allow recursive VM entry
temp = vm->callLevel; // temp = vm->callLevel;
vm->programStack = programStack - 4; vm->programStack = programStack - 4;
#ifdef DEBUG_VM #ifdef DEBUG_VM
stomped = *(int *)&image[ programStack + 4 ]; stomped = *(int *)&image[ programStack + 4 ];
@ -558,7 +556,7 @@ nextInstruction2:
opStack++; opStack++;
*opStack = r; *opStack = r;
programCounter = *(int *)&image[ programStack ]; programCounter = *(int *)&image[ programStack ];
vm->callLevel = temp; // vm->callLevel = temp;
#ifdef DEBUG_VM #ifdef DEBUG_VM
if ( vm_debugLevel ) { if ( vm_debugLevel ) {
Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) ); Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
@ -599,7 +597,7 @@ nextInstruction2:
// vm_debugLevel = 2; // vm_debugLevel = 2;
// VM_StackTrace( vm, programCounter, programStack ); // VM_StackTrace( vm, programCounter, programStack );
} }
vm->callLevel++; // vm->callLevel++;
} }
#endif #endif
goto nextInstruction; goto nextInstruction;
@ -614,7 +612,7 @@ nextInstruction2:
#ifdef DEBUG_VM #ifdef DEBUG_VM
profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter ); profileSymbol = VM_ValueToFunctionSymbol( vm, programCounter );
if ( vm_debugLevel ) { if ( vm_debugLevel ) {
vm->callLevel--; // vm->callLevel--;
Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) ); Com_Printf( "%s<--- %s\n", DEBUGSTR, VM_ValueToSymbol( vm, programCounter ) );
} }
#endif #endif

View file

@ -156,7 +156,7 @@ struct vm_s {
int numSymbols; int numSymbols;
struct vmSymbol_s *symbols; struct vmSymbol_s *symbols;
int callLevel; // for debug indenting int callLevel; // counts recursive VM_Call
int breakFunction; // increment breakCount on function entry to this int breakFunction; // increment breakCount on function entry to this
int breakCount; int breakCount;

View file

@ -1069,7 +1069,6 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
currentVM = vm; currentVM = vm;
++vm->callLevel;
// Com_Printf("entering %s level %d, call %d, arg1 = 0x%x\n", vm->name, vm->callLevel, args[0], args[1]); // Com_Printf("entering %s level %d, call %d, arg1 = 0x%x\n", vm->name, vm->callLevel, args[0], args[1]);
// interpret the code // interpret the code
@ -1131,7 +1130,6 @@ int VM_CallCompiled( vm_t *vm, int *args ) {
} }
// Com_Printf("exiting %s level %d\n", vm->name, vm->callLevel); // Com_Printf("exiting %s level %d\n", vm->name, vm->callLevel);
--vm->callLevel;
vm->programStack = stackOnEntry; vm->programStack = stackOnEntry;
return *(int *)opStack; return *(int *)opStack;