5 #define HunkAlloc BADGDFG sdfhhsf FHS
8 #define Host_Error Sys_Error
10 // I put the following here to resolve "undefined reference to `__imp__vsnprintf'" with MinGW64 ~ Moodles
12 #if (_MSC_VER >= 1400)
13 //with MSVC 8, use MS extensions
14 #define snprintf linuxlike_snprintf_vc8
15 int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
16 #define vsnprintf(a, b, c, d) vsnprintf_s(a, b, _TRUNCATE, c, d)
19 #define snprintf linuxlike_snprintf
20 int VARGS linuxlike_snprintf(char *buffer, int size, const char *format, ...) LIKEPRINTF(3);
21 #define vsnprintf linuxlike_vsnprintf
22 int VARGS linuxlike_vsnprintf(char *buffer, int size, const char *format, va_list argptr);
27 //=============================================================================
35 void PR_PrintStatement (progfuncs_t *progfuncs, dstatement16_t *s)
38 printf("PR_PrintStatement is unsupported\n");
40 if ( (unsigned)s->op < OP_NUMOPS)
42 printf ("%s ", pr_opcodes[s->op].name);
43 i = strlen(pr_opcodes[s->op].name);
48 if (s->op == OP_IF || s->op == OP_IFNOT)
49 printf ("%sbranch %i",PR_GlobalString(progfuncs, s->a),s->b);
50 else if (s->op == OP_GOTO)
52 printf ("branch %i",s->a);
54 else if ( (unsigned)(s->op - OP_STORE_F) < 6)
56 printf ("%s",PR_GlobalString(progfuncs, s->a));
57 printf ("%s", PR_GlobalStringNoContents(progfuncs, s->b));
62 printf ("%s",PR_GlobalString(progfuncs, s->a));
64 printf ("%s",PR_GlobalString(progfuncs, s->b));
66 printf ("%s", PR_GlobalStringNoContents(progfuncs, s->c));
77 char *QC_ucase(char *str)
85 if (*str >= 'a' && *str <= 'z')
86 *str = *str - 'a' + 'A';
92 void PR_StackTrace (progfuncs_t *progfuncs)
106 printf ("<NO STACK>\n");
111 globalbase = (int *)pr_globals + pr_xfunction->parm_start - pr_xfunction->locals;
114 pr_stack[pr_depth].f = pr_xfunction;
115 pr_stack[pr_depth].s = pr_xstatement;
116 for (i=pr_depth ; i>0 ; i--)
122 printf ("<NO FUNCTION>\n");
126 if (pr_stack[i].progsnum != progs)
128 progs = pr_stack[i].progsnum;
130 printf ("<%s>\n", pr_progstate[progs].filename);
133 printf ("stripped : %s\n", f->s_name+progfuncs->stringtable);
136 if (pr_progstate[progs].linenums)
137 printf ("%12s %i : %s\n", f->s_file+progfuncs->stringtable, pr_progstate[progs].linenums[pr_stack[i].s], f->s_name+progfuncs->stringtable);
139 printf ("%12s : %s\n", f->s_file+progfuncs->stringtable, f->s_name+progfuncs->stringtable);
144 for (arg = 0; arg < f->locals; arg++)
147 local = ED_GlobalAtOfs16(progfuncs, f->parm_start+arg);
150 printf(" ofs %i: %f : %i\n", f->parm_start+arg, *(float *)(globalbase - f->locals+arg), *(int *)(globalbase - f->locals+arg) );
154 printf(" %s: %s\n", local->s_name+progfuncs->stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg)));
155 if (local->type == ev_vector)
161 globalbase = localstack + localstack_used;
163 globalbase -= f->locals;
176 void PR_Profile_f (void)
178 dfunction_t *f, *best;
188 for (i=0 ; i<pr_progs->numfunctions ; i++)
190 f = &pr_functions[i];
191 if (f->profile > max && f->first_statement >=0)
200 printf ("%7i %s\n", best->profile, best->s_name);
213 Aborts the currently executing function
216 void VARGS PR_RunError (progfuncs_t *progfuncs, char *error, ...)
221 va_start (argptr,error);
222 Q_vsnprintf (string,sizeof(string)-1, error,argptr);
226 // void SV_EndRedirect (void);
230 // PR_PrintStatement (pr_statements + pr_xstatement);
231 PR_StackTrace (progfuncs);
234 //editbadfile(pr_strings + pr_xfunction->s_file, -1);
236 // pr_depth = 0; // dump the stack so host_error can shutdown functions
237 // prinst->exitdepth = 0;
239 Abort ("%s", string);
243 ============================================================================
246 The interpretation main loop
247 ============================================================================
254 Returns the new program statement counter
257 void PR_AbortStack (progfuncs_t *progfuncs);
258 int ASMCALL PR_EnterFunction (progfuncs_t *progfuncs, dfunction_t *f, int progsnum)
262 pr_stack[pr_depth].s = pr_xstatement;
263 pr_stack[pr_depth].f = pr_xfunction;
264 pr_stack[pr_depth].progsnum = progsnum;
265 pr_stack[pr_depth].pushed = pr_spushed;
267 if (pr_depth == MAX_STACK_DEPTH)
270 PR_StackTrace (progfuncs);
272 printf ("stack overflow on call to %s\n", progfuncs->stringtable+f->s_name);
274 //comment this out if you want the progs to try to continue anyway (could cause infinate loops)
275 PR_AbortStack(progfuncs);
276 Abort("Stack Overflow in %s\n", progfuncs->stringtable+f->s_name);
277 return pr_xstatement;
280 localstack_used += pr_spushed; //make sure the call doesn't hurt pushed pointers
282 // save off any locals that the new function steps on (to a side place, fromwhere they are restored on exit)
284 if (localstack_used + c > LOCALSTACK_SIZE)
286 localstack_used -= pr_spushed;
288 PR_RunError (progfuncs, "PR_ExecuteProgram: locals stack overflow\n");
291 for (i=0 ; i < c ; i++)
292 localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
293 localstack_used += c;
295 // copy parameters (set initial values)
297 for (i=0 ; i<f->numparms ; i++)
299 for (j=0 ; j<f->parm_size[i] ; j++)
301 ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];
307 return f->first_statement - 1; // offset the s++
315 int ASMCALL PR_LeaveFunction (progfuncs_t *progfuncs)
320 Sys_Error ("prog stack underflow");
322 // restore locals from the stack
323 c = pr_xfunction->locals;
324 localstack_used -= c;
325 if (localstack_used < 0)
326 PR_RunError (progfuncs, "PR_ExecuteProgram: locals stack underflow\n");
328 for (i=0 ; i < c ; i++)
329 ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
333 PR_MoveParms(progfuncs, pr_stack[pr_depth].progsnum, pr_typecurrent);
334 PR_SwitchProgs(progfuncs, pr_stack[pr_depth].progsnum);
335 pr_xfunction = pr_stack[pr_depth].f;
336 pr_spushed = pr_stack[pr_depth].pushed;
338 localstack_used -= pr_spushed;
339 return pr_stack[pr_depth].s;
342 ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val)
349 if (pr_typecurrent < 0)
352 switch (pr_progstate[pr_typecurrent].structtype)
356 //this gets parms fine, but not locals
358 for (i = 0; i < pr_xfunction->numparms; i++)
360 def16 = ED_GlobalAtOfs16(progfuncs, pr_xfunction->parm_start+i);
363 if (!strcmp(def16->s_name+progfuncs->stringtable, name))
365 *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i];
367 //we need something like this for functions that are not the top layer
368 // *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4];
369 def.ofs = def16->ofs;
370 def.s_name = def16->s_name;
371 def.type = def16->type;
375 def16 = ED_FindGlobal16(progfuncs, name);
378 def.ofs = def16->ofs;
379 def.type = def16->type;
380 def.s_name = def16->s_name;
385 //this gets parms fine, but not locals
387 for (i = 0; i < pr_xfunction->numparms; i++)
389 def32 = ED_GlobalAtOfs32(progfuncs, pr_xfunction->parm_start+i);
392 if (!strcmp(def32->s_name+progfuncs->stringtable, name))
394 *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i];
396 //we need something like this for functions that are not the top layer
397 // *val = (eval_t *)&localstack[localstack_used-pr_xfunction->numparms*4];
401 def32 = ED_FindGlobal32(progfuncs, name);
406 Sys_Error("Bad struct type in ED_FindLocalOrGlobal");
410 *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[def32->ofs];
414 char *COM_TrimString(char *str)
417 static char buffer[256];
418 while (*str <= ' ' && *str>'\0')
421 for (i = 0; i < 255; i++)
431 char *EvaluateDebugString(progfuncs_t *progfuncs, char *key)
433 static char buf[256];
444 assignment = strchr(key, '=');
448 c = strchr(key, '.');
450 def = ED_FindLocalOrGlobal(progfuncs, key, &val);
457 def->type = ev_entity;
459 val->edict = atoi(key);
465 return "(Bad string)";
469 //go through ent vars
470 c = strchr(key, '.');
475 type = type &~DEF_SAVEGLOBAL;
476 if (current_progstate && current_progstate->types)
477 type = current_progstate->types[type].type;
478 if (type != ev_entity)
479 return "'.' without entity";
481 fdef = ED_FindField(progfuncs, COM_TrimString(c2));
484 return "(Bad string)";
485 ed = PROG_TO_EDICT(progfuncs, val->_int);
487 return "(Invalid Entity)";
488 val = (eval_t *) (((char *)ed->fields) + fdef->ofs*4);
495 while(*assignment == ' ')
497 switch (type&~DEF_SAVEGLOBAL)
500 *(string_t *)val = PR_StringToProgs(progfuncs, ED_NewString (progfuncs, assignment, 0));
504 if (assignment[0] == '0' && (assignment[1] == 'x' || assignment[1] == 'X'))
505 *(float*)val = strtoul(assignment, NULL, 0);
507 *(float *)val = (float)atof (assignment);
511 *(int *)val = atoi (assignment);
515 strcpy (string, assignment);
518 for (i=0 ; i<3 ; i++)
520 while (*v && *v != ' ')
523 ((float *)d)[i] = (float)atof (w);
529 *(int *)val = EDICT_TO_PROG(progfuncs, EDICT_NUM(progfuncs, atoi (assignment)));
533 fdef = ED_FindField (progfuncs, assignment);
536 size_t l,nl = strlen(assignment);
537 strcpy(buf, "Can't find field ");
539 if (nl > sizeof(buf)-l-2)
540 nl = sizeof(buf)-l-2;
541 memcpy(buf+l, assignment, nl);
542 assignment[l+nl+0] = '\n';
543 assignment[l+nl+1] = 0;
546 *(int *)val = G_INT(fdef->ofs);
554 char *s = assignment;
555 if (s[0] && s[1] == ':')
560 else if (s[0] && s[1] && s[2] == ':')
566 func = ED_FindFunction (progfuncs, s, &i, progsnum);
569 size_t l,nl = strlen(s);
571 assignment[-1] = '=';
573 strcpy(buf, "Can't find field ");
575 if (nl > sizeof(buf)-l-2)
576 nl = sizeof(buf)-l-2;
577 memcpy(buf+l, assignment, nl);
578 assignment[l+nl+0] = '\n';
579 assignment[l+nl+1] = 0;
582 *(func_t *)val = (func - pr_progstate[i].functions) | (i<<24);
590 assignment[-1] = '=';
592 strcpy(buf, PR_ValueString(progfuncs, type, val));
598 //int EditorHighlightLine(window_t *wnd, int line);
599 void SetExecutionToLine(progfuncs_t *progfuncs, int linenum)
601 int pn = pr_typecurrent;
603 dfunction_t *f = pr_xfunction;
605 switch(current_progstate->structtype)
609 for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++)
611 if (pr_statements16[snum].op == OP_DONE)
617 for (snum = f->first_statement; pr_progstate[pn].linenums[snum] < linenum; snum++)
619 if (pr_statements32[snum].op == OP_DONE)
624 Sys_Error("Bad struct type");
627 debugstatement = snum;
628 // EditorHighlightLine(editwnd, pr_progstate[pn].linenums[snum]);
631 //0 clear. 1 set, 2 toggle, 3 check
632 int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int flag) //write alternate route to work by function name.
637 int pn = pr_typecurrent;
639 int op = 0; //warning about not being initialized before use
641 for (pn = 0; (unsigned)pn < maxprogs; pn++)
643 if (!pr_progstate || !pr_progstate[pn].progs)
646 if (linenum) //linenum is set means to set the breakpoint on a file and line
648 if (!pr_progstate[pn].linenums)
651 for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++)
653 if (!stricmp(f->s_file+progfuncs->stringtable, filename))
655 for (i = f->first_statement; ; i++)
657 if (pr_progstate[pn].linenums[i] >= linenum)
659 fl = pr_progstate[pn].linenums[i];
662 if ((unsigned int)pr_progstate[pn].linenums[i] > fl)
665 switch(pr_progstate[pn].structtype)
669 op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op;
673 op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op;
676 Sys_Error("Bad structtype");
707 switch(pr_progstate[pn].structtype)
711 ((dstatement16_t*)pr_progstate[pn].statements + i)->op = op;
715 ((dstatement32_t*)pr_progstate[pn].statements + i)->op = op;
718 Sys_Error("Bad structtype");
728 else //set the breakpoint on the first statement of the function specified.
730 for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++)
732 if (!strcmp(f->s_name+progfuncs->stringtable, filename))
734 i = f->first_statement;
735 switch(pr_progstate[pn].structtype)
739 op = ((dstatement16_t*)pr_progstate[pn].statements + i)->op;
743 op = ((dstatement32_t*)pr_progstate[pn].statements + i)->op;
746 Sys_Error("Bad structtype");
776 switch(pr_progstate[pn].structtype)
780 ((dstatement16_t*)pr_progstate[pn].statements + i)->op = op;
784 ((dstatement32_t*)pr_progstate[pn].statements + i)->op = op;
787 Sys_Error("Bad structtype");
800 int ShowStep(progfuncs_t *progfuncs, int statement)
803 // texture realcursortex;
804 static int lastline = 0;
805 static char *lastfile = 0;
807 int pn = pr_typecurrent;
809 dfunction_t *f = pr_xfunction;
811 if (f && pr_progstate[pn].linenums && externs->useeditor)
813 if (lastline == pr_progstate[pn].linenums[statement] && lastfile == f->s_file+progfuncs->stringtable)
814 return statement; //no info/same line as last time
816 lastline = pr_progstate[pn].linenums[statement];
817 lastfile = f->s_file+progfuncs->stringtable;
819 lastline = externs->useeditor(progfuncs, lastfile, lastline, 0, NULL);
821 if (pr_progstate[pn].linenums[statement] != lastline)
823 for (i = f->first_statement; ; i++)
825 if (lastline == pr_progstate[pn].linenums[i])
829 else if (lastline <= pr_progstate[pn].linenums[i])
836 else if (f) //annoying.
838 if (*(f->s_file+progfuncs->stringtable)) //if we can't get the filename, then it was stripped, and debugging it like this is useless
839 if (externs->useeditor)
840 externs->useeditor(progfuncs, f->s_file+progfuncs->stringtable, -1, 0, NULL);
848 //DMW: all pointer functions are modified to be absoloute pointers from NULL not sv_edicts
854 void PR_ExecuteCode (progfuncs_t *progfuncs, int s)
856 eval_t *t, *swtch=NULL;
858 int swtchtype = 0; //warning about not being initialized before use
859 dstatement16_t *st16;
860 dstatement32_t *st32;
871 prinst->continuestatement = -1;
873 if (current_progstate->jit)
875 PR_EnterJIT(progfuncs, current_progstate->jit, s);
879 fnum = pr_xfunction - pr_functions;
883 #define PRBOUNDSCHECK
884 #define RUNAWAYCHECK() \
887 pr_xstatement = st-pr_statements; \
888 PR_StackTrace(progfuncs); \
889 printf ("runaway loop error\n"); \
890 while(pr_depth > prinst->exitdepth) \
891 PR_LeaveFunction(progfuncs); \
896 #define OPA ((eval_t *)&glob[st->a])
897 #define OPB ((eval_t *)&glob[st->b])
898 #define OPC ((eval_t *)&glob[st->c])
900 restart: //jumped to when the progs might have changed.
902 switch (current_progstate->structtype)
907 st16 = &pr_statements16[s];
911 #ifdef SEPARATEINCLUDES
912 #include "execloop16d.h"
914 #include "execloop.h"
921 #include "execloop.h"
924 Sys_Error("PR_ExecuteProgram - should be unreachable");
929 st32 = &pr_statements32[s];
933 #ifdef SEPARATEINCLUDES
934 #include "execloop32d.h"
936 #include "execloop.h"
943 #ifdef SEPARATEINCLUDES
944 #include "execloop32.h"
946 #include "execloop.h"
950 Sys_Error("PR_ExecuteProgram - should be unreachable");
953 Sys_Error("PR_ExecuteProgram - bad structtype");
958 void PR_ExecuteProgram (progfuncs_t *progfuncs, func_t fnum)
962 unsigned int initial_progs;
969 unsigned int newprogs = (fnum & 0xff000000)>>24;
971 initial_progs = pr_typecurrent;
972 if (newprogs != initial_progs)
974 if (newprogs >= maxprogs || !&pr_progstate[newprogs].globals) //can happen with hexen2...
976 printf("PR_ExecuteProgram: tried branching into invalid progs\n");
979 PR_MoveParms(progfuncs, newprogs, pr_typecurrent);
980 PR_SwitchProgs(progfuncs, newprogs);
983 if (!(fnum & ~0xff000000) || (signed)(fnum & ~0xff000000) >= pr_progs->numfunctions)
985 // if (pr_global_struct->self)
986 // ED_Print (PROG_TO_EDICT(pr_global_struct->self));
987 printf("PR_ExecuteProgram: NULL function from exe\n");
988 // Host_Error ("PR_ExecuteProgram: NULL function from exe");
990 // PR_MoveParms(0, pr_typecurrent);
991 PR_SwitchProgs(progfuncs, initial_progs);
995 oldexitdepth = prinst->exitdepth;
997 f = &pr_functions[fnum & ~0xff000000];
999 if (f->first_statement < 0)
1000 { // negative statements are built in functions
1001 i = -f->first_statement;
1003 if (i < externs->numglobalbuiltins)
1004 (*externs->globalbuiltins[i]) (progfuncs, (struct globalvars_s *)current_progstate->globals);
1007 i -= externs->numglobalbuiltins;
1008 if (i > current_progstate->numbuiltins)
1010 printf ("Bad builtin call number %i (from exe)\n", -f->first_statement);
1011 // PR_MoveParms(p, pr_typecurrent);
1012 PR_SwitchProgs(progfuncs, initial_progs);
1015 current_progstate->builtins [i] (progfuncs, (struct globalvars_s *)current_progstate->globals);
1017 PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
1018 PR_SwitchProgs(progfuncs, initial_progs);
1025 // make a stack frame
1026 prinst->exitdepth = pr_depth;
1029 s = PR_EnterFunction (progfuncs, f, initial_progs);
1031 tempdepth = prinst->numtempstringsstack;
1032 PR_ExecuteCode(progfuncs, s);
1035 PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
1036 PR_SwitchProgs(progfuncs, initial_progs);
1038 PR_FreeTemps(progfuncs, tempdepth);
1039 prinst->numtempstringsstack = tempdepth;
1041 prinst->exitdepth = oldexitdepth;
1054 typedef struct qcthread_s {
1056 qcthreadstack_t fstack[MAX_STACK_DEPTH];
1058 int lstack[LOCALSTACK_SIZE];
1064 struct qcthread_s *PR_ForkStack(progfuncs_t *progfuncs)
1065 { //QC code can call builtins that call qc code.
1066 //to get around the problems of restoring the builtins we simply don't save the thread over the builtin.
1068 int ed = prinst->exitdepth;
1069 int localsoffset, baselocalsoffset;
1070 qcthread_t *thread = memalloc(sizeof(qcthread_t));
1073 //copy out the functions stack.
1074 for (i = 0,localsoffset=0; i < ed; i++)
1076 if (i+1 == pr_depth)
1079 f = pr_stack[i+1].f;
1080 localsoffset += f->locals; //this is where it crashes
1082 baselocalsoffset = localsoffset;
1083 for (i = ed; i < pr_depth; i++)
1085 thread->fstack[i-ed].fnum = pr_stack[i].f - pr_progstate[pr_stack[i].progsnum].functions;
1086 thread->fstack[i-ed].progsnum = pr_stack[i].progsnum;
1087 thread->fstack[i-ed].statement = pr_stack[i].s;
1089 if (i+1 == pr_depth)
1092 f = pr_stack[i+1].f;
1093 localsoffset += f->locals;
1095 thread->fstackdepth = pr_depth - ed;
1097 for (i = pr_depth - 1; i >= ed ; i--)
1099 if (i+1 == pr_depth)
1102 f = pr_stack[i+1].f;
1103 localsoffset -= f->locals;
1104 for (l = 0; l < f->locals; l++)
1106 thread->lstack[localsoffset-baselocalsoffset + l ] = ((int *)pr_globals)[f->parm_start + l];
1107 ((int *)pr_globals)[f->parm_start + l] = localstack[localsoffset+l]; //copy the old value into the globals (so the older functions have the correct locals.
1111 for (i = ed; i < pr_depth ; i++) //we need to get the locals back to how they were.
1113 if (i+1 == pr_depth)
1116 f = pr_stack[i+1].f;
1118 for (l = 0; l < f->locals; l++)
1120 ((int *)pr_globals)[f->parm_start + l] = thread->lstack[localsoffset-baselocalsoffset + l];
1122 localsoffset += f->locals;
1124 thread->lstackused = localsoffset - baselocalsoffset;
1126 thread->xstatement = pr_xstatement;
1127 thread->xfunction = pr_xfunction - pr_progstate[pr_typecurrent].functions;
1128 thread->xprogs = pr_typecurrent;
1133 void PR_ResumeThread (progfuncs_t *progfuncs, struct qcthread_s *thread)
1135 dfunction_t *f, *oldf;
1137 progsnum_t initial_progs;
1143 progsnum_t prnum = thread->xprogs;
1144 int fnum = thread->xfunction;
1146 if (localstack_used + thread->lstackused > LOCALSTACK_SIZE)
1147 PR_RunError(progfuncs, "Too many locals on resumtion of QC thread\n");
1149 if (pr_depth + thread->fstackdepth > MAX_STACK_DEPTH)
1150 PR_RunError(progfuncs, "Too large stack on resumtion of QC thread\n");
1153 //do progs switching stuff as appropriate. (fteqw only)
1154 initial_progs = pr_typecurrent;
1155 PR_MoveParms(progfuncs, prnum, pr_typecurrent);
1156 PR_SwitchProgs(progfuncs, prnum);
1159 oldexitdepth = prinst->exitdepth;
1160 prinst->exitdepth = pr_depth;
1163 //add on the callstack.
1164 for (i = 0; i < thread->fstackdepth; i++)
1166 if (pr_depth == prinst->exitdepth)
1168 pr_stack[pr_depth].f = pr_xfunction;
1169 pr_stack[pr_depth].s = pr_xstatement;
1170 pr_stack[pr_depth].progsnum = initial_progs;
1174 pr_stack[pr_depth].progsnum = thread->fstack[i].progsnum;
1175 pr_stack[pr_depth].f = pr_progstate[thread->fstack[i].progsnum].functions + thread->fstack[i].fnum;
1176 pr_stack[pr_depth].s = thread->fstack[i].statement;
1179 if (i+1 == thread->fstackdepth)
1180 f = &pr_functions[fnum];
1182 f = pr_progstate[thread->fstack[i+1].progsnum].functions + thread->fstack[i+1].fnum;
1183 for (l = 0; l < f->locals; l++)
1185 localstack[localstack_used++] = ((int *)pr_globals)[f->parm_start + l];
1186 ((int *)pr_globals)[f->parm_start + l] = thread->lstack[ls++];
1192 if (ls != thread->lstackused)
1193 PR_RunError(progfuncs, "Thread stores incorrect locals count\n");
1196 f = &pr_functions[fnum];
1198 // thread->lstackused -= f->locals; //the current function is the odd one out.
1200 //add on the locals stack
1201 memcpy(localstack+localstack_used, thread->lstack, sizeof(int)*thread->lstackused);
1202 localstack_used += thread->lstackused;
1204 //bung the locals of the current function on the stack.
1205 // for (i=0 ; i < f->locals ; i++)
1206 // ((int *)pr_globals)[f->parm_start + i] = 0xff00ff00;//thread->lstack[thread->lstackused+i];
1209 // PR_EnterFunction (progfuncs, f, initial_progs);
1210 oldf = pr_xfunction;
1212 s = thread->xstatement;
1214 tempdepth = prinst->numtempstringsstack;
1215 PR_ExecuteCode(progfuncs, s);
1218 PR_MoveParms(progfuncs, initial_progs, pr_typecurrent);
1219 PR_SwitchProgs(progfuncs, initial_progs);
1220 PR_FreeTemps(progfuncs, tempdepth);
1221 prinst->numtempstringsstack = tempdepth;
1223 prinst->exitdepth = oldexitdepth;
1224 pr_xfunction = oldf;
1227 void PR_AbortStack (progfuncs_t *progfuncs)
1229 while(pr_depth > prinst->exitdepth+1)
1230 PR_LeaveFunction(progfuncs);
1231 prinst->continuestatement = 0;