vars.c 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /***** spin: vars.c *****/
  2. /* Copyright (c) 1991-2000 by Lucent Technologies - Bell Laboratories */
  3. /* All Rights Reserved. This software is for educational purposes only. */
  4. /* Permission is given to distribute this code provided that this intro- */
  5. /* ductory message is not removed and no monies are exchanged. */
  6. /* No guarantee is expressed or implied by the distribution of this code. */
  7. /* Software written by Gerard J. Holzmann as part of the book: */
  8. /* `Design and Validation of Computer Protocols,' ISBN 0-13-539925-4, */
  9. /* Prentice Hall, Englewood Cliffs, NJ, 07632. */
  10. /* Send bug-reports and/or questions to: gerard@research.bell-labs.com */
  11. #include "spin.h"
  12. #ifdef PC
  13. #include "y_tab.h"
  14. #else
  15. #include "y.tab.h"
  16. #endif
  17. extern Ordered *all_names;
  18. extern RunList *X, *LastX;
  19. extern Symbol *Fname;
  20. extern char Buf[];
  21. extern int lineno, depth, verbose, xspin, limited_vis;
  22. extern int analyze, jumpsteps, nproc, nstop, columns;
  23. extern short no_arrays, Have_claim, Skip_claim;
  24. extern void sr_mesg(FILE *, int, int);
  25. extern void sr_buf(int, int);
  26. static int getglobal(Lextok *);
  27. static int setglobal(Lextok *, int);
  28. static int maxcolnr = 1;
  29. int
  30. getval(Lextok *sn)
  31. { Symbol *s = sn->sym;
  32. if (strcmp(s->name, "_") == 0)
  33. { non_fatal("attempt to read value of '_'", 0);
  34. return 0;
  35. }
  36. if (strcmp(s->name, "_last") == 0)
  37. return (LastX)?LastX->pid:0;
  38. if (strcmp(s->name, "_p") == 0)
  39. return (X && X->pc)?X->pc->seqno:0;
  40. if (strcmp(s->name, "_pid") == 0)
  41. { if (!X) return 0;
  42. return X->pid - Have_claim;
  43. }
  44. if (strcmp(s->name, "_nr_pr") == 0)
  45. return nproc-nstop; /* new 3.3.10 */
  46. if (s->context && s->type)
  47. return getlocal(sn);
  48. if (!s->type) /* not declared locally */
  49. { s = lookup(s->name); /* try global */
  50. sn->sym = s; /* fix it */
  51. }
  52. return getglobal(sn);
  53. }
  54. int
  55. setval(Lextok *v, int n)
  56. {
  57. if (v->sym->context && v->sym->type)
  58. return setlocal(v, n);
  59. if (!v->sym->type)
  60. v->sym = lookup(v->sym->name);
  61. return setglobal(v, n);
  62. }
  63. void
  64. rm_selfrefs(Symbol *s, Lextok *i)
  65. {
  66. if (!i) return;
  67. if (i->ntyp == NAME
  68. && strcmp(i->sym->name, s->name) == 0
  69. && ( (!i->sym->context && !s->context)
  70. || ( i->sym->context && s->context
  71. && strcmp(i->sym->context->name, s->context->name) == 0)))
  72. { lineno = i->ln;
  73. Fname = i->fn;
  74. non_fatal("self-reference initializing '%s'", s->name);
  75. i->ntyp = CONST;
  76. i->val = 0;
  77. } else
  78. { rm_selfrefs(s, i->lft);
  79. rm_selfrefs(s, i->rgt);
  80. }
  81. }
  82. int
  83. checkvar(Symbol *s, int n)
  84. { int i, oln = lineno; /* calls on eval() change it */
  85. Symbol *ofnm = Fname;
  86. if (n >= s->nel || n < 0)
  87. { printf("spin: indexing %s[%d] - size is %d\n",
  88. s->name, n, s->nel);
  89. non_fatal("indexing array \'%s\'", s->name);
  90. return 0;
  91. }
  92. if (s->type == 0)
  93. { non_fatal("undecl var %s (assuming int)", s->name);
  94. s->type = INT;
  95. }
  96. /* not a STRUCT */
  97. if (s->val == (int *) 0) /* uninitialized */
  98. { s->val = (int *) emalloc(s->nel*sizeof(int));
  99. for (i = 0; i < s->nel; i++)
  100. { if (s->type != CHAN)
  101. { rm_selfrefs(s, s->ini);
  102. s->val[i] = eval(s->ini);
  103. } else if (!analyze)
  104. s->val[i] = qmake(s);
  105. } }
  106. lineno = oln;
  107. Fname = ofnm;
  108. return 1;
  109. }
  110. static int
  111. getglobal(Lextok *sn)
  112. { Symbol *s = sn->sym;
  113. int i, n = eval(sn->lft);
  114. if (s->type == 0 && X && (i = find_lab(s, X->n, 0)))
  115. { printf("findlab through getglobal on %s\n", s->name);
  116. return i; /* can this happen? */
  117. }
  118. if (s->type == STRUCT)
  119. return Rval_struct(sn, s, 1); /* 1 = check init */
  120. if (checkvar(s, n))
  121. return cast_val(s->type, s->val[n], s->nbits);
  122. return 0;
  123. }
  124. int
  125. cast_val(int t, int v, int w)
  126. { int i=0; short s=0; unsigned char u=0;
  127. if (t == INT || t == CHAN) i = v;
  128. else if (t == SHORT) s = (short) v;
  129. else if (t == BYTE || t == MTYPE) u = (unsigned char)v;
  130. else if (t == BIT) u = (unsigned char)(v&1);
  131. else if (t == UNSIGNED)
  132. { if (w == 0)
  133. fatal("cannot happen, cast_val", (char *)0);
  134. u = (unsigned char)(v& ((1<<w)-1));
  135. }
  136. if (v != i+s+u)
  137. { char buf[32]; sprintf(buf, "%d->%d (%d)", v, i+s+u, t);
  138. non_fatal("value (%s) truncated in assignment", buf);
  139. }
  140. return (int)(i+s+u);
  141. }
  142. static int
  143. setglobal(Lextok *v, int m)
  144. {
  145. if (v->sym->type == STRUCT)
  146. (void) Lval_struct(v, v->sym, 1, m);
  147. else
  148. { int n = eval(v->lft);
  149. if (checkvar(v->sym, n))
  150. { if (v->sym->nbits > 0)
  151. m = (m & ((1<<v->sym->nbits)-1));
  152. v->sym->val[n] = m;
  153. v->sym->setat = depth;
  154. } }
  155. return 1;
  156. }
  157. void
  158. dumpclaims(FILE *fd, int pid, char *s)
  159. { extern Lextok *Xu_List; extern int Pid;
  160. extern short terse;
  161. Lextok *m; int cnt = 0; int oPid = Pid;
  162. for (m = Xu_List; m; m = m->rgt)
  163. if (strcmp(m->sym->name, s) == 0)
  164. { cnt=1;
  165. break;
  166. }
  167. if (cnt == 0) return;
  168. Pid = pid;
  169. fprintf(fd, "#ifndef XUSAFE\n");
  170. for (m = Xu_List; m; m = m->rgt)
  171. { if (strcmp(m->sym->name, s) != 0)
  172. continue;
  173. no_arrays = 1;
  174. putname(fd, "\t\tsetq_claim(", m->lft, 0, "");
  175. no_arrays = 0;
  176. fprintf(fd, ", %d, ", m->val);
  177. terse = 1;
  178. putname(fd, "\"", m->lft, 0, "\", h, ");
  179. terse = 0;
  180. fprintf(fd, "\"%s\");\n", s);
  181. }
  182. fprintf(fd, "#endif\n");
  183. Pid = oPid;
  184. }
  185. void
  186. dumpglobals(void)
  187. { Ordered *walk;
  188. Lextok *dummy;
  189. Symbol *sp;
  190. int j;
  191. for (walk = all_names; walk; walk = walk->next)
  192. { sp = walk->entry;
  193. if (!sp->type || sp->context || sp->owner
  194. || sp->type == PROCTYPE || sp->type == PREDEF
  195. || (sp->type == MTYPE && ismtype(sp->name)))
  196. continue;
  197. if (sp->type == STRUCT)
  198. { dump_struct(sp, sp->name, 0);
  199. continue;
  200. }
  201. for (j = 0; j < sp->nel; j++)
  202. { int prefetch;
  203. if (sp->type == CHAN)
  204. { doq(sp, j, 0);
  205. continue;
  206. }
  207. if ((verbose&4) && !(verbose&64)
  208. && (sp->setat < depth
  209. && jumpsteps != depth))
  210. continue;
  211. dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
  212. dummy->sym = sp;
  213. dummy->lft->val = j;
  214. /* in case of cast_val warnings, do this first: */
  215. prefetch = getglobal(dummy);
  216. printf("\t\t%s", sp->name);
  217. if (sp->nel > 1) printf("[%d]", j);
  218. printf(" = ");
  219. sr_mesg(stdout, prefetch,
  220. sp->type == MTYPE);
  221. printf("\n");
  222. if (limited_vis && (sp->hidden&2))
  223. { int colpos;
  224. Buf[0] = '\0';
  225. if (!xspin)
  226. { if (columns == 2)
  227. sprintf(Buf, "~G%s = ", sp->name);
  228. else
  229. sprintf(Buf, "%s = ", sp->name);
  230. }
  231. sr_buf(prefetch, sp->type == MTYPE);
  232. if (sp->colnr == 0)
  233. { sp->colnr = maxcolnr;
  234. maxcolnr = 1+(maxcolnr%10);
  235. }
  236. colpos = nproc+sp->colnr-1;
  237. if (columns == 2)
  238. { pstext(colpos, Buf);
  239. continue;
  240. }
  241. if (!xspin)
  242. { printf("\t\t%s\n", Buf);
  243. continue;
  244. }
  245. printf("MSC: ~G %s %s\n", sp->name, Buf);
  246. printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ",
  247. depth, colpos);
  248. printf("(state 0)\t[printf('MSC: globvar\\\\n')]\n");
  249. printf("\t\t%s", sp->name);
  250. if (sp->nel > 1) printf("[%d]", j);
  251. printf(" = %s\n", Buf);
  252. } } }
  253. }
  254. void
  255. dumplocal(RunList *r)
  256. { Lextok *dummy;
  257. Symbol *z, *s = r->symtab;
  258. int i;
  259. for (z = s; z; z = z->next)
  260. { if (z->type == STRUCT)
  261. { dump_struct(z, z->name, r);
  262. continue;
  263. }
  264. for (i = 0; i < z->nel; i++)
  265. { if (z->type == CHAN)
  266. { doq(z, i, r);
  267. continue;
  268. }
  269. if ((verbose&4) && !(verbose&64)
  270. && (z->setat < depth
  271. && jumpsteps != depth))
  272. continue;
  273. dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
  274. dummy->sym = z;
  275. dummy->lft->val = i;
  276. printf("\t\t%s(%d):%s",
  277. r->n->name, r->pid, z->name);
  278. if (z->nel > 1) printf("[%d]", i);
  279. printf(" = ");
  280. sr_mesg(stdout, getval(dummy),
  281. z->type == MTYPE);
  282. printf("\n");
  283. if (limited_vis && (z->hidden&2))
  284. { int colpos;
  285. Buf[0] = '\0';
  286. if (!xspin)
  287. { if (columns == 2)
  288. sprintf(Buf, "~G%s(%d):%s = ",
  289. r->n->name, r->pid, z->name);
  290. else
  291. sprintf(Buf, "%s(%d):%s = ",
  292. r->n->name, r->pid, z->name);
  293. }
  294. sr_buf(getval(dummy), z->type==MTYPE);
  295. if (z->colnr == 0)
  296. { z->colnr = maxcolnr;
  297. maxcolnr = 1+(maxcolnr%10);
  298. }
  299. colpos = nproc+z->colnr-1;
  300. if (columns == 2)
  301. { pstext(colpos, Buf);
  302. continue;
  303. }
  304. if (!xspin)
  305. { printf("\t\t%s\n", Buf);
  306. continue;
  307. }
  308. printf("MSC: ~G %s(%d):%s %s\n",
  309. r->n->name, r->pid, z->name, Buf);
  310. printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ",
  311. depth, colpos);
  312. printf("(state 0)\t[printf('MSC: locvar\\\\n')]\n");
  313. printf("\t\t%s(%d):%s",
  314. r->n->name, r->pid, z->name);
  315. if (z->nel > 1) printf("[%d]", i);
  316. printf(" = %s\n", Buf);
  317. } } }
  318. }