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
14 years ago
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
Show 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 =
...
@@ -21,6 +21,8 @@ char *runtimeimport =
"func \"\".printsp ()\n"
"func \"\".printsp ()\n"
"func \"\".printf ()\n"
"func \"\".printf ()\n"
"func \"\".concatstring ()\n"
"func \"\".concatstring ()\n"
"func \"\".append ()\n"
"func \"\".appendslice (typ *uint8, x any, y []any) any\n"
"func \"\".cmpstring (? string, ? string) int\n"
"func \"\".cmpstring (? string, ? string) int\n"
"func \"\".slicestring (? string, ? int, ? int) string\n"
"func \"\".slicestring (? string, ? int, ? int) string\n"
"func \"\".slicestring1 (? string, ? int) string\n"
"func \"\".slicestring1 (? string, ? int) string\n"
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/go.h
View file @
d8b5d039
...
@@ -6,6 +6,8 @@
...
@@ -6,6 +6,8 @@
#include <libc.h>
#include <libc.h>
#include <bio.h>
#include <bio.h>
#undef OAPPEND
// avoid <ctype.h>
// avoid <ctype.h>
#undef isblank
#undef isblank
#define isblank goisblank
#define isblank goisblank
...
@@ -349,6 +351,7 @@ enum
...
@@ -349,6 +351,7 @@ enum
OADD
,
OSUB
,
OOR
,
OXOR
,
OADDSTR
,
OADD
,
OSUB
,
OOR
,
OXOR
,
OADDSTR
,
OADDR
,
OADDR
,
OANDAND
,
OANDAND
,
OAPPEND
,
OARRAY
,
OARRAY
,
OARRAYBYTESTR
,
OARRAYRUNESTR
,
OARRAYBYTESTR
,
OARRAYRUNESTR
,
OSTRARRAYBYTE
,
OSTRARRAYRUNE
,
OSTRARRAYBYTE
,
OSTRARRAYRUNE
,
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/lex.c
View file @
d8b5d039
...
@@ -1531,6 +1531,7 @@ static struct
...
@@ -1531,6 +1531,7 @@ static struct
"type"
,
LTYPE
,
Txxx
,
OXXX
,
"type"
,
LTYPE
,
Txxx
,
OXXX
,
"var"
,
LVAR
,
Txxx
,
OXXX
,
"var"
,
LVAR
,
Txxx
,
OXXX
,
"append"
,
LNAME
,
Txxx
,
OAPPEND
,
"cap"
,
LNAME
,
Txxx
,
OCAP
,
"cap"
,
LNAME
,
Txxx
,
OCAP
,
"close"
,
LNAME
,
Txxx
,
OCLOSE
,
"close"
,
LNAME
,
Txxx
,
OCLOSE
,
"closed"
,
LNAME
,
Txxx
,
OCLOSED
,
"closed"
,
LNAME
,
Txxx
,
OCLOSED
,
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/print.c
View file @
d8b5d039
...
@@ -37,6 +37,7 @@ exprfmt(Fmt *f, Node *n, int prec)
...
@@ -37,6 +37,7 @@ exprfmt(Fmt *f, Node *n, int prec)
}
}
switch
(
n
->
op
)
{
switch
(
n
->
op
)
{
case
OAPPEND
:
case
ONAME
:
case
ONAME
:
case
ONONAME
:
case
ONONAME
:
case
OPACK
:
case
OPACK
:
...
@@ -400,6 +401,7 @@ exprfmt(Fmt *f, Node *n, int prec)
...
@@ -400,6 +401,7 @@ exprfmt(Fmt *f, Node *n, int prec)
fmtprint
(
f
,
")"
);
fmtprint
(
f
,
")"
);
break
;
break
;
case
OAPPEND
:
case
OCAP
:
case
OCAP
:
case
OCLOSE
:
case
OCLOSE
:
case
OCLOSED
:
case
OCLOSED
:
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/runtime.go
View file @
d8b5d039
...
@@ -36,6 +36,10 @@ func printf()
...
@@ -36,6 +36,10 @@ func printf()
// filled in by compiler: int n, string, string, ...
// filled in by compiler: int n, string, string, ...
func
concatstring
()
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
cmpstring
(
string
,
string
)
int
func
slicestring
(
string
,
int
,
int
)
string
func
slicestring
(
string
,
int
,
int
)
string
func
slicestring1
(
string
,
int
)
string
func
slicestring1
(
string
,
int
)
string
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/subr.c
View file @
d8b5d039
...
@@ -810,6 +810,7 @@ goopnames[] =
...
@@ -810,6 +810,7 @@ goopnames[] =
[
OANDAND
]
=
"&&"
,
[
OANDAND
]
=
"&&"
,
[
OANDNOT
]
=
"&^"
,
[
OANDNOT
]
=
"&^"
,
[
OAND
]
=
"&"
,
[
OAND
]
=
"&"
,
[
OAPPEND
]
=
"append"
,
[
OAS
]
=
"="
,
[
OAS
]
=
"="
,
[
OAS2
]
=
"="
,
[
OAS2
]
=
"="
,
[
OBREAK
]
=
"break"
,
[
OBREAK
]
=
"break"
,
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/typecheck.c
View file @
d8b5d039
...
@@ -730,7 +730,7 @@ reswitch:
...
@@ -730,7 +730,7 @@ reswitch:
typecheck
(
&
n
->
left
,
Erv
|
Etype
|
Ecall
);
typecheck
(
&
n
->
left
,
Erv
|
Etype
|
Ecall
);
l
=
n
->
left
;
l
=
n
->
left
;
if
(
l
->
op
==
ONAME
&&
l
->
etype
!=
0
)
{
if
(
l
->
op
==
ONAME
&&
l
->
etype
!=
0
)
{
if
(
n
->
isddd
)
if
(
n
->
isddd
&&
l
->
etype
!=
OAPPEND
)
yyerror
(
"invalid use of ... with builtin %#N"
,
l
);
yyerror
(
"invalid use of ... with builtin %#N"
,
l
);
// builtin: OLEN, OCAP, etc.
// builtin: OLEN, OCAP, etc.
n
->
op
=
l
->
etype
;
n
->
op
=
l
->
etype
;
...
@@ -905,6 +905,40 @@ reswitch:
...
@@ -905,6 +905,40 @@ reswitch:
ok
|=
Etop
;
ok
|=
Etop
;
goto
ret
;
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
:
case
OCOPY
:
ok
|=
Etop
|
Erv
;
ok
|=
Etop
|
Erv
;
args
=
n
->
list
;
args
=
n
->
list
;
...
...
This diff is collapsed.
Click to expand it.
src/cmd/gc/walk.c
View file @
d8b5d039
...
@@ -18,6 +18,7 @@ static NodeList* paramstoheap(Type **argin, int out);
...
@@ -18,6 +18,7 @@ static NodeList* paramstoheap(Type **argin, int out);
static
NodeList
*
reorder1
(
NodeList
*
);
static
NodeList
*
reorder1
(
NodeList
*
);
static
NodeList
*
reorder3
(
NodeList
*
);
static
NodeList
*
reorder3
(
NodeList
*
);
static
Node
*
addstr
(
Node
*
,
NodeList
**
);
static
Node
*
addstr
(
Node
*
,
NodeList
**
);
static
Node
*
append
(
Node
*
,
NodeList
**
);
static
NodeList
*
walkdefstack
;
static
NodeList
*
walkdefstack
;
...
@@ -1265,6 +1266,10 @@ walkexpr(Node **np, NodeList **init)
...
@@ -1265,6 +1266,10 @@ walkexpr(Node **np, NodeList **init)
}
}
goto
ret
;
goto
ret
;
case
OAPPEND
:
n
=
append
(
n
,
init
);
goto
ret
;
case
OCOPY
:
case
OCOPY
:
if
(
n
->
right
->
type
->
etype
==
TSTRING
)
if
(
n
->
right
->
type
->
etype
==
TSTRING
)
fn
=
syslook
(
"slicestringcopy"
,
1
);
fn
=
syslook
(
"slicestringcopy"
,
1
);
...
@@ -2304,3 +2309,44 @@ addstr(Node *n, NodeList **init)
...
@@ -2304,3 +2309,44 @@ addstr(Node *n, NodeList **init)
return
r
;
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
;
}
This diff is collapsed.
Click to expand it.
src/pkg/runtime/slice.c
View file @
d8b5d039
...
@@ -8,37 +8,101 @@
...
@@ -8,37 +8,101 @@
static
int32
debug
=
0
;
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
// see also unsafe·NewArray
// makeslice(typ *Type, len, cap int64) (ary []any);
// makeslice(typ *Type, len, cap int64) (ary []any);
void
void
·
makeslice
(
SliceType
*
t
,
int64
len
,
int64
cap
,
Slice
ret
)
·
makeslice
(
SliceType
*
t
,
int64
len
,
int64
cap
,
Slice
ret
)
{
{
uintptr
size
;
if
(
len
<
0
||
(
int32
)
len
!=
len
)
if
(
len
<
0
||
(
int32
)
len
!=
len
)
panicstring
(
"makeslice: len out of range"
);
panicstring
(
"makeslice: len out of range"
);
if
(
cap
<
len
||
(
int32
)
cap
!=
cap
||
cap
>
((
uintptr
)
-
1
)
/
t
->
elem
->
size
)
if
(
cap
<
len
||
(
int32
)
cap
!=
cap
||
cap
>
((
uintptr
)
-
1
)
/
t
->
elem
->
size
)
panicstring
(
"makeslice: cap out of range"
);
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
;
size
=
cap
*
t
->
elem
->
size
;
ret
.
len
=
len
;
ret
->
len
=
len
;
ret
.
cap
=
cap
;
ret
->
cap
=
cap
;
if
((
t
->
elem
->
kind
&
KindNoPointers
))
if
((
t
->
elem
->
kind
&
KindNoPointers
))
ret
.
array
=
mallocgc
(
size
,
RefNoPointers
,
1
,
1
);
ret
->
array
=
mallocgc
(
size
,
RefNoPointers
,
1
,
1
);
else
else
ret
.
array
=
mal
(
size
);
ret
->
array
=
mal
(
size
);
}
FLUSH
(
&
ret
);
static
void
appendslice
(
SliceType
*
,
Slice
,
Slice
,
Slice
*
);
if
(
debug
)
{
// append(type *Type, n int, old []T, ...,) []T
printf
(
"makeslice(%S, %D, %D); ret="
,
#pragma textflag 7
*
t
->
string
,
len
,
cap
);
void
·
printslice
(
ret
);
·
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);
// sliceslice(old []any, lb uint64, hb uint64, width uint64) (ary []any);
void
void
·
sliceslice
(
Slice
old
,
uint64
lb
,
uint64
hb
,
uint64
width
,
Slice
ret
)
·
sliceslice
(
Slice
old
,
uint64
lb
,
uint64
hb
,
uint64
width
,
Slice
ret
)
...
...
This diff is collapsed.
Click to expand it.
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