'Catch' divisions by zero in the VM:
[divverent/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
8 #if PRVMTRACE
9                         PRVM_PrintStatement(st);
10 #endif
11 #if PRVMSTATEMENTPROFILING
12                         prog->statement_profile[st - prog->statements]++;
13 #endif
14
15                         switch (st->op)
16                         {
17                         case OP_ADD_F:
18                                 OPC->_float = OPA->_float + OPB->_float;
19                                 break;
20                         case OP_ADD_V:
21                                 OPC->vector[0] = OPA->vector[0] + OPB->vector[0];
22                                 OPC->vector[1] = OPA->vector[1] + OPB->vector[1];
23                                 OPC->vector[2] = OPA->vector[2] + OPB->vector[2];
24                                 break;
25                         case OP_SUB_F:
26                                 OPC->_float = OPA->_float - OPB->_float;
27                                 break;
28                         case OP_SUB_V:
29                                 OPC->vector[0] = OPA->vector[0] - OPB->vector[0];
30                                 OPC->vector[1] = OPA->vector[1] - OPB->vector[1];
31                                 OPC->vector[2] = OPA->vector[2] - OPB->vector[2];
32                                 break;
33                         case OP_MUL_F:
34                                 OPC->_float = OPA->_float * OPB->_float;
35                                 break;
36                         case OP_MUL_V:
37                                 OPC->_float = OPA->vector[0]*OPB->vector[0] + OPA->vector[1]*OPB->vector[1] + OPA->vector[2]*OPB->vector[2];
38                                 break;
39                         case OP_MUL_FV:
40                                 OPC->vector[0] = OPA->_float * OPB->vector[0];
41                                 OPC->vector[1] = OPA->_float * OPB->vector[1];
42                                 OPC->vector[2] = OPA->_float * OPB->vector[2];
43                                 break;
44                         case OP_MUL_VF:
45                                 OPC->vector[0] = OPB->_float * OPA->vector[0];
46                                 OPC->vector[1] = OPB->_float * OPA->vector[1];
47                                 OPC->vector[2] = OPB->_float * OPA->vector[2];
48                                 break;
49                         case OP_DIV_F:
50                                 if( OPB->_float != 0.0f )
51                                 {
52                                         OPC->_float = OPA->_float / OPB->_float;
53                                 } 
54                                 else 
55                                 {
56                                         if( developer.integer >= 1 ) {
57                                                 VM_Warning( "Attempted division by zero in %s\n", PRVM_NAME );
58                                         }
59                                         OPC->_float = 0.0f;
60                                 }
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 += (st - startst);
155                                         prog->xstatement = st - prog->statements;
156                                         PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
157                                         return;
158                                 }
159 #endif
160                                 ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
161                                 ptr->_int = OPA->_int;
162                                 break;
163                         case OP_STOREP_V:
164 #if PRVMBOUNDSCHECK
165                                 if (OPB->_int < 0 || OPB->_int + 12 > prog->edictareasize)
166                                 {
167                                         prog->xfunction->profile += (st - startst);
168                                         prog->xstatement = st - prog->statements;
169                                         PRVM_ERROR("%s attempted to write to an out of bounds edict (%i)", PRVM_NAME, OPB->_int);
170                                         return;
171                                 }
172 #endif
173                                 ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
174                                 ptr->vector[0] = OPA->vector[0];
175                                 ptr->vector[1] = OPA->vector[1];
176                                 ptr->vector[2] = OPA->vector[2];
177                                 break;
178
179                         case OP_ADDRESS:
180 #if PRVMBOUNDSCHECK
181                                 if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
182                                 {
183                                         prog->xfunction->profile += (st - startst);
184                                         prog->xstatement = st - prog->statements;
185                                         PRVM_ERROR("%s attempted to address an invalid field (%i) in an edict", PRVM_NAME, OPB->_int);
186                                         return;
187                                 }
188 #endif
189                                 if (OPA->edict == 0 && !prog->allowworldwrites)
190                                 {
191                                         prog->xfunction->profile += (st - startst);
192                                         prog->xstatement = st - prog->statements;
193                                         PRVM_ERROR("forbidden assignment to null/world entity in %s", PRVM_NAME);
194                                         return;
195                                 }
196                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
197                                 OPC->_int = (unsigned char *)((int *)ed->fields.vp + OPB->_int) - (unsigned char *)prog->edictsfields;
198                                 break;
199
200                         case OP_LOAD_F:
201                         case OP_LOAD_FLD:
202                         case OP_LOAD_ENT:
203                         case OP_LOAD_S:
204                         case OP_LOAD_FNC:
205 #if PRVMBOUNDSCHECK
206                                 if ((unsigned int)(OPB->_int) >= (unsigned int)(prog->progs->entityfields))
207                                 {
208                                         prog->xfunction->profile += (st - startst);
209                                         prog->xstatement = st - prog->statements;
210                                         PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
211                                         return;
212                                 }
213 #endif
214                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
215                                 OPC->_int = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->_int;
216                                 break;
217
218                         case OP_LOAD_V:
219 #if PRVMBOUNDSCHECK
220                                 if (OPB->_int < 0 || OPB->_int + 2 >= prog->progs->entityfields)
221                                 {
222                                         prog->xfunction->profile += (st - startst);
223                                         prog->xstatement = st - prog->statements;
224                                         PRVM_ERROR("%s attempted to read an invalid field in an edict (%i)", PRVM_NAME, OPB->_int);
225                                         return;
226                                 }
227 #endif
228                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
229                                 OPC->vector[0] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[0];
230                                 OPC->vector[1] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[1];
231                                 OPC->vector[2] = ((prvm_eval_t *)((int *)ed->fields.vp + OPB->_int))->vector[2];
232                                 break;
233
234                 //==================
235
236                         case OP_IFNOT:
237                                 if (!OPA->_int)
238                                 {
239                                         prog->xfunction->profile += (st - startst);
240                                         st += st->b - 1;        // offset the s++
241                                         startst = st;
242                                         if (++jumpcount == 10000000)
243                                         {
244                                                 prog->xstatement = st - prog->statements;
245                                                 PRVM_Profile(1<<30, 1000000);
246                                                 PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME);
247                                         }
248                                 }
249                                 break;
250
251                         case OP_IF:
252                                 if (OPA->_int)
253                                 {
254                                         prog->xfunction->profile += (st - startst);
255                                         st += st->b - 1;        // offset the s++
256                                         startst = st;
257                                         if (++jumpcount == 10000000)
258                                         {
259                                                 prog->xstatement = st - prog->statements;
260                                                 PRVM_Profile(1<<30, 1000000);
261                                                 PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME);
262                                         }
263                                 }
264                                 break;
265
266                         case OP_GOTO:
267                                 prog->xfunction->profile += (st - startst);
268                                 st += st->a - 1;        // offset the s++
269                                 startst = st;
270                                 if (++jumpcount == 10000000)
271                                 {
272                                         prog->xstatement = st - prog->statements;
273                                         PRVM_Profile(1<<30, 1000000);
274                                         PRVM_ERROR("runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", jumpcount, PRVM_NAME);
275                                 }
276                                 break;
277
278                         case OP_CALL0:
279                         case OP_CALL1:
280                         case OP_CALL2:
281                         case OP_CALL3:
282                         case OP_CALL4:
283                         case OP_CALL5:
284                         case OP_CALL6:
285                         case OP_CALL7:
286                         case OP_CALL8:
287                                 prog->xfunction->profile += (st - startst);
288                                 startst = st;
289                                 prog->xstatement = st - prog->statements;
290                                 prog->argc = st->op - OP_CALL0;
291                                 if (!OPA->function)
292                                         PRVM_ERROR("NULL function in %s", PRVM_NAME);
293
294                                 newf = &prog->functions[OPA->function];
295                                 newf->callcount++;
296
297                                 if (newf->first_statement < 0)
298                                 {
299                                         // negative statements are built in functions
300                                         int builtinnumber = -newf->first_statement;
301                                         prog->xfunction->builtinsprofile++;
302                                         if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
303                                                 prog->builtins[builtinnumber]();
304                                         else
305                                                 PRVM_ERROR("No such builtin #%i in %s", builtinnumber, PRVM_NAME);
306                                 }
307                                 else
308                                         st = prog->statements + PRVM_EnterFunction(newf);
309                                 startst = st;
310                                 break;
311
312                         case OP_DONE:
313                         case OP_RETURN:
314                                 prog->xfunction->profile += (st - startst);
315                                 prog->xstatement = st - prog->statements;
316
317                                 prog->globals.generic[OFS_RETURN] = prog->globals.generic[(unsigned short) st->a];
318                                 prog->globals.generic[OFS_RETURN+1] = prog->globals.generic[(unsigned short) st->a+1];
319                                 prog->globals.generic[OFS_RETURN+2] = prog->globals.generic[(unsigned short) st->a+2];
320
321                                 st = prog->statements + PRVM_LeaveFunction();
322                                 startst = st;
323                                 if (prog->depth <= exitdepth)
324                                         return;         // all done
325                                 if (prog->trace != cachedpr_trace)
326                                         goto chooseexecprogram;
327                                 break;
328
329                         case OP_STATE:
330                                 if(prog->flag & PRVM_OP_STATE)
331                                 {
332                                         ed = PRVM_PROG_TO_EDICT(PRVM_G_INT(prog->self->ofs));
333                                         PRVM_E_FLOAT(ed,PRVM_ED_FindField ("nextthink")->ofs) = *prog->time + 0.1;
334                                         PRVM_E_FLOAT(ed,PRVM_ED_FindField ("frame")->ofs) = OPA->_float;
335                                         *(func_t *)((float*)ed->fields.vp + PRVM_ED_FindField ("think")->ofs) = OPB->function;
336                                 }
337                                 else
338                                 {
339                                         prog->xfunction->profile += (st - startst);
340                                         prog->xstatement = st - prog->statements;
341                                         PRVM_ERROR("OP_STATE not supported by %s", PRVM_NAME);
342                                 }
343                                 break;
344
345 // LordHavoc: to be enabled when Progs version 7 (or whatever it will be numbered) is finalized
346 /*
347                         case OP_ADD_I:
348                                 OPC->_int = OPA->_int + OPB->_int;
349                                 break;
350                         case OP_ADD_IF:
351                                 OPC->_int = OPA->_int + (int) OPB->_float;
352                                 break;
353                         case OP_ADD_FI:
354                                 OPC->_float = OPA->_float + (float) OPB->_int;
355                                 break;
356                         case OP_SUB_I:
357                                 OPC->_int = OPA->_int - OPB->_int;
358                                 break;
359                         case OP_SUB_IF:
360                                 OPC->_int = OPA->_int - (int) OPB->_float;
361                                 break;
362                         case OP_SUB_FI:
363                                 OPC->_float = OPA->_float - (float) OPB->_int;
364                                 break;
365                         case OP_MUL_I:
366                                 OPC->_int = OPA->_int * OPB->_int;
367                                 break;
368                         case OP_MUL_IF:
369                                 OPC->_int = OPA->_int * (int) OPB->_float;
370                                 break;
371                         case OP_MUL_FI:
372                                 OPC->_float = OPA->_float * (float) OPB->_int;
373                                 break;
374                         case OP_MUL_VI:
375                                 OPC->vector[0] = (float) OPB->_int * OPA->vector[0];
376                                 OPC->vector[1] = (float) OPB->_int * OPA->vector[1];
377                                 OPC->vector[2] = (float) OPB->_int * OPA->vector[2];
378                                 break;
379                         case OP_DIV_VF:
380                                 {
381                                         float temp = 1.0f / OPB->_float;
382                                         OPC->vector[0] = temp * OPA->vector[0];
383                                         OPC->vector[1] = temp * OPA->vector[1];
384                                         OPC->vector[2] = temp * OPA->vector[2];
385                                 }
386                                 break;
387                         case OP_DIV_I:
388                                 OPC->_int = OPA->_int / OPB->_int;
389                                 break;
390                         case OP_DIV_IF:
391                                 OPC->_int = OPA->_int / (int) OPB->_float;
392                                 break;
393                         case OP_DIV_FI:
394                                 OPC->_float = OPA->_float / (float) OPB->_int;
395                                 break;
396                         case OP_CONV_IF:
397                                 OPC->_float = OPA->_int;
398                                 break;
399                         case OP_CONV_FI:
400                                 OPC->_int = OPA->_float;
401                                 break;
402                         case OP_BITAND_I:
403                                 OPC->_int = OPA->_int & OPB->_int;
404                                 break;
405                         case OP_BITOR_I:
406                                 OPC->_int = OPA->_int | OPB->_int;
407                                 break;
408                         case OP_BITAND_IF:
409                                 OPC->_int = OPA->_int & (int)OPB->_float;
410                                 break;
411                         case OP_BITOR_IF:
412                                 OPC->_int = OPA->_int | (int)OPB->_float;
413                                 break;
414                         case OP_BITAND_FI:
415                                 OPC->_float = (int)OPA->_float & OPB->_int;
416                                 break;
417                         case OP_BITOR_FI:
418                                 OPC->_float = (int)OPA->_float | OPB->_int;
419                                 break;
420                         case OP_GE_I:
421                                 OPC->_float = OPA->_int >= OPB->_int;
422                                 break;
423                         case OP_LE_I:
424                                 OPC->_float = OPA->_int <= OPB->_int;
425                                 break;
426                         case OP_GT_I:
427                                 OPC->_float = OPA->_int > OPB->_int;
428                                 break;
429                         case OP_LT_I:
430                                 OPC->_float = OPA->_int < OPB->_int;
431                                 break;
432                         case OP_AND_I:
433                                 OPC->_float = OPA->_int && OPB->_int;
434                                 break;
435                         case OP_OR_I:
436                                 OPC->_float = OPA->_int || OPB->_int;
437                                 break;
438                         case OP_GE_IF:
439                                 OPC->_float = (float)OPA->_int >= OPB->_float;
440                                 break;
441                         case OP_LE_IF:
442                                 OPC->_float = (float)OPA->_int <= OPB->_float;
443                                 break;
444                         case OP_GT_IF:
445                                 OPC->_float = (float)OPA->_int > OPB->_float;
446                                 break;
447                         case OP_LT_IF:
448                                 OPC->_float = (float)OPA->_int < OPB->_float;
449                                 break;
450                         case OP_AND_IF:
451                                 OPC->_float = (float)OPA->_int && OPB->_float;
452                                 break;
453                         case OP_OR_IF:
454                                 OPC->_float = (float)OPA->_int || OPB->_float;
455                                 break;
456                         case OP_GE_FI:
457                                 OPC->_float = OPA->_float >= (float)OPB->_int;
458                                 break;
459                         case OP_LE_FI:
460                                 OPC->_float = OPA->_float <= (float)OPB->_int;
461                                 break;
462                         case OP_GT_FI:
463                                 OPC->_float = OPA->_float > (float)OPB->_int;
464                                 break;
465                         case OP_LT_FI:
466                                 OPC->_float = OPA->_float < (float)OPB->_int;
467                                 break;
468                         case OP_AND_FI:
469                                 OPC->_float = OPA->_float && (float)OPB->_int;
470                                 break;
471                         case OP_OR_FI:
472                                 OPC->_float = OPA->_float || (float)OPB->_int;
473                                 break;
474                         case OP_NOT_I:
475                                 OPC->_float = !OPA->_int;
476                                 break;
477                         case OP_EQ_I:
478                                 OPC->_float = OPA->_int == OPB->_int;
479                                 break;
480                         case OP_EQ_IF:
481                                 OPC->_float = (float)OPA->_int == OPB->_float;
482                                 break;
483                         case OP_EQ_FI:
484                                 OPC->_float = OPA->_float == (float)OPB->_int;
485                                 break;
486                         case OP_NE_I:
487                                 OPC->_float = OPA->_int != OPB->_int;
488                                 break;
489                         case OP_NE_IF:
490                                 OPC->_float = (float)OPA->_int != OPB->_float;
491                                 break;
492                         case OP_NE_FI:
493                                 OPC->_float = OPA->_float != (float)OPB->_int;
494                                 break;
495                         case OP_STORE_I:
496                                 OPB->_int = OPA->_int;
497                                 break;
498                         case OP_STOREP_I:
499 #if PRBOUNDSCHECK
500                                 if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
501                                 {
502                                         prog->xfunction->profile += (st - startst);
503                                         prog->xstatement = st - prog->statements;
504                                         PRVM_ERROR ("%s Progs attempted to write to an out of bounds edict", PRVM_NAME);
505                                         return;
506                                 }
507 #endif
508                                 ptr = (prvm_eval_t *)((unsigned char *)prog->edictsfields + OPB->_int);
509                                 ptr->_int = OPA->_int;
510                                 break;
511                         case OP_LOAD_I:
512 #if PRBOUNDSCHECK
513                                 if (OPA->edict < 0 || OPA->edict >= pr_edictareasize)
514                                 {
515                                         prog->xfunction->profile += (st - startst);
516                                         prog->xstatement = st - prog->statements;
517                                         PRVM_ERROR ("%s Progs attempted to read an out of bounds edict number", PRVM_NAME);
518                                         return;
519                                 }
520                                 if (OPB->_int < 0 || OPB->_int >= progs->entityfields)
521                                 {
522                                         prog->xfunction->profile += (st - startst);
523                                         prog->xstatement = st - prog->statements;
524                                         PRVM_ERROR ("%s Progs attempted to read an invalid field in an edict", PRVM_NAME);
525                                         return;
526                                 }
527 #endif
528                                 ed = PRVM_PROG_TO_EDICT(OPA->edict);
529                                 OPC->_int = ((prvm_eval_t *)((int *)ed->v + OPB->_int))->_int;
530                                 break;
531
532                         case OP_GSTOREP_I:
533                         case OP_GSTOREP_F:
534                         case OP_GSTOREP_ENT:
535                         case OP_GSTOREP_FLD:            // integers
536                         case OP_GSTOREP_S:
537                         case OP_GSTOREP_FNC:            // pointers
538 #if PRBOUNDSCHECK
539                                 if (OPB->_int < 0 || OPB->_int >= pr_globaldefs)
540                                 {
541                                         prog->xfunction->profile += (st - startst);
542                                         prog->xstatement = st - prog->statements;
543                                         PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME);
544                                         return;
545                                 }
546 #endif
547                                 pr_globals[OPB->_int] = OPA->_float;
548                                 break;
549                         case OP_GSTOREP_V:
550 #if PRBOUNDSCHECK
551                                 if (OPB->_int < 0 || OPB->_int + 2 >= pr_globaldefs)
552                                 {
553                                         prog->xfunction->profile += (st - startst);
554                                         prog->xstatement = st - prog->statements;
555                                         PRVM_ERROR ("%s Progs attempted to write to an invalid indexed global", PRVM_NAME);
556                                         return;
557                                 }
558 #endif
559                                 pr_globals[OPB->_int  ] = OPA->vector[0];
560                                 pr_globals[OPB->_int+1] = OPA->vector[1];
561                                 pr_globals[OPB->_int+2] = OPA->vector[2];
562                                 break;
563
564                         case OP_GADDRESS:
565                                 i = OPA->_int + (int) OPB->_float;
566 #if PRBOUNDSCHECK
567                                 if (i < 0 || i >= pr_globaldefs)
568                                 {
569                                         prog->xfunction->profile += (st - startst);
570                                         prog->xstatement = st - prog->statements;
571                                         PRVM_ERROR ("%s Progs attempted to address an out of bounds global", PRVM_NAME);
572                                         return;
573                                 }
574 #endif
575                                 OPC->_float = pr_globals[i];
576                                 break;
577
578                         case OP_GLOAD_I:
579                         case OP_GLOAD_F:
580                         case OP_GLOAD_FLD:
581                         case OP_GLOAD_ENT:
582                         case OP_GLOAD_S:
583                         case OP_GLOAD_FNC:
584 #if PRBOUNDSCHECK
585                                 if (OPA->_int < 0 || OPA->_int >= pr_globaldefs)
586                                 {
587                                         prog->xfunction->profile += (st - startst);
588                                         prog->xstatement = st - prog->statements;
589                                         PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME);
590                                         return;
591                                 }
592 #endif
593                                 OPC->_float = pr_globals[OPA->_int];
594                                 break;
595
596                         case OP_GLOAD_V:
597 #if PRBOUNDSCHECK
598                                 if (OPA->_int < 0 || OPA->_int + 2 >= pr_globaldefs)
599                                 {
600                                         prog->xfunction->profile += (st - startst);
601                                         prog->xstatement = st - prog->statements;
602                                         PRVM_ERROR ("%s Progs attempted to read an invalid indexed global", PRVM_NAME);
603                                         return;
604                                 }
605 #endif
606                                 OPC->vector[0] = pr_globals[OPA->_int  ];
607                                 OPC->vector[1] = pr_globals[OPA->_int+1];
608                                 OPC->vector[2] = pr_globals[OPA->_int+2];
609                                 break;
610
611                         case OP_BOUNDCHECK:
612                                 if (OPA->_int < 0 || OPA->_int >= st->b)
613                                 {
614                                         prog->xfunction->profile += (st - startst);
615                                         prog->xstatement = st - prog->statements;
616                                         PRVM_ERROR ("%s Progs boundcheck failed at line number %d, value is < 0 or >= %d", PRVM_NAME, st->b, st->c);
617                                         return;
618                                 }
619                                 break;
620
621 */
622
623                         default:
624                                 prog->xfunction->profile += (st - startst);
625                                 prog->xstatement = st - prog->statements;
626                                 PRVM_ERROR ("Bad opcode %i in %s", st->op, PRVM_NAME);
627                         }
628                 }
629