]> Cypherpunks repositories - gostls13.git/commitdiff
eliminate the package global name space assumption in object files
authorRuss Cox <rsc@golang.org>
Sat, 23 Jan 2010 01:06:20 +0000 (17:06 -0800)
committerRuss Cox <rsc@golang.org>
Sat, 23 Jan 2010 01:06:20 +0000 (17:06 -0800)
5g/6g/8g: add import statements to export metadata, mapping package path to package name.
recognize "" as the path of the package in export metadata.
use "" as the path of the package in object symbol names.

5c/6c/8c, 5a/6a/8a: rewrite leading . to "". so that ·Sin means Sin in this package.

5l/6l/8l: rewrite "" in symbol names as object files are read.

gotest: handle new symbol names.

gopack: handle new import lines in export metadata.

Collectively, these changes eliminate the assumption of a global
name space in the object file formats.  Higher level pieces such as
reflect and the computation of type hashes still depend on the
assumption; we're not done yet.

R=ken2, r, ken3
CC=golang-dev
https://golang.org/cl/186263

37 files changed:
src/cmd/5g/ggen.c
src/cmd/5g/gobj.c
src/cmd/5g/gsubr.c
src/cmd/5l/l.h
src/cmd/5l/obj.c
src/cmd/6g/ggen.c
src/cmd/6g/gobj.c
src/cmd/6g/gsubr.c
src/cmd/6g/reg.c
src/cmd/6l/obj.c
src/cmd/8g/ggen.c
src/cmd/8g/gobj.c
src/cmd/8g/gsubr.c
src/cmd/8g/reg.c
src/cmd/8l/obj.c
src/cmd/cc/lex.c
src/cmd/cc/lexbody
src/cmd/gc/align.c
src/cmd/gc/builtin.c.boot
src/cmd/gc/dcl.c
src/cmd/gc/export.c
src/cmd/gc/gen.c
src/cmd/gc/go.h
src/cmd/gc/go.y
src/cmd/gc/init.c
src/cmd/gc/lex.c
src/cmd/gc/obj.c
src/cmd/gc/reflect.c
src/cmd/gc/subr.c
src/cmd/gc/typecheck.c
src/cmd/gc/unsafe.c
src/cmd/gopack/ar.c
src/cmd/gotest/gotest
src/cmd/ld/go.c
src/cmd/ld/lib.c
src/cmd/ld/lib.h
src/pkg/debug/gosym/pclntab_test.go

index e859f0578c38ea13469c000993adb580a526621e..3f32e601b3051125ecf073055c99c52b5c0465ef 100644 (file)
@@ -810,7 +810,7 @@ cgen_inline(Node *n, Node *res)
                goto no;
        if(!n->left->addable)
                goto no;
-       if(strcmp(n->left->sym->package, "runtime") != 0)
+       if(n->left->sym->pkg != runtimepkg)
                goto no;
        if(strcmp(n->left->sym->name, "slicearray") == 0)
                goto slicearray;
index 33cd123a4ce789b08efb2d9863a8556580711092..fffba011d012e1cfb4a27039f44cd008a522f902 100644 (file)
@@ -354,7 +354,7 @@ datastring(char *s, int len, Addr *a)
                tmp.lit.s[len] = '\0';
                len++;
                snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
-               ao.sym = pkglookup(namebuf, "string");
+               ao.sym = pkglookup(namebuf, stringpkg);
                ao.name = D_EXTERN;
        }
        *a = ao;
@@ -436,7 +436,7 @@ datagostring(Strlit *sval, Addr *a)
                // so that multiple modules using the same string
                // can share it.
                snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
-               ao.sym = pkglookup(namebuf, "go.string");
+               ao.sym = pkglookup(namebuf, gostringpkg);
                ao.name = D_EXTERN;
        }
 
index 5357d06fa0b123198136fbb4af0ef9020bf0324b..561d2ccceb6f29ab5124888909548b0c36dff486 100644 (file)
@@ -1074,8 +1074,8 @@ naddr(Node *n, Addr *a, int canemitcode)
                if(n->method) {
                        if(n->type != T)
                        if(n->type->sym != S)
-                       if(n->type->sym->package != nil)
-                               a->sym = pkglookup(a->sym->name, n->type->sym->package);
+                       if(n->type->sym->pkg != nil)
+                               a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
                }
 
                a->type = D_OREG;
index ba2de0a0f2f0fd3cfd02123151f3ca75e4eeb54d..8c00f11c1ce78b3286cae934de22659781a6d07e 100644 (file)
@@ -479,11 +479,4 @@ void       linuxshdr(char *name, uint32 type, vlong flags, vlong addr, vlong off,
        vlong size, uint32 link, uint32 info, vlong align, vlong entsize);
 int    linuxstrtable(void);
 
-/*
- *     go.c
- */
-void   deadcode(void);
-char*  gotypefor(char *name);
-void   ldpkg(Biobuf *f, int64 len, char *filename);
-
 #endif
index c1fdc7731bfef2eedd38d8765c3d8cc2d06835cb..9cfa0c45f4a5eb8a38c8f73f4dbe3bd927c42f21 100644 (file)
@@ -259,7 +259,7 @@ main(int argc, char *argv[])
        lastp = firstp;
 
        while(*argv)
-               objfile(*argv++);
+               objfile(*argv++, "main");
        if(!debug['l'])
                loadlib();
 
@@ -435,7 +435,7 @@ nopout(Prog *p)
 static void puntfp(Prog *);
 
 void
-ldobj1(Biobuf *f, int64 len, char *pn)
+ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
 {
        int32 ipc;
        Prog *p, *t;
@@ -445,7 +445,7 @@ ldobj1(Biobuf *f, int64 len, char *pn)
        char *name;
        int ntext;
        int32 eof;
-       char src[1024];
+       char src[1024], *x;
 
        ntext = 0;
        eof = Boffset(f) + len;
@@ -488,7 +488,11 @@ loop:
                        }
                        goto eof;
                }
-               s = lookup(name, r);
+               x = expandpkg(name, pkg);
+               s = lookup(x, r);
+               if(x != name)
+                       free(x);
+               name = nil;
 
                if(sig != 0){
                        if(s->sig != 0 && s->sig != sig)
index 5b42d0f1ae09b98fe1a73d76f3564fe844b2bfe0..731e922bb6666e560183ec142910e8c46183459c 100644 (file)
@@ -1138,7 +1138,7 @@ cgen_inline(Node *n, Node *res)
                goto no;
        if(!n->left->addable)
                goto no;
-       if(strcmp(n->left->sym->package, "runtime") != 0)
+       if(n->left->sym->pkg != runtimepkg)
                goto no;
        if(strcmp(n->left->sym->name, "slicearray") == 0)
                goto slicearray;
index ead0def1bcaee6affce6460e859b33c18a1ddaf2..0d97c610db05f260a876948dd22080c1125f4878 100644 (file)
@@ -364,7 +364,7 @@ datastring(char *s, int len, Addr *a)
                tmp.lit.s[len] = '\0';
                len++;
                snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
-               ao.sym = pkglookup(namebuf, "string");
+               ao.sym = pkglookup(namebuf, stringpkg);
                ao.type = D_EXTERN;
        }
        *a = ao;
@@ -445,7 +445,7 @@ datagostring(Strlit *sval, Addr *a)
                // so that multiple modules using the same string
                // can share it.
                snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
-               ao.sym = pkglookup(namebuf, "go.string");
+               ao.sym = pkglookup(namebuf, gostringpkg);
                ao.type = D_EXTERN;
        }
 
index aad5ff03f107faa4e4de17e564704e715b274db0..07471ffa7ce91a9282745294d763e233f1f273b8 100644 (file)
@@ -977,8 +977,8 @@ naddr(Node *n, Addr *a, int canemitcode)
                if(n->method) {
                        if(n->type != T)
                        if(n->type->sym != S)
-                       if(n->type->sym->package != nil)
-                               a->sym = pkglookup(a->sym->name, n->type->sym->package);
+                       if(n->type->sym->pkg != nil)
+                               a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
                }
 
                switch(n->class) {
index 9475f5943ed8564f96ce5f85ec6fc038397050cd..c8dd9a3ee1d337790a14c5e84b5fce623b1dcfaf 100644 (file)
@@ -1555,10 +1555,10 @@ noreturn(Prog *p)
        int i;
 
        if(symlist[0] == S) {
-               symlist[0] = pkglookup("throwindex", "runtime");
-               symlist[1] = pkglookup("throwslice", "runtime");
-               symlist[2] = pkglookup("throwinit", "runtime");
-               symlist[3] = pkglookup("panicl", "runtime");
+               symlist[0] = pkglookup("throwindex", runtimepkg);
+               symlist[1] = pkglookup("throwslice", runtimepkg);
+               symlist[2] = pkglookup("throwinit", runtimepkg);
+               symlist[3] = pkglookup("panicl", runtimepkg);
        }
 
        s = p->to.sym;
index 9ecdf6ee81a384315d83eb7f9d7c8429a75574a7..e29cdb94725774cd21cd2911ff48efaa4fd06115 100644 (file)
@@ -347,7 +347,7 @@ main(int argc, char *argv[])
        lastp = firstp;
 
        while(*argv)
-               objfile(*argv++);
+               objfile(*argv++, "main");
 
        if(!debug['l'])
                loadlib();
@@ -485,14 +485,14 @@ nopout(Prog *p)
 }
 
 void
-ldobj1(Biobuf *f, int64 len, char *pn)
+ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
 {
        vlong ipc;
        Prog *p, *t;
        int v, o, r, skip, mode;
        Sym *h[NSYM], *s, *di;
        uint32 sig;
-       char *name;
+       char *name, *x;
        int ntext;
        vlong eof;
        char src[1024];
@@ -542,7 +542,11 @@ loop:
                        }
                        goto eof;
                }
-               s = lookup(name, r);
+               x = expandpkg(name, pkg);
+               s = lookup(x, r);
+               if(x != name)
+                       free(x);
+               name = nil;
 
                if(debug['S'] && r == 0)
                        sig = 1729;
index 2e8837267ceb6a3962fb5737f06f0d920770c7d9..63a6b6f62282f63e441d8a88050f672f3f12f3b5 100644 (file)
@@ -836,7 +836,7 @@ cgen_inline(Node *n, Node *res)
                goto no;
        if(!n->left->addable)
                goto no;
-       if(strcmp(n->left->sym->package, "runtime") != 0)
+       if(n->left->sym->pkg != runtimepkg)
                goto no;
        if(strcmp(n->left->sym->name, "slicearray") == 0)
                goto slicearray;
index 698ebeeb6d91cc290e8b83a94a4ada0ea10865fa..68ebd3d1600995b39db2868d9bf848ec3bfde309 100644 (file)
@@ -362,7 +362,7 @@ datastring(char *s, int len, Addr *a)
                tmp.lit.s[len] = '\0';
                len++;
                snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
-               ao.sym = pkglookup(namebuf, "string");
+               ao.sym = pkglookup(namebuf, stringpkg);
                ao.type = D_EXTERN;
        }
        *a = ao;
@@ -443,7 +443,7 @@ datagostring(Strlit *sval, Addr *a)
                // so that multiple modules using the same string
                // can share it.
                snprint(namebuf, sizeof(namebuf), "\"%Z\"", sval);
-               ao.sym = pkglookup(namebuf, "go.string");
+               ao.sym = pkglookup(namebuf, gostringpkg);
                ao.type = D_EXTERN;
        }
 
