d125cd7eeb2266cfb294b2c1699e86b8d2c4f330
[xonotic/darkplaces.git] / prvm_execprogram.h
1
2 // This code isn't #ifdef/#define protectable, don't try.
3
4                 while (1)
5                 {
6                         st++;
7                         if (++profile > 10000000) // LordHavoc: increased runaway loop limit 100x
8                         {
9                                 // LordHavoc: update profile counter for debugging reasons
10                                 // (identifying erroneous loops and recursion patterns)
11                                 prog->xfunction->profile += profile - startprofile;
12                                 startprofile = profile;
13                                 // update the statement number before we error out
14                                 prog->xstatement = st - prog->statements;
15                                 PRVM_ERROR("runaway loop counter hit limit of %d opcodes\ntip: if having trouble identifying the problem, try typing profile now in %s", profile, PRVM_NAME);
16                         }
17
18 #if PRVMTRACE
19                         prog->xfunction->profile += profile - startprofile;
20                         startprofile = profile;
21                         prog->xstatement = st - prog->statements;
22                         PRVM_PrintStatement(st);
23 #endif
24
25                         switch (st->op)
26                         {
27                         case OP_ADD_F:
28                                 OPC->_float = OPA->_float + OPB->_float;
29                                 break;
30                         case OP_ADD_V:
31                                 OPC->vector[0] = OPA->vector[0] + OPB->vector[0];
32                                 OPC->vector[1] = OPA->vector[1] + OPB->vector[1];
33                                 OPC->vector[2] = OPA->vector[2] + OPB->vector[2];
34                                 break;
35                         case OP_SUB_F:
36                                 OPC->_float = OPA->_float - OPB->_float;
37                                 break;
38                         case OP_SUB_V:
39                                 OPC->vector[0] = OPA->vector[0] - OPB->vector[0];
40                                 OPC->vector[1] = OPA->vector[1] - OPB->vector[1];
41                                 OPC->vector[2] = OPA->vector[2] - OPB->vector[2];
42                                 break;
43                         case OP_MUL_F:
44                                 OPC->_float = OPA->_float * OPB->_float;
45                                 break;
46                         case OP_MUL_V:
47                                 OPC->_float = OPA->vector[0]*OPB->vector[0] + OPA->vector[1]*OPB->vector[1] + OPA->vector[2]*OPB->vector[2];
48                                 break;
49                         case OP_MUL_FV:
50                                 OPC->vector[0] = OPA->_float * OPB->vector[0];
51                                 OPC->vector[1] = OPA->_float * OPB->vector[1];
52                                 OPC->vector[2] = OPA->_float * OPB->vector[2];
53                                 break;
54                         case OP_MUL_VF:
55                                 OPC->vector[0] = OPB->_float * OPA->vector[0];
56                                 OPC->vector[1] = OPB->_float * OPA->vector[1];
57                                 OPC->vector[2] = OPB->_float * OPA->vector[2];
58                                 break;
59                         case OP_DIV_F:
60                                 OPC->_float = OPA->_float / OPB->_float;
61                                 break;
62                         case OP_BITAND:
63                                 OPC->_float = (int)OPA->_float & (int)OPB->_float;
64                                 break;
65                         case OP_BITOR:
66                                 OPC->_float = (int)OPA->_float | (int)OPB->_float;
67                                 break;
68                         case OP_GE:
69                                 OPC->_float = OPA->_float >= OPB->_float;
70                                 break;
71                         case OP_LE:
72                                 OPC->_float = OPA->_float <= OPB->_float;
73                                 break;
74                         case OP_GT:
75                                 OPC->_float = OPA->_float > OPB->_float;
76                                 break;
77                         case OP_LT:
78                                 OPC->_float = OPA->_float < OPB->_float;
79                                 break;
80                         case OP_AND:
81                                 OPC->_float = OPA->_float && OPB->_float;
82                                 break;
83                         case OP_OR:
84                                 OPC->_float = OPA->_float || OPB->_float;
85                                 break;
86                         case OP_NOT_F:
87                                 OPC->_float = !OPA->_float;
88                                 break;
89                         case OP_NOT_V:
90                                 OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2];
91                                 break;
92                         case OP_NOT_S:
93                                 OPC->_float = !OPA->string || !*PRVM_GetString(OPA->string);
94                                 break;
95                         case OP_NOT_FNC:
96                                 OPC->_float = !OPA->function;
97                                 break;
98                         case OP_NOT_ENT:
99                                 OPC->_float = (OPA->edict == 0);
100                                 break;
101                         case OP_EQ_F:
102                                 OPC->_float = OPA->_float == OPB->_float;
103                                 break;
104                         case OP_EQ_V:
105                                 OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]);
106                                 break;
107                         case OP_EQ_S:
108                                 OPC->_float = !strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
109                                 break;
110                         case OP_EQ_E:
111                                 OPC->_float = OPA->_int == OPB->_int;
112                                 break;
113                         case OP_EQ_FNC:
114                                 OPC->_float = OPA->function == OPB->function;
115                                 break;
116                         case OP_NE_F:
117                                 OPC->_float = OPA->_float != OPB->_float;
118                                 break;
119                         case OP_NE_V:
120                                 OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]);
121                                 break;
122                         case OP_NE_S:
123                                 OPC->_float = strcmp(PRVM_GetString(OPA->string),PRVM_GetString(OPB->string));
124                                 break;
125                         case OP_NE_E:
126                                 OPC->_float = OPA->_int != OPB->_int;
127                                 break;
128                         case OP_NE_FNC:
129                                 OPC->_float = OPA->function != OPB->function;
130                                 break;
131
132                 //==================
133                         case OP_STORE_F:
134                         case OP_STORE_ENT:
135                         case OP_STORE_FLD:              // integers
136                         case OP_STORE_S:
137                         case OP_STORE_FNC:              // pointers
138                                 OPB->_int = OPA->_int;
139                                 break;
140                         case OP_STORE_V:
141                                 OPB->ivector[0] = OPA->ivector[0];
142                                 OPB->ivector[1] = OPA->ivector[1];
143                                 OPB->ivector[2] = OPA->ivector[2];
144                                 break;
145
146                         case OP_STOREP_F:
147                         case OP_STOREP_ENT:
148                         case OP_STOREP_FLD:             // integers
149                         case OP_STOREP_S:
150                         case OP_STOREP_FNC:             // pointers
151 #if PRVMBOUNDSCHECK
152                                 if (OPB->_int < 0 || OPB->_int + 4 > prog->edictareasize)
153                                 {
154                                         prog->xfunction->profile += profile - startprofile;
155                                         startprofile = profile;
156                                         prog->xstatement = st - prog->statements;
157                                         PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)\n", PRVM_NAME, OPB->_int);
158                                         return;
159                                 }
160 #endif
161                                 ptr = (prvm_eval_t *)((qbyte *)prog->edictsfields + OPB->_int);
162                                 ptr->_int = OPA->_int;
163                                 break;
164                         case OP_STOREP_V:
165 #if PRVMBOUNDSCHECK
166                                 if (OPB->_int < 0 || OPB->_int + 12 > prog->edictareasize)
167                                 {
168                                         prog->xfunction->profile += profile - startprofile;
169                                         startprofile = profile;
170                                         prog->xstatement = st - prog->statements;
171                                         PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)\n", PRVM_NAME, OPB->_int);
172                                         return;
173                                 }
174 #endif
175                                 ptr = (prvm_eval_t *)((qbyte *)prog->edictsfields + OPB->_int);
176                                 ptr->vector[0] = OPA->vector[0];
177                                 ptr->vector[1] = OPA->vector[1];
178                                 ptr->vector[2] = OPA->vector[2];
179                                 break;
180
181                         case OP_ADDRESS:
182 #if PRVMBOUNDSCHECK
183                                 if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
184                                 {
185                                         prog->xfunction->profile += profile - startprofile;
186                                         startprofile = profile;
187                                         prog->xstatement = st - prog->statements;
188                                         PRVM_ERROR("%s attempted to address an invalid field (%i) in an edict\n", PRVM_NAME, OPB->_int);
189                                         return;
190                                 }
191 #endif
192                                 if (OPA->edict == 0 && !prog->allowworldwrites)
193                                 {
194                                         prog->xfunction->profile += profile - startprofile;
195                                         startprofile = profile;
196                                         prog->xstatement = st - prog->statements;
197                                         PRVM_ERROR("forbidden assignment to null/world entity in %s", PRVM_NAME);
198                                         return;
199                                 }
200                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
201                                 OPC->_int = (qbyte *)((int *)ed->fields.vp + OPB->_int) - (qbyte *)prog->edictsfields;
202                                 break;
203
204                         case OP_LOAD_F:
205                         case OP_LOAD_FLD:
206                         case OP_LOAD_ENT:
207                         case OP_LOAD_S:
208                         case OP_LOAD_FNC:
209 #if PRVMBOUNDSCHECK
210                                 if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
211                                 {
212                                         prog->xfunction->profile += profile - startprofile;
213                                         startprofile = profile;
214                                         prog->xstatement = st - prog->statements;
215                                         PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)\n", PRVM_NAME, OPB->_int);
216                                         return;
217                                 }
218 #endif
219                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
220                                 OPC->_int = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->_int;
221                                 break;
222
223                         case OP_LOAD_V:
224 #if PRVMBOUNDSCHECK
225                                 if (OPB->_int < 0 || OPB->_int + 2 >= prog->progs->entityfields)
226                                 {
227                                         prog->xfunction->profile += profile - startprofile;
228                                         startprofile = profile;
229                                         prog->xstatement = st - prog->statements;
230                                         PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)\n", PRVM_NAME, OPB->_int);
231                                         return;
232                                 }
233 #endif
234                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
235                                 OPC->vector[0] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[0];
236                                 OPC->vector[1] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[1];
237                                 OPC->vector[2] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[2];
238                                 break;
239
240                 //==================
241
242                         case OP_IFNOT:
243                                 if (!OPA->_int)
244                                         st += st->b - 1;        // offset the s++
245                                 break;
246
247                         case OP_IF:
248                                 if (OPA->_int)
249                                         st += st->b - 1;        // offset the s++
250                                 break;
251
252                         case OP_GOTO:
253                                 st += st->a - 1;        // offset the s++
254                                 break;
255
256                         case OP_CALL0:
257                         case OP_CALL1:
258                         case OP_CALL2:
259                         case OP_CALL3:
260                         case OP_CALL4:
261                         case OP_CALL5:
262                         case OP_CALL6:
263                         case OP_CALL7:
264                         case OP_CALL8:
265                                 prog->xfunction->profile += profile - startprofile;
266                                 startprofile = profile;
267                                 prog->xstatement = st - prog->statements;
268                                 prog->argc = st->op - OP_CALL0;
269                                 if (!OPA->function)
270                                         PRVM_ERROR("NULL function in %s", PRVM_NAME);
271
272                                 newf = &prog->functions[OPA->function];
273                                 newf->callcount++;
274
275                                 if (newf->first_statement < 0)
276                                 {
277                                         // negative statements are built in functions
278                                         int builtinnumber = -newf->first_statement;
279                                         prog->xfunction->builtinsprofile++;
280                                         if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
281                                                 prog->builtins[builtinnumber]();
282                                         else
283                                                 PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
284                                 }
285                                 else
286                                         st = prog->statements + PRVM_EnterFunction(newf);
287                                 break;
288
289                         case OP_DONE:
290                         case OP_RETURN:
291                                 prog->xfunction->profile += profile - startprofile;
292                                 startprofile = profile;
293                                 prog->xstatement = st - prog->statements;
294
295                                 prog->globals.generic[OFS_RETURN] = prog->globals.generic[(unsigned short) st->a];
296                                 prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[(unsigned short) st->a+1];
297                                 prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[(unsigned short) st->a+2];
298
299                                 st = prog->statements + PRVM_LeaveFunction();
300                                 if (prog->depth <= exitdepth)
301                                         return;         // all done
302                                 if (prog->trace != cachedpr_trace)
303                                         goto chooseexecprogram;
304                                 break;
305
306                         case OP_STATE:
307                                 if(prog->flag & PRVM_OP_STATE)
308                                 {
309                                         prog->xfunction->profile += profile - startprofile;
310                                         startprofile = profile;
311                                         prog->xstatement = st - prog->statements;
312                                         ed = PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs));
313                                         PRVM_E_FLOAT(ed,PRVM_ED_FindField ("nextthink")->ofs) = *prog->time + 0.1;
314                                         PRVM_E_FLOAT(ed,PRVM_ED_FindField ("frame")->ofs) = OPA->_float;
315                                         *(func_t *)((float*)ed->fields.vp + PRVM_ED_FindField ("think")->ofs) = OPB->function;
316                                 }
317                                 else
318                                         PRVM_ERROR("OP_STATE not supported by %s\n", PRVM_NAME);
319                                 break;
320
321 // LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
322 /*
323                         case OP_ADD_I:
324                                 OPC->_int = OPA->_int + OPB->_int;
325                                 break;
326                         case OP_ADD_IF:
327                                 OPC->_int = OPA->_int + (int) OPB->_float;
328                                 break;
329                         case OP_ADD_FI:
330                                 OPC->_float = OPA->_float + (float) OPB->_int;
331                                 break;
332                         case OP_SUB_I:
333                                 OPC->_int = OPA->_int - OPB->_int;
334                                 break;
335                         case OP_SUB_IF:
336                                 OPC->_int = OPA->_int - (int) OPB->_float;
337                                 break;
338                         case OP_SUB_FI:
339                                 OPC->_float = OPA->_float - (float) OPB->_int;
340                                 break;
341                         case OP_MUL_I:
342                                 OPC->_int = OPA->_int * OPB->_int;
343                                 break;
344                         case OP_MUL_IF:
345                                 OPC->_int = OPA->_int * (int) OPB->_float;
346                                 break;
347                         case OP_MUL_FI:
348                                 OPC->_float = OPA->_float * (float) OPB->_int;
349                                 break;
350                         case OP_MUL_VI:
351                                 OPC->vector[0] = (float) OPB->_int * OPA->vector[0];
352                                 OPC->vector[1] = (float) OPB->_int * OPA->vector[1];
353                                 OPC->vector[2] = (float) OPB->_int * OPA->vector[2];
354                                 break;
355                         case OP_DIV_VF:
356                                 {
357                                         float temp = 1.0f / OPB->_float;
358                                         OPC->vector[0] = temp * OPA->vector[0];
359                                         OPC->vector[1] = temp * OPA->vector[1];
360                                         OPC->vector[2] = temp * OPA->vector[2];
361                                 }
362                                 break;
363                         case OP_DIV_I:
364                                 OPC->_int = OPA->_int / OPB->_int;
365                                 break;
366                         case OP_DIV_IF:
367                                 OPC->_int = OPA->_int / (int) OPB->_float;
368                                 break;
369                         case OP_DIV_FI:
370                                 OPC->_float = OPA->_float / (float) OPB->_int;
371                                 break;
372                         case OP_CONV_IF:
373                                 OPC->_float = OPA->_int;
374                                 break;
375                         case OP_CONV_FI:
376                                 OPC->_int = OPA->_float;
377                                 break;
378                         case OP_BITAND_I:
379                                 OPC->_int = OPA->_int & OPB->_int;
380                                 break;
381                         case OP_BITOR_I:
382                                 OPC->_int = OPA->_int | OPB->_int;
383                                 break;
384                         case OP_BITAND_IF:
385                                 OPC->_int = OPA->_int & (int)OPB->_float;
386                                 break;
387                         case OP_BITOR_IF:
388                                 OPC->_int = OPA->_int | (int)OPB->_float;
389                                 break;
390                         case OP_BITAND_FI:
391                                 OPC->_float = (int)OPA->_float & OPB->_int;
392                                 break;
393                         case OP_BITOR_FI:
394                                 OPC->_float = (int)OPA->_float | OPB->_int;
395                                 break;
396                         case OP_GE_I:
397                                 OPC->_float = OPA->_int >= OPB->_int;
398                                 break;
399                         case OP_LE_I:
400                                 OPC->_float = OPA->_int <= OPB->_int;
401                                 break;
402                         case OP_GT_I:
403                                 OPC->_float = OPA->_int > OPB->_int;
404                                 break;
405                         case OP_LT_I:
406                                 OPC->_float = OPA->_int < OPB->_int;
407                                 break;
408                         case OP_AND_I:
409                                 OPC->_float = OPA->_int && OPB->_int;
410                                 break;
411                         case OP_OR_I:
412                                 OPC->_float = OPA->_int || OPB->_int;
413                                 break;
414                         case OP_GE_IF:
415                                 OPC->_float = (float)OPA->_int >= OPB->_float;
416                                 break;
417                         case OP_LE_IF:
418                                 OPC->_float = (float)OPA->_int <= OPB->_float;
419                                 break;
420                         case OP_GT_IF:
421                                 OPC->_float = (float)OPA->_int > OPB->_float;
422                                 break;
423                         case OP_LT_IF:
424                                 OPC->_float = (float)OPA->_int < OPB->_float;
425                                 break;
426                         case OP_AND_IF:
427                                 OPC->_float = (float)OPA->_int && OPB->_float;
428                                 break;
429                         case OP_OR_IF:
430                                 OPC->_float = (float)OPA->_int || OPB->_float;
431                                 break;
432                         case OP_GE_FI:
433                                 OPC->_float = OPA->_float >= (float)OPB->_int;
434                                 break;
435                         case OP_LE_FI:
436                                 OPC->_float = OPA->_float <= (float)OPB->_int;
437                                 break;
438                         case OP_GT_FI:
439                                 OPC->_float = OPA->_float > (float)OPB->_int;
440                                 break;
441                         case OP_LT_FI:
442                                 OPC->_float = OPA->_float < (float)OPB->_int;
443                                 break;
444                         case OP_AND_FI:
445                                 OPC->_float = OPA->_float && (float)OPB->_int;
446                                 break;
447                         case OP_OR_FI:
448                                 OPC->_float = OPA->_float || (float)OPB->_int;
449                                 break;
450                         case OP_NOT_I:
451                                 OPC->_float = !OPA->_int;
452                                 break;
453                         case OP_EQ_I:
454                                 OPC->_float = OPA->_int == OPB->_int;
455                                 break;
456                         case OP_EQ_IF:
457                                 OPC->_float = (float)OPA->_int == OPB->_float;
458                                 break;
459                         case OP_EQ_FI:
460                                 OPC->_float = OPA->_float == (float)OPB->_int;
461                                 break;
462                         case OP_NE_I:
463                                 OPC->_float = OPA->_int != OPB->_int;
464                                 break;
465                         case OP_NE_IF:
466                                 OPC->_float = (float)OPA->_int != OPB->_float;
467                                 break;
468                         case OP_NE_FI:
469                                 OPC->_float = OPA->_float != (float)OPB->_int;
470                                 break;
471                         case OP_STORE_I:
472                                 OPB->_int = OPA->_int;
473                                 break;
474                         case OP_STOREP_I:
475 #if PRBOUNDSCHECK
476                                 if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
477                                 {
478                                         pr_xfunction->profile += profile - startprofile;
479                                         startprofile = profile;
480                                         pr_xstatement = st - pr_statements;
481                                         Host_Error("Progs attempted to write to an out of bounds edict\n");
482                                         return;
483                                 }
484 #endif
485                                 ptr = (prvm_eval_t *)((qbyte *)prog->edictsfields + OPB->_int);
486                                 ptr->_int = OPA->_int;
487                                 break;
488                         case OP_LOAD_I:
489 #if PRBOUNDSCHECK
490                                 if (OPA->edict < 0 || OPA->edict >= pr_edictareasize)
491                                 {
492                                         pr_xfunction->profile += profile - startprofile;
493                                         startprofile = profile;
494                                         pr_xstatement = st - pr_statements;
495                                         Host_Error("Progs attempted to read an out of bounds edict number\n");
496                                         return;
497                                 }
498                                 if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
499                                 {
500                                         pr_xfunction->profile += profile - startprofile;
501                                         startprofile = profile;
502                                         pr_xstatement = st - pr_statements;
503                                         Host_Error("Progs attempted to read an invalid field in an edict\n");
504                                         return;
505                                 }
506 #endif
507                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
508                                 OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
509                                 break;
510
511                         case OP_GSTOREP_I:
512                         case OP_GSTOREP_F:
513                         case OP_GSTOREP_ENT:
514                         case OP_GSTOREP_FLD:            // integers
515                         case OP_GSTOREP_S:
516                         case OP_GSTOREP_FNC:            // pointers
517 #if PRBOUNDSCHECK
518                                 if (OPB->_int < 0 || OPB->_int >= pr_globaldefs)
519                                 {
520                                         pr_xfunction->profile += profile - startprofile;
521                                         startprofile = profile;
522                                         pr_xstatement = st - pr_statements;
523                                         Host_Error("Progs attempted to write to an invalid indexed global\n");
524                                         return;
525                                 }
526 #endif
527                                 pr_globals[OPB->_int] = OPA->_float;
528                                 break;
529                         case OP_GSTOREP_V:
530 #if PRBOUNDSCHECK
531                                 if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)
532                                 {
533                                         pr_xfunction->profile += profile - startprofile;
534                                         startprofile = profile;
535                                         pr_xstatement = st - pr_statements;
536                                         Host_Error("Progs attempted to write to an invalid indexed global\n");
537                                         return;
538                                 }
539 #endif
540                                 pr_globals[OPB->_int  ] = OPA->vector[0];
541                                 pr_globals[OPB->_int+1] = OPA->vector[1];
542                                 pr_globals[OPB->_int+2] = OPA->vector[2];
543                                 break;
544
545                         case OP_GADDRESS:
546                                 i = OPA->_int + (int) OPB->_float;
547 #if PRBOUNDSCHECK
548                                 if (i < 0 || i >= pr_globaldefs)
549                                 {
550                                         pr_xfunction->profile += profile - startprofile;
551                                         startprofile = profile;
552                                         pr_xstatement = st - pr_statements;
553                                         Host_Error("Progs attempted to address an out of bounds global\n");
554                                         return;
555                                 }
556 #endif
557                                 OPC->_float = pr_globals[i];
558                                 break;
559
560                         case OP_GLOAD_I:
561                         case OP_GLOAD_F:
562                         case OP_GLOAD_FLD:
563                         case OP_GLOAD_ENT:
564                         case OP_GLOAD_S:
565                         case OP_GLOAD_FNC:
566 #if PRBOUNDSCHECK
567                                 if (OPA->_int < 0 || OPA->_int >= pr_globaldefs)
568                                 {
569                                         pr_xfunction->profile += profile - startprofile;
570                                         startprofile = profile;
571                                         pr_xstatement = st - pr_statements;
572                                         Host_Error("Progs attempted to read an invalid indexed global\n");
573                                         return;
574                                 }
575 #endif
576                                 OPC->_float = pr_globals[OPA->_int];
577                                 break;
578
579                         case OP_GLOAD_V:
580 #if PRBOUNDSCHECK
581                                 if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)
582                                 {
583                                         pr_xfunction->profile += profile - startprofile;
584                                         startprofile = profile;
585                                         pr_xstatement = st - pr_statements;
586                                         Host_Error("Progs attempted to read an invalid indexed global\n");
587                                         return;
588                                 }
589 #endif
590                                 OPC->vector[0] = pr_globals[OPA->_int  ];
591                                 OPC->vector[1] = pr_globals[OPA->_int+1];
592                                 OPC->vector[2] = pr_globals[OPA->_int+2];
593                                 break;
594
595                         case OP_BOUNDCHECK:
596                                 if (OPA->_int < 0 || OPA->_int >= st->b)
597                                 {
598                                         pr_xfunction->profile += profile - startprofile;
599                                         startprofile = profile;
600                                         pr_xstatement = st - pr_statements;
601                                         Host_Error("Progs boundcheck failed at line number %d, value is < 0 or >= %d\n", st->b, st->c);
602                                         return;
603                                 }
604                                 break;
605
606 */
607
608                         default:
609                                 prog->xfunction->profile += profile - startprofile;
610                                 startprofile = profile;
611                                 prog->xstatement = st - prog->statements;
612                                 PRVM_ERROR ("Bad opcode %i in %s", st->op, PRVM_NAME);
613                         }
614                 }
615