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:
parent
d169dcee3b
commit
aa347c4a0d
@ -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)
|
||||
|
2028
src/cmd/gc/dcl.c
2028
src/cmd/gc/dcl.c
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||
|
@ -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
193
src/cmd/gc/init.c
Normal 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;
|
||||
}
|
||||
|
||||
|
@ -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
87
src/cmd/gc/unsafe.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user