Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
6fceadbb
Commit
6fceadbb
authored
Aug 30, 2009
by
Ken Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cleanup getting ready for static init
R=rsc OCL=34090 CL=34090
parent
3c098e27
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
21 additions
and
482 deletions
+21
-482
init.c
src/cmd/gc/init.c
+6
-9
sinit.c
src/cmd/gc/sinit.c
+14
-472
subr.c
src/cmd/gc/subr.c
+1
-1
No files found.
src/cmd/gc/init.c
View file @
6fceadbb
...
...
@@ -32,19 +32,22 @@ renameinit(Node *n)
* hand-craft the following initialization code
* var initdone·<file> uint8 (1)
* func Init·<file>() (2)
* if initdone·<file>
{
(3)
* if initdone·<file>
!= 0 {
(3)
* if initdone·<file> == 2 (4)
* return
* throw(); (5)
* }
* initdone.<file>
++
; (6)
* initdone.<file>
+= 1
; (6)
* // over all matching imported symbols
* <pkg>.init·<file>() (7)
* { <init stmts> } (8)
* init·<file>() // if any (9)
* initdone.<file>
++
; (10)
* initdone.<file>
+= 1
; (10)
* return (11)
* }
* note that this code cannot have an assignment
* statement or, because of the initflag, it will
* be converted into a data statement.
*/
int
anyinit
(
NodeList
*
n
)
...
...
@@ -119,7 +122,6 @@ fninit(NodeList *n)
// (2)
maxarg
=
0
;
snprint
(
namebuf
,
sizeof
(
namebuf
),
"Init·"
);
// this is a botch since we need a known name to
...
...
@@ -196,14 +198,9 @@ fninit(NodeList *n)
fn
->
nbody
=
r
;
//dump("b", fn);
//dump("r", fn->nbody);
initflag
=
1
;
// flag for loader static initialization
funcbody
(
fn
);
typecheck
(
&
fn
,
Etop
);
funccompile
(
fn
);
initflag
=
0
;
}
src/cmd/gc/sinit.c
View file @
6fceadbb
...
...
@@ -8,455 +8,6 @@
#include "go.h"
static
struct
{
NodeList
*
list
;
Node
*
mapname
;
Type
*
type
;
}
xxx
;
enum
{
TC_xxx
,
TC_unknown
,
// class
TC_struct
,
TC_array
,
TC_slice
,
TC_map
,
TS_start
,
// state
TS_middle
,
TS_end
,
};
/*
* the init code (thru initfix) reformats the
* var = ...
* statements, rewriting the automatic
* variables with the static variables.
* this allows the code generator to
* generate DATA statements instead
* of assignment statements.
* it is quadradic, may need to change.
* it is extremely fragile knowing exactly
* how the code from (struct|array|map)lit
* will look. ideally the lit routines could
* write the code in this form, but ...
*/
static
int
typeclass
(
Type
*
t
)
{
if
(
t
!=
T
)
switch
(
t
->
etype
)
{
case
TSTRUCT
:
return
TC_struct
;
case
TARRAY
:
if
(
t
->
bound
>=
0
)
return
TC_array
;
return
TC_slice
;
case
TMAP
:
return
TC_map
;
}
return
TC_unknown
;
}
void
initlin
(
NodeList
*
l
)
{
Node
*
n
;
for
(;
l
;
l
=
l
->
next
)
{
n
=
l
->
n
;
switch
(
n
->
op
)
{
case
ODCLFUNC
:
case
ODCLCONST
:
case
ODCLTYPE
:
continue
;
}
initlin
(
n
->
ninit
);
n
->
ninit
=
nil
;
xxx
.
list
=
list
(
xxx
.
list
,
n
);
switch
(
n
->
op
)
{
default:
print
(
"o = %O
\n
"
,
n
->
op
);
break
;
case
OCALL
:
// call to mapassign1
case
OAS
:
break
;
}
}
}
int
inittmp
(
Node
*
n
)
{
if
(
n
!=
N
)
if
(
n
->
op
==
ONAME
)
if
(
n
->
sym
!=
S
)
if
(
n
->
class
==
PAUTO
)
if
(
memcmp
(
n
->
sym
->
name
,
"autotmp_"
,
8
)
==
0
)
return
1
;
return
0
;
}
int
sametmp
(
Node
*
n1
,
Node
*
n2
)
{
if
(
inittmp
(
n1
))
if
(
n1
->
xoffset
==
n2
->
xoffset
)
return
1
;
return
0
;
}
Node
*
findarg
(
Node
*
n
,
char
*
arg
,
char
*
fn
)
{
Node
*
a
;
NodeList
*
l
;
if
(
n
==
N
||
n
->
op
!=
OCALL
||
n
->
left
==
N
||
n
->
left
->
sym
==
S
||
strcmp
(
n
->
left
->
sym
->
name
,
fn
)
!=
0
)
return
N
;
for
(
l
=
n
->
list
;
l
;
l
=
l
->
next
)
{
a
=
l
->
n
;
if
(
a
->
op
==
OAS
&&
a
->
left
!=
N
&&
a
->
right
!=
N
&&
a
->
left
->
op
==
OINDREG
&&
a
->
left
->
sym
!=
S
)
if
(
strcmp
(
a
->
left
->
sym
->
name
,
arg
)
==
0
)
return
a
->
right
;
}
return
N
;
}
Node
*
slicerewrite
(
Node
*
n
)
{
Node
*
nel
;
Type
*
t
;
int
b
;
Node
*
a
;
while
(
n
->
op
==
OCONVNOP
)
n
=
n
->
left
;
// call to makeslice - find nel argument
nel
=
findarg
(
n
,
"nel"
,
"makeslice"
);
if
(
nel
==
N
||
!
isslice
(
n
->
type
))
goto
no
;
b
=
mpgetfix
(
nel
->
val
.
u
.
xval
);
t
=
shallow
(
n
->
type
);
t
->
bound
=
b
;
// special hack for zero-size array
// invent an l-value to point at
if
(
b
==
0
)
a
=
staticname
(
types
[
TBOOL
]);
else
a
=
staticname
(
t
);
a
=
nod
(
OCOMPSLICE
,
a
,
N
);
a
->
type
=
n
->
type
;
return
a
;
no:
return
N
;
}
Node
*
maprewrite
(
Node
*
n
)
{
Node
*
nel
;
Type
*
ta
,
*
tb
;
Node
*
a
;
// call to makemap - find len argument
nel
=
findarg
(
n
,
"hint"
,
"makemap"
);
if
(
nel
==
N
)
goto
no
;
ta
=
n
->
type
;
if
(
ta
->
etype
!=
TMAP
)
goto
no
;
// create a new type from map[index]value
// [0]struct { a index; b value) }
tb
=
typ
(
TFIELD
);
tb
->
type
=
ta
->
down
;
tb
->
sym
=
lookup
(
"key"
);
tb
->
nname
=
newname
(
tb
->
sym
);
tb
->
down
=
typ
(
TFIELD
);
tb
->
down
->
type
=
ta
->
type
;
tb
->
down
->
sym
=
lookup
(
"val"
);
tb
->
down
->
nname
=
newname
(
tb
->
down
->
sym
);
ta
=
typ
(
TSTRUCT
);
ta
->
type
=
tb
;
tb
=
typ
(
TARRAY
);
tb
->
type
=
ta
;
tb
->
bound
=
0
;
dowidth
(
tb
);
a
=
staticname
(
tb
);
a
=
nod
(
OCOMPMAP
,
a
,
N
);
a
->
type
=
n
->
type
;
// save stuff for this iteration
xxx
.
mapname
=
a
->
left
;
xxx
.
type
=
tb
;
return
a
;
no:
return
N
;
}
// convert the call to mapassign1
// into static[i].key = k, static[i].val = v
Node
*
mapindex
(
Node
*
n
)
{
Node
*
index
,
*
val
,
*
key
,
*
a
,
*
b
,
*
r
;
// pull all the primatives
key
=
findarg
(
n
,
"key"
,
"mapassign1"
);
if
(
key
==
N
)
return
N
;
val
=
findarg
(
n
,
"val"
,
"mapassign1"
);
if
(
val
==
N
)
return
N
;
index
=
nodintconst
(
xxx
.
type
->
bound
);
xxx
.
type
->
bound
++
;
dowidth
(
xxx
.
type
);
// build tree
a
=
nod
(
OINDEX
,
xxx
.
mapname
,
index
);
a
=
nod
(
ODOT
,
a
,
newname
(
lookup
(
"key"
)));
a
=
nod
(
OAS
,
a
,
key
);
b
=
nod
(
OINDEX
,
xxx
.
mapname
,
index
);
b
=
nod
(
ODOT
,
b
,
newname
(
lookup
(
"val"
)));
b
=
nod
(
OAS
,
b
,
val
);
r
=
liststmt
(
list
(
list1
(
a
),
b
));
walkstmt
(
&
r
);
return
r
;
}
// for a copy out reference, A = B,
// look through the whole structure
// and substitute references of B to A.
// some rewrite goes on also.
void
initsub
(
Node
*
n
,
Node
*
nam
)
{
Node
*
r
,
*
w
,
*
c
;
NodeList
*
l
;
int
class
,
state
;
// we could probably get a little more
// out of this if we allow minimal simple
// expression on the right (eg OADDR-ONAME)
if
(
n
->
op
!=
ONAME
)
return
;
class
=
typeclass
(
nam
->
type
);
state
=
TS_start
;
switch
(
class
)
{
case
TC_struct
:
goto
str
;
case
TC_array
:
goto
ary
;
case
TC_slice
:
goto
sli
;
case
TC_map
:
goto
map
;
}
return
;
str:
for
(
l
=
xxx
.
list
;
l
;
l
=
l
->
next
)
{
r
=
l
->
n
;
if
(
r
->
op
!=
OAS
&&
r
->
op
!=
OEMPTY
)
continue
;
// optional first usage "nam = N"
if
(
r
->
right
==
N
&&
sametmp
(
r
->
left
,
nam
))
{
if
(
state
!=
TS_start
)
{
dump
(
""
,
r
);
fatal
(
"initsub: str-first and state=%d"
,
state
);
}
state
=
TS_middle
;
r
->
op
=
OEMPTY
;
continue
;
}
// last usage "n = nam"
if
(
r
->
left
!=
N
&&
sametmp
(
r
->
right
,
nam
))
{
if
(
state
==
TS_end
)
{
dump
(
""
,
r
);
fatal
(
"initsub: str-last and state=%d"
,
state
);
}
state
=
TS_end
;
r
->
op
=
OEMPTY
;
continue
;
}
// middle usage "(nam DOT name) AS expr"
if
(
r
->
left
->
op
!=
ODOT
||
!
sametmp
(
r
->
left
->
left
,
nam
))
continue
;
if
(
state
==
TS_end
)
{
dump
(
""
,
r
);
fatal
(
"initsub: str-middle and state=%d"
,
state
);
}
state
=
TS_middle
;
r
->
left
->
left
=
n
;
}
return
;
ary:
for
(
l
=
xxx
.
list
;
l
;
l
=
l
->
next
)
{
r
=
l
->
n
;
if
(
r
->
op
!=
OAS
&&
r
->
op
!=
OEMPTY
)
continue
;
// optional first usage "nam = N"
if
(
r
->
right
==
N
&&
sametmp
(
r
->
left
,
nam
))
{
if
(
state
!=
TS_start
)
{
dump
(
""
,
r
);
fatal
(
"initsub: ary-first and state=%d"
,
state
);
}
state
=
TS_middle
;
r
->
op
=
OEMPTY
;
continue
;
}
// last usage "n = nam"
if
(
r
->
left
!=
N
&&
sametmp
(
r
->
right
,
nam
))
{
if
(
state
==
TS_end
)
{
dump
(
""
,
r
);
fatal
(
"initsub: ary-last and state=%d"
,
state
);
}
state
=
TS_end
;
r
->
op
=
OEMPTY
;
continue
;
}
// middle usage "(nam INDEX literal) = expr"
if
(
r
->
left
->
op
!=
OINDEX
||
!
sametmp
(
r
->
left
->
left
,
nam
))
continue
;
if
(
state
==
TS_end
)
{
dump
(
""
,
r
);
fatal
(
"initsub: ary-middle and state=%d"
,
state
);
}
state
=
TS_middle
;
r
->
left
->
left
=
n
;
}
return
;
sli:
w
=
N
;
for
(
l
=
xxx
.
list
;
l
;
l
=
l
->
next
)
{
r
=
l
->
n
;
if
(
r
->
op
!=
OAS
&&
r
->
op
!=
OEMPTY
)
continue
;
// first usage "nam = (makeslice CALL args)"
if
(
r
->
right
!=
N
&&
sametmp
(
r
->
left
,
nam
))
{
w
=
slicerewrite
(
r
->
right
);
if
(
w
==
N
)
continue
;
if
(
state
!=
TS_start
)
{
dump
(
""
,
r
);
fatal
(
"initsub: sli-first and state=%d"
,
state
);
}
state
=
TS_middle
;
r
->
right
=
w
;
r
->
left
=
n
;
continue
;
}
// last usage "n = nam"
if
(
r
->
left
!=
N
&&
sametmp
(
r
->
right
,
nam
))
{
if
(
state
!=
TS_middle
)
{
dump
(
""
,
r
);
setlineno
(
r
);
fatal
(
"initsub: sli-last and state=%d"
,
state
);
}
state
=
TS_end
;
r
->
op
=
OEMPTY
;
continue
;
}
// middle usage "(nam INDEX literal) = expr"
if
(
r
->
left
->
op
!=
OINDEX
||
!
sametmp
(
r
->
left
->
left
,
nam
))
continue
;
if
(
state
!=
TS_middle
)
{
dump
(
""
,
r
);
fatal
(
"initsub: sli-middle and state=%d"
,
state
);
}
state
=
TS_middle
;
r
->
left
->
left
=
w
->
left
;
}
return
;
map:
return
;
w
=
N
;
for
(
l
=
xxx
.
list
;
l
;
l
=
l
->
next
)
{
r
=
l
->
n
;
if
(
r
->
op
==
OCALL
)
{
// middle usage "(CALL mapassign1 key, val, map)"
c
=
mapindex
(
r
);
if
(
c
==
N
)
continue
;
state
=
TS_middle
;
*
r
=
*
c
;
continue
;
}
if
(
r
->
op
!=
OAS
&&
r
->
op
!=
OEMPTY
)
continue
;
// first usage "nam = (makemap CALL args)"
if
(
r
->
right
!=
N
&&
sametmp
(
r
->
left
,
nam
))
{
w
=
maprewrite
(
r
->
right
);
if
(
w
==
N
)
continue
;
if
(
state
!=
TS_start
)
{
dump
(
""
,
r
);
fatal
(
"initsub: map-first and state=%d"
,
state
);
}
state
=
TS_middle
;
r
->
right
=
w
;
r
->
left
=
n
;
continue
;
}
// last usage "n = nam"
if
(
r
->
left
!=
N
&&
sametmp
(
r
->
right
,
nam
))
{
if
(
state
!=
TS_middle
)
{
dump
(
""
,
r
);
fatal
(
"initsub: map-last and state=%d"
,
state
);
}
state
=
TS_end
;
r
->
op
=
OEMPTY
;
continue
;
}
}
return
;
}
static
void
init1
(
Node
*
n
,
NodeList
**
out
)
{
...
...
@@ -489,16 +40,17 @@ init1(Node *n, NodeList **out)
n
->
initorder
=
2
;
if
(
n
->
defn
!=
N
)
{
switch
(
n
->
defn
->
op
)
{
default:
goto
bad
;
case
ODCLFUNC
:
for
(
l
=
n
->
defn
->
nbody
;
l
;
l
=
l
->
next
)
init1
(
l
->
n
,
out
);
break
;
case
OAS
:
if
(
n
->
defn
->
left
!=
n
)
{
default:
dump
(
"defn"
,
n
->
defn
);
fatal
(
"bad defn"
);
}
if
(
n
->
defn
->
left
!=
n
)
goto
bad
;
init1
(
n
->
defn
->
right
,
out
);
if
(
debug
[
'j'
])
print
(
"%S
\n
"
,
n
->
sym
);
...
...
@@ -508,6 +60,10 @@ init1(Node *n, NodeList **out)
}
n
->
initorder
=
1
;
return
;
bad:
dump
(
"defn"
,
n
->
defn
);
fatal
(
"bad defn"
);
}
static
void
...
...
@@ -532,23 +88,9 @@ initreorder(NodeList *l, NodeList **out)
NodeList
*
initfix
(
NodeList
*
l
)
{
Node
*
r
;
Node
List
*
lout
;
xxx
.
list
=
nil
;
initreorder
(
l
,
&
xxx
.
list
);
if
(
0
)
return
xxx
.
list
;
if
(
nerrors
!=
0
)
return
xxx
.
list
;
// look for the copy-out reference
for
(
l
=
xxx
.
list
;
l
;
l
=
l
->
next
)
{
r
=
l
->
n
;
if
(
r
->
op
==
OAS
)
if
(
inittmp
(
r
->
right
))
initsub
(
r
->
left
,
r
->
right
);
}
return
xxx
.
list
;
lout
=
nil
;
initreorder
(
l
,
&
lout
);
return
lout
;
}
src/cmd/gc/subr.c
View file @
6fceadbb
...
...
@@ -609,7 +609,7 @@ dodump(Node *n, int dep)
print
(
"%O-rlist
\n
"
,
n
->
op
);
dodumplist
(
n
->
rlist
,
dep
+
1
);
}
if
(
n
->
nbody
!=
nil
)
{
if
(
n
->
op
!=
OIF
&&
n
->
nbody
!=
nil
)
{
indent
(
dep
);
print
(
"%O-nbody
\n
"
,
n
->
op
);
dodumplist
(
n
->
nbody
,
dep
+
1
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment