ref: da1de51de2edb383cc26a1b726df4cfc9328e1c7
parent: 8bd18e2d1caef67781ae69d761bdfca8d2bcf41d
parent: ea7fb6cca6d0fbe0f4f3f3ef269d97e76c488c27
author: Ori Bernstein <[email protected]>
date: Thu Dec 12 11:44:11 EST 2013
Merge branch 'master' of git+ssh://git.eigenstate.org/git/ori/mc
--- a/6/isel.c
+++ b/6/isel.c
@@ -353,22 +353,8 @@
static void blit(Isel *s, Loc *to, Loc *from, size_t dstoff, size_t srcoff, size_t sz)
{
- AsmOp op;
Loc *sp, *dp, *len; /* pointers to src, dst */
- if (sz % 8 == 0) {
- sz /= 8;
- op = Irepmovsq;
- } else if (sz % 4 == 0) {
- sz /= 4;
- op = Irepmovsl;
- } else if (sz % 2 == 0) {
- sz /= 2;
- op = Irepmovsw;
- } else {
- op = Irepmovsb;
- }
-
len = loclit(sz, ModeQ);
sp = inr(s, from);
dp = inr(s, to);
@@ -385,7 +371,7 @@
g(s, Ilea, locmem(dstoff, dp, NULL, ModeQ), locphysreg(Rrdi), NULL);
else
g(s, Imov, dp, locphysreg(Rrdi), NULL);
- g(s, op, NULL);
+ g(s, Irepmovsb, NULL);
}
static Loc *gencall(Isel *s, Node *n)
--- a/libstd/Makefile
+++ b/libstd/Makefile
@@ -11,8 +11,8 @@
fmt.myr \
hashfuncs.myr \
htab.myr \
- ipaddr.myr \
intparse.myr \
+ ipparse.myr \
now.myr \
option.myr \
optparse.myr \
@@ -23,7 +23,10 @@
sldup.myr \
sleq.myr \
sljoin.myr \
+ slpush.myr \
slurp.myr \
+ strsplit.myr \
+ strstrip.myr \
strcmp.myr \
sys.myr \
types.myr \
--- a/libstd/alloc.myr
+++ b/libstd/alloc.myr
@@ -118,7 +118,7 @@
/* if the slice wouldn't change buckets, we don't need to realloc. */
if samebucket(sl.len * sizeof(@a), len * sizeof(@a))
- -> sl
+ -> (sl castto(@a#))[:len]
;;
new = slalloc(len)
--- /dev/null
+++ b/libstd/ipparse.myr
@@ -1,0 +1,45 @@
+use "types.use"
+use "intparse.use"
+use "option.use"
+
+ /* FIXME: needed for decls which should be pulled in as hidden */
+use "strcmp.use"
+use "utf.use"
+use "fmt.use"
+
+pkg std =
+ const ip4parse : (ip : byte[:] -> option(byte[4]))
+ const ip6parse : (ip : byte[:] -> option(byte[16]))
+;;
+
+const ip4parse = {ip
+ var addr
+ var last : size
+ var x : option(int32)
+ var val : int32 /* need int32 to check for overflow */
+ var i
+ var j : size
+
+ i = 0
+ for j = 0; j < ip.len; j++
+ if ip[j] == '.' castto(byte)
+ put("seg[%z..%z] = %s\n", last, j, ip[last:j])
+ val = intparsebase(ip[last:j], 10)
+ if val < 0 || val > 255
+ -> `None
+ ;;
+ addr[i++] = val castto(byte)
+ last = j + 1
+ ;;
+ ;;
+ put("seg[%z..%z] = %s\n", last, j, ip[last:j])
+ val = intparsebase(ip[last:j], 10)
+ if val < 0 || val > 255
+ -> `None
+ ;;
+ addr[i] = val castto(byte)
+ if j != ip.len
+ -> `None
+ ;;
+ -> `Some addr
+}
--- a/libstd/resolve.myr
+++ b/libstd/resolve.myr
@@ -3,7 +3,11 @@
use "endian.use"
use "error.use"
use "fmt.use"
+use "option.use"
use "slcp.use"
+use "slurp.use"
+use "strsplit.use"
+use "strstrip.use"
use "sys.use"
use "types.use"
@@ -12,37 +16,65 @@
`Badhost
`Badsrv
`Badquery
+ `Badresp
;;
+ type netaddr = union
+ `Ipv4 byte[4]
+ `Ipv6 byte[16]
+ ;;
+
type hostinfo = struct
- flags : uint32
fam : sockfam
stype : socktype
+ ttl : uint32
+ addr : netaddr
+ /*
proto : uint32
+ flags : uint32
addr : sockaddr[:]
canon : byte[:]
next : hostinfo#
+ */
;;
- const resolve : (host : byte[:] -> hostinfo#)
+ const resolve : (host : byte[:] -> error(hostinfo[:], resolveerr))
;;
-type dnshdr = struct
- id : uint16
- /* {qr:1|op:4|aa:1|tc:1|rd:1|ra:1|z:3|rcode:4} */
- flags : uint16
- qdcnt : uint16
- ancnt : uint16
- nscnt : uint16
- arcnt : uint16
-;;
+const Hostfile = "/etc/hosts"
const resolve = {host : byte[:]
- var hinf
+ match hostfind(host)
+ | `Some h: -> h
+ | `None: -> dnsresolve(host)
+ ;;
+}
- hinf = zalloc()
- dnsresolve(host)
- -> hinf
+const hostfind = {host
+ -> `None
+ /*
+ var hdat
+ var lines
+ var ip
+ var hn
+ var str
+ var i
+
+ match slurp(Hostfile)
+ | `Success h: hdat = h
+ | `Failure m: -> `None
+ ;;
+
+ lines = strsplit(hdat, "\n")
+ for i = 0; i < lines.len; i++
+ lines[i] = strstrip(lines[i])
+ (ip, str) = nextword(lines)
+ (hn, str) = nextword(str)
+ if streq(hn, host)
+ -> parseip(ip)
+ ;;
+ ;;
+ */
}
const dnsresolve = {host : byte[:]
@@ -55,10 +87,7 @@
if (nsrv = dnsconnect()) < 0
-> `Failure (`Badsrv)
;;
- if !dnsquery(nsrv, host)
- -> `Failure (`Badquery)
- ;;
- -> `Success true
+ -> dnsquery(nsrv, host)
}
const dnsconnect = {
@@ -71,7 +100,8 @@
put("Warning: Failed to open socket: %l\n", s)
-> -1
;;
- /* hardcode Google DNS for now */
+ /* hardcode Google DNS for now.
+ FIXME: parse /etc/resolv.conf */
sa.fam = Afinet
sa.port = hosttonet(53) /* port 53 */
sa.addr = [8,8,8,8] /* 8.8.8.8 */
@@ -84,10 +114,13 @@
}
const dnsquery = {srv, host
- tquery(srv, host)
- rquery(srv)
- put("Unimplemented query: srv=%z, host=%s\n", srv, host)
- -> false
+ var id
+ var r
+
+ id = tquery(srv, host)
+ r = rquery(srv, id)
+ put("Got hosts. Returning\n")
+ -> r
}
const Qr : uint16 = 1 << 0
@@ -96,14 +129,15 @@
const Rd : uint16 = 1 << 7
const Ra : uint16 = 1 << 8
-var nextid = 42
+var nextid : uint16 = 42
const tquery = {srv, host
var pkt : byte[512] /* big enough */
var off : size
+ put("Sending request for %s\n", host)
/* header */
off = 0
- off += pack16(pkt[:], off, nextid++) /* id */
+ off += pack16(pkt[:], off, nextid) /* id */
off += pack16(pkt[:], off, Ra) /* flags */
off += pack16(pkt[:], off, 1) /* qdcount */
off += pack16(pkt[:], off, 0) /* ancount */
@@ -115,11 +149,11 @@
off += pack16(pkt[:], off, 0x1) /* qtype: a record */
off += pack16(pkt[:], off, 0x1) /* qclass: inet4 */
- write(1, pkt[:off])
write(srv, pkt[:off])
+ -> nextid++
}
-const rquery = {srv
+const rquery = {srv, id
var pktbuf : byte[1024]
var pkt
var n
@@ -130,10 +164,56 @@
put("Warning: Failed to read from %z: %i\n", srv, n)
;;
pkt = pktbuf[:n]
+ put("Got response:\n");
dumpresponse(pkt)
+ -> hosts(pkt, id)
}
+const hosts = {pkt, id : uint16
+ var off
+ var v
+ var q
+ var a
+ var i
+ var hinf : hostinfo[:]
+ off = 0
+ /* parse header */
+ (v, off) = unpack16(pkt, off) /* id */
+ if v != id
+ -> `Failure (`Badresp)
+ ;;
+ put("Unpacking flags")
+ (v, off) = unpack16(pkt, off) /* flags */
+ (q, off) = unpack16(pkt, off) /* qdcount */
+ (a, off) = unpack16(pkt, off) /* ancount */
+ (v, off) = unpack16(pkt, off) /* nscount */
+ (v, off) = unpack16(pkt, off) /* arcount */
+
+ /* skip past query records */
+ for i = 0; i < q; i++
+ put("Skipping query record")
+ off = skipname(pkt, off) /* name */
+ (v, off) = unpack16(pkt, off) /* type */
+ (v, off) = unpack16(pkt, off) /* class */
+ ;;
+
+ /* parse answer records */
+ hinf = slalloc(a castto(size))
+ for i = 0; i < a; i++
+ off = skipname(pkt, off) /* name */
+ (v, off) = unpack16(pkt, off) /* type */
+ (v, off) = unpack16(pkt, off) /* class */
+ (hinf[i].ttl, off) = unpack32(pkt, off) /* ttl */
+ (v, off) = unpack16(pkt, off) /* rdatalen */
+ /* the thing we're interested in: our IP address */
+ hinf[i].addr = `Ipv4 [pkt[off], pkt[off+1], pkt[off+2], pkt[off+3]]
+ off += 4;
+ ;;
+ -> `Success hinf
+}
+
+
const dumpresponse = {pkt
var nquery
var nans
@@ -141,13 +221,8 @@
var v
var i
- put("packet size = %z\n", pkt.len)
(v, off) = unpack16(pkt, 0)
- put("hdr.id = %w\n", v)
(v, off) = unpack16(pkt, off)
- put("hdr.rawflag = %i\n", (((v castto(uint32)) & 0xf000) >> 12))
- put("hdr.flag = [Qr = %t, Aa = %t, Tc = %t, Rd = %t, Ra = %t]\n", (v&Qr) == 0, (v&Aa) == 0, (v&Tc) == 0, (v&Rd)==0, (v&Ra)==0)
- put("hdr.rcode = %w\n", (v >> 11) & 0xf)
(nquery, off) = unpack16(pkt, off)
put("hdr.qdcount = %w\n", nquery)
(nans, off) = unpack16(pkt, off)
@@ -203,6 +278,21 @@
-> off
}
+const skipname = {pkt, off
+ var sz
+
+ for sz = pkt[off] castto(size); sz != 0; sz = pkt[off] castto(size)
+ /* ptr is 2 bytes */
+ if sz & 0xC0 == 0xC0
+ -> off + 2
+ else
+ off += sz + 1
+ ;;
+ ;;
+ -> off + 1
+}
+
+
const printname = {pkt, off
var sz
@@ -231,6 +321,16 @@
v = (buf[off] castto(uint16)) << 8
v |= (buf[off + 1] castto(uint16))
-> (v, off+sizeof(uint16))
+}
+
+const unpack32 = {buf, off
+ var v
+
+ v = (buf[off] castto(uint32)) << 24
+ v |= (buf[off+1] castto(uint32)) << 32
+ v |= (buf[off+2] castto(uint32)) << 8
+ v |= (buf[off+3] castto(uint32))
+ -> (v, off+sizeof(uint32))
}
const packname = {buf, off : size, host
--- /dev/null
+++ b/libstd/strsplit.myr
@@ -1,0 +1,29 @@
+use "alloc.use"
+use "die.use"
+use "extremum.use"
+use "fmt.use"
+use "slpush.use"
+use "sys.use"
+use "types.use"
+
+pkg std =
+ const strsplit : (s : byte[:], delim : byte[:] -> byte[:][:])
+;;
+
+const strsplit = {s, delim
+ var i
+ var last
+ var sp
+
+ sp = [][:]
+ last = 0
+ assert(delim.len == 1, "FIXME: We should support strings as delimiters")
+ for i = 0; i < s.len; i++
+ if s[i] == delim[0]
+ sp = slpush(sp, s[last:i])
+ last = i + 1
+ ;;
+ ;;
+ -> sp
+}
+
--- /dev/null
+++ b/libstd/strstrip.myr
@@ -1,0 +1,44 @@
+use "types.use"
+use "utf.use"
+use "chartype.use"
+
+pkg std =
+ const strstrip : (str : byte[:] -> byte[:])
+ const strfstrip : (str : byte[:] -> byte[:])
+ const strrstrip : (str : byte[:] -> byte[:])
+;;
+
+/* strip blanks from both head and tail of str */
+const strstrip = {str
+ -> strrstrip(strfstrip(str))
+}
+
+/* strip forward on str */
+const strfstrip = {str
+ var c
+
+ for c = decode(str); isblank(c); c = decode(str)
+ str = str[charlen(c):]
+ ;;
+ -> str
+
+}
+
+/* strip reverse on str */
+const strrstrip = {str
+ var i
+ var end
+
+ /* scan backwards for start of utf8 char */
+ end = 0
+ for i = str.len; i != 0; i--
+ if str[i] & 0x80 == 0
+ if !isspace(decode(str[i-1:]))
+ goto donestrip
+ ;;
+ end = i - 1
+ ;;
+ ;;
+:donestrip
+ -> str[:end]
+}
--- a/mi/df.c
+++ b/mi/df.c
@@ -13,7 +13,28 @@
#include "parse.h"
#include "opt.h"
+/*
+static void nodeuse(Node *n, Bitset *bs)
+{
+}
+
+static void nodedef(Node *n, Bitset *bs)
+{
+}
+
+static void bbuse(Bb *bb, Bitset *bs)
+{
+}
+
+static void bbdef(Bb *bb, Bitset *bs)
+{
+}
+*/
+
void flow(Cfg *cfg)
{
}
+void checkret(Cfg *cfg)
+{
+}
--- a/mi/opt.h
+++ b/mi/opt.h
@@ -3,6 +3,8 @@
struct Cfg {
Bb **bb;
+ Bb *start;
+ Bb *end;
size_t nbb;
/* for building bb */
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -479,7 +479,7 @@
size_t max(size_t a, size_t b);
size_t min(size_t a, size_t b);
-size_t align(size_t sz, size_t align);
+size_t align(size_t sz, size_t a);
/* suffix replacement */
char *swapsuffix(char *buf, size_t sz, char *s, char *suf, char *swap);
--- a/parse/tok.c
+++ b/parse/tok.c
@@ -526,7 +526,7 @@
continue;
if (c == '.')
isfloat = 1;
- else if (hexval(c) > base)
+ else if (hexval(c) < 0 || hexval(c) > base)
fatal(line, "Integer digit '%c' outside of base %d", c, base);
}
--- a/parse/util.c
+++ b/parse/util.c
@@ -375,8 +375,11 @@
return b;
}
-size_t align(size_t sz, size_t align)
+size_t align(size_t sz, size_t a)
{
- return (sz + align - 1) & ~(align - 1);
+ /* align to 0 just returns sz */
+ if (a == 0)
+ return sz;
+ return (sz + a - 1) & ~(a - 1);
}
--- /dev/null
+++ b/test/data/strsplit-expected
@@ -1,0 +1,4 @@
+a
+b
+c
+d
--- /dev/null
+++ b/test/data/strstrip-expected
@@ -1,0 +1,15 @@
+"abc"
+"abc "
+" abc"
+--
+"世界"
+"世界 "
+" 世界"
+--
+""
+""
+""
+--
+""
+""
+""
--- a/test/match-badtypes.myr
+++ b/test/match-badtypes.myr
@@ -7,9 +7,7 @@
*/
const foo = {
match 123
- "asdf": 123
- ;;
- 234: 888
- ;;
+ |"asdf": 123
+ |234567: 888
;;
}
--- a/test/matchmixed.myr
+++ b/test/matchmixed.myr
@@ -7,8 +7,8 @@
const main = {
match "asdf"
- `A: std.put("Got a\n");;
- `B: std.put("Got b\n");;
+ | `A: std.put("Got a\n")
+ | `B: std.put("Got b\n")
;;
-> 42
}
--- /dev/null
+++ b/test/strsplit.myr
@@ -1,0 +1,12 @@
+use std
+
+const main = {
+ var i
+ var sp
+
+ sp = std.strsplit("a,b,c,d", ",")
+ for i = 0; i < sp.len; i++
+ std.put("%s\n", sp[i])
+ ;;
+ -> 0
+}
--- /dev/null
+++ b/test/strstrip.myr
@@ -1,0 +1,23 @@
+use std
+
+const main = {
+ std.put("\"%s\"\n", std.strstrip(" abc "))
+ std.put("\"%s\"\n", std.strfstrip(" abc "))
+ std.put("\"%s\"\n", std.strrstrip(" abc "))
+
+ std.put("--\n")
+ std.put("\"%s\"\n", std.strstrip(" 世界 "))
+ std.put("\"%s\"\n", std.strfstrip(" 世界 "))
+ std.put("\"%s\"\n", std.strrstrip(" 世界 "))
+
+ std.put("--\n")
+ std.put("\"%s\"\n", std.strstrip(" "))
+ std.put("\"%s\"\n", std.strfstrip(" "))
+ std.put("\"%s\"\n", std.strrstrip(" "))
+
+ std.put("--\n")
+ std.put("\"%s\"\n", std.strstrip(""))
+ std.put("\"%s\"\n", std.strfstrip(""))
+ std.put("\"%s\"\n", std.strrstrip(""))
+ -> 0
+}
--- a/test/tests
+++ b/test/tests
@@ -105,6 +105,8 @@
B encodechar P 1世界äa
B strtab C
B catfile C
+B strstrip C
+B strsplit C
# B local-labels E 10 ## BUGGERED
F declmismatch
F infermismatch