]> Cypherpunks repositories - gostls13.git/commitdiff
string nil same as string ""
authorKen Thompson <ken@golang.org>
Tue, 24 Jun 2008 21:11:20 +0000 (14:11 -0700)
committerKen Thompson <ken@golang.org>
Tue, 24 Jun 2008 21:11:20 +0000 (14:11 -0700)
SVN=124381

src/cmd/6g/cgen.c
src/cmd/6g/gen.c
src/cmd/6g/gsubr.c
src/cmd/gc/walk.c
src/runtime/runtime.c
src/runtime/runtime.h

index 9f3fa92e57e9ba8675a6a4fb789f95b94f7c8d9b..6b820c52344614ad7d963137a3632708a27f6e0d 100644 (file)
@@ -155,6 +155,15 @@ cgen(Node *n, Node *res)
                        regfree(&n1);
                        break;
                }
+               if(isptrto(nl->type, TMAP)) {
+                       regalloc(&n1, types[tptr], res);
+                       cgen(nl, &n1);
+                       n1.op = OINDREG;
+                       n1.type = types[TINT32];
+                       gmove(&n1, res);
+                       regfree(&n1);
+                       break;
+               }
                fatal("cgen: OLEN: unknown type %lT", nl->type);
                break;
 
index 923c3a721bd0ff910072be1cccdca30c2297daae..cbd2dd651bfb31589321fa91c27cf6281960f2d0 100644 (file)
@@ -825,11 +825,6 @@ cgen_as(Node *nl, Node *nr, int op)
 
                case TPTR32:
                case TPTR64:
-                       if(isptrto(nl->type, TSTRING)) {
-                               nr->val.ctype = CTSTR;
-                               nr->val.sval = &emptystring;
-                               break;
-                       }
                        nr->val.ctype = CTNIL;
                        nr->val.vval = 0;
                        break;
index 956d357be3ecf1aa65518bd6df7706c7e789593e..a35c786a8bd3a3ff3b7701431ae2f757499f6fec 100644 (file)
@@ -1687,8 +1687,11 @@ stringpool(Node *n)
        Pool *p;
        int w;
 
-       if(n->op != OLITERAL || n->val.ctype != CTSTR)
-               fatal("stringpool: not string");
+       if(n->op != OLITERAL || n->val.ctype != CTSTR) {
+               if(n->val.ctype == CTNIL)
+                       return;
+               fatal("stringpool: not string %N", n);
+       }
 
        p = mal(sizeof(*p));
 
index 86fe1439d6c1aeccbf55c321eaad6c7391b69005..6b3860d283b67b3883bb3090e95653233c5850e3 100644 (file)
@@ -239,31 +239,53 @@ loop:
                        goto ret;
                }
 
-               if(cr != 1) {
-                       yyerror("bad shape across assignment");
-                       goto ret;
-               }
-
                switch(r->op) {
                case OCALLMETH:
                case OCALLINTER:
                case OCALL:
-                       walktype(r, Erv);
-                       l = ascompatet(n->op, &n->left, &r->type, 0);
-                       if(l != N) {
-                               *n = *nod(OLIST, r, reorder2(l));
+                       if(cr == 1) {
+                               // a,b,... = fn()
+                               walktype(r, Erv);
+                               l = ascompatet(n->op, &n->left, &r->type, 0);
+                               if(l != N) {
+                                       *n = *nod(OLIST, r, reorder2(l));
+                               }
+                               goto ret;
                        }
                        break;
 
                case OINDEX:
                case OINDEXPTR:
-                       if(!isptrto(r->left->type, TMAP))
-                               goto badt;
-                       if(cl != 2)
-                               goto badt;
-                       *n = *mapop(n, top);
+                       if(cl == 2 && cr == 1) {
+                               // a,b = map[] - mapaccess2
+                               if(!isptrto(r->left->type, TMAP))
+                                       break;
+                               l = mapop(n, top);
+                               if(l == N)
+                                       break;
+                               *n = *l;
+                               goto ret;
+                       }
+                       break;
+               }
+
+               switch(l->op) {
+               case OINDEX:
+               case OINDEXPTR:
+                       if(cl == 1 && cr == 2) {
+                               // map[] = a,b - mapassign2
+                               if(!isptrto(l->left->type, TMAP))
+                                       break;
+                               l = mapop(n, top);
+                               if(l == N)
+                                       break;
+                               *n = *l;
+                               goto ret;
+                       }
                        break;
                }
+
+               yyerror("bad shape across assignment - cr=%d cl=%d\n", cr, cl);
                goto ret;
 
        case OBREAK:
@@ -455,6 +477,8 @@ loop:
                        goto badt;
                case TSTRING:
                        break;
+               case TMAP:
+                       break;
                }
                n->type = types[TINT32];
                goto ret;
