summaryrefslogtreecommitdiff
path: root/src/cmd/gc/reflect.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc/reflect.c')
-rw-r--r--src/cmd/gc/reflect.c939
1 files changed, 0 insertions, 939 deletions
diff --git a/src/cmd/gc/reflect.c b/src/cmd/gc/reflect.c
deleted file mode 100644
index 810787d30..000000000
--- a/src/cmd/gc/reflect.c
+++ /dev/null
@@ -1,939 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-#include "go.h"
-
-/*
- * runtime interface and reflection data structures
- */
-
-static NodeList* signatlist;
-static Sym* dtypesym(Type*);
-static Sym* weaktypesym(Type*);
-
-static int
-sigcmp(Sig *a, Sig *b)
-{
- int i;
-
- i = strcmp(a->name, b->name);
- if(i != 0)
- return i;
- if(a->pkg == b->pkg)
- return 0;
- if(a->pkg == nil)
- return -1;
- if(b->pkg == nil)
- return +1;
- return strcmp(a->pkg->path->s, b->pkg->path->s);
-}
-
-static Sig*
-lsort(Sig *l, int(*f)(Sig*, Sig*))
-{
- Sig *l1, *l2, *le;
-
- if(l == 0 || l->link == 0)
- return l;
-
- l1 = l;
- l2 = l;
- for(;;) {
- l2 = l2->link;
- if(l2 == 0)
- break;
- l2 = l2->link;
- if(l2 == 0)
- break;
- l1 = l1->link;
- }
-
- l2 = l1->link;
- l1->link = 0;
- l1 = lsort(l, f);
- l2 = lsort(l2, f);
-
- /* set up lead element */
- if((*f)(l1, l2) < 0) {
- l = l1;
- l1 = l1->link;
- } else {
- l = l2;
- l2 = l2->link;
- }
- le = l;
-
- for(;;) {
- if(l1 == 0) {
- while(l2) {
- le->link = l2;
- le = l2;
- l2 = l2->link;
- }
- le->link = 0;
- break;
- }
- if(l2 == 0) {
- while(l1) {
- le->link = l1;
- le = l1;
- l1 = l1->link;
- }
- break;
- }
- if((*f)(l1, l2) < 0) {
- le->link = l1;
- le = l1;
- l1 = l1->link;
- } else {
- le->link = l2;
- le = l2;
- l2 = l2->link;
- }
- }
- le->link = 0;
- return l;
-}
-
-/*
- * f is method type, with receiver.
- * return function type, receiver as first argument (or not).
- */
-Type*
-methodfunc(Type *f, Type *receiver)
-{
- NodeList *in, *out;
- Node *d;
- Type *t;
-
- in = nil;
- if(receiver) {
- d = nod(ODCLFIELD, N, N);
- d->type = receiver;
- in = list(in, d);
- }
- for(t=getinargx(f)->type; t; t=t->down) {
- d = nod(ODCLFIELD, N, N);
- d->type = t->type;
- d->isddd = t->isddd;
- in = list(in, d);
- }
-
- out = nil;
- for(t=getoutargx(f)->type; t; t=t->down) {
- d = nod(ODCLFIELD, N, N);
- d->type = t->type;
- out = list(out, d);
- }
-
- return functype(N, in, out);
-}
-
-/*
- * return methods of non-interface type t, sorted by name.
- * generates stub functions as needed.
- */
-static Sig*
-methods(Type *t)
-{
- Type *f, *mt, *it, *this;
- Sig *a, *b;
- Sym *method;
- Prog *oldlist;
-
- // named method type
- mt = methtype(t);
- if(mt == T)
- return nil;
- expandmeth(mt->sym, mt);
-
- // type stored in interface word
- it = t;
- if(it->width > widthptr)
- it = ptrto(t);
-
- // make list of methods for t,
- // generating code if necessary.
- a = nil;
- oldlist = nil;
- for(f=mt->xmethod; f; f=f->down) {
- if(f->type->etype != TFUNC)
- continue;
- if(f->etype != TFIELD)
- fatal("methods: not field");
- method = f->sym;
- if(method == nil)
- continue;
-
- // get receiver type for this particular method.
- // if pointer receiver but non-pointer t and
- // this is not an embedded pointer inside a struct,
- // method does not apply.
- this = getthisx(f->type)->type->type;
- if(isptr[this->etype] && this->type == t)
- continue;
- if(isptr[this->etype] && !isptr[t->etype]
- && f->embedded != 2 && !isifacemethod(f->type))
- continue;
-
- b = mal(sizeof(*b));
- b->link = a;
- a = b;
-
- a->name = method->name;
- if(!exportname(method->name)) {
- if(method->pkg == nil)
- fatal("methods: missing package");
- a->pkg = method->pkg;
- }
- a->isym = methodsym(method, it, 1);
- a->tsym = methodsym(method, t, 0);
- a->type = methodfunc(f->type, t);
- a->mtype = methodfunc(f->type, nil);
-
- if(!(a->isym->flags & SymSiggen)) {
- a->isym->flags |= SymSiggen;
- if(!eqtype(this, it) || this->width < types[tptr]->width) {
- if(oldlist == nil)
- oldlist = pc;
- // Is okay to call genwrapper here always,
- // but we can generate more efficient code
- // using genembedtramp if all that is necessary
- // is a pointer adjustment and a JMP.
- if(isptr[it->etype] && isptr[this->etype]
- && f->embedded && !isifacemethod(f->type))
- genembedtramp(it, f, a->isym, 1);
- else
- genwrapper(it, f, a->isym, 1);
- }
- }
-
- if(!(a->tsym->flags & SymSiggen)) {
- a->tsym->flags |= SymSiggen;
- if(!eqtype(this, t)) {
- if(oldlist == nil)
- oldlist = pc;
- if(isptr[t->etype] && isptr[this->etype]
- && f->embedded && !isifacemethod(f->type))
- genembedtramp(t, f, a->tsym, 0);
- else
- genwrapper(t, f, a->tsym, 0);
- }
- }
- }
-
- // restore data output
- if(oldlist) {
- // old list ended with AEND; change to ANOP
- // so that the trampolines that follow can be found.
- nopout(oldlist);
-
- // start new data list
- newplist();
- }
-
- return lsort(a, sigcmp);
-}
-
-/*
- * return methods of interface type t, sorted by name.
- */
-static Sig*
-imethods(Type *t)
-{
- Sig *a, *all, *last;
- Type *f;
- Sym *method, *isym;
- Prog *oldlist;
-
- all = nil;
- last = nil;
- oldlist = nil;
- for(f=t->type; f; f=f->down) {
- if(f->etype != TFIELD)
- fatal("imethods: not field");
- if(f->type->etype != TFUNC || f->sym == nil)
- continue;
- method = f->sym;
- a = mal(sizeof(*a));
- a->name = method->name;
- if(!exportname(method->name)) {
- if(method->pkg == nil)
- fatal("imethods: missing package");
- a->pkg = method->pkg;
- }
- a->mtype = f->type;
- a->offset = 0;
- a->type = methodfunc(f->type, nil);
-
- if(last && sigcmp(last, a) >= 0)
- fatal("sigcmp vs sortinter %s %s", last->name, a->name);
- if(last == nil)
- all = a;
- else
- last->link = a;
- last = a;
-
- // Compiler can only refer to wrappers for
- // named interface types.
- if(t->sym == S)
- continue;
-
- // NOTE(rsc): Perhaps an oversight that
- // IfaceType.Method is not in the reflect data.
- // Generate the method body, so that compiled
- // code can refer to it.
- isym = methodsym(method, t, 0);
- if(!(isym->flags & SymSiggen)) {
- isym->flags |= SymSiggen;
- if(oldlist == nil)
- oldlist = pc;
- genwrapper(t, f, isym, 0);
- }
- }
-
- if(oldlist) {
- // old list ended with AEND; change to ANOP
- // so that the trampolines that follow can be found.
- nopout(oldlist);
-
- // start new data list
- newplist();
- }
-
- return all;
-}
-
-static void
-dimportpath(Pkg *p)
-{
- static Pkg *gopkg;
- char *nam;
- Node *n;
-
- if(p->pathsym != S)
- return;
-
- if(gopkg == nil) {
- gopkg = mkpkg(strlit("go"));
- gopkg->name = "go";
- }
- nam = smprint("importpath.%s.", p->prefix);
-
- n = nod(ONAME, N, N);
- n->sym = pkglookup(nam, gopkg);
- free(nam);
- n->class = PEXTERN;
- n->xoffset = 0;
- p->pathsym = n->sym;
-
- gdatastring(n, p->path);
- ggloblsym(n->sym, types[TSTRING]->width, 1);
-}
-
-static int
-dgopkgpath(Sym *s, int ot, Pkg *pkg)
-{
- if(pkg == nil)
- return dgostringptr(s, ot, nil);
-
- // Emit reference to go.importpath.""., which 6l will
- // rewrite using the correct import path. Every package
- // that imports this one directly defines the symbol.
- if(pkg == localpkg) {
- static Sym *ns;
-
- if(ns == nil)
- ns = pkglookup("importpath.\"\".", mkpkg(strlit("go")));
- return dsymptr(s, ot, ns, 0);
- }
-
- dimportpath(pkg);
- return dsymptr(s, ot, pkg->pathsym, 0);
-}
-
-/*
- * uncommonType
- * ../../pkg/runtime/type.go:/uncommonType
- */
-static int
-dextratype(Sym *sym, int off, Type *t, int ptroff)
-{
- int ot, n;
- Sym *s;
- Sig *a, *m;
-
- m = methods(t);
- if(t->sym == nil && m == nil)
- return off;
-
- // fill in *extraType pointer in header
- dsymptr(sym, ptroff, sym, off);
-
- n = 0;
- for(a=m; a; a=a->link) {
- dtypesym(a->type);
- n++;
- }
-
- ot = off;
- s = sym;
- if(t->sym) {
- ot = dgostringptr(s, ot, t->sym->name);
- if(t != types[t->etype])
- ot = dgopkgpath(s, ot, t->sym->pkg);
- else
- ot = dgostringptr(s, ot, nil);
- } else {
- ot = dgostringptr(s, ot, nil);
- ot = dgostringptr(s, ot, nil);
- }
-
- // slice header
- ot = dsymptr(s, ot, s, ot + widthptr + 2*4);
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
-
- // methods
- for(a=m; a; a=a->link) {
- // method
- // ../../pkg/runtime/type.go:/method
- ot = dgostringptr(s, ot, a->name);
- ot = dgopkgpath(s, ot, a->pkg);
- ot = dsymptr(s, ot, dtypesym(a->mtype), 0);
- ot = dsymptr(s, ot, dtypesym(a->type), 0);
- if(a->isym)
- ot = dsymptr(s, ot, a->isym, 0);
- else
- ot = duintptr(s, ot, 0);
- if(a->tsym)
- ot = dsymptr(s, ot, a->tsym, 0);
- else
- ot = duintptr(s, ot, 0);
- }
-
- return ot;
-}
-
-enum {
- KindBool = 1,
- KindInt,
- KindInt8,
- KindInt16,
- KindInt32,
- KindInt64,
- KindUint,
- KindUint8,
- KindUint16,
- KindUint32,
- KindUint64,
- KindUintptr,
- KindFloat32,
- KindFloat64,
- KindComplex64,
- KindComplex128,
- KindArray,
- KindChan,
- KindFunc,
- KindInterface,
- KindMap,
- KindPtr,
- KindSlice,
- KindString,
- KindStruct,
- KindUnsafePointer,
-
- KindNoPointers = 1<<7,
-};
-
-static int
-kinds[] =
-{
- [TINT] = KindInt,
- [TUINT] = KindUint,
- [TINT8] = KindInt8,
- [TUINT8] = KindUint8,
- [TINT16] = KindInt16,
- [TUINT16] = KindUint16,
- [TINT32] = KindInt32,
- [TUINT32] = KindUint32,
- [TINT64] = KindInt64,
- [TUINT64] = KindUint64,
- [TUINTPTR] = KindUintptr,
- [TFLOAT32] = KindFloat32,
- [TFLOAT64] = KindFloat64,
- [TBOOL] = KindBool,
- [TSTRING] = KindString,
- [TPTR32] = KindPtr,
- [TPTR64] = KindPtr,
- [TSTRUCT] = KindStruct,
- [TINTER] = KindInterface,
- [TCHAN] = KindChan,
- [TMAP] = KindMap,
- [TARRAY] = KindArray,
- [TFUNC] = KindFunc,
- [TCOMPLEX64] = KindComplex64,
- [TCOMPLEX128] = KindComplex128,
- [TUNSAFEPTR] = KindUnsafePointer,
-};
-
-static char*
-structnames[] =
-{
- [TINT] = "*runtime.IntType",
- [TUINT] = "*runtime.UintType",
- [TINT8] = "*runtime.IntType",
- [TUINT8] = "*runtime.UintType",
- [TINT16] = "*runtime.IntType",
- [TUINT16] = "*runtime.UintType",
- [TINT32] = "*runtime.IntType",
- [TUINT32] = "*runtime.UintType",
- [TINT64] = "*runtime.IntType",
- [TUINT64] = "*runtime.UintType",
- [TUINTPTR] = "*runtime.UintType",
- [TCOMPLEX64] = "*runtime.ComplexType",
- [TCOMPLEX128] = "*runtime.ComplexType",
- [TFLOAT32] = "*runtime.FloatType",
- [TFLOAT64] = "*runtime.FloatType",
- [TBOOL] = "*runtime.BoolType",
- [TSTRING] = "*runtime.StringType",
- [TUNSAFEPTR] = "*runtime.UnsafePointerType",
-
- [TPTR32] = "*runtime.PtrType",
- [TPTR64] = "*runtime.PtrType",
- [TSTRUCT] = "*runtime.StructType",
- [TINTER] = "*runtime.InterfaceType",
- [TCHAN] = "*runtime.ChanType",
- [TMAP] = "*runtime.MapType",
- [TARRAY] = "*runtime.ArrayType",
- [TFUNC] = "*runtime.FuncType",
-};
-
-static Sym*
-typestruct(Type *t)
-{
- char *name;
- int et;
-
- et = t->etype;
- if(et < 0 || et >= nelem(structnames) || (name = structnames[et]) == nil) {
- fatal("typestruct %lT", t);
- return nil; // silence gcc
- }
-
- if(isslice(t))
- name = "*runtime.SliceType";
-
- return pkglookup(name, typepkg);
-}
-
-static int
-haspointers(Type *t)
-{
- Type *t1;
-
- switch(t->etype) {
- case TINT:
- case TUINT:
- case TINT8:
- case TUINT8:
- case TINT16:
- case TUINT16:
- case TINT32:
- case TUINT32:
- case TINT64:
- case TUINT64:
- case TUINTPTR:
- case TFLOAT32:
- case TFLOAT64:
- case TBOOL:
- return 0;
- case TARRAY:
- if(t->bound < 0) // slice
- return 1;
- return haspointers(t->type);
- case TSTRUCT:
- for(t1=t->type; t1!=T; t1=t1->down)
- if(haspointers(t1->type))
- return 1;
- return 0;
- case TSTRING:
- case TPTR32:
- case TPTR64:
- case TUNSAFEPTR:
- case TINTER:
- case TCHAN:
- case TMAP:
- case TFUNC:
- default:
- return 1;
- }
-}
-
-/*
- * commonType
- * ../../pkg/runtime/type.go:/commonType
- */
-static int
-dcommontype(Sym *s, int ot, Type *t)
-{
- int i;
- Sym *sptr;
- char *p;
-
- dowidth(t);
-
- sptr = nil;
- if(t->sym != nil && !isptr[t->etype])
- sptr = dtypesym(ptrto(t));
- else
- sptr = weaktypesym(ptrto(t));
-
- // empty interface pointing at this type.
- // all the references that we emit are *interface{};
- // they point here.
- ot = rnd(ot, widthptr);
- ot = dsymptr(s, ot, typestruct(t), 0);
- ot = dsymptr(s, ot, s, 2*widthptr);
-
- // ../../pkg/runtime/type.go:/commonType
- // actual type structure
- // type commonType struct {
- // size uintptr;
- // hash uint32;
- // alg uint8;
- // align uint8;
- // fieldAlign uint8;
- // kind uint8;
- // string *string;
- // *extraType;
- // ptrToThis *Type
- // }
- ot = duintptr(s, ot, t->width);
- ot = duint32(s, ot, typehash(t));
- ot = duint8(s, ot, algtype(t));
- ot = duint8(s, ot, t->align); // align
- ot = duint8(s, ot, t->align); // fieldAlign
- i = kinds[t->etype];
- if(t->etype == TARRAY && t->bound < 0)
- i = KindSlice;
- if(!haspointers(t))
- i |= KindNoPointers;
- ot = duint8(s, ot, i); // kind
- longsymnames = 1;
- p = smprint("%-T", t);
- longsymnames = 0;
- ot = dgostringptr(s, ot, p); // string
- free(p);
-
- // skip pointer to extraType,
- // which follows the rest of this type structure.
- // caller will fill in if needed.
- // otherwise linker will assume 0.
- ot += widthptr;
-
- ot = dsymptr(s, ot, sptr, 0); // ptrto type
- return ot;
-}
-
-Sym*
-typesym(Type *t)
-{
- char *p;
- Sym *s;
-
- p = smprint("%#-T", t);
- s = pkglookup(p, typepkg);
- free(p);
- return s;
-}
-
-Node*
-typename(Type *t)
-{
- Sym *s;
- Node *n;
-
- if(t == T || (isptr[t->etype] && t->type == T) || isideal(t))
- fatal("typename %T", t);
- s = typesym(t);
- if(s->def == N) {
- n = nod(ONAME, N, N);
- n->sym = s;
- n->type = types[TUINT8];
- n->addable = 1;
- n->ullman = 1;
- n->class = PEXTERN;
- n->xoffset = 0;
- s->def = n;
-
- signatlist = list(signatlist, typenod(t));
- }
-
- n = nod(OADDR, s->def, N);
- n->type = ptrto(s->def->type);
- n->addable = 1;
- n->ullman = 2;
- return n;
-}
-
-static Sym*
-weaktypesym(Type *t)
-{
- char *p;
- Sym *s;
- static Pkg *weak;
-
- if(weak == nil) {
- weak = mkpkg(strlit("weak.type"));
- weak->name = "weak.type";
- weak->prefix = "weak.type"; // not weak%2etype
- }
-
- p = smprint("%#-T", t);
- s = pkglookup(p, weak);
- free(p);
- return s;
-}
-
-static Sym*
-dtypesym(Type *t)
-{
- int ot, xt, n, isddd, dupok;
- Sym *s, *s1, *s2;
- Sig *a, *m;
- Type *t1, *tbase, *t2;
-
- if(isideal(t))
- fatal("dtypesym %T", t);
-
- s = typesym(t);
- if(s->flags & SymSiggen)
- return s;
- s->flags |= SymSiggen;
-
- // special case (look for runtime below):
- // when compiling package runtime,
- // emit the type structures for int, float, etc.
- tbase = t;
- if(isptr[t->etype] && t->sym == S && t->type->sym != S)
- tbase = t->type;
- dupok = tbase->sym == S;
-
- if(compiling_runtime && tbase == types[tbase->etype]) // int, float, etc
- goto ok;
-
- // named types from other files are defined only by those files
- if(tbase->sym && !tbase->local)
- return s;
- if(isforw[tbase->etype])
- return s;
-
-ok:
- ot = 0;
- xt = 0;
- switch(t->etype) {
- default:
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- break;
-
- case TARRAY:
- if(t->bound >= 0) {
- // ../../pkg/runtime/type.go:/ArrayType
- s1 = dtypesym(t->type);
- t2 = typ(TARRAY);
- t2->type = t->type;
- t2->bound = -1; // slice
- s2 = dtypesym(t2);
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s1, 0);
- ot = dsymptr(s, ot, s2, 0);
- ot = duintptr(s, ot, t->bound);
- } else {
- // ../../pkg/runtime/type.go:/SliceType
- s1 = dtypesym(t->type);
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s1, 0);
- }
- break;
-
- case TCHAN:
- // ../../pkg/runtime/type.go:/ChanType
- s1 = dtypesym(t->type);
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s1, 0);
- ot = duintptr(s, ot, t->chan);
- break;
-
- case TFUNC:
- for(t1=getthisx(t)->type; t1; t1=t1->down)
- dtypesym(t1->type);
- isddd = 0;
- for(t1=getinargx(t)->type; t1; t1=t1->down) {
- isddd = t1->isddd;
- dtypesym(t1->type);
- }
- for(t1=getoutargx(t)->type; t1; t1=t1->down)
- dtypesym(t1->type);
-
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = duint8(s, ot, isddd);
-
- // two slice headers: in and out.
- ot = rnd(ot, widthptr);
- ot = dsymptr(s, ot, s, ot+2*(widthptr+2*4));
- n = t->thistuple + t->intuple;
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
- ot = dsymptr(s, ot, s, ot+1*(widthptr+2*4)+n*widthptr);
- ot = duint32(s, ot, t->outtuple);
- ot = duint32(s, ot, t->outtuple);
-
- // slice data
- for(t1=getthisx(t)->type; t1; t1=t1->down, n++)
- ot = dsymptr(s, ot, dtypesym(t1->type), 0);
- for(t1=getinargx(t)->type; t1; t1=t1->down, n++)
- ot = dsymptr(s, ot, dtypesym(t1->type), 0);
- for(t1=getoutargx(t)->type; t1; t1=t1->down, n++)
- ot = dsymptr(s, ot, dtypesym(t1->type), 0);
- break;
-
- case TINTER:
- m = imethods(t);
- n = 0;
- for(a=m; a; a=a->link) {
- dtypesym(a->type);
- n++;
- }
-
- // ../../pkg/runtime/type.go:/InterfaceType
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s, ot+widthptr+2*4);
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
- for(a=m; a; a=a->link) {
- // ../../pkg/runtime/type.go:/imethod
- ot = dgostringptr(s, ot, a->name);
- ot = dgopkgpath(s, ot, a->pkg);
- ot = dsymptr(s, ot, dtypesym(a->type), 0);
- }
- break;
-
- case TMAP:
- // ../../pkg/runtime/type.go:/MapType
- s1 = dtypesym(t->down);
- s2 = dtypesym(t->type);
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s1, 0);
- ot = dsymptr(s, ot, s2, 0);
- break;
-
- case TPTR32:
- case TPTR64:
- if(t->type->etype == TANY) {
- // ../../pkg/runtime/type.go:/UnsafePointerType
- ot = dcommontype(s, ot, t);
- break;
- }
- // ../../pkg/runtime/type.go:/PtrType
- s1 = dtypesym(t->type);
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s1, 0);
- break;
-
- case TSTRUCT:
- // ../../pkg/runtime/type.go:/StructType
- // for security, only the exported fields.
- n = 0;
- for(t1=t->type; t1!=T; t1=t1->down) {
- dtypesym(t1->type);
- n++;
- }
- ot = dcommontype(s, ot, t);
- xt = ot - 2*widthptr;
- ot = dsymptr(s, ot, s, ot+widthptr+2*4);
- ot = duint32(s, ot, n);
- ot = duint32(s, ot, n);
- for(t1=t->type; t1!=T; t1=t1->down) {
- // ../../pkg/runtime/type.go:/structField
- if(t1->sym && !t1->embedded) {
- ot = dgostringptr(s, ot, t1->sym->name);
- if(exportname(t1->sym->name))
- ot = dgostringptr(s, ot, nil);
- else
- ot = dgopkgpath(s, ot, t1->sym->pkg);
- } else {
- ot = dgostringptr(s, ot, nil);
- ot = dgostringptr(s, ot, nil);
- }
- ot = dsymptr(s, ot, dtypesym(t1->type), 0);
- ot = dgostrlitptr(s, ot, t1->note);
- ot = duintptr(s, ot, t1->width); // field offset
- }
- break;
- }
- ot = dextratype(s, ot, t, xt);
- ggloblsym(s, ot, dupok);
- return s;
-}
-
-void
-dumptypestructs(void)
-{
- int i;
- NodeList *l;
- Node *n;
- Type *t;
- Pkg *p;
-
- // copy types from externdcl list to signatlist
- for(l=externdcl; l; l=l->next) {
- n = l->n;
- if(n->op != OTYPE)
- continue;
- signatlist = list(signatlist, n);
- }
-
- // process signatlist
- for(l=signatlist; l; l=l->next) {
- n = l->n;
- if(n->op != OTYPE)
- continue;
- t = n->type;
- dtypesym(t);
- if(t->sym)
- dtypesym(ptrto(t));
- }
-
- // generate import strings for imported packages
- for(i=0; i<nelem(phash); i++)
- for(p=phash[i]; p; p=p->link)
- if(p->direct)
- dimportpath(p);
-
- // do basic types if compiling package runtime.
- // they have to be in at least one package,
- // and runtime is always loaded implicitly,
- // so this is as good as any.
- // another possible choice would be package main,
- // but using runtime means fewer copies in .6 files.
- if(compiling_runtime) {
- for(i=1; i<=TBOOL; i++)
- dtypesym(ptrto(types[i]));
- dtypesym(ptrto(types[TSTRING]));
- dtypesym(ptrto(types[TUNSAFEPTR]));
-
- // add paths for runtime and main, which 6l imports implicitly.
- dimportpath(runtimepkg);
- dimportpath(mkpkg(strlit("main")));
- }
-}