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.
8
* runtime interface and reflection data structures
11
static NodeList* signatlist;
12
static Sym* dtypesym(Type*);
13
static Sym* weaktypesym(Type*);
16
sigcmp(Sig *a, Sig *b)
20
i = strcmp(a->name, b->name);
29
return strcmp(a->pkg->path->s, b->pkg->path->s);
33
lsort(Sig *l, int(*f)(Sig*, Sig*))
37
if(l == 0 || l->link == 0)
57
/* set up lead element */
58
if((*f)(l1, l2) < 0) {
85
if((*f)(l1, l2) < 0) {
100
* f is method type, with receiver.
101
* return function type, receiver as first argument (or not).
104
methodfunc(Type *f, Type *receiver)
112
d = nod(ODCLFIELD, N, N);
116
for(t=getinargx(f)->type; t; t=t->down) {
117
d = nod(ODCLFIELD, N, N);
124
for(t=getoutargx(f)->type; t; t=t->down) {
125
d = nod(ODCLFIELD, N, N);
130
return functype(N, in, out);
134
* return methods of non-interface type t, sorted by name.
135
* generates stub functions as needed.
141
Type *f, *mt, *it, *this;
150
expandmeth(mt->sym, mt);
152
// type stored in interface word
154
if(it->width > widthptr)
157
// make list of methods for t,
158
// generating code if necessary.
162
for(f=mt->xmethod; f; f=f->down) {
163
if(f->type->etype != TFUNC)
165
if(f->etype != TFIELD)
166
fatal("methods: not field");
171
// get receiver type for this particular method.
172
// if pointer receiver but non-pointer t and
173
// this is not an embedded pointer inside a struct,
174
// method does not apply.
175
this = getthisx(f->type)->type->type;
176
if(isptr[this->etype] && this->type == t)
178
if(isptr[this->etype] && !isptr[t->etype]
179
&& f->embedded != 2 && !isifacemethod(f->type))
186
a->name = method->name;
187
a->isym = methodsym(method, it, 1);
188
a->tsym = methodsym(method, t, 0);
189
a->type = methodfunc(f->type, t);
190
a->mtype = methodfunc(f->type, nil);
192
if(!(a->isym->flags & SymSiggen)) {
193
a->isym->flags |= SymSiggen;
194
if(!eqtype(this, it) || this->width < types[tptr]->width) {
197
// Is okay to call genwrapper here always,
198
// but we can generate more efficient code
199
// using genembedtramp if all that is necessary
200
// is a pointer adjustment and a JMP.
201
if(isptr[it->etype] && isptr[this->etype]
202
&& f->embedded && !isifacemethod(f->type))
203
genembedtramp(it, f, a->isym, 1);
205
genwrapper(it, f, a->isym, 1);
209
if(!(a->tsym->flags & SymSiggen)) {
210
a->tsym->flags |= SymSiggen;
211
if(!eqtype(this, t)) {
214
if(isptr[t->etype] && isptr[this->etype]
215
&& f->embedded && !isifacemethod(f->type))
216
genembedtramp(t, f, a->tsym, 0);
218
genwrapper(t, f, a->tsym, 0);
223
// restore data output
225
// old list ended with AEND; change to ANOP
226
// so that the trampolines that follow can be found.
229
// start new data list
233
return lsort(a, sigcmp);
237
* return methods of interface type t, sorted by name.
252
for(f=t->type; f; f=f->down) {
253
if(f->etype != TFIELD)
254
fatal("imethods: not field");
255
if(f->type->etype != TFUNC || f->sym == nil)
259
a->name = method->name;
260
if(!exportname(method->name))
261
a->pkg = method->pkg;
264
a->type = methodfunc(f->type, nil);
266
if(last && sigcmp(last, a) >= 0)
267
fatal("sigcmp vs sortinter %s %s", last->name, a->name);
274
// Compiler can only refer to wrappers for
275
// named interface types.
279
// NOTE(rsc): Perhaps an oversight that
280
// IfaceType.Method is not in the reflect data.
281
// Generate the method body, so that compiled
282
// code can refer to it.
283
isym = methodsym(method, t, 0);
284
if(!(isym->flags & SymSiggen)) {
285
isym->flags |= SymSiggen;
288
genwrapper(t, f, isym, 0);
293
// old list ended with AEND; change to ANOP
294
// so that the trampolines that follow can be found.
297
// start new data list
305
dgopkgpath(Sym *s, int ot, Pkg *pkg)
308
return dgostringptr(s, ot, nil);
310
// Emit reference to go.importpath.""., which 6l will
311
// rewrite using the correct import path. Every package
312
// that imports this one directly defines the symbol.
313
if(pkg == localpkg) {
317
ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
318
return dsymptr(s, ot, ns, 0);
321
return dgostringptr(s, ot, pkg->name);
332
gopkg = mkpkg(strlit("go"));
335
nam = smprint("importpath.%s.", p->prefix);
337
n = nod(ONAME, N, N);
338
n->sym = pkglookup(nam, gopkg);
343
gdatastring(n, p->path);
344
ggloblsym(n->sym, types[TSTRING]->width, 1);
349
* ../../pkg/runtime/type.go:/uncommonType
360
if(t->sym == nil && m == nil)
364
for(a=m; a; a=a->link) {
369
p = smprint("_.%#T", t);
370
s = pkglookup(p, typepkg);
373
ot = dgostringptr(s, ot, t->sym->name);
374
if(t != types[t->etype])
375
ot = dgopkgpath(s, ot, t->sym->pkg);
377
ot = dgostringptr(s, ot, nil);
379
ot = dgostringptr(s, ot, nil);
380
ot = dgostringptr(s, ot, nil);
384
ot = dsymptr(s, ot, s, ot + widthptr + 2*4);
385
ot = duint32(s, ot, n);
386
ot = duint32(s, ot, n);
389
for(a=m; a; a=a->link) {
391
// ../../pkg/runtime/type.go:/method
392
ot = dgostringptr(s, ot, a->name);
393
ot = dgopkgpath(s, ot, a->pkg);
394
ot = dsymptr(s, ot, dtypesym(a->mtype), 0);
395
ot = dsymptr(s, ot, dtypesym(a->type), 0);
397
ot = dsymptr(s, ot, a->isym, 0);
399
ot = duintptr(s, ot, 0);
401
ot = dsymptr(s, ot, a->tsym, 0);
403
ot = duintptr(s, ot, 0);
438
KindNoPointers = 1<<7,
447
[TUINT8] = KindUint8,
448
[TINT16] = KindInt16,
449
[TUINT16] = KindUint16,
450
[TINT32] = KindInt32,
451
[TUINT32] = KindUint32,
452
[TINT64] = KindInt64,
453
[TUINT64] = KindUint64,
454
[TUINTPTR] = KindUintptr,
455
[TFLOAT32] = KindFloat32,
456
[TFLOAT64] = KindFloat64,
458
[TSTRING] = KindString,
461
[TSTRUCT] = KindStruct,
462
[TINTER] = KindInterface,
465
[TARRAY] = KindArray,
467
[TCOMPLEX64] = KindComplex64,
468
[TCOMPLEX128] = KindComplex128,
474
[TINT] = "*runtime.IntType",
475
[TUINT] = "*runtime.UintType",
476
[TINT8] = "*runtime.IntType",
477
[TUINT8] = "*runtime.UintType",
478
[TINT16] = "*runtime.IntType",
479
[TUINT16] = "*runtime.UintType",
480
[TINT32] = "*runtime.IntType",
481
[TUINT32] = "*runtime.UintType",
482
[TINT64] = "*runtime.IntType",
483
[TUINT64] = "*runtime.UintType",
484
[TUINTPTR] = "*runtime.UintType",
485
[TCOMPLEX64] = "*runtime.ComplexType",
486
[TCOMPLEX128] = "*runtime.ComplexType",
487
[TFLOAT32] = "*runtime.FloatType",
488
[TFLOAT64] = "*runtime.FloatType",
489
[TBOOL] = "*runtime.BoolType",
490
[TSTRING] = "*runtime.StringType",
492
[TPTR32] = "*runtime.PtrType",
493
[TPTR64] = "*runtime.PtrType",
494
[TSTRUCT] = "*runtime.StructType",
495
[TINTER] = "*runtime.InterfaceType",
496
[TCHAN] = "*runtime.ChanType",
497
[TMAP] = "*runtime.MapType",
498
[TARRAY] = "*runtime.ArrayType",
499
[TFUNC] = "*runtime.FuncType",
509
if(et < 0 || et >= nelem(structnames) || (name = structnames[et]) == nil) {
510
fatal("typestruct %lT", t);
511
return nil; // silence gcc
515
name = "*runtime.SliceType";
517
if(isptr[et] && t->type->etype == TANY)
518
name = "*runtime.UnsafePointerType";
520
return pkglookup(name, typepkg);
545
if(t->bound < 0) // slice
547
return haspointers(t->type);
549
for(t1=t->type; t1!=T; t1=t1->down)
550
if(haspointers(t1->type))
567
* ../../pkg/runtime/type.go:/commonType
570
dcommontype(Sym *s, int ot, Type *t)
580
if(t->sym != nil && !isptr[t->etype])
581
sptr = dtypesym(ptrto(t));
583
sptr = weaktypesym(ptrto(t));
587
// empty interface pointing at this type.
588
// all the references that we emit are *interface{};
590
ot = rnd(ot, widthptr);
591
ot = dsymptr(s, ot, typestruct(t), 0);
592
ot = dsymptr(s, ot, s, 2*widthptr);
594
// ../../pkg/runtime/type.go:/commonType
595
// actual type structure
596
// type commonType struct {
607
ot = duintptr(s, ot, t->width);
608
ot = duint32(s, ot, typehash(t));
609
ot = duint8(s, ot, algtype(t));
610
ot = duint8(s, ot, t->align); // align
611
ot = duint8(s, ot, t->align); // fieldAlign
613
if(t->etype == TARRAY && t->bound < 0)
615
if(isptr[t->etype] && t->type->etype == TANY)
616
i = KindUnsafePointer;
619
ot = duint8(s, ot, i); // kind
621
p = smprint("%-T", t);
623
ot = dgostringptr(s, ot, p); // string
626
ot = dsymptr(s, ot, s1, 0); // extraType
628
ot = duintptr(s, ot, 0);
629
ot = dsymptr(s, ot, sptr, 0); // ptr to type
639
p = smprint("%#-T", t);
640
s = pkglookup(p, typepkg);
651
if(t == T || (isptr[t->etype] && t->type == T) || isideal(t))
652
fatal("typename %T", t);
655
n = nod(ONAME, N, N);
657
n->type = types[TUINT8];
664
signatlist = list(signatlist, typenod(t));
667
n = nod(OADDR, s->def, N);
668
n->type = ptrto(s->def->type);
682
weak = mkpkg(strlit("weak.type"));
683
weak->name = "weak.type";
684
weak->prefix = "weak.type"; // not weak%2etype
687
p = smprint("%#-T", t);
688
s = pkglookup(p, weak);
696
int ot, n, isddd, dupok;
702
fatal("dtypesym %T", t);
705
if(s->flags & SymSiggen)
707
s->flags |= SymSiggen;
709
// special case (look for runtime below):
710
// when compiling package runtime,
711
// emit the type structures for int, float, etc.
713
if(isptr[t->etype] && t->sym == S && t->type->sym != S)
715
dupok = tbase->sym == S;
717
if(compiling_runtime) {
718
if(tbase == types[tbase->etype]) // int, float, etc
720
if(tbase->etype == tptr && tbase->type->etype == TANY) // unsafe.Pointer
724
// named types from other files are defined only by those files
725
if(tbase->sym && !tbase->local)
727
if(isforw[tbase->etype])
734
ot = dcommontype(s, ot, t);
738
// ../../pkg/runtime/type.go:/ArrayType
739
s1 = dtypesym(t->type);
740
ot = dcommontype(s, ot, t);
741
ot = dsymptr(s, ot, s1, 0);
743
ot = duintptr(s, ot, -1);
745
ot = duintptr(s, ot, t->bound);
749
// ../../pkg/runtime/type.go:/ChanType
750
s1 = dtypesym(t->type);
751
ot = dcommontype(s, ot, t);
752
ot = dsymptr(s, ot, s1, 0);
753
ot = duintptr(s, ot, t->chan);
757
for(t1=getthisx(t)->type; t1; t1=t1->down)
760
for(t1=getinargx(t)->type; t1; t1=t1->down) {
764
for(t1=getoutargx(t)->type; t1; t1=t1->down)
767
ot = dcommontype(s, ot, t);
768
ot = duint8(s, ot, isddd);
770
// two slice headers: in and out.
771
ot = rnd(ot, widthptr);
772
ot = dsymptr(s, ot, s, ot+2*(widthptr+2*4));
773
n = t->thistuple + t->intuple;
774
ot = duint32(s, ot, n);
775
ot = duint32(s, ot, n);
776
ot = dsymptr(s, ot, s, ot+1*(widthptr+2*4)+n*widthptr);
777
ot = duint32(s, ot, t->outtuple);
778
ot = duint32(s, ot, t->outtuple);
781
for(t1=getthisx(t)->type; t1; t1=t1->down, n++)
782
ot = dsymptr(s, ot, dtypesym(t1->type), 0);
783
for(t1=getinargx(t)->type; t1; t1=t1->down, n++)
784
ot = dsymptr(s, ot, dtypesym(t1->type), 0);
785
for(t1=getoutargx(t)->type; t1; t1=t1->down, n++)
786
ot = dsymptr(s, ot, dtypesym(t1->type), 0);
792
for(a=m; a; a=a->link) {
797
// ../../pkg/runtime/type.go:/InterfaceType
798
ot = dcommontype(s, ot, t);
799
ot = dsymptr(s, ot, s, ot+widthptr+2*4);
800
ot = duint32(s, ot, n);
801
ot = duint32(s, ot, n);
802
for(a=m; a; a=a->link) {
803
// ../../pkg/runtime/type.go:/imethod
804
ot = dgostringptr(s, ot, a->name);
805
ot = dgopkgpath(s, ot, a->pkg);
806
ot = dsymptr(s, ot, dtypesym(a->type), 0);
811
// ../../pkg/runtime/type.go:/MapType
812
s1 = dtypesym(t->down);
813
s2 = dtypesym(t->type);
814
ot = dcommontype(s, ot, t);
815
ot = dsymptr(s, ot, s1, 0);
816
ot = dsymptr(s, ot, s2, 0);
821
if(t->type->etype == TANY) {
822
// ../../pkg/runtime/type.go:/UnsafePointerType
823
ot = dcommontype(s, ot, t);
826
// ../../pkg/runtime/type.go:/PtrType
827
s1 = dtypesym(t->type);
828
ot = dcommontype(s, ot, t);
829
ot = dsymptr(s, ot, s1, 0);
833
// ../../pkg/runtime/type.go:/StructType
834
// for security, only the exported fields.
836
for(t1=t->type; t1!=T; t1=t1->down) {
840
ot = dcommontype(s, ot, t);
841
ot = dsymptr(s, ot, s, ot+widthptr+2*4);
842
ot = duint32(s, ot, n);
843
ot = duint32(s, ot, n);
844
for(t1=t->type; t1!=T; t1=t1->down) {
845
// ../../pkg/runtime/type.go:/structField
846
if(t1->sym && !t1->embedded) {
847
ot = dgostringptr(s, ot, t1->sym->name);
848
if(exportname(t1->sym->name))
849
ot = dgostringptr(s, ot, nil);
851
ot = dgopkgpath(s, ot, t1->sym->pkg);
853
ot = dgostringptr(s, ot, nil);
854
ot = dgostringptr(s, ot, nil);
856
ot = dsymptr(s, ot, dtypesym(t1->type), 0);
857
ot = dgostrlitptr(s, ot, t1->note);
858
ot = duintptr(s, ot, t1->width); // field offset
863
ggloblsym(s, ot, dupok);
868
dumptypestructs(void)
876
// copy types from externdcl list to signatlist
877
for(l=externdcl; l; l=l->next) {
881
signatlist = list(signatlist, n);
884
// process signatlist
885
for(l=signatlist; l; l=l->next) {
895
// generate import strings for imported packages
896
for(i=0; i<nelem(phash); i++)
897
for(p=phash[i]; p; p=p->link)
901
// do basic types if compiling package runtime.
902
// they have to be in at least one package,
903
// and runtime is always loaded implicitly,
904
// so this is as good as any.
905
// another possible choice would be package main,
906
// but using runtime means fewer copies in .6 files.
907
if(compiling_runtime) {
908
for(i=1; i<=TBOOL; i++)
909
dtypesym(ptrto(types[i]));
910
dtypesym(ptrto(types[TSTRING]));
911
dtypesym(ptrto(pkglookup("Pointer", unsafepkg)->def->type));
913
// add paths for runtime and main, which 6l imports implicitly.
914
dimportpath(runtimepkg);
915
dimportpath(mkpkg(strlit("main")));