Annotation of quake1/pr_exec.c, revision 1.1.1.1

1.1       root        1: 
                      2: #include "quakedef.h"
                      3: 
                      4: 
                      5: /*
                      6: 
                      7: */
                      8: 
                      9: typedef struct
                     10: {
                     11:        int                             s;
                     12:        dfunction_t             *f;
                     13: } prstack_t;
                     14: 
                     15: #define        MAX_STACK_DEPTH         32
                     16: prstack_t      pr_stack[MAX_STACK_DEPTH];
                     17: int                    pr_depth;
                     18: 
                     19: #define        LOCALSTACK_SIZE         2048
                     20: int                    localstack[LOCALSTACK_SIZE];
                     21: int                    localstack_used;
                     22: 
                     23: 
                     24: qboolean       pr_trace;
                     25: dfunction_t    *pr_xfunction;
                     26: int                    pr_xstatement;
                     27: 
                     28: 
                     29: int            pr_argc;
                     30: 
                     31: char *pr_opnames[] =
                     32: {
                     33: "DONE",
                     34: 
                     35: "MUL_F",
                     36: "MUL_V", 
                     37: "MUL_FV",
                     38: "MUL_VF",
                     39:  
                     40: "DIV",
                     41: 
                     42: "ADD_F",
                     43: "ADD_V", 
                     44:   
                     45: "SUB_F",
                     46: "SUB_V",
                     47: 
                     48: "EQ_F",
                     49: "EQ_V",
                     50: "EQ_S", 
                     51: "EQ_E",
                     52: "EQ_FNC",
                     53:  
                     54: "NE_F",
                     55: "NE_V", 
                     56: "NE_S",
                     57: "NE_E", 
                     58: "NE_FNC",
                     59:  
                     60: "LE",
                     61: "GE",
                     62: "LT",
                     63: "GT", 
                     64: 
                     65: "INDIRECT",
                     66: "INDIRECT",
                     67: "INDIRECT", 
                     68: "INDIRECT", 
                     69: "INDIRECT",
                     70: "INDIRECT", 
                     71: 
                     72: "ADDRESS", 
                     73: 
                     74: "STORE_F",
                     75: "STORE_V",
                     76: "STORE_S",
                     77: "STORE_ENT",
                     78: "STORE_FLD",
                     79: "STORE_FNC",
                     80: 
                     81: "STOREP_F",
                     82: "STOREP_V",
                     83: "STOREP_S",
                     84: "STOREP_ENT",
                     85: "STOREP_FLD",
                     86: "STOREP_FNC",
                     87: 
                     88: "RETURN",
                     89:   
                     90: "NOT_F",
                     91: "NOT_V",
                     92: "NOT_S", 
                     93: "NOT_ENT", 
                     94: "NOT_FNC", 
                     95:   
                     96: "IF",
                     97: "IFNOT",
                     98:   
                     99: "CALL0",
                    100: "CALL1",
                    101: "CALL2",
                    102: "CALL3",
                    103: "CALL4",
                    104: "CALL5",
                    105: "CALL6",
                    106: "CALL7",
                    107: "CALL8",
                    108:   
                    109: "STATE",
                    110:   
                    111: "GOTO", 
                    112:   
                    113: "AND",
                    114: "OR", 
                    115: 
                    116: "BITAND",
                    117: "BITOR"
                    118: };
                    119: 
                    120: char *PR_GlobalString (int ofs);
                    121: char *PR_GlobalStringNoContents (int ofs);
                    122: 
                    123: 
                    124: //=============================================================================
                    125: 
                    126: /*
                    127: =================
                    128: PR_PrintStatement
                    129: =================
                    130: */
                    131: void PR_PrintStatement (dstatement_t *s)
                    132: {
                    133:        int             i;
                    134:        
                    135:        if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0]))
                    136:        {
                    137:                Con_Printf ("%s ",  pr_opnames[s->op]);
                    138:                i = strlen(pr_opnames[s->op]);
                    139:                for ( ; i<10 ; i++)
                    140:                        Con_Printf (" ");
                    141:        }
                    142:                
                    143:        if (s->op == OP_IF || s->op == OP_IFNOT)
                    144:                Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
                    145:        else if (s->op == OP_GOTO)
                    146:        {
                    147:                Con_Printf ("branch %i",s->a);
                    148:        }
                    149:        else if ( (unsigned)(s->op - OP_STORE_F) < 6)
                    150:        {
                    151:                Con_Printf ("%s",PR_GlobalString(s->a));
                    152:                Con_Printf ("%s", PR_GlobalStringNoContents(s->b));
                    153:        }
                    154:        else
                    155:        {
                    156:                if (s->a)
                    157:                        Con_Printf ("%s",PR_GlobalString(s->a));
                    158:                if (s->b)
                    159:                        Con_Printf ("%s",PR_GlobalString(s->b));
                    160:                if (s->c)
                    161:                        Con_Printf ("%s", PR_GlobalStringNoContents(s->c));
                    162:        }
                    163:        Con_Printf ("\n");
                    164: }
                    165: 
                    166: /*
                    167: ============
                    168: PR_StackTrace
                    169: ============
                    170: */
                    171: void PR_StackTrace (void)
                    172: {
                    173:        dfunction_t     *f;
                    174:        int                     i;
                    175:        
                    176:        if (pr_depth == 0)
                    177:        {
                    178:                Con_Printf ("<NO STACK>\n");
                    179:                return;
                    180:        }
                    181:        
                    182:        pr_stack[pr_depth].f = pr_xfunction;
                    183:        for (i=pr_depth ; i>=0 ; i--)
                    184:        {
                    185:                f = pr_stack[i].f;
                    186:                
                    187:                if (!f)
                    188:                {
                    189:                        Con_Printf ("<NO FUNCTION>\n");
                    190:                }
                    191:                else
                    192:                        Con_Printf ("%12s : %s\n", pr_strings + f->s_file, pr_strings + f->s_name);             
                    193:        }
                    194: }
                    195: 
                    196: 
                    197: /*
                    198: ============
                    199: PR_Profile_f
                    200: 
                    201: ============
                    202: */
                    203: void PR_Profile_f (void)
                    204: {
                    205:        dfunction_t     *f, *best;
                    206:        int                     max;
                    207:        int                     num;
                    208:        int                     i;
                    209:        
                    210:        num = 0;        
                    211:        do
                    212:        {
                    213:                max = 0;
                    214:                best = NULL;
                    215:                for (i=0 ; i<progs->numfunctions ; i++)
                    216:                {
                    217:                        f = &pr_functions[i];
                    218:                        if (f->profile > max)
                    219:                        {
                    220:                                max = f->profile;
                    221:                                best = f;
                    222:                        }
                    223:                }
                    224:                if (best)
                    225:                {
                    226:                        if (num < 10)
                    227:                                Con_Printf ("%7i %s\n", best->profile, pr_strings+best->s_name);
                    228:                        num++;
                    229:                        best->profile = 0;
                    230:                }
                    231:        } while (best);
                    232: }
                    233: 
                    234: 
                    235: /*
                    236: ============
                    237: PR_RunError
                    238: 
                    239: Aborts the currently executing function
                    240: ============
                    241: */
                    242: void PR_RunError (char *error, ...)
                    243: {
                    244:        va_list         argptr;
                    245:        char            string[1024];
                    246: 
                    247:        va_start (argptr,error);
                    248:        vsprintf (string,error,argptr);
                    249:        va_end (argptr);
                    250: 
                    251:        PR_PrintStatement (pr_statements + pr_xstatement);
                    252:        PR_StackTrace ();
                    253:        Con_Printf ("%s\n", string);
                    254:        
                    255:        pr_depth = 0;           // dump the stack so host_error can shutdown functions
                    256: 
                    257:        Host_Error ("Program error");
                    258: }
                    259: 
                    260: /*
                    261: ============================================================================
                    262: PR_ExecuteProgram
                    263: 
                    264: The interpretation main loop
                    265: ============================================================================
                    266: */
                    267: 
                    268: /*
                    269: ====================
                    270: PR_EnterFunction
                    271: 
                    272: Returns the new program statement counter
                    273: ====================
                    274: */
                    275: int PR_EnterFunction (dfunction_t *f)
                    276: {
                    277:        int             i, j, c, o;
                    278: 
                    279:        pr_stack[pr_depth].s = pr_xstatement;
                    280:        pr_stack[pr_depth].f = pr_xfunction;    
                    281:        pr_depth++;
                    282:        if (pr_depth >= MAX_STACK_DEPTH)
                    283:                PR_RunError ("stack overflow");
                    284: 
                    285: // save off any locals that the new function steps on
                    286:        c = f->locals;
                    287:        if (localstack_used + c > LOCALSTACK_SIZE)
                    288:                PR_RunError ("PR_ExecuteProgram: locals stack overflow\n");
                    289: 
                    290:        for (i=0 ; i < c ; i++)
                    291:                localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
                    292:        localstack_used += c;
                    293: 
                    294: // copy parameters
                    295:        o = f->parm_start;
                    296:        for (i=0 ; i<f->numparms ; i++)
                    297:        {
                    298:                for (j=0 ; j<f->parm_size[i] ; j++)
                    299:                {
                    300:                        ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];
                    301:                        o++;
                    302:                }
                    303:        }
                    304: 
                    305:        pr_xfunction = f;
                    306:        return f->first_statement - 1;  // offset the s++
                    307: }
                    308: 
                    309: /*
                    310: ====================
                    311: PR_LeaveFunction
                    312: ====================
                    313: */
                    314: int PR_LeaveFunction (void)
                    315: {
                    316:        int             i, c;
                    317: 
                    318:        if (pr_depth <= 0)
                    319:                Sys_Error ("prog stack underflow");
                    320: 
                    321: // restore locals from the stack
                    322:        c = pr_xfunction->locals;
                    323:        localstack_used -= c;
                    324:        if (localstack_used < 0)
                    325:                PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");
                    326: 
                    327:        for (i=0 ; i < c ; i++)
                    328:                ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
                    329: 
                    330: // up stack
                    331:        pr_depth--;
                    332:        pr_xfunction = pr_stack[pr_depth].f;
                    333:        return pr_stack[pr_depth].s;
                    334: }
                    335: 
                    336: 
                    337: /*
                    338: ====================
                    339: PR_ExecuteProgram
                    340: ====================
                    341: */
                    342: void PR_ExecuteProgram (func_t fnum)
                    343: {
                    344:        eval_t  *a, *b, *c;
                    345:        int                     s;
                    346:        dstatement_t    *st;
                    347:        dfunction_t     *f, *newf;
                    348:        int             runaway;
                    349:        int             i;
                    350:        edict_t *ed;
                    351:        int             exitdepth;
                    352:        eval_t  *ptr;
                    353: 
                    354:        if (!fnum || fnum >= progs->numfunctions)
                    355:        {
                    356:                if (pr_global_struct->self)
                    357:                        ED_Print (PROG_TO_EDICT(pr_global_struct->self));
                    358:                Host_Error ("PR_ExecuteProgram: NULL function");
                    359:        }
                    360:        
                    361:        f = &pr_functions[fnum];
                    362: 
                    363:        runaway = 100000;
                    364:        pr_trace = false;
                    365: 
                    366: // make a stack frame
                    367:        exitdepth = pr_depth;
                    368: 
                    369:        s = PR_EnterFunction (f);
                    370:        
                    371: while (1)
                    372: {
                    373:        s++;    // next statement
                    374: 
                    375:        st = &pr_statements[s];
                    376:        a = (eval_t *)&pr_globals[st->a];
                    377:        b = (eval_t *)&pr_globals[st->b];
                    378:        c = (eval_t *)&pr_globals[st->c];
                    379:        
                    380:        if (!--runaway)
                    381:                PR_RunError ("runaway loop error");
                    382:                
                    383:        pr_xfunction->profile++;
                    384:        pr_xstatement = s;
                    385:        
                    386:        if (pr_trace)
                    387:                PR_PrintStatement (st);
                    388:                
                    389:        switch (st->op)
                    390:        {
                    391:        case OP_ADD_F:
                    392:                c->_float = a->_float + b->_float;
                    393:                break;
                    394:        case OP_ADD_V:
                    395:                c->vector[0] = a->vector[0] + b->vector[0];
                    396:                c->vector[1] = a->vector[1] + b->vector[1];
                    397:                c->vector[2] = a->vector[2] + b->vector[2];
                    398:                break;
                    399:                
                    400:        case OP_SUB_F:
                    401:                c->_float = a->_float - b->_float;
                    402:                break;
                    403:        case OP_SUB_V:
                    404:                c->vector[0] = a->vector[0] - b->vector[0];
                    405:                c->vector[1] = a->vector[1] - b->vector[1];
                    406:                c->vector[2] = a->vector[2] - b->vector[2];
                    407:                break;
                    408: 
                    409:        case OP_MUL_F:
                    410:                c->_float = a->_float * b->_float;
                    411:                break;
                    412:        case OP_MUL_V:
                    413:                c->_float = a->vector[0]*b->vector[0]
                    414:                                + a->vector[1]*b->vector[1]
                    415:                                + a->vector[2]*b->vector[2];
                    416:                break;
                    417:        case OP_MUL_FV:
                    418:                c->vector[0] = a->_float * b->vector[0];
                    419:                c->vector[1] = a->_float * b->vector[1];
                    420:                c->vector[2] = a->_float * b->vector[2];
                    421:                break;
                    422:        case OP_MUL_VF:
                    423:                c->vector[0] = b->_float * a->vector[0];
                    424:                c->vector[1] = b->_float * a->vector[1];
                    425:                c->vector[2] = b->_float * a->vector[2];
                    426:                break;
                    427: 
                    428:        case OP_DIV_F:
                    429:                c->_float = a->_float / b->_float;
                    430:                break;
                    431:        
                    432:        case OP_BITAND:
                    433:                c->_float = (int)a->_float & (int)b->_float;
                    434:                break;
                    435:        
                    436:        case OP_BITOR:
                    437:                c->_float = (int)a->_float | (int)b->_float;
                    438:                break;
                    439:        
                    440:                
                    441:        case OP_GE:
                    442:                c->_float = a->_float >= b->_float;
                    443:                break;
                    444:        case OP_LE:
                    445:                c->_float = a->_float <= b->_float;
                    446:                break;
                    447:        case OP_GT:
                    448:                c->_float = a->_float > b->_float;
                    449:                break;
                    450:        case OP_LT:
                    451:                c->_float = a->_float < b->_float;
                    452:                break;
                    453:        case OP_AND:
                    454:                c->_float = a->_float && b->_float;
                    455:                break;
                    456:        case OP_OR:
                    457:                c->_float = a->_float || b->_float;
                    458:                break;
                    459:                
                    460:        case OP_NOT_F:
                    461:                c->_float = !a->_float;
                    462:                break;
                    463:        case OP_NOT_V:
                    464:                c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];
                    465:                break;
                    466:        case OP_NOT_S:
                    467:                c->_float = !a->string || !pr_strings[a->string];
                    468:                break;
                    469:        case OP_NOT_FNC:
                    470:                c->_float = !a->function;
                    471:                break;
                    472:        case OP_NOT_ENT:
                    473:                c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts);
                    474:                break;
                    475: 
                    476:        case OP_EQ_F:
                    477:                c->_float = a->_float == b->_float;
                    478:                break;
                    479:        case OP_EQ_V:
                    480:                c->_float = (a->vector[0] == b->vector[0]) &&
                    481:                                        (a->vector[1] == b->vector[1]) &&
                    482:                                        (a->vector[2] == b->vector[2]);
                    483:                break;
                    484:        case OP_EQ_S:
                    485:                c->_float = !strcmp(pr_strings+a->string,pr_strings+b->string);
                    486:                break;
                    487:        case OP_EQ_E:
                    488:                c->_float = a->_int == b->_int;
                    489:                break;
                    490:        case OP_EQ_FNC:
                    491:                c->_float = a->function == b->function;
                    492:                break;
                    493: 
                    494: 
                    495:        case OP_NE_F:
                    496:                c->_float = a->_float != b->_float;
                    497:                break;
                    498:        case OP_NE_V:
                    499:                c->_float = (a->vector[0] != b->vector[0]) ||
                    500:                                        (a->vector[1] != b->vector[1]) ||
                    501:                                        (a->vector[2] != b->vector[2]);
                    502:                break;
                    503:        case OP_NE_S:
                    504:                c->_float = strcmp(pr_strings+a->string,pr_strings+b->string);
                    505:                break;
                    506:        case OP_NE_E:
                    507:                c->_float = a->_int != b->_int;
                    508:                break;
                    509:        case OP_NE_FNC:
                    510:                c->_float = a->function != b->function;
                    511:                break;
                    512: 
                    513: //==================
                    514:        case OP_STORE_F:
                    515:        case OP_STORE_ENT:
                    516:        case OP_STORE_FLD:              // integers
                    517:        case OP_STORE_S:
                    518:        case OP_STORE_FNC:              // pointers
                    519:                b->_int = a->_int;
                    520:                break;
                    521:        case OP_STORE_V:
                    522:                b->vector[0] = a->vector[0];
                    523:                b->vector[1] = a->vector[1];
                    524:                b->vector[2] = a->vector[2];
                    525:                break;
                    526:                
                    527:        case OP_STOREP_F:
                    528:        case OP_STOREP_ENT:
                    529:        case OP_STOREP_FLD:             // integers
                    530:        case OP_STOREP_S:
                    531:        case OP_STOREP_FNC:             // pointers
                    532:                ptr = (eval_t *)((byte *)sv.edicts + b->_int);
                    533:                ptr->_int = a->_int;
                    534:                break;
                    535:        case OP_STOREP_V:
                    536:                ptr = (eval_t *)((byte *)sv.edicts + b->_int);
                    537:                ptr->vector[0] = a->vector[0];
                    538:                ptr->vector[1] = a->vector[1];
                    539:                ptr->vector[2] = a->vector[2];
                    540:                break;
                    541:                
                    542:        case OP_ADDRESS:
                    543:                ed = PROG_TO_EDICT(a->edict);
                    544: #ifdef PARANOID
                    545:                NUM_FOR_EDICT(ed);              // make sure it's in range
                    546: #endif
                    547:                if (ed == (edict_t *)sv.edicts && sv.state == ss_active)
                    548:                        PR_RunError ("assignment to world entity");
                    549:                c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
                    550:                break;
                    551:                
                    552:        case OP_LOAD_F:
                    553:        case OP_LOAD_FLD:
                    554:        case OP_LOAD_ENT:
                    555:        case OP_LOAD_S:
                    556:        case OP_LOAD_FNC:
                    557:                ed = PROG_TO_EDICT(a->edict);
                    558: #ifdef PARANOID
                    559:                NUM_FOR_EDICT(ed);              // make sure it's in range
                    560: #endif
                    561:                a = (eval_t *)((int *)&ed->v + b->_int);
                    562:                c->_int = a->_int;
                    563:                break;
                    564: 
                    565:        case OP_LOAD_V:
                    566:                ed = PROG_TO_EDICT(a->edict);
                    567: #ifdef PARANOID
                    568:                NUM_FOR_EDICT(ed);              // make sure it's in range
                    569: #endif
                    570:                a = (eval_t *)((int *)&ed->v + b->_int);
                    571:                c->vector[0] = a->vector[0];
                    572:                c->vector[1] = a->vector[1];
                    573:                c->vector[2] = a->vector[2];
                    574:                break;
                    575:                
                    576: //==================
                    577: 
                    578:        case OP_IFNOT:
                    579:                if (!a->_int)
                    580:                        s += st->b - 1; // offset the s++
                    581:                break;
                    582:                
                    583:        case OP_IF:
                    584:                if (a->_int)
                    585:                        s += st->b - 1; // offset the s++
                    586:                break;
                    587:                
                    588:        case OP_GOTO:
                    589:                s += st->a - 1; // offset the s++
                    590:                break;
                    591:                
                    592:        case OP_CALL0:
                    593:        case OP_CALL1:
                    594:        case OP_CALL2:
                    595:        case OP_CALL3:
                    596:        case OP_CALL4:
                    597:        case OP_CALL5:
                    598:        case OP_CALL6:
                    599:        case OP_CALL7:
                    600:        case OP_CALL8:
                    601:                pr_argc = st->op - OP_CALL0;
                    602:                if (!a->function)
                    603:                        PR_RunError ("NULL function");
                    604: 
                    605:                newf = &pr_functions[a->function];
                    606: 
                    607:                if (newf->first_statement < 0)
                    608:                {       // negative statements are built in functions
                    609:                        i = -newf->first_statement;
                    610:                        if (i >= pr_numbuiltins)
                    611:                                PR_RunError ("Bad builtin call number");
                    612:                        pr_builtins[i] ();
                    613:                        break;
                    614:                }
                    615: 
                    616:                s = PR_EnterFunction (newf);
                    617:                break;
                    618: 
                    619:        case OP_DONE:
                    620:        case OP_RETURN:
                    621:                pr_globals[OFS_RETURN] = pr_globals[st->a];
                    622:                pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
                    623:                pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
                    624:        
                    625:                s = PR_LeaveFunction ();
                    626:                if (pr_depth == exitdepth)
                    627:                        return;         // all done
                    628:                break;
                    629:                
                    630:        case OP_STATE:
                    631:                ed = PROG_TO_EDICT(pr_global_struct->self);
                    632:                ed->v.nextthink = pr_global_struct->time + 0.1;
                    633:                if (a->_float != ed->v.frame)
                    634:                {
                    635:                        ed->v.frame = a->_float;
                    636:                }
                    637:                ed->v.think = b->function;
                    638:                break;
                    639:                
                    640:        default:
                    641:                PR_RunError ("Bad opcode %i", st->op);
                    642:        }
                    643: }
                    644: 
                    645: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.