Annotation of quake1/pr_exec.c, revision 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.