DarkPlaces
Game engine based on the Quake 1 engine by id Software, developed by LadyHavoc
 
prvm_execprogram.h
Go to the documentation of this file.
2int i;
5// NEED to reset startst after calling this! startst may or may not be clobbered!
6#define ADVANCE_PROFILE_BEFORE_JUMP() \
7 prog->xfunction->profile += (st - startst); \
8 if (prvm_statementprofiling.integer || (prvm_coverage.integer & 4)) { \
9 /* All statements from startst+1 to st have been hit. */ \
10 while (++startst <= st) { \
11 if (prog->statement_profile[startst - cached_statements]++ == 0 && (prvm_coverage.integer & 4)) \
12 PRVM_StatementCoverageEvent(prog, prog->xfunction, startst - cached_statements); \
13 } \
14 /* Observe: startst now is clobbered (now at st+1)! */ \
15 }
16
17#ifdef PRVMTIMEPROFILING
18#define PRE_ERROR() \
19 ADVANCE_PROFILE_BEFORE_JUMP(); \
20 prog->xstatement = st - cached_statements; \
21 tm = Sys_DirtyTime(); \
22 prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0; \
23 startst = st; \
24 starttm = tm
25#else
26#define PRE_ERROR() \
27 ADVANCE_PROFILE_BEFORE_JUMP(); \
28 prog->xstatement = st - cached_statements; \
29 startst = st
30#endif
31
32// This code isn't #ifdef/#define protectable, don't try.
33
34#if HAVE_COMPUTED_GOTOS && !(PRVMSLOWINTERPRETER || PRVMTIMEPROFILING)
35 // NOTE: Due to otherwise duplicate labels, only ONE interpreter path may
36 // ever hit this!
37# define USE_COMPUTED_GOTOS 1
38#endif
39
40#if USE_COMPUTED_GOTOS
41 // Must exactly match opcode_e enum in pr_comp.h
42 static const void *dispatchtable[] = {
43 &&handle_OP_DONE,
44 &&handle_OP_MUL_F,
45 &&handle_OP_MUL_V,
46 &&handle_OP_MUL_FV,
47 &&handle_OP_MUL_VF,
48 &&handle_OP_DIV_F,
49 &&handle_OP_ADD_F,
50 &&handle_OP_ADD_V,
51 &&handle_OP_SUB_F,
52 &&handle_OP_SUB_V,
53
54 &&handle_OP_EQ_F,
55 &&handle_OP_EQ_V,
56 &&handle_OP_EQ_S,
57 &&handle_OP_EQ_E,
58 &&handle_OP_EQ_FNC,
59
60 &&handle_OP_NE_F,
61 &&handle_OP_NE_V,
62 &&handle_OP_NE_S,
63 &&handle_OP_NE_E,
64 &&handle_OP_NE_FNC,
65
66 &&handle_OP_LE_F,
67 &&handle_OP_GE_F,
68 &&handle_OP_LT_F,
69 &&handle_OP_GT_F,
70
71 &&handle_OP_LOAD_F,
72 &&handle_OP_LOAD_V,
73 &&handle_OP_LOAD_S,
74 &&handle_OP_LOAD_ENT,
75 &&handle_OP_LOAD_FLD,
76 &&handle_OP_LOAD_FNC,
77
78 &&handle_OP_ADDRESS,
79
80 &&handle_OP_STORE_F,
81 &&handle_OP_STORE_V,
82 &&handle_OP_STORE_S,
83 &&handle_OP_STORE_ENT,
84 &&handle_OP_STORE_FLD,
85 &&handle_OP_STORE_FNC,
86
87 &&handle_OP_STOREP_F,
88 &&handle_OP_STOREP_V,
89 &&handle_OP_STOREP_S,
90 &&handle_OP_STOREP_ENT,
91 &&handle_OP_STOREP_FLD,
92 &&handle_OP_STOREP_FNC,
93
94 &&handle_OP_RETURN,
95 &&handle_OP_NOT_F,
96 &&handle_OP_NOT_V,
97 &&handle_OP_NOT_S,
98 &&handle_OP_NOT_ENT,
99 &&handle_OP_NOT_FNC,
100 &&handle_OP_IF,
101 &&handle_OP_IFNOT,
102 &&handle_OP_CALL0,
103 &&handle_OP_CALL1,
104 &&handle_OP_CALL2,
105 &&handle_OP_CALL3,
106 &&handle_OP_CALL4,
107 &&handle_OP_CALL5,
108 &&handle_OP_CALL6,
109 &&handle_OP_CALL7,
110 &&handle_OP_CALL8,
111 &&handle_OP_STATE,
112 &&handle_OP_GOTO,
113 &&handle_OP_AND_F,
114 &&handle_OP_OR_F,
115
116 &&handle_OP_BITAND_F,
117 &&handle_OP_BITOR_F,
118
119 NULL,
120 NULL,
121 NULL,
122 NULL,
123 NULL,
124 NULL,
125 NULL,
126 NULL,
127 NULL,
128 NULL,
129 NULL,
130 NULL,
131 NULL,
132 NULL,
133 NULL,
134 NULL,
135 NULL,
136 NULL,
137 NULL,
138 NULL,
139 NULL,
140 NULL,
141 NULL,
142 NULL,
143 NULL,
144 NULL,
145 NULL,
146 NULL,
147 NULL,
148 NULL,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 NULL,
155 NULL,
156 NULL,
157 NULL,
158 NULL,
159 NULL,
160 NULL,
161 NULL,
162 NULL,
163 NULL,
164 NULL,
165 NULL,
166
167 &&handle_OP_STORE_I,
168
169 NULL,
170 NULL,
171
172 &&handle_OP_ADD_I,
173 &&handle_OP_ADD_FI,
174 &&handle_OP_ADD_IF,
175
176 &&handle_OP_SUB_I,
177 &&handle_OP_SUB_FI,
178 &&handle_OP_SUB_IF,
179 &&handle_OP_CONV_ITOF,
180 &&handle_OP_CONV_FTOI,
181
182 NULL,
183 NULL,
184
185 &&handle_OP_LOAD_I,
186 &&handle_OP_STOREP_I,
187
188 NULL,
189 NULL,
190
191 &&handle_OP_BITAND_I,
192 &&handle_OP_BITOR_I,
193
194 &&handle_OP_MUL_I,
195 &&handle_OP_DIV_I,
196 &&handle_OP_EQ_I,
197 &&handle_OP_NE_I,
198
199 NULL,
200 NULL,
201
202 &&handle_OP_NOT_I,
203
204 &&handle_OP_DIV_VF,
205
206 NULL,
207 &&handle_OP_RSHIFT_I,
208 &&handle_OP_LSHIFT_I,
209
210 &&handle_OP_GLOBALADDRESS,
211 &&handle_OP_ADD_PIW,
212 &&handle_OP_LOADA_F,
213 &&handle_OP_LOADA_V,
214 &&handle_OP_LOADA_S,
215 &&handle_OP_LOADA_ENT,
216 &&handle_OP_LOADA_FLD,
217 &&handle_OP_LOADA_FNC,
218 &&handle_OP_LOADA_I,
219
220 &&handle_OP_STORE_P,
221 &&handle_OP_LOAD_P,
222
223 &&handle_OP_LOADP_F,
224 &&handle_OP_LOADP_V,
225 &&handle_OP_LOADP_S,
226 &&handle_OP_LOADP_ENT,
227 &&handle_OP_LOADP_FLD,
228 &&handle_OP_LOADP_FNC,
229 &&handle_OP_LOADP_I,
230
231 &&handle_OP_LE_I,
232 &&handle_OP_GE_I,
233 &&handle_OP_LT_I,
234 &&handle_OP_GT_I,
235
236 &&handle_OP_LE_IF,
237 &&handle_OP_GE_IF,
238 &&handle_OP_LT_IF,
239 &&handle_OP_GT_IF,
240
241 &&handle_OP_LE_FI,
242 &&handle_OP_GE_FI,
243 &&handle_OP_LT_FI,
244 &&handle_OP_GT_FI,
245
246 &&handle_OP_EQ_IF,
247 &&handle_OP_EQ_FI,
248
249 NULL,
250 NULL,
251 NULL,
252 NULL,
253
254 &&handle_OP_MUL_IF,
255 &&handle_OP_MUL_FI,
256 &&handle_OP_MUL_VI,
257
258 NULL,
259
260 &&handle_OP_DIV_IF,
261 &&handle_OP_DIV_FI,
262 &&handle_OP_BITAND_IF,
263 &&handle_OP_BITOR_IF,
264 &&handle_OP_BITAND_FI,
265 &&handle_OP_BITOR_FI,
266 &&handle_OP_AND_I,
267 &&handle_OP_OR_I,
268 &&handle_OP_AND_IF,
269 &&handle_OP_OR_IF,
270 &&handle_OP_AND_FI,
271 &&handle_OP_OR_FI,
272 &&handle_OP_NE_IF,
273 &&handle_OP_NE_FI,
274
275 &&handle_OP_GSTOREP_I,
276 &&handle_OP_GSTOREP_F,
277 &&handle_OP_GSTOREP_ENT,
278 &&handle_OP_GSTOREP_FLD,
279 &&handle_OP_GSTOREP_S,
280 &&handle_OP_GSTOREP_FNC,
281 &&handle_OP_GSTOREP_V,
282 &&handle_OP_GADDRESS,
283 &&handle_OP_GLOAD_I,
284 &&handle_OP_GLOAD_F,
285 &&handle_OP_GLOAD_FLD,
286 &&handle_OP_GLOAD_ENT,
287 &&handle_OP_GLOAD_S,
288 &&handle_OP_GLOAD_FNC,
289 &&handle_OP_BOUNDCHECK,
290
291 NULL,
292 NULL,
293 NULL,
294 NULL,
295
296 &&handle_OP_GLOAD_V,
297
298 NULL,
299 NULL,
300
301 NULL,
302 NULL,
303 NULL,
304 NULL,
305
306
307 NULL,
308 NULL,
309
310
311 &&handle_OP_LE_U,
312 &&handle_OP_LT_U,
313 &&handle_OP_DIV_U,
314 &&handle_OP_RSHIFT_U,
315 };
316#define DISPATCH_OPCODE() \
317 goto *dispatchtable[(++st)->op]
318#define HANDLE_OPCODE(opcode) handle_##opcode
319
320 DISPATCH_OPCODE(); // jump to first opcode
321#else // USE_COMPUTED_GOTOS
322#define DISPATCH_OPCODE() break
323#define HANDLE_OPCODE(opcode) case opcode
324
325#if PRVMSLOWINTERPRETER
326 {
327 if (prog->watch_global_type != ev_void)
328 {
329 prvm_eval_t *g = PRVM_GLOBALFIELDVALUE(prog->watch_global);
330 prog->xstatement = st + 1 - cached_statements;
331 PRVM_Watchpoint(prog, 1, "Global watchpoint hit by engine", prog->watch_global_type, &prog->watch_global_value, g);
332 }
333 if (prog->watch_field_type != ev_void && prog->watch_edict < prog->max_edicts)
334 {
335 prvm_eval_t *g = PRVM_EDICTFIELDVALUE(prog->edicts + prog->watch_edict, prog->watch_field);
336 prog->xstatement = st + 1 - cached_statements;
337 PRVM_Watchpoint(prog, 1, "Entityfield watchpoint hit by engine", prog->watch_field_type, &prog->watch_edictfield_value, g);
338 }
339 }
340#endif
341
342 while (1)
343 {
344 st++;
345#endif // USE_COMPUTED_GOTOS
346
347#if !USE_COMPUTED_GOTOS
348
349#if PRVMSLOWINTERPRETER
350 if (prog->trace)
351 PRVM_PrintStatement(prog, st);
352 if (prog->break_statement >= 0)
353 if ((st - cached_statements) == prog->break_statement)
354 {
355 prog->xstatement = st - cached_statements;
356 PRVM_Breakpoint(prog, prog->break_stack_index, "Breakpoint hit");
357 }
358#endif
359 switch (st->op)
360 {
361#endif
363 OPC->_float = OPA->_float + OPB->_float;
366 OPC->vector[0] = OPA->vector[0] + OPB->vector[0];
367 OPC->vector[1] = OPA->vector[1] + OPB->vector[1];
368 OPC->vector[2] = OPA->vector[2] + OPB->vector[2];
371 OPC->_float = OPA->_float - OPB->_float;
374 OPC->vector[0] = OPA->vector[0] - OPB->vector[0];
375 OPC->vector[1] = OPA->vector[1] - OPB->vector[1];
376 OPC->vector[2] = OPA->vector[2] - OPB->vector[2];
379 OPC->_float = OPA->_float * OPB->_float;
382 OPC->_float = OPA->vector[0]*OPB->vector[0] + OPA->vector[1]*OPB->vector[1] + OPA->vector[2]*OPB->vector[2];
385 tempfloat = OPA->_float;
386 OPC->vector[0] = tempfloat * OPB->vector[0];
387 OPC->vector[1] = tempfloat * OPB->vector[1];
388 OPC->vector[2] = tempfloat * OPB->vector[2];
391 tempfloat = OPB->_float;
392 OPC->vector[0] = tempfloat * OPA->vector[0];
393 OPC->vector[1] = tempfloat * OPA->vector[1];
394 OPC->vector[2] = tempfloat * OPA->vector[2];
397 if( OPB->_float == 0.0f )
398 {
399 PRE_ERROR();
400 VM_Warning(prog, "Attempted division of %f by zero\n", OPA->_float);
402 {
403 OPC->_float = 0;
405 }
406 }
407 OPC->_float = OPA->_float / OPB->_float;
410 OPC->_float = (prvm_int_t)OPA->_float & (prvm_int_t)OPB->_float;
413 OPC->_float = (prvm_int_t)OPA->_float | (prvm_int_t)OPB->_float;
416 OPC->_float = OPA->_float >= OPB->_float;
419 OPC->_float = OPA->_float <= OPB->_float;
422 OPC->_float = OPA->_float > OPB->_float;
425 OPC->_float = OPA->_float < OPB->_float;
428 OPC->_float = PRVM_FLOAT_IS_TRUE_FOR_INT(OPA->_int) && PRVM_FLOAT_IS_TRUE_FOR_INT(OPB->_int); // TODO change this back to float, and add AND_I to be used by fteqcc for anything not a float
431 OPC->_float = PRVM_FLOAT_IS_TRUE_FOR_INT(OPA->_int) || PRVM_FLOAT_IS_TRUE_FOR_INT(OPB->_int); // TODO change this back to float, and add OR_I to be used by fteqcc for anything not a float
434 OPC->_float = !PRVM_FLOAT_IS_TRUE_FOR_INT(OPA->_int);
437 OPC->_float = !OPA->vector[0] && !OPA->vector[1] && !OPA->vector[2];
440 OPC->_float = !OPA->string || !*PRVM_GetString(prog, OPA->string);
443 OPC->_float = !OPA->function;
446 OPC->_float = (OPA->edict == 0);
449 OPC->_float = OPA->_float == OPB->_float;
452 OPC->_float = (OPA->vector[0] == OPB->vector[0]) && (OPA->vector[1] == OPB->vector[1]) && (OPA->vector[2] == OPB->vector[2]);
455 OPC->_float = !strcmp(PRVM_GetString(prog, OPA->string),PRVM_GetString(prog, OPB->string));
458 OPC->_float = OPA->_int == OPB->_int;
461 OPC->_float = OPA->function == OPB->function;
464 OPC->_float = OPA->_float != OPB->_float;
467 OPC->_float = (OPA->vector[0] != OPB->vector[0]) || (OPA->vector[1] != OPB->vector[1]) || (OPA->vector[2] != OPB->vector[2]);
470 OPC->_float = strcmp(PRVM_GetString(prog, OPA->string),PRVM_GetString(prog, OPB->string));
473 OPC->_float = OPA->_int != OPB->_int;
476 OPC->_float = OPA->function != OPB->function;
478
479 //==================
482 HANDLE_OPCODE(OP_STORE_FLD): // integers
483 HANDLE_OPCODE(OP_STORE_FNC): // pointers
484 OPB->_int = OPA->_int;
487 // refresh the garbage collection on the string - this guards
488 // against a certain sort of repeated migration to earlier
489 // points in the scan that could otherwise result in the string
490 // being freed for being unused
492 PRVM_GetString(prog, OPA->_int);
493 OPB->_int = OPA->_int;
496 OPB->ivector[0] = OPA->ivector[0];
497 OPB->ivector[1] = OPA->ivector[1];
498 OPB->ivector[2] = OPA->ivector[2];
500
503 HANDLE_OPCODE(OP_STOREP_FLD): // integers
504 HANDLE_OPCODE(OP_STOREP_FNC): // pointers
505 addr = OPB->_uint + OPC->_uint;
506 if ((ofs = addr - cached_vmentity1start) < cached_entityfieldsarea_entityfields)
507 {
508 // OK entity write.
509 ptr = (prvm_eval_t *)(cached_edictsfields_entity1 + ofs);
510 }
511 else if ((ofs = addr - cached_vmglobal1) < cached_vmglobals_1)
512 {
513 // OK global write.
514 ptr = (prvm_eval_t *)(global1 + ofs);
515 }
516 else if ((ofs = addr - cached_vmentity0start) < cached_entityfields)
517 {
518 if (!cached_allowworldwrites)
519 {
520 PRE_ERROR();
521 VM_Warning(prog, "Attempted assignment to world.%s (edictnum 0 field %"PRVM_PRIi"+%"PRVM_PRIi")\n", PRVM_GetString(prog, PRVM_ED_FieldAtOfs(prog, ofs)->s_name), OPB->_int, OPC->_int);
522 // Perform entity write anyway.
523 }
524 ptr = (prvm_eval_t *)(cached_edictsfields + ofs);
525 }
526 else
527 {
528 PRE_ERROR();
529 prog->error_cmd("%s attempted to write to an out of bounds address %"PRVM_PRIu"+%"PRVM_PRIi"", prog->name, OPB->_uint, OPC->_int);
530 goto cleanup;
531 }
532 ptr->_int = OPA->_int;
535 addr = OPB->_uint + OPC->_uint;
536 if ((ofs = addr - cached_vmentity1start) < cached_entityfieldsarea_entityfields)
537 {
538 // OK entity write.
539 ptr = (prvm_eval_t *)(cached_edictsfields_entity1 + ofs);
540 }
541 else if ((ofs = addr - cached_vmglobal1) < cached_vmglobals_1)
542 {
543 // OK global write.
544 ptr = (prvm_eval_t *)(global1 + ofs);
545 }
546 else if ((ofs = addr - cached_vmentity0start) < cached_entityfields)
547 {
548 if (!cached_allowworldwrites)
549 {
550 PRE_ERROR();
551 VM_Warning(prog, "Attempted assignment to world.%s (edictnum 0 field %"PRVM_PRIi"+%"PRVM_PRIi")\n", PRVM_GetString(prog, PRVM_ED_FieldAtOfs(prog, ofs)->s_name), OPB->_int, OPC->_int);
552 // Perform entity write anyway.
553 }
554 ptr = (prvm_eval_t *)(cached_edictsfields + ofs);
555 }
556 else
557 {
558 PRE_ERROR();
559 prog->error_cmd("%s attempted to write to an out of bounds address %"PRVM_PRIu"+%"PRVM_PRIi"", prog->name, OPB->_uint, OPC->_int);
560 goto cleanup;
561 }
562 // refresh the garbage collection on the string - this guards
563 // against a certain sort of repeated migration to earlier
564 // points in the scan that could otherwise result in the string
565 // being freed for being unused
567 PRVM_GetString(prog, OPA->_int);
568 ptr->_int = OPA->_int;
571 addr = OPB->_uint + OPC->_uint;
572 if ((ofs = addr - cached_vmentity1start) < cached_entityfieldsarea_entityfields_2)
573 {
574 // OK entity write.
575 ptr = (prvm_eval_t *)(cached_edictsfields_entity1 + ofs);
576 }
577 else if ((ofs = addr - cached_vmglobal1) < cached_vmglobals_3)
578 {
579 // OK global write.
580 ptr = (prvm_eval_t *)(global1 + ofs);
581 }
582 else if ((ofs = addr - cached_vmentity0start) < cached_entityfields_2)
583 {
584 if (!cached_allowworldwrites)
585 {
586 PRE_ERROR();
587 VM_Warning(prog, "Attempted assignment to world.%s (edictnum 0 field %"PRVM_PRIi"+%"PRVM_PRIi")\n", PRVM_GetString(prog, PRVM_ED_FieldAtOfs(prog, ofs)->s_name), OPB->_int, OPC->_int);
588 // Perform entity write anyway.
589 }
590 ptr = (prvm_eval_t *)(cached_edictsfields + ofs);
591 }
592 else
593 {
594 PRE_ERROR();
595 prog->error_cmd("%s attempted to write to an out of bounds address %"PRVM_PRIu"+%"PRVM_PRIi"", prog->name, OPB->_uint, OPC->_int);
596 goto cleanup;
597 }
598 ptr->ivector[0] = OPA->ivector[0];
599 ptr->ivector[1] = OPA->ivector[1];
600 ptr->ivector[2] = OPA->ivector[2];
602
604 if ((prvm_uint_t)OPA->edict >= cached_max_edicts)
605 {
606 PRE_ERROR();
607 prog->error_cmd("%s attempted to address an out of bounds edict number", prog->name);
608 goto cleanup;
609 }
610 if (OPB->_uint >= cached_entityfields)
611 {
612 PRE_ERROR();
613 prog->error_cmd("%s attempted to address an invalid field (%"PRVM_PRIu") in an edict", prog->name, OPB->_uint);
614 goto cleanup;
615 }
616#if 0
617 if (OPA->edict == 0 && !cached_allowworldwrites)
618 {
619 PRE_ERROR();
620 prog->error_cmd("Forbidden assignment to world (edictnum 0) in %s", prog->name);
621 goto cleanup;
622 }
623#endif
624 OPC->_int = cached_vmentity0start + OPA->edict * cached_entityfields + OPB->_int;
626
632 if ((prvm_uint_t)OPA->edict >= cached_max_edicts)
633 {
634 PRE_ERROR();
635 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
636 goto cleanup;
637 }
638 if (OPB->_uint >= cached_entityfields)
639 {
640 PRE_ERROR();
641 prog->error_cmd("%s attempted to read an invalid field in an edict (%"PRVM_PRIu")", prog->name, OPB->_uint);
642 goto cleanup;
643 }
644 ed = PRVM_PROG_TO_EDICT(OPA->edict);
645 OPC->_int = ((prvm_eval_t *)(ed->fields.ip + OPB->_int))->_int;
648 if ((prvm_uint_t)OPA->edict >= cached_max_edicts)
649 {
650 PRE_ERROR();
651 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
652 goto cleanup;
653 }
654 if (OPB->_uint >= cached_entityfields)
655 {
656 PRE_ERROR();
657 prog->error_cmd("%s attempted to read an invalid field in an edict (%"PRVM_PRIu")", prog->name, OPB->_uint);
658 goto cleanup;
659 }
660 ed = PRVM_PROG_TO_EDICT(OPA->edict);
661 OPC->_int = ((prvm_eval_t *)(ed->fields.ip + OPB->_int))->_int;
662 // refresh the garbage collection on the string - this guards
663 // against a certain sort of repeated migration to earlier
664 // points in the scan that could otherwise result in the string
665 // being freed for being unused
667 PRVM_GetString(prog, OPC->_int);
669
671 if ((prvm_uint_t)OPA->edict >= cached_max_edicts)
672 {
673 PRE_ERROR();
674 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
675 goto cleanup;
676 }
677 if (OPB->_uint >= cached_entityfields_2)
678 {
679 PRE_ERROR();
680 prog->error_cmd("%s attempted to read an invalid field in an edict (%"PRVM_PRIu")", prog->name, OPB->_uint);
681 goto cleanup;
682 }
683 ed = PRVM_PROG_TO_EDICT(OPA->edict);
684 ptr = (prvm_eval_t *)(ed->fields.ip + OPB->_int);
685 OPC->ivector[0] = ptr->ivector[0];
686 OPC->ivector[1] = ptr->ivector[1];
687 OPC->ivector[2] = ptr->ivector[2];
689
690 //==================
691
693 //spike FIXME -- dp redefined IFNOT[_I] as IFNOT_F, which breaks if(0x80000000)
694 //spike FIXME -- you should add separate IFNOT_I/IFNOT_F opcodes and remap IFNOT_I to ITNOT_F in v6 progs for compat.
695 if(!FLOAT_IS_TRUE_FOR_INT(OPA->_int))
696 // TODO add an "int-if", and change this one to OPA->_float
697 // although mostly unneeded, thanks to the only float being false being 0x0 and 0x80000000 (negative zero)
698 // and entity, string, field values can never have that value
699 {
701 st += st->operand[1] - 1; // offset the st++
702 startst = st;
703 // no bounds check needed, it is done when loading progs
704 if (++jumpcount == 10000000 && prvm_runawaycheck)
705 {
706 prog->xstatement = st - cached_statements;
707 PRVM_Profile(prog, 1<<30, 1000000, 0);
708 prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
709 }
710 }
712
714 //spike FIXME -- dp redefined IF[_I] as IF_F
715 // TODO: plan is:
716 // - Add IF_F, IFNOT_F.
717 // - Rename this to IF_I, IFNOT_I.
718 // - Add sv_gameplayfix variable to remap IF_I and IFNOT_I to IF_F and IFNOT_F on progs load.
719 // - Define this fix for Nexuiz.
720 // - Add generation of IF_F, IFNOT_F instructions to gmqcc.
721 // - Move Xonotic to that.
722 if(FLOAT_IS_TRUE_FOR_INT(OPA->_int))
723 // TODO add an "int-if", and change this one, as well as the FLOAT_IS_TRUE_FOR_INT usages, to OPA->_float
724 // although mostly unneeded, thanks to the only float being false being 0x0 and 0x80000000 (negative zero)
725 // and entity, string, field values can never have that value
726 {
728 st += st->operand[1] - 1; // offset the st++
729 startst = st;
730 // no bounds check needed, it is done when loading progs
731 if (++jumpcount == 10000000 && prvm_runawaycheck)
732 {
733 prog->xstatement = st - cached_statements;
734 PRVM_Profile(prog, 1<<30, 0.01, 0);
735 prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
736 }
737 }
739
742 st += st->operand[0] - 1; // offset the st++
743 startst = st;
744 // no bounds check needed, it is done when loading progs
745 if (++jumpcount == 10000000 && prvm_runawaycheck)
746 {
747 prog->xstatement = st - cached_statements;
748 PRVM_Profile(prog, 1<<30, 0.01, 0);
749 prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
750 }
752
762#ifdef PRVMTIMEPROFILING
763 tm = Sys_DirtyTime();
764 prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
765 starttm = tm;
766#endif
768 startst = st;
769 prog->xstatement = st - cached_statements;
770 prog->argc = st->op - OP_CALL0;
771 if (!OPA->function)
772 {
773 prog->error_cmd("NULL function in %s", prog->name);
774 }
775
776 if(!OPA->function || OPA->function < 0 || OPA->function >= prog->numfunctions)
777 {
778 PRE_ERROR();
779 prog->error_cmd("%s attempted CALL outside the program", prog->name);
780 goto cleanup;
781 }
782
783 enterfunc = &prog->functions[OPA->function];
784 if (enterfunc->callcount++ == 0 && (prvm_coverage.integer & 1))
785 PRVM_FunctionCoverageEvent(prog, enterfunc);
786
787 if (enterfunc->first_statement < 0)
788 {
789 // negative first_statement values are built in functions
790 int builtinnumber = -enterfunc->first_statement;
791 prog->xfunction->builtinsprofile++;
792 if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
793 {
794 prog->builtins[builtinnumber](prog);
795#ifdef PRVMTIMEPROFILING
796 tm = Sys_DirtyTime();
797 enterfunc->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
798 prog->xfunction->tbprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
799 starttm = tm;
800#endif
801 // builtins may cause ED_Alloc() to be called, update cached variables
803 // these do not change
804 //cached_statements = prog->statements;
805 //cached_allowworldwrites = prog->allowworldwrites;
806 //cached_flag = prog->flag;
807 // if prog->trace changed we need to change interpreter path
808 if (prog->trace != cachedpr_trace)
809 goto chooseexecprogram;
810 }
811 else
812 prog->error_cmd("No such builtin #%i in %s. This program is corrupt or incompatible with DarkPlaces (or this version of it)", builtinnumber, prog->name);
813 }
814 else
815 st = cached_statements + PRVM_EnterFunction(prog, enterfunc);
816 startst = st;
818
821#ifdef PRVMTIMEPROFILING
822 tm = Sys_DirtyTime();
823 prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
824 starttm = tm;
825#endif
827 prog->xstatement = st - cached_statements;
828
829 prog->globals.ip[OFS_RETURN ] = prog->globals.ip[st->operand[0] ];
830 prog->globals.ip[OFS_RETURN+1] = prog->globals.ip[st->operand[0]+1];
831 prog->globals.ip[OFS_RETURN+2] = prog->globals.ip[st->operand[0]+2];
832
833 st = cached_statements + PRVM_LeaveFunction(prog);
834 startst = st;
835 if (prog->depth <= exitdepth)
836 goto cleanup; // all done
838
840 if(cached_flag & PRVM_OP_STATE)
841 {
844 PRVM_gameedictfloat(ed,frame) = OPA->_float;
845 PRVM_gameedictfunction(ed,think) = OPB->function;
846 }
847 else
848 {
849 PRE_ERROR();
850 prog->xstatement = st - cached_statements;
851 prog->error_cmd("OP_STATE not supported by %s", prog->name);
852 }
854
856 OPC->_int = OPA->_int + OPB->_int;
859 OPC->_float = ((prvm_vec_t) OPA->_int) + OPB->_float;
862 OPC->_float = OPA->_float + (prvm_vec_t) OPB->_int;
865 OPC->_int = OPA->_int - OPB->_int;
868 OPC->_float = ((prvm_vec_t) OPA->_int) - OPB->_float;
871 OPC->_float = OPA->_float - (prvm_vec_t) OPB->_int;
874 OPC->_int = OPA->_int * OPB->_int;
877 OPC->_float = ((prvm_vec_t) OPA->_int) * OPB->_float;
880 OPC->_float = OPA->_float * (prvm_vec_t) OPB->_int;
883 OPC->vector[0] = (prvm_vec_t) OPB->_int * OPA->vector[0];
884 OPC->vector[1] = (prvm_vec_t) OPB->_int * OPA->vector[1];
885 OPC->vector[2] = (prvm_vec_t) OPB->_int * OPA->vector[2];
888 if( OPB->_float == 0.0f )
889 {
890 PRE_ERROR();
891 VM_Warning(prog, "Attempted division of '%f %f %f' by zero\n", OPA->vector[0], OPA->vector[1], OPA->vector[2]);
893 {
894 OPC->vector[0] = 0;
895 OPC->vector[1] = 0;
896 OPC->vector[2] = 0;
898 }
899 }
900 tempfloat = OPB->_float;
901 OPC->vector[0] = OPA->vector[0] / tempfloat;
902 OPC->vector[1] = OPA->vector[1] / tempfloat;
903 OPC->vector[2] = OPA->vector[2] / tempfloat;
906 // NOTE: This also catches the second kind of division that can trap, namely, -2147483648 / -1,
907 // whose result is not representable as int32_t and raises the same CPU exception.
908 if( OPB->_int != 0 && (OPB->_int != -1 || OPA->_int != PRVM_INT_MIN) )
909 {
910 OPC->_int = OPA->_int / OPB->_int;
911 }
912 else
913 {
914 PRE_ERROR();
915 VM_Warning(prog, "Attempted division of %"PRVM_PRIi" by %"PRVM_PRIi"\n", OPA->_int, OPB->_int);
916 OPC->_int = 0;
917 }
920 if( OPB->_float == 0.0f )
921 {
922 PRE_ERROR();
923 VM_Warning(prog, "Attempted division of %"PRVM_PRIi" by zero\n", OPA->_int);
925 {
926 OPC->_float = 0;
928 }
929 }
930 OPC->_float = ((prvm_vec_t) OPA->_int) / OPB->_float;
933 if( OPB->_int == 0 )
934 {
935 PRE_ERROR();
936 VM_Warning(prog, "Attempted division of %f by zero\n", OPA->_float);
938 {
939 OPC->_float = 0;
941 }
942 }
943 OPC->_float = OPA->_float / (prvm_vec_t) OPB->_int;
946 OPC->_float = OPA->_int;
949 OPC->_int = OPA->_float;
952 OPC->_int = OPA->_int & OPB->_int;
955 OPC->_int = OPA->_int | OPB->_int;
958 OPC->_int = OPA->_int & (prvm_int_t)OPB->_float;
961 OPC->_int = OPA->_int | (prvm_int_t)OPB->_float;
964 OPC->_int = (prvm_int_t)OPA->_float & OPB->_int;
967 OPC->_int = (prvm_int_t)OPA->_float | OPB->_int;
970 OPC->_int = OPA->_int >= OPB->_int;
973 OPC->_int = OPA->_int <= OPB->_int;
976 OPC->_int = OPA->_int > OPB->_int;
979 OPC->_int = OPA->_int < OPB->_int;
982 OPC->_int = OPA->_int && OPB->_int;
985 OPC->_int = OPA->_int || OPB->_int;
988 OPC->_int = (prvm_vec_t)OPA->_int >= OPB->_float;
991 OPC->_int = (prvm_vec_t)OPA->_int <= OPB->_float;
994 OPC->_int = (prvm_vec_t)OPA->_int > OPB->_float;
997 OPC->_int = (prvm_vec_t)OPA->_int < OPB->_float;
1000 OPC->_int = (prvm_vec_t)OPA->_int && OPB->_float;
1003 OPC->_int = (prvm_vec_t)OPA->_int || OPB->_float;
1006 OPC->_int = OPA->_float >= (prvm_vec_t)OPB->_int;
1009 OPC->_int = OPA->_float <= (prvm_vec_t)OPB->_int;
1012 OPC->_int = OPA->_float > (prvm_vec_t)OPB->_int;
1015 OPC->_int = OPA->_float < (prvm_vec_t)OPB->_int;
1018 OPC->_int = OPA->_float && (prvm_vec_t)OPB->_int;
1021 OPC->_int = OPA->_float || (prvm_vec_t)OPB->_int;
1024 OPC->_int = !OPA->_int;
1027 OPC->_int = OPA->_int == OPB->_int;
1030 OPC->_int = (prvm_vec_t)OPA->_int == OPB->_float;
1033 OPC->_int = OPA->_float == (prvm_vec_t)OPB->_int;
1036 OPC->_int = OPA->_int != OPB->_int;
1039 OPC->_int = (prvm_vec_t)OPA->_int != OPB->_float;
1042 OPC->_int = OPA->_float != (prvm_vec_t)OPB->_int;
1046 OPB->_int = OPA->_int;
1049#if PRBOUNDSCHECK
1050 if (OPB->_int < 0 || OPB->_int + 4 > pr_edictareasize)
1051 {
1052 PRE_ERROR();
1053 prog->error_cmd("%s attempted to write to an out of bounds edict", prog->name);
1054 goto cleanup;
1055 }
1056#endif
1057 ptr = (prvm_eval_t *)(prog->edictsfields.ip + OPB->_int);
1058 ptr->_int = OPA->_int;
1061#if PRBOUNDSCHECK
1062 if (OPA->edict < 0 || OPA->edict >= prog->max_edicts)
1063 {
1064 PRE_ERROR();
1065 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
1066 goto cleanup;
1067 }
1068 if (OPB->_int < 0 || OPB->_int >= progs->entityfields.ip)
1069 {
1070 PRE_ERROR();
1071 prog->error_cmd("%s attempted to read an invalid field in an edict", prog->name);
1072 goto cleanup;
1073 }
1074#endif
1075 ed = PRVM_PROG_TO_EDICT(OPA->edict);
1076 OPC->_int = ((prvm_eval_t *)((int *)ed->fields.ip + OPB->_int))->_int;
1078
1082 HANDLE_OPCODE(OP_GSTOREP_FLD): // integers
1084 HANDLE_OPCODE(OP_GSTOREP_FNC): // pointers
1085 if (OPB->_int < 0 || OPB->_int >= prog->numglobals)
1086 {
1087 PRE_ERROR();
1088 prog->error_cmd("%s attempted to write to an invalid indexed global", prog->name);
1089 goto cleanup;
1090 }
1091 prog->globals.ip[OPB->_int] = OPA->_int;
1094 if (OPB->_int < 0 || OPB->_int + 2 >= prog->numglobals)
1095 {
1096 PRE_ERROR();
1097 prog->error_cmd("%s attempted to write to an invalid indexed global", prog->name);
1098 goto cleanup;
1099 }
1100 prog->globals.ip[OPB->_int ] = OPA->ivector[0];
1101 prog->globals.ip[OPB->_int+1] = OPA->ivector[1];
1102 prog->globals.ip[OPB->_int+2] = OPA->ivector[2];
1104
1106 i = OPA->_int + (prvm_int_t) OPB->_float;
1107 if (i < 0 || i >= prog->numglobaldefs)
1108 {
1109 PRE_ERROR();
1110 prog->error_cmd("%s attempted to address an out of bounds global", prog->name);
1111 goto cleanup;
1112 }
1113 OPC->_int = prog->globals.ip[i];
1115
1122 if (OPA->_int < 0 || OPA->_int >= prog->numglobals)
1123 {
1124 PRE_ERROR();
1125 prog->error_cmd("%s attempted to read an invalid indexed global", prog->name);
1126 goto cleanup;
1127 }
1128 OPC->_int = prog->globals.ip[OPA->_int];
1130
1132 if (OPA->_int < 0 || OPA->_int + 2 >= prog->numglobals)
1133 {
1134 PRE_ERROR();
1135 prog->error_cmd("%s attempted to read an invalid indexed global", prog->name);
1136 goto cleanup;
1137 }
1138 OPC->ivector[0] = prog->globals.ip[OPA->_int ];
1139 OPC->ivector[1] = prog->globals.ip[OPA->_int+1];
1140 OPC->ivector[2] = prog->globals.ip[OPA->_int+2];
1142
1144 if ((unsigned int)OPA->_int < (unsigned int)st->operand[2] || (unsigned int)OPA->_int >= (unsigned int)st->operand[1])
1145 {
1146 PRE_ERROR();
1147 prog->error_cmd("Progs boundcheck failed in %s, value is < %"PRVM_PRIi" or >= %"PRVM_PRIi"", prog->name, OPC->_int, OPB->_int);
1148 goto cleanup;
1149 }
1151
1152 // FTEQW pointer instructions.
1154 OPC->_int = PRVM_GLOBALSBASE + st->operand[0] + 1 * OPB->_int;
1157 OPC->_int = OPA->_int + 1 * OPB->_int;
1164 ofs = st->operand[0] + OPB->_int;
1165 if (ofs >= cached_vmglobals)
1166 {
1167 PRE_ERROR();
1168 prog->error_cmd("%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (unsigned int)st->operand[0], OPB->_int);
1169 goto cleanup;
1170 }
1171 src = (prvm_eval_t *)&globals[ofs];
1172 OPC->_int = src->_int;
1175 ofs = st->operand[0] + OPB->_int;
1176 if (ofs >= cached_vmglobals)
1177 {
1178 PRE_ERROR();
1179 prog->error_cmd("%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (unsigned int)st->operand[0], OPB->_int);
1180 goto cleanup;
1181 }
1182 src = (prvm_eval_t *)&globals[ofs];
1183 // refresh the garbage collection on the string - this guards
1184 // against a certain sort of repeated migration to earlier
1185 // points in the scan that could otherwise result in the string
1186 // being freed for being unused
1188 PRVM_GetString(prog, src->_int);
1189 OPC->_int = src->_int;
1192 ofs = st->operand[0] + OPB->_int;
1193 if (ofs >= cached_vmglobals_2)
1194 {
1195 PRE_ERROR();
1196 prog->error_cmd("%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (unsigned int)st->operand[0], OPB->_int);
1197 goto cleanup;
1198 }
1199 src = (prvm_eval_t *)&globals[ofs];
1200 OPC->ivector[0] = src->ivector[0];
1201 OPC->ivector[1] = src->ivector[1];
1202 OPC->ivector[2] = src->ivector[2];
1206 HANDLE_OPCODE(OP_LOADP_FLD): // integers
1207 HANDLE_OPCODE(OP_LOADP_FNC): // pointers
1209 addr = OPA->_uint + OPB->_uint;
1210 if ((ofs = addr - cached_vmentity0start) < cached_entityfieldsarea)
1211 {
1212 // OK entity write.
1213 ptr = (prvm_eval_t *)(cached_edictsfields + ofs);
1214 }
1215 else if ((ofs = addr - PRVM_GLOBALSBASE) < cached_vmglobals)
1216 {
1217 // OK global write.
1218 ptr = (prvm_eval_t *)(globals + ofs);
1219 }
1220 else
1221 {
1222 PRE_ERROR();
1223 prog->error_cmd("%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (unsigned int)OPA->_int, OPB->_int);
1224 goto cleanup;
1225 }
1226 OPC->_int = ptr->_int;
1229 addr = OPA->_uint + OPB->_uint;
1230 if ((ofs = addr - cached_vmentity0start) < cached_entityfieldsarea)
1231 {
1232 // OK entity write.
1233 ptr = (prvm_eval_t *)(cached_edictsfields + ofs);
1234 }
1235 else if ((ofs = addr - PRVM_GLOBALSBASE) < cached_vmglobals)
1236 {
1237 // OK global write.
1238 ptr = (prvm_eval_t *)(globals + ofs);
1239 }
1240 else
1241 {
1242 PRE_ERROR();
1243 prog->error_cmd("%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (unsigned int)OPA->_int, OPB->_int);
1244 goto cleanup;
1245 }
1247 PRVM_GetString(prog, ptr->_int);
1248 OPC->_int = ptr->_int;
1251 addr = OPA->_uint + OPB->_uint;
1252 if ((ofs = addr - cached_vmentity0start) < cached_entityfieldsarea_2)
1253 {
1254 // OK entity write.
1255 ptr = (prvm_eval_t *)(cached_edictsfields + ofs);
1256 }
1257 else if ((ofs = addr - PRVM_GLOBALSBASE) < cached_vmglobals_2)
1258 {
1259 // OK global write.
1260 ptr = (prvm_eval_t *)(globals + ofs);
1261 }
1262 else
1263 {
1264 PRE_ERROR();
1265 prog->error_cmd("%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (unsigned int)OPA->_int, OPB->_int);
1266 goto cleanup;
1267 }
1268 OPC->ivector[0] = ptr->ivector[0];
1269 OPC->ivector[1] = ptr->ivector[1];
1270 OPC->ivector[2] = ptr->ivector[2];
1273 OPC->_int = OPA->_int >> OPB->_int;
1276 OPC->_int = OPA->_int << OPB->_int;
1279 OPC->_int = (OPA->_uint <= OPB->_uint);
1282 OPC->_int = (OPA->_uint < OPB->_uint);
1285 if( OPB->_uint != 0 )
1286 {
1287 OPC->_uint = OPA->_uint / OPB->_uint;
1288 }
1289 else
1290 {
1291 PRE_ERROR();
1292 VM_Warning(prog, "Attempted division of %"PRVM_PRIu" by zero\n", OPA->_uint);
1293 OPC->_uint = 0;
1294 }
1297 OPC->_uint = OPA->_uint >> OPB->_uint;
1299
1300#if !USE_COMPUTED_GOTOS
1301 default:
1302 PRE_ERROR();
1303 prog->error_cmd("Bad opcode %i in %s. This program is corrupt or incompatible with DarkPlaces (or this version of it)", st->op, prog->name);
1304 goto cleanup;
1305 }
1306#if PRVMSLOWINTERPRETER
1307 {
1308 if (prog->watch_global_type != ev_void)
1309 {
1310 prvm_eval_t *g = PRVM_GLOBALFIELDVALUE(prog->watch_global);
1311 prog->xstatement = st - cached_statements;
1312 PRVM_Watchpoint(prog, 0, "Global watchpoint hit", prog->watch_global_type, &prog->watch_global_value, g);
1313 }
1314 if (prog->watch_field_type != ev_void && prog->watch_edict < prog->max_edicts)
1315 {
1316 prvm_eval_t *g = PRVM_EDICTFIELDVALUE(prog->edicts + prog->watch_edict, prog->watch_field);
1317 prog->xstatement = st - cached_statements;
1318 PRVM_Watchpoint(prog, 0, "Entityfield watchpoint hit", prog->watch_field_type, &prog->watch_edictfield_value, g);
1319 }
1320 }
1321#endif
1322 }
1323#endif // !USE_COMPUTED_GOTOS
1324
1325#undef DISPATCH_OPCODE
1326#undef HANDLE_OPCODE
1327#undef USE_COMPUTED_GOTOS
1328#undef PRE_ERROR
1329#undef ADVANCE_PROFILE_BEFORE_JUMP
qbool prvm_runawaycheck
Definition prvm_edict.c:60
entity self
float time
float nextthink
float frame
@ OP_SUB_FI
Definition pr_comp.h:194
@ OP_STOREP_S
Definition pr_comp.h:93
@ OP_NE_E
Definition pr_comp.h:67
@ OP_LOADA_ENT
Definition pr_comp.h:235
@ OP_AND_I
Definition pr_comp.h:284
@ OP_LE_FI
Definition pr_comp.h:261
@ OP_ADD_I
Definition pr_comp.h:189
@ OP_GSTOREP_FLD
Definition pr_comp.h:296
@ OP_STORE_V
Definition pr_comp.h:85
@ OP_GSTOREP_FNC
Definition pr_comp.h:298
@ OP_RSHIFT_U
Definition pr_comp.h:333
@ OP_SUB_F
Definition pr_comp.h:55
@ OP_LOAD_ENT
Definition pr_comp.h:78
@ OP_LOAD_F
Definition pr_comp.h:75
@ OP_LT_FI
Definition pr_comp.h:263
@ OP_GE_I
Definition pr_comp.h:252
@ OP_DIV_I
Definition pr_comp.h:213
@ OP_LT_I
Definition pr_comp.h:253
@ OP_IF
Definition pr_comp.h:104
@ OP_LOAD_FLD
Definition pr_comp.h:79
@ OP_MUL_VI
Definition pr_comp.h:276
@ OP_BITOR_F
Definition pr_comp.h:121
@ OP_STOREP_V
Definition pr_comp.h:92
@ OP_GLOAD_ENT
Definition pr_comp.h:304
@ OP_GLOAD_F
Definition pr_comp.h:302
@ OP_EQ_FI
Definition pr_comp.h:267
@ OP_GSTOREP_I
Definition pr_comp.h:293
@ OP_MUL_VF
Definition pr_comp.h:51
@ OP_ADD_IF
Definition pr_comp.h:191
@ OP_GLOAD_FLD
Definition pr_comp.h:303
@ OP_NOT_I
Definition pr_comp.h:221
@ OP_LOADA_I
Definition pr_comp.h:238
@ OP_GSTOREP_F
Definition pr_comp.h:294
@ OP_CALL8
Definition pr_comp.h:114
@ OP_CONV_ITOF
Definition pr_comp.h:197
@ OP_DIV_F
Definition pr_comp.h:52
@ OP_GT_F
Definition pr_comp.h:73
@ OP_DIV_IF
Definition pr_comp.h:278
@ OP_MUL_I
Definition pr_comp.h:212
@ OP_OR_FI
Definition pr_comp.h:289
@ OP_CALL6
Definition pr_comp.h:112
@ OP_ADD_V
Definition pr_comp.h:54
@ OP_STOREP_ENT
Definition pr_comp.h:94
@ OP_STOREP_FNC
Definition pr_comp.h:96
@ OP_AND_IF
Definition pr_comp.h:286
@ OP_CALL5
Definition pr_comp.h:111
@ OP_LOADP_V
Definition pr_comp.h:244
@ OP_NE_FNC
Definition pr_comp.h:68
@ OP_NE_S
Definition pr_comp.h:66
@ OP_BITOR_FI
Definition pr_comp.h:283
@ OP_LT_IF
Definition pr_comp.h:258
@ OP_STORE_P
Definition pr_comp.h:240
@ OP_CONV_FTOI
Definition pr_comp.h:198
@ OP_LOADA_FNC
Definition pr_comp.h:237
@ OP_LOADP_ENT
Definition pr_comp.h:246
@ OP_STORE_I
Definition pr_comp.h:185
@ OP_SUB_V
Definition pr_comp.h:56
@ OP_BITAND_FI
Definition pr_comp.h:282
@ OP_NOT_ENT
Definition pr_comp.h:102
@ OP_GSTOREP_S
Definition pr_comp.h:297
@ OP_GLOAD_I
Definition pr_comp.h:301
@ OP_OR_IF
Definition pr_comp.h:287
@ OP_STOREP_I
Definition pr_comp.h:205
@ OP_DIV_FI
Definition pr_comp.h:279
@ OP_EQ_FNC
Definition pr_comp.h:62
@ OP_LE_U
Definition pr_comp.h:330
@ OP_STOREP_FLD
Definition pr_comp.h:95
@ OP_MUL_FV
Definition pr_comp.h:50
@ OP_LOAD_P
Definition pr_comp.h:241
@ OP_NE_V
Definition pr_comp.h:65
@ OP_STORE_FLD
Definition pr_comp.h:88
@ OP_GLOBALADDRESS
Definition pr_comp.h:229
@ OP_ADD_PIW
Definition pr_comp.h:230
@ OP_CALL1
Definition pr_comp.h:107
@ OP_EQ_I
Definition pr_comp.h:214
@ OP_EQ_V
Definition pr_comp.h:59
@ OP_STORE_ENT
Definition pr_comp.h:87
@ OP_MUL_IF
Definition pr_comp.h:274
@ OP_GSTOREP_ENT
Definition pr_comp.h:295
@ OP_GT_IF
Definition pr_comp.h:259
@ OP_NE_IF
Definition pr_comp.h:290
@ OP_ADD_F
Definition pr_comp.h:53
@ OP_LT_F
Definition pr_comp.h:72
@ OP_RSHIFT_I
Definition pr_comp.h:226
@ OP_LOADP_S
Definition pr_comp.h:245
@ OP_MUL_FI
Definition pr_comp.h:275
@ OP_LOADA_F
Definition pr_comp.h:232
@ OP_GE_F
Definition pr_comp.h:71
@ OP_GE_IF
Definition pr_comp.h:257
@ OP_DIV_U
Definition pr_comp.h:332
@ OP_LE_I
Definition pr_comp.h:251
@ OP_LE_F
Definition pr_comp.h:70
@ OP_LOADP_I
Definition pr_comp.h:249
@ OP_BITAND_F
Definition pr_comp.h:120
@ OP_LE_IF
Definition pr_comp.h:256
@ OP_ADD_FI
Definition pr_comp.h:190
@ OP_GE_FI
Definition pr_comp.h:262
@ OP_AND_F
Definition pr_comp.h:117
@ OP_CALL0
Definition pr_comp.h:106
@ OP_LOADP_FLD
Definition pr_comp.h:247
@ OP_NE_F
Definition pr_comp.h:64
@ OP_NOT_F
Definition pr_comp.h:99
@ OP_STORE_S
Definition pr_comp.h:86
@ OP_LOAD_S
Definition pr_comp.h:77
@ OP_OR_I
Definition pr_comp.h:285
@ OP_CALL4
Definition pr_comp.h:110
@ OP_EQ_E
Definition pr_comp.h:61
@ OP_DIV_VF
Definition pr_comp.h:223
@ OP_STOREP_F
Definition pr_comp.h:91
@ OP_SUB_IF
Definition pr_comp.h:195
@ OP_LSHIFT_I
Definition pr_comp.h:227
@ OP_CALL2
Definition pr_comp.h:108
@ OP_GLOAD_V
Definition pr_comp.h:314
@ OP_MUL_V
Definition pr_comp.h:49
@ OP_GLOAD_S
Definition pr_comp.h:305
@ OP_LOADA_FLD
Definition pr_comp.h:236
@ OP_SUB_I
Definition pr_comp.h:193
@ OP_NE_FI
Definition pr_comp.h:291
@ OP_LOADP_F
Definition pr_comp.h:243
@ OP_STATE
Definition pr_comp.h:115
@ OP_GT_I
Definition pr_comp.h:254
@ OP_LOAD_I
Definition pr_comp.h:203
@ OP_LOADA_V
Definition pr_comp.h:233
@ OP_LOADA_S
Definition pr_comp.h:234
@ OP_CALL3
Definition pr_comp.h:109
@ OP_RETURN
Definition pr_comp.h:98
@ OP_OR_F
Definition pr_comp.h:118
@ OP_ADDRESS
Definition pr_comp.h:82
@ OP_EQ_IF
Definition pr_comp.h:266
@ OP_BITAND_I
Definition pr_comp.h:209
@ OP_EQ_F
Definition pr_comp.h:58
@ OP_DONE
Definition pr_comp.h:47
@ OP_NOT_V
Definition pr_comp.h:100
@ OP_BOUNDCHECK
Definition pr_comp.h:307
@ OP_AND_FI
Definition pr_comp.h:288
@ OP_GSTOREP_V
Definition pr_comp.h:299
@ OP_EQ_S
Definition pr_comp.h:60
@ OP_BITOR_IF
Definition pr_comp.h:281
@ OP_LOAD_FNC
Definition pr_comp.h:80
@ OP_NE_I
Definition pr_comp.h:215
@ OP_GT_FI
Definition pr_comp.h:264
@ OP_NOT_FNC
Definition pr_comp.h:103
@ OP_LOAD_V
Definition pr_comp.h:76
@ OP_GOTO
Definition pr_comp.h:116
@ OP_GLOAD_FNC
Definition pr_comp.h:306
@ OP_BITAND_IF
Definition pr_comp.h:280
@ OP_CALL7
Definition pr_comp.h:113
@ OP_GADDRESS
Definition pr_comp.h:300
@ OP_STORE_FNC
Definition pr_comp.h:89
@ OP_LT_U
Definition pr_comp.h:331
@ OP_BITOR_I
Definition pr_comp.h:210
@ OP_MUL_F
Definition pr_comp.h:48
@ OP_LOADP_FNC
Definition pr_comp.h:248
@ OP_NOT_S
Definition pr_comp.h:101
@ OP_STORE_F
Definition pr_comp.h:84
@ OP_IFNOT
Definition pr_comp.h:105
#define OFS_RETURN
Definition pr_comp.h:33
@ ev_void
Definition pr_comp.h:29
#define PRVM_FLOAT_IS_TRUE_FOR_INT(x)
Definition progs.h:35
#define PRVM_gameedictfloat(ed, fieldname)
Definition progsvm.h:160
#define PRVM_gameedictfunction(ed, fieldname)
Definition progsvm.h:164
#define PRVM_OP_STATE
Definition progsvm.h:238
void PRVM_Watchpoint(prvm_prog_t *prog, int stack_index, const char *text, etype_t type, prvm_eval_t *o, prvm_eval_t *n)
void VM_Warning(prvm_prog_t *prog, const char *fmt,...) DP_FUNC_PRINTF(2)
Definition prvm_cmds.c:25
#define PRVM_gameglobaledict(fieldname)
Definition progsvm.h:168
const char * PRVM_GetString(prvm_prog_t *prog, int num)
void PRVM_Breakpoint(prvm_prog_t *prog, int stack_index, const char *text)
#define PRVM_gameglobalfloat(fieldname)
Definition progsvm.h:165
#define PRVM_PROG_TO_EDICT(n)
Definition progsvm.h:877
void PRVM_Profile(prvm_prog_t *prog, int maxfunctions, double mintime, int sortby)
Definition prvm_exec.c:539
#define PRVM_GLOBALFIELDVALUE(fieldoffset)
Definition progsvm.h:215
mdef_t * PRVM_ED_FieldAtOfs(prvm_prog_t *prog, unsigned int ofs)
Definition prvm_edict.c:357
#define PRVM_EDICTFIELDVALUE(ed, fieldoffset)
Definition progsvm.h:209
cvar_t prvm_coverage
Definition prvm_edict.c:39
cvar_t prvm_gameplayfix_div0is0
Definition prvm_edict.c:57
#define OPC
Definition prvm_exec.c:945
#define OPA
Definition prvm_exec.c:943
#define CACHE_CHANGING(DECLARE)
Definition prvm_exec.c:971
static void PRVM_FunctionCoverageEvent(prvm_prog_t *prog, mfunction_t *func)
Definition prvm_exec.c:919
#define PRVM_GLOBALSBASE
Definition prvm_exec.c:951
static int PRVM_EnterFunction(prvm_prog_t *prog, mfunction_t *f)
Definition prvm_exec.c:799
static int PRVM_LeaveFunction(prvm_prog_t *prog)
Definition prvm_exec.c:845
#define NO_DECLARE(t)
Definition prvm_exec.c:981
static void PRVM_PrintStatement(prvm_prog_t *prog, mstatement_t *s)
Definition prvm_exec.c:329
#define OPB
Definition prvm_exec.c:944
#define PRE_ERROR()
prvm_uint_t ofs
cvar_t prvm_garbagecollection_enable
Definition prvm_edict.c:48
prvm_eval_t * src
prvm_uint_t addr
#define HANDLE_OPCODE(opcode)
int i
#define ADVANCE_PROFILE_BEFORE_JUMP()
#define DISPATCH_OPCODE()
#define FLOAT_IS_TRUE_FOR_INT(x)
Definition qdefs.h:193
#define NULL
Definition qtypes.h:12
uint32_t prvm_uint_t
Definition qtypes.h:57
#define PRVM_PRIu
Definition qtypes.h:59
#define PRVM_INT_MIN
Definition qtypes.h:60
#define PRVM_PRIi
Definition qtypes.h:58
float prvm_vec_t
Definition qtypes.h:55
int32_t prvm_int_t
Definition qtypes.h:56
dp_FragColor g
Definition cvar.h:66
int integer
Definition cvar.h:73
double Sys_DirtyTime(void)
Definition sys_shared.c:417
prvm_int_t ivector[3]
Definition progsvm.h:66
prvm_int_t _int
Definition progsvm.h:67