summaryrefslogtreecommitdiff
path: root/src/cmd/gc
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/gc')
-rw-r--r--src/cmd/gc/builtin.c.boot1
-rw-r--r--src/cmd/gc/go.h1
-rw-r--r--src/cmd/gc/lex.c1
-rw-r--r--src/cmd/gc/print.c2
-rw-r--r--src/cmd/gc/runtime.go1
-rw-r--r--src/cmd/gc/subr.c1
-rw-r--r--src/cmd/gc/typecheck.c26
-rw-r--r--src/cmd/gc/walk.c13
8 files changed, 45 insertions, 1 deletions
diff --git a/src/cmd/gc/builtin.c.boot b/src/cmd/gc/builtin.c.boot
index fc8a6d1f6..8b794efdb 100644
--- a/src/cmd/gc/builtin.c.boot
+++ b/src/cmd/gc/builtin.c.boot
@@ -25,6 +25,7 @@ char *runtimeimport =
"func runtime.sliceinttostring (? []int) (? string)\n"
"func runtime.stringiter (? string, ? int) (? int)\n"
"func runtime.stringiter2 (? string, ? int) (retk int, retv int)\n"
+ "func runtime.slicecopy (to any, fr any, wid uint32) (? int)\n"
"func runtime.ifaceI2E (iface any) (ret any)\n"
"func runtime.ifaceE2I (typ *uint8, iface any) (ret any)\n"
"func runtime.ifaceT2E (typ *uint8, elem any) (ret any)\n"
diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h
index f5b88ff59..7702efbf7 100644
--- a/src/cmd/gc/go.h
+++ b/src/cmd/gc/go.h
@@ -346,6 +346,7 @@ enum
OCMPIFACE, OCMPSTR,
OCOMPLIT, OMAPLIT, OSTRUCTLIT, OARRAYLIT,
OCONV, OCONVNOP, OCONVIFACE, OCONVSLICE,
+ OCOPY,
ODCL, ODCLFUNC, ODCLFIELD, ODCLCONST, ODCLTYPE,
ODOT, ODOTPTR, ODOTMETH, ODOTINTER, OXDOT,
ODOTTYPE,
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c
index 14500dc75..f858aa95e 100644
--- a/src/cmd/gc/lex.c
+++ b/src/cmd/gc/lex.c
@@ -1245,6 +1245,7 @@ static struct
"cap", LNAME, Txxx, OCAP,
"close", LNAME, Txxx, OCLOSE,
"closed", LNAME, Txxx, OCLOSED,
+ "copy", LNAME, Txxx, OCOPY,
"len", LNAME, Txxx, OLEN,
"make", LNAME, Txxx, OMAKE,
"new", LNAME, Txxx, ONEW,
diff --git a/src/cmd/gc/print.c b/src/cmd/gc/print.c
index ce4f721ae..bbb7b0fbd 100644
--- a/src/cmd/gc/print.c
+++ b/src/cmd/gc/print.c
@@ -44,6 +44,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case OCAP:
case OCLOSE:
case OCLOSED:
+ case OCOPY:
case OLEN:
case OMAKE:
case ONEW:
@@ -305,6 +306,7 @@ exprfmt(Fmt *f, Node *n, int prec)
case OCLOSE:
case OCLOSED:
case OLEN:
+ case OCOPY:
case OMAKE:
case ONEW:
case OPANIC:
diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go
index 5e3632920..1f078f2da 100644
--- a/src/cmd/gc/runtime.go
+++ b/src/cmd/gc/runtime.go
@@ -33,6 +33,7 @@ func slicebytetostring([]byte) string
func sliceinttostring([]int) string
func stringiter(string, int) int
func stringiter2(string, int) (retk int, retv int)
+func slicecopy(to any, fr any, wid uint32) int
func ifaceI2E(iface any) (ret any)
func ifaceE2I(typ *byte, iface any) (ret any)
diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c
index 75ece477d..22e59c5c8 100644
--- a/src/cmd/gc/subr.c
+++ b/src/cmd/gc/subr.c
@@ -746,6 +746,7 @@ goopnames[] =
[OCLOSE] = "close",
[OCOM] = "^",
[OCONTINUE] = "continue",
+ [OCOPY] = "copy",
[ODEC] = "--",
[ODEFER] = "defer",
[ODIV] = "/",
diff --git a/src/cmd/gc/typecheck.c b/src/cmd/gc/typecheck.c
index 108a2d3e9..86633b86d 100644
--- a/src/cmd/gc/typecheck.c
+++ b/src/cmd/gc/typecheck.c
@@ -761,6 +761,32 @@ reswitch:
ok |= Etop;
goto ret;
+ case OCOPY:
+ ok |= Erv;
+ args = n->list;
+ if(args == nil || args->next == nil) {
+ yyerror("missing arguments to copy");
+ goto error;
+ }
+ if(args->next->next != nil) {
+ yyerror("too many arguments to copy");
+ goto error;
+ }
+ typecheck(&args->n, Erv);
+ typecheck(&args->next->n, Erv);
+ if(!isslice(args->n->type) || !isslice(args->next->n->type)) {
+ yyerror("arguments to copy must be slices");
+ goto error;
+ }
+ if(!eqtype(args->n->type, args->next->n->type)) {
+ yyerror("arguments to copy must be slices of the same type");
+ goto error;
+ }
+ n->left = args->n;
+ n->right = args->next->n;
+ n->type = types[TINT];
+ goto ret;
+
case OCONV:
doconv:
ok |= Erv;
diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c
index 6aa23783f..bb100b971 100644
--- a/src/cmd/gc/walk.c
+++ b/src/cmd/gc/walk.c
@@ -307,6 +307,7 @@ walkstmt(Node **np)
case OAS2MAPR:
case OCLOSE:
case OCLOSED:
+ case OCOPY:
case OCALLMETH:
case OCALLINTER:
case OCALL:
@@ -904,6 +905,15 @@ walkexpr(Node **np, NodeList **init)
conv(n->right, types[TINT]));
goto ret;
+ case OCOPY:
+ fn = syslook("slicecopy", 1);
+ argtype(fn, n->left->type);
+ argtype(fn, n->right->type);
+ n = mkcall1(fn, n->type, init,
+ n->left, n->right,
+ nodintconst(n->left->type->width));
+ goto ret;
+
case OCLOSE:
// cannot use chanfn - closechan takes any, not chan any
fn = syslook("closechan", 1);
@@ -950,7 +960,8 @@ walkexpr(Node **np, NodeList **init)
case ORUNESTR:
// sys_intstring(v)
- n = mkcall("intstring", n->type, init, conv(n->left, types[TINT64])); // TODO(rsc): int64?!
+ n = mkcall("intstring", n->type, init,
+ conv(n->left, types[TINT64])); // TODO(rsc): int64?!
goto ret;
case OARRAYBYTESTR: