Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
d8b5d039
Commit
d8b5d039
authored
Oct 27, 2010
by
Russ Cox
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
gc: implement append
R=ken2 CC=golang-dev
https://golang.org/cl/2757042
parent
b803a255
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
169 additions
and
12 deletions
+169
-12
src/cmd/gc/builtin.c.boot
src/cmd/gc/builtin.c.boot
+2
-0
src/cmd/gc/go.h
src/cmd/gc/go.h
+3
-0
src/cmd/gc/lex.c
src/cmd/gc/lex.c
+1
-0
src/cmd/gc/print.c
src/cmd/gc/print.c
+2
-0
src/cmd/gc/runtime.go
src/cmd/gc/runtime.go
+4
-0
src/cmd/gc/subr.c
src/cmd/gc/subr.c
+1
-0
src/cmd/gc/typecheck.c
src/cmd/gc/typecheck.c
+35
-1
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+46
-0
src/pkg/runtime/slice.c
src/pkg/runtime/slice.c
+75
-11
No files found.
src/cmd/gc/builtin.c.boot
View file @
d8b5d039
...
...
@@ -21,6 +21,8 @@ char *runtimeimport =
"func \"\".printsp ()\n"
"func \"\".printf ()\n"
"func \"\".concatstring ()\n"
"func \"\".append ()\n"
"func \"\".appendslice (typ *uint8, x any, y []any) any\n"
"func \"\".cmpstring (? string, ? string) int\n"
"func \"\".slicestring (? string, ? int, ? int) string\n"
"func \"\".slicestring1 (? string, ? int) string\n"
...
...
src/cmd/gc/go.h
View file @
d8b5d039
...
...
@@ -6,6 +6,8 @@
#include <libc.h>
#include <bio.h>
#undef OAPPEND
// avoid <ctype.h>
#undef isblank
#define isblank goisblank
...
...
@@ -349,6 +351,7 @@ enum
OADD
,
OSUB
,
OOR
,
OXOR
,
OADDSTR
,
OADDR
,
OANDAND
,
OAPPEND
,
OARRAY
,
OARRAYBYTESTR
,
OARRAYRUNESTR
,
OSTRARRAYBYTE
,
OSTRARRAYRUNE
,
...
...
src/cmd/gc/lex.c
View file @
d8b5d039
...
...
@@ -1531,6 +1531,7 @@ static struct
"type"
,
LTYPE
,
Txxx
,
OXXX
,
"var"
,
LVAR
,
Txxx
,
OXXX
,
"append"
,
LNAME
,
Txxx
,
OAPPEND
,
"cap"
,
LNAME
,
Txxx
,
OCAP
,
"close"
,
LNAME
,
Txxx
,
OCLOSE
,
"closed"
,
LNAME
,
Txxx
,
OCLOSED
,
...
...
src/cmd/gc/print.c
View file @
d8b5d039
...
...
@@ -37,6 +37,7 @@ exprfmt(Fmt *f, Node *n, int prec)
}
switch
(
n
->
op
)
{
case
OAPPEND
:
case
ONAME
:
case
ONONAME
:
case
OPACK
:
...
...
@@ -400,6 +401,7 @@ exprfmt(Fmt *f, Node *n, int prec)
fmtprint
(
f
,
")"
);
break
;
case
OAPPEND
:
case
OCAP
:
case
OCLOSE
:
case
OCLOSED
:
...
...
src/cmd/gc/runtime.go
View file @
d8b5d039
...
...
@@ -36,6 +36,10 @@ func printf()
// filled in by compiler: int n, string, string, ...
func
concatstring
()
// filled in by compiler: Type*, int n, Slice, ...
func
append
()
func
appendslice
(
typ
*
byte
,
x
any
,
y
[]
any
)
any
func
cmpstring
(
string
,
string
)
int
func
slicestring
(
string
,
int
,
int
)
string
func
slicestring1
(
string
,
int
)
string
...
...
src/cmd/gc/subr.c
View file @
d8b5d039
...
...
@@ -810,6 +810,7 @@ goopnames[] =
[
OANDAND
]
=
"&&"
,
[
OANDNOT
]
=
"&^"
,
[
OAND
]
=
"&"
,
[
OAPPEND
]
=
"append"
,
[
OAS
]
=
"="
,
[
OAS2
]
=
"="
,
[
OBREAK
]
=
"break"
,
...
...
src/cmd/gc/typecheck.c
View file @
d8b5d039
...
...
@@ -730,7 +730,7 @@ reswitch:
typecheck
(
&
n
->
left
,
Erv
|
Etype
|
Ecall
);
l
=
n
->
left
;
if
(
l
->
op
==
ONAME
&&
l
->
etype
!=
0
)
{
if
(
n
->
isddd
)
if
(
n
->
isddd
&&
l
->
etype
!=
OAPPEND
)
yyerror
(
"invalid use of ... with builtin %#N"
,
l
);
// builtin: OLEN, OCAP, etc.
n
->
op
=
l
->
etype
;
...
...
@@ -905,6 +905,40 @@ reswitch:
ok
|=
Etop
;
goto
ret
;
case
OAPPEND
:
ok
|=
Erv
;
args
=
n
->
list
;
if
(
args
==
nil
)
{
yyerror
(
"missing arguments to append"
);
goto
error
;
}
typechecklist
(
args
,
Erv
);
if
((
t
=
args
->
n
->
type
)
==
T
)
goto
error
;
n
->
type
=
t
;
if
(
!
isslice
(
t
))
{
yyerror
(
"first argument to append must be slice; have %lT"
,
t
);
goto
error
;
}
if
(
n
->
isddd
)
{
if
(
args
->
next
==
nil
)
{
yyerror
(
"cannot use ... on first argument to append"
);
goto
error
;
}
if
(
args
->
next
->
next
!=
nil
)
{
yyerror
(
"too many arguments to append"
);
goto
error
;
}
args
->
next
->
n
=
assignconv
(
args
->
next
->
n
,
t
->
orig
,
"append"
);
goto
ret
;
}
for
(
args
=
args
->
next
;
args
!=
nil
;
args
=
args
->
next
)
{
if
(
args
->
n
->
type
==
T
)
continue
;
args
->
n
=
assignconv
(
args
->
n
,
t
->
type
,
"append"
);
}
goto
ret
;
case
OCOPY
:
ok
|=
Etop
|
Erv
;
args
=
n
->
list
;
...
...
src/cmd/gc/walk.c
View file @
d8b5d039
...
...
@@ -18,6 +18,7 @@ static NodeList* paramstoheap(Type **argin, int out);
static
NodeList
*
reorder1
(
NodeList
*
);
static
NodeList
*
reorder3
(
NodeList
*
);
static
Node
*
addstr
(
Node
*
,
NodeList
**
);
static
Node
*
append
(
Node
*
,
NodeList
**
);
static
NodeList
*
walkdefstack
;
...
...
@@ -1264,6 +1265,10 @@ walkexpr(Node **np, NodeList **init)
l
);
}
goto
ret
;
case
OAPPEND
:
n
=
append
(
n
,
init
);
goto
ret
;
case
OCOPY
:
if
(
n
->
right
->
type
->
etype
==
TSTRING
)
...
...
@@ -2304,3 +2309,44 @@ addstr(Node *n, NodeList **init)
return
r
;
}
static
Node
*
append
(
Node
*
n
,
NodeList
**
init
)
{
int
i
,
j
;
Node
*
f
,
*
r
;
NodeList
*
in
,
*
args
;
if
(
n
->
isddd
)
{
f
=
syslook
(
"appendslice"
,
1
);
argtype
(
f
,
n
->
type
);
argtype
(
f
,
n
->
type
->
type
);
argtype
(
f
,
n
->
type
);
r
=
mkcall1
(
f
,
n
->
type
,
init
,
typename
(
n
->
type
),
n
->
list
->
n
,
n
->
list
->
next
->
n
);
return
r
;
}
j
=
count
(
n
->
list
)
-
1
;
f
=
syslook
(
"append"
,
1
);
f
->
type
=
T
;
f
->
ntype
=
nod
(
OTFUNC
,
N
,
N
);
in
=
list1
(
nod
(
ODCLFIELD
,
N
,
typenod
(
ptrto
(
types
[
TUINT8
]))));
// type
in
=
list
(
in
,
nod
(
ODCLFIELD
,
N
,
typenod
(
types
[
TINT
])));
// count
in
=
list
(
in
,
nod
(
ODCLFIELD
,
N
,
typenod
(
n
->
type
)));
// slice
for
(
i
=
0
;
i
<
j
;
i
++
)
in
=
list
(
in
,
nod
(
ODCLFIELD
,
N
,
typenod
(
n
->
type
->
type
)));
f
->
ntype
->
list
=
in
;
f
->
ntype
->
rlist
=
list1
(
nod
(
ODCLFIELD
,
N
,
typenod
(
n
->
type
)));
args
=
list1
(
typename
(
n
->
type
));
args
=
list
(
args
,
nodintconst
(
j
));
args
=
concat
(
args
,
n
->
list
);
r
=
nod
(
OCALL
,
f
,
N
);
r
->
list
=
args
;
typecheck
(
&
r
,
Erv
);
walkexpr
(
&
r
,
init
);
r
->
type
=
n
->
type
;
return
r
;
}
src/pkg/runtime/slice.c
View file @
d8b5d039
...
...
@@ -8,37 +8,101 @@
static
int32
debug
=
0
;
static
void
makeslice
(
SliceType
*
,
int32
,
int32
,
Slice
*
);
void
·
slicecopy
(
Slice
to
,
Slice
fm
,
uintptr
width
,
int32
ret
);
// see also unsafe·NewArray
// makeslice(typ *Type, len, cap int64) (ary []any);
void
·
makeslice
(
SliceType
*
t
,
int64
len
,
int64
cap
,
Slice
ret
)
{
uintptr
size
;
if
(
len
<
0
||
(
int32
)
len
!=
len
)
panicstring
(
"makeslice: len out of range"
);
if
(
cap
<
len
||
(
int32
)
cap
!=
cap
||
cap
>
((
uintptr
)
-
1
)
/
t
->
elem
->
size
)
panicstring
(
"makeslice: cap out of range"
);
makeslice
(
t
,
len
,
cap
,
&
ret
);
if
(
debug
)
{
printf
(
"makeslice(%S, %D, %D); ret="
,
*
t
->
string
,
len
,
cap
);
·
printslice
(
ret
);
}
}
static
void
makeslice
(
SliceType
*
t
,
int32
len
,
int32
cap
,
Slice
*
ret
)
{
uintptr
size
;
size
=
cap
*
t
->
elem
->
size
;
ret
.
len
=
len
;
ret
.
cap
=
cap
;
ret
->
len
=
len
;
ret
->
cap
=
cap
;
if
((
t
->
elem
->
kind
&
KindNoPointers
))
ret
.
array
=
mallocgc
(
size
,
RefNoPointers
,
1
,
1
);
ret
->
array
=
mallocgc
(
size
,
RefNoPointers
,
1
,
1
);
else
ret
.
array
=
mal
(
size
);
ret
->
array
=
mal
(
size
);
}
FLUSH
(
&
ret
);
static
void
appendslice
(
SliceType
*
,
Slice
,
Slice
,
Slice
*
);
if
(
debug
)
{
printf
(
"makeslice(%S, %D, %D); ret="
,
*
t
->
string
,
len
,
cap
);
·
printslice
(
ret
);
// append(type *Type, n int, old []T, ...,) []T
#pragma textflag 7
void
·
append
(
SliceType
*
t
,
int32
n
,
Slice
old
,
...)
{
Slice
sl
;
Slice
*
ret
;
sl
.
len
=
n
;
sl
.
array
=
(
byte
*
)(
&
old
+
1
);
ret
=
(
Slice
*
)(
sl
.
array
+
((
t
->
elem
->
size
*
n
+
sizeof
(
uintptr
)
-
1
)
&
~
(
sizeof
(
uintptr
)
-
1
)));
appendslice
(
t
,
old
,
sl
,
ret
);
}
// appendslice(type *Type, x, y, []T) []T
void
·
appendslice
(
SliceType
*
t
,
Slice
x
,
Slice
y
,
Slice
ret
)
{
appendslice
(
t
,
x
,
y
,
&
ret
);
}
static
void
appendslice
(
SliceType
*
t
,
Slice
x
,
Slice
y
,
Slice
*
ret
)
{
Slice
newx
;
int32
m
;
uintptr
w
;
if
(
x
.
len
+
y
.
len
<
x
.
len
)
throw
(
"append: slice overflow"
);
w
=
t
->
elem
->
size
;
if
(
x
.
len
+
y
.
len
>
x
.
cap
)
{
m
=
x
.
cap
;
if
(
m
==
0
)
m
=
y
.
len
;
else
{
do
{
if
(
x
.
len
<
1024
)
m
+=
m
;
else
m
+=
m
/
4
;
}
while
(
m
<
x
.
len
+
y
.
len
);
}
makeslice
(
t
,
x
.
len
,
m
,
&
newx
);
memmove
(
newx
.
array
,
x
.
array
,
x
.
len
*
w
);
x
=
newx
;
}
memmove
(
x
.
array
+
x
.
len
*
w
,
y
.
array
,
y
.
len
*
w
);
x
.
len
+=
y
.
len
;
*
ret
=
x
;
}
// sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any);
void
·
sliceslice
(
Slice
old
,
uint64
lb
,
uint64
hb
,
uint64
width
,
Slice
ret
)
...
...
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