index 2b94824996ab1ad9f0cffd4a89d7b986df75009f..e09ba7b20d279e9f7bc146b235aa33d75fd15d51 100644 (file)
@@ -1691,8 +1691,8 @@ naddr(Node *n, Addr *a, int canemitcode)
                if(n->method) {
                        if(n->type != T)
                        if(n->type->sym != S)
-                       if(n->type->sym->package != nil)
-                               a->sym = pkglookup(a->sym->name, n->type->sym->package);
+                       if(n->type->sym->pkg != nil)
+                               a->sym = pkglookup(a->sym->name, n->type->sym->pkg);
                }
 
                switch(n->class) {
index 66e1bc2f36b8ea24318fb68ce85d4dce11c9be54..50f47d9ca2f10b106e0a70ca1828b210cb292a3d 100644 (file)
@@ -1447,10 +1447,10 @@ noreturn(Prog *p)
        int i;
 
        if(symlist[0] == S) {
-               symlist[0] = pkglookup("throwindex", "runtime");
-               symlist[1] = pkglookup("throwslice", "runtime");
-               symlist[2] = pkglookup("throwinit", "runtime");
-               symlist[3] = pkglookup("panicl", "runtime");
+               symlist[0] = pkglookup("throwindex", runtimepkg);
+               symlist[1] = pkglookup("throwslice", runtimepkg);
+               symlist[2] = pkglookup("throwinit", runtimepkg);
+               symlist[3] = pkglookup("panicl", runtimepkg);
        }
 
        s = p->to.sym;
index 5918b0e8016d9504be75b0e79018e6580171c8cc..0d950748b60c5aa33c153ad4215e148e50d72310 100644 (file)
@@ -385,7 +385,7 @@ main(int argc, char *argv[])
        lastp = firstp;
 
        while(*argv)
-               objfile(*argv++);
+               objfile(*argv++, "main");
 
        if(!debug['l'])
                loadlib();
@@ -523,7 +523,7 @@ nopout(Prog *p)
 }
 
 void
-ldobj1(Biobuf *f, int64 len, char *pn)
+ldobj1(Biobuf *f, char *pkg, int64 len, char *pn)
 {
        int32 ipc;
        Prog *p, *t;
@@ -532,7 +532,7 @@ ldobj1(Biobuf *f, int64 len, char *pn)
        uint32 sig;
        int ntext;
        int32 eof;
-       char *name;
+       char *name, *x;
        char src[1024];
 
        ntext = 0;
@@ -580,7 +580,11 @@ loop:
                        }
                        goto eof;
                }
-               s = lookup(name, r);
+               x = expandpkg(name, pkg);
+               s = lookup(x, r);
+               if(x != name)
+                       free(x);
+               name = nil;
 
                if(debug['S'] && r == 0)
                        sig = 1729;
index 5a5651852037eb6003e4fc47cbbb533d272fec45..857b15206fff819ac43740b4460cce301f9775d2 100644 (file)
@@ -405,6 +405,13 @@ lookup(void)
        int c, n;
        char *r, *w;
 
+       if(symb[0] == 0xc2 && symb[1] == 0xb7) {
+               // turn leading · into ""·
+               memmove(symb+2, symb, w-symb);
+               symb[0] = '"';
+               symb[1] = '"';
+       }
+
        // turn · into .
        for(r=w=symb; *r; r++) {
                if((uchar)*r == 0xc2 && (uchar)*(r+1) == 0xb7) {
@@ -413,7 +420,7 @@ lookup(void)
                }else
                        *w++ = *r;
        }
-       *w = '\0';
+       *w++ = '\0';
 
        h = 0;
        for(p=symb; *p;) {
index c3b2d452946c4af8c38644a50fd820b5cd0216d7..7c726b3f5ea1e2c799f8e49e1e2c4f3fee6eeb03 100644 (file)
@@ -231,7 +231,13 @@ lookup(void)
                }else
                        *w++ = *r;
        }
-       *w = '\0';
+       *w++ = '\0';
+       if(symb[0] == '.') {
+               // turn leading . into "".
+               memmove(symb+2, symb, w-symb);
+               symb[0] = '"';
+               symb[1] = '"';
+       }
 
        h = 0;
        for(p=symb; c = *p; p++)
