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
66a603c9
Commit
66a603c9
authored
Aug 28, 2008
by
Ken Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
arrays
R=r OCL=14603 CL=14603
parent
30fd44cf
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
612 additions
and
70 deletions
+612
-70
align.c
src/cmd/6g/align.c
+4
-2
cgen.c
src/cmd/6g/cgen.c
+90
-6
export.c
src/cmd/gc/export.c
+12
-2
go.h
src/cmd/gc/go.h
+18
-6
go.y
src/cmd/gc/go.y
+11
-1
lex.c
src/cmd/gc/lex.c
+1
-0
subr.c
src/cmd/gc/subr.c
+37
-14
sys.go
src/cmd/gc/sys.go
+11
-0
sysimport.c
src/cmd/gc/sysimport.c
+0
-0
walk.c
src/cmd/gc/walk.c
+250
-36
Makefile
src/runtime/Makefile
+1
-0
array.c
src/runtime/array.c
+165
-0
runtime.h
src/runtime/runtime.h
+9
-0
powser1.go
test/chan/powser1.go
+3
-3
No files found.
src/cmd/6g/align.c
View file @
66a603c9
...
...
@@ -157,12 +157,14 @@ dowidth(Type *t)
case
TSTRING
:
// implemented as pointer
w
=
wptr
;
break
;
case
TARRAY
:
case
TDARRAY
:
fatal
(
"width of a dynamic array"
);
case
TARRAY
:
if
(
t
->
type
==
T
)
break
;
dowidth
(
t
->
type
);
w
=
t
->
bound
*
t
->
type
->
width
;
w
=
t
->
bound
*
t
->
type
->
width
;
// + offsetof(Array, b[0]);
break
;
case
TSTRUCT
:
...
...
src/cmd/6g/cgen.c
View file @
66a603c9
...
...
@@ -136,6 +136,20 @@ cgen(Node *n, Node *res)
}
regalloc
(
&
n1
,
nl
->
type
,
res
);
cgen
(
nl
,
&
n1
);
if
(
isptrto
(
n
->
type
,
TARRAY
)
&&
isptrto
(
nl
->
type
,
TDARRAY
))
{
// convert dynamic array to static array
n2
=
n1
;
n2
.
op
=
OINDREG
;
n2
.
xoffset
=
offsetof
(
Array
,
array
);
n2
.
type
=
types
[
tptr
];
gins
(
AMOVQ
,
&
n2
,
&
n1
);
}
if
(
isptrto
(
n
->
type
,
TDARRAY
)
&&
isptrto
(
nl
->
type
,
TARRAY
))
{
// conver static array to dynamic array
// it is assumed that the dope is just before the array
nodconst
(
&
n2
,
types
[
tptr
],
offsetof
(
Array
,
b
));
gins
(
ASUBQ
,
&
n2
,
&
n1
);
}
gmove
(
&
n1
,
res
);
regfree
(
&
n1
);
break
;
...
...
@@ -173,9 +187,33 @@ cgen(Node *n, Node *res)
regfree
(
&
n1
);
break
;
}
if
(
isptrto
(
nl
->
type
,
TDARRAY
))
{
regalloc
(
&
n1
,
types
[
tptr
],
res
);
cgen
(
nl
,
&
n1
);
n1
.
op
=
OINDREG
;
n1
.
type
=
types
[
TUINT32
];
n1
.
xoffset
=
offsetof
(
Array
,
nel
);
gmove
(
&
n1
,
res
);
regfree
(
&
n1
);
break
;
}
fatal
(
"cgen: OLEN: unknown type %lT"
,
nl
->
type
);
break
;
case
OCAP
:
if
(
isptrto
(
nl
->
type
,
TDARRAY
))
{
regalloc
(
&
n1
,
types
[
tptr
],
res
);
cgen
(
nl
,
&
n1
);
n1
.
op
=
OINDREG
;
n1
.
type
=
types
[
TUINT32
];
n1
.
xoffset
=
offsetof
(
Array
,
cap
);
gmove
(
&
n1
,
res
);
regfree
(
&
n1
);
break
;
}
fatal
(
"cgen: OCAP: unknown type %lT"
,
nl
->
type
);
break
;
case
OADDR
:
agen
(
nl
,
res
);
break
;
...
...
@@ -253,6 +291,7 @@ agen(Node *n, Node *res)
{
Node
*
nl
,
*
nr
;
Node
n1
,
n2
,
n3
,
tmp
;
Prog
*
p1
;
uint32
w
;
Type
*
t
;
...
...
@@ -347,15 +386,60 @@ agen(Node *n, Node *res)
// &a is in res
// i is in &n1
// w is width
nodconst
(
&
n3
,
types
[
TINT64
],
w
);
// w/tint64
if
(
isptrto
(
nl
->
type
,
TDARRAY
))
{
regalloc
(
&
n2
,
types
[
tptr
],
res
);
gmove
(
res
,
&
n2
);
if
(
!
debug
[
'B'
])
{
// check bounds
n3
=
n2
;
n3
.
op
=
OINDREG
;
n3
.
type
=
types
[
tptr
];
n3
.
xoffset
=
offsetof
(
Array
,
nel
);
gins
(
optoas
(
OCMP
,
types
[
TUINT32
]),
&
n1
,
&
n3
);
p1
=
gbranch
(
optoas
(
OLT
,
types
[
TUINT32
]),
T
);
nodconst
(
&
n3
,
types
[
TUINT8
],
5
);
// 5 is range trap
gins
(
AINT
,
&
n3
,
N
);
patch
(
p1
,
pc
);
}
// fetch array base from dope
n3
=
n2
;
n3
.
op
=
OINDREG
;
n3
.
type
=
types
[
tptr
];
n3
.
xoffset
=
offsetof
(
Array
,
array
);
gins
(
AMOVQ
,
&
n3
,
&
n2
);
gmove
(
&
n2
,
res
);
regfree
(
&
n2
);
}
else
if
(
!
debug
[
'B'
])
{
// check bounds
nodconst
(
&
n3
,
types
[
TUINT32
],
nl
->
type
->
bound
);
if
(
isptrto
(
nl
->
type
,
TARRAY
))
nodconst
(
&
n3
,
types
[
TUINT32
],
nl
->
type
->
type
->
bound
);
gins
(
optoas
(
OCMP
,
types
[
TUINT32
]),
&
n1
,
&
n3
);
p1
=
gbranch
(
optoas
(
OLT
,
types
[
TUINT32
]),
T
);
nodconst
(
&
n3
,
types
[
TUINT8
],
5
);
// 5 is range trap
gins
(
AINT
,
&
n3
,
N
);
patch
(
p1
,
pc
);
}
t
=
types
[
TUINT64
];
if
(
issigned
[
n1
.
type
->
etype
])
regalloc
(
&
n2
,
types
[
TINT64
],
&
n1
);
// i/int64
else
regalloc
(
&
n2
,
types
[
TUINT64
],
&
n1
);
// i/uint64
t
=
types
[
TINT64
];
regalloc
(
&
n2
,
t
,
&
n1
);
// i
gmove
(
&
n1
,
&
n2
);
gins
(
optoas
(
OMUL
,
types
[
TINT64
]),
&
n3
,
&
n2
);
gins
(
optoas
(
OADD
,
types
[
tptr
]),
&
n2
,
res
);
regfree
(
&
n1
);
nodconst
(
&
n3
,
t
,
w
);
// w
gins
(
optoas
(
OMUL
,
t
),
&
n3
,
&
n2
);
gins
(
optoas
(
OADD
,
types
[
tptr
]),
&
n2
,
res
);
regfree
(
&
n2
);
break
;
...
...
src/cmd/gc/export.c
View file @
66a603c9
...
...
@@ -147,12 +147,17 @@ dumpexporttype(Sym *s)
break
;
case
TARRAY
:
case
TDARRAY
:
reexport
(
t
->
type
);
/* type 2 */
Bprint
(
bout
,
"
\t
type "
);
if
(
s
->
export
!=
0
)
Bprint
(
bout
,
"!"
);
if
(
et
==
TDARRAY
)
{
Bprint
(
bout
,
"%lS [] %lS
\n
"
,
s
,
t
->
type
->
sym
);
break
;
}
Bprint
(
bout
,
"%lS [%lud] %lS
\n
"
,
s
,
t
->
bound
,
t
->
type
->
sym
);
break
;
...
...
@@ -517,8 +522,13 @@ doimport2(Node *ss, Val *b, Node *st)
Type
*
t
;
Sym
*
s
;
t
=
typ
(
TARRAY
);
t
->
bound
=
mpgetfix
(
b
->
u
.
xval
);
if
(
b
==
nil
)
{
t
=
typ
(
TDARRAY
);
t
->
dbound
=
N
;
}
else
{
t
=
typ
(
TARRAY
);
t
->
bound
=
mpgetfix
(
b
->
u
.
xval
);
}
s
=
pkglookup
(
st
->
sym
->
name
,
st
->
psym
->
name
);
t
->
type
=
s
->
otype
;
...
...
src/cmd/gc/go.h
View file @
66a603c9
...
...
@@ -3,11 +3,6 @@
// license that can be found in the LICENSE file.
/*
todo:
1. dyn arrays
2. multi
tothinkabout:
2. argument in import
*/
#include <u.h>
...
...
@@ -55,6 +50,21 @@ struct String
char
s
[
3
];
// variable
};
/*
* note this is the runtime representation
* of the compilers arrays. it is probably
* insafe to use it this way, but it puts
* all the changes in one place.
*/
typedef
struct
Array
Array
;
struct
Array
{
// must not move anything
uchar
array
[
8
];
// pointer to data
uint32
nel
;
// number of elements
uint32
cap
;
// allocated number of elements
uchar
b
;
// actual array - may not be contig
};
enum
{
Mpscale
=
29
,
/* safely smaller than bits in a long */
...
...
@@ -131,6 +141,7 @@ struct Type
// TARRAY
int32
bound
;
Node
*
dbound
;
};
#define T ((Type*)0)
...
...
@@ -251,7 +262,7 @@ enum
ORETURN
,
OFOR
,
OIF
,
OSWITCH
,
OI2S
,
OS2I
,
OI2I
,
OAS
,
OASOP
,
OCASE
,
OXCASE
,
OSCASE
,
OFALL
,
OXFALL
,
OGOTO
,
OPROC
,
ONEW
,
OEMPTY
,
OSELECT
,
OLEN
,
OPANIC
,
OPRINT
,
OTYPEOF
,
OLEN
,
O
CAP
,
O
PANIC
,
OPRINT
,
OTYPEOF
,
OOROR
,
OANDAND
,
...
...
@@ -669,6 +680,7 @@ Type* fixmap(Type*);
Node
*
mapop
(
Node
*
,
int
);
Type
*
fixchan
(
Type
*
);
Node
*
chanop
(
Node
*
,
int
);
Node
*
arrayop
(
Node
*
,
int
);
Node
*
isandss
(
Type
*
,
Node
*
);
Node
*
convas
(
Node
*
);
void
arrayconv
(
Type
*
,
Node
*
);
...
...
src/cmd/gc/go.y
View file @
66a603c9
...
...
@@ -18,7 +18,7 @@
%
token
<
sym
>
LPACKAGE
LIMPORT
LEXPORT
%
token
<
sym
>
LMAP
LCHAN
LINTERFACE
LFUNC
LSTRUCT
%
token
<
sym
>
LCOLAS
LFALL
LRETURN
%
token
<
sym
>
LNEW
LLEN
LTYPEOF
LPANIC
LPRINT
%
token
<
sym
>
LNEW
LLEN
L
CAP
L
TYPEOF
LPANIC
LPRINT
%
token
<
sym
>
LVAR
LTYPE
LCONST
LCONVERT
LSELECT
%
token
<
sym
>
LFOR
LIF
LELSE
LSWITCH
LCASE
LDEFAULT
%
token
<
sym
>
LBREAK
LCONTINUE
LGO
LGOTO
LRANGE
...
...
@@ -733,6 +733,10 @@ pexpr:
{
$$
=
nod
(
OLEN
,
$
3
,
N
);
}
|
LCAP
'('
expr
')'
{
$$
=
nod
(
OCAP
,
$
3
,
N
);
}
|
LTYPEOF
'('
type
')'
{
$$
=
nod
(
OTYPEOF
,
N
,
N
);
...
...
@@ -852,6 +856,7 @@ key:
|
LFALSE
|
LIOTA
|
LLEN
|
LCAP
|
LPANIC
|
LPRINT
|
LNEW
...
...
@@ -1519,6 +1524,11 @@ hidden_import:
//
type
array
doimport2
($
2
,
&$
4
,
$
6
);
}
|
LTYPE
hidden_importsym
'['
']'
hidden_importsym
{
//
type
array
doimport2
($
2
,
nil
,
$
5
);
}
|
LTYPE
hidden_importsym
'('
ohidden_importsym_list
')'
{
//
type
function
...
...
src/cmd/gc/lex.c
View file @
66a603c9
...
...
@@ -998,6 +998,7 @@ static struct
"map"
,
LMAP
,
Txxx
,
"new"
,
LNEW
,
Txxx
,
"len"
,
LLEN
,
Txxx
,
"cap"
,
LCAP
,
Txxx
,
"nil"
,
LNIL
,
Txxx
,
"package"
,
LPACKAGE
,
Txxx
,
"panic"
,
LPANIC
,
Txxx
,
...
...
src/cmd/gc/subr.c
View file @
66a603c9
...
...
@@ -374,27 +374,39 @@ Type*
aindex
(
Node
*
b
,
Type
*
t
)
{
Type
*
r
;
r
=
typ
(
TARRAY
);
r
->
type
=
t
;
if
(
t
->
etype
==
TDARRAY
)
yyerror
(
"dynamic array type cannot be a dynamic array"
);
int
bound
;
walktype
(
b
,
Erv
);
switch
(
whatis
(
b
))
{
default:
yyerror
(
"array bound must be a constant integer expression"
);
default:
// variable bound
walktype
(
b
,
Erv
);
if
(
b
->
type
!=
T
&&
isint
[
b
->
type
->
etype
])
goto
dyn
;
yyerror
(
"array bound must be an integer expression"
);
bound
=
0
;
break
;
case
Wnil
:
// default zero lb
r
->
bound
=
0
;
break
;
case
Wnil
:
// open bound
goto
dyn
;
case
Wlitint
:
// fixed
lb
r
->
bound
=
mpgetfix
(
b
->
val
.
u
.
xval
);
case
Wlitint
:
// fixed
bound
bound
=
mpgetfix
(
b
->
val
.
u
.
xval
);
break
;
}
// fixed array
r
=
typ
(
TARRAY
);
r
->
type
=
t
;
r
->
dbound
=
b
;
r
->
bound
=
bound
;
return
r
;
dyn:
// dynamic array
r
=
typ
(
TDARRAY
);
r
->
type
=
t
;
r
->
dbound
=
b
;
r
->
bound
=
0
;
return
r
;
}
...
...
@@ -641,6 +653,7 @@ opnames[] =
[
OLABEL
]
=
"LABEL"
,
[
OLE
]
=
"LE"
,
[
OLEN
]
=
"LEN"
,
[
OCAP
]
=
"CAP"
,
[
OLIST
]
=
"LIST"
,
[
OLITERAL
]
=
"LITERAL"
,
[
OLSH
]
=
"LSH"
,
...
...
@@ -1001,6 +1014,8 @@ Tconv(Fmt *fp)
case
TDARRAY
:
snprint
(
buf1
,
sizeof
(
buf1
),
"[]%T"
,
t
->
type
);
if
(
t
->
dbound
!=
N
)
snprint
(
buf1
,
sizeof
(
buf1
),
"[<expr>]%T"
,
t
->
type
);
strncat
(
buf
,
buf1
,
sizeof
(
buf
));
break
;
...
...
@@ -1229,7 +1244,6 @@ eqtype(Type *t1, Type *t2, int d)
{
if
(
d
>=
10
)
return
1
;
if
(
t1
==
t2
)
return
1
;
if
(
t1
==
T
||
t2
==
T
)
...
...
@@ -1279,6 +1293,11 @@ eqtype(Type *t1, Type *t2, int d)
t2
=
t2
->
down
;
}
return
1
;
case
TARRAY
:
if
(
t1
->
bound
==
t2
->
bound
)
break
;
return
0
;
}
return
eqtype
(
t1
->
type
,
t2
->
type
,
d
+
1
);
}
...
...
@@ -1304,6 +1323,8 @@ loop:
case
TPTR32
:
case
TPTR64
:
case
TCHAN
:
case
TARRAY
:
case
TDARRAY
:
stp
=
&
st
->
type
;
goto
loop
;
...
...
@@ -1373,6 +1394,8 @@ deep(Type *t)
case
TPTR32
:
case
TPTR64
:
case
TCHAN
:
case
TARRAY
:
case
TDARRAY
:
nt
=
shallow
(
t
);
nt
->
type
=
deep
(
t
->
type
);
break
;
...
...
src/cmd/gc/sys.go
View file @
66a603c9
...
...
@@ -56,6 +56,11 @@ func selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
func
selectrecv
(
sel
*
byte
,
hchan
*
chan
any
,
elem
*
any
)
(
selected
bool
);
func
selectgo
(
sel
*
byte
);
func
newarray
(
nel
uint32
,
cap
uint32
,
width
uint32
)
(
ary
*
[]
any
);
func
arraysliced
(
old
*
[]
any
,
lb
uint32
,
hb
uint32
,
width
uint32
)
(
ary
*
[]
any
);
func
arrayslices
(
old
*
any
,
nel
uint32
,
lb
uint32
,
hb
uint32
,
width
uint32
)
(
ary
*
[]
any
);
func
arrays2d
(
old
*
any
,
nel
uint32
)
(
ary
*
[]
any
);
func
gosched
();
func
goexit
();
...
...
@@ -124,6 +129,12 @@ export
selectrecv
selectgo
// dynamic arrays
newarray
arraysliced
arrayslices
arrays2d
// go routines
gosched
goexit
...
...
src/cmd/gc/sysimport.c
View file @
66a603c9
This diff is collapsed.
Click to expand it.
src/cmd/gc/walk.c
View file @
66a603c9
...
...
@@ -429,17 +429,20 @@ loop:
}
}
if
(
t
->
etype
==
TARRAY
)
{
arrayconv
(
t
,
l
);
// convert dynamic to static generated by ONEW
if
(
isptrto
(
t
,
TARRAY
)
&&
isptrto
(
l
->
type
,
TDARRAY
))
goto
ret
;
}
// if(t->etype == TARRAY) {
// arrayconv(t, l);
// goto ret;
// }
r
=
isandss
(
n
->
type
,
l
);
if
(
r
!=
N
)
{
*
n
=
*
r
;
goto
ret
;
}
badtype
(
n
->
op
,
l
->
type
,
t
);
goto
ret
;
...
...
@@ -566,6 +569,28 @@ loop:
n
->
type
=
types
[
TINT32
];
goto
ret
;
case
OCAP
:
if
(
top
!=
Erv
)
goto
nottop
;
walktype
(
n
->
left
,
Erv
);
evconst
(
n
);
t
=
n
->
left
->
type
;
if
(
t
!=
T
&&
isptr
[
t
->
etype
])
t
=
t
->
type
;
if
(
t
==
T
)
goto
ret
;
switch
(
t
->
etype
)
{
default:
goto
badt
;
case
TDARRAY
:
break
;
case
TARRAY
:
nodconst
(
n
,
types
[
TINT32
],
t
->
bound
);
break
;
}
n
->
type
=
types
[
TINT32
];
goto
ret
;
case
OINDEX
:
case
OINDEXPTR
:
if
(
top
==
Etop
)
...
...
@@ -627,8 +652,8 @@ loop:
*
n
=
*
mapop
(
n
,
top
);
break
;
case
TARRAY
:
case
TDARRAY
:
case
TARRAY
:
// right side must be an int
if
(
n
->
right
->
type
==
T
)
{
convlit
(
n
->
right
,
types
[
TINT32
]);
...
...
@@ -672,10 +697,17 @@ loop:
walktype
(
n
->
right
,
Erv
);
if
(
n
->
left
==
N
||
n
->
right
==
N
)
goto
ret
;
if
(
isptrto
(
n
->
left
->
type
,
TSTRING
))
{
t
=
n
->
left
->
type
;
if
(
isptr
[
t
->
etype
])
t
=
t
->
type
;
if
(
t
->
etype
==
TSTRING
)
{
*
n
=
*
stringop
(
n
,
top
);
goto
ret
;
}
if
(
t
->
etype
==
TDARRAY
||
t
->
etype
==
TARRAY
)
{
*
n
=
*
arrayop
(
n
,
top
);
goto
ret
;
}
badtype
(
OSLICE
,
n
->
left
->
type
,
T
);
goto
ret
;
...
...
@@ -1403,6 +1435,9 @@ ascompat(Type *t1, Type *t2)
if
(
isptrto
(
t1
,
TSTRUCT
))
return
1
;
if
(
isptrto
(
t1
,
TDARRAY
))
if
(
isptrto
(
t2
,
TARRAY
))
return
1
;
return
0
;
}
...
...
@@ -1498,13 +1533,19 @@ newcompat(Node *n)
fatal
(
"newcompat: type should be pointer %lT"
,
t
);
t
=
t
->
type
;
if
(
t
->
etype
==
TMAP
)
{
switch
(
t
->
etype
)
{
case
TMAP
:
r
=
mapop
(
n
,
Erv
);
return
r
;
}
if
(
t
->
etype
==
TCHAN
)
{
case
TCHAN
:
r
=
chanop
(
n
,
Erv
);
return
r
;
case
TDARRAY
:
case
TARRAY
:
r
=
arrayop
(
n
,
Erv
);
return
r
;
}
if
(
n
->
left
!=
N
)
...
...
@@ -2082,6 +2123,168 @@ shape:
return
N
;
}
Type
*
fixarray
(
Type
*
tm
)
{
Type
*
t
;
t
=
tm
->
type
;
if
(
t
==
T
)
{
fatal
(
"fixarray: t nil"
);
return
T
;
}
if
(
t
->
etype
!=
TDARRAY
&&
t
->
etype
!=
TARRAY
)
{
fatal
(
"fixarray: %lT not array"
,
tm
);
return
T
;
}
if
(
t
->
type
==
T
)
{
fatal
(
"fixarray: array element type is nil"
);
return
T
;
}
dowidth
(
t
->
type
);
return
t
;
}
Node
*
arrayop
(
Node
*
n
,
int
top
)
{
Node
*
r
,
*
a
;
Type
*
t
;
Node
*
on
;
Iter
save
;
r
=
n
;
switch
(
n
->
op
)
{
default:
fatal
(
"darrayop: unknown op %O"
,
n
->
op
);
case
ONEW
:
// newarray(nel uint32, max uint32, width uint32) (ary *[]any)
t
=
fixarray
(
n
->
type
);
a
=
nodintconst
(
t
->
type
->
width
);
// width
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TUINT32
];
r
=
a
;
a
=
listfirst
(
&
save
,
&
n
->
left
);
// max
if
(
a
==
N
)
a
=
nodintconst
(
0
);
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TUINT32
];
r
=
list
(
a
,
r
);
a
=
t
->
dbound
;
// nel
if
(
a
==
N
)
a
=
nodintconst
(
t
->
bound
);
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TUINT32
];
r
=
list
(
a
,
r
);
on
=
syslook
(
"newarray"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
r
=
nod
(
OCALL
,
on
,
r
);
walktype
(
r
,
top
);
if
(
t
->
etype
==
TARRAY
)
{
// single case when we can convert a dynamic
// array pointer to a static array pointer
// saves making a sys function to alloc a static
r
=
nod
(
OCONV
,
r
,
N
);
r
->
type
=
ptrto
(
t
);
}
break
;
case
OAS
:
// arrays2d(old *any, nel uint32) (ary *[]any)
t
=
fixarray
(
n
->
right
->
type
);
a
=
nodintconst
(
t
->
bound
);
// nel
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TUINT32
];
r
=
a
;
a
=
n
->
right
;
// old
r
=
list
(
a
,
r
);
on
=
syslook
(
"arrays2d"
,
1
);
argtype
(
on
,
n
->
right
->
type
->
type
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
r
);
walktype
(
r
,
top
);
n
->
right
=
r
;
return
n
;
case
OSLICE
:
if
(
isptrto
(
n
->
left
->
type
,
TARRAY
))
goto
slicestatic
;
// arrayslices(old *[]any, lb uint32, hb uint32, width uint32) (ary *[]any)
t
=
fixarray
(
n
->
left
->
type
);
a
=
nodintconst
(
t
->
type
->
width
);
// width
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TUINT32
];
r
=
a
;
a
=
nod
(
OCONV
,
n
->
right
->
right
,
N
);
// hb
a
->
type
=
types
[
TUINT32
];
r
=
list
(
a
,
r
);
a
=
nod
(
OCONV
,
n
->
right
->
left
,
N
);
// lb
a
->
type
=
types
[
TINT32
];
r
=
list
(
a
,
r
);
a
=
n
->
left
;
// old
r
=
list
(
a
,
r
);
on
=
syslook
(
"arraysliced"
,
1
);
argtype
(
on
,
t
->
type
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
r
);
walktype
(
r
,
top
);
break
;
slicestatic:
// arrayslices(old *any, nel uint32, lb uint32, hb uint32, width uint32) (ary *[]any)
t
=
fixarray
(
n
->
left
->
type
);
a
=
nodintconst
(
t
->
type
->
width
);
// width
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TUINT32
];
r
=
a
;
a
=
nod
(
OCONV
,
n
->
right
->
right
,
N
);
// hb
a
->
type
=
types
[
TUINT32
];
r
=
list
(
a
,
r
);
a
=
nod
(
OCONV
,
n
->
right
->
left
,
N
);
// lb
a
->
type
=
types
[
TINT32
];
r
=
list
(
a
,
r
);
a
=
nodintconst
(
t
->
bound
);
// nel
a
=
nod
(
OCONV
,
a
,
N
);
a
->
type
=
types
[
TINT32
];
r
=
list
(
a
,
r
);
a
=
n
->
left
;
// old
r
=
list
(
a
,
r
);
on
=
syslook
(
"arrayslices"
,
1
);
argtype
(
on
,
t
);
// any-1
argtype
(
on
,
t
->
type
);
// any-2
r
=
nod
(
OCALL
,
on
,
r
);
walktype
(
r
,
top
);
break
;
}
return
r
;
}
void
diagnamed
(
Type
*
t
)
{
...
...
@@ -2178,37 +2381,48 @@ convas(Node *n)
return
n
;
}
if
(
isptrto
(
lt
,
TDARRAY
)
&&
isptrto
(
rt
,
TARRAY
))
{
if
(
!
eqtype
(
lt
->
type
->
type
,
rt
->
type
->
type
,
0
))
goto
bad
;
*
n
=
*
arrayop
(
n
,
Etop
);
return
n
;
}
if
(
ascompat
(
lt
,
rt
))
return
n
;
bad:
badtype
(
n
->
op
,
lt
,
rt
);
return
n
;
}
void
arrayconv
(
Type
*
t
,
Node
*
n
)
{
int
c
;
Iter
save
;
Node
*
l
;
l
=
listfirst
(
&
save
,
&
n
);
c
=
0
;
loop:
if
(
l
==
N
)
{
if
(
t
->
bound
==
0
)
t
->
bound
=
c
;
if
(
t
->
bound
==
0
||
t
->
bound
<
c
)
yyerror
(
"error with array convert bounds"
);
return
;
}
c
++
;
walktype
(
l
,
Erv
);
convlit
(
l
,
t
->
type
);
if
(
!
ascompat
(
l
->
type
,
t
->
type
))
badtype
(
OARRAY
,
l
->
type
,
t
->
type
);
l
=
listnext
(
&
save
);
goto
loop
;
}
//
void
//
arrayconv(Type *t, Node *n)
//
{
//
int c;
//
Iter save;
//
Node *l;
//
//
l = listfirst(&save, &n);
//
c = 0;
//
//
loop:
//
if(l == N) {
//
if(t->bound == 0)
//
t->bound = c;
//
if(t->bound == 0 || t->bound < c)
//
yyerror("error with array convert bounds");
//
return;
//
}
//
//
c++;
//
walktype(l, Erv);
//
convlit(l, t->type);
//
if(!ascompat(l->type, t->type))
//
badtype(OARRAY, l->type, t->type);
//
l = listnext(&save);
//
goto loop;
//
}
Node
*
old2new
(
Node
*
n
,
Type
*
t
)
...
...
src/runtime/Makefile
View file @
66a603c9
...
...
@@ -20,6 +20,7 @@ LIBOFILES=\
runtime.
$O
\
map.
$O
\
chan.
$O
\
array.
$O
\
print.
$O
\
rune.
$O
\
proc.
$O
\
...
...
src/runtime/array.c
0 → 100644
View file @
66a603c9
// 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 "runtime.h"
static
int32
debug
=
0
;
// newarray(nel uint32, cap uint32, width uint32) (ary *[]any);
void
sys
·
newarray
(
uint32
nel
,
uint32
cap
,
uint32
width
,
Array
*
ret
)
{
Array
*
d
;
uint64
size
;
if
(
cap
<
nel
)
cap
=
nel
;
size
=
cap
*
width
;
d
=
mal
(
sizeof
(
*
d
)
-
sizeof
(
d
->
b
)
+
size
);
d
->
nel
=
nel
;
d
->
cap
=
cap
;
d
->
array
=
d
->
b
;
ret
=
d
;
FLUSH
(
&
d
);
if
(
debug
)
{
prints
(
"newarray: nel="
);
sys
·
printint
(
nel
);
prints
(
"; cap="
);
sys
·
printint
(
cap
);
prints
(
"; width="
);
sys
·
printint
(
width
);
prints
(
"; ret="
);
sys
·
printpointer
(
ret
);
prints
(
"
\n
"
);
}
}
// arraysliced(old *[]any, lb uint32, hb uint32, width uint32) (ary *[]any);
void
sys
·
arraysliced
(
Array
*
old
,
uint32
lb
,
uint32
hb
,
uint32
width
,
Array
*
ret
)
{
Array
*
d
;
if
(
hb
>
old
->
cap
||
lb
>
hb
)
{
if
(
debug
)
{
prints
(
"sys·arrayslices: old="
);
sys
·
printpointer
(
old
);
prints
(
"; lb="
);
sys
·
printint
(
lb
);
prints
(
"; hb="
);
sys
·
printint
(
hb
);
prints
(
"; width="
);
sys
·
printint
(
width
);
prints
(
"
\n
"
);
prints
(
"oldarray: nel="
);
sys
·
printint
(
old
->
nel
);
prints
(
"; cap="
);
sys
·
printint
(
old
->
cap
);
prints
(
"
\n
"
);
}
throw
(
"sys·arraysliced: new size exceeds old size"
);
}
// new array is inside old array
d
=
mal
(
sizeof
(
*
d
)
-
sizeof
(
d
->
b
));
d
->
nel
=
hb
-
lb
;
d
->
cap
=
old
->
cap
-
lb
;
d
->
array
=
old
->
array
+
lb
*
width
;
ret
=
d
;
FLUSH
(
&
d
);
if
(
debug
)
{
prints
(
"sys·arrayslices: old="
);
sys
·
printpointer
(
old
);
prints
(
"; lb="
);
sys
·
printint
(
lb
);
prints
(
"; hb="
);
sys
·
printint
(
hb
);
prints
(
"; width="
);
sys
·
printint
(
width
);
prints
(
"; ret="
);
sys
·
printpointer
(
ret
);
prints
(
"
\n
"
);
}
}
// arrayslices(old *any, nel uint32, lb uint32, hb uint32, width uint32) (ary *[]any);
void
sys
·
arrayslices
(
byte
*
old
,
uint32
nel
,
uint32
lb
,
uint32
hb
,
uint32
width
,
Array
*
ret
)
{
Array
*
d
;
if
(
hb
>
nel
||
lb
>
hb
)
{
if
(
debug
)
{
prints
(
"sys·arrayslices: old="
);
sys
·
printpointer
(
old
);
prints
(
"; nel="
);
sys
·
printint
(
nel
);
prints
(
"; lb="
);
sys
·
printint
(
lb
);
prints
(
"; hb="
);
sys
·
printint
(
hb
);
prints
(
"; width="
);
sys
·
printint
(
width
);
prints
(
"
\n
"
);
}
throw
(
"sys·arrayslices: new size exceeds cap"
);
}
// new array is inside old array
d
=
mal
(
sizeof
(
*
d
)
-
sizeof
(
d
->
b
));
d
->
nel
=
hb
-
lb
;
d
->
cap
=
nel
-
lb
;
d
->
array
=
old
+
lb
*
width
;
ret
=
d
;
FLUSH
(
&
d
);
if
(
debug
)
{
prints
(
"sys·arrayslices: old="
);
sys
·
printpointer
(
old
);
prints
(
"; nel="
);
sys
·
printint
(
nel
);
prints
(
"; lb="
);
sys
·
printint
(
lb
);
prints
(
"; hb="
);
sys
·
printint
(
hb
);
prints
(
"; width="
);
sys
·
printint
(
width
);
prints
(
"; ret="
);
sys
·
printpointer
(
ret
);
prints
(
"
\n
"
);
}
}
// arrays2d(old *any, nel uint32) (ary *[]any)
void
sys
·
arrays2d
(
byte
*
old
,
uint32
nel
,
Array
*
ret
)
{
Array
*
d
;
// new dope to old array
d
=
mal
(
sizeof
(
*
d
)
-
sizeof
(
d
->
b
));
d
->
nel
=
nel
;
d
->
cap
=
nel
;
d
->
array
=
old
;
ret
=
d
;
FLUSH
(
&
d
);
if
(
debug
)
{
prints
(
"sys·arrays2d: old="
);
sys
·
printpointer
(
old
);
prints
(
"; nel="
);
sys
·
printint
(
nel
);
prints
(
"; ret="
);
sys
·
printpointer
(
ret
);
prints
(
"
\n
"
);
}
}
src/runtime/runtime.h
View file @
66a603c9
...
...
@@ -37,6 +37,7 @@ typedef struct String *string;
typedef
struct
Sigs
Sigs
;
typedef
struct
Sigi
Sigi
;
typedef
struct
Map
Map
;
typedef
struct
Array
Array
;
typedef
struct
Gobuf
Gobuf
;
typedef
struct
G
G
;
typedef
struct
M
M
;
...
...
@@ -99,6 +100,14 @@ struct Sigi
uint32
hash
;
uint32
offset
;
};
struct
Array
{
// must not move anything
byte
*
array
;
// actual data
uint32
nel
;
// number of elements
uint32
cap
;
// allocate3d number of elements
byte
b
[
8
];
// actual array - may not be contig
};
struct
Map
{
Sigi
*
si
;
...
...
test/chan/powser1.go
View file @
66a603c9
...
...
@@ -325,7 +325,7 @@ func Split(U PS) *dch2{
func
Add
(
U
,
V
PS
)
PS
{
Z
:=
mkPS
();
go
func
(
U
,
V
,
Z
PS
){
var
uv
*
[
2
]
*
rat
;
var
uv
*
[]
*
rat
;
for
{
<-
Z
.
req
;
uv
=
get2
(
U
,
V
);
...
...
@@ -419,9 +419,9 @@ func Shift(c *rat, U PS) PS{
// Convert array of coefficients, constant term first
// to a (finite) power series
/* BUG: NEED LEN OF ARRAY
func Poly(a [] *rat) PS{
Z:=mkPS();
/* BUG: NEED LEN OF ARRAY
begin func(a [] *rat, Z PS){
j:=0;
done:=0;
...
...
@@ -431,9 +431,9 @@ func Poly(a [] *rat) PS{
for(; i<j; i=i+1) put(a[i],Z);
put(finis,Z);
}();
*/
return Z;
}
*/
// Multiply. The algorithm is
// let U = u + x*UU
...
...
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