shithub: mc

Download patch

ref: 5131214c8ddbd9a4f3a4b6c9acef575985ff867d
parent: fe0e401477b76a165557e25a4def39f47f5178e2
author: Ori Bernstein <[email protected]>
date: Mon Oct 6 13:43:30 EDT 2014

Split libstd into libstd and libsys.

--- a/6/simp.c
+++ b/6/simp.c
@@ -1820,6 +1820,7 @@
                 lappend(&s->blobs, &s->nblobs, dcl);
                 break;
             default:
+                die("Unsupported initializer for %s\n", declname(dcl));
                 break;
         }
     } else if (!dcl->decl.isconst && !e) {
--- a/configure
+++ b/configure
@@ -61,7 +61,7 @@
         exit 1
         ;;
 esac
-echo '#define Instroot "'$prefix'"' > config.h
+
 case $MACH in
     *x86_64*)
         echo 'export ARCH=x64' >> config.mk
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -1,67 +1,73 @@
+SYSLIB=sys
+SYSSRC= \
+	sys.myr \
+	systypes.myr \
+	ifreq.myr \
+
+SYSASMSRC= \
+	syscall.s \
+	util.s
+
+
 STDLIB=std
 STDSRC= \
-    alloc.myr \
-    bigint.myr \
-    bitset.myr \
-    blat.myr \
-    chartype.myr \
-    cmp.myr \
-    dial.myr \
-    die.myr \
-    dir.myr \
-    endian.myr \
-    env.myr \
-    execvp.myr \
-    extremum.myr \
-    fltbits.myr \
-    fmt.myr \
-    fltfmt.myr \
-    hashfuncs.myr \
-    hasprefix.myr \
-    hassuffix.myr \
-    htab.myr \
-    ifreq.myr \
-    intparse.myr \
-    ipparse.myr \
-    mk.myr \
-    now.myr \
-    option.myr \
-    optparse.myr \
-    pathjoin.myr \
-    rand.myr \
-    resolve.myr \
-    result.myr \
-    search.myr \
-    slcp.myr \
-    sldup.myr \
-    sleq.myr \
-    slfill.myr \
-    sljoin.myr \
-    slpush.myr \
-    slput.myr \
-    slurp.myr \
-    sort.myr \
-    spork.myr \
-    strfind.myr \
-    strjoin.myr \
-    strsplit.myr \
-    strstrip.myr \
-    swap.myr \
-    sys.myr \
-    try.myr \
-    types.myr \
-    units.myr \
-    utf.myr \
-    varargs.myr \
-    waitstatus.myr \
+	alloc.myr \
+	bigint.myr \
+	bitset.myr \
+	blat.myr \
+	chartype.myr \
+	cmp.myr \
+	dial.myr \
+	die.myr \
+	dir.myr \
+	endian.myr \
+	env.myr \
+	execvp.myr \
+	extremum.myr \
+	fltbits.myr \
+	fmt.myr \
+	fltfmt.myr \
+	hashfuncs.myr \
+	hasprefix.myr \
+	hassuffix.myr \
+	htab.myr \
+	intparse.myr \
+	ipparse.myr \
+	mk.myr \
+	now.myr \
+	option.myr \
+	optparse.myr \
+	pathjoin.myr \
+	rand.myr \
+	resolve.myr \
+	result.myr \
+	search.myr \
+	slcp.myr \
+	sldup.myr \
+	sleq.myr \
+	slfill.myr \
+	sljoin.myr \
+	slpush.myr \
+	slput.myr \
+	slurp.myr \
+	sort.myr \
+	spork.myr \
+	strfind.myr \
+	strjoin.myr \
+	strsplit.myr \
+	strstrip.myr \
+	syswrap.myr \
+	swap.myr \
+	try.myr \
+	types.myr \
+	units.myr \
+	utf.myr \
+	varargs.myr \
+	waitstatus.myr \
 
-ASMSRC= \
-    syscall.s \
-    util.s
-
 include ../config.mk
 
-all: lib$(STDLIB).a $(MYRBIN) test
+all: lib$(STDLIB).a $(MYRBIN)
 
 %.myr: %+$(SYS)-$(ARCH).myr
 	cp $< $@
@@ -78,21 +84,26 @@
 %.s: %+$(ARCH).s
 	cp $< $@
 
