diff options
-rw-r--r-- | src/cmd/gc/lex.c | 1 | ||||
-rw-r--r-- | src/cmd/gc/sys.go | 1 | ||||
-rw-r--r-- | src/cmd/gc/sysimport.c | 1 | ||||
-rw-r--r-- | src/cmd/gc/walk.c | 28 | ||||
-rw-r--r-- | src/runtime/iface.c | 47 |
5 files changed, 77 insertions, 1 deletions
diff --git a/src/cmd/gc/lex.c b/src/cmd/gc/lex.c index df02fc2f8..41bc1c74b 100644 --- a/src/cmd/gc/lex.c +++ b/src/cmd/gc/lex.c @@ -1063,6 +1063,7 @@ lexinit(void) case TPTR32: case TPTR64: + case TINTER: okforeq[i] = 1; break; } diff --git a/src/cmd/gc/sys.go b/src/cmd/gc/sys.go index 83be8da94..ddfffa564 100644 --- a/src/cmd/gc/sys.go +++ b/src/cmd/gc/sys.go @@ -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; diff --git a/src/cmd/gc/sysimport.c b/src/cmd/gc/sysimport.c index 81ed5321b..9303cea2f 100644 --- a/src/cmd/gc/sysimport.c +++ b/src/cmd/gc/sysimport.c @@ -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" diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 4f9ccd34a..47a3d10cb 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -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); diff --git a/src/runtime/iface.c b/src/runtime/iface.c index de59172d1..b303e459e 100644 --- a/src/runtime/iface.c +++ b/src/runtime/iface.c @@ -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) { |