@@ -1348,7 +1372,7 @@ mapop(Node *n, int top)
        Node *r, *a;
        Type *t;
        Node *on;
-       int alg1, alg2;
+       int alg1, alg2, cl, cr;
 
        lno = dynlineno;
        dynlineno = n->lineno;
@@ -1433,53 +1457,66 @@ mapop(Node *n, int top)
                r->type = t->type;
                break;
 
-       access2:
-               // mapaccess2(hmap *map[any-1]any-2, key any-3) (val-4 any, pres bool);
+       case OAS:
+               cl = listcount(n->left);
+               cr = listcount(n->right);
 
-               t = fixmap(n->right->left->type);
+               if(cl == 1 && cr == 2)
+                       goto assign2;
+               if(cl == 2 && cr == 1)
+                       goto access2;
+               if(cl != 1 || cr != 1)
+                       goto shape;
+
+               // mapassign1(hmap *map[any-1]any-2, key any-3, val any-4);
+
+//dump("assign1", n);
+               if(n->left->op != OINDEX)
+                       goto shape;
+
+               t = fixmap(n->left->left->type);
                if(t == T)
                        break;
 
-               a = n->right->right;                    // key
+               a = n->right;                           // val
                r = a;
-               a = n->right->left;                     // map
+               a = n->left->right;                     // key
+               r = nod(OLIST, a, r);
+               a = n->left->left;                      // map
                r = nod(OLIST, a, r);
 
-               on = syslook("mapaccess2", 1);
+               on = syslook("mapassign1", 1);
 
                argtype(on, t->down);   // any-1
                argtype(on, t->type);   // any-2
                argtype(on, t->down);   // any-3
                argtype(on, t->type);   // any-4
 
-               n->right = nod(OCALL, on, r);
-               walktype(n, Etop);
-               r = n;
+               r = nod(OCALL, on, r);
+               walktype(r, Erv);
                break;
 
-       case OAS:
-               if(top != Elv) {
-                       if(top == Etop)
-                               goto access2;
-                       goto nottop;
-               }
-               if(n->left->op != OINDEX)
-                       fatal("mapos: AS left not OINDEX");
+       assign2:
+               // mapassign2(hmap *map[any]any, key any, val any, pres bool);
 
-               // mapassign1(hmap *map[any-1]any-2, key any-3, val any-4);
+//dump("assign2", n);
+               if(n->left->op != OINDEX)
+                       goto shape;
 
                t = fixmap(n->left->left->type);
                if(t == T)
                        break;
 
-               a = n->right;                           // val
+               a = n->right->right;                    // pres
                r = a;
+               a = n->right->left;                     // val
+               r =nod(OLIST, a, r);
                a = n->left->right;                     // key
                r = nod(OLIST, a, r);
                a = n->left->left;                      // map
                r = nod(OLIST, a, r);
 
-               on = syslook("mapassign1", 1);
+               on = syslook("mapassign2", 1);
 
                argtype(on, t->down);   // any-1
                argtype(on, t->type);   // any-2
@@ -1490,42 +1527,43 @@ mapop(Node *n, int top)
                walktype(r, Erv);
                break;
 
-/* BOTCH get 2nd version attached */
-               if(top != Elv)
-                       goto nottop;
-               if(n->left->op != OINDEX)
-                       fatal("mapos: AS left not OINDEX");
+       access2:
+               // mapaccess2(hmap *map[any-1]any-2, key any-3) (val-4 any, pres bool);
 
-               // mapassign2(hmap *map[any]any, key any, val any, pres bool);
+//dump("access2", n);
+               if(n->right->op != OINDEX)
+                       goto shape;
 
-               t = fixmap(n->left->left->type);
+               t = fixmap(n->right->left->type);
                if(t == T)
                        break;
 
-               a = n->right;                           // pres
+               a = n->right->right;                    // key
                r = a;
-               a = n->right;                           // val
-               r =nod(OLIST, a, r);
-               a = n->left->right;                     // key
-               r = nod(OLIST, a, r);
-               a = n->left->left;                      // map
+               a = n->right->left;                     // map
                r = nod(OLIST, a, r);
 
-               on = syslook("mapassign2", 1);
+               on = syslook("mapaccess2", 1);
 
                argtype(on, t->down);   // any-1
                argtype(on, t->type);   // any-2
                argtype(on, t->down);   // any-3
                argtype(on, t->type);   // any-4
 
-               r = nod(OCALL, on, r);
-               walktype(r, Erv);
+               n->right = nod(OCALL, on, r);
+               walktype(n, Etop);
+               r = n;
                break;
 
        }
        dynlineno = lno;
        return r;
 
+shape:
+       dump("shape", n);
+       fatal("mapop: cl=%d cr=%d, %O", top, n->op);
+       return N;
+
 nottop:
        dump("bad top", n);
        fatal("mapop: top=%d %O", top, n->op);
