1
0
mirror of https://github.com/golang/go synced 2024-11-12 03:40:21 -07:00

move various bits of code around

and delete some dead code.
no actual changes here.

R=ken
OCL=32764
CL=32764
This commit is contained in:
Russ Cox 2009-08-04 18:43:32 -07:00
parent d169dcee3b
commit aa347c4a0d
7 changed files with 1233 additions and 1239 deletions

View File

@ -15,28 +15,30 @@ YFILES=\
go.y\
OFILES=\
reflect.$O\
y.tab.$O\
lex.$O\
subr.$O\
dcl.$O\
sinit.$O\
export.$O\
walk.$O\
swt.$O\
align.$O\
bits.$O\
builtin.$O\
compat.$O\
const.$O\
dcl.$O\
export.$O\
gen.$O\
init.$O\
lex.$O\
mparith1.$O\
mparith2.$O\
mparith3.$O\
builtin.$O\
compat.$O\
bits.$O\
align.$O\
gen.$O\
obj.$O\
print.$O\
typecheck.$O\
reflect.$O\
select.$O\
sinit.$O\
subr.$O\
swt.$O\
typecheck.$O\
unsafe.$O\
walk.$O\
y.tab.$O\
$(LIB): $(OFILES)
ar rsc $(LIB) $(OFILES)

File diff suppressed because it is too large Load Diff

View File

@ -601,8 +601,6 @@ EXTERN char namebuf[NSYMB];
EXTERN char lexbuf[NSYMB];
EXTERN char debug[256];
EXTERN Sym* hash[NHASH];
EXTERN Sym* dclstack;
EXTERN Sym* b0stack;
EXTERN Sym* pkgmyname; // my name for package
EXTERN Sym* pkgimportname; // package name from imported package
EXTERN int tptr; // either TPTR32 or TPTR64
@ -814,7 +812,6 @@ void argtype(Node*, Type*);
int eqargs(Type*, Type*);
uint32 typehash(Type*, int, int);
void frame(int);
Node* dobad(void);
Node* nodintconst(int64);
void nodconst(Node*, Type*, int64);
Node* nodnil(void);
@ -921,7 +918,6 @@ Type* newtype(Sym*);
Type* oldtype(Sym*);
void fninit(NodeList*);
Node* nametodcl(Node*, Type*);
Node* anondcl(Type*);
NodeList* checkarglist(NodeList*);
void checkwidth(Type*);
void defercheckwidth(void);

View File

@ -1137,7 +1137,6 @@ fndcl:
{
Node *n;
b0stack = dclstack; // mark base for fn literals
$$ = nod(ODCLFUNC, N, N);
$$->nname = $1;
if($3 == nil && $5 == nil)
@ -1159,7 +1158,6 @@ fndcl:
rcvr = N;
}
b0stack = dclstack; // mark base for fn literals
$$ = nod(ODCLFUNC, N, N);
$$->nname = $4;
$$->nname = methodname($4, rcvr->type);

193
src/cmd/gc/init.c Normal file
View File

