]> Cypherpunks repositories - gostls13.git/commitdiff
interface equality
authorKen Thompson <ken@golang.org>
Tue, 14 Oct 2008 22:08:23 +0000 (15:08 -0700)
committerKen Thompson <ken@golang.org>
Tue, 14 Oct 2008 22:08:23 +0000 (15:08 -0700)
R=r
OCL=17116
CL=17118

src/cmd/gc/lex.c
src/cmd/gc/sys.go
src/cmd/gc/sysimport.c
src/cmd/gc/walk.c
src/runtime/iface.c

index df02fc2f80dd67dc753b7502eaf7eec8a52c0b9b..41bc1c74b264564d1ebc49116420da0336c68be8 100644 (file)
@@ -1063,6 +1063,7 @@ lexinit(void)
 
                case TPTR32:
                case TPTR64:
+               case TINTER:
                        okforeq[i] = 1;
                        break;
                }
index 83be8da946508c946189dbf99723d09d010c890a..ddfffa564576c64813111dd237ee3a9435b7ab06 100644 (file)
@@ -31,6 +31,7 @@ export func   arraystring(*[]byte) string;
 export func    ifaceT2I(sigi *byte, sigt *byte, elem any) (ret any);
 export func    ifaceI2T(sigt *byte, iface any) (ret any);
 export func    ifaceI2I(sigi *byte, iface any) (ret any);
+export func    ifaceeq(i1 any, i2 any) (ret bool);
 
 export func    argc() int32;
 export func    envc() int32;
index 81ed5321b964c5f74b7a0e61bdf69d2116f9446f..9303cea2f47ed04153693d7224d95bb70f1801d7 100644 (file)
@@ -31,6 +31,7 @@ char *sysimport =
        "export func sys.ifaceT2I (sigi *sys.uint8, sigt *sys.uint8, elem sys.any) (ret sys.any)\n"
        "export func sys.ifaceI2T (sigt *sys.uint8, iface sys.any) (ret sys.any)\n"
        "export func sys.ifaceI2I (sigi *sys.uint8, iface sys.any) (ret sys.any)\n"
+       "export func sys.ifaceeq (i1 sys.any, i2 sys.any) (ret sys.bool)\n"
        "export func sys.argc () (? sys.int32)\n"
        "export func sys.envc () (? sys.int32)\n"
        "export func sys.argv (? sys.int32) (? sys.string)\n"
index 4f9ccd34a78fdcea2e2e5046fa2be469ff55e2b1..47a3d10cb6c574c3fa29412454fa02e1b269965b 100644 (file)
@@ -681,7 +681,7 @@ loop:
                convlit(n->right, n->left->type);
                if(n->left->type == T || n->right->type == T)
                        goto ret;
-               if(!ascompat(n->left->type, n->right->type))
+               if(!eqtype(n->left->type, n->right->type, 0))
                        goto badt;
 
                switch(n->op) {
@@ -952,6 +952,10 @@ loop:
                et = n->left->type->etype;
                if(!okforeq[et])
                        goto badt;
+               if(isinter(n->left->type)) {
+                       indir(n, ifaceop(T, n, n->op));
+                       goto ret;
+               }
                t = types[TBOOL];
                break;
 
@@ -2550,6 +2554,28 @@ ifaceop(Type *tl, Node *n, int op)
                argtype(on, tr);
                argtype(on, tl);
                break;
+
+       case OEQ:
+       case ONE:
+               // ifaceeq(i1 any-1, i2 any-2) (ret bool);
+               a = n->right;                           // i2
+               r = a;
+
+               a = n->left;                            // i1
+               r = list(a, r);
+
+               on = syslook("ifaceeq", 1);
+               argtype(on, n->right->type);
+               argtype(on, n->left->type);
+
+               r = nod(OCALL, on, r);
+               if(op == ONE)
+                       r = nod(ONOT, r, N);
+
+               dump("bef", r);
+               walktype(r, Erv);
+               dump("aft", r);
+               return r;
        }
 
        r = nod(OCALL, on, r);
index de59172d1780221e0bbfeeaf469b0b76d5528cdd..b303e459e17a3b0add512e1fe6e9607647cde701 100644 (file)
@@ -261,6 +261,53 @@ sys·ifaceI2I(Sigi *si, Map *im, void *it, Map *retim, void *retit)
        FLUSH(&retit);
 }
 
+// ifaceeq(i1 any, i2 any) (ret bool);
+void
+sys·ifaceeq(Map *im1, void *it1, Map *im2, void *it2, byte ret)
+{
+       if(debug) {
+               prints("Ieq i1=");
+               printiface(im1, it1);
+               prints(" i2=");
+               printiface(im2, it2);
+               prints("\n");
+       }
+
+       ret = false;
+
+       // are they both nil
+       if(im1 == nil) {
+               if(im2 == nil)
+                       goto yes;
+               goto no;
+       }
+       if(im2 == nil)
+               goto no;
+
+       // values
+       if(it1 != it2)
+               goto no;
+
+       // types
+       if(im1 == im2)
+               goto yes;
+       if(im1->sigt == im2->sigt)
+               goto yes;
+       if(im1->sigt->hash != im2->sigt->hash)
+               goto no;
+
+
+yes:
+       ret = true;
+no:
+       if(debug) {
+               prints("Ieq ret=");
+               sys·printbool(ret);
+               prints("\n");
+       }
+       FLUSH(&ret);
+}
+
 void
 sys·printinter(Map *im, void *it)
 {