ref: 08b1eacc62abb4f77fd7403c692cdc4b84c7dd76
parent: 92d743d5e5eaf030196e52bdcc94b8c1735c1219
 parent: 30234b14a10a94f21b6f84559fce135f43cb2e71
	author: Ori Bernstein <orib@google.com>
	date: Thu Oct  4 10:51:44 EDT 2012
	
Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/mc
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -12,7 +12,8 @@
ASMSRC= \
start.s \
- syscall.s
+ syscall.s \
+ util.s
include ../config.mk
--- a/libstd/sys-linux.myr
+++ b/libstd/sys-linux.myr
@@ -369,6 +369,7 @@
const Sysprocess_vm_writev : scno = 311
extern const syscall : (sc:scno, args:... -> int64)
+ extern const cstring : (str : byte[:] -> byte*)
const exit : (status:int64 -> void)
const getpid : ( -> int64)
@@ -387,9 +388,9 @@
 const exit	= {status;		syscall(Sysexit, 1);} const getpid	= {;			-> syscall(Sysgetpid, 1);} const kill	= {pid, sig;		-> syscall(Syskill, pid, sig);}-const open	= {path, opts, mode;	-> syscall(Sysopen, path castto(char*), opts);}+const open	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), opts, mode);} const close	= {fd;			-> syscall(Sysclose, fd);}-const creat	= {path, mode;		-> syscall(Syscreat, path castto(char*), mode);}+const creat	= {path, mode;		-> syscall(Syscreat, cstring(path), mode);} const read	= {fd, buf;		-> syscall(Sysread, fd, buf castto(char*), buf.len);} const write	= {fd, buf;		-> syscall(Syswrite, fd, buf castto(char*), buf.len castto(size));} const lseek	= {fd, off, whence;	-> syscall(Syslseek, fd, off, whence);}--- a/libstd/sys-osx.myr
+++ b/libstd/sys-osx.myr
@@ -415,6 +415,7 @@
const Sysfileport_makefd : scno = 0x20001b1
extern const syscall : (sc:scno, args:... -> int64)
+ extern const cstring : (str : byte[:] -> byte*)
const exit : (status:int64 -> void)
const getpid : ( -> int64)
@@ -433,7 +434,7 @@
 const exit	= {status;		syscall(Sysexit, 1);} const getpid	= {;			-> syscall(Sysgetpid, 1);} const kill	= {pid, sig;		-> syscall(Syskill, pid, sig);}-const open	= {path, opts, mode;	-> syscall(Sysopen, path castto(char*), opts);}+const open	= {path, opts, mode;	-> syscall(Sysopen, cstring(path), opts, mode);} const close	= {fd;			-> syscall(Sysclose, fd);} const creat	= {path, mode;		-> open(path, Ocreat | Otrunc | Owronly, mode);} const read	= {fd, buf;		-> syscall(Sysread, fd, buf castto(char*), buf.len);}--- a/libstd/syscall-linux.s
