vars.c 8.2 KB

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