shithub: mc

Download patch

ref: 6e6ce5029f094dfac9318672376f639989b072e4
parent: 67daccb5fd16d15ead42807d57cc66010ef2faa2
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Mar 28 19:13:04 EDT 2015

Tweak the ABI for type information.

--- a/6/gengas.c
+++ b/6/gengas.c
@@ -15,6 +15,8 @@
 #include "asm.h"
 #include "../config.h"
 
+#define Tdindirect 0x80
+
 static char *insnfmt[] = {
 #define Insn(val, gasfmt, p9fmt, use, def) gasfmt,
 #include "insns.def"
@@ -487,15 +489,26 @@
     writeasm(fd, &is, fn);
 }
 
+void gennamevec(FILE *fd, Node *n)
+{
+    if (n->name.ns) {
+        fprintf(fd, "\t.quad %zd\n", strlen(n->name.name) + strlen(n->name.ns) + 1);
+        fprintf(fd, "\t.ascii \"%s.%s\"\n", n->name.ns, n->name.name);
+    } else {
+        fprintf(fd, "\t.quad %zd\n", strlen(n->name.name));
+        fprintf(fd, "\t.ascii \"%s\"\n", n->name.name);
+    }
+}
+
 static void genstructmemb(FILE *fd, Node *sdecl)
 {
-    fprintf(fd, "\t.ascii \"%s\" /* struct member */\n", namestr(sdecl->decl.name));
+    gennamevec(fd, sdecl->decl.name);
     gentydesc(fd, sdecl->decl.type);
 }
 
 static void genunionmemb(FILE *fd, Ucon *ucon)
 {
-    fprintf(fd, "\t.ascii \"%s\" /* union constructor */\n", namestr(ucon->name));
+    gennamevec(fd, ucon->name);
     if (ucon->etype)
         gentydesc(fd, ucon->etype);
     else
@@ -508,10 +521,15 @@
 static void gentydesc(FILE *fd, Type *ty)
 {
     char buf[512];
+    uint8_t tt;
     Node *sz;
     size_t i;
 
-    fprintf(fd, "\t.byte %d\n", ty->type);
+    /* names are pulled out of line */
+    tt = ty->type;
+    if (ty->type == Tyname)
+        tt |= Tdindirect;
+    fprintf(fd, "\t.byte %d\n", tt);
     switch (ty->type) {
         case Ntypes: case Tyvar: case Tybad: case Typaram:
         case Tygeneric: case Tyunres:
@@ -555,10 +573,12 @@
                 gentydesc(fd, ty->sub[i]);
             break;
         case Tystruct:
+            fprintf(fd, "\t.quad %zd\n", ty->nmemb);
             for (i = 0; i < ty->nmemb; i++)
                 genstructmemb(fd, ty->sdecls[i]);
             break;
         case Tyunion:
+            fprintf(fd, "\t.quad %zd\n", ty->nmemb);
             for (i = 0; i < ty->nmemb; i++)
                 genunionmemb(fd, ty->udecls[i]);
             break;
@@ -578,12 +598,19 @@
             return;
         if (ty->vis == Visexport)
             fprintf(fd, ".globl %s /* tid: %d */\n", buf, ty->tid);
-        fprintf(fd, "%s:\n", buf);
+    }
+    fprintf(fd, "%s:\n", buf);
+    fprintf(fd, "\t.quad %s$data\n", buf);
+    fprintf(fd, "\t.quad %s$end - %s$data\n", buf, buf);
+    fprintf(fd, "%s$data:\n", buf);
+    if (ty->type == Tyname) {
+        fprintf(fd, "\t.byte %d\n", ty->type);
+        gennamevec(fd, ty->name);
         gentydesc(fd, ty->sub[0]);
     } else {
-        fprintf(fd, "%s:\n", buf);
         gentydesc(fd, ty);
     }
+    fprintf(fd, "%s$end:\n\n", buf);
 }
 
 void gengas(Node *file, char *out)
@@ -638,11 +665,12 @@
         genblob(fd, blob[i], globls, strtab);
     fprintf(fd, "\n");
 
-    fprintf(fd, ".text\n");
+    fprintf(fd, ".section .text\n");
     for (i = 0; i < nfn; i++)
         genfunc(fd, fn[i], globls, strtab);
     fprintf(fd, "\n");
 
+    fprintf(fd, ".section .rodata\n");
     for (i = 0; i < ntypes; i++)
         if (types[i]->isreflect && !types[i]->isimport)
             gentype(fd, types[i]);
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -894,6 +894,8 @@
         typeerror(st, a, b, ctx, NULL);
     }
     mergetraits(st, ctx, a, b);
+    if (a->isreflect || b->isreflect)
+        r->isreflect = a->isreflect = b->isreflect = 1;
     membunify(st, ctx, a, b);
 
     /* if we have delayed types for a tyvar, transfer it over. */
@@ -2174,7 +2176,7 @@
     k = htkeys(st->ty, &n);
     for (i = 0; i < n; i++) {
         t = gettype(st, k[i]);
-        if (t->vis != Visexport)
+        if (!t->isreflect && t->vis != Visexport)
             continue;
         if (hidelocal && t->ispkglocal)
             t->vis = Vishidden;