index 5b8d0489eb4d6f7d8d726487b6e265eb5abf88e1..9c668633b44a57ebef275d4c7c275c44bc2023ec 100644 (file)
@@ -6,6 +6,9 @@
 
 int32  debug   = 0;
 
+static int32   empty           = 0;
+static string  emptystring     = (string)&empty;
+
 void
 sys_printbool(bool v)
 {
@@ -73,11 +76,12 @@ sys_printpointer(void *p)
 void
 sys_printstring(string v)
 {
-       sys_write(1, v->str, v->len);
+       if(v != nil)
+               sys_write(1, v->str, v->len);
 }
 
 int32
-strlen(int8 *s)
+findnull(int8 *s)
 {
        int32 l;
 
@@ -89,7 +93,7 @@ strlen(int8 *s)
 void
 prints(int8 *s)
 {
-       sys_write(1, s, strlen(s));
+       sys_write(1, s, findnull(s));
 }
 
 void
@@ -220,6 +224,11 @@ cmpstring(string s1, string s2)
        uint32 i, l;
        byte c1, c2;
 
+       if(s1 == nil)
+               s1 = emptystring;
+       if(s2 == nil)
+               s2 = emptystring;
+
        l = s1->len;
        if(s2->len < l)
                l = s2->len;
@@ -250,11 +259,11 @@ sys_catstring(string s1, string s2, string s3)
 {
        uint32 l;
 
-       if(s1->len == 0) {
+       if(s1 == nil || s1->len == 0) {
                s3 = s2;
                goto out;
        }
-       if(s2->len == 0) {
+       if(s2 == nil || s2->len == 0) {
                s3 = s1;
                goto out;
        }
@@ -317,6 +326,9 @@ sys_slicestring(string si, int32 lindex, int32 hindex, string so)
        string s, str;
        int32 l;
 
+       if(si == nil)
+               si = emptystring;
+
        if(lindex < 0 || lindex > si->len ||
           hindex < lindex || hindex > si->len) {
                sys_printpc(&si);
@@ -334,6 +346,9 @@ sys_slicestring(string si, int32 lindex, int32 hindex, string so)
 void
 sys_indexstring(string s, int32 i, byte b)
 {
+       if(s == nil)
+               s = emptystring;
+
        if(i < 0 || i >= s->len) {
                sys_printpc(&s);
                prints(" ");
@@ -785,6 +800,7 @@ struct      Link
 
 struct Hmap
 {
+       uint32  len;            // must be first
        uint32  keysize;
        uint32  valsize;
        uint32  hint;
@@ -881,7 +897,7 @@ static void
 stringcopy(uint32 s, string *a, string *b)
 {
        if(b == nil) {
-               *b = nil;
+               *a = nil;
                return;
        }
        *a = *b;
@@ -932,6 +948,7 @@ sys_newmap(uint32 keysize, uint32 valsize,
 
        m = mal(sizeof(*m));
 
+       m->len = 0;
        m->keysize = keysize;
        m->valsize = valsize;
        m->keyalg = &algarray[keyalg];
@@ -1053,6 +1070,7 @@ sys_mapassign(Hmap *m, byte *ak, byte *av)
        l->link = m->link;
        m->link = l;
        m->keyalg->copy(m->keysize, l->data, ak);
+       m->len++;
 
 out:
        m->valalg->copy(m->valsize, l->data+m->valoffset, av);
@@ -1088,7 +1106,6 @@ sys_mapassign2(Hmap *m, ...)
        Link **ll;
        byte *ak, *av, *ap;
 
-
        ak = (byte*)&m + m->ko;
        av = (byte*)&m + m->vo;
        ap = (byte*)&m + m->po;
@@ -1104,6 +1121,7 @@ sys_mapassign2(Hmap *m, ...)
                if(m->keyalg->equal(m->keysize, ak, (*ll)->data)) {
                        m->valalg->copy(m->valsize, (*ll)->data+m->valoffset, nil);
                        (*ll) = (*ll)->link;
+                       m->len--;
                        if(debug) {
                                prints("mapdelete (found): map=");
                                sys_printpointer(m);
index fa9395f1be16825207bdbe5221cc21268b5c2cb9..15b33a070e9149e6b245221dafc57fddcd240e5e 100644 (file)
@@ -103,7 +103,7 @@ void        sys_write(int32, void*, int32);
 void   sys_breakpoint(void);
 uint8* sys_mmap(byte*, uint32, int32, int32, int32, uint32);
 void   sys_memclr(byte*, uint32);
-void* sys_getcallerpc(void*);
+void*  sys_getcallerpc(void*);
 void   sys_sigaction(int64, void*, void*);
 void   sys_rt_sigaction(int64, void*, void*, uint64);