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
dee07c88
Commit
dee07c88
authored
Jun 23, 2008
by
Ken Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
maps
SVN=124030
parent
12c2864e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
418 additions
and
50 deletions
+418
-50
walk.c
src/cmd/gc/walk.c
+59
-50
runtime.c
src/runtime/runtime.c
+359
-0
No files found.
src/cmd/gc/walk.c
View file @
dee07c88
...
...
@@ -27,7 +27,7 @@ walktype(Node *n, int top)
Type
*
t
;
Sym
*
s
;
long
lno
;
int
et
;
int
et
,
cl
,
cr
;
/*
* walk the whole tree of the body of a function.
...
...
@@ -229,29 +229,47 @@ loop:
l
=
n
->
left
;
r
=
n
->
right
;
if
(
l
==
N
)
goto
ret
;
walktype
(
l
,
Elv
);
walktype
(
r
,
Erv
);
if
(
l
==
N
||
l
->
type
==
T
)
if
(
l
==
N
||
r
==
N
)
goto
ret
;
convlit
(
r
,
l
->
type
);
if
(
r
==
N
||
r
->
type
==
T
)
cl
=
listcount
(
l
);
cr
=
listcount
(
r
);
if
(
cl
==
cr
)
{
walktype
(
r
,
Erv
);
l
=
ascompatee
(
n
->
op
,
&
n
->
left
,
&
n
->
right
);
if
(
l
!=
N
)
*
n
=
*
reorder3
(
l
);
goto
ret
;
}
if
(
cr
!=
1
)
{
yyerror
(
"bad shape across assignment"
);
goto
ret
;
}
if
(
r
->
op
==
OCALL
&&
l
->
op
==
OLIST
)
{
switch
(
r
->
op
)
{
case
OCALLMETH
:
case
OCALLINTER
:
case
OCALL
:
walktype
(
r
,
Erv
);
l
=
ascompatet
(
n
->
op
,
&
n
->
left
,
&
r
->
type
,
0
);
if
(
l
!=
N
)
{
*
n
=
*
nod
(
OLIST
,
r
,
reorder2
(
l
));
}
goto
ret
;
}
break
;
l
=
ascompatee
(
n
->
op
,
&
n
->
left
,
&
n
->
right
);
if
(
l
!=
N
)
*
n
=
*
reorder3
(
l
);
case
OINDEX
:
case
OINDEXPTR
:
if
(
!
isptrto
(
r
->
left
->
type
,
TMAP
))
goto
badt
;
if
(
cl
!=
2
)
goto
badt
;
*
n
=
*
mapop
(
n
,
top
);
break
;
}
goto
ret
;
case
OBREAK
:
...
...
@@ -1412,7 +1430,7 @@ mapop(Node *n, int top)
a
=
n
->
left
;
// map
r
=
nod
(
OLIST
,
a
,
r
);
on
=
syslook
(
"mapaccess
1
"
,
1
);
on
=
syslook
(
"mapaccess
2
"
,
1
);
argtype
(
on
,
t
->
down
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
...
...
@@ -1424,26 +1442,16 @@ mapop(Node *n, int top)
r
->
type
=
t
->
type
;
break
;
// mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
access2:
// mapaccess2(hmap *map[any-1]any-2, key any-3) (val-4 any, pres bool);
t
=
fixmap
(
n
->
left
->
type
);
t
=
fixmap
(
n
->
right
->
left
->
type
);
if
(
t
==
T
)
break
;
convlit
(
n
->
right
,
t
->
down
);
if
(
!
eqtype
(
n
->
right
->
type
,
t
->
down
,
0
))
{
badtype
(
n
->
op
,
n
->
right
->
type
,
t
->
down
);
break
;
}
a
=
n
->
right
;
// key
if
(
!
isptr
[
t
->
down
->
etype
])
{
a
=
nod
(
OADDR
,
a
,
N
);
a
->
type
=
ptrto
(
t
);
}
a
=
n
->
right
->
right
;
// key
r
=
a
;
a
=
n
->
left
;
// map
a
=
n
->
right
->
left
;
// map
r
=
nod
(
OLIST
,
a
,
r
);
on
=
syslook
(
"mapaccess2"
,
1
);
...
...
@@ -1453,14 +1461,17 @@ mapop(Node *n, int top)
argtype
(
on
,
t
->
down
);
// any-3
argtype
(
on
,
t
->
type
);
// any-4
r
=
nod
(
OCALL
,
on
,
r
);
walktype
(
r
,
Erv
);
r
->
type
=
t
->
type
;
n
->
right
=
nod
(
OCALL
,
on
,
r
);
walktype
(
n
,
Etop
);
r
=
n
;
break
;
case
OAS
:
if
(
top
!=
Elv
)
if
(
top
!=
Elv
)
{
if
(
top
==
Etop
)
goto
access2
;
goto
nottop
;
}
if
(
n
->
left
->
op
!=
OINDEX
)
fatal
(
"mapos: AS left not OINDEX"
);
...
...
@@ -1661,7 +1672,7 @@ colas(Node *nl, Node *nr)
/* nl is an expression list.
* nr is an expression list.
* return a newname-list from
* t
he types
from the rhs.
* t
ypes derived
from the rhs.
*/
n
=
N
;
cr
=
listcount
(
nr
);
...
...
@@ -1675,21 +1686,19 @@ colas(Node *nl, Node *nr)
l
=
listfirst
(
&
savel
,
&
nl
);
r
=
listfirst
(
&
saver
,
&
nr
);
loop:
if
(
l
==
N
)
return
n
;
walktype
(
r
,
Erv
);
defaultlit
(
r
);
a
=
old2new
(
l
,
r
->
type
);
if
(
n
==
N
)
n
=
a
;
else
n
=
nod
(
OLIST
,
n
,
a
);
while
(
l
!=
N
)
{
walktype
(
r
,
Erv
);
defaultlit
(
r
);
a
=
old2new
(
l
,
r
->
type
);
if
(
n
==
N
)
n
=
a
;
else
n
=
nod
(
OLIST
,
n
,
a
);
l
=
listnext
(
&
savel
);
r
=
listnext
(
&
saver
);
goto
loop
;
l
=
listnext
(
&
savel
);
r
=
listnext
(
&
saver
);
}
return
n
;
multi:
/*
...
...
@@ -1738,9 +1747,9 @@ multi:
if
(
t
==
T
||
t
->
etype
!=
TMAP
)
goto
badt
;
a
=
old2new
(
nl
->
left
,
t
ypes
[
TBOOL
]
);
a
=
old2new
(
nl
->
left
,
t
->
type
);
n
=
a
;
a
=
old2new
(
nl
->
right
,
t
->
type
);
a
=
old2new
(
nl
->
right
,
t
ypes
[
TBOOL
]
);
n
=
nod
(
OLIST
,
n
,
a
);
break
;
}
...
...
src/runtime/runtime.c
View file @
dee07c88
...
...
@@ -764,3 +764,362 @@ check(void)
// prints(1"check ok\n");
initsig
();
}
typedef
struct
Link
Link
;
typedef
struct
Hmap
Hmap
;
typedef
struct
Alg
Alg
;
struct
Alg
{
uint64
(
*
hash
)(
uint32
,
void
*
);
uint32
(
*
equal
)(
uint32
,
void
*
,
void
*
);
void
(
*
print
)(
uint32
,
void
*
);
void
(
*
copy
)(
uint32
,
void
*
,
void
*
);
};
struct
Link
{
Link
*
link
;
byte
data
[
8
];
};
struct
Hmap
{
uint32
keysize
;
uint32
valsize
;
uint32
hint
;
Alg
*
keyalg
;
Alg
*
valalg
;
uint32
valoffset
;
uint32
ko
;
uint32
vo
;
uint32
po
;
Link
*
link
;
};
static
uint64
memhash
(
uint32
s
,
void
*
a
)
{
prints
(
"memhash
\n
"
);
return
0x12345
;
}
static
uint32
memequal
(
uint32
s
,
void
*
a
,
void
*
b
)
{
byte
*
ba
,
*
bb
;
uint32
i
;
ba
=
a
;
bb
=
b
;
for
(
i
=
0
;
i
<
s
;
i
++
)
if
(
ba
[
i
]
!=
bb
[
i
])
return
0
;
return
1
;
}
static
void
memprint
(
uint32
s
,
void
*
a
)
{
uint64
v
;
v
=
0xbadb00b
;
switch
(
s
)
{
case
1
:
v
=
*
(
uint8
*
)
a
;
break
;
case
2
:
v
=
*
(
uint16
*
)
a
;
break
;
case
4
:
v
=
*
(
uint32
*
)
a
;
break
;
case
8
:
v
=
*
(
uint64
*
)
a
;
break
;
}
sys_printint
(
v
);
}
static
void
memcopy
(
uint32
s
,
void
*
a
,
void
*
b
)
{
byte
*
ba
,
*
bb
;
uint32
i
;
ba
=
a
;
bb
=
b
;
if
(
bb
==
nil
)
{
for
(
i
=
0
;
i
<
s
;
i
++
)
ba
[
i
]
=
0
;
return
;
}
for
(
i
=
0
;
i
<
s
;
i
++
)
ba
[
i
]
=
bb
[
i
];
}
static
uint64
stringhash
(
uint32
s
,
string
*
a
)
{
prints
(
"stringhash
\n
"
);
return
0x12345
;
}
static
uint32
stringequal
(
uint32
s
,
string
*
a
,
string
*
b
)
{
return
cmpstring
(
*
a
,
*
b
)
==
0
;
}
static
void
stringprint
(
uint32
s
,
string
*
a
)
{
sys_printstring
(
*
a
);
}
static
void
stringcopy
(
uint32
s
,
string
*
a
,
string
*
b
)
{
if
(
b
==
nil
)
{
*
b
=
nil
;
return
;
}
*
a
=
*
b
;
}
static
uint32
rnd
(
uint32
n
,
uint32
m
)
{
uint32
r
;
r
=
n
%
m
;
if
(
r
)
n
+=
m
-
r
;
return
n
;
}
static
Alg
algarray
[]
=
{
{
&
memhash
,
&
memequal
,
&
memprint
,
&
memcopy
},
{
&
stringhash
,
&
stringequal
,
&
stringprint
,
&
stringcopy
},
};
// newmap(keysize uint32, valsize uint32,
// keyalg uint32, valalg uint32,
// hint uint32) (hmap *map[any]any);
void
sys_newmap
(
uint32
keysize
,
uint32
valsize
,
uint32
keyalg
,
uint32
valalg
,
uint32
hint
,
Hmap
*
ret
)
{
Hmap
*
m
;
if
(
keyalg
>=
nelem
(
algarray
)
||
valalg
>=
nelem
(
algarray
))
{
prints
(
"0<="
);
sys_printint
(
keyalg
);
prints
(
"<"
);
sys_printint
(
nelem
(
algarray
));
prints
(
"
\n
0<="
);
sys_printint
(
valalg
);
prints
(
"<"
);
sys_printint
(
nelem
(
algarray
));
prints
(
"
\n
"
);
throw
(
"sys_newmap: key/val algorithm out of range"
);
}
m
=
mal
(
sizeof
(
*
m
));
m
->
keysize
=
keysize
;
m
->
valsize
=
valsize
;
m
->
keyalg
=
&
algarray
[
keyalg
];
m
->
valalg
=
&
algarray
[
valalg
];
m
->
hint
=
hint
;
// these calculations are compiler dependent
m
->
valoffset
=
rnd
(
keysize
,
valsize
);
m
->
ko
=
rnd
(
sizeof
(
m
),
keysize
);
m
->
vo
=
rnd
(
m
->
ko
+
keysize
,
valsize
);
m
->
po
=
rnd
(
m
->
vo
+
valsize
,
1
);
ret
=
m
;
FLUSH
(
&
ret
);
if
(
debug
)
{
prints
(
"newmap: map="
);
sys_printpointer
(
m
);
prints
(
"; keysize="
);
sys_printint
(
keysize
);
prints
(
"; valsize="
);
sys_printint
(
valsize
);
prints
(
"; keyalg="
);
sys_printint
(
keyalg
);
prints
(
"; valalg="
);
sys_printint
(
valalg
);
prints
(
"; valoffset="
);
sys_printint
(
m
->
valoffset
);
prints
(
"; ko="
);
sys_printint
(
m
->
ko
);
prints
(
"; vo="
);
sys_printint
(
m
->
vo
);
prints
(
"; po="
);
sys_printint
(
m
->
po
);
prints
(
"
\n
"
);
}
}
// mapaccess1(hmap *map[any]any, key any) (val any);
void
sys_mapaccess1
(
Hmap
*
m
,
...)
{
Link
*
l
;
byte
*
ak
,
*
av
;
ak
=
(
byte
*
)
&
m
+
m
->
ko
;
av
=
(
byte
*
)
&
m
+
m
->
vo
;
for
(
l
=
m
->
link
;
l
!=
nil
;
l
=
l
->
link
)
{
if
(
m
->
keyalg
->
equal
(
m
->
keysize
,
ak
,
l
->
data
))
{
m
->
valalg
->
copy
(
m
->
valsize
,
av
,
l
->
data
+
m
->
valoffset
);
goto
out
;
}
}
m
->
valalg
->
copy
(
m
->
valsize
,
av
,
0
);
out:
if
(
1
)
{
prints
(
"sys_mapaccess1: map="
);
sys_printpointer
(
m
);
prints
(
"; key="
);
m
->
keyalg
->
print
(
m
->
keysize
,
ak
);
prints
(
"; val="
);
m
->
valalg
->
print
(
m
->
valsize
,
av
);
prints
(
"
\n
"
);
}
}
// mapaccess2(hmap *map[any]any, key any) (val any, pres bool);
void
sys_mapaccess2
(
Hmap
*
m
,
...)
{
Link
*
l
;
byte
*
ak
,
*
av
,
*
ap
;
ak
=
(
byte
*
)
&
m
+
m
->
ko
;
av
=
(
byte
*
)
&
m
+
m
->
vo
;
ap
=
(
byte
*
)
&
m
+
m
->
po
;
for
(
l
=
m
->
link
;
l
!=
nil
;
l
=
l
->
link
)
{
if
(
m
->
keyalg
->
equal
(
m
->
keysize
,
ak
,
l
->
data
))
{
*
ap
=
true
;
m
->
valalg
->
copy
(
m
->
valsize
,
av
,
l
->
data
+
m
->
valoffset
);
goto
out
;
}
}
*
ap
=
false
;
m
->
valalg
->
copy
(
m
->
valsize
,
av
,
nil
);
out:
if
(
debug
)
{
prints
(
"sys_mapaccess2: map="
);
sys_printpointer
(
m
);
prints
(
"; key="
);
m
->
keyalg
->
print
(
m
->
keysize
,
ak
);
prints
(
"; val="
);
m
->
valalg
->
print
(
m
->
valsize
,
av
);
prints
(
"; pres="
);
sys_printbool
(
*
ap
);
prints
(
"
\n
"
);
}
}
static
void
sys_mapassign
(
Hmap
*
m
,
byte
*
ak
,
byte
*
av
)
{
Link
*
l
;
// mapassign(hmap *map[any]any, key any, val any);
for
(
l
=
m
->
link
;
l
!=
nil
;
l
=
l
->
link
)
{
if
(
m
->
keyalg
->
equal
(
m
->
keysize
,
ak
,
l
->
data
))
goto
out
;
}
l
=
mal
((
sizeof
(
*
l
)
-
8
)
+
m
->
keysize
+
m
->
valsize
);
l
->
link
=
m
->
link
;
m
->
link
=
l
;
m
->
keyalg
->
copy
(
m
->
keysize
,
l
->
data
,
ak
);
out:
m
->
valalg
->
copy
(
m
->
valsize
,
l
->
data
+
m
->
valoffset
,
av
);
if
(
debug
)
{
prints
(
"mapassign: map="
);
sys_printpointer
(
m
);
prints
(
"; key="
);
m
->
keyalg
->
print
(
m
->
keysize
,
ak
);
prints
(
"; val="
);
m
->
valalg
->
print
(
m
->
valsize
,
av
);
prints
(
"
\n
"
);
}
}
// mapassign1(hmap *map[any]any, key any, val any);
void
sys_mapassign1
(
Hmap
*
m
,
...)
{
Link
**
ll
;
byte
*
ak
,
*
av
;
ak
=
(
byte
*
)
&
m
+
m
->
ko
;
av
=
(
byte
*
)
&
m
+
m
->
vo
;
sys_mapassign
(
m
,
ak
,
av
);
}
// mapassign2(hmap *map[any]any, key any, val any, pres bool);
void
sys_mapassign2
(
Hmap
*
m
,
...)
{
Link
**
ll
;
byte
*
ak
,
*
av
,
*
ap
;
ak
=
(
byte
*
)
&
m
+
m
->
ko
;
av
=
(
byte
*
)
&
m
+
m
->
vo
;
ap
=
(
byte
*
)
&
m
+
m
->
po
;
if
(
*
ap
==
true
)
{
// assign
sys_mapassign
(
m
,
ak
,
av
);
return
;
}
// delete
for
(
ll
=&
m
->
link
;
(
*
ll
)
!=
nil
;
ll
=&
(
*
ll
)
->
link
)
{
if
(
m
->
keyalg
->
equal
(
m
->
keysize
,
ak
,
(
*
ll
)
->
data
))
{
m
->
valalg
->
copy
(
m
->
valsize
,
(
*
ll
)
->
data
+
m
->
valoffset
,
nil
);
(
*
ll
)
=
(
*
ll
)
->
link
;
if
(
debug
)
{
prints
(
"mapdelete (found): map="
);
sys_printpointer
(
m
);
prints
(
"; key="
);
m
->
keyalg
->
print
(
m
->
keysize
,
ak
);
prints
(
"
\n
"
);
}
return
;
}
}
if
(
debug
)
{
prints
(
"mapdelete (not found): map="
);
sys_printpointer
(
m
);
prints
(
"; key="
);
m
->
keyalg
->
print
(
m
->
keysize
,
ak
);
prints
(
" *** not found
\n
"
);
}
}
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