1 /***** spin: vars.c *****/
2
3 /*
4 * This file is part of the public release of Spin. It is subject to the
5 * terms in the LICENSE file that is included in this source directory.
6 * Tool documentation is available at http://spinroot.com
7 */
8
9 #include "spin.h"
10 #include "y.tab.h"
11
12 extern char GBuf[];
13 extern int analyze, jumpsteps, nproc, nstop, columns, old_priority_rules;
14 extern int lineno, depth, verbose, xspin, limited_vis, Pid_nr;
15 extern Lextok *Xu_List;
16 extern Ordered *all_names;
17 extern RunList *X_lst, *LastX;
18 extern short no_arrays, Have_claim, terse;
19 extern Symbol *Fname;
20
21 extern void sr_buf(int, int, const char *);
22 extern void sr_mesg(FILE *, int, int, const char *);
23
24 static int getglobal(Lextok *);
25 static int setglobal(Lextok *, int);
26 static int maxcolnr = 1;
27
28 int
getval(Lextok * sn)29 getval(Lextok *sn)
30 { Symbol *s = sn->sym;
31
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_lst && X_lst->pc)?X_lst->pc->seqno:0;
40 if (strcmp(s->name, "_pid") == 0)
41 { if (!X_lst) return 0;
42 return X_lst->pid - Have_claim;
43 }
44 if (strcmp(s->name, "_priority") == 0)
45 { if (!X_lst) return 0;
46
47 if (old_priority_rules)
48 { non_fatal("cannot refer to _priority with -o6", (char *) 0);
49 return 1;
50 }
51 return X_lst->priority;
52 }
53
54 if (strcmp(s->name, "_nr_pr") == 0)
55 { return nproc-nstop; /* new 3.3.10 */
56 }
57
58 if (s->context && s->type)
59 { return getlocal(sn);
60 }
61
62 if (!s->type) /* not declared locally */
63 { s = lookup(s->name); /* try global */
64 sn->sym = s; /* fix it */
65 }
66
67 return getglobal(sn);
68 }
69
70 int
setval(Lextok * v,int n)71 setval(Lextok *v, int n)
72 {
73 if (strcmp(v->sym->name, "_last") == 0
74 || strcmp(v->sym->name, "_p") == 0
75 || strcmp(v->sym->name, "_pid") == 0
76 || strcmp(v->sym->name, "_nr_qs") == 0
77 || strcmp(v->sym->name, "_nr_pr") == 0)
78 { non_fatal("illegal assignment to %s", v->sym->name);
79 }
80 if (strcmp(v->sym->name, "_priority") == 0)
81 { if (old_priority_rules)
82 { non_fatal("cannot refer to _priority with -o6", (char *) 0);
83 return 1;
84 }
85 if (!X_lst)
86 { non_fatal("no context for _priority", (char *) 0);
87 return 1;
88 }
89 X_lst->priority = n;
90 }
91
92 if (v->sym->context && v->sym->type)
93 return setlocal(v, n);
94 if (!v->sym->type)
95 v->sym = lookup(v->sym->name);
96 return setglobal(v, n);
97 }
98
99 void
rm_selfrefs(Symbol * s,Lextok * i)100 rm_selfrefs(Symbol *s, Lextok *i)
101 {
102 if (!i) return;
103
104 if (i->ntyp == NAME
105 && strcmp(i->sym->name, s->name) == 0
106 && ( (!i->sym->context && !s->context)
107 || ( i->sym->context && s->context
108 && strcmp(i->sym->context->name, s->context->name) == 0)))
109 { lineno = i->ln;
110 Fname = i->fn;
111 non_fatal("self-reference initializing '%s'", s->name);
112 i->ntyp = CONST;
113 i->val = 0;
114 } else
115 { rm_selfrefs(s, i->lft);
116 rm_selfrefs(s, i->rgt);
117 }
118 }
119
120 int
checkvar(Symbol * s,int n)121 checkvar(Symbol *s, int n)
122 { int i, oln = lineno; /* calls on eval() change it */
123 Symbol *ofnm = Fname;
124 Lextok *z, *y;
125
126 if (!in_bound(s, n))
127 return 0;
128
129 if (s->type == 0)
130 { non_fatal("undecl var %s (assuming int)", s->name);
131 s->type = INT;
132 }
133 /* not a STRUCT */
134 if (s->val == (int *) 0) /* uninitialized */
135 { s->val = (int *) emalloc(s->nel*sizeof(int));
136 z = s->ini;
137 for (i = 0; i < s->nel; i++)
138 { if (z && z->ntyp == ',')
139 { y = z->lft;
140 z = z->rgt;
141 } else
142 { y = z;
143 }
144 if (s->type != CHAN)
145 { rm_selfrefs(s, y);
146 s->val[i] = eval(y);
147 } else if (!analyze)
148 { s->val[i] = qmake(s);
149 } } }
150 lineno = oln;
151 Fname = ofnm;
152
153 return 1;
154 }
155
156 static int
getglobal(Lextok * sn)157 getglobal(Lextok *sn)
158 { Symbol *s = sn->sym;
159 int i, n = eval(sn->lft);
160
161 if (s->type == 0 && X_lst && (i = find_lab(s, X_lst->n, 0))) /* getglobal */
162 { printf("findlab through getglobal on %s\n", s->name);
163 return i; /* can this happen? */
164 }
165 if (s->type == STRUCT)
166 { return Rval_struct(sn, s, 1); /* 1 = check init */
167 }
168 if (checkvar(s, n))
169 { return cast_val(s->type, s->val[n], s->nbits);
170 }
171 return 0;
172 }
173
174 int
cast_val(int t,int v,int w)175 cast_val(int t, int v, int w)
176 { int i=0; short s=0; unsigned int u=0;
177
178 if (t == PREDEF || t == INT || t == CHAN) i = v; /* predef means _ */
179 else if (t == SHORT) s = (short) v;
180 else if (t == BYTE || t == MTYPE) u = (unsigned char)v;
181 else if (t == BIT) u = (unsigned char)(v&1);
182 else if (t == UNSIGNED)
183 { if (w == 0)
184 fatal("cannot happen, cast_val", (char *)0);
185 /* u = (unsigned)(v& ((1<<w)-1)); problem when w=32 */
186 u = (unsigned)(v& (~0u>>(8*sizeof(unsigned)-w))); /* doug */
187 }
188
189 if (v != i+s+ (int) u)
190 { char buf[64]; sprintf(buf, "%d->%d (%d)", v, i+s+(int)u, t);
191 non_fatal("value (%s) truncated in assignment", buf);
192 }
193 return (int)(i+s+(int)u);
194 }
195
196 static int
setglobal(Lextok * v,int m)197 setglobal(Lextok *v, int m)
198 {
199 if (v->sym->type == STRUCT)
200 { (void) Lval_struct(v, v->sym, 1, m);
201 } else
202 { int n = eval(v->lft);
203 if (checkvar(v->sym, n))
204 { int oval = v->sym->val[n];
205 int nval = cast_val(v->sym->type, m, v->sym->nbits);
206 v->sym->val[n] = nval;
207 if (oval != nval)
208 { v->sym->setat = depth;
209 } } }
210 return 1;
211 }
212
213 void
dumpclaims(FILE * fd,int pid,char * s)214 dumpclaims(FILE *fd, int pid, char *s)
215 { Lextok *m; int cnt = 0; int oPid = Pid_nr;
216
217 for (m = Xu_List; m; m = m->rgt)
218 if (strcmp(m->sym->name, s) == 0)
219 { cnt=1;
220 break;
221 }
222 if (cnt == 0) return;
223
224 Pid_nr = pid;
225 fprintf(fd, "#ifndef XUSAFE\n");
226 for (m = Xu_List; m; m = m->rgt)
227 { if (strcmp(m->sym->name, s) != 0)
228 continue;
229 no_arrays = 1;
230 putname(fd, "\t\tsetq_claim(", m->lft, 0, "");
231 no_arrays = 0;
232 fprintf(fd, ", %d, ", m->val);
233 terse = 1;
234 putname(fd, "\"", m->lft, 0, "\", h, ");
235 terse = 0;
236 fprintf(fd, "\"%s\");\n", s);
237 }
238 fprintf(fd, "#endif\n");
239 Pid_nr = oPid;
240 }
241
242 void
dumpglobals(void)243 dumpglobals(void)
244 { Ordered *walk;
245 static Lextok *dummy = ZN;
246 Symbol *sp;
247 int j;
248
249 if (!dummy)
250 dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
251
252 for (walk = all_names; walk; walk = walk->next)
253 { sp = walk->entry;
254 if (!sp->type || sp->context || sp->owner
255 || sp->type == PROCTYPE || sp->type == PREDEF
256 || sp->type == CODE_FRAG || sp->type == CODE_DECL
257 || (sp->type == MTYPE && ismtype(sp->name)))
258 continue;
259
260 if (sp->type == STRUCT)
261 { if ((verbose&4) && !(verbose&64)
262 && (sp->setat < depth
263 && jumpsteps != depth))
264 { continue;
265 }
266 dump_struct(sp, sp->name, 0);
267 continue;
268 }
269 for (j = 0; j < sp->nel; j++)
270 { int prefetch;
271 char *s = 0;
272 if (sp->type == CHAN)
273 { doq(sp, j, 0);
274 continue;
275 }
276 if ((verbose&4) && !(verbose&64)
277 && (sp->setat < depth
278 && jumpsteps != depth))
279 { continue;
280 }
281
282 dummy->sym = sp;
283 dummy->lft->val = j;
284 /* in case of cast_val warnings, do this first: */
285 prefetch = getglobal(dummy);
286 printf("\t\t%s", sp->name);
287 if (sp->nel > 1 || sp->isarray) printf("[%d]", j);
288 printf(" = ");
289 if (sp->type == MTYPE
290 && sp->mtype_name)
291 { s = sp->mtype_name->name;
292 }
293 sr_mesg(stdout, prefetch, sp->type == MTYPE, s);
294 printf("\n");
295 if (limited_vis && (sp->hidden&2))
296 { int colpos;
297 GBuf[0] = '\0';
298 if (!xspin)
299 { if (columns == 2)
300 sprintf(GBuf, "~G%s = ", sp->name);
301 else
302 sprintf(GBuf, "%s = ", sp->name);
303 }
304 sr_buf(prefetch, sp->type == MTYPE, s);
305 if (sp->colnr == 0)
306 { sp->colnr = (unsigned char) maxcolnr;
307 maxcolnr = 1+(maxcolnr%10);
308 }
309 colpos = nproc+sp->colnr-1;
310 if (columns == 2)
311 { pstext(colpos, GBuf);
312 continue;
313 }
314 if (!xspin)
315 { printf("\t\t%s\n", GBuf);
316 continue;
317 }
318 printf("MSC: ~G %s %s\n", sp->name, GBuf);
319 printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ",
320 depth, colpos);
321 printf("(state 0)\t[printf('MSC: globvar\\\\n')]\n");
322 printf("\t\t%s", sp->name);
323 if (sp->nel > 1 || sp->isarray) printf("[%d]", j);
324 printf(" = %s\n", GBuf);
325 } } }
326 }
327
328 void
dumplocal(RunList * r,int final)329 dumplocal(RunList *r, int final)
330 { static Lextok *dummy = ZN;
331 Symbol *z, *s;
332 int i;
333
334 if (!r) return;
335
336 s = r->symtab;
337
338 if (!dummy)
339 { dummy = nn(ZN, NAME, nn(ZN,CONST,ZN,ZN), ZN);
340 }
341
342 for (z = s; z; z = z->next)
343 { if (z->type == STRUCT)
344 { dump_struct(z, z->name, r);
345 continue;
346 }
347 for (i = 0; i < z->nel; i++)
348 { char *t = 0;
349 if (z->type == CHAN)
350 { doq(z, i, r);
351 continue;
352 }
353
354 if ((verbose&4) && !(verbose&64)
355 && !final
356 && (z->setat < depth
357 && jumpsteps != depth))
358 { continue;
359 }
360
361 dummy->sym = z;
362 dummy->lft->val = i;
363
364 printf("\t\t%s(%d):%s",
365 r->n->name, r->pid - Have_claim, z->name);
366 if (z->nel > 1 || z->isarray) printf("[%d]", i);
367 printf(" = ");
368
369 if (z->type == MTYPE
370 && z->mtype_name)
371 { t = z->mtype_name->name;
372 }
373 sr_mesg(stdout, getval(dummy), z->type == MTYPE, t);
374 printf("\n");
375 if (limited_vis && (z->hidden&2))
376 { int colpos;
377 GBuf[0] = '\0';
378 if (!xspin)
379 { if (columns == 2)
380 sprintf(GBuf, "~G%s(%d):%s = ",
381 r->n->name, r->pid, z->name);
382 else
383 sprintf(GBuf, "%s(%d):%s = ",
384 r->n->name, r->pid, z->name);
385 }
386 sr_buf(getval(dummy), z->type==MTYPE, t);
387 if (z->colnr == 0)
388 { z->colnr = (unsigned char) maxcolnr;
389 maxcolnr = 1+(maxcolnr%10);
390 }
391 colpos = nproc+z->colnr-1;
392 if (columns == 2)
393 { pstext(colpos, GBuf);
394 continue;
395 }
396 if (!xspin)
397 { printf("\t\t%s\n", GBuf);
398 continue;
399 }
400 printf("MSC: ~G %s(%d):%s %s\n",
401 r->n->name, r->pid, z->name, GBuf);
402
403 printf("%3d:\tproc %3d (TRACK) line 1 \"var\" ",
404 depth, colpos);
405 printf("(state 0)\t[printf('MSC: locvar\\\\n')]\n");
406 printf("\t\t%s(%d):%s",
407 r->n->name, r->pid, z->name);
408 if (z->nel > 1 || z->isarray) printf("[%d]", i);
409 printf(" = %s\n", GBuf);
410 } } }
411 }
412