-lib$(STDLIB).a: $(STDSRC) $(ASMSRC) ../6/6m
-	../myrbuild/myrbuild -C../6/6m -M../muse/muse -l $(STDLIB) $(STDSRC) $(ASMSRC)
+lib$(STDLIB).a: $(STDSRC) $(ASMSRC) $(SYSLIB) lib$(SYSLIB).a ../6/6m
+	../myrbuild/myrbuild -I. -C../6/6m -M../muse/muse -l $(STDLIB) $(STDSRC) $(STDASMSRC)
 
-OBJ=$(STDSRC:.myr=.o) $(ASMSRC:.s=.o)
-USE=$(STDSRC:.myr=.use) $(STDLIB)
+lib$(SYSLIB).a: $(SYSSRC) $(SYSASMSRC) ../6/6m
+	../myrbuild/myrbuild -C../6/6m -M../muse/muse -l $(SYSLIB) $(SYSSRC) $(SYSASMSRC)
+
+OBJ=$(STDSRC:.myr=.o) $(SYSSRC:.myr=.o) $(STDASMSRC:.s=.o) $(SYSASMSRC:.s=.o)
+USE=$(STDSRC:.myr=.use) $(SYSSRC:.myr=.use) $(STDLIB)
 .PHONY: clean
 clean:
 	rm -f $(OBJ)
 	rm -f $(USE)
-	rm -f lib$(STDLIB).a
+	rm -f lib$(STDLIB).a lib$(SYSLIB).a
 
 install: all
 	mkdir -p  $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr)
 	install libstd.a $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr)
+	install libsys.a $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr)
 	install std $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr)
+	install sys $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr)
 
 uninstall:
 	rm -f $(abspath $(DESTDIR)/$(INST_ROOT)/lib/myr/libstd.a)
--- a/libstd/alloc.myr
+++ b/libstd/alloc.myr
@@ -1,6 +1,6 @@
+use sys
 use "die.use"
 use "extremum.use"
-use "sys.use"
 use "types.use"
 use "units.use"
 
@@ -224,8 +224,8 @@
 		bkt = &buckets[bktnum(sz)]
 		p = bktalloc(bkt)
 	else
-		p = mmap(Zbyteptr, sz, Mprotrw, Mpriv | Manon, -1, 0)
-		if p == Mapbad
+		p = sys.mmap(Zbyteptr, sz castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
+		if p == sys.Mapbad
 			die("could not map memory\n")
 		;;
 	;;
@@ -245,7 +245,7 @@
 		bkt = &buckets[bktnum(sz)]
 		bktfree(bkt, p)
 	else
-		munmap(p, sz)
+		sys.munmap(p, sz castto(sys.size))
 	;;
 }
 
@@ -275,8 +275,8 @@
 	   cost us memory, and 64 bits of address space means that we're not
 	   going to have issues with running out of address space for a
 	   while. On a 32 bit system this would be a bad idea. */
-	p = mmap(Zbyteptr, Slabsz*2, Mprotrw, Mpriv | Manon, -1, 0)
-	if p == Mapbad
+	p = sys.mmap(Zbyteptr, Slabsz*2 castto(sys.size), sys.Mprotrw, sys.Mpriv | sys.Manon, -1, 0)
+	if p == sys.Mapbad
 		die("Unable to mmap")
 	;;
 
@@ -348,7 +348,7 @@
 		else
 			/* we mapped 2*Slabsz so we could align it,
 			 so we need to unmap the same */
-			munmap(s.head, Slabsz*2)
+			sys.munmap(s.head, Slabsz*2 castto(sys.size))
 		;;
 	;;
 	s.nfree++
--- a/libstd/blat.myr
+++ b/libstd/blat.myr
@@ -1,4 +1,4 @@
-use "sys.use"
+use "syswrap.use"
 use "fmt.use"
 
 pkg std =
--- a/libstd/dial.myr
+++ b/libstd/dial.myr
@@ -1,16 +1,17 @@
 use "alloc.use"
 use "chartype.use"
 use "die.use"
-use "result.use"
-use "sys.use"
-use "sleq.use"
-use "option.use"
-use "ipparse.use"
-use "resolve.use"
-use "fmt.use"
 use "endian.use"
-use "intparse.use"
+use "fmt.use"
 use "hasprefix.use"
