341 {
342 st++;
343#endif
344
345#if !USE_COMPUTED_GOTOS
346
347#if PRVMSLOWINTERPRETER
348 if (prog->trace)
350 if (prog->break_statement >= 0)
351 if ((st - cached_statements) == prog->break_statement)
352 {
353 prog->xstatement = st - cached_statements;
355 }
356#endif
357 switch (st->op)
358 {
359#endif
365 OPC->vector[1] =
OPA->vector[1] +
OPB->vector[1];
366 OPC->vector[2] =
OPA->vector[2] +
OPB->vector[2];
373 OPC->vector[1] =
OPA->vector[1] -
OPB->vector[1];
374 OPC->vector[2] =
OPA->vector[2] -
OPB->vector[2];
383 tempfloat =
OPA->_float;
384 OPC->vector[0] = tempfloat *
OPB->vector[0];
385 OPC->vector[1] = tempfloat *
OPB->vector[1];
386 OPC->vector[2] = tempfloat *
OPB->vector[2];
389 tempfloat =
OPB->_float;
390 OPC->vector[0] = tempfloat *
OPA->vector[0];
391 OPC->vector[1] = tempfloat *
OPA->vector[1];
392 OPC->vector[2] = tempfloat *
OPA->vector[2];
395 if(
OPB->_float == 0.0f )
396 {
398 VM_Warning(prog,
"Attempted division of %f by zero\n",
OPA->_float);
400 {
403 }
404 }
414 OPC->_float =
OPA->_float >=
OPB->_float;
417 OPC->_float =
OPA->_float <=
OPB->_float;
441 OPC->_float = !
OPA->function;
444 OPC->_float = (
OPA->edict == 0);
447 OPC->_float =
OPA->_float ==
OPB->_float;
459 OPC->_float =
OPA->function ==
OPB->function;
462 OPC->_float =
OPA->_float !=
OPB->_float;
474 OPC->_float =
OPA->function !=
OPB->function;
476
477
485
486
487
488
494 OPB->ivector[0] =
OPA->ivector[0];
495 OPB->ivector[1] =
OPA->ivector[1];
496 OPB->ivector[2] =
OPA->ivector[2];
498
504 if ((
ofs =
addr - cached_vmentity1start) < cached_entityfieldsarea_entityfields)
505 {
506
508 }
509 else if ((
ofs =
addr - cached_vmglobal1) < cached_vmglobals_1)
510 {
511
513 }
514 else if ((
ofs =
addr - cached_vmentity0start) < cached_entityfields)
515 {
516 if (!cached_allowworldwrites)
517 {
520
521 }
523 }
524 else
525 {
527 prog->error_cmd(
"%s attempted to write to an out of bounds address %"PRVM_PRIu"+%"PRVM_PRIi"", prog->name,
OPB->_uint,
OPC->_int);
528 goto cleanup;
529 }
530 ptr->_int =
OPA->_int;
534 if ((
ofs =
addr - cached_vmentity1start) < cached_entityfieldsarea_entityfields)
535 {
536
538 }
539 else if ((
ofs =
addr - cached_vmglobal1) < cached_vmglobals_1)
540 {
541
543 }
544 else if ((
ofs =
addr - cached_vmentity0start) < cached_entityfields)
545 {
546 if (!cached_allowworldwrites)
547 {
550
551 }
553 }
554 else
555 {
557 prog->error_cmd(
"%s attempted to write to an out of bounds address %"PRVM_PRIu"+%"PRVM_PRIi"", prog->name,
OPB->_uint,
OPC->_int);
558 goto cleanup;
559 }
560
561
562
563
566 ptr->_int =
OPA->_int;
570 if ((
ofs =
addr - cached_vmentity1start) < cached_entityfieldsarea_entityfields_2)
571 {
572
574 }
575 else if ((
ofs =
addr - cached_vmglobal1) < cached_vmglobals_3)
576 {
577
579 }
580 else if ((
ofs =
addr - cached_vmentity0start) < cached_entityfields_2)
581 {
582 if (!cached_allowworldwrites)
583 {
586
587 }
589 }
590 else
591 {
593 prog->error_cmd(
"%s attempted to write to an out of bounds address %"PRVM_PRIu"+%"PRVM_PRIi"", prog->name,
OPB->_uint,
OPC->_int);
594 goto cleanup;
595 }
596 ptr->ivector[0] =
OPA->ivector[0];
597 ptr->ivector[1] =
OPA->ivector[1];
598 ptr->ivector[2] =
OPA->ivector[2];
600
603 {
605 prog->error_cmd("%s attempted to address an out of bounds edict number", prog->name);
606 goto cleanup;
607 }
608 if (
OPB->_uint >= cached_entityfields)
609 {
611 prog->error_cmd(
"%s attempted to address an invalid field (%"PRVM_PRIu") in an edict", prog->name,
OPB->_uint);
612 goto cleanup;
613 }
614#if 0
615 if (
OPA->edict == 0 && !cached_allowworldwrites)
616 {
618 prog->error_cmd("Forbidden assignment to world (edictnum 0) in %s", prog->name);
619 goto cleanup;
620 }
621#endif
622 OPC->_int = cached_vmentity0start +
OPA->edict * cached_entityfields +
OPB->_int;
624
631 {
633 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
634 goto cleanup;
635 }
636 if (
OPB->_uint >= cached_entityfields)
637 {
639 prog->error_cmd(
"%s attempted to read an invalid field in an edict (%"PRVM_PRIu")", prog->name,
OPB->_uint);
640 goto cleanup;
641 }
647 {
649 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
650 goto cleanup;
651 }
652 if (
OPB->_uint >= cached_entityfields)
653 {
655 prog->error_cmd(
"%s attempted to read an invalid field in an edict (%"PRVM_PRIu")", prog->name,
OPB->_uint);
656 goto cleanup;
657 }
660
661
662
663
667
670 {
672 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
673 goto cleanup;
674 }
675 if (
OPB->_uint >= cached_entityfields_2)
676 {
678 prog->error_cmd(
"%s attempted to read an invalid field in an edict (%"PRVM_PRIu")", prog->name,
OPB->_uint);
679 goto cleanup;
680 }
683 OPC->ivector[0] = ptr->ivector[0];
684 OPC->ivector[1] = ptr->ivector[1];
685 OPC->ivector[2] = ptr->ivector[2];
687
688
689
691
692
694
695
696
697 {
699 st += st->operand[1] - 1;
700 startst = st;
701
703 {
704 prog->xstatement = st - cached_statements;
706 prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
707 }
708 }
710
712
713
714
715
716
717
718
719
721
722
723
724 {
726 st += st->operand[1] - 1;
727 startst = st;
728
730 {
731 prog->xstatement = st - cached_statements;
733 prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
734 }
735 }
737
740 st += st->operand[0] - 1;
741 startst = st;
742
744 {
745 prog->xstatement = st - cached_statements;
747 prog->error_cmd("%s runaway loop counter hit limit of %d jumps\ntip: read above for list of most-executed functions", prog->name, jumpcount);
748 }
750
762 prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
763 starttm = tm;
764#endif
766 startst = st;
767 prog->xstatement = st - cached_statements;
770 {
771 prog->error_cmd("NULL function in %s", prog->name);
772 }
773
774 if(!
OPA->function ||
OPA->function < 0 ||
OPA->function >= prog->numfunctions)
775 {
777 prog->error_cmd("%s attempted CALL outside the program", prog->name);
778 goto cleanup;
779 }
780
781 enterfunc = &prog->functions[
OPA->function];
782 if (enterfunc->callcount++ == 0 && (
prvm_coverage.integer & 1))
784
785 if (enterfunc->first_statement < 0)
786 {
787
788 int builtinnumber = -enterfunc->first_statement;
789 prog->xfunction->builtinsprofile++;
790 if (builtinnumber < prog->numbuiltins && prog->builtins[builtinnumber])
791 {
792 prog->builtins[builtinnumber](prog);
793#ifdef PRVMTIMEPROFILING
795 enterfunc->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
796 prog->xfunction->tbprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
797 starttm = tm;
798#endif
799
801
802
803
804
805
806 if (prog->trace != cachedpr_trace)
807 goto chooseexecprogram;
808 }
809 else
810 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);
811 }
812 else
814 startst = st;
816
821 prog->xfunction->tprofile += (tm - starttm >= 0 && tm - starttm < 1800) ? (tm - starttm) : 0;
822 starttm = tm;
823#endif
825 prog->xstatement = st - cached_statements;
826
827 prog->globals.ip[
OFS_RETURN ] = prog->globals.ip[st->operand[0] ];
828 prog->globals.ip[
OFS_RETURN+1] = prog->globals.ip[st->operand[0]+1];
829 prog->globals.ip[
OFS_RETURN+2] = prog->globals.ip[st->operand[0]+2];
830
832 startst = st;
833 if (prog->depth <= exitdepth)
834 goto cleanup;
836
839 {
844 }
845 else
846 {
848 prog->xstatement = st - cached_statements;
849 prog->error_cmd("OP_STATE not supported by %s", prog->name);
850 }
852
886 if(
OPB->_float == 0.0f )
887 {
889 VM_Warning(prog,
"Attempted division of '%f %f %f' by zero\n",
OPA->vector[0],
OPA->vector[1],
OPA->vector[2]);
891 {
896 }
897 }
898 tempfloat =
OPB->_float;
899 OPC->vector[0] =
OPA->vector[0] / tempfloat;
900 OPC->vector[1] =
OPA->vector[1] / tempfloat;
901 OPC->vector[2] =
OPA->vector[2] / tempfloat;
904
905
907 {
909 }
910 else
911 {
915 }
918 if(
OPB->_float == 0.0f )
919 {
923 {
926 }
927 }
932 {
934 VM_Warning(prog,
"Attempted division of %f by zero\n",
OPA->_float);
936 {
939 }
940 }
1047#if PRBOUNDSCHECK
1048 if (
OPB->_int < 0 ||
OPB->_int + 4 > pr_edictareasize)
1049 {
1051 prog->error_cmd("%s attempted to write to an out of bounds edict", prog->name);
1052 goto cleanup;
1053 }
1054#endif
1056 ptr->_int =
OPA->_int;
1059#if PRBOUNDSCHECK
1060 if (
OPA->edict < 0 ||
OPA->edict >= prog->max_edicts)
1061 {
1063 prog->error_cmd("%s attempted to read an out of bounds edict number", prog->name);
1064 goto cleanup;
1065 }
1066 if (
OPB->_int < 0 ||
OPB->_int >= progs->entityfields.ip)
1067 {
1069 prog->error_cmd("%s attempted to read an invalid field in an edict", prog->name);
1070 goto cleanup;
1071 }
1072#endif
1076
1083 if (
OPB->_int <= 0 ||
OPB->_int >= prog->numglobals)
1084 {
1086 prog->error_cmd("%s attempted to write to an invalid indexed global", prog->name);
1087 goto cleanup;
1088 }
1089 prog->globals.ip[
OPB->_int] =
OPA->_int;
1092 if (
OPB->_int <= 0 ||
OPB->_int + 2 >= prog->numglobals)
1093 {
1095 prog->error_cmd("%s attempted to write to an invalid indexed global", prog->name);
1096 goto cleanup;
1097 }
1098 prog->globals.ip[
OPB->_int ] =
OPA->ivector[0];
1099 prog->globals.ip[
OPB->_int+1] =
OPA->ivector[1];
1100 prog->globals.ip[
OPB->_int+2] =
OPA->ivector[2];
1102
1109 if (
OPA->_int < 0 ||
OPA->_int >= prog->numglobals)
1110 {
1112 prog->error_cmd("%s attempted to read an invalid indexed global", prog->name);
1113 goto cleanup;
1114 }
1115 OPC->_int = prog->globals.ip[
OPA->_int];
1117
1119 if (
OPA->_int < 0 ||
OPA->_int + 2 >= prog->numglobals)
1120 {
1122 prog->error_cmd("%s attempted to read an invalid indexed global", prog->name);
1123 goto cleanup;
1124 }
1125 OPC->ivector[0] = prog->globals.ip[
OPA->_int ];
1126 OPC->ivector[1] = prog->globals.ip[
OPA->_int+1];
1127 OPC->ivector[2] = prog->globals.ip[
OPA->_int+2];
1129
1131 if ((unsigned
int)
OPA->_int < (unsigned
int)st->operand[2] || (unsigned
int)
OPA->_int >= (unsigned
int)st->operand[1])
1132 {
1134 prog->error_cmd(
"Progs boundcheck failed in %s, value is < %"PRVM_PRIi" or >= %"PRVM_PRIi"", prog->name,
OPC->_int,
OPB->_int);
1135 goto cleanup;
1136 }
1138
1139
1151 ofs = st->operand[0] +
OPB->_int;
1152 if (
ofs >= cached_vmglobals)
1153 {
1155 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);
1156 goto cleanup;
1157 }
1162 ofs = st->operand[0] +
OPB->_int;
1163 if (
ofs >= cached_vmglobals)
1164 {
1166 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);
1167 goto cleanup;
1168 }
1170
1171
1172
1173
1179 ofs = st->operand[0] +
OPB->_int;
1180 if (
ofs >= cached_vmglobals_2)
1181 {
1183 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);
1184 goto cleanup;
1185 }
1187 OPC->ivector[0] =
src->ivector[0];
1188 OPC->ivector[1] =
src->ivector[1];
1189 OPC->ivector[2] =
src->ivector[2];
1197 if ((
ofs =
addr - cached_vmentity0start) < cached_entityfieldsarea)
1198 {
1199
1201 }
1203 {
1204
1206 }
1207 else
1208 {
1210 prog->error_cmd(
"%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (
unsigned int)
OPA->_int,
OPB->_int);
1211 goto cleanup;
1212 }
1213 OPC->_int = ptr->_int;
1217 if ((
ofs =
addr - cached_vmentity0start) < cached_entityfieldsarea)
1218 {
1219
1221 }
1223 {
1224
1226 }
1227 else
1228 {
1230 prog->error_cmd(
"%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (
unsigned int)
OPA->_int,
OPB->_int);
1231 goto cleanup;
1232 }
1235 OPC->_int = ptr->_int;
1239 if ((
ofs =
addr - cached_vmentity0start) < cached_entityfieldsarea_2)
1240 {
1241
1243 }
1245 {
1246
1248 }
1249 else
1250 {
1252 prog->error_cmd(
"%s attempted to read from an out of bounds address %u+%"PRVM_PRIi"", prog->name, (
unsigned int)
OPA->_int,
OPB->_int);
1253 goto cleanup;
1254 }
1255 OPC->ivector[0] = ptr->ivector[0];
1256 OPC->ivector[1] = ptr->ivector[1];
1257 OPC->ivector[2] = ptr->ivector[2];
1272 if(
OPB->_uint != 0 )
1273 {
1275 }
1276 else
1277 {
1281 }
1286
1287#if !USE_COMPUTED_GOTOS
1288 default:
1290 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);
1291 goto cleanup;
1292 }
1293#if PRVMSLOWINTERPRETER
1294 {
1295 if (prog->watch_global_type !=
ev_void)
1296 {
1298 prog->xstatement = st - cached_statements;
1299 PRVM_Watchpoint(prog, 0,
"Global watchpoint hit", prog->watch_global_type, &prog->watch_global_value,
g);
1300 }
1301 if (prog->watch_field_type !=
ev_void && prog->watch_edict < prog->max_edicts)
1302 {
1304 prog->xstatement = st - cached_statements;
1305 PRVM_Watchpoint(prog, 0,
"Entityfield watchpoint hit", prog->watch_field_type, &prog->watch_edictfield_value,
g);
1306 }
1307 }
1308#endif
1309 }
vector(vector v) normalize
static int(ZEXPORT *qz_inflate)(z_stream *strm
GLsizei const GLchar ** string
#define PRVM_FLOAT_IS_TRUE_FOR_INT(x)
#define PRVM_gameedictfloat(ed, fieldname)
#define PRVM_gameedictfunction(ed, fieldname)
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)
#define PRVM_gameglobaledict(fieldname)
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)
#define PRVM_PROG_TO_EDICT(n)
void PRVM_Profile(prvm_prog_t *prog, int maxfunctions, double mintime, int sortby)
#define PRVM_GLOBALFIELDVALUE(fieldoffset)
mdef_t * PRVM_ED_FieldAtOfs(prvm_prog_t *prog, unsigned int ofs)
#define PRVM_EDICTFIELDVALUE(ed, fieldoffset)
cvar_t prvm_gameplayfix_div0is0
cvar_t prvm_garbagecollection_enable
#define CACHE_CHANGING(DECLARE)
static void PRVM_FunctionCoverageEvent(prvm_prog_t *prog, mfunction_t *func)
static int PRVM_EnterFunction(prvm_prog_t *prog, mfunction_t *f)
#define HANDLE_OPCODE(opcode)
#define PRVMTIMEPROFILING
static int PRVM_LeaveFunction(prvm_prog_t *prog)
static void PRVM_PrintStatement(prvm_prog_t *prog, mstatement_t *s)
#define HANDLE_OPCODE(opcode)
#define ADVANCE_PROFILE_BEFORE_JUMP()
#define DISPATCH_OPCODE()
#define FLOAT_IS_TRUE_FOR_INT(x)
double Sys_DirtyTime(void)