2 Copyright (C) 1996-1997 Id Software, Inc.
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 See the GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
34 #define MAX_STACK_DEPTH 32
35 prstack_t pr_stack[MAX_STACK_DEPTH];
38 #define LOCALSTACK_SIZE 2048
39 int localstack[LOCALSTACK_SIZE];
44 dfunction_t *pr_xfunction;
139 char *PR_GlobalString (int ofs);
140 char *PR_GlobalStringNoContents (int ofs);
143 //=============================================================================
150 void PR_PrintStatement (dstatement_t *s)
154 if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0]))
156 Con_Printf ("%s ", pr_opnames[s->op]);
157 i = strlen(pr_opnames[s->op]);
162 if (s->op == OP_IF || s->op == OP_IFNOT)
163 Con_Printf ("%sbranch %i",PR_GlobalString((unsigned short) s->a),s->b);
164 else if (s->op == OP_GOTO)
166 Con_Printf ("branch %i",s->a);
168 else if ( (unsigned)(s->op - OP_STORE_F) < 6)
170 Con_Printf ("%s",PR_GlobalString((unsigned short) s->a));
171 Con_Printf ("%s", PR_GlobalStringNoContents((unsigned short) s->b));
176 Con_Printf ("%s",PR_GlobalString((unsigned short) s->a));
178 Con_Printf ("%s",PR_GlobalString((unsigned short) s->b));
180 Con_Printf ("%s", PR_GlobalStringNoContents((unsigned short) s->c));
190 void PR_StackTrace (void)
195 pr_stack[pr_depth].s = pr_xstatement;
196 pr_stack[pr_depth].f = pr_xfunction;
197 for (i = pr_depth;i > 0;i--)
202 Con_Printf ("<NULL FUNCTION>\n");
204 Con_Printf ("%12s : %s : statement %i\n", pr_strings + f->s_file, pr_strings + f->s_name, pr_stack[i].s - f->first_statement);
215 void PR_Profile_f (void)
217 dfunction_t *f, *best;
227 for (i=0 ; i<progs->numfunctions ; i++)
229 f = &pr_functions[i];
230 if (f->profile > max)
239 Con_Printf ("%7i %s\n", best->profile, pr_strings+best->s_name);
251 Aborts the currently executing function
254 void PR_RunError (char *error, ...)
260 va_start (argptr,error);
261 vsprintf (string,error,argptr);
266 for (i = -4;i <= 0;i++)
267 if (pr_xstatement + i >= pr_xfunction->first_statement)
268 PR_PrintStatement (pr_statements + pr_xstatement + i);
271 Con_Printf("null function executing??\n");
273 Con_Printf ("%s\n", string);
275 pr_depth = 0; // dump the stack so host_error can shutdown functions
277 Host_Error ("Program error");
281 ============================================================================
284 The interpretation main loop
285 ============================================================================
292 Returns the new program statement counter
295 int PR_EnterFunction (dfunction_t *f)
300 PR_RunError ("PR_EnterFunction: NULL function\n");
302 pr_stack[pr_depth].s = pr_xstatement;
303 pr_stack[pr_depth].f = pr_xfunction;
305 if (pr_depth >= MAX_STACK_DEPTH)
306 PR_RunError ("stack overflow");
308 // save off any locals that the new function steps on
310 if (localstack_used + c > LOCALSTACK_SIZE)
311 PR_RunError ("PR_ExecuteProgram: locals stack overflow\n");
313 for (i=0 ; i < c ; i++)
314 localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
315 localstack_used += c;
319 for (i=0 ; i<f->numparms ; i++)
321 for (j=0 ; j<f->parm_size[i] ; j++)
323 ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];
329 return f->first_statement - 1; // offset the s++
337 int PR_LeaveFunction (void)
342 Host_Error ("prog stack underflow");
345 PR_RunError ("PR_LeaveFunction: NULL function\n");
346 // restore locals from the stack
347 c = pr_xfunction->locals;
348 localstack_used -= c;
349 if (localstack_used < 0)
350 PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");
352 for (i=0 ; i < c ; i++)
353 ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
357 pr_xfunction = pr_stack[pr_depth].f;
358 return pr_stack[pr_depth].s;
366 // LordHavoc: optimized
367 #define OPA ((eval_t *)&pr_globals[(unsigned short) st->a])
368 #define OPB ((eval_t *)&pr_globals[(unsigned short) st->b])
369 #define OPC ((eval_t *)&pr_globals[(unsigned short) st->c])
370 extern cvar_t pr_boundscheck;
371 void PR_ExecuteProgram (func_t fnum, char *errormessage)
374 dfunction_t *f, *newf;
377 int profile, startprofile, cachedpr_trace, exitdepth;
379 if (!fnum || fnum >= progs->numfunctions)
381 if (pr_global_struct->self)
382 ED_Print (PROG_TO_EDICT(pr_global_struct->self));
383 Host_Error ("PR_ExecuteProgram: %s", errormessage);
386 f = &pr_functions[fnum];
390 // we know we're done when pr_depth drops to this
391 exitdepth = pr_depth;
393 // make a stack frame
394 st = &pr_statements[PR_EnterFunction (f)];
395 startprofile = profile = 0;
398 cachedpr_trace = pr_trace;
399 if (pr_boundscheck.integer)
401 #define PRBOUNDSCHECK 1
405 #include "pr_execprogram.h"
410 #include "pr_execprogram.h"
419 #include "pr_execprogram.h"
424 #include "pr_execprogram.h"