@ -0,0 +1,193 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go.h"
/*
* a function named init is a special case.
* it is called by the initialization before
* main is run. to make it unique within a
* package and also uncallable, the name,
* normally "pkg.init", is altered to "pkg.init·filename".
*/
Node*
renameinit(Node *n)
{
Sym *s;
s = n->sym;
if(s == S)
return n;
if(strcmp(s->name, "init") != 0)
return n;
snprint(namebuf, sizeof(namebuf), "init·%s", filename);
s = lookup(namebuf);
return newname(s);
}
/*
* hand-craft the following initialization code
* var initdone·<file> uint8 (1)
* func Init·<file>() (2)
* if initdone·<file> { (3)
* if initdone·<file> == 2 (4)
* return
* throw(); (5)
* }
* initdone.<file>++; (6)
* // over all matching imported symbols
* <pkg>.init·<file>() (7)
* { <init stmts> } (8)
* init·<file>() // if any (9)
* initdone.<file>++; (10)
* return (11)
* }
*/
int
anyinit(NodeList *n)
{
uint32 h;
Sym *s;
// are there any init statements
if(n != nil)
return 1;
// is this main
if(strcmp(package, "main") == 0)
return 1;
// is there an explicit init function
snprint(namebuf, sizeof(namebuf), "init·%s", filename);
s = lookup(namebuf);
if(s->def != N)
return 1;
// are there any imported init functions
for(h=0; h<NHASH; h++)
for(s = hash[h]; s != S; s = s->link) {
if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0)
continue;
if(s->def == N)
continue;
return 1;
}
// then none
return 0;
}
void
fninit(NodeList *n)
{
Node *gatevar;
Node *a, *b, *fn;
NodeList *r;
uint32 h;
Sym *s, *initsym;
if(strcmp(package, "PACKAGE") == 0) {
// sys.go or unsafe.go during compiler build
return;
}
if(!anyinit(n))
return;
r = nil;
// (1)
snprint(namebuf, sizeof(namebuf), "initdone·%s", filename);
gatevar = newname(lookup(namebuf));
addvar(gatevar, types[TUINT8], PEXTERN);
// (2)
maxarg = 0;
stksize = initstksize;
snprint(namebuf, sizeof(namebuf), "Init·%s", filename);
// this is a botch since we need a known name to
// call the top level init function out of rt0
if(strcmp(package, "main") == 0)
snprint(namebuf, sizeof(namebuf), "init");
fn = nod(ODCLFUNC, N, N);
initsym = lookup(namebuf);
fn->nname = newname(initsym);
fn->type = functype(N, nil, nil);
funchdr(fn);
// (3)
a = nod(OIF, N, N);
a->ntest = nod(ONE, gatevar, nodintconst(0));
r = list(r, a);
// (4)
b = nod(OIF, N, N);
b->ntest = nod(OEQ, gatevar, nodintconst(2));
b->nbody = list1(nod(ORETURN, N, N));
a->nbody = list1(b);
// (5)
b = syslook("throwinit", 0);
b = nod(OCALL, b, N);
a->nbody = list(a->nbody, b);
// (6)
a = nod(OASOP, gatevar, nodintconst(1));
a->etype = OADD;
r = list(r, a);
// (7)
for(h=0; h<NHASH; h++)
for(s = hash[h]; s != S; s = s->link) {
if(s->name[0] != 'I' || strncmp(s->name, "Init·", 6) != 0)
continue;
if(s->def == N)
continue;
if(s == initsym)
continue;
// could check that it is fn of no args/returns
a = nod(OCALL, s->def, N);
r = list(r, a);
}
// (8)
r = concat(r, initfix(n));
// (9)
// could check that it is fn of no args/returns
snprint(namebuf, sizeof(namebuf), "init·%s", filename);
s = lookup(namebuf);
if(s->def != N) {
a = nod(OCALL, s->def, N);
r = list(r, a);
}
// (10)
a = nod(OASOP, gatevar, nodintconst(1));
a->etype = OADD;
r = list(r, a);
// (11)
a = nod(ORETURN, N, N);
r = list(r, a);
exportsym(fn->nname->sym);
fn->nbody = r;
//dump("b", fn);
//dump("r", fn->nbody);
popdcl();
initflag = 1; // flag for loader static initialization
compile(fn);
initflag = 0;
}

View File

