1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 #include "go.h"
6
7 /*
8 * machine size and rounding
9 * alignment is dictated around
10 * the size of a pointer, set in betypeinit
11 * (see ../6g/galign.c).
12 */
13
14 static int defercalc;
15
16 uint32
17 rnd(uint32 o, uint32 r)
18 {
19 if(r < 1 || r > 8 || (r&(r-1)) != 0)
20 fatal("rnd");
21 return (o+r-1)&~(r-1);
22 }
23
24 static void
25 offmod(Type *t)
26 {
27 Type *f;
28 int32 o;
29
30 o = 0;
31 for(f=t->type; f!=T; f=f->down) {
32 if(f->etype != TFIELD)
33 fatal("offmod: not TFIELD: %lT", f);
34 f->width = o;
35 o += widthptr;
36 if(o >= MAXWIDTH) {
37 yyerror("interface too large");
38 o = widthptr;
39 }
40 }
41 }
42
43 static vlong
44 widstruct(Type *errtype, Type *t, vlong o, int flag)
45 {
46 Type *f;
47 int32 w, maxalign;
48
49 maxalign = flag;
50 if(maxalign < 1)
51 maxalign = 1;
52 for(f=t->type; f!=T; f=f->down) {
53 if(f->etype != TFIELD)
54 fatal("widstruct: not TFIELD: %lT", f);
55 dowidth(f->type);
56 if(f->type->align > maxalign)
57 maxalign = f->type->align;
58 if(f->type->width < 0)
59 fatal("invalid width %lld", f->type->width);
60 w = f->type->width;
61 if(f->type->align > 0)
62 o = rnd(o, f->type->align);
63 f->width = o; // really offset for TFIELD
64 if(f->nname != N) {
65 // this same stackparam logic is in addrescapes
66 // in typecheck.c. usually addrescapes runs after
67 // widstruct, in which case we could drop this,
68 // but function closure functions are the exception.
69 if(f->nname->stackparam) {
70 f->nname->stackparam->xoffset = o;
71 f->nname->xoffset = 0;
72 } else
73 f->nname->xoffset = o;
74 }
75 o += w;
76 if(o >= MAXWIDTH) {
77 yyerror("type %lT too large", errtype);
78 o = 8; // small but nonzero
79 }
80 }
81 // final width is rounded
82 if(flag)
83 o = rnd(o, maxalign);
84 t->align = maxalign;
85
86 // type width only includes back to first field's offset
87 if(t->type == T)
88 t->width = 0;
89 else
90 t->width = o - t->type->width;
91 return o;
92 }
93
94 void
95 dowidth(Type *t)
96 {
97 int32 et;
98 int64 w;
99 int lno;
100 Type *t1;
101
102 if(widthptr == 0)
103 fatal("dowidth without betypeinit");
104
105 if(t == T)
106 return;
107
108 if(t->width > 0)
109 return;
110
111 if(t->width == -2) {
112 lno = lineno;
113 lineno = t->lineno;
114 yyerror("invalid recursive type %T", t);
115 t->width = 0;
116 lineno = lno;
117 return;
118 }
119
120 // defer checkwidth calls until after we're done
121 defercalc++;
122
123 lno = lineno;
124 lineno = t->lineno;
125 t->width = -2;
126 t->align = 0;
127
128 et = t->etype;
129 switch(et) {
130 case TFUNC:
131 case TCHAN:
132 case TMAP:
133 case TSTRING:
134 break;
135
136 default:
137 /* simtype == 0 during bootstrap */
138 if(simtype[t->etype] != 0)
139 et = simtype[t->etype];
140 break;
141 }
142
143 w = 0;
144 switch(et) {
145 default:
146 fatal("dowidth: unknown type: %T", t);
147 break;
148
149 /* compiler-specific stuff */
150 case TINT8:
151 case TUINT8:
152 case TBOOL: // bool is int8
153 w = 1;
154 break;
155 case TINT16:
156 case TUINT16:
157 w = 2;
158 break;
159 case TINT32:
160 case TUINT32:
161 case TFLOAT32:
162 w = 4;
163 break;
164 case TINT64:
165 case TUINT64:
166 case TFLOAT64:
167 case TCOMPLEX64:
168 w = 8;
169 t->align = widthptr;
170 break;
171 case TCOMPLEX128:
172 w = 16;
173 t->align = widthptr;
174 break;
175 case TPTR32:
176 w = 4;
177 checkwidth(t->type);
178 break;
179 case TPTR64:
180 w = 8;
181 checkwidth(t->type);
182 break;
183 case TUNSAFEPTR:
184 w = widthptr;
185 break;
186 case TINTER: // implemented as 2 pointers
187 w = 2*widthptr;
188 t->align = widthptr;
189 offmod(t);
190 break;
191 case TCHAN: // implemented as pointer
192 w = widthptr;
193 checkwidth(t->type);
194
195 // make fake type to check later to
196 // trigger channel argument check.
197 t1 = typ(TCHANARGS);
198 t1->type = t;
199 checkwidth(t1);
200 break;
201 case TCHANARGS:
202 t1 = t->type;
203 dowidth(t->type); // just in case
204 if(t1->type->width >= (1<<16))
205 yyerror("channel element type too large (>64kB)");
206 t->width = 1;
207 break;
208 case TMAP: // implemented as pointer
209 w = widthptr;
210 checkwidth(t->type);
211 checkwidth(t->down);
212 break;
213 case TFORW: // should have been filled in
214 yyerror("invalid recursive type %T", t);
215 w = 1; // anything will do
216 break;
217 case TANY:
218 // dummy type; should be replaced before use.
219 if(!debug['A'])
220 fatal("dowidth any");
221 w = 1; // anything will do
222 break;
223 case TSTRING:
224 if(sizeof_String == 0)
225 fatal("early dowidth string");
226 w = sizeof_String;
227 t->align = widthptr;
228 break;
229 case TARRAY:
230 if(t->type == T)
231 break;
232 if(t->bound >= 0) {
233 uint64 cap;
234
235 dowidth(t->type);
236 if(t->type->width != 0) {
237 cap = (MAXWIDTH-1) / t->type->width;
238 if(t->bound > cap)
239 yyerror("type %lT larger than address space", t);
240 }
241 w = t->bound * t->type->width;
242 t->align = t->type->align;
243 }
244 else if(t->bound == -1) {
245 w = sizeof_Array;
246 checkwidth(t->type);
247 t->align = widthptr;
248 }
249 else if(t->bound == -100)
250 yyerror("use of [...] array outside of array literal");
251 else
252 fatal("dowidth %T", t); // probably [...]T
253 break;
254
255 case TSTRUCT:
256 if(t->funarg)
257 fatal("dowidth fn struct %T", t);
258 w = widstruct(t, t, 0, 1);
259 break;
260
261 case TFUNC:
262 // make fake type to check later to
263 // trigger function argument computation.
264 t1 = typ(TFUNCARGS);
265 t1->type = t;
266 checkwidth(t1);
267
268 // width of func type is pointer
269 w = widthptr;
270 break;
271
272 case TFUNCARGS:
273 // function is 3 cated structures;
274 // compute their widths as side-effect.
275 t1 = t->type;
276 w = widstruct(t->type, *getthis(t1), 0, 0);
277 w = widstruct(t->type, *getinarg(t1), w, widthptr);
278 w = widstruct(t->type, *getoutarg(t1), w, widthptr);
279 t1->argwid = w;
280 if(w%widthptr)
281 warn("bad type %T %d\n", t1, w);
282 t->align = 1;
283 break;
284 }
285
286 t->width = w;
287 if(t->align == 0) {
288 if(w > 8 || (w&(w-1)) != 0)
289 fatal("invalid alignment for %T", t);
290 t->align = w;
291 }
292 lineno = lno;
293
294 if(defercalc == 1)
295 resumecheckwidth();
296 else
297 --defercalc;
298 }
299
300 /*
301 * when a type's width should be known, we call checkwidth
302 * to compute it. during a declaration like
303 *
304 * type T *struct { next T }
305 *
306 * it is necessary to defer the calculation of the struct width
307 * until after T has been initialized to be a pointer to that struct.
308 * similarly, during import processing structs may be used
309 * before their definition. in those situations, calling
310 * defercheckwidth() stops width calculations until
311 * resumecheckwidth() is called, at which point all the
312 * checkwidths that were deferred are executed.
313 * dowidth should only be called when the type's size
314 * is needed immediately. checkwidth makes sure the
315 * size is evaluated eventually.
316 */
317 typedef struct TypeList TypeList;
318 struct TypeList {
319 Type *t;
320 TypeList *next;
321 };
322
323 static TypeList *tlfree;
324 static TypeList *tlq;
325
326 void
327 checkwidth(Type *t)
328 {
329 TypeList *l;
330
331 if(t == T)
332 return;
333
334 // function arg structs should not be checked
335 // outside of the enclosing function.
336 if(t->funarg)
337 fatal("checkwidth %T", t);
338
339 if(!defercalc) {
340 dowidth(t);
341 return;
342 }
343 if(t->deferwidth)
344 return;
345 t->deferwidth = 1;
346
347 l = tlfree;
348 if(l != nil)
349 tlfree = l->next;
350 else
351 l = mal(sizeof *l);
352
353 l->t = t;
354 l->next = tlq;
355 tlq = l;
356 }
357
358 void
359 defercheckwidth(void)
360 {
361 // we get out of sync on syntax errors, so don't be pedantic.
362 if(defercalc && nerrors == 0)
363 fatal("defercheckwidth");
364 defercalc = 1;
365 }
366
367 void
368 resumecheckwidth(void)
369 {
370 TypeList *l;
371
372 if(!defercalc)
373 fatal("resumecheckwidth");
374 for(l = tlq; l != nil; l = tlq) {
375 l->t->deferwidth = 0;
376 tlq = l->next;
377 dowidth(l->t);
378 l->next = tlfree;
379 tlfree = l;
380 }
381 defercalc = 0;
382 }
383
384 void
385 typeinit(void)
386 {
387 int i, etype, sameas;
388 Type *t;
389 Sym *s, *s1;
390
391 if(widthptr == 0)
392 fatal("typeinit before betypeinit");
393
394 for(i=0; i<NTYPE; i++)
395 simtype[i] = i;
396
397 types[TPTR32] = typ(TPTR32);
398 dowidth(types[TPTR32]);
399
400 types[TPTR64] = typ(TPTR64);
401 dowidth(types[TPTR64]);
402
403 t = typ(TUNSAFEPTR);
404 types[TUNSAFEPTR] = t;
405 t->sym = pkglookup("Pointer", unsafepkg);
406 t->sym->def = typenod(t);
407
408 dowidth(types[TUNSAFEPTR]);
409
410 tptr = TPTR32;
411 if(widthptr == 8)
412 tptr = TPTR64;
413
414 for(i=TINT8; i<=TUINT64; i++)
415 isint[i] = 1;
416 isint[TINT] = 1;
417 isint[TUINT] = 1;
418 isint[TUINTPTR] = 1;
419
420 isfloat[TFLOAT32] = 1;
421 isfloat[TFLOAT64] = 1;
422
423 iscomplex[TCOMPLEX64] = 1;
424 iscomplex[TCOMPLEX128] = 1;
425
426 isptr[TPTR32] = 1;
427 isptr[TPTR64] = 1;
428
429 isforw[TFORW] = 1;
430
431 issigned[TINT] = 1;
432 issigned[TINT8] = 1;
433 issigned[TINT16] = 1;
434 issigned[TINT32] = 1;
435 issigned[TINT64] = 1;
436
437 /*
438 * initialize okfor
439 */
440 for(i=0; i<NTYPE; i++) {
441 if(isint[i] || i == TIDEAL) {
442 okforeq[i] = 1;
443 okforcmp[i] = 1;
444 okforarith[i] = 1;
445 okforadd[i] = 1;
446 okforand[i] = 1;
447 okforconst[i] = 1;
448 issimple[i] = 1;
449 minintval[i] = mal(sizeof(*minintval[i]));
450 maxintval[i] = mal(sizeof(*maxintval[i]));
451 }
452 if(isfloat[i]) {
453 okforeq[i] = 1;
454 okforcmp[i] = 1;
455 okforadd[i] = 1;
456 okforarith[i] = 1;
457 okforconst[i] = 1;
458 issimple[i] = 1;
459 minfltval[i] = mal(sizeof(*minfltval[i]));
460 maxfltval[i] = mal(sizeof(*maxfltval[i]));
461 }
462 if(iscomplex[i]) {
463 okforeq[i] = 1;
464 okforadd[i] = 1;
465 okforarith[i] = 1;
466 okforconst[i] = 1;
467 issimple[i] = 1;
468 }
469 }
470
471 issimple[TBOOL] = 1;
472
473 okforadd[TSTRING] = 1;
474
475 okforbool[TBOOL] = 1;
476
477 okforcap[TARRAY] = 1;
478 okforcap[TCHAN] = 1;
479
480 okforconst[TBOOL] = 1;
481 okforconst[TSTRING] = 1;
482
483 okforlen[TARRAY] = 1;
484 okforlen[TCHAN] = 1;
485 okforlen[TMAP] = 1;
486 okforlen[TSTRING] = 1;
487
488 okforeq[TPTR32] = 1;
489 okforeq[TPTR64] = 1;
490 okforeq[TUNSAFEPTR] = 1;
491 okforeq[TINTER] = 1;
492 okforeq[TMAP] = 1;
493 okforeq[TCHAN] = 1;
494 okforeq[TFUNC] = 1;
495 okforeq[TSTRING] = 1;
496 okforeq[TBOOL] = 1;
497 okforeq[TARRAY] = 1; // refined in typecheck
498
499 okforcmp[TSTRING] = 1;
500
501 for(i=0; i<nelem(okfor); i++)
502 okfor[i] = okfornone;
503
504 // binary
505 okfor[OADD] = okforadd;
506 okfor[OAND] = okforand;
507 okfor[OANDAND] = okforbool;
508 okfor[OANDNOT] = okforand;
509 okfor[ODIV] = okforarith;
510 okfor[OEQ] = okforeq;
511 okfor[OGE] = okforcmp;
512 okfor[OGT] = okforcmp;
513 okfor[OLE] = okforcmp;
514 okfor[OLT] = okforcmp;
515 okfor[OMOD] = okforand;
516 okfor[OMUL] = okforarith;
517 okfor[ONE] = okforeq;
518 okfor[OOR] = okforand;
519 okfor[OOROR] = okforbool;
520 okfor[OSUB] = okforarith;
521 okfor[OXOR] = okforand;
522 okfor[OLSH] = okforand;
523 okfor[ORSH] = okforand;
524
525 // unary
526 okfor[OCOM] = okforand;
527 okfor[OMINUS] = okforarith;
528 okfor[ONOT] = okforbool;
529 okfor[OPLUS] = okforarith;
530
531 // special
532 okfor[OCAP] = okforcap;
533 okfor[OLEN] = okforlen;
534
535 // comparison
536 iscmp[OLT] = 1;
537 iscmp[OGT] = 1;
538 iscmp[OGE] = 1;
539 iscmp[OLE] = 1;
540 iscmp[OEQ] = 1;
541 iscmp[ONE] = 1;
542
543 mpatofix(maxintval[TINT8], "0x7f");
544 mpatofix(minintval[TINT8], "-0x80");
545 mpatofix(maxintval[TINT16], "0x7fff");
546 mpatofix(minintval[TINT16], "-0x8000");
547 mpatofix(maxintval[TINT32], "0x7fffffff");
548 mpatofix(minintval[TINT32], "-0x80000000");
549 mpatofix(maxintval[TINT64], "0x7fffffffffffffff");
550 mpatofix(minintval[TINT64], "-0x8000000000000000");
551
552 mpatofix(maxintval[TUINT8], "0xff");
553 mpatofix(maxintval[TUINT16], "0xffff");
554 mpatofix(maxintval[TUINT32], "0xffffffff");
555 mpatofix(maxintval[TUINT64], "0xffffffffffffffff");
556
557 /* f is valid float if min < f < max. (min and max are not themselves valid.) */
558 mpatoflt(maxfltval[TFLOAT32], "33554431p103"); /* 2^24-1 p (127-23) + 1/2 ulp*/
559 mpatoflt(minfltval[TFLOAT32], "-33554431p103");
560 mpatoflt(maxfltval[TFLOAT64], "18014398509481983p970"); /* 2^53-1 p (1023-52) + 1/2 ulp */
561 mpatoflt(minfltval[TFLOAT64], "-18014398509481983p970");
562
563 maxfltval[TCOMPLEX64] = maxfltval[TFLOAT32];
564 minfltval[TCOMPLEX64] = minfltval[TFLOAT32];
565 maxfltval[TCOMPLEX128] = maxfltval[TFLOAT64];
566 minfltval[TCOMPLEX128] = minfltval[TFLOAT64];
567
568 /* for walk to use in error messages */
569 types[TFUNC] = functype(N, nil, nil);
570
571 /* types used in front end */
572 // types[TNIL] got set early in lexinit
573 types[TIDEAL] = typ(TIDEAL);
574 types[TINTER] = typ(TINTER);
575
576 /* simple aliases */
577 simtype[TMAP] = tptr;
578 simtype[TCHAN] = tptr;
579 simtype[TFUNC] = tptr;
580 simtype[TUNSAFEPTR] = tptr;
581
582 /* pick up the backend typedefs */
583 for(i=0; typedefs[i].name; i++) {
584 s = lookup(typedefs[i].name);
585 s1 = pkglookup(typedefs[i].name, builtinpkg);
586
587 etype = typedefs[i].etype;
588 if(etype < 0 || etype >= nelem(types))
589 fatal("typeinit: %s bad etype", s->name);
590 sameas = typedefs[i].sameas;
591 if(sameas < 0 || sameas >= nelem(types))
592 fatal("typeinit: %s bad sameas", s->name);
593 simtype[etype] = sameas;
594 minfltval[etype] = minfltval[sameas];
595 maxfltval[etype] = maxfltval[sameas];
596 minintval[etype] = minintval[sameas];
597 maxintval[etype] = maxintval[sameas];
598
599 t = types[etype];
600 if(t != T)
601 fatal("typeinit: %s already defined", s->name);
602
603 t = typ(etype);
604 t->sym = s;
605
606 dowidth(t);
607 types[etype] = t;
608 s1->def = typenod(t);
609 }
610
611 Array_array = rnd(0, widthptr);
612 Array_nel = rnd(Array_array+widthptr, types[TUINT32]->width);
613 Array_cap = rnd(Array_nel+types[TUINT32]->width, types[TUINT32]->width);
614 sizeof_Array = rnd(Array_cap+types[TUINT32]->width, widthptr);
615
616 // string is same as slice wo the cap
617 sizeof_String = rnd(Array_nel+types[TUINT32]->width, widthptr);
618
619 dowidth(types[TSTRING]);
620 dowidth(idealstring);
621 }
622
623 /*
624 * compute total size of f's in/out arguments.
625 */
626 int
627 argsize(Type *t)
628 {
629 Iter save;
630 Type *fp;
631 int w, x;
632
633 w = 0;
634
635 fp = structfirst(&save, getoutarg(t));
636 while(fp != T) {
637 x = fp->width + fp->type->width;
638 if(x > w)
639 w = x;
640 fp = structnext(&save);
641 }
642
643 fp = funcfirst(&save, t);
644 while(fp != T) {
645 x = fp->width + fp->type->width;
646 if(x > w)
647 w = x;
648 fp = funcnext(&save);
649 }
650
651 w = (w+widthptr-1) & ~(widthptr-1);
652 return w;
653 }