+ }
+ }
+
+cleanup:
+ if (developer_insane.integer && prog->tempstringsbuf.cursize > restorevm_tempstringsbuf_cursize)
+ Con_DPrintf("CLVM_ExecuteProgram: %s used %i bytes of tempstrings\n", PRVM_GetString(prog, prog->functions[fnum].s_name), prog->tempstringsbuf.cursize - restorevm_tempstringsbuf_cursize);
+ // delete tempstrings created by this function
+ prog->tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
+
+ tm = Sys_DirtyTime() - calltime;if (tm < 0 || tm >= 1800) tm = 0;
+ func->totaltime += tm;
+
+ if (prog == SVVM_prog)
+ SV_FlushBroadcastMessages();
+}
+#endif
+
+/*
+====================
+SVVM_ExecuteProgram
+====================
+*/
+#ifdef PROFILING
+void SVVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage)
+#else
+void PRVM_ExecuteProgram (prvm_prog_t *prog, func_t fnum, const char *errormessage)
+#endif
+{
+ mstatement_t *st, *startst;
+ mfunction_t *func, *enterfunc;
+ prvm_edict_t *ed;
+ prvm_eval_t *ptr;
+ int jumpcount, cachedpr_trace, exitdepth;
+ int restorevm_tempstringsbuf_cursize;
+ double calltime;
+ double tm, starttm;
+ prvm_vec_t tempfloat;
+ // these may become out of date when a builtin is called, and are updated accordingly
+ prvm_vec_t *cached_edictsfields = prog->edictsfields.fp;
+ unsigned int cached_entityfields = prog->entityfields;
+ unsigned int cached_entityfields_3 = prog->entityfields - 3;
+ unsigned int cached_entityfieldsarea = prog->entityfieldsarea;
+ unsigned int cached_entityfieldsarea_entityfields = prog->entityfieldsarea - prog->entityfields;
+ unsigned int cached_entityfieldsarea_3 = prog->entityfieldsarea - 3;
+ unsigned int cached_entityfieldsarea_entityfields_3 = prog->entityfieldsarea - prog->entityfields - 3;
+ unsigned int cached_max_edicts = prog->max_edicts;
+ // these do not change
+ mstatement_t *cached_statements = prog->statements;
+ qboolean cached_allowworldwrites = prog->allowworldwrites;
+ unsigned int cached_flag = prog->flag;
+
+ calltime = Sys_DirtyTime();
+
+ if (!fnum || fnum >= (unsigned int)prog->numfunctions)
+ {
+ if (PRVM_allglobaledict(self))
+ PRVM_ED_Print(prog, PRVM_PROG_TO_EDICT(PRVM_allglobaledict(self)), NULL);
+ prog->error_cmd("SVVM_ExecuteProgram: %s", errormessage);
+ }
+
+ func = &prog->functions[fnum];
+
+ // after executing this function, delete all tempstrings it created
+ restorevm_tempstringsbuf_cursize = prog->tempstringsbuf.cursize;
+
+ prog->trace = prvm_traceqc.integer;
+
+ // we know we're done when pr_depth drops to this
+ exitdepth = prog->depth;
+
+// make a stack frame
+ st = &prog->statements[PRVM_EnterFunction(prog, func)];
+ // save the starting statement pointer for profiling
+ // (when the function exits or jumps, the (st - startst) integer value is
+ // added to the function's profile counter)
+ startst = st;
+ starttm = calltime;
+ // instead of counting instructions, we count jumps
+ jumpcount = 0;
+ // add one to the callcount of this function because otherwise engine-called functions aren't counted
+ if (prog->xfunction->callcount++ == 0 && (prvm_coverage.integer & 1))
+ PRVM_FunctionCoverageEvent(prog, prog->xfunction);
+
+chooseexecprogram:
+ cachedpr_trace = prog->trace;
+ if (prog->trace || prog->watch_global_type != ev_void || prog->watch_field_type != ev_void || prog->break_statement >= 0)
+ {
+#define PRVMSLOWINTERPRETER 1
+ if (prvm_timeprofiling.integer)
+ {
+#define PRVMTIMEPROFILING 1