+++ b/libstd/syscall-linux.s
@@ -20,3 +20,4 @@
popq %rbp
ret
+
--- /dev/null
+++ b/libstd/util.s
@@ -1,0 +1,29 @@
+/*
+ * Allocates a C string on the stack, for
+ * use within system calls, which is the only
+ * place the Myrddin stack should need nul-terminated
+ * strings.
+ *
+ * This is in assembly, because for efficiency we
+ * allocate the C strings on the stack, and don't adjust
+ * %rsp when returning.
+ */
+.globl std$cstring
+std$cstring:
+ movq (%rsp),%r15 /* ret addr */
+ movq 8(%rsp),%rsi /* src */
+ movq %rsp,%rdi /* dest */
+ movq %rsp,%rax /* ret val */
+ movq 16(%rsp),%rcx /* len */
+
+ subq %rcx,%rsp /* get stack */
+ subq $1,%rsp /* nul */
+ andq $(~15),%rsp /* align */
+
+ cld
+ rep movsb
+ movb $0,(%rdi) /* terminate */
+
+ pushq %r15 /* ret addr */
+ ret
+
--- a/myrbuild/myrbuild.c
+++ b/myrbuild/myrbuild.c
@@ -162,7 +162,7 @@
char *localdep;
char *deps[512];
char buf[1024];
-    char *extra[2] = {"-o", "" /* filename */};+    char *extra[] = {"-g", "-o", "" /* filename */};     if (hassuffix(file, ".myr")) {getdeps(file, deps, 512, &ndeps);
@@ -189,8 +189,8 @@
     } else if (hassuffix(file, ".s")) {swapsuffix(buf, sizeof buf, file, ".s", ".o");
         if (isfresh(file, buf)) {- extra[1] = buf;
- gencmd(&cmd, &ncmd, as, file, extra, 2);
+ extra[2] = buf;
+ gencmd(&cmd, &ncmd, as, file, extra, 3);
run(cmd);
}
}
--- a/parse/dump.c
+++ b/parse/dump.c
@@ -132,7 +132,7 @@
outnode(n->file.stmts[i], fd, depth + 1);
break;
case Ndecl:
- fprintf(fd, "(did = %zd, isconst = %d, isgeneric = %d, isextern = %d\n, isexport = %d)",
+ fprintf(fd, "(did = %zd, isconst = %d, isgeneric = %d, isextern = %d, isexport = %d)\n",
n->decl.did, n->decl.isconst, n->decl.isgeneric, n->decl.isextern, n->decl.isexport);
outsym(n, fd, depth + 1);
outnode(n->decl.init, fd, depth + 1);
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -130,12 +130,29 @@
ret = mktyvar(t->line);
htput(ht, t->pname, ret);
return ret;
+    } else if (t->type == Tygeneric) {+ for (i = 0; i < t->nparam; i++)
+ if (!hthas(ht, t->param[i]->pname))
+ htput(ht, t->param[i]->pname, mktyvar(t->param[i]->line));
+ return mktyname(t->line, t->name, tyfreshen(st, ht, t->sub[0]));
+    } else {+ ret = tydup(t);
+ for (i = 0; i < t->nsub; i++)
+ ret->sub[i] = tyfreshen(st, ht, t->sub[i]);
+ return ret;
}
+}
- ret = tydup(t);
- for (i = 0; i < t->nsub; i++)
- ret->sub[i] = tyfreshen(st, ht, t->sub[i]);
- return ret;
+static Type *tyspecialize(Inferstate *st, Type *t)
+{+ Htab *ht;
+
+ assert(t->type == Tygeneric);
+ ht = mkht(strhash, streq);
+ t = tyfreshen(st, ht, t);
+ htfree(ht);
+
+ return t;
}
/* Freshens the type of a declaration. */
@@ -484,11 +501,17 @@
b = t;
}
+ if (a->type == Tygeneric)
+ a = tyspecialize(st, a);
+ if (b->type == Tygeneric)
+ b = tyspecialize(st, b);
+
r = NULL;
     if (a->type == Tyvar) {tytab[a->tid] = b;
r = b;
}
+
/* Disallow recursive types */
if (a->type == Tyvar && b->type != Tyvar)
if (occurs(a, b))
--- a/parse/type.c
+++ b/parse/type.c
@@ -53,12 +53,24 @@
r = mktype(t->line, t->type);
r->resolved = 0; /* re-resolving doesn't hurt */
+ r->fixed = 0; /* re-resolving doesn't hurt */
+
r->cstrs = bsdup(t->cstrs);
+ r->cstrlist = memdup(t->cstrlist, t->ncstrlist * sizeof(Node*));
+ r->ncstrlist = t->ncstrlist;
+
+ r->param = memdup(t->param, t->nparam * sizeof(Type*));
+ r->nparam = t->nparam;
+ r->inst = memdup(t->param, t->nparam * sizeof(Type*));
+ r->ninst = t->ninst;
+
+ r->sub = memdup(t->sub, t->nsub * sizeof(Type*));
r->nsub = t->nsub;
r->nmemb = t->nmemb;
- r->sub = memdup(t->sub, t->nsub * sizeof(Type*));
     switch (t->type) {- case Tyunres: r->name = t->name; break;
+ case Tygeneric: r->name = t->name; break;
+ case Tyname: r->name = t->name; break;
+ case Tyunres: r->name = t->name; break;
case Tyarray: r->asize = t->asize; break;
case Typaram: r->pname = strdup(t->pname); break;
case Tystruct: r->sdecls = memdup(t->sdecls, t->nmemb*sizeof(Node*)); break;
--
⑨