mirror of
https://github.com/golang/go
synced 2024-11-22 00:14:42 -07:00
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:
parent
d1b14a6fb0
commit
1cecac8134
@ -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
|
||||
*/
|
||||
|
@ -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");
|
||||
}
|
||||
|
||||
|
@ -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, "/???");
|
||||
|
@ -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")));
|
||||
}
|
||||
}
|
||||
|
@ -3413,8 +3413,6 @@ pathtoprefix(char *s)
|
||||
return p;
|
||||
}
|
||||
|
||||
static Pkg *phash[128];
|
||||
|
||||
Pkg*
|
||||
mkpkg(Strlit *path)
|
||||
{
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user