]> Cypherpunks repositories - gostls13.git/commitdiff
gc, runtime: copy([]byte, string)
authorRuss Cox <rsc@golang.org>
Tue, 26 Oct 2010 15:36:07 +0000 (08:36 -0700)
committerRuss Cox <rsc@golang.org>
Tue, 26 Oct 2010 15:36:07 +0000 (08:36 -0700)
R=ken2
CC=golang-dev
https://golang.org/cl/2741041

src/cmd/gc/builtin.c.boot
src/cmd/gc/runtime.go
src/cmd/gc/typecheck.c
src/cmd/gc/walk.c
src/pkg/runtime/slice.c

index 12f870d7812b474736a6009b22f08bd3237284be..bb1a5f5fa62167d4ca1d3a9b7d254fd264fa05c4 100644 (file)
@@ -33,6 +33,7 @@ char *runtimeimport =
        "func \"\".stringiter (? string, ? int) int\n"
        "func \"\".stringiter2 (? string, ? int) (retk int, retv int)\n"
        "func \"\".slicecopy (to any, fr any, wid uint32) int\n"
+       "func \"\".slicestringcopy (to any, fr any) int\n"
        "func \"\".convI2E (elem any) any\n"
        "func \"\".convI2I (typ *uint8, elem any) any\n"
        "func \"\".convT2E (typ *uint8, elem any) any\n"
index 36ed7e96fff76a301739c52ec1fbd84012ca4d80..2279384473f81697f9725165649803803a6cf950 100644 (file)
@@ -48,6 +48,7 @@ func stringtosliceint(string) []int
 func stringiter(string, int) int
 func stringiter2(string, int) (retk int, retv int)
 func slicecopy(to any, fr any, wid uint32) int
+func slicestringcopy(to any, fr any) int
 
 // interface conversions
 func convI2E(elem any) (ret any)
index 43cf4a7c3671a2241786b9a38dda40d6777e81ec..614833740a06097e4ef6a12d550e9639af9067a7 100644 (file)
@@ -926,13 +926,18 @@ reswitch:
                        goto error;
                defaultlit(&n->left, T);
                defaultlit(&n->right, T);
+               
+               // copy([]byte, string)
+               if(isslice(n->left->type) && n->left->type->type == types[TUINT8] && n->right->type->etype == TSTRING)
+                       goto ret;
+
                if(!isslice(n->left->type) || !isslice(n->right->type)) {
                        if(!isslice(n->left->type) && !isslice(n->right->type))
                                yyerror("arguments to copy must be slices; have %lT, %lT", n->left->type, n->right->type);
                        else if(!isslice(n->left->type))
                                yyerror("first argument to copy should be slice; have %lT", n->left->type);
                        else
-                               yyerror("second argument to copy should be slice; have %lT", n->right->type);
+                               yyerror("second argument to copy should be slice or string; have %lT", n->right->type);
                        goto error;
                }
                if(!eqtype(n->left->type->type, n->right->type->type)) {
index 4588ac1c18f1a11d8835f5ffc060dcefab2840d2..bf20102c7da87e4fdc4f348dd2ada01db0b8b18d 100644 (file)
@@ -1261,7 +1261,10 @@ walkexpr(Node **np, NodeList **init)
                goto ret;
 
        case OCOPY:
-               fn = syslook("slicecopy", 1);
+               if(n->right->type->etype == TSTRING)
+                       fn = syslook("slicestringcopy", 1);
+               else
+                       fn = syslook("slicecopy", 1);
                argtype(fn, n->left->type);
                argtype(fn, n->right->type);
                n = mkcall1(fn, n->type, init,
index 67e44e93c092e324e4f9d9a9b55870ce920dad21..d0ba4ede3f82f6feeb7ee75695c19076c87d6bcc 100644 (file)
@@ -217,6 +217,24 @@ out:
        }
 }
 
+void
+·slicestringcopy(Slice to, String fm, int32 ret)
+{
+       if(fm.len == 0 || to.len == 0) {
+               ret = 0;
+               goto out;
+       }
+       
+       ret = fm.len;
+       if(to.len < ret)
+               ret = to.len;
+       
+       memmove(to.array, fm.str, ret);
+
+out:
+       FLUSH(&ret);
+}
+
 void
 ·printslice(Slice a)
 {