#include "vm_local.h"
Include dependency graph for vm.c:

Go to the source code of this file.
Defines | |
| #define | MAX_STACK 256 |
| #define | MAX_VM 3 |
| #define | STACK_MASK (MAX_STACK-1) |
| #define | STACK_SIZE 0x20000 |
Functions | |
| int | ParseHex (const char *text) |
| void * | VM_ArgPtr (int intValue) |
| int QDECL | VM_Call (vm_t *vm, int callnum,...) |
| void | VM_Clear (void) |
| vm_t * | VM_Create (const char *module, int(*systemCalls)(int *), vmInterpret_t interpret) |
| void | VM_Debug (int level) |
| int QDECL | VM_DllSyscall (int arg,...) |
| void * | VM_ExplicitArgPtr (vm_t *vm, int intValue) |
| void | VM_Free (vm_t *vm) |
| void | VM_Init (void) |
| void | VM_LoadSymbols (vm_t *vm) |
| void | VM_LogSyscalls (int *args) |
| int QDECL | VM_ProfileSort (const void *a, const void *b) |
| vm_t * | VM_Restart (vm_t *vm) |
| const char * | VM_SymbolForCompiledPointer (vm_t *vm, void *code) |
| int | VM_SymbolToValue (vm_t *vm, const char *symbol) |
| vmSymbol_t * | VM_ValueToFunctionSymbol (vm_t *vm, int value) |
| const char * | VM_ValueToSymbol (vm_t *vm, int value) |
| void * | VM_VM2C (vmptr_t p, int length) |
| void | VM_VmInfo_f (void) |
| void | VM_VmProfile_f (void) |
Variables | |
| vm_t * | currentVM = NULL |
| vm_t * | lastVM = NULL |
| int | vm_debugLevel |
| vm_t | vmTable [MAX_VM] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Definition at line 183 of file vm.c. 00183 {
00184 int value;
00185 int c;
00186
00187 value = 0;
00188 while ( ( c = *text++ ) != 0 ) {
00189 if ( c >= '0' && c <= '9' ) {
00190 value = value * 16 + c - '0';
00191 continue;
00192 }
00193 if ( c >= 'a' && c <= 'f' ) {
00194 value = value * 16 + 10 + c - 'a';
00195 continue;
00196 }
00197 if ( c >= 'A' && c <= 'F' ) {
00198 value = value * 16 + 10 + c - 'A';
00199 continue;
00200 }
00201 }
00202
00203 return value;
00204 }
|
|
|
Definition at line 607 of file vm.c. References currentVM, vm_s::dataBase, and vm_s::dataMask. 00607 {
00608 if ( !intValue ) {
00609 return NULL;
00610 }
00611 // bk001220 - currentVM is missing on reconnect
00612 if ( currentVM==NULL )
00613 return NULL;
00614
00615 if ( currentVM->entryPoint ) {
00616 return (void *)(currentVM->dataBase + intValue);
00617 }
00618 else {
00619 return (void *)(currentVM->dataBase + (intValue & currentVM->dataMask));
00620 }
00621 }
|
|
||||||||||||||||
|
Definition at line 668 of file vm.c. References Com_Error(), Com_Printf(), vm_s::compiled, currentVM, ERR_FATAL, i, lastVM, QDECL, r, va_arg, va_end, va_list, va_start, VM_CallCompiled(), VM_CallInterpreted(), and vm_t. Referenced by CIN_PlayCinematic(), CL_CGameRendering(), CL_CharEvent(), CL_Disconnect(), CL_Frame(), CL_GameCommand(), CL_InitCGame(), CL_InitUI(), CL_KeyEvent(), CL_MouseEvent(), CL_ShutdownCGame(), CL_ShutdownUI(), Con_MessageMode3_f(), Con_MessageMode4_f(), SCR_DrawScreenField(), SV_BotFrame(), SV_ClientEnterWorld(), SV_ClientThink(), SV_DirectConnect(), SV_DropClient(), SV_ExecuteClientCommand(), SV_Frame(), SV_GameCommand(), SV_InitGameVM(), SV_MapRestart_f(), SV_RestartGameProgs(), SV_ShutdownGameProgs(), SV_SpawnServer(), SV_UpdateUserinfo_f(), UI_GameCommand(), and UI_usesUniqueCDKey(). 00668 {
00669 vm_t *oldVM;
00670 int r;
00671 int i;
00672 int args[16];
00673 va_list ap;
00674
00675
00676 if ( !vm ) {
00677 Com_Error( ERR_FATAL, "VM_Call with NULL vm" );
00678 }
00679
00680 oldVM = currentVM;
00681 currentVM = vm;
00682 lastVM = vm;
00683
00684 if ( vm_debugLevel ) {
00685 Com_Printf( "VM_Call( %i )\n", callnum );
00686 }
00687
00688 // if we have a dll loaded, call it directly
00689 if ( vm->entryPoint ) {
00690 //rcg010207 - see dissertation at top of VM_DllSyscall() in this file.
00691 va_start(ap, callnum);
00692 for (i = 0; i < sizeof (args) / sizeof (args[i]); i++) {
00693 args[i] = va_arg(ap, int);
00694 }
00695 va_end(ap);
00696
00697 r = vm->entryPoint( callnum, args[0], args[1], args[2], args[3],
00698 args[4], args[5], args[6], args[7],
00699 args[8], args[9], args[10], args[11],
00700 args[12], args[13], args[14], args[15]);
00701 } else if ( vm->compiled ) {
00702 r = VM_CallCompiled( vm, &callnum );
00703 } else {
00704 r = VM_CallInterpreted( vm, &callnum );
00705 }
00706
00707 if ( oldVM != NULL ) // bk001220 - assert(currentVM!=NULL) for oldVM==NULL
00708 currentVM = oldVM;
00709 return r;
00710 }
|
Here is the call graph for this function:

|
|
Definition at line 595 of file vm.c. References Com_Memset(), currentVM, vm_s::dllHandle, i, lastVM, Sys_UnloadDll(), vm_t, and vmTable. Referenced by Hunk_Clear(). 00595 {
00596 int i;
00597 for (i=0;i<MAX_VM; i++) {
00598 if ( vmTable[i].dllHandle ) {
00599 Sys_UnloadDll( vmTable[i].dllHandle );
00600 }
00601 Com_Memset( &vmTable[i], 0, sizeof( vm_t ) );
00602 }
00603 currentVM = NULL;
00604 lastVM = NULL;
00605 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 435 of file vm.c. References byte, vm_s::codeLength, Com_Error(), Com_Memcpy(), Com_Printf(), Com_sprintf(), vm_s::compiled, Cvar_VariableValue(), vm_s::dataBase, vm_s::dataMask, vm_s::dllHandle, ERR_FATAL, vm_s::fqpath, FS_FreeFile(), FS_ReadFile(), h_high, header, Hunk_Alloc(), Hunk_MemoryRemaining(), i, vm_s::instructionPointers, vm_s::instructionPointersLength, length(), LittleLong(), vm_s::name, name, vm_s::programStack, Q_stricmp(), Q_strncpyz(), vm_s::stackBottom, Sys_LoadDll(), vm_s::systemCall, VM_Compile(), VM_DllSyscall(), VM_Free(), VM_LoadSymbols(), VM_MAGIC, VM_PrepareInterpreter(), vm_t, and vmTable. Referenced by CL_InitCGame(), CL_InitUI(), SV_InitGameProgs(), and VM_Restart(). 00436 {
00437 vm_t *vm;
00438 vmHeader_t *header;
00439 int length;
00440 int dataLength;
00441 int i, remaining;
00442 char filename[MAX_QPATH];
00443
00444 if ( !module || !module[0] || !systemCalls ) {
00445 Com_Error( ERR_FATAL, "VM_Create: bad parms" );
00446 }
00447
00448 remaining = Hunk_MemoryRemaining();
00449
00450 // see if we already have the VM
00451 for ( i = 0 ; i < MAX_VM ; i++ ) {
00452 if (!Q_stricmp(vmTable[i].name, module)) {
00453 vm = &vmTable[i];
00454 return vm;
00455 }
00456 }
00457
00458 // find a free vm
00459 for ( i = 0 ; i < MAX_VM ; i++ ) {
00460 if ( !vmTable[i].name[0] ) {
00461 break;
00462 }
00463 }
00464
00465 if ( i == MAX_VM ) {
00466 Com_Error( ERR_FATAL, "VM_Create: no free vm_t" );
00467 }
00468
00469 vm = &vmTable[i];
00470
00471 Q_strncpyz( vm->name, module, sizeof( vm->name ) );
00472 vm->systemCall = systemCalls;
00473
00474 // never allow dll loading with a demo
00475 if ( interpret == VMI_NATIVE ) {
00476 if ( Cvar_VariableValue( "fs_restrict" ) ) {
00477 interpret = VMI_COMPILED;
00478 }
00479 }
00480
00481 if ( interpret == VMI_NATIVE ) {
00482 // try to load as a system dll
00483 Com_Printf( "Loading dll file %s.\n", vm->name );
00484 vm->dllHandle = Sys_LoadDll( module, vm->fqpath , &vm->entryPoint, VM_DllSyscall );
00485 if ( vm->dllHandle ) {
00486 return vm;
00487 }
00488
00489 Com_Printf( "Failed to load dll, looking for qvm.\n" );
00490 interpret = VMI_COMPILED;
00491 }
00492
00493 // load the image
00494 Com_sprintf( filename, sizeof(filename), "vm/%s.qvm", vm->name );
00495 Com_Printf( "Loading vm file %s.\n", filename );
00496 length = FS_ReadFile( filename, (void **)&header );
00497 if ( !header ) {
00498 Com_Printf( "Failed.\n" );
00499 VM_Free( vm );
00500 return NULL;
00501 }
00502
00503 // byte swap the header
00504 for ( i = 0 ; i < sizeof( *header ) / 4 ; i++ ) {
00505 ((int *)header)[i] = LittleLong( ((int *)header)[i] );
00506 }
00507
00508 // validate
00509 if ( header->vmMagic != VM_MAGIC
00510 || header->bssLength < 0
00511 || header->dataLength < 0
00512 || header->litLength < 0
00513 || header->codeLength <= 0 ) {
00514 VM_Free( vm );
00515 Com_Error( ERR_FATAL, "%s has bad header", filename );
00516 }
00517
00518 // round up to next power of 2 so all data operations can
00519 // be mask protected
00520 dataLength = header->dataLength + header->litLength + header->bssLength;
00521 for ( i = 0 ; dataLength > ( 1 << i ) ; i++ ) {
00522 }
00523 dataLength = 1 << i;
00524
00525 // allocate zero filled space for initialized and uninitialized data
00526 vm->dataBase = Hunk_Alloc( dataLength, h_high );
00527 vm->dataMask = dataLength - 1;
00528
00529 // copy the intialized data
00530 Com_Memcpy( vm->dataBase, (byte *)header + header->dataOffset, header->dataLength + header->litLength );
00531
00532 // byte swap the longs
00533 for ( i = 0 ; i < header->dataLength ; i += 4 ) {
00534 *(int *)(vm->dataBase + i) = LittleLong( *(int *)(vm->dataBase + i ) );
00535 }
00536
00537 // allocate space for the jump targets, which will be filled in by the compile/prep functions
00538 vm->instructionPointersLength = header->instructionCount * 4;
00539 vm->instructionPointers = Hunk_Alloc( vm->instructionPointersLength, h_high );
00540
00541 // copy or compile the instructions
00542 vm->codeLength = header->codeLength;
00543
00544 if ( interpret >= VMI_COMPILED ) {
00545 vm->compiled = qtrue;
00546 VM_Compile( vm, header );
00547 } else {
00548 vm->compiled = qfalse;
00549 VM_PrepareInterpreter( vm, header );
00550 }
00551
00552 // free the original file
00553 FS_FreeFile( header );
00554
00555 // load the map file
00556 VM_LoadSymbols( vm );
00557
00558 // the stack is implicitly at the end of the image
00559 vm->programStack = vm->dataMask + 1;
00560 vm->stackBottom = vm->programStack - STACK_SIZE;
00561
00562 Com_Printf("%s loaded in %d bytes on the hunk\n", module, remaining - Hunk_MemoryRemaining());
00563
00564 return vm;
00565 }
|
Here is the call graph for this function:

|
|
Definition at line 57 of file vm.c. References vm_debugLevel. Referenced by CL_CGameRendering(), and VM_CallInterpreted(). 00057 {
00058 vm_debugLevel = level;
00059 }
|
|
||||||||||||
|
Definition at line 327 of file vm.c. References currentVM, i, QDECL, vm_s::systemCall, va_arg, va_end, va_list, and va_start. Referenced by VM_Create(). 00327 {
00328 #if ((defined __linux__) && (defined __powerpc__))
00329 // rcg010206 - see commentary above
00330 int args[16];
00331 int i;
00332 va_list ap;
00333
00334 args[0] = arg;
00335
00336 va_start(ap, arg);
00337 for (i = 1; i < sizeof (args) / sizeof (args[i]); i++)
00338 args[i] = va_arg(ap, int);
00339 va_end(ap);
00340
00341 return currentVM->systemCall( args );
00342 #else // original id code
00343 return currentVM->systemCall( &arg );
00344 #endif
00345 }
|
|
||||||||||||
|
Definition at line 623 of file vm.c. References currentVM, vm_s::dataBase, vm_s::dataMask, and vm_t. Referenced by SV_DirectConnect(), SV_MapRestart_f(), and SV_SpawnServer(). 00623 {
00624 if ( !intValue ) {
00625 return NULL;
00626 }
00627
00628 // bk010124 - currentVM is missing on reconnect here as well?
00629 if ( currentVM==NULL )
00630 return NULL;
00631
00632 //
00633 if ( vm->entryPoint ) {
00634 return (void *)(vm->dataBase + intValue);
00635 }
00636 else {
00637 return (void *)(vm->dataBase + (intValue & vm->dataMask));
00638 }
00639 }
|
|
|
Definition at line 572 of file vm.c. References vm_s::codeBase, Com_Memset(), currentVM, vm_s::dataBase, vm_s::dllHandle, vm_s::instructionPointers, lastVM, Sys_UnloadDll(), vm_t, and Z_Free(). Referenced by CL_ShutdownCGame(), CL_ShutdownUI(), SV_ShutdownGameProgs(), VM_Create(), and VM_Restart(). 00572 {
00573
00574 if ( vm->dllHandle ) {
00575 Sys_UnloadDll( vm->dllHandle );
00576 Com_Memset( vm, 0, sizeof( *vm ) );
00577 }
00578 #if 0 // now automatically freed by hunk
00579 if ( vm->codeBase ) {
00580 Z_Free( vm->codeBase );
00581 }
00582 if ( vm->dataBase ) {
00583 Z_Free( vm->dataBase );
00584 }
00585 if ( vm->instructionPointers ) {
00586 Z_Free( vm->instructionPointers );
00587 }
00588 #endif
00589 Com_Memset( vm, 0, sizeof( *vm ) );
00590
00591 currentVM = NULL;
00592 lastVM = NULL;
00593 }
|
Here is the call graph for this function:

|
|
Definition at line 66 of file vm.c. References Cmd_AddCommand(), Com_Memset(), CVAR_ARCHIVE, Cvar_Get(), VM_VmInfo_f(), VM_VmProfile_f(), and vmTable. Referenced by Com_Init(). 00066 {
00067 Cvar_Get( "vm_cgame", "2", CVAR_ARCHIVE ); // !@# SHIP WITH SET TO 2
00068 Cvar_Get( "vm_game", "2", CVAR_ARCHIVE ); // !@# SHIP WITH SET TO 2
00069 Cvar_Get( "vm_ui", "2", CVAR_ARCHIVE ); // !@# SHIP WITH SET TO 2
00070
00071 Cmd_AddCommand ("vmprofile", VM_VmProfile_f );
00072 Cmd_AddCommand ("vminfo", VM_VmInfo_f );
00073
00074 Com_Memset( vmTable, 0, sizeof( vmTable ) );
00075 }
|
Here is the call graph for this function:

|
|
Definition at line 211 of file vm.c. References com_developer, COM_Parse(), Com_Printf(), Com_sprintf(), COM_StripExtension(), count, FS_FreeFile(), FS_ReadFile(), h_high, Hunk_Alloc(), vm_s::instructionPointers, vm_s::instructionPointersLength, cvar_s::integer, vm_s::name, name, vmSymbol_s::next, vm_s::numSymbols, ParseHex(), Q_strncpyz(), segment, strlen(), vm_s::symbols, symbols, token, value, vm_t, and vmSymbol_t. Referenced by VM_Create(). 00211 {
00212 int len;
00213 char *mapfile, *text_p, *token;
00214 char name[MAX_QPATH];
00215 char symbols[MAX_QPATH];
00216 vmSymbol_t **prev, *sym;
00217 int count;
00218 int value;
00219 int chars;
00220 int segment;
00221 int numInstructions;
00222
00223 // don't load symbols if not developer
00224 if ( !com_developer->integer ) {
00225 return;
00226 }
00227
00228 COM_StripExtension( vm->name, name );
00229 Com_sprintf( symbols, sizeof( symbols ), "vm/%s.map", name );
00230 len = FS_ReadFile( symbols, (void **)&mapfile );
00231 if ( !mapfile ) {
00232 Com_Printf( "Couldn't load symbol file: %s\n", symbols );
00233 return;
00234 }
00235
00236 numInstructions = vm->instructionPointersLength >> 2;
00237
00238 // parse the symbols
00239 text_p = mapfile;
00240 prev = &vm->symbols;
00241 count = 0;
00242
00243 while ( 1 ) {
00244 token = COM_Parse( &text_p );
00245 if ( !token[0] ) {
00246 break;
00247 }
00248 segment = ParseHex( token );
00249 if ( segment ) {
00250 COM_Parse( &text_p );
00251 COM_Parse( &text_p );
00252 continue; // only load code segment values
00253 }
00254
00255 token = COM_Parse( &text_p );
00256 if ( !token[0] ) {
00257 Com_Printf( "WARNING: incomplete line at end of file\n" );
00258 break;
00259 }
00260 value = ParseHex( token );
00261
00262 token = COM_Parse( &text_p );
00263 if ( !token[0] ) {
00264 Com_Printf( "WARNING: incomplete line at end of file\n" );
00265 break;
00266 }
00267 chars = strlen( token );
00268 sym = Hunk_Alloc( sizeof( *sym ) + chars, h_high );
00269 *prev = sym;
00270 prev = &sym->next;
00271 sym->next = NULL;
00272
00273 // convert value from an instruction number to a code offset
00274 if ( value >= 0 && value < numInstructions ) {
00275 value = vm->instructionPointers[value];
00276 }
00277
00278 sym->symValue = value;
00279 Q_strncpyz( sym->symName, token, chars + 1 );
00280
00281 count++;
00282 }
00283
00284 vm->numSymbols = count;
00285 Com_Printf( "%i symbols parsed from %s\n", count, symbols );
00286 FS_FreeFile( mapfile );
00287 }
|
Here is the call graph for this function:

|
|
Definition at line 815 of file vm.c. References currentVM, vm_s::dataBase, f, fopen(), and fprintf(). 00815 {
00816 static int callnum;
00817 static FILE *f;
00818
00819 if ( !f ) {
00820 f = fopen("syscalls.log", "w" );
00821 }
00822 callnum++;
00823 fprintf(f, "%i: %i (%i) = %i %i %i %i\n", callnum, args - (int *)currentVM->dataBase,
00824 args[0], args[1], args[2], args[3], args[4] );
00825 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 714 of file vm.c. References vmSymbol_s::profileCount, QDECL, and vmSymbol_t. Referenced by VM_VmProfile_f(). 00714 {
00715 vmSymbol_t *sa, *sb;
00716
00717 sa = *(vmSymbol_t **)a;
00718 sb = *(vmSymbol_t **)b;
00719
00720 if ( sa->profileCount < sb->profileCount ) {
00721 return -1;
00722 }
00723 if ( sa->profileCount > sb->profileCount ) {
00724 return 1;
00725 }
00726 return 0;
00727 }
|
|
|
Definition at line 355 of file vm.c. References byte, Com_Error(), Com_Memcpy(), Com_Memset(), Com_Printf(), Com_sprintf(), vm_s::dataBase, vm_s::dllHandle, ERR_DROP, ERR_FATAL, FS_FreeFile(), FS_ReadFile(), header, i, int(), length(), LittleLong(), vm_s::name, name, Q_strncpyz(), vm_s::systemCall, VM_Create(), VM_Free(), VM_MAGIC, vm_t, and VMI_NATIVE. Referenced by SV_RestartGameProgs(). 00355 {
00356 vmHeader_t *header;
00357 int length;
00358 int dataLength;
00359 int i;
00360 char filename[MAX_QPATH];
00361
00362 // DLL's can't be restarted in place
00363 if ( vm->dllHandle ) {
00364 char name[MAX_QPATH];
00365 int (*systemCall)( int *parms );
00366
00367 systemCall = vm->systemCall;
00368 Q_strncpyz( name, vm->name, sizeof( name ) );
00369
00370 VM_Free( vm );
00371
00372 vm = VM_Create( name, systemCall, VMI_NATIVE );
00373 return vm;
00374 }
00375
00376 // load the image
00377 Com_Printf( "VM_Restart()\n", filename );
00378 Com_sprintf( filename, sizeof(filename), "vm/%s.qvm", vm->name );
00379 Com_Printf( "Loading vm file %s.\n", filename );
00380 length = FS_ReadFile( filename, (void **)&header );
00381 if ( !header ) {
00382 Com_Error( ERR_DROP, "VM_Restart failed.\n" );
00383 }
00384
00385 // byte swap the header
00386 for ( i = 0 ; i < sizeof( *header ) / 4 ; i++ ) {
00387 ((int *)header)[i] = LittleLong( ((int *)header)[i] );
00388 }
00389
00390 // validate
00391 if ( header->vmMagic != VM_MAGIC
00392 || header->bssLength < 0
00393 || header->dataLength < 0
00394 || header->litLength < 0
00395 || header->codeLength <= 0 ) {
00396 VM_Free( vm );
00397 Com_Error( ERR_FATAL, "%s has bad header", filename );
00398 }
00399
00400 // round up to next power of 2 so all data operations can
00401 // be mask protected
00402 dataLength = header->dataLength + header->litLength + header->bssLength;
00403 for ( i = 0 ; dataLength > ( 1 << i ) ; i++ ) {
00404 }
00405 dataLength = 1 << i;
00406
00407 // clear the data
00408 Com_Memset( vm->dataBase, 0, dataLength );
00409
00410 // copy the intialized data
00411 Com_Memcpy( vm->dataBase, (byte *)header + header->dataOffset, header->dataLength + header->litLength );
00412
00413 // byte swap the longs
00414 for ( i = 0 ; i < header->dataLength ; i += 4 ) {
00415 *(int *)(vm->dataBase + i) = LittleLong( *(int *)(vm->dataBase + i ) );
00416 }
00417
00418 // free the original file
00419 FS_FreeFile( header );
00420
00421 return vm;
00422 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 154 of file vm.c. References code, vm_s::codeBase, vm_s::codeLength, i, vm_s::instructionPointers, vm_t, and VM_ValueToSymbol(). 00154 {
00155 int i;
00156
00157 if ( code < (void *)vm->codeBase ) {
00158 return "Before code block";
00159 }
00160 if ( code >= (void *)(vm->codeBase + vm->codeLength) ) {
00161 return "After code block";
00162 }
00163
00164 // find which original instruction it is after
00165 for ( i = 0 ; i < vm->codeLength ; i++ ) {
00166 if ( (void *)vm->instructionPointers[i] > code ) {
00167 break;
00168 }
00169 }
00170 i--;
00171
00172 // now look up the bytecode instruction pointer
00173 return VM_ValueToSymbol( vm, i );
00174 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 137 of file vm.c. References vmSymbol_s::next, strcmp(), vm_s::symbols, vmSymbol_s::symName, vmSymbol_s::symValue, vm_t, and vmSymbol_t. 00137 {
00138 vmSymbol_t *sym;
00139
00140 for ( sym = vm->symbols ; sym ; sym = sym->next ) {
00141 if ( !strcmp( symbol, sym->symName ) ) {
00142 return sym->symValue;
00143 }
00144 }
00145 return 0;
00146 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 115 of file vm.c. References vmSymbol_s::next, vm_s::symbols, vmSymbol_s::symValue, vm_t, and vmSymbol_t. Referenced by VM_CallInterpreted(). 00115 {
00116 vmSymbol_t *sym;
00117 static vmSymbol_t nullSym;
00118
00119 sym = vm->symbols;
00120 if ( !sym ) {
00121 return &nullSym;
00122 }
00123
00124 while ( sym->next && sym->next->symValue <= value ) {
00125 sym = sym->next;
00126 }
00127
00128 return sym;
00129 }
|
|
||||||||||||
|
Definition at line 85 of file vm.c. References Com_sprintf(), vmSymbol_s::next, vm_s::symbols, vmSymbol_s::symName, vmSymbol_s::symValue, value, vm_t, and vmSymbol_t. Referenced by VM_CallInterpreted(), VM_StackTrace(), and VM_SymbolForCompiledPointer(). 00085 {
00086 vmSymbol_t *sym;
00087 static char text[MAX_TOKEN_CHARS];
00088
00089 sym = vm->symbols;
00090 if ( !sym ) {
00091 return "NO SYMBOLS";
00092 }
00093
00094 // find the symbol
00095 while ( sym->next && sym->next->symValue <= value ) {
00096 sym = sym->next;
00097 }
00098
00099 if ( value == sym->symValue ) {
00100 return sym->symName;
00101 }
00102
00103 Com_sprintf( text, sizeof( text ), "%s+%i", sym->symName, value - sym->symValue );
00104
00105 return text;
00106 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 53 of file vm.c. 00053 {
00054 return (void *)p;
00055 }
|
|
|
Definition at line 782 of file vm.c. References vm_s::codeLength, Com_Printf(), vm_s::compiled, vm_s::dataMask, vm_s::dllHandle, i, vm_s::instructionPointersLength, vm_s::name, vm_t, and vmTable. Referenced by VM_Init(). 00782 {
00783 vm_t *vm;
00784 int i;
00785
00786 Com_Printf( "Registered virtual machines:\n" );
00787 for ( i = 0 ; i < MAX_VM ; i++ ) {
00788 vm = &vmTable[i];
00789 if ( !vm->name[0] ) {
00790 break;
00791 }
00792 Com_Printf( "%s : ", vm->name );
00793 if ( vm->dllHandle ) {
00794 Com_Printf( "native\n" );
00795 continue;
00796 }
00797 if ( vm->compiled ) {
00798 Com_Printf( "compiled on load\n" );
00799 } else {
00800 Com_Printf( "interpreted\n" );
00801 }
00802 Com_Printf( " code length : %7i\n", vm->codeLength );
00803 Com_Printf( " table length: %7i\n", vm->instructionPointersLength );
00804 Com_Printf( " data length : %7i\n", vm->dataMask + 1 );
00805 }
00806 }
|
Here is the call graph for this function:

|
|
Definition at line 735 of file vm.c. References Com_Printf(), i, vmSymbol_s::next, vm_s::numSymbols, vmSymbol_s::profileCount, qsort(), vm_s::symbols, vmSymbol_s::symName, VM_ProfileSort(), vm_t, vmSymbol_t, Z_Free(), and Z_Malloc(). Referenced by VM_Init(). 00735 {
00736 vm_t *vm;
00737 vmSymbol_t **sorted, *sym;
00738 int i;
00739 double total;
00740
00741 if ( !lastVM ) {
00742 return;
00743 }
00744
00745 vm = lastVM;
00746
00747 if ( !vm->numSymbols ) {
00748 return;
00749 }
00750
00751 sorted = Z_Malloc( vm->numSymbols * sizeof( *sorted ) );
00752 sorted[0] = vm->symbols;
00753 total = sorted[0]->profileCount;
00754 for ( i = 1 ; i < vm->numSymbols ; i++ ) {
00755 sorted[i] = sorted[i-1]->next;
00756 total += sorted[i]->profileCount;
00757 }
00758
00759 qsort( sorted, vm->numSymbols, sizeof( *sorted ), VM_ProfileSort );
00760
00761 for ( i = 0 ; i < vm->numSymbols ; i++ ) {
00762 int perc;
00763
00764 sym = sorted[i];
00765
00766 perc = 100 * (float) sym->profileCount / total;
00767 Com_Printf( "%2i%% %9i %s\n", perc, sym->profileCount, sym->symName );
00768 sym->profileCount = 0;
00769 }
00770
00771 Com_Printf(" %9.0f total\n", total );
00772
00773 Z_Free( sorted );
00774 }
|
Here is the call graph for this function:

|
|
Definition at line 39 of file vm.c. Referenced by callAsmCall(), VM_ArgPtr(), VM_Call(), VM_CallCompiled(), VM_Clear(), VM_DllSyscall(), VM_ExplicitArgPtr(), VM_Free(), and VM_LogSyscalls(). |
|
|
Definition at line 40 of file vm.c. Referenced by VM_Call(), VM_Clear(), and VM_Free(). |
|
|
Definition at line 41 of file vm.c. Referenced by VM_CallInterpreted(), and VM_Debug(). |
|
|
Definition at line 44 of file vm.c. Referenced by VM_Clear(), VM_Create(), VM_Init(), and VM_VmInfo_f(). |
1.3.9.1