@ -393,10 +393,11 @@ typ(int et)
return t;
}
Node*
dobad(void)
Type*
sortinter(Type *t)
{
return nod(OBAD, N, N);
return t;
}
Node*
@ -2636,23 +2637,25 @@ NodeList*
structargs(Type **tl, int mustname)
{
Iter savet;
Node *a;
Node *a, *n;
NodeList *args;
Type *t;
char nam[100];
int n;
char buf[100];
int gen;
args = nil;
n = 0;
gen = 0;
for(t = structfirst(&savet, tl); t != T; t = structnext(&savet)) {
n = N;
if(t->sym)
a = nametodcl(newname(t->sym), t->type);
n = newname(t->sym);
else if(mustname) {
// have to give it a name so we can refer to it in trampoline
snprint(nam, sizeof nam, ".anon%d", n++);
a = nametodcl(newname(lookup(nam)), t->type);
} else
a = anondcl(t->type);
snprint(buf, sizeof buf, ".anon%d", gen++);
n = newname(lookup(buf));
}
a = nod(ODCLFIELD, n, N);
a->type = t->type;
args = list(args, a);
}
return args;
@ -2694,7 +2697,8 @@ genwrapper(Type *rcvr, Type *method, Sym *newnam)
dclcontext = PEXTERN;
markdcl();
this = nametodcl(newname(lookup(".this")), rcvr);
this = nod(ODCLFIELD, newname(lookup(".this")), N);
this->type = rcvr;
in = structargs(getinarg(method->type), 1);
out = structargs(getoutarg(method->type), 0);
@ -2982,6 +2986,9 @@ liststmt(NodeList *l)
return n;
}
/*
* return nelem of list
*/
int
count(NodeList *l)
{
@ -2992,3 +2999,96 @@ count(NodeList *l)
n++;
return n;
}
/*
* return nelem of list
*/
int
structcount(Type *t)
{
int v;
Iter s;
v = 0;
for(t = structfirst(&s, &t); t != T; t = structnext(&s))
v++;
return v;
}
/*
* when a type's width should be known, we call checkwidth
* to compute it. during a declaration like
*
* type T *struct { next T }
*
* it is necessary to defer the calculation of the struct width
* until after T has been initialized to be a pointer to that struct.
* similarly, during import processing structs may be used
* before their definition. in those situations, calling
* defercheckwidth() stops width calculations until
* resumecheckwidth() is called, at which point all the
* checkwidths that were deferred are executed.
* sometimes it is okay to
*/
typedef struct TypeList TypeList;
struct TypeList {
Type *t;
TypeList *next;
};
static TypeList *tlfree;
static TypeList *tlq;
static int defercalc;
void
checkwidth(Type *t)
{
TypeList *l;
// function arg structs should not be checked
// outside of the enclosing function.
if(t->funarg)
fatal("checkwidth %T", t);
if(!defercalc) {
dowidth(t);
return;
}
l = tlfree;
if(l != nil)
tlfree = l->next;
else
l = mal(sizeof *l);
l->t = t;
l->next = tlq;
tlq = l;
}
void
defercheckwidth(void)
{
// we get out of sync on syntax errors, so don't be pedantic.
// if(defercalc)
// fatal("defercheckwidth");
defercalc = 1;
}
void
resumecheckwidth(void)
{
TypeList *l;
if(!defercalc)
fatal("restartcheckwidth");
defercalc = 0;
for(l = tlq; l != nil; l = tlq) {
dowidth(l->t);
tlq = l->next;
l->next = tlfree;
tlfree = l;
}
}

87
src/cmd/gc/unsafe.c Normal file
View File

@ -0,0 +1,87 @@
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include "go.h"
/*
* look for
* unsafe.Sizeof
* unsafe.Offsetof
* rewrite with a constant
*/
Node*
unsafenmagic(Node *fn, NodeList *args)
{
Node *r, *n;
Sym *s;
Type *t, *tr;
long v;
Val val;
if(fn == N || fn->op != ONAME || (s = fn->sym) == S)
goto no;
if(strcmp(s->package, "unsafe") != 0)
goto no;
if(args == nil) {
yyerror("missing argument for %S", s);
goto no;
}
r = args->n;
n = nod(OLITERAL, N, N);
if(strcmp(s->name, "Sizeof") == 0) {
typecheck(&r, Erv);
tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING];
if(tr == T)
goto no;
v = tr->width;
goto yes;
}
if(strcmp(s->name, "Offsetof") == 0) {
if(r->op != ODOT && r->op != ODOTPTR)
goto no;
typecheck(&r, Erv);
v = r->xoffset;
goto yes;
}
if(strcmp(s->name, "Alignof") == 0) {
typecheck(&r, Erv);
tr = r->type;
if(r->op == OLITERAL && r->val.ctype == CTSTR)
tr = types[TSTRING];
if(tr == T)
goto no;
// make struct { byte; T; }
t = typ(TSTRUCT);
t->type = typ(TFIELD);
t->type->type = types[TUINT8];
t->type->down = typ(TFIELD);
t->type->down->type = tr;
// compute struct widths
dowidth(t);
// the offset of T is its required alignment
v = t->type->down->width;
goto yes;
}
no:
return N;
yes:
if(args->next != nil)
yyerror("extra arguments for %S", s);
// any side effects disappear; ignore init
val.ctype = CTINT;
val.u.xval = mal(sizeof(*n->val.u.xval));
mpmovecfix(val.u.xval, v);
n = nod(OLITERAL, N, N);
n->val = val;
n->type = types[TINT];
return n;
}