+use "intparse.use"
+use "ipparse.use"
+use "option.use"
+use "resolve.use"
+use "result.use"
+use "sleq.use"
+use "sys.use"
+use "syswrap.use"
 use "utf.use"
 
 pkg std =
@@ -30,7 +31,7 @@
 const dial = {str
 	var proto, host, port
 	var socktype, portnum
-	var sa : sockaddr_in	/* we only support inet sockets right now.. ugh. */
+	var sa : sys.sockaddr_in	/* we only support inet sockets right now.. ugh. */
 	var sock
 
 	(proto, str) = nameseg(str)
@@ -50,9 +51,9 @@
 	elif sleq(proto, "unix")
 		-> `Fail "net unix proto not yet supported\n"
 	elif sleq(proto, "tcp")
-		socktype = Sockstream
+		socktype = sys.Sockstream
 	elif sleq(proto, "udp")
-		socktype = Sockdgram
+		socktype = sys.Sockdgram
 	;;
 
 	match parseport(port)
@@ -62,7 +63,7 @@
 
 	match getaddr(host)
 	| `Ipv4 bits:
-		sa.fam = Afinet
+		sa.fam = sys.Afinet
 		sa.addr = bits
 		sa.port = hosttonet(portnum)
 	| `Ipv6 bits:
@@ -69,19 +70,19 @@
 		-> `Fail "ipv6 not yet supported"
 	;;
 
-	sock = socket(sa.fam, socktype, 0)
+	sock = sys.socket(sa.fam, socktype, 0)
 	if sock < 0
 		-> `Fail "failed to connect to socket"
 	;;
 	var err
-	err = connect(sock, (&sa) castto(sockaddr#), sizeof(sockaddr_in))
+	err = sys.connect(sock, (&sa) castto(sys.sockaddr#), sizeof(sys.sockaddr_in))
 	if err < 0
 		put("Errno %i\n", -err)
-		close(sock)
+		sys.close(sock)
 		-> `Fail "Failed to bind socket"
 	;;
 
-	-> `Ok sock
+	-> `Ok (sock castto(fd))
 }
 
 const parseport = {port
--- a/libstd/die.myr
+++ b/libstd/die.myr
@@ -1,4 +1,4 @@
-use "sys.use"
+use "syswrap.use"
 use "types.use"
 
 pkg std = 
--- a/libstd/dir+linux.myr
+++ b/libstd/dir+linux.myr
@@ -1,3 +1,5 @@
+use sys
+
 use "alloc.use"
 use "die.use"
 use "option.use"
@@ -4,12 +6,11 @@
 use "result.use"
 use "slcp.use"
 use "sldup.use"
-use "sys.use"
 use "types.use"
 
 pkg std =
 	type dir = struct
-		fd	: fd
+		fd	: sys.fd
 		buf	: byte[16384]
 		len	: int64
 		off	: int64
@@ -26,7 +27,7 @@
 	var fd
 	var dir
 
-	fd = open(p, Ordonly | Odir)
+	fd = sys.open(p, sys.Ordonly | sys.Odir)
 	if fd < 0
 		-> `Fail "couldn't open directory"
 	;;
@@ -41,7 +42,7 @@
 	var namelen
 
 	if d.off >= d.len
-		len = getdents64(d.fd, d.buf[:])
+		len = sys.getdents64(d.fd, d.buf[:])
 		if len <= 0
 			-> `None
 		;;
@@ -49,7 +50,7 @@
 		d.off = 0
 	;;
 
-	dent = &d.buf[d.off] castto(dirent64#)
+	dent = &d.buf[d.off] castto(sys.dirent64#)
 	namelen = 0
 	d.off += dent.reclen castto(int64)
 	while dent.name[namelen] != 0
@@ -59,7 +60,7 @@
 }
 
 const dirclose = {d
-	close(d.fd)
+	sys.close(d.fd)
 	free(d)
 }
 
--- a/libstd/env.myr
+++ b/libstd/env.myr
@@ -1,10 +1,10 @@
+use sys
+
 use "extremum.use"
 use "option.use"
 use "sleq.use"
 
 pkg std =
-	extern var _environment	: byte[:][:]
-
 	const getenv :	(name : byte[:] -> option(byte[:]))
 	const getenvv :	(name : byte[:], default : byte[:] -> byte[:])
 ;;
@@ -11,7 +11,7 @@
 
 const getenv = {name
 	var n
-	for env in _environment
+	for env in sys.__environment
 		n = min(name.len, env.len)
 		if sleq(name, env[:n]) && sleq(env[n:n+1], "=")
 			-> `Some env[n+1:]
--- a/libstd/execvp.myr
+++ b/libstd/execvp.myr
@@ -4,7 +4,7 @@
 use "option.use"
 use "strfind.use"
 use "strsplit.use"
-use "sys.use"
+use "syswrap.use"
 
 pkg std = 
 	const execvp	: (cmd : byte[:], args : byte[:][:] -> int64)
--- a/libstd/fmt.myr
+++ b/libstd/fmt.myr
@@ -1,8 +1,10 @@
+use sys
+
 use "alloc.use"
 use "die.use"
-use "sys.use"
 use "types.use"
 use "utf.use"
+use "syswrap.use"
 use "varargs.use"
 use "extremum.use"
 use "chartype.use"
--- a/libstd/now.myr
+++ b/libstd/now.myr
@@ -1,4 +1,5 @@
-use "sys.use"
+use sys
+
 use "types.use"
 use "fmt.use"
 
@@ -12,7 +13,7 @@
 	var sec
 	var nsec
 
-	if clock_gettime(`Clockrealtime, &tm) == 0	
+	if sys.clock_gettime(`sys.Clockrealtime, &tm) == 0
 		sec = tm.sec
 		nsec = tm.nsec castto(uint64)
 		-> (sec*1_000_000 + nsec/1000) castto(time)
--- a/libstd/optparse.myr
+++ b/libstd/optparse.myr
@@ -4,7 +4,7 @@
 use "fmt.use"
 use "option.use"
 use "slpush.use"
-use "sys.use"
+use "syswrap.use"
 use "types.use"
 use "utf.use"
 
--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -1,3 +1,4 @@
+use sys
 use "alloc.use"
 use "chartype.use"
 use "die.use"
@@ -16,7 +17,6 @@
 use "strfind.use"
 use "strsplit.use"
 use "strstrip.use"
-use "sys.use"
 use "types.use"
 use "utf.use"
 
@@ -50,8 +50,8 @@
 	;;
 
 	type hostinfo = struct
-		fam	: sockfam
-		stype	: socktype
+		fam	: sys.sockfam
+		stype	: sys.socktype
 		ttl	: uint32
 		addr	: netaddr
 	/*
@@ -135,8 +135,8 @@
 	var fam
 
 	match addr
-	| `Ipv4 _:	fam = Afinet
-	| `Ipv6 _:	fam = Afinet6
+	| `Ipv4 _:	fam = sys.Afinet
+	| `Ipv6 _:	fam = sys.Afinet6
 	;;
 	while true
 		match word(str)
@@ -234,18 +234,18 @@
 }
 
 const dnsconnectv4 = {addr
-	var sa : sockaddr_in
+	var sa : sys.sockaddr_in
 	var s
 	var status
-	
-	s = socket(Afinet, Sockdgram, 0)
+
+	s = sys.socket(sys.Afinet, sys.Sockdgram, 0)
 	if s < 0
 		-> -1
 	;;
-	sa.fam = Afinet
+	sa.fam = sys.Afinet
 	sa.port = hosttonet(53)
 	sa.addr = addr
-	status = connect(s, (&sa) castto(sockaddr#), sizeof(sockaddr_in))
+	status = sys.connect(s, (&sa) castto(sys.sockaddr#), sizeof(sys.sockaddr_in))
 	if status < 0
 		-> -1
 	;;
@@ -286,7 +286,7 @@
 	off += pack16(pkt[:], off, t castto(uint16)) /* qtype: a record */
 	off += pack16(pkt[:], off, 0x1) /* qclass: inet4 */
 
-	write(srv, pkt[:off])
+	sys.write(srv, pkt[:off])
 	-> nextid++
 }
 
@@ -295,7 +295,7 @@
 	var pkt
 	var n
 
-	n = read(srv, pktbuf[:])
+	n = sys.read(srv, pktbuf[:])
 	if n < 0
 	;;
 	pkt = pktbuf[:n]
--- a/libstd/slurp.myr
+++ b/libstd/slurp.myr
@@ -3,7 +3,7 @@
 use "result.use"
 use "extremum.use"
 use "fmt.use"
-use "sys.use"
+use "syswrap.use"
 use "types.use"
 
 pkg std =
--- a/libstd/spork.myr
+++ b/libstd/spork.myr
@@ -1,7 +1,9 @@
+use sys
+
 use "die.use"
 use "execvp.use"
 use "fmt.use"
-use "sys.use"
+use "syswrap.use"
 
 pkg std =
 	const spork	: (cmd : byte[:][:]	-> (pid, fd, fd))
@@ -9,21 +11,21 @@
 ;;
 
 const spork = {cmd
-	var infds : fd[2], outfds : fd[2]
+	var infds  :fd[2], outfds : fd[2]
 	var err
 	var pid
 
 	/* open up pipes */
-	err = pipe(infds[:])
+	err = pipe(&infds)
 	if err != 0
 		fatal(1, "Could not create pipes: err %l\n", -err)
 	;;
-	err = pipe(outfds[:])
+	err = pipe(&outfds)
 	if err != 0
 		fatal(1, "Could not create pipes: err %l\n", -err)
 	;;
 
-	pid = sporkfd(cmd, infds[0], outfds[1])
+	pid = sporkfd(cmd, infds[0] castto(fd), outfds[1] castto(fd))
 	/* close unused fd ends */
 	close(infds[0]);
 	close(outfds[1]);
@@ -40,10 +42,10 @@
 	/* child */
 	elif pid == 0
 		/* stdin/stdout for our communication. */
-		if dup2(infd, 0) != 0
+		if sys.dup2(infd castto(sys.fd), 0) != 0
 			fatal(1, "unable to set stdin\n")
 		;;
-		if dup2(outfd, 1) != 1
+		if sys.dup2(outfd castto(sys.fd), 1) != 1
 			fatal(1, "unable to set stdout\n")
 		;;
 		close(infd)
@@ -53,7 +55,7 @@
 		;;
 	/* parent */
 	else
-		-> pid
+		-> pid castto(pid)
 	;;
 }
 
--- a/libstd/sys+linux.myr
+++ b/libstd/sys+linux.myr
@@ -1,7 +1,6 @@
-use "types.use"
-use "varargs.use"
+use "systypes.use"
 
-pkg std =
+pkg sys =
 	type pid	= int64	/* process id */
 	type scno	= int64	/* syscall */
 	type fdopt	= int64	/* fd options */
@@ -565,12 +564,12 @@
 	const lstat	: (path:byte[:], sb:statbuf# -> int64)
 	const fstat	: (fd:fd, sb:statbuf# -> int64)
 	const mkdir	: (path : byte[:], mode : int64	-> int64)
-	const ioctl	: (fd:fd, req : int64, args:... -> int64)
+	generic ioctl	: (fd:fd, req : int64, arg:@a# -> int64)
 	const getdents64	: (fd:fd, buf : byte[:] -> int64)
 	const chdir	: (p : byte[:] -> int64)
 
 	/* fd stuff */
-	const pipe	: (fds : fd[:] -> int64)
+	const pipe	: (fds : fd[2]# -> int64)
 	const dup	: (fd : fd -> fd)
 	const dup2	: (src : fd, dst : fd -> fd)
 
@@ -600,6 +599,10 @@
 
 	/* system information */
 	const uname 	: (buf : utsname# -> int)
+
+	/* exported values: initialized by start code */
+	extern const __environment : byte[:][:]
+	extern const __cenvp : byte##
 ;;
 
 /* 
@@ -610,9 +613,9 @@
 	-> x castto(uint64)
 }
 
+/* asm stubs from util.s */
 extern const cstring	: (str : byte[:] -> byte#)
 extern const alloca	: (sz : size	-> byte#)
-extern const __cenvp : byte##
 
 /* process management */
 const exit	= {status;		syscall(Sysexit, a(status))}
@@ -680,19 +683,12 @@
 const lstat	= {path, sb;		-> syscall(Syslstat, cstring(path), a(sb))}
 const fstat	= {fd, sb;		-> syscall(Sysfstat, a(fd), a(sb))}
 const mkdir	= {path, mode;		-> syscall(Sysmkdir, cstring(path), a(mode)) castto(int64)}
-const ioctl	= {fd, req, args
-	var arg : byte#
-	var ap
-
-	ap = vastart(&args)
-	(arg, ap) = vanext(ap)
-	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)
-}
+generic ioctl	= {fd, req, arg;	-> syscall(Sysioctl, a(fd), a(req), a(arg)) castto(int64)}
 const getdents64	= {fd, buf;	-> syscall(Sysgetdents64, a(fd), buf castto(byte#), a(buf.len))}
 const chdir	= {dir;	-> syscall(Syschdir, dir)}
 
 /* file stuff */
-const pipe	= {fds;	-> syscall(Syspipe, fds castto(fd#))}
+const pipe	= {fds;	-> syscall(Syspipe, a(fds))}
 const dup 	= {fd;	-> syscall(Sysdup, a(fd)) castto(fd)}
 const dup2 	= {src, dst;	-> syscall(Sysdup2, a(src), a(dst)) castto(fd)}
 
--- a/libstd/syscall+linux-x64.s
+++ b/libstd/syscall+linux-x64.s
@@ -1,5 +1,5 @@
-.globl std$syscall
-std$syscall:
+.globl sys$syscall
+sys$syscall:
 	pushq %rbp 
 	pushq %rdi 
 	pushq %rsi 
--- /dev/null
+++ b/libstd/systypes.myr
@@ -1,0 +1,7 @@
+pkg sys =
+	type size	= int64		/* spans entire address space */
+	type usize	= int64		/* signed size */
+	type off	= uint64	/* file offsets */
+	type intptr	= uint64	/* can hold any pointer losslessly */
+	type time	= int64		/* milliseconds since epoch */
+;;
--- /dev/null
+++ b/libstd/syswrap.myr
@@ -1,0 +1,61 @@
+use sys
+use "types.use"
+
+pkg std =
+	type fd		= sys.fd
+	type pid	= sys.pid
+	type fdopt	= sys.fdopt
+
+	const Ordonly  	: fdopt = sys.Ordonly	castto(fdopt)
+	const Owronly  	: fdopt = sys.Owronly	castto(fdopt)
+	const Ordwr    	: fdopt = sys.Ordwr	castto(fdopt)
+	const Ocreat   	: fdopt = sys.Ocreat	castto(fdopt)
+	const Oexcl  	: fdopt = sys.Oexcl	castto(fdopt)
+	const Otrunc   	: fdopt = sys.Otrunc	castto(fdopt)
+	const Oappend  	: fdopt = sys.Oappend	castto(fdopt)
+	const Odir	: fdopt = sys.Odir	castto(fdopt)
+
+	/* fd stuff */
+	const open	: (path : byte[:], opts : fdopt -> fd)
+	const openmode	: (path : byte[:], opts : fdopt, mode : int64 -> fd)
+	const close	: (fd : fd -> int64)
+	const creat	: (path : byte[:], mode : int64 -> fd)
+	const read	: (fd : fd, buf : byte[:] -> size)
+	const write	: (fd : fd, buf : byte[:] -> size)
+	const pipe	: (fds : fd[2]# -> int64)
+
+	/* path manipulation */
+	const mkdir	: (path : byte[:], mode : int64 -> int64)
+	const unlink	: (path : byte[:] -> int)
+
+	/* process stuff */
+	const getpid	: ( -> pid)
+	const kill	: (pid:pid, sig:int64 -> int64)
+	const fork	: (-> pid)
+	const execv	: (cmd : byte[:], args : byte[:][:] -> int64)
+	const execve	: (cmd : byte[:], args : byte[:][:], env : byte[:][:] -> int64)
+	const exit	: (status:int -> void)
+	const waitpid	: (pid:pid, loc:int32#, opt : int64	-> int64)
+;;
+
+/* fd stuff */
+const open	= {path, opts;	-> sys.open(path, opts castto(sys.fdopt)) castto(fd)}
+const openmode	= {path, opts, mode;	-> sys.openmode(path, opts castto(sys.fdopt), mode) castto(fd)}
+const close	= {fd;		-> sys.close(fd castto(sys.fd))}
+const creat	= {path, mode;	-> sys.creat(path, mode) castto(fd)}
+const read	= {fd, buf;	-> sys.read(fd castto(sys.fd), buf) castto(size)}
+const write	= {fd, buf;	-> sys.write(fd castto(sys.fd), buf) castto(size)}
+const pipe	= {fds;		-> sys.pipe(fds castto(sys.fd[2]#))}
+
+/* path manipulation */
+const mkdir	= {path, mode;	-> sys.mkdir(path, mode)}
+const unlink	= {path;	-> sys.unlink(path)}
+
+/* process stuff */
+const getpid	= {;		-> sys.getpid() castto(pid)}
+const kill	= {pid, sig;	-> sys.kill(pid castto(sys.pid), sig)}
+const fork	= {;		-> sys.fork() castto(pid)}
+const execv	= {cmd, args;	-> sys.execv(cmd, args)}
+const execve	= {cmd, args, env;	-> sys.execve(cmd, args, env)}
+const exit	= {status;	sys.exit(status)}
+const waitpid	= {pid, loc, opt;	-> sys.waitpid(pid castto(sys.pid), loc, opt)}
--- a/libstd/types.myr
+++ b/libstd/types.myr
@@ -1,7 +1,9 @@
+use sys
+
 pkg std =
-	type size	= int64		/* spans entire address space */
-	type usize	= int64		/* signed size */
-	type off	= uint64	/* file offsets */
-	type intptr	= uint64	/* can hold any pointer losslessly */
-	type time	= int64		/* milliseconds since epoch */
+	type size	= sys.size	/* spans entire address space */
+	type usize	= sys.usize	/* signed size */
+	type off	= sys.off	/* file offsets */
+	type intptr	= sys.intptr	/* can hold any pointer losslessly */
+	type time	= sys.time	/* milliseconds since epoch */
 ;;
--- a/libstd/util.s
+++ b/libstd/util.s
@@ -8,10 +8,10 @@
  * allocate the C strings on the stack, and don't adjust
  * %rsp when returning.
  */
-.globl std$cstring
-.globl _std$cstring
-_std$cstring:
-std$cstring:
+.globl sys$cstring
+.globl _sys$cstring
+_sys$cstring:
+sys$cstring:
 	/* save registers */
 	pushq %rbp
 	movq %rsp,%rbp
@@ -23,7 +23,7 @@
 	movq 8(%rbp),%r15	/* ret addr */
 	movq 16(%rbp),%rsi	/* src */
 	movq 24(%rbp),%rcx	/* len */
-	
+
 	subq %rcx,%rsp		/* get stack */
 	subq $1,%rsp		/* +1 for nul */
 	movq %rsp,%rdi		/* dest */
@@ -30,11 +30,11 @@
 	movq %rsp,%rax		/* ret val */
 	subq $16,%rsp		/* "unpop" the args */
 	andq $(~15),%rsp	/* align */
-	
+
 	cld
 	rep movsb
 	movb $0,(%rdi)		/* terminate */
-	
+
 	pushq %r15		/* ret addr */
 
 	/* restore registers */
@@ -45,10 +45,10 @@
 	movq (%rbp),%rbp
 	ret
 
-.globl std$alloca
-.globl _std$alloca
-_std$alloca:
-std$alloca:
+.globl sys$alloca
+.globl _sys$alloca
+_sys$alloca:
+sys$alloca:
 	/* save registers */
 	pushq %rbp
 	movq %rsp,%rbp
@@ -57,7 +57,7 @@
 
 	movq 8(%rbp),%r15	/* ret addr */
 	movq 16(%rbp),%rbx	/* len */
-	
+
 	/* get stack space */
 	subq %rbx,%rsp		/* get stack space */
 	movq %rsp,%rax		/* top of stack (return value) */
--- a/opt/fold.c
+++ b/opt/fold.c
@@ -37,10 +37,11 @@
 
 static Node *val(int line, vlong val, Type *t)
 {
-    Node *n;
+    Node *l, *n;
 
-    n = mkint(line, val);
-    n = mkexpr(line, Olit, n, NULL);
+    l = mkint(line, val);
+    n = mkexpr(line, Olit, l, NULL);
+    l->lit.type = t;
     n->expr.type = t;
     return n;
 }
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -2032,6 +2032,16 @@
     }
 }
 
+int isexportinit(Node *n)
+{
+    if (n->decl.isgeneric && !n->decl.trait)
+        return 1;
+    /* we want to inline small values, which means we need to export them */
+    if (istyprimitive(n->decl.type))
+        return 1;
+    return 0;
+}
+
 static void nodetag(Stab *st, Node *n, int ingeneric, int hidelocal)
 {
     size_t i;
@@ -2093,8 +2103,8 @@
             taghidden(n->decl.type);
             if (hidelocal && n->decl.ispkglocal)
                 n->decl.vis = Vishidden;
-            /* generics export their body. */
-            if (n->decl.isgeneric)
+            n->decl.isexportinit = isexportinit(n);
+            if (n->decl.isexportinit)
                 nodetag(st, n->decl.init, n->decl.isgeneric, hidelocal);
             break;
         case Nfunc:
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -276,6 +276,7 @@
             char  ispkglocal;
             char  ishidden;
             char  isimport;
+            char  isexportinit;
         } decl;
 
         struct {
@@ -455,6 +456,7 @@
 int   istysigned(Type *t);
 int   istyunsigned(Type *t);
 int   istyfloat(Type *t);
+int   istyprimitive(Type *t);
 int   isgeneric(Type *t);
 int   hasparams(Type *t);
 
--- a/parse/type.c
+++ b/parse/type.c
@@ -303,6 +303,11 @@
     }
 }
 
+int istyprimitive(Type *t)
+{
+    return istysigned(t) || istyunsigned(t) || istyfloat(t);
+}
+
 int isgeneric(Type *t)
 {
     size_t i;
@@ -738,5 +743,4 @@
     }
 #include "types.def"
 #undef Ty
-
 }
--- a/parse/use.c
+++ b/parse/use.c
@@ -147,9 +147,10 @@
     wrbool(fd, val->decl.isgeneric);
     wrbool(fd, val->decl.isextern);
     wrbool(fd, val->decl.ispkglocal);
-
-    if (val->decl.isgeneric && !val->decl.trait)
+    wrbool(fd, val->decl.isexportinit);
+    if (val->decl.isexportinit) {
         pickle(fd, val->decl.init);
+    }
 }
 
 static Node *rdsym(FILE *fd, Trait *ctx)
@@ -171,8 +172,8 @@
     n->decl.isextern = rdbool(fd);
     n->decl.ispkglocal = rdbool(fd);
     n->decl.isimport = 1;
-
-    if (n->decl.isgeneric && !ctx)
+    n->decl.isexportinit = rdbool(fd);
+    if (n->decl.isexportinit)
         n->decl.init = unpickle(fd);
     return n;
 }
--- a/rt/start-linux.s
+++ b/rt/start-linux.s
@@ -1,16 +1,17 @@
 .data
-/* std._environment : byte[:][:] */
-.globl std$_environment
-std$_environment:
-.envbase:
-.quad 0 /* env size */
-.envlen:
-.quad 0 /* env ptr */
 
-.globl std$__cenvp
-std$__cenvp:
-.quad 0
+/* sys._environment : byte[:][:] */
+.globl sys$__environment
+sys$__environment:
+    .envbase:
+    .quad 0 /* env size */
+    .envlen:
+    .quad 0 /* env ptr */
 
+.globl sys$__cenvp
+sys$__cenvp:
+    .quad 0
+
 .text
 /*
  * The entry point for the whole program.
@@ -18,7 +19,7 @@
  *  - Sets up all argc entries as slices
  *  - Sets up all envp entries as slices
  *  - Converts argc/argv to a slice
- *  - Stashes envp in std._environment
+ *  - Stashes envp in sys._environment
  *  - Stashes a raw envp copy in __cenvp (for syscalls to use)
  *  - Calls main()
  */
@@ -45,11 +46,11 @@
 	subq	%rax,%rsp
 	movq	%rsp, %rdx	/* saved args[:] */
 
-	/* convert envp to byte[:][:] for std._environment */
+	/* convert envp to byte[:][:] for sys._environment */
 	movq	(%rbp),%rax
 	leaq	16(%rbp,%rax,8), %rbx	/* envp = argv + 8*argc + 8 */
         /* store envp for some syscalls to use without converting */
-        movq    %rbx,std$__cenvp(%rip)
+        movq    %rbx,sys$__cenvp(%rip)
 	movq	%r9,%rax
 	movq	%rsp, %rcx
 	movq	%r9,.envlen
--- a/test/import-type.myr
+++ b/test/import-type.myr
@@ -1,7 +1,8 @@
 use std
+use sys
 
 const main = {
 	var x : std.size
 	var y : std.off
-	var z : std.statbuf
+	var z : sys.statbuf
 }