gc: record full package paths in runtime type data

detect compilation of special package runtime with
compiler flag instead of package name.

R=ken2
CC=golang-dev
https://golang.org/cl/193080
This commit is contained in:
Russ Cox 2010-01-24 23:33:59 -08:00
parent d1b14a6fb0
commit 1cecac8134
7 changed files with 67 additions and 11 deletions

View File

@ -308,7 +308,8 @@ struct Pkg
Strlit* path;
char* prefix;
Pkg* link;
int exported;
char exported; // import line written in export data
char direct; // imported directly
};
typedef struct Iter Iter;
@ -659,6 +660,7 @@ 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 Pkg* phash[128];
EXTERN int tptr; // either TPTR32 or TPTR64
extern char* runtimeimport;
extern char* unsafeimport;
@ -732,6 +734,8 @@ EXTERN int funcdepth;
EXTERN int typecheckok;
EXTERN int packagequotes;
EXTERN int compiling_runtime;
/*
* y.tab.c
*/

View File

@ -235,6 +235,7 @@ import_package:
LPACKAGE sym ';'
{
importpkg->name = $2->name;
importpkg->direct = 1;
// PGNS: fixme
if(strcmp($2->name, "main") == 0)
@ -242,7 +243,7 @@ import_package:
// PGNS: This should go away once we get
// rid of the global package name space.
if(localpkg->name && strcmp($2->name, localpkg->name) == 0 && strcmp($2->name, "runtime") != 0)
if(localpkg->name && strcmp($2->name, localpkg->name) == 0 && !compiling_runtime)
yyerror("package cannot import itself");
}

View File

@ -68,6 +68,9 @@ main(int argc, char *argv[])
if(argc < 1)
goto usage;
// special flag to detect compilation of package runtime
compiling_runtime = debug['+'];
pathname = mal(1000);
if(getwd(pathname, 999) == 0)
strcpy(pathname, "/???");

View File

@ -267,12 +267,42 @@ 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.
// 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);
}
return dgostringptr(s, ot, pkg->name);
}
static void
dimportpath(Pkg *p)
{
static Pkg *gopkg;
char *nam;
Node *n;
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;
gdatastring(n, p->path);
ggloblsym(n->sym, types[TSTRING]->width, 1);
}
/*
* uncommonType
@ -626,8 +656,7 @@ dtypesym(Type *t)
else
tsym = t->sym;
// PGNS: Fixme
if(strcmp(localpkg->name, "runtime") == 0) {
if(compiling_runtime) {
if(t == types[t->etype])
goto ok;
if(t1 && t1 == types[t1->etype])
@ -784,6 +813,7 @@ dumptypestructs(void)
NodeList *l;
Node *n;
Type *t;
Pkg *p;
// copy types from externdcl list to signatlist
for(l=externdcl; l; l=l->next) {
@ -804,17 +834,27 @@ dumptypestructs(void)
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 reflect is always loaded implicitly,
// 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(strcmp(localpkg->name, "runtime") == 0) { // PGNS: fixme
if(compiling_runtime) {
for(i=1; i<=TBOOL; i++)
dtypesym(ptrto(types[i]));
dtypesym(ptrto(types[TSTRING]));
dtypesym(typ(TDDD));
dtypesym(ptrto(pkglookup("Pointer", unsafepkg)->def->type));
// add paths for runtime and main, which 6l imports implicitly.
dimportpath(runtimepkg);
dimportpath(mkpkg(strlit("main")));
}
}

View File

@ -3413,8 +3413,6 @@ pathtoprefix(char *s)
return p;
}
static Pkg *phash[128];
Pkg*
mkpkg(Strlit *path)
{

View File

@ -5,6 +5,7 @@
package reflect_test
import (
"container/vector"
"io"
"os"
. "reflect"
@ -1188,3 +1189,9 @@ func TestFieldByName(t *testing.T) {
}
}
}
func TestImportPath(t *testing.T) {
if path := Typeof(vector.Vector{}).PkgPath(); path != "container/vector" {
t.Errorf("Typeof(vector.Vector{}).PkgPath() = %q, want \"container/vector\"", path)
}
}

View File

@ -91,6 +91,9 @@ HFILES=\
GOFILES+=$(GOFILES_$(GOOS))
# special, out of the way compiler flag that means "add runtime metadata to output"
GC+= -+
include ../../Make.pkg
clean: clean-local