index cf085164657556f7c82828dc1dc70be444ef7686..ba84c4377fca5f8115f8f98047f5af539d61523e 100644 (file)
@@ -531,7 +531,7 @@ typeinit(void)
        /* pick up the backend typedefs */
        for(i=0; typedefs[i].name; i++) {
                s = lookup(typedefs[i].name);
-               s1 = pkglookup(typedefs[i].name, "/builtin/");
+               s1 = pkglookup(typedefs[i].name, builtinpkg);
 
                etype = typedefs[i].etype;
                if(etype < 0 || etype >= nelem(types))
index d2aec4e2afbbe7a547bf4e51f9f60c84ed0c1b67..3fb75f8649711b89377ee44eb93268dc526fe40a 100644 (file)
@@ -1,92 +1,92 @@
 char *runtimeimport =
        "package runtime\n"
-       "func \"runtime\".mal (? int32) (? *any)\n"
-       "func \"runtime\".throwindex ()\n"
-       "func \"runtime\".throwreturn ()\n"
-       "func \"runtime\".throwinit ()\n"
-       "func \"runtime\".panicl ()\n"
-       "func \"runtime\".printbool (? bool)\n"
-       "func \"runtime\".printfloat (? float64)\n"
-       "func \"runtime\".printint (? int64)\n"
-       "func \"runtime\".printuint (? uint64)\n"
-       "func \"runtime\".printstring (? string)\n"
-       "func \"runtime\".printpointer (? any)\n"
-       "func \"runtime\".printiface (? any)\n"
-       "func \"runtime\".printeface (? any)\n"
-       "func \"runtime\".printslice (? any)\n"
-       "func \"runtime\".printnl ()\n"
-       "func \"runtime\".printsp ()\n"
-       "func \"runtime\".catstring (? string, ? string) (? string)\n"
-       "func \"runtime\".cmpstring (? string, ? string) (? int)\n"
-       "func \"runtime\".slicestring (? string, ? int, ? int) (? string)\n"
-       "func \"runtime\".slicestring1 (? string, ? int) (? string)\n"
-       "func \"runtime\".indexstring (? string, ? int) (? uint8)\n"
-       "func \"runtime\".intstring (? int64) (? string)\n"
-       "func \"runtime\".slicebytetostring (? []uint8) (? string)\n"
-       "func \"runtime\".sliceinttostring (? []int) (? string)\n"
-       "func \"runtime\".stringiter (? string, ? int) (? int)\n"
-       "func \"runtime\".stringiter2 (? string, ? int) (retk int, retv int)\n"
-       "func \"runtime\".slicecopy (to any, fr any, wid uint32) (? int)\n"
-       "func \"runtime\".ifaceI2E (iface any) (ret any)\n"
-       "func \"runtime\".ifaceE2I (typ *uint8, iface any) (ret any)\n"
-       "func \"runtime\".ifaceT2E (typ *uint8, elem any) (ret any)\n"
-       "func \"runtime\".ifaceE2T (typ *uint8, elem any) (ret any)\n"
-       "func \"runtime\".ifaceE2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
-       "func \"runtime\".ifaceE2T2 (typ *uint8, elem any) (ret any, ok bool)\n"
-       "func \"runtime\".ifaceT2I (typ1 *uint8, typ2 *uint8, elem any) (ret any)\n"
-       "func \"runtime\".ifaceI2T (typ *uint8, iface any) (ret any)\n"
-       "func \"runtime\".ifaceI2T2 (typ *uint8, iface any) (ret any, ok bool)\n"
-       "func \"runtime\".ifaceI2I (typ *uint8, iface any) (ret any)\n"
-       "func \"runtime\".ifaceI2Ix (typ *uint8, iface any) (ret any)\n"
-       "func \"runtime\".ifaceI2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
-       "func \"runtime\".ifaceeq (i1 any, i2 any) (ret bool)\n"
-       "func \"runtime\".efaceeq (i1 any, i2 any) (ret bool)\n"
-       "func \"runtime\".ifacethash (i1 any) (ret uint32)\n"
-       "func \"runtime\".efacethash (i1 any) (ret uint32)\n"
-       "func \"runtime\".makemap (key *uint8, val *uint8, hint int) (hmap map[any] any)\n"
-       "func \"runtime\".mapaccess1 (hmap map[any] any, key any) (val any)\n"
-       "func \"runtime\".mapaccess2 (hmap map[any] any, key any) (val any, pres bool)\n"
-       "func \"runtime\".mapassign1 (hmap map[any] any, key any, val any)\n"
-       "func \"runtime\".mapassign2 (hmap map[any] any, key any, val any, pres bool)\n"
-       "func \"runtime\".mapiterinit (hmap map[any] any, hiter *any)\n"
-       "func \"runtime\".mapiternext (hiter *any)\n"
-       "func \"runtime\".mapiter1 (hiter *any) (key any)\n"
-       "func \"runtime\".mapiter2 (hiter *any) (key any, val any)\n"
-       "func \"runtime\".makechan (elem *uint8, hint int) (hchan chan any)\n"
-       "func \"runtime\".chanrecv1 (hchan <-chan any) (elem any)\n"
-       "func \"runtime\".chanrecv2 (hchan <-chan any) (elem any, pres bool)\n"
-       "func \"runtime\".chansend1 (hchan chan<- any, elem any)\n"
-       "func \"runtime\".chansend2 (hchan chan<- any, elem any) (pres bool)\n"
-       "func \"runtime\".closechan (hchan any)\n"
-       "func \"runtime\".closedchan (hchan any) (? bool)\n"
-       "func \"runtime\".newselect (size int) (sel *uint8)\n"
-       "func \"runtime\".selectsend (sel *uint8, hchan chan<- any, elem any) (selected bool)\n"
-       "func \"runtime\".selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
-       "func \"runtime\".selectdefault (sel *uint8) (selected bool)\n"
-       "func \"runtime\".selectgo (sel *uint8)\n"
-       "func \"runtime\".makeslice (typ *uint8, nel int, cap int) (ary []any)\n"
-       "func \"runtime\".sliceslice1 (old []any, lb int, width int) (ary []any)\n"
-       "func \"runtime\".sliceslice (old []any, lb int, hb int, width int) (ary []any)\n"
-       "func \"runtime\".slicearray (old *any, nel int, lb int, hb int, width int) (ary []any)\n"
-       "func \"runtime\".closure ()\n"
-       "func \"runtime\".int64div (? int64, ? int64) (? int64)\n"
-       "func \"runtime\".uint64div (? uint64, ? uint64) (? uint64)\n"
-       "func \"runtime\".int64mod (? int64, ? int64) (? int64)\n"
-       "func \"runtime\".uint64mod (? uint64, ? uint64) (? uint64)\n"
-       "func \"runtime\".float64toint64 (? float64) (? int64)\n"
-       "func \"runtime\".int64tofloat64 (? int64) (? float64)\n"
+       "func \"\".mal (? int32) (? *any)\n"
+       "func \"\".throwindex ()\n"
+       "func \"\".throwreturn ()\n"
+       "func \"\".throwinit ()\n"
+       "func \"\".panicl ()\n"
+       "func \"\".printbool (? bool)\n"
+       "func \"\".printfloat (? float64)\n"
+       "func \"\".printint (? int64)\n"
+       "func \"\".printuint (? uint64)\n"
+       "func \"\".printstring (? string)\n"
+       "func \"\".printpointer (? any)\n"
+       "func \"\".printiface (? any)\n"
+       "func \"\".printeface (? any)\n"
+       "func \"\".printslice (? any)\n"
+       "func \"\".printnl ()\n"
+       "func \"\".printsp ()\n"
+       "func \"\".catstring (? string, ? string) (? string)\n"
+       "func \"\".cmpstring (? string, ? string) (? int)\n"
+       "func \"\".slicestring (? string, ? int, ? int) (? string)\n"
+       "func \"\".slicestring1 (? string, ? int) (? string)\n"
+       "func \"\".indexstring (? string, ? int) (? uint8)\n"
+       "func \"\".intstring (? int64) (? string)\n"
+       "func \"\".slicebytetostring (? []uint8) (? string)\n"
+       "func \"\".sliceinttostring (? []int) (? string)\n"
+       "func \"\".stringiter (? string, ? int) (? int)\n"
+       "func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
+       "func \"\".slicecopy (to any, fr any, wid uint32) (? int)\n"
+       "func \"\".ifaceI2E (iface any) (ret any)\n"
+       "func \"\".ifaceE2I (typ *uint8, iface any) (ret any)\n"
+       "func \"\".ifaceT2E (typ *uint8, elem any) (ret any)\n"
+       "func \"\".ifaceE2T (typ *uint8, elem any) (ret any)\n"
+       "func \"\".ifaceE2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
+       "func \"\".ifaceE2T2 (typ *uint8, elem any) (ret any, ok bool)\n"
+       "func \"\".ifaceT2I (typ1 *uint8, typ2 *uint8, elem any) (ret any)\n"
+       "func \"\".ifaceI2T (typ *uint8, iface any) (ret any)\n"
+       "func \"\".ifaceI2T2 (typ *uint8, iface any) (ret any, ok bool)\n"
+       "func \"\".ifaceI2I (typ *uint8, iface any) (ret any)\n"
+       "func \"\".ifaceI2Ix (typ *uint8, iface any) (ret any)\n"
+       "func \"\".ifaceI2I2 (typ *uint8, iface any) (ret any, ok bool)\n"
+       "func \"\".ifaceeq (i1 any, i2 any) (ret bool)\n"
+       "func \"\".efaceeq (i1 any, i2 any) (ret bool)\n"
+       "func \"\".ifacethash (i1 any) (ret uint32)\n"
+       "func \"\".efacethash (i1 any) (ret uint32)\n"
+       "func \"\".makemap (key *uint8, val *uint8, hint int) (hmap map[any] any)\n"
+       "func \"\".mapaccess1 (hmap map[any] any, key any) (val any)\n"
+       "func \"\".mapaccess2 (hmap map[any] any, key any) (val any, pres bool)\n"
+       "func \"\".mapassign1 (hmap map[any] any, key any, val any)\n"
+       "func \"\".mapassign2 (hmap map[any] any, key any, val any, pres bool)\n"
+       "func \"\".mapiterinit (hmap map[any] any, hiter *any)\n"
+       "func \"\".mapiternext (hiter *any)\n"
+       "func \"\".mapiter1 (hiter *any) (key any)\n"
+       "func \"\".mapiter2 (hiter *any) (key any, val any)\n"
+       "func \"\".makechan (elem *uint8, hint int) (hchan chan any)\n"
+       "func \"\".chanrecv1 (hchan <-chan any) (elem any)\n"
+       "func \"\".chanrecv2 (hchan <-chan any) (elem any, pres bool)\n"
+       "func \"\".chansend1 (hchan chan<- any, elem any)\n"
+       "func \"\".chansend2 (hchan chan<- any, elem any) (pres bool)\n"
+       "func \"\".closechan (hchan any)\n"
+       "func \"\".closedchan (hchan any) (? bool)\n"
+       "func \"\".newselect (size int) (sel *uint8)\n"
+       "func \"\".selectsend (sel *uint8, hchan chan<- any, elem any) (selected bool)\n"
+       "func \"\".selectrecv (sel *uint8, hchan <-chan any, elem *any) (selected bool)\n"
+       "func \"\".selectdefault (sel *uint8) (selected bool)\n"
+       "func \"\".selectgo (sel *uint8)\n"
+       "func \"\".makeslice (typ *uint8, nel int, cap int) (ary []any)\n"
+       "func \"\".sliceslice1 (old []any, lb int, width int) (ary []any)\n"
+       "func \"\".sliceslice (old []any, lb int, hb int, width int) (ary []any)\n"
+       "func \"\".slicearray (old *any, nel int, lb int, hb int, width int) (ary []any)\n"
+       "func \"\".closure ()\n"
+       "func \"\".int64div (? int64, ? int64) (? int64)\n"
+       "func \"\".uint64div (? uint64, ? uint64) (? uint64)\n"
+       "func \"\".int64mod (? int64, ? int64) (? int64)\n"
+       "func \"\".uint64mod (? uint64, ? uint64) (? uint64)\n"
+       "func \"\".float64toint64 (? float64) (? int64)\n"
+       "func \"\".int64tofloat64 (? int64) (? float64)\n"
        "\n"
        "$$\n";
 char *unsafeimport =
        "package unsafe\n"
-       "type \"unsafe\".Pointer *any\n"
-       "func \"unsafe\".Offsetof (? any) (? int)\n"
-       "func \"unsafe\".Sizeof (? any) (? int)\n"
-       "func \"unsafe\".Alignof (? any) (? int)\n"
-       "func \"unsafe\".Typeof (i interface { }) (typ interface { })\n"
-       "func \"unsafe\".Reflect (i interface { }) (typ interface { }, addr \"unsafe\".Pointer)\n"
-       "func \"unsafe\".Unreflect (typ interface { }, addr \"unsafe\".Pointer) (ret interface { })\n"
-       "func \"unsafe\".New (typ interface { }) (? \"unsafe\".Pointer)\n"
-       "func \"unsafe\".NewArray (typ interface { }, n int) (? \"unsafe\".Pointer)\n"
+       "type \"\".Pointer *any\n"
+       "func \"\".Offsetof (? any) (? int)\n"
+       "func \"\".Sizeof (? any) (? int)\n"
+       "func \"\".Alignof (? any) (? int)\n"
+       "func \"\".Typeof (i interface { }) (typ interface { })\n"
+       "func \"\".Reflect (i interface { }) (typ interface { }, addr \"\".Pointer)\n"
+       "func \"\".Unreflect (typ interface { }, addr \"\".Pointer) (ret interface { })\n"
+       "func \"\".New (typ interface { }) (? \"\".Pointer)\n"
+       "func \"\".NewArray (typ interface { }, n int) (? \"\".Pointer)\n"
        "\n"
        "$$\n";
index 24c28b1f18e828082f419cfb4b80aa8277412e40..4639eda8d20f25153da3e0724748b3ce4cff9592 100644 (file)
@@ -27,8 +27,7 @@ static        Sym*    dclstack;
 void
 dcopy(Sym *a, Sym *b)
 {
-       a->packagename = b->packagename;
-       a->package = b->package;
+       a->pkg = b->pkg;
        a->name = b->name;
        a->def = b->def;
        a->block = b->block;
@@ -69,7 +68,7 @@ popdcl(void)
        for(d=dclstack; d!=S; d=d->link) {
                if(d->name == nil)
                        break;
-               s = pkglookup(d->name, d->package);
+               s = pkglookup(d->name, d->pkg);
                dcopy(s, d);
                if(dflag())
                        print("\t%L pop %S %p\n", lineno, s, s->def);
@@ -88,7 +87,7 @@ poptodcl(void)
        for(d=dclstack; d!=S; d=d->link) {
                if(d->name == nil)
                        break;
-               s = pkglookup(d->name, d->package);
+               s = pkglookup(d->name, d->pkg);
                dcopy(s, d);
                if(dflag())
                        print("\t%L pop %S\n", lineno, s);
@@ -129,7 +128,7 @@ dumpdcl(char *st)
                        continue;
                }
                print(" '%s'", d->name);
-               s = pkglookup(d->name, d->package);
+               s = pkglookup(d->name, d->pkg);
                print(" %lS\n", s);
        }
 }
@@ -883,7 +882,7 @@ stotype(NodeList *l, int et, Type **t)
                        f->nname = n->left;
                        f->embedded = n->embedded;
                        f->sym = f->nname->sym;
-                       if(pkgimportname != S && !exportname(f->sym->name))
+                       if(importpkg && !exportname(f->sym->name))
                                f->sym = pkglookup(f->sym->name, structpkg);
                        if(f->sym && !isblank(f->nname)) {
                                for(t1=*t0; t1!=T; t1=t1->down) {
@@ -1151,7 +1150,7 @@ methodsym(Sym *nsym, Type *t0)
                t0 = ptrto(t);
 
        snprint(buf, sizeof(buf), "%#hT·%s", t0, nsym->name);
-       return pkglookup(buf, s->package);
+       return pkglookup(buf, s->pkg);
 
 bad:
        yyerror("illegal receiver type: %T", t0);
@@ -1183,7 +1182,7 @@ methodname1(Node *n, Node *t)
        if(t->sym == S || isblank(n))
                return newname(n->sym);
        snprint(buf, sizeof(buf), "%s%S·%S", star, t->sym, n->sym);
-       return newname(pkglookup(buf, t->sym->package));
+       return newname(pkglookup(buf, t->sym->pkg));
 }
 
 /*
@@ -1217,8 +1216,8 @@ addmethod(Sym *sf, Type *t, int local)
        }
 
        pa = f;
-       if(pkgimportname != S && !exportname(sf->name))
-               sf = pkglookup(sf->name, pkgimportname->name);
+       if(importpkg && !exportname(sf->name))
+               sf = pkglookup(sf->name, importpkg);
 
        n = nod(ODCLFIELD, newname(sf), N);
        n->type = t;
index ad013ed66708227ee4567fcf746774ba65ff5856..16e6097953efa5c19f6d9dbcd985e3dc6679d899 100644 (file)
@@ -69,6 +69,15 @@ autoexport(Node *n, int ctxt)
                packagesym(n);
 }
 
+void
+dumppkg(Pkg *p)
+{
+       if(p == nil || p == localpkg || p->exported)
+               return;
+       p->exported = 1;
+       Bprint(bout, "\timport %s \"%Z\"\n", p->name, p->path);
+}
+
 void
 dumpprereq(Type *t)
 {
@@ -79,8 +88,11 @@ dumpprereq(Type *t)
                return;
        t->printed = 1;
 
-       if(t->sym != S && t->etype != TFIELD)
-               dumpsym(t->sym);
+       if(t->sym != S) {
+               dumppkg(t->sym->pkg);
+               if(t->etype != TFIELD)
+                       dumpsym(t->sym);
+       }
        dumpprereq(t->type);
        dumpprereq(t->down);
 }
@@ -101,7 +113,7 @@ dumpexportconst(Sym *s)
                dumpprereq(t);
 
        Bprint(bout, "\t");
-       Bprint(bout, "const %lS", s);
+       Bprint(bout, "const %#S", s);
        if(t != T && !isideal(t))
                Bprint(bout, " %#T", t);
        Bprint(bout, " = ");
@@ -145,9 +157,9 @@ dumpexportvar(Sym *s)
 
        Bprint(bout, "\t");
        if(t->etype == TFUNC && n->class == PFUNC)
-               Bprint(bout, "func %lS %#hhT", s, t);
+               Bprint(bout, "func %#S %#hhT", s, t);
        else
-               Bprint(bout, "var %lS %#T", s, t);
+               Bprint(bout, "var %#S %#T", s, t);
        Bprint(bout, "\n");
 }
 
@@ -180,6 +192,9 @@ dumpsym(Sym *s)
                yyerror("unknown export symbol: %S", s);
                return;
        }
+       
+       dumppkg(s->pkg);
+
        switch(s->def->op) {
        default:
                yyerror("unexpected export symbol: %O %S", s->def->op, s);
@@ -227,10 +242,9 @@ dumpexport(void)
        lno = lineno;
 
        packagequotes = 1;
-       Bprint(bout, "   import\n");
        Bprint(bout, "\n$$  // exports\n");
 
-       Bprint(bout, "    package %s\n", package);
+       Bprint(bout, "    package %s\n", localpkg->name);
 
        for(l=exportlist; l; l=l->next) {
                lineno = l->n->lineno;
@@ -269,7 +283,6 @@ importsym(Sym *s, int op)
                        s->flags |= SymExport;
                else
                        s->flags |= SymPackage; // package scope
-               s->flags |= SymImported;
        }
        return s;
 }
@@ -298,8 +311,7 @@ mypackage(Sym *s)
 {
        // we import all definitions for runtime.
        // lowercase ones can only be used by the compiler.
-       return strcmp(s->package, package) == 0
-               || strcmp(s->package, "runtime") == 0;
+       return s->pkg == localpkg || s->pkg == runtimepkg;
 }
 
 void
index 56dd752fb775af41bb5d612e6b15cba33de822c6..279cad998f77a45a41a5e13f4210d284cbe93093 100644 (file)
@@ -14,7 +14,7 @@ sysfunc(char *name)
 {
        Node *n;
 
-       n = newname(pkglookup(name, "runtime"));
+       n = newname(pkglookup(name, runtimepkg));
        n->class = PFUNC;
        return n;
 }
index fea438fd132958e2eed61cb207cb2e6856803768..cb0b1a119ec9a471e2542d8c4054d66dcb126e62 100644 (file)
@@ -136,6 +136,7 @@ struct      Val
        } u;
 };
 
+typedef        struct  Pkg Pkg;
 typedef        struct  Sym     Sym;
 typedef        struct  Node    Node;
 typedef        struct  NodeList        NodeList;
@@ -258,6 +259,9 @@ struct      Node
        Node*   outer;  // outer PPARAMREF in nested closure
        Node*   closure;        // ONAME/PHEAP <-> ONAME/PPARAMREF
 
+       // OPACK
+       Pkg*    pkg;
+
        Sym*    sym;            // various
        int32   vargen;         // unique name for OTYPE/ONAME
        int32   lineno;
@@ -278,9 +282,8 @@ enum
        SymExport       = 1<<0,
        SymPackage      = 1<<1,
        SymExported     = 1<<2,
-       SymImported     = 1<<3,
-       SymUniq         = 1<<4,
-       SymSiggen       = 1<<5,
+       SymUniq         = 1<<3,
+       SymSiggen       = 1<<4,
 };
 
 struct Sym
@@ -291,8 +294,7 @@ struct      Sym
        Sym*    link;
 
        // saved and restored by dcopy
-       char*   packagename;    // package name
-       char*   package;        // import path
+       Pkg*    pkg;
        char*   name;           // variable name
        Node*   def;            // definition: ONAME OTYPE OPACK or OLITERAL
        int32   block;          // blocknumber to catch redeclaration
@@ -300,6 +302,15 @@ struct     Sym
 };
 #define        S       ((Sym*)0)
 
+struct Pkg
+{
+       char*   name;
+       Strlit* path;
+       char*   prefix;
+       Pkg*    link;
+       int     exported;
+};
+
 typedef        struct  Iter    Iter;
 struct Iter
 {
@@ -530,10 +541,10 @@ struct    Typedef
 extern Typedef typedefs[];
 
 typedef        struct  Sig     Sig;
-struct Sig
+struct Sig
 {
        char*   name;
-       char*   package;
+       Pkg*    pkg;
        Sym*    isym;
        Sym*    tsym;
        Type*   type;
@@ -631,7 +642,6 @@ EXTERN      Hist*   ehist;
 
 EXTERN char*   infile;
 EXTERN char*   outfile;
-EXTERN char*   package;
 EXTERN Biobuf* bout;
 EXTERN int     nerrors;
 EXTERN int     nsyntaxerrors;
@@ -639,8 +649,16 @@ EXTERN     char    namebuf[NSYMB];
 EXTERN char    lexbuf[NSYMB];
 EXTERN char    debug[256];
 EXTERN Sym*    hash[NHASH];
-EXTERN Sym*    pkgmyname;      // my name for package
-EXTERN Sym*    pkgimportname;  // package name from imported package
+EXTERN Sym*    importmyname;   // my name for package
+EXTERN Pkg*    localpkg;       // package being compiled
+EXTERN Pkg*    importpkg;      // package being imported
+EXTERN Pkg*    structpkg;      // package that declared struct, during import
+EXTERN Pkg*    builtinpkg;     // fake package for builtins
+EXTERN Pkg*    gostringpkg;    // fake pkg for Go strings
+EXTERN Pkg*    runtimepkg;     // package runtime
+EXTERN Pkg*    stringpkg;      // fake package for C strings
+EXTERN Pkg*    typepkg;        // fake package for runtime type info
+EXTERN Pkg*    unsafepkg;      // package unsafe
 EXTERN int     tptr;           // either TPTR32 or TPTR64
 extern char*   runtimeimport;
 extern char*   unsafeimport;
@@ -701,7 +719,6 @@ EXTERN      int     widthptr;
 EXTERN Node*   typesw;
 EXTERN Node*   nblank;
 
-EXTERN char*   structpkg;
 extern int     thechar;
 extern char*   thestring;
 EXTERN char*   hunk;
@@ -805,9 +822,11 @@ void*      remal(void*, int32, int32);
 void   errorexit(void);
 uint32 stringhash(char*);
 Sym*   lookup(char*);
-Sym*   pkglookup(char*, char*);
-Sym*   restrictlookup(char*, char*);
-void   importdot(Sym*, Node*);
+Sym*   pkglookup(char*, Pkg*);
+Sym*   restrictlookup(char*, Pkg*);
+Pkg*   mkpkg(Strlit*);
+Strlit*        strlit(char*);
+void   importdot(Pkg*, Node*);
 void   yyerror(char*, ...);
 void   yyerrorl(int, char*, ...);
 void   flusherrors(void);
@@ -915,7 +934,6 @@ void        umagic(Magic*);
 void   redeclare(Sym*, char*);
 Sym*   ngotype(Node*);
 
-char*  toimportpath(Strlit*);
 
 /*
  *     dcl.c
index 93adf1c1afa9b263f86bbe951cda44c96c99081f..bc543d5e346f5a9403060bc053fcc17f281c294f 100644 (file)
@@ -142,6 +142,8 @@ package:
  */
 loadsys:
        {
+               importpkg = runtimepkg;
+
                if(debug['A'])
                        cannedimports("runtime.builtin", "package runtime\n\n$$\n\n");
                else
@@ -150,7 +152,7 @@ loadsys:
        import_package
        import_there
        {
-               pkgimportname = S;
+               importpkg = nil;
        }
 
 imports:
@@ -164,25 +166,25 @@ import:
 import_stmt:
        import_here import_package import_there
        {
-               Sym *import, *my;
+               Pkg *ipkg;
+               Sym *my;
                Node *pack;
+               
+               ipkg = importpkg;
+               my = importmyname;
+               importpkg = nil;
+               importmyname = S;
 
-               import = pkgimportname;
-               my = pkgmyname;
-               pkgmyname = S;
-               pkgimportname = S;
-
-               if(import == S)
-                       break;
+               if(my == nil)
+                       my = lookup(ipkg->name);
 
                pack = nod(OPACK, N, N);
-               pack->sym = import;
+               pack->sym = my;
+               pack->pkg = ipkg;
                pack->lineno = $1;
 
-               if(my == S)
-                       my = import;
                if(my->name[0] == '.') {
-                       importdot(import, pack);
+                       importdot(ipkg, pack);
                        break;
                }
                if(my->name[0] == '_' && my->name[1] == '\0')
@@ -211,36 +213,36 @@ import_here:
        {
                // import with original name
                $$ = parserline();
-               pkgimportname = S;
-               pkgmyname = S;
+               importmyname = S;
                importfile(&$1, $$);
        }
 |      sym LLITERAL
        {
                // import with given name
                $$ = parserline();
-               pkgimportname = S;
-               pkgmyname = $1;
+               importmyname = $1;
                importfile(&$2, $$);
        }
 |      '.' LLITERAL
        {
                // import into my name space
                $$ = parserline();
-               pkgmyname = lookup(".");
+               importmyname = lookup(".");
                importfile(&$2, $$);
        }
 
 import_package:
        LPACKAGE sym ';'
        {
-               pkgimportname = $2;
+               importpkg->name = $2->name;
+
+               // PGNS: fixme
                if(strcmp($2->name, "main") == 0)
                        yyerror("cannot import package main");
 
-               // TODO(rsc): This should go away once we get
+               // PGNS: This should go away once we get
                // rid of the global package name space.
-               if(strcmp($2->name, package) == 0 && strcmp(package, "runtime") != 0)
+               if(localpkg->name && strcmp($2->name, localpkg->name) == 0 && strcmp($2->name, "runtime") != 0)
                        yyerror("package cannot import itself");
        }
 
@@ -254,16 +256,6 @@ import_there:
                checkimports();
                unimportfile();
        }
-|      LIMPORT '$' '$'
-       {
-               defercheckwidth();
-       }
-       hidden_import_list '$' '$'
-       {
-               resumecheckwidth();
-               checkimports();
-               unimportfile();
-       }
 
 /*
  * declarations
@@ -786,7 +778,7 @@ pexpr:
        {
                if($1->op == OPACK) {
                        Sym *s;
-                       s = restrictlookup($3->name, $1->sym->name);
+                       s = restrictlookup($3->name, $1->pkg);
                        $1->used = 1;
                        $$ = oldname(s);
                        break;
@@ -977,7 +969,7 @@ dotname:
        {
                if($1->op == OPACK) {
                        Sym *s;
-                       s = restrictlookup($3->name, $1->sym->name);
+                       s = restrictlookup($3->name, $1->pkg);
                        $1->used = 1;
                        $$ = oldname(s);
                        break;
@@ -1256,14 +1248,14 @@ packname:
        }
 |      LNAME '.' sym
        {
-               char *pkg;
+               Pkg *pkg;
 
                if($1->def == N || $1->def->op != OPACK) {
                        yyerror("%S is not a package", $1);
-                       pkg = $1->name;
+                       pkg = localpkg;
                } else {
                        $1->def->used = 1;
-                       pkg = $1->def->sym->name;
+                       pkg = $1->def->pkg;
                }
                $$ = restrictlookup($3->name, pkg);
        }
@@ -1549,16 +1541,15 @@ oliteral:
  * an output package
  */
 hidden_import:
-       LIMPORT sym LLITERAL
+       LIMPORT sym LLITERAL ';'
        {
                // Informational: record package name
                // associated with import path, for use in
                // human-readable messages.
+               Pkg *p;
 
-               Sym *s;
-
-               s = pkglookup("", toimportpath($3.u.sval));
-               s->packagename = $2->name;
+               p = mkpkg($3.u.sval);
+               p->name = $2->name;
        }
 |      LVAR hidden_pkg_importsym hidden_type ';'
        {
@@ -1617,7 +1608,7 @@ hidden_type_misc:
 |      LNAME
        {
                // predefined name like uint8
-               $1 = pkglookup($1->name, "/builtin/");
+               $1 = pkglookup($1->name, builtinpkg);
                if($1->def == N || $1->def->op != OTYPE) {
                        yyerror("%s is not a type", $1->name);
                        $$ = T;
@@ -1709,7 +1700,7 @@ hidden_structdcl:
                s = $2->sym;
                if(s == S && isptr[$2->etype])
                        s = $2->type->sym;
-               if(s && strcmp(s->package, "/builtin/") == 0)
+               if(s && s->pkg == builtinpkg)
                        s = lookup(s->name);
                $$ = embedded(s);
                $$->right = typenod($2);
@@ -1759,7 +1750,7 @@ hidden_constant:
        }
 |      sym
        {
-               $$ = oldname(pkglookup($1->name, "/builtin/"));
+               $$ = oldname(pkglookup($1->name, builtinpkg));
                if($$->op != OLITERAL)
                        yyerror("bad constant %S", $$->sym);
        }
@@ -1767,14 +1758,20 @@ hidden_constant:
 hidden_importsym:
        LLITERAL '.' sym
        {
-               $$ = pkglookup($3->name, toimportpath($1.u.sval));
+               Pkg *p;
+
+               if($1.u.sval->len == 0)
+                       p = importpkg;
+               else
+                       p = mkpkg($1.u.sval);
+               $$ = pkglookup($3->name, p);
        }
 
 hidden_pkg_importsym:
        hidden_importsym
        {
                $$ = $1;
-               structpkg = $$->package;
+               structpkg = $$->pkg;
        }
 
 hidden_import_list:
index ef97459eb30669d31e35cff3b4895df96c474aba..3c2ecf27ff71fab7168768dde7d934bc39c0ca2b 100644 (file)
@@ -70,7 +70,7 @@ anyinit(NodeList *n)
        }
 
        // is this main
-       if(strcmp(package, "main") == 0)
+       if(strcmp(localpkg->name, "main") == 0)
                return 1;
 
        // is there an explicit init function
@@ -103,7 +103,7 @@ fninit(NodeList *n)
        uint32 h;
        Sym *s, *initsym;
 
-       if(strcmp(package, "PACKAGE") == 0) {
+       if(debug['A']) {
                // sys.go or unsafe.go during compiler build
                return;
        }
@@ -126,7 +126,7 @@ fninit(NodeList *n)
 
        // this is a botch since we need a known name to
        // call the top level init function out of rt0
-       if(strcmp(package, "main") == 0)
+       if(strcmp(localpkg->name, "main") == 0)
                snprint(namebuf, sizeof(namebuf), "init");
 
        fn = nod(ODCLFUNC, N, N);
index 84e6a2e97b5c1cc29e77ae1e8cebbe4910444c67..efbb11631dc80233fe161f9e64c835c4e2611fe8 100644 (file)
@@ -8,8 +8,8 @@
 #include <ar.h>
 
 extern int yychar;
-char nopackage[] = "____";
 void lexfini(void);
+static char *goos, *goarch, *goroot;
 
 #define        DBG     if(!debug['x']);else print
 enum
@@ -23,8 +23,22 @@ main(int argc, char *argv[])
        int i, c;
        NodeList *l;
 
+       localpkg = mkpkg(strlit(""));
+       localpkg->prefix = "\"\"";
+
+       builtinpkg = mkpkg(strlit("go.builtin"));
+       gostringpkg = mkpkg(strlit("go.string"));
+       gostringpkg->prefix = "go.string";
+       runtimepkg = mkpkg(strlit("runtime"));
+       stringpkg = mkpkg(strlit("string"));
+       typepkg = mkpkg(strlit("type"));
+       unsafepkg = mkpkg(strlit("unsafe"));
+
+       goroot = getgoroot();
+       goos = getgoos();
+       goarch = thestring;
+
        outfile = nil;
-       package = nopackage;
        ARGBEGIN {
        default:
                c = ARGC();
@@ -36,10 +50,6 @@ main(int argc, char *argv[])
                outfile = ARGF();
                break;
 
-       case 'k':
-               package = ARGF();
-               break;
-
        case 'I':
                addidir(ARGF());
                break;
@@ -98,7 +108,7 @@ main(int argc, char *argv[])
                        Bterm(curio.bin);
        }
        testdclstack();
-       mkpackage(package);     // final import not used checks
+       mkpackage(localpkg->name);      // final import not used checks
        lexfini();
 
        typecheckok = 1;
@@ -140,7 +150,6 @@ usage:
        print("  -e no limit on number of errors printed\n");
        print("  -f print stack frame structure\n");
        print("  -h panic on an error\n");
-       print("  -k name specify package name\n");
        print("  -o file specify output file\n");
        print("  -S print the assembly language\n");
        print("  -w print the parse tree after typing\n");
@@ -219,15 +228,8 @@ islocalname(Strlit *name)
 int
 findpkg(Strlit *name)
 {
-       static char *goroot, *goos, *goarch;
        Idir *p;
 
-       if(goroot == nil) {
-               goroot = getgoroot();
-               goos = getgoos();
-               goarch = thestring;
-       }
-
        if(islocalname(name)) {
                // try .a before .6.  important for building libraries:
                // if there is an array.6 in the array.a library,
@@ -267,21 +269,39 @@ importfile(Val *f, int line)
        char *file, *p;
        int32 c;
        int len;
+       Strlit *path;
+       char cleanbuf[1024];
 
        // TODO(rsc): don't bother reloading imports more than once
 
+       // PGNS: canonicalize import path for ./ imports in findpkg.
+
        if(f->ctype != CTSTR) {
                yyerror("import statement not a string");
                return;
        }
 
+       if(strlen(f->u.sval->s) != f->u.sval->len)
+               fatal("import path contains NUL");
+
        if(strcmp(f->u.sval->s, "unsafe") == 0) {
+               importpkg = mkpkg(f->u.sval);
                cannedimports("unsafe.6", unsafeimport);
                return;
        }
 
        if(!findpkg(f->u.sval))
                fatal("can't find import: %Z", f->u.sval);
+
+       path = f->u.sval;
+       if(islocalname(path)) {
+               snprint(cleanbuf, sizeof cleanbuf, "%s/%s", pathname, path->s);
+               cleanname(cleanbuf);
+               path = strlit(cleanbuf);
+       }
+
+       importpkg = mkpkg(path);
+
        imp = Bopen(namebuf, OREAD);
        if(imp == nil)
                fatal("can't open import: %Z", f->u.sval);
@@ -1286,7 +1306,7 @@ lexinit(void)
                                        dowidth(t);
                                types[etype] = t;
                        }
-                       s1 = pkglookup(syms[i].name, "/builtin/");      // impossible pkg name for builtins
+                       s1 = pkglookup(syms[i].name, builtinpkg);
                        s1->lexical = LNAME;
                        s1->def = typenod(t);
                        continue;
@@ -1307,12 +1327,12 @@ lexinit(void)
        idealstring = typ(TSTRING);
        idealbool = typ(TBOOL);
 
-       s = pkglookup("true", "/builtin/");
+       s = pkglookup("true", builtinpkg);
        s->def = nodbool(1);
        s->def->sym = lookup("true");
        s->def->type = idealbool;
 
-       s = pkglookup("false", "/builtin/");
+       s = pkglookup("false", builtinpkg);
        s->def = nodbool(0);
        s->def->sym = lookup("false");
        s->def->type = idealbool;
@@ -1444,28 +1464,22 @@ lexname(int lex)
 }
 
 void
-mkpackage(char* pkg)
+mkpackage(char* pkgname)
 {
        Sym *s;
        int32 h;
        char *p;
 
-       if(package == nopackage) {
-               if(strcmp(pkg, "_") == 0)
+       if(localpkg->name == nil) {
+               if(strcmp(pkgname, "_") == 0)
                        yyerror("invalid package name _");
-
-               // redefine all names to be this package.
-               for(h=0; h<NHASH; h++)
-                       for(s = hash[h]; s != S; s = s->link)
-                               if(s->package == nopackage)
-                                       s->package = pkg;
-               package = pkg;
+               localpkg->name = pkgname;
        } else {
-               if(strcmp(pkg, package) != 0)
-                       yyerror("package %s; expected %s", pkg, package);
+               if(strcmp(pkgname, localpkg->name) != 0)
+                       yyerror("package %s; expected %s", pkgname, localpkg->name);
                for(h=0; h<NHASH; h++) {
                        for(s = hash[h]; s != S; s = s->link) {
-                               if(s->def == N || s->package != package)
+                               if(s->def == N || s->pkg != localpkg)
                                        continue;
                                if(s->def->op == OPACK) {
                                        // throw away top-level package name leftover
index e2343021b189cf23052ffdd18bbb32211585278f..12054645f1c2eada99136c0cfda894b6631cba50 100644 (file)
@@ -17,7 +17,7 @@ dumpobj(void)
 
        Bprint(bout, "%s\n", thestring);
        Bprint(bout, "  exports automatically generated from\n");
-       Bprint(bout, "  %s in package \"%s\"\n", curio.infile, package);
+       Bprint(bout, "  %s in package \"%s\"\n", curio.infile, localpkg->name);
        dumpexport();
        Bprint(bout, "\n!\n");
 
@@ -51,7 +51,7 @@ dumpglobls(void)
                        fatal("external %#N nil type\n", n);
                if(n->class == PFUNC)
                        continue;
-               if(n->sym->package != package)
+               if(n->sym->pkg != localpkg)
                        continue;
                dowidth(n->type);
 
@@ -63,9 +63,7 @@ dumpglobls(void)
 void
 Bputname(Biobuf *b, Sym *s)
 {
-// PGNS: Uncomment next line.
-//     if(strcmp(s->package, package) != 0)
-               Bwrite(b, s->package, strlen(s->package));
+       Bprint(b, "%s", s->pkg->prefix);
        Bputc(b, '.');
        Bwrite(b, s->name, strlen(s->name)+1);
 }
index 85d4ad6d682c27f921e9f5f8c07e507177a5bf12..0e9ece92f54d1c13b8691deabd82cf30453d277f 100644 (file)
@@ -174,8 +174,8 @@ methods(Type *t)
                a->name = method->name;
                a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type);
                if(!exportname(a->name)) {
-                       a->package = method->package;
-                       a->hash += PRIME10*stringhash(a->package);
+                       a->pkg = method->pkg;
+                       a->hash += PRIME10*stringhash(a->pkg->name);
                }
                a->perm = o++;
                a->isym = methodsym(method, it);
@@ -250,8 +250,8 @@ imethods(Type *t)
                a->name = f->sym->name;
                a->hash = PRIME8*stringhash(a->name) + PRIME9*typehash(f->type);
                if(!exportname(a->name)) {
-                       a->package = f->sym->package;
-                       a->hash += PRIME10*stringhash(a->package);
+                       a->pkg = f->sym->pkg;
+                       a->hash += PRIME10*stringhash(a->pkg->name);
                }
                a->perm = o++;
                a->offset = 0;
@@ -261,6 +261,19 @@ imethods(Type *t)
        return lsort(a, sigcmp);
 }
 
+static int
+dgopkgpath(Sym *s, int ot, Pkg *pkg)
+{
+       if(pkg == nil)
+               return dgostringptr(s, ot, nil);
+
+       // PGNS: This needs to be import path instead of pkg->name,
+       // but we need to figure out how to fill it in during 6l when
+       // trying to refer to localpkg.
+       return dgostringptr(s, ot, pkg->name);
+}
+
+
 /*
  * uncommonType
  * ../../pkg/runtime/type.go:/uncommonType
@@ -283,13 +296,13 @@ dextratype(Type *t)
                n++;
        }
 
-       p = smprint("%#-T", t);
-       s = pkglookup(p, "extratype");
+       p = smprint("_.%#T", t);
+       s = pkglookup(p, typepkg);
        ot = 0;
        if(t->sym) {
                ot = dgostringptr(s, ot, t->sym->name);
                if(t != types[t->etype])
-                       ot = dgostringptr(s, ot, t->sym->package);
+                       ot = dgopkgpath(s, ot, t->sym->pkg);
                else
                        ot = dgostringptr(s, ot, nil);
        } else {
@@ -309,7 +322,7 @@ dextratype(Type *t)
                ot = duint32(s, ot, a->hash);
                ot = rnd(ot, widthptr);
                ot = dgostringptr(s, ot, a->name);
-               ot = dgostringptr(s, ot, a->package);
+               ot = dgopkgpath(s, ot, a->pkg);
                ot = dsymptr(s, ot, dtypesym(a->type), 0);
                if(a->isym)
                        ot = dsymptr(s, ot, a->isym, 0);
@@ -435,7 +448,7 @@ typestruct(Type *t)
        if(isptr[et] && t->type->etype == TANY)
                name = "*runtime.UnsafePointerType";
 
-       return pkglookup(name, "type");
+       return pkglookup(name, typepkg);
 }
 
 static int
@@ -550,7 +563,7 @@ typesym(Type *t)
        Sym *s;
 
        p = smprint("%#-T", t);
-       s = pkglookup(p, "type");
+       s = pkglookup(p, typepkg);
        free(p);
        return s;
 }
@@ -613,7 +626,8 @@ dtypesym(Type *t)
        else
                tsym = t->sym;
 
-       if(strcmp(package, "runtime") == 0) {
+       // PGNS: Fixme
+       if(strcmp(localpkg->name, "runtime") == 0) {
                if(t == types[t->etype])
                        goto ok;
                if(t1 && t1 == types[t1->etype])
@@ -702,7 +716,7 @@ ok:
                        ot = duint32(s, ot, a->hash);
                        ot = duint32(s, ot, a->perm);
                        ot = dgostringptr(s, ot, a->name);
-                       ot = dgostringptr(s, ot, a->package);
+                       ot = dgopkgpath(s, ot, a->pkg);
                        ot = dsymptr(s, ot, dtypesym(a->type), 0);
                }
                break;
@@ -747,7 +761,7 @@ ok:
                                if(exportname(t1->sym->name))
                                        ot = dgostringptr(s, ot, nil);
                                else
-                                       ot = dgostringptr(s, ot, t1->sym->package);
+                                       ot = dgopkgpath(s, ot, t1->sym->pkg);
                        } else {
                                ot = dgostringptr(s, ot, nil);
                                ot = dgostringptr(s, ot, nil);
@@ -796,11 +810,11 @@ dumptypestructs(void)
        // so this is as good as any.
        // another possible choice would be package main,
        // but using runtime means fewer copies in .6 files.
-       if(strcmp(package, "runtime") == 0) {
+       if(strcmp(localpkg->name, "runtime") == 0) {    // PGNS: fixme
                for(i=1; i<=TBOOL; i++)
                        dtypesym(ptrto(types[i]));
                dtypesym(ptrto(types[TSTRING]));
                dtypesym(typ(TDDD));
-               dtypesym(ptrto(pkglookup("Pointer", "unsafe")->def->type));
+               dtypesym(ptrto(pkglookup("Pointer", unsafepkg)->def->type));
        }
 }
index 411000b0c4ed773fbe7d1af3dd728c7abf12ad0f..c15bdd0ffd4c22f0f50f02e4178d10c8822fb4c4 100644 (file)
@@ -256,11 +256,11 @@ stringhash(char *p)
 Sym*
 lookup(char *name)
 {
-       return pkglookup(name, package);
+       return pkglookup(name, localpkg);
 }
 
 Sym*
-pkglookup(char *name, char *pkg)
+pkglookup(char *name, Pkg *pkg)
 {
        Sym *s;
        uint32 h;
@@ -269,26 +269,17 @@ pkglookup(char *name, char *pkg)
        h = stringhash(name) % NHASH;
        c = name[0];
        for(s = hash[h]; s != S; s = s->link) {
-               if(s->name[0] != c)
+               if(s->name[0] != c || s->pkg != pkg)
                        continue;
                if(strcmp(s->name, name) == 0)
-                       if(s->package && strcmp(s->package, pkg) == 0)
-                               return s;
+                       return s;
        }
 
        s = mal(sizeof(*s));
        s->name = mal(strlen(name)+1);
        strcpy(s->name, name);
 
-       // botch - should probably try to reuse the pkg string
-       if(pkg == package)
-               s->package = package;
-       else {
-               s->package = mal(strlen(pkg)+1);
-               strcpy(s->package, pkg);
-       }
-
-       s->packagename = s->package;
+       s->pkg = pkg;
 
        s->link = hash[h];
        hash[h] = s;
@@ -298,9 +289,9 @@ pkglookup(char *name, char *pkg)
 }
 
 Sym*
-restrictlookup(char *name, char *pkg)
+restrictlookup(char *name, Pkg *pkg)
 {
-       if(!exportname(name) && strcmp(pkg, package) != 0)
+       if(!exportname(name) && pkg != localpkg)
                yyerror("cannot refer to unexported name %s.%s", pkg, name);
        return pkglookup(name, pkg);
 }
@@ -309,25 +300,19 @@ restrictlookup(char *name, char *pkg)
 // find all the exported symbols in package opkg
 // and make them available in the current package
 void
-importdot(Sym *opkg, Node *pack)
+importdot(Pkg *opkg, Node *pack)
 {
        Sym *s, *s1;
        uint32 h;
-       int c, n;
-
-       if(strcmp(opkg->name, package) == 0)
-               return;
+       int n;
 
        n = 0;
-       c = opkg->name[0];
        for(h=0; h<NHASH; h++) {
                for(s = hash[h]; s != S; s = s->link) {
-                       if(s->package[0] != c)
+                       if(s->pkg != opkg)
                                continue;
                        if(!exportname(s->name) || utfrune(s->name, 0xb7))      // 0xb7 = center dot
                                continue;
-                       if(strcmp(s->package, opkg->name) != 0)
-                               continue;
                        s1 = lookup(s->name);
                        if(s1->def != N) {
                                redeclare(s1, "during import");
@@ -983,27 +968,41 @@ int
 Sconv(Fmt *fp)
 {
        Sym *s;
-       char *pkg, *nam;
 
        s = va_arg(fp->args, Sym*);
        if(s == S) {
                fmtstrcpy(fp, "<S>");
                return 0;
        }
+       
+       if(fp->flags & FmtShort)
+               goto shrt;
 
-       pkg = "<nil>";
-       nam = pkg;
+       if(exporting || (fp->flags & FmtSharp)) {
+               if(packagequotes)
+                       fmtprint(fp, "\"%Z\"", s->pkg->path);
+               else {
+                       // PGNS: Should be s->pkg->prefix
+                       fmtprint(fp, "%s", s->pkg->name);
+               }
+               fmtprint(fp, ".%s", s->name);
+               return 0;
+       }
 
-       if(s->packagename != nil)
-               pkg = s->packagename;
-       else
-               abort();
-       if(s->name != nil)
-               nam = s->name;
+       if(s->pkg != localpkg || (fp->flags & FmtLong)) {
+               fmtprint(fp, "%s.%s", s->pkg->name, s->name);
+               return 0;
+       }
+
+shrt:
+       fmtstrcpy(fp, s->name);
+       return 0;
+
+       /*
 
        if(!(fp->flags & FmtShort)) {
                if((fp->flags & FmtLong) && packagequotes) {
-                       fmtprint(fp, "\"%s\".%s", s->package, nam);
+                       fmtprint(fp, "\"%Z\".%s", s->pkg->path, nam);
                        return 0;
                }
                if((fp->flags & FmtLong) || strcmp(s->package, package) != 0) {
@@ -1012,6 +1011,7 @@ Sconv(Fmt *fp)
                }
        }
        fmtstrcpy(fp, nam);
+       */
        return 0;
 }
 
@@ -1057,10 +1057,8 @@ Tpretty(Fmt *fp, Type *t)
                        if(fp->flags & FmtShort)
                                fmtprint(fp, "%hS", s);
                        else
-                               fmtprint(fp, "%lS", s);
-                       if(strcmp(s->package, package) != 0)
-                               return 0;
-                       if(s->flags & SymImported)
+                               fmtprint(fp, "%S", s);
+                       if(s->pkg != localpkg)
                                return 0;
                        if(t->vargen)
                                fmtprint(fp, "·%d", t->vargen);
@@ -1537,13 +1535,13 @@ isselect(Node *n)
        if(n == N)
                return 0;
        n = n->left;
-       s = pkglookup("selectsend", "runtime");
+       s = pkglookup("selectsend", runtimepkg);
        if(s == n->sym)
                return 1;
-       s = pkglookup("selectrecv", "runtime");
+       s = pkglookup("selectrecv", runtimepkg);
        if(s == n->sym)
                return 1;
-       s = pkglookup("selectdefault", "runtime");
+       s = pkglookup("selectdefault", runtimepkg);
        if(s == n->sym)
                return 1;
        return 0;
@@ -1959,7 +1957,7 @@ syslook(char *name, int copy)
        Sym *s;
        Node *n;
 
-       s = pkglookup(name, "runtime");
+       s = pkglookup(name, runtimepkg);
        if(s == S || s->def == N)
                fatal("looksys: cant find runtime.%s", name);
 
@@ -2585,7 +2583,7 @@ expand0(Type *t, int followptr)
 
        if(u->etype == TINTER) {
                for(f=u->type; f!=T; f=f->down) {
-                       if(!exportname(f->sym->name) && strcmp(f->sym->package, package) != 0)
+                       if(!exportname(f->sym->name) && f->sym->pkg != localpkg)
                                continue;
                        if(f->sym->flags & SymUniq)
                                continue;
@@ -2602,7 +2600,7 @@ expand0(Type *t, int followptr)
        u = methtype(t);
        if(u != T) {
                for(f=u->method; f!=T; f=f->down) {
-                       if(!exportname(f->sym->name) && strcmp(f->sym->package, package) != 0)
+                       if(!exportname(f->sym->name) && f->sym->pkg != localpkg)
                                continue;
                        if(f->sym->flags & SymUniq)
                                continue;
@@ -3379,15 +3377,74 @@ ngotype(Node *n)
        return S;
 }
 
-char*
-toimportpath(Strlit *s)
+/*
+ * Convert raw string to the prefix that will be used in the symbol table.
+ * Invalid bytes turn into %xx.  Right now the only bytes that need
+ * escaping are %, ., and ", but we escape all control characters too.
+ */
+static char*
+pathtoprefix(char *s)
 {
-       char *p;
+       static char hex[] = "0123456789abcdef";
+       char *p, *r, *w;
+       int n;
 
-//PGNS: Do better once these are import paths
-// rather than package names in disguise.
-       p = mal(s->len+1);
-       memmove(p, s->s, s->len);
-       p[s->len] = '\0';
+       // check for chars that need escaping
+       n = 0;
+       for(r=s; *r; r++)
+               if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"')
+                       n++;
+
+       // quick exit
+       if(n == 0)
+               return s;
+
+       // escape
+       p = mal((r-s)+1+2*n);
+       for(r=s, w=p; *r; r++) {
+               if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"') {
+                       *w++ = '%';
+                       *w++ = hex[(*r>>4)&0xF];
+                       *w++ = hex[*r&0xF];
+               } else
+                       *w++ = *r;
+       }
+       *w = '\0';
        return p;
 }
+
+static Pkg *phash[128];
+
+Pkg*
+mkpkg(Strlit *path)
+{
+       Pkg *p;
+       int h;
+       
+       if(strlen(path->s) != path->len)
+               fatal("import path contains NUL byte");
+       
+       h = stringhash(path->s) & (nelem(phash)-1);
+       for(p=phash[h]; p; p=p->link)
+               if(p->path->len == path->len && memcmp(path->s, p->path->s, path->len) == 0)
+                       return p;
+
+       p = mal(sizeof *p);
+       p->path = path;
+       p->prefix = pathtoprefix(path->s);
+       p->link = phash[h];
+       phash[h] = p;
+       return p;
+}
+
+Strlit*
+strlit(char *s)
+{
+       Strlit *t;
+       
+       t = mal(sizeof *t + strlen(s));
+       strcpy(t->s, s);
+       t->len = strlen(s);
+       return t;
+}
+
index f0866ae3bb05f65deb003ad8b87a008c1c9d6390..abadbfa2193ce12415271daed67324e1b37fd838 100644 (file)
@@ -1567,7 +1567,7 @@ exportassignok(Type *t, char *desc)
                        s = f->sym;
                        // s == nil doesn't happen for embedded fields (they get the type symbol).
                        // it only happens for fields in a ... struct.
-                       if(s != nil && !exportname(s->name) && strcmp(package, s->package) != 0) {
+                       if(s != nil && !exportname(s->name) && s->pkg != localpkg) {
                                char *prefix;
                                
                                prefix = "";
@@ -1800,7 +1800,7 @@ typecheckcomplit(Node **np)
                                        continue;
                                }
                                s = f->sym;
-                               if(s != nil && !exportname(s->name) && strcmp(package, s->package) != 0)
+                               if(s != nil && !exportname(s->name) && s->pkg != localpkg)
                                        yyerror("implicit assignment of %T field '%s' in struct literal", t, s->name);
                                ll->n = typecheckconv(nil, ll->n, f->type, 0, "field value");
                                ll->n = nod(OKEY, newname(f->sym), ll->n);
index f94e1c78c9fdbd0dec83ec0f7fc53efd9420fc2a..5d27dd648d7b550552438eb650a2153baf11be24 100644 (file)
@@ -21,7 +21,7 @@ unsafenmagic(Node *fn, NodeList *args)
 
        if(fn == N || fn->op != ONAME || (s = fn->sym) == S)
                goto no;
-       if(strcmp(s->package, "unsafe") != 0)
+       if(s->pkg != unsafepkg)
                goto no;
 
        if(args == nil) {
index dfe2024922e98aaecbaf5842d6df69b2cad64a70..ff7f298187ae4850ed39020ac9a8317a2ec6a563 100644 (file)
@@ -1500,40 +1500,34 @@ ilookup(char *name)
        return x;
 }
 
-/*
- * a and b don't match.
- * is one a forward declaration and the other a valid completion?
- * if so, return the one to keep.
- */
-char*
-forwardfix(char *a, char *b)
-{
-       char *t;
-
-       if(strlen(a) > strlen(b)) {
-               t = a;
-               a = b;
-               b = t;
-       }
-       if(strcmp(a, "struct") == 0 && strncmp(b, "struct ", 7) == 0)
-               return b;
-       if(strcmp(a, "interface") == 0 && strncmp(b, "interface ", 10) == 0)
-               return b;
-       return nil;
-}
-
 int parsemethod(char**, char*, char**);
 int parsepkgdata(char**, char*, char**, char**, char**);
 
 void
 loadpkgdata(char *data, int len)
 {
-       char *p, *ep, *prefix, *name, *def, *ndef;
+       char *p, *ep, *prefix, *name, *def;
        Import *x;
 
        p = data;
        ep = data + len;
        while(parsepkgdata(&p, ep, &prefix, &name, &def) > 0) {
+               if(strcmp(prefix, "import") == 0) {
+                       // backwards from the rest: def is unique, name is not.
+                       x = ilookup(def);
+                       if(x->prefix == nil) {
+                               x->prefix = prefix;
+                               x->def = name;
+                               x->file = file;
+                       } else if(strcmp(x->def, name) != 0) {
+                               fprint(2, "gopack: conflicting package names for %s\n", def);
+                               fprint(2, "%s:\t%s\n", x->file, x->def);
+                               fprint(2, "%s:\t%s\n", file, name);
+                               errors++;
+                       }
+                       continue;
+               }
+                               
                x = ilookup(name);
                if(x->prefix == nil) {
                        x->prefix = prefix;
@@ -1544,11 +1538,7 @@ loadpkgdata(char *data, int len)
                        fprint(2, "%s:\t%s %s ...\n", x->file, x->prefix, name);
                        fprint(2, "%s:\t%s %s ...\n", file, prefix, name);
                        errors++;
-               } else if(strcmp(x->def, def) == 0) {
-                       // fine
-               } else if((ndef = forwardfix(x->def, def)) != nil) {
-                       x->def = ndef;
-               } else {
+               } else if(strcmp(x->def, def) != 0) {
                        fprint(2, "gopack: conflicting definitions for %s\n", name);
                        fprint(2, "%s:\t%s %s %s\n", x->file, x->prefix, name, x->def);
                        fprint(2, "%s:\t%s %s %s\n", file, prefix, name, def);
@@ -1574,7 +1564,7 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp)
        prefix = p;
 
        prefix = p;
-       if(p + 6 > ep)
+       if(p + 7 > ep)
                return -1;
        if(strncmp(p, "var ", 4) == 0)
                p += 4;
@@ -1584,6 +1574,8 @@ parsepkgdata(char **pp, char *ep, char **prefixp, char **namep, char **defp)
                p += 5;
        else if(strncmp(p, "const ", 6) == 0)
                p += 6;
+       else if(strncmp(p, "import ", 7) == 0)
+               p += 7;
        else {
                fprint(2, "gopack: confused in pkg data near <<%.20s>>\n", p);
                errors++;
@@ -1745,6 +1737,16 @@ getpkgdef(char **datap, int *lenp)
        p = strappend(p, "\n");
        for(i=0; i<nimport; i++) {
                x = all[i];
+               if(strcmp(x->prefix, "import") == 0) {
+                       // prefix def name\n
+                       p = strappend(p, x->prefix);
+                       p = strappend(p, " ");
+                       p = strappend(p, x->def);
+                       p = strappend(p, " ");
+                       p = strappend(p, x->name);
+                       p = strappend(p, "\n");
+                       continue;
+               }
                // prefix name def\n
                p = strappend(p, x->prefix);
                p = strappend(p, " ");
index cb0a2cdd9abdb9c304f48f30838186ba518d7968..b975513095ccd44280341a06850ccd31a433d601 100755 (executable)
@@ -109,20 +109,41 @@ trap "rm -f _testmain.go _testmain.$O" 0 1 2 3 14 15
 MAKEFLAGS=
 MAKELEVEL=
 
+# usage: nmgrep pattern file...
+nmgrep() {
+       pat="$1"
+       shift
+       for i
+       do
+               # Package symbol "".Foo is pkg.Foo when imported in Go.
+               # Figure out pkg.
+               case "$i" in
+               *.a)
+                       pkg=$(gopack p $i __.PKGDEF | sed -n 's/^package //p' | sed 1q)
+                       ;;
+               *)
+                       pkg=$(sed -n 's/^ .* in package "\(.*\)".*/\1/p' $i | sed 1q)
+                       ;;
+               esac
+               "$GOBIN"/6nm -s "$i" | egrep ' T .*\.'"$pat"'$' |
+               sed 's/.* //; /\..*\./d; s/""\./'"$pkg"'./g'
+       done
+}
+
 importpath=$("$GOBIN"/gomake -s importpath)
 {
        # test functions are named TestFoo
        # the grep -v eliminates methods and other special names
        # that have multiple dots.
        pattern='Test([^a-z].*)?'
-       tests=$("$GOBIN"/6nm -s _test/$importpath.a $xofile | egrep ' T .*\.'$pattern'$' | sed 's/.* //; /\..*\./d')
+       tests=$(nmgrep $pattern _test/$importpath.a $xofile)
        if [ "x$tests" = x ]; then
                echo 'gotest: error: no tests matching '$pattern in _test/$importpath.a $xofile 1>&2
                exit 2
        fi
        # benchmarks are named BenchmarkFoo.
        pattern='Benchmark([^a-z].*)?'
-       benchmarks=$("$GOBIN"/6nm -s _test/$importpath.a $xofile | egrep ' T .*\.'$pattern'$' | sed 's/.* //; /\..*\./d')
+       benchmarks=$(nmgrep $pattern _test/$importpath.a $xofile)
 
        # package spec
        echo 'package main'
index 8f9d198bc2adcd7cd9b997c630015c561c13d741..1797f34d3028931ea8b768f4d89f130737ede3c3 100644 (file)
@@ -65,13 +65,13 @@ ilookup(char *name)
        return x;
 }
 
-static void loadpkgdata(char*, char*, int);
+static void loadpkgdata(char*, char*, char*, int);
 static void loaddynld(char*, char*, int);
 static int parsemethod(char**, char*, char**);
-static int parsepkgdata(char*, char**, char*, char**, char**, char**);
+static int parsepkgdata(char*, char*, char**, char*, char**, char**, char**);
 
 void
-ldpkg(Biobuf *f, int64 len, char *filename)
+ldpkg(Biobuf *f, char *pkg, int64 len, char *filename)
 {
        char *data, *p0, *p1;
 
@@ -115,8 +115,7 @@ ldpkg(Biobuf *f, int64 len, char *filename)
                        p0++;
                while(*p0 != ' ' && *p0 != '\t' && *p0 != '\n')
                        p0++;
-
-               loadpkgdata(filename, p0, p1 - p0);
+               loadpkgdata(filename, pkg, p0, p1 - p0);
        }
 
        // local types begin where exports end.
@@ -132,7 +131,8 @@ ldpkg(Biobuf *f, int64 len, char *filename)
                return;
        }
 
-       loadpkgdata(filename, p0, p1 - p0);
+       // PGNS: Should be using import path, not pkg.
+       loadpkgdata(filename, pkg, p0, p1 - p0);
 
        // look for dynld section
        p0 = strstr(p1, "\n$$  // dynld");
@@ -153,38 +153,16 @@ ldpkg(Biobuf *f, int64 len, char *filename)
        }
 }
 
-/*
- * a and b don't match.
- * is one a forward declaration and the other a valid completion?
- * if so, return the one to keep.
- */
-char*
-forwardfix(char *a, char *b)
-{
-       char *t;
-
-       if(strlen(a) > strlen(b)) {
-               t = a;
-               a = b;
-               b = t;
-       }
-       if(strcmp(a, "struct") == 0 && strncmp(b, "struct ", 7) == 0)
-               return b;
-       if(strcmp(a, "interface") == 0 && strncmp(b, "interface ", 10) == 0)
-               return b;
-       return nil;
-}
-
 static void
-loadpkgdata(char *file, char *data, int len)
+loadpkgdata(char *file, char *pkg, char *data, int len)
 {
-       char *p, *ep, *prefix, *name, *def, *ndef;
+       char *p, *ep, *prefix, *name, *def;
        Import *x;
 
        file = strdup(file);
        p = data;
        ep = data + len;
-       while(parsepkgdata(file, &p, ep, &prefix, &name, &def) > 0) {
+       while(parsepkgdata(file, pkg, &p, ep, &prefix, &name, &def) > 0) {
                x = ilookup(name);
                if(x->prefix == nil) {
                        x->prefix = prefix;
@@ -195,11 +173,7 @@ loadpkgdata(char *file, char *data, int len)
                        fprint(2, "%s:\t%s %s ...\n", x->file, x->prefix, name);
                        fprint(2, "%s:\t%s %s ...\n", file, prefix, name);
                        nerrors++;
-               } else if(strcmp(x->def, def) == 0) {
-                       // fine
-               } else if((ndef = forwardfix(x->def, def)) != nil) {
-                       x->def = ndef;
-               } else {
+               } else if(strcmp(x->def, def) != 0) {
                        fprint(2, "%s: conflicting definitions for %s\n", argv0, name);
                        fprint(2, "%s:\t%s %s %s\n", x->file, x->prefix, name, x->def);
                        fprint(2, "%s:\t%s %s %s\n", file, prefix, name, def);
@@ -208,14 +182,44 @@ loadpkgdata(char *file, char *data, int len)
        }
 }
 
+// replace all "". with pkg.
+char*
+expandpkg(char *t0, char *pkg)
+{
+       int n;
+       char *p;
+       char *w, *w0, *t;
+       
+       n = 0;
+       for(p=t0; (p=strstr(p, "\"\".")) != nil; p+=3)
+               n++;
+
+       if(n == 0)
+               return t0;
+
+       // use malloc, not mal, so that caller can free
+       w0 = malloc(strlen(t0) + strlen(pkg)*n);
+       w = w0;
+       for(p=t=t0; (p=strstr(p, "\"\".")) != nil; p=t) {
+               memmove(w, t, p - t);
+               w += p-t;
+               strcpy(w, pkg);
+               w += strlen(pkg);
+               t = p+2;
+       }
+       strcpy(w, t);
+       return w0;
+}
+
 static int
-parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char **defp)
+parsepkgdata(char *file, char *pkg, char **pp, char *ep, char **prefixp, char **namep, char **defp)
 {
        char *p, *prefix, *name, *def, *edef, *meth;
        int n;
 
        // skip white space
        p = *pp;
+loop:
        while(p < ep && (*p == ' ' || *p == '\t' || *p == '\n'))
                p++;
        if(p == ep || strncmp(p, "$$\n", 3) == 0)
@@ -223,7 +227,7 @@ parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char
 
        // prefix: (var|type|func|const)
        prefix = p;
-       if(p + 6 > ep)
+       if(p + 7 > ep)
                return -1;
        if(strncmp(p, "var ", 4) == 0)
                p += 4;
@@ -233,6 +237,12 @@ parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char
                p += 5;
        else if(strncmp(p, "const ", 6) == 0)
                p += 6;
+       else if(strncmp(p, "import ", 7) == 0) {
+               p += 7;
+               while(p < ep && *p != '\n')
+                       p++;
+               goto loop;
+       }
        else {
                fprint(2, "%s: confused in pkg data near <<%.40s>>\n", argv0, prefix);
                nerrors++;
@@ -277,6 +287,9 @@ parsepkgdata(char *file, char **pp, char *ep, char **prefixp, char **namep, char
                memmove(edef, meth, n);
                edef += n;
        }
+       
+       name = expandpkg(name, pkg);
+       def = expandpkg(def, pkg);
 
        // done
        *pp = p;
index 8039bf8ee0e70a1cbd92095ddb25e9053cc5bf6c..7ede8c89e187c4d50555d4886b20df5773e356d4 100644 (file)
@@ -32,6 +32,8 @@
 #include       "lib.h"
 #include       <ar.h>
 
+int iconv(Fmt*);
+
 char   symname[]       = SYMDEF;
 char*  libdir[16] = { "." };
 int    nlibdir = 1;
@@ -54,6 +56,7 @@ Lflag(char *arg)
 void
 libinit(void)
 {
+       fmtinstall('i', iconv);
        mywhatsys();    // get goroot, goarch, goos
        if(strcmp(goarch, thestring) != 0)
                print("goarch is not known: %s\n", goarch);
@@ -91,6 +94,7 @@ addlib(char *src, char *obj)
 {
        char name[1024], pname[1024], comp[256], *p;
        int i, search;
+       Library *l;
 
        if(histfrogp <= 0)
                return;
@@ -133,9 +137,11 @@ addlib(char *src, char *obj)
                        diag("library component too long");
                        return;
                }
-               strcat(name, "/");
+               if(i > 0 || !search)
+                       strcat(name, "/");
                strcat(name, comp);
        }
+       cleanname(name);
 
        if(search) {
                // try dot, -L "libdir", and then goroot.
@@ -144,28 +150,42 @@ addlib(char *src, char *obj)
                        if(access(pname, AEXIST) >= 0)
                                break;
                }
-               strcpy(name, pname);
-       }
-       cleanname(name);
+       }else
+               strcpy(pname, name);
+       cleanname(pname);
+       
+       /* runtime.a -> runtime */
+       if(strlen(name) > 2 && name[strlen(name)-2] == '.')
+               name[strlen(name)-2] = '\0';
+
        if(debug['v'])
-               Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, name);
+               Bprint(&bso, "%5.2f addlib: %s %s pulls in %s\n", cputime(), obj, src, pname);
 
        for(i=0; i<libraryp; i++)
-               if(strcmp(name, library[i]) == 0)
+               if(strcmp(pname, library[i].file) == 0)
                        return;
        if(libraryp == nlibrary){
                nlibrary = 50 + 2*libraryp;
                library = realloc(library, sizeof library[0] * nlibrary);
-               libraryobj = realloc(libraryobj, sizeof libraryobj[0] * nlibrary);
        }
 
-       p = mal(strlen(name) + 1);
-       strcpy(p, name);
-       library[libraryp] = p;
+       l = &library[libraryp++];
+
        p = mal(strlen(obj) + 1);
        strcpy(p, obj);
-       libraryobj[libraryp] = p;
-       libraryp++;
+       l->objref = p;
+
+       p = mal(strlen(src) + 1);
+       strcpy(p, src);
+       l->srcref = p;
+
+       p = mal(strlen(pname) + 1);
+       strcpy(p, pname);
+       l->file = p;
+
+       p = mal(strlen(name) + 1);
+       strcpy(p, name);
+       l->pkg = p;
 }
 
 void
@@ -180,8 +200,8 @@ loop:
        xrefresolv = 0;
        for(i=0; i<libraryp; i++) {
                if(debug['v'])
-                       Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i], libraryobj[i]);
-               objfile(library[i]);
+                       Bprint(&bso, "%5.2f autolib: %s (from %s)\n", cputime(), library[i].file, library[i].objref);
+               objfile(library[i].file, library[i].pkg);
        }
        if(xrefresolv)
        for(h=0; h<nelem(hash); h++)
@@ -192,11 +212,11 @@ loop:
        i = strlen(goroot)+strlen(goarch)+strlen(goos)+20;
        a = mal(i);
        snprint(a, i, "%s/pkg/%s_%s/runtime.a", goroot, goos, goarch);
-       objfile(a);
+       objfile(a, "runtime");
 }
 
 void
-objfile(char *file)
+objfile(char *file, char *pkg)
 {
        int32 off, esym, cnt, l;
        int work;
@@ -205,7 +225,9 @@ objfile(char *file)
        char magbuf[SARMAG];
        char name[100], pname[150];
        struct ar_hdr arhdr;
-       char *e, *start, *stop;
+       char *e, *start, *stop, *x;
+       
+       pkg = smprint("%i", pkg);
 
        if(file[0] == '-' && file[1] == 'l') {  // TODO: fix this
                if(debug['9'])
@@ -217,7 +239,7 @@ objfile(char *file)
                file = name;
        }
        if(debug['v'])
-               Bprint(&bso, "%5.2f ldobj: %s\n", cputime(), file);
+               Bprint(&bso, "%5.2f ldobj: %s (%s)\n", cputime(), file, pkg);
        Bflush(&bso);
        f = Bopen(file, 0);
        if(f == nil) {
@@ -229,7 +251,7 @@ objfile(char *file)
                /* load it as a regular file */
                l = Bseek(f, 0L, 2);
                Bseek(f, 0L, 0);
-               ldobj(f, l, file);
+               ldobj(f, pkg, l, file);
                Bterm(f);
                return;
        }
@@ -268,7 +290,10 @@ objfile(char *file)
                Bflush(&bso);
                work = 0;
                for(e = start; e < stop; e = strchr(e+5, 0) + 1) {
-                       s = lookup(e+5, 0);
+                       x = expandpkg(e+5, pkg);
+                       s = lookup(x, 0);
+                       if(x != e+5)
+                               free(x);
                        if(s->type != SXREF)
                                continue;
                        sprint(pname, "%s(%s)", file, s->name);
@@ -290,7 +315,7 @@ objfile(char *file)
                                l--;
                        sprint(pname, "%s(%.*s)", file, l, arhdr.name);
                        l = atolwhex(arhdr.size);
-                       ldobj(f, l, pname);
+                       ldobj(f, pkg, l, pname);
                        if(s->type == SXREF) {
                                diag("%s: failed to load: %s", file, s->name);
                                errorexit();
@@ -308,7 +333,7 @@ out:
 }
 
 void
-ldobj(Biobuf *f, int64 len, char *pn)
+ldobj(Biobuf *f, char *pkg, int64 len, char *pn)
 {
        static int files;
        static char **filen;
@@ -362,10 +387,11 @@ ldobj(Biobuf *f, int64 len, char *pn)
        import1 = Boffset(f);
 
        Bseek(f, import0, 0);
-       ldpkg(f, import1 - import0 - 2, pn);    // -2 for !\n
+       ldpkg(f, pkg, import1 - import0 - 2, pn);       // -2 for !\n
        Bseek(f, import1, 0);
 
-       ldobj1(f, eof - Boffset(f), pn);
+       // PGNS: Should be using import path, not pkg.
+       ldobj1(f, pkg, eof - Boffset(f), pn);
        return;
 
 eof:
@@ -757,3 +783,56 @@ mal(uint32 n)
        memset(v, 0, n);
        return v;
 }
+
+// Copied from ../gc/subr.c:/^pathtoprefix; must stay in sync.
+/*
+ * Convert raw string to the prefix that will be used in the symbol table.
+ * Invalid bytes turn into %xx.  Right now the only bytes that need
+ * escaping are %, ., and ", but we escape all control characters too.
+ */
+static char*
+pathtoprefix(char *s)
+{
+       static char hex[] = "0123456789abcdef";
+       char *p, *r, *w;
+       int n;
+
+       // check for chars that need escaping
+       n = 0;
+       for(r=s; *r; r++)
+               if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"')
+                       n++;
+
+       // quick exit
+       if(n == 0)
+               return s;
+
+       // escape
+       p = mal((r-s)+1+2*n);
+       for(r=s, w=p; *r; r++) {
+               if(*r <= ' ' || *r == '.' || *r == '%' || *r == '"') {
+                       *w++ = '%';
+                       *w++ = hex[(*r>>4)&0xF];
+                       *w++ = hex[*r&0xF];
+               } else
+                       *w++ = *r;
+       }
+       *w = '\0';
+       return p;
+}
+
+int
+iconv(Fmt *fp)
+{
+       char *p;
+
+       p = va_arg(fp->args, char*);
+       if(p == nil) {
+               fmtstrcpy(fp, "<nil>");
+               return 0;
+       }
+       p = pathtoprefix(p);
+       fmtstrcpy(fp, p);
+       return 0;
+}
+
index bf26ae87d80d4847e8c682783702237cb52f3f62..8943b05aa69fbfcb3757e72e4b4259a98c0a7d47 100644 (file)
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 
+typedef struct Library Library;
+struct Library
+{
+       char *objref;   // object where we found the reference
+       char *srcref;   // src file where we found the reference
+       char *file;             // object file
+       char *pkg;      // import path
+};
+
 extern char    symname[];
 extern char    *libdir[];
 extern int     nlibdir;
@@ -36,8 +45,7 @@ extern        int     cout;
 EXTERN char*   INITENTRY;
 EXTERN char    thechar;
 EXTERN char*   thestring;
-EXTERN char**  library;
-EXTERN char**  libraryobj;
+EXTERN Library*        library;
 EXTERN int     libraryp;
 EXTERN int     nlibrary;
 EXTERN Sym*    hash[NHASH];
@@ -71,15 +79,16 @@ void        readundefs(char *f, int t);
 int32  Bget4(Biobuf *f);
 void   loadlib(void);
 void   errorexit(void);
-void   objfile(char *file);
+void   objfile(char *file, char *pkg);
 void   libinit(void);
 void   Lflag(char *arg);
 void   usage(void);
-void   ldobj1(Biobuf *f, int64 len, char *pn);
-void   ldobj(Biobuf*, int64, char*);
-void   ldpkg(Biobuf*, int64, char*);
+void   ldobj1(Biobuf *f, char*, int64 len, char *pn);
+void   ldobj(Biobuf*, char*, int64, char*);
+void   ldpkg(Biobuf*, char*, int64, char*);
 void   mark(Sym *s);
-
+char*  expandpkg(char*, char*);
+void   deadcode(void);
 
 int    pathchar(void);
 void*  mal(uint32);
index 9ab493d5967e32c5b959a19c9f08510cf1a3cd60..84e952f8a89ef078ef2e59522c6915303236a60a 100644 (file)
@@ -63,7 +63,7 @@ func TestLineFromAline(t *testing.T) {
        tab := getTable(t)
 
        // Find the sym package
-       pkg := tab.LookupFunc("gosym.TestLineFromAline").Obj
+       pkg := tab.LookupFunc("debug/gosym.TestLineFromAline").Obj
        if pkg == nil {
                t.Fatalf("nil pkg")
        }