pr_exec.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /*
  2. Copyright (C) 1996-1997 Id Software, Inc.
  3. This program is free software; you can redistribute it and/or
  4. modify it under the terms of the GNU General Public License
  5. as published by the Free Software Foundation; either version 2
  6. of the License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. See the GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program; if not, write to the Free Software
  13. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  14. */
  15. #include "qwsvdef.h"
  16. /*
  17. */
  18. typedef struct
  19. {
  20. int s;
  21. dfunction_t *f;
  22. } prstack_t;
  23. #define MAX_STACK_DEPTH 32
  24. prstack_t pr_stack[MAX_STACK_DEPTH];
  25. int pr_depth;
  26. #define LOCALSTACK_SIZE 2048
  27. int localstack[LOCALSTACK_SIZE];
  28. int localstack_used;
  29. qboolean pr_trace;
  30. dfunction_t *pr_xfunction;
  31. int pr_xstatement;
  32. int pr_argc;
  33. char *pr_opnames[] =
  34. {
  35. "DONE",
  36. "MUL_F",
  37. "MUL_V",
  38. "MUL_FV",
  39. "MUL_VF",
  40. "DIV",
  41. "ADD_F",
  42. "ADD_V",
  43. "SUB_F",
  44. "SUB_V",
  45. "EQ_F",
  46. "EQ_V",
  47. "EQ_S",
  48. "EQ_E",
  49. "EQ_FNC",
  50. "NE_F",
  51. "NE_V",
  52. "NE_S",
  53. "NE_E",
  54. "NE_FNC",
  55. "LE",
  56. "GE",
  57. "LT",
  58. "GT",
  59. "INDIRECT",
  60. "INDIRECT",
  61. "INDIRECT",
  62. "INDIRECT",
  63. "INDIRECT",
  64. "INDIRECT",
  65. "ADDRESS",
  66. "STORE_F",
  67. "STORE_V",
  68. "STORE_S",
  69. "STORE_ENT",
  70. "STORE_FLD",
  71. "STORE_FNC",
  72. "STOREP_F",
  73. "STOREP_V",
  74. "STOREP_S",
  75. "STOREP_ENT",
  76. "STOREP_FLD",
  77. "STOREP_FNC",
  78. "RETURN",
  79. "NOT_F",
  80. "NOT_V",
  81. "NOT_S",
  82. "NOT_ENT",
  83. "NOT_FNC",
  84. "IF",
  85. "IFNOT",
  86. "CALL0",
  87. "CALL1",
  88. "CALL2",
  89. "CALL3",
  90. "CALL4",
  91. "CALL5",
  92. "CALL6",
  93. "CALL7",
  94. "CALL8",
  95. "STATE",
  96. "GOTO",
  97. "AND",
  98. "OR",
  99. "BITAND",
  100. "BITOR"
  101. };
  102. char *PR_GlobalString (int ofs);
  103. char *PR_GlobalStringNoContents (int ofs);
  104. //=============================================================================
  105. /*
  106. =================
  107. PR_PrintStatement
  108. =================
  109. */
  110. void PR_PrintStatement (dstatement_t *s)
  111. {
  112. int i;
  113. if ( (unsigned)s->op < sizeof(pr_opnames)/sizeof(pr_opnames[0]))
  114. {
  115. Con_Printf ("%s ", pr_opnames[s->op]);
  116. i = strlen(pr_opnames[s->op]);
  117. for ( ; i<10 ; i++)
  118. Con_Printf (" ");
  119. }
  120. if (s->op == OP_IF || s->op == OP_IFNOT)
  121. Con_Printf ("%sbranch %i",PR_GlobalString(s->a),s->b);
  122. else if (s->op == OP_GOTO)
  123. {
  124. Con_Printf ("branch %i",s->a);
  125. }
  126. else if ( (unsigned)(s->op - OP_STORE_F) < 6)
  127. {
  128. Con_Printf ("%s",PR_GlobalString(s->a));
  129. Con_Printf ("%s", PR_GlobalStringNoContents(s->b));
  130. }
  131. else
  132. {
  133. if (s->a)
  134. Con_Printf ("%s",PR_GlobalString(s->a));
  135. if (s->b)
  136. Con_Printf ("%s",PR_GlobalString(s->b));
  137. if (s->c)
  138. Con_Printf ("%s", PR_GlobalStringNoContents(s->c));
  139. }
  140. Con_Printf ("\n");
  141. }
  142. /*
  143. ============
  144. PR_StackTrace
  145. ============
  146. */
  147. void PR_StackTrace (void)
  148. {
  149. dfunction_t *f;
  150. int i;
  151. if (pr_depth == 0)
  152. {
  153. Con_Printf ("<NO STACK>\n");
  154. return;
  155. }
  156. pr_stack[pr_depth].f = pr_xfunction;
  157. for (i=pr_depth ; i>=0 ; i--)
  158. {
  159. f = pr_stack[i].f;
  160. if (!f)
  161. {
  162. Con_Printf ("<NO FUNCTION>\n");
  163. }
  164. else
  165. Con_Printf ("%12s : %s\n", PR_GetString(f->s_file), PR_GetString(f->s_name));
  166. }
  167. }
  168. /*
  169. ============
  170. PR_Profile_f
  171. ============
  172. */
  173. void PR_Profile_f (void)
  174. {
  175. dfunction_t *f, *best;
  176. int max;
  177. int num;
  178. int i;
  179. num = 0;
  180. do
  181. {
  182. max = 0;
  183. best = NULL;
  184. for (i=0 ; i<progs->numfunctions ; i++)
  185. {
  186. f = &pr_functions[i];
  187. if (f->profile > max)
  188. {
  189. max = f->profile;
  190. best = f;
  191. }
  192. }
  193. if (best)
  194. {
  195. if (num < 10)
  196. Con_Printf ("%7i %s\n", best->profile, PR_GetString(best->s_name));
  197. num++;
  198. best->profile = 0;
  199. }
  200. } while (best);
  201. }
  202. /*
  203. ============
  204. PR_RunError
  205. Aborts the currently executing function
  206. ============
  207. */
  208. void PR_RunError (char *error, ...)
  209. {
  210. va_list argptr;
  211. char string[1024];
  212. va_start (argptr,error);
  213. vsprintf (string,error,argptr);
  214. va_end (argptr);
  215. PR_PrintStatement (pr_statements + pr_xstatement);
  216. PR_StackTrace ();
  217. Con_Printf ("%s\n", string);
  218. pr_depth = 0; // dump the stack so SV_Error can shutdown functions
  219. SV_Error ("Program error");
  220. }
  221. /*
  222. ============================================================================
  223. PR_ExecuteProgram
  224. The interpretation main loop
  225. ============================================================================
  226. */
  227. /*
  228. ====================
  229. PR_EnterFunction
  230. Returns the new program statement counter
  231. ====================
  232. */
  233. int PR_EnterFunction (dfunction_t *f)
  234. {
  235. int i, j, c, o;
  236. pr_stack[pr_depth].s = pr_xstatement;
  237. pr_stack[pr_depth].f = pr_xfunction;
  238. pr_depth++;
  239. if (pr_depth >= MAX_STACK_DEPTH)
  240. PR_RunError ("stack overflow");
  241. // save off any locals that the new function steps on
  242. c = f->locals;
  243. if (localstack_used + c > LOCALSTACK_SIZE)
  244. PR_RunError ("PR_ExecuteProgram: locals stack overflow\n");
  245. for (i=0 ; i < c ; i++)
  246. localstack[localstack_used+i] = ((int *)pr_globals)[f->parm_start + i];
  247. localstack_used += c;
  248. // copy parameters
  249. o = f->parm_start;
  250. for (i=0 ; i<f->numparms ; i++)
  251. {
  252. for (j=0 ; j<f->parm_size[i] ; j++)
  253. {
  254. ((int *)pr_globals)[o] = ((int *)pr_globals)[OFS_PARM0+i*3+j];
  255. o++;
  256. }
  257. }
  258. pr_xfunction = f;
  259. return f->first_statement - 1; // offset the s++
  260. }
  261. /*
  262. ====================
  263. PR_LeaveFunction
  264. ====================
  265. */
  266. int PR_LeaveFunction (void)
  267. {
  268. int i, c;
  269. if (pr_depth <= 0)
  270. SV_Error ("prog stack underflow");
  271. // restore locals from the stack
  272. c = pr_xfunction->locals;
  273. localstack_used -= c;
  274. if (localstack_used < 0)
  275. PR_RunError ("PR_ExecuteProgram: locals stack underflow\n");
  276. for (i=0 ; i < c ; i++)
  277. ((int *)pr_globals)[pr_xfunction->parm_start + i] = localstack[localstack_used+i];
  278. // up stack
  279. pr_depth--;
  280. pr_xfunction = pr_stack[pr_depth].f;
  281. return pr_stack[pr_depth].s;
  282. }
  283. /*
  284. ====================
  285. PR_ExecuteProgram
  286. ====================
  287. */
  288. void PR_ExecuteProgram (func_t fnum)
  289. {
  290. eval_t *a, *b, *c;
  291. int s;
  292. dstatement_t *st;
  293. dfunction_t *f, *newf;
  294. int runaway;
  295. int i;
  296. edict_t *ed;
  297. int exitdepth;
  298. eval_t *ptr;
  299. if (!fnum || fnum >= progs->numfunctions)
  300. {
  301. if (pr_global_struct->self)
  302. ED_Print (PROG_TO_EDICT(pr_global_struct->self));
  303. SV_Error ("PR_ExecuteProgram: NULL function");
  304. }
  305. f = &pr_functions[fnum];
  306. runaway = 100000;
  307. pr_trace = false;
  308. // make a stack frame
  309. exitdepth = pr_depth;
  310. s = PR_EnterFunction (f);
  311. while (1)
  312. {
  313. s++; // next statement
  314. st = &pr_statements[s];
  315. a = (eval_t *)&pr_globals[st->a];
  316. b = (eval_t *)&pr_globals[st->b];
  317. c = (eval_t *)&pr_globals[st->c];
  318. if (--runaway == 0)
  319. PR_RunError ("runaway loop error");
  320. pr_xfunction->profile++;
  321. pr_xstatement = s;
  322. if (pr_trace)
  323. PR_PrintStatement (st);
  324. switch (st->op)
  325. {
  326. case OP_ADD_F:
  327. c->_float = a->_float + b->_float;
  328. break;
  329. case OP_ADD_V:
  330. c->vector[0] = a->vector[0] + b->vector[0];
  331. c->vector[1] = a->vector[1] + b->vector[1];
  332. c->vector[2] = a->vector[2] + b->vector[2];
  333. break;
  334. case OP_SUB_F:
  335. c->_float = a->_float - b->_float;
  336. break;
  337. case OP_SUB_V:
  338. c->vector[0] = a->vector[0] - b->vector[0];
  339. c->vector[1] = a->vector[1] - b->vector[1];
  340. c->vector[2] = a->vector[2] - b->vector[2];
  341. break;
  342. case OP_MUL_F:
  343. c->_float = a->_float * b->_float;
  344. break;
  345. case OP_MUL_V:
  346. c->_float = a->vector[0]*b->vector[0]
  347. + a->vector[1]*b->vector[1]
  348. + a->vector[2]*b->vector[2];
  349. break;
  350. case OP_MUL_FV:
  351. c->vector[0] = a->_float * b->vector[0];
  352. c->vector[1] = a->_float * b->vector[1];
  353. c->vector[2] = a->_float * b->vector[2];
  354. break;
  355. case OP_MUL_VF:
  356. c->vector[0] = b->_float * a->vector[0];
  357. c->vector[1] = b->_float * a->vector[1];
  358. c->vector[2] = b->_float * a->vector[2];
  359. break;
  360. case OP_DIV_F:
  361. c->_float = a->_float / b->_float;
  362. break;
  363. case OP_BITAND:
  364. c->_float = (int)a->_float & (int)b->_float;
  365. break;
  366. case OP_BITOR:
  367. c->_float = (int)a->_float | (int)b->_float;
  368. break;
  369. case OP_GE:
  370. c->_float = a->_float >= b->_float;
  371. break;
  372. case OP_LE:
  373. c->_float = a->_float <= b->_float;
  374. break;
  375. case OP_GT:
  376. c->_float = a->_float > b->_float;
  377. break;
  378. case OP_LT:
  379. c->_float = a->_float < b->_float;
  380. break;
  381. case OP_AND:
  382. c->_float = a->_float && b->_float;
  383. break;
  384. case OP_OR:
  385. c->_float = a->_float || b->_float;
  386. break;
  387. case OP_NOT_F:
  388. c->_float = !a->_float;
  389. break;
  390. case OP_NOT_V:
  391. c->_float = !a->vector[0] && !a->vector[1] && !a->vector[2];
  392. break;
  393. case OP_NOT_S:
  394. c->_float = !a->string || !*PR_GetString(a->string);
  395. break;
  396. case OP_NOT_FNC:
  397. c->_float = !a->function;
  398. break;
  399. case OP_NOT_ENT:
  400. c->_float = (PROG_TO_EDICT(a->edict) == sv.edicts);
  401. break;
  402. case OP_EQ_F:
  403. c->_float = a->_float == b->_float;
  404. break;
  405. case OP_EQ_V:
  406. c->_float = (a->vector[0] == b->vector[0]) &&
  407. (a->vector[1] == b->vector[1]) &&
  408. (a->vector[2] == b->vector[2]);
  409. break;
  410. case OP_EQ_S:
  411. c->_float = !strcmp(PR_GetString(a->string), PR_GetString(b->string));
  412. break;
  413. case OP_EQ_E:
  414. c->_float = a->_int == b->_int;
  415. break;
  416. case OP_EQ_FNC:
  417. c->_float = a->function == b->function;
  418. break;
  419. case OP_NE_F:
  420. c->_float = a->_float != b->_float;
  421. break;
  422. case OP_NE_V:
  423. c->_float = (a->vector[0] != b->vector[0]) ||
  424. (a->vector[1] != b->vector[1]) ||
  425. (a->vector[2] != b->vector[2]);
  426. break;
  427. case OP_NE_S:
  428. c->_float = strcmp(PR_GetString(a->string), PR_GetString(b->string));
  429. break;
  430. case OP_NE_E:
  431. c->_float = a->_int != b->_int;
  432. break;
  433. case OP_NE_FNC:
  434. c->_float = a->function != b->function;
  435. break;
  436. //==================
  437. case OP_STORE_F:
  438. case OP_STORE_ENT:
  439. case OP_STORE_FLD: // integers
  440. case OP_STORE_S:
  441. case OP_STORE_FNC: // pointers
  442. b->_int = a->_int;
  443. break;
  444. case OP_STORE_V:
  445. b->vector[0] = a->vector[0];
  446. b->vector[1] = a->vector[1];
  447. b->vector[2] = a->vector[2];
  448. break;
  449. case OP_STOREP_F:
  450. case OP_STOREP_ENT:
  451. case OP_STOREP_FLD: // integers
  452. case OP_STOREP_S:
  453. case OP_STOREP_FNC: // pointers
  454. ptr = (eval_t *)((byte *)sv.edicts + b->_int);
  455. ptr->_int = a->_int;
  456. break;
  457. case OP_STOREP_V:
  458. ptr = (eval_t *)((byte *)sv.edicts + b->_int);
  459. ptr->vector[0] = a->vector[0];
  460. ptr->vector[1] = a->vector[1];
  461. ptr->vector[2] = a->vector[2];
  462. break;
  463. case OP_ADDRESS:
  464. ed = PROG_TO_EDICT(a->edict);
  465. #ifdef PARANOID
  466. NUM_FOR_EDICT(ed); // make sure it's in range
  467. #endif
  468. if (ed == (edict_t *)sv.edicts && sv.state == ss_active)
  469. PR_RunError ("assignment to world entity");
  470. c->_int = (byte *)((int *)&ed->v + b->_int) - (byte *)sv.edicts;
  471. break;
  472. case OP_LOAD_F:
  473. case OP_LOAD_FLD:
  474. case OP_LOAD_ENT:
  475. case OP_LOAD_S:
  476. case OP_LOAD_FNC:
  477. ed = PROG_TO_EDICT(a->edict);
  478. #ifdef PARANOID
  479. NUM_FOR_EDICT(ed); // make sure it's in range
  480. #endif
  481. a = (eval_t *)((int *)&ed->v + b->_int);
  482. c->_int = a->_int;
  483. break;
  484. case OP_LOAD_V:
  485. ed = PROG_TO_EDICT(a->edict);
  486. #ifdef PARANOID
  487. NUM_FOR_EDICT(ed); // make sure it's in range
  488. #endif
  489. a = (eval_t *)((int *)&ed->v + b->_int);
  490. c->vector[0] = a->vector[0];
  491. c->vector[1] = a->vector[1];
  492. c->vector[2] = a->vector[2];
  493. break;
  494. //==================
  495. case OP_IFNOT:
  496. if (!a->_int)
  497. s += st->b - 1; // offset the s++
  498. break;
  499. case OP_IF:
  500. if (a->_int)
  501. s += st->b - 1; // offset the s++
  502. break;
  503. case OP_GOTO:
  504. s += st->a - 1; // offset the s++
  505. break;
  506. case OP_CALL0:
  507. case OP_CALL1:
  508. case OP_CALL2:
  509. case OP_CALL3:
  510. case OP_CALL4:
  511. case OP_CALL5:
  512. case OP_CALL6:
  513. case OP_CALL7:
  514. case OP_CALL8:
  515. pr_argc = st->op - OP_CALL0;
  516. if (!a->function)
  517. PR_RunError ("NULL function");
  518. newf = &pr_functions[a->function];
  519. if (newf->first_statement < 0)
  520. { // negative statements are built in functions
  521. i = -newf->first_statement;
  522. if (i >= pr_numbuiltins)
  523. PR_RunError ("Bad builtin call number");
  524. pr_builtins[i] ();
  525. break;
  526. }
  527. s = PR_EnterFunction (newf);
  528. break;
  529. case OP_DONE:
  530. case OP_RETURN:
  531. pr_globals[OFS_RETURN] = pr_globals[st->a];
  532. pr_globals[OFS_RETURN+1] = pr_globals[st->a+1];
  533. pr_globals[OFS_RETURN+2] = pr_globals[st->a+2];
  534. s = PR_LeaveFunction ();
  535. if (pr_depth == exitdepth)
  536. return; // all done
  537. break;
  538. case OP_STATE:
  539. ed = PROG_TO_EDICT(pr_global_struct->self);
  540. ed->v.nextthink = pr_global_struct->time + 0.1;
  541. if (a->_float != ed->v.frame)
  542. {
  543. ed->v.frame = a->_float;
  544. }
  545. ed->v.think = b->function;
  546. break;
  547. default:
  548. PR_RunError ("Bad opcode %i", st->op);
  549. }
  550. }
  551. }
  552. /*----------------------*/
  553. char *pr_strtbl[MAX_PRSTR];
  554. int num_prstr;
  555. char *PR_GetString(int num)
  556. {
  557. if (num < 0) {
  558. //Con_DPrintf("GET:%d == %s\n", num, pr_strtbl[-num]);
  559. return pr_strtbl[-num];
  560. }
  561. return pr_strings + num;
  562. }
  563. int PR_SetString(char *s)
  564. {
  565. int i;
  566. if (s - pr_strings < 0) {
  567. for (i = 0; i <= num_prstr; i++)
  568. if (pr_strtbl[i] == s)
  569. break;
  570. if (i < num_prstr)
  571. return -i;
  572. if (num_prstr == MAX_PRSTR - 1)
  573. Sys_Error("MAX_PRSTR");
  574. num_prstr++;
  575. pr_strtbl[num_prstr] = s;
  576. //Con_DPrintf("SET:%d == %s\n", -num_prstr, s);
  577. return -num_prstr;
  578. }
  579. return (int)(s - pr_strings);
  580. }