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