633 lines · 11.2 KB · C
RawDownload
#include <stdarg.h>#include "quakedef.h" typedef struct{	int s;	dfunction_t *f;} prstack_t; #define MAX_STACK_DEPTH 32prstack_t pr_stack[MAX_STACK_DEPTH];int pr_depth; #define LOCALSTACK_SIZE 2048int localstack[LOCALSTACK_SIZE];int localstack_used; bool pr_trace;dfunction_t *pr_xfunction;int pr_xstatement; int pr_argc; char *pr_opnames[] ={"DONE", "MUL_F","MUL_V","MUL_FV","MUL_VF", "DIV", "ADD_F","ADD_V", "SUB_F","SUB_V", "EQ_F","EQ_V","EQ_S","EQ_E","EQ_FNC", "NE_F","NE_V","NE_S","NE_E","NE_FNC", "LE","GE","LT","GT", "INDIRECT","INDIRECT","INDIRECT","INDIRECT","INDIRECT","INDIRECT", "ADDRESS", "STORE_F","STORE_V","STORE_S","STORE_ENT","STORE_FLD","STORE_FNC", "STOREP_F","STOREP_V","STOREP_S","STOREP_ENT","STOREP_FLD","STOREP_FNC", "RETURN", "NOT_F","NOT_V","NOT_S","NOT_ENT","NOT_FNC", "IF","IFNOT", "CALL0","CALL1","CALL2","CALL3","CALL4","CALL5","CALL6","CALL7","CALL8", "STATE", "GOTO", "AND","OR", "BITAND","BITOR"}; char *PR_GlobalString (int ofs);char *PR_GlobalStringNoContents (int ofs); //============================================================================= /*=================PR_PrintStatement=================*/void PR_PrintStatement (dstatement_t *s){	int i; 	if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0]))	{		Con_Printf ("%s ", pr_opnames[s->op]);		i = strlen(pr_opnames[s->op]);		for ( ; i<10 ; i++)			Con_Printf (" ");	} 	if (s->op == OP_IF || s->op == OP_IFNOT)		Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b);	else if (s->op == OP_GOTO)	{		Con_Printf ("branch %i",s->a);	}	else if ( (unsigned)(s->op - OP_STORE_F) < 6)	{		Con_Printf ("%s",PR_GlobalString(s->a));		Con_Printf ("%s", PR_GlobalStringNoContents(s->b));	}	else	{		if (s->a)			Con_Printf ("a=%s",PR_GlobalString(s->a));		if (s->b)			Con_Printf ("b=%s",PR_GlobalString(s->b));		if (s->c)			Con_Printf ("c=%s", PR_GlobalStringNoContents(s->c));	}	Con_Printf ("\n");} /*============PR_StackTrace============*/void PR_StackTrace (void){	dfunction_t *f;	int i; 	if (pr_depth == 0)	{		Con_Printf ("<NO STACK>\n");		return;	} 	pr_stack[pr_depth].f = pr_xfunction;	for (i=pr_depth ; i>=0 ; i--)	{		f = pr_stack[i].f; 		if (!f)		{			Con_Printf ("<NO FUNCTION>\n");		}		else			Con_Printf ("%12s : %s\n", PR_GetString(f->s_file), PR_GetString(f->s_name));	}} /*============PR_Profile_f ============*/void PR_Profile_f (void){	dfunction_t *f, *best;	int max;	int num;	int i; 	num = 0;	do	{		max = 0;		best = NULL;		for (i=0 ; i<progs->numfunctions ; i++)		{			f = &pr_functions[i];			if (f->profile > max)			{				max = f->profile;				best = f;			}		}		if (best)		{			if (num < 10)				Con_Printf ("%7i %s\n", best->profile, PR_GetString(best->s_name));			num++;			best->profile = 0;		}	} while (best);} /*============PR_RunError Aborts the currently executing function============*/void PR_RunError (char *error, ...){	va_list argptr;	char string[1024]; 	va_start (argptr,error);	vsprintf (string,error,argptr);	va_end (argptr); 	PR_PrintStatement (pr_statements + pr_xstatement);	PR_StackTrace ();	Con_Printf ("%s\n", string); 	pr_depth = 0; // dump the stack so host_error can shutdown functions 	Host_Error ("Program error");} /*============================================================================PR_ExecuteProgram The interpretation main loop============================================================================*/ /*====================PR_EnterFunction Returns the new program statement counter====================*/int PR_EnterFunction (dfunction_t *f){	int i, j, c, o; 	pr_stack[pr_depth].s = pr_xstatement;	pr_stack[pr_depth].f = pr_xfunction;	pr_depth++;	if (pr_depth >= MAX_STACK_DEPTH)		PR_RunError ("stack overflow"); // save off any locals that the new function steps on	c = f->locals;	if (localstack_used + c > LOCALSTACK_SIZE)		PR_RunError ("PR_ExecuteProgram: locals stack overflow\n"); 	for (i=0 ; i < c ; i++)		localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];	localstack_used += c; // copy parameters	o = f->parm_start;	for (i=0 ; i<f->numparms ; i++)	{		for (j=0 ; j<f->parm_size[i] ; j++)		{			((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];			o++;		}	} 	pr_xfunction = f;	return f->first_statement - 1; // offset the s++} /*====================PR_LeaveFunction====================*/int PR_LeaveFunction (void){	int i, c; 	if (pr_depth <= 0)		Sys_Error ("prog stack underflow"); // restore locals from the stack	c = pr_xfunction->locals;	localstack_used -= c;	if (localstack_used < 0)		PR_RunError ("PR_ExecuteProgram: locals stack underflow\n"); 	for (i=0 ; i < c ; i++)		((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i]; // up stack	pr_depth--;	pr_xfunction = pr_stack[pr_depth].f;	return pr_stack[pr_depth].s;} /*====================PR_ExecuteProgram====================*/void PR_ExecuteProgram (func_t fnum){	eval_t *a, *b, *c;	int s;	dstatement_t *st;	dfunction_t *f, *newf;	int runaway;	int i;	edict_t *ed;	int exitdepth;	eval_t *ptr; 	if (!fnum || fnum >= progs->numfunctions)	{		if (pr_global_struct->self)			ED_Print (PROG_TO_EDICT(pr_global_struct->self));		Host_Error ("PR_ExecuteProgram: NULL function");	} 	f = &pr_functions[fnum]; 	runaway = 100000;	pr_trace = false; // make a stack frame	exitdepth = pr_depth; 	s = PR_EnterFunction (f); while (1){	s++; // next statement 	st = &pr_statements[s];	a = (eval_t *)&pr_globals[st->a];	b = (eval_t *)&pr_globals[st->b];	c = (eval_t *)&pr_globals[st->c]; 	if (!--runaway)		PR_RunError ("runaway loop error"); 	pr_xfunction->profile++;	pr_xstatement = s; 	if (pr_trace)		PR_PrintStatement (st); 	switch (st->op)	{	case OP_ADD_F:		c->_float = a->_float + b->_float;		break;	case OP_ADD_V:		c->vector[0] = a->vector[0] + b->vector[0];		c->vector[1] = a->vector[1] + b->vector[1];		c->vector[2] = a->vector[2] + b->vector[2];		break; 	case OP_SUB_F:		c->_float = a->_float - b->_float;		break;	case OP_SUB_V:		c->vector[0] = a->vector[0] - b->vector[0];		c->vector[1] = a->vector[1] - b->vector[1];		c->vector[2] = a->vector[2] - b->vector[2];		break; 	case OP_MUL_F:		c->_float = a->_float * b->_float;		break;	case OP_MUL_V:		c->_float = a->vector[0]*b->vector[0]				+ a->vector[1]*b->vector[1]				+ a->vector[2]*b->vector[2];		break;	case OP_MUL_FV:		c->vector[0] = a->_float * b->vector[0];		c->vector[1] = a->_float * b->vector[1];		c->vector[2] = a->_float * b->vector[2];		break;	case OP_MUL_VF:		c->vector[0] = b->_float * a->vector[0];		c->vector[1] = b->_float * a->vector[1];		c->vector[2] = b->_float * a->vector[2];		break; 	case OP_DIV_F:		c->_float = a->_float / b->_float;		break; 	case OP_BITAND:		c->_float = (int)a->_float & (int)b->_float;		break; 	case OP_BITOR:		c->_float = (int)a->_float | (int)b->_float;		break; 	case OP_GE:		c->_float = a->_float >= b->_float;		break;	case OP_LE:		c->_float = a->_float <= b->_float;		break;	case OP_GT:		c->_float = a->_float > b->_float;		break;	case OP_LT:		c->_float = a->_float < b->_float;		break;	case OP_AND:		c->_float = a->_float && b->_float;		break;	case OP_OR:		c->_float = a->_float || b->_float;		break; 	case OP_NOT_F:		c->_float = !a->_float;		break;	case OP_NOT_V:		c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];		break;	case OP_NOT_S:		c->_float = !a->string || !PR_GetString(a->string)[0];		break;	case OP_NOT_FNC:		c->_float = !a->function;		break;	case OP_NOT_ENT:		c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts);		break; 	case OP_EQ_F:		c->_float = a->_float == b->_float;		break;	case OP_EQ_V:		c->_float = (a->vector[0] == b->vector[0]) &&					(a->vector[1] == b->vector[1]) &&					(a->vector[2] == b->vector[2]);		break;	case OP_EQ_S:		c->_float = !strcmp(PR_GetString(a->string), PR_GetString(b->string));		break;	case OP_EQ_E:		c->_float = a->_int == b->_int;		break;	case OP_EQ_FNC:		c->_float = a->function == b->function;		break; 	case OP_NE_F:		c->_float = a->_float != b->_float;		break;	case OP_NE_V:		c->_float = (a->vector[0] != b->vector[0]) ||					(a->vector[1] != b->vector[1]) ||					(a->vector[2] != b->vector[2]);		break;	case OP_NE_S:		c->_float = strcmp(PR_GetString(a->string), PR_GetString(b->string));		break;	case OP_NE_E:		c->_float = a->_int != b->_int;		break;	case OP_NE_FNC:		c->_float = a->function != b->function;		break; //==================

Lines 1–500 of 633.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t