update from cinap. - add the concatinate instruction, - add load/unload instructions (incomplete), - don't use pointers as truth values, (yeh!) a few personal edits (sorry) - don't use single-line if statements e.g. (if(x)something;) - list static variables after automatics. todo: - evalcat should let r be a uchar* rather than a void* to avoid casts. Reference: /n/atom/patch/applied2013/acpicat Date: Thu Jul 4 01:37:38 CES 2013 Signed-off-by: quanstro@quanstro.net --- /sys/src/libaml/aml.c Thu Jul 4 01:33:11 2013 +++ /sys/src/libaml/aml.c Thu Jul 4 01:33:11 2013 @@ -86,7 +86,7 @@ int space; uvlong off; uvlong len; - uchar *va; + uchar *va; /* non nil when mapped */ }; struct Field { @@ -169,8 +169,8 @@ Oindex, Omutex, Oevent, Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8, Oif, Oelse, Owhile, Obreak, Oret, Ocall, - Ostore, Oderef, Osize, Oref, Ocref, - Oacq, Orel, Ostall, Osleep, + Ostore, Oderef, Osize, Oref, Ocref, Ocat, + Oacq, Orel, Ostall, Osleep, Oload, Ounload, }; static Op optab[]; @@ -271,6 +271,12 @@ continue; } *hh = h->link; + if(h->tag == 'r'){ + Region *r = (void*)H2D(h); + + /* TODO: unmap region */ + r->va = nil; + } memset(h, ~0, sizeof(Heap)+h->size); amlfree(h); i++; @@ -436,19 +442,6 @@ } static uvlong -ival(void *p) -{ - if(p != nil) - switch(TAG(p)){ - case 'i': - return *((uvlong*)p); - case 's': - return strtoull((char*)p, 0, 0); - } - return 0; -} - -static uvlong rwreg(void *reg, int off, int len, uvlong v, int write) { Region *r; @@ -460,6 +453,7 @@ p = reg; if((off+len) > SIZE(p)) break; + RWMem: if(write){ /* putle(p, v, 8); */ for(i=0; i r->len) break; if(amldebug){ - print("rwreg: %s %-8s [%llux+%x]/%d %llux\n", + print("\nrwreg: %s %-8s [%llux+%x]/%d %llux\n", write ? "W" : "R", spacename[r->space], r->off, off, len, v); } + /* TODO: map region */ + if(r->va != nil){ + p = r->va + off; + goto RWMem; + } break; } return ~0; } +static uvlong +ival(void *p) +{ + int n; + + if(p != nil){ + switch(TAG(p)){ + case 'i': + return *((uvlong*)p); + case 's': + if(*((char*)p) == 0) + break; + return strtoull((char*)p, 0, 16); + case 'b': + n = SIZE(p); + if(n > 0){ + if(n > 8) n = 8; + return rwreg(p, 0, n, 0, 0); + } + } + } + return 0; +} + static void *deref(void *p); static void *store(void *s, void *d); @@ -592,25 +615,63 @@ static void* copy(int tag, void *s) { + uvlong v; void *d; + int i, n; + static char hex[] = "0123456789ABCDEF"; - if(s != nil){ - int n; - if(tag == 0) - tag = TAG(s); + if(tag == 0){ + if(s == nil) + return nil; + tag = TAG(s); + } + if(s == nil || TAG(s) == 'i'){ + n = 4; + v = ival(s); + if(v > 0xFFFFFFFFULL) + n <<= 1; switch(tag){ case 'b': + d = mk(tag, n); + rwreg(d, 0, n, v, 1); + return d; case 's': - n = SIZE(s); - if(tag == 's' && TAG(s) == 'b') - n++; + n <<= 1; + d = mk(tag, n+1); + ((char*)d)[n] = 0; + while(n > 0){ + ((char*)d)[--n] = hex[v & 0xF]; + v >>= 4; + } + return d; + case 'i': + if(v == 0ULL) + return nil; + return mki(v); + } + } else { + n = SIZE(s); + switch(tag){ + case 's': + if(TAG(s) == 'b'){ + d = mk(tag, n*3 + 1); + for(i=0; i> 4]; + ((char*)d)[i*3 + 1] = hex[((uchar*)s)[i] & 0xF]; + ((char*)d)[i*3 + 2] = ' '; + } + ((char*)d)[n*3] = 0; + return d; + } + /* no break */ + case 'b': + if(TAG(s) == 's'){ + n = strlen(s); + /* zero length string is converted to zero length buffer */ if(n > 0) n++; + } d = mk(tag, n); memmove(d, s, n); - if(tag == 's') - ((uchar*)d)[n-1] = 0; return d; - case 'i': - return mki(ival(s)); } } return s; @@ -631,33 +692,37 @@ /* no break */ case 'R': case 'L': pp = ((Ref*)d)->ptr; - while(p = *pp){ + while((p = *pp) != nil){ switch(TAG(p)){ case 'R': case 'A': case 'L': pp = ((Ref*)p)->ptr; - continue; + break; case 'N': pp = &((Name*)p)->v; - if(*pp != p) - continue; + break; } - break; + if(*pp == p) + break; } break; case 'N': pp = &((Name*)d)->v; + break; } p = *pp; - if(p && TAG(p) != 'N'){ + if(p != nil && TAG(p) != 'N'){ switch(TAG(p)){ case 'f': case 'u': rwfield(p, s, 1); return d; } - *pp = copy(TAG(p), s); - } else - *pp = copy(0, s); + if(TAG(d) != 'A' && TAG(d) != 'L'){ + *pp = copy(TAG(p), s); + return d; + } + } + *pp = copy(0, s); return d; } @@ -1133,12 +1198,13 @@ Name *n; Region *r; - if(n = FP->arg[0]){ + if((n = FP->arg[0]) != nil){ r = mk('r', sizeof(Region)); r->space = ival(FP->arg[1]); r->off = ival(FP->arg[2]); r->len = ival(FP->arg[3]); r->name = n; + r->va = nil; n->v = r; } return nil; @@ -1321,44 +1387,45 @@ evalcmp(void) { void *a, *b; - int c; - - if((a = FP->arg[0]) == nil) - a = mki(0); - if((b = FP->arg[1]) == nil) - b = mki(0); + int tag, c; - switch(TAG(a)){ - default: - return nil; - case 'i': + a = FP->arg[0]; + b = FP->arg[1]; + if(a == nil || TAG(a) == 'i'){ c = ival(a) - ival(b); - break; - case 's': - if(TAG(b) != 's') - b = copy('s', b); - c = strcmp((char*)a, (char*)b); - break; - case 'b': - if(TAG(b) != 'b') - b = copy('b', b); - if((c = SIZE(a) - SIZE(b)) == 0) - c = memcmp(a, b, SIZE(a)); - break; + } else { + tag = TAG(a); + if(b == nil || TAG(b) != tag) + b = copy(tag, b); + if(TAG(b) != tag) + return nil; /* botch */ + switch(tag){ + default: + return nil; /* botch */ + case 's': + c = strcmp((char*)a, (char*)b); + break; + case 'b': + if((c = SIZE(a) - SIZE(b)) == 0) + c = memcmp(a, b, SIZE(a)); + break; + } } switch(FP->op - optab){ case Oleq: - if(c == 0) return mki(1); + if(c == 0) + return mki(1); break; case Olgt: - if(c > 0) return mki(1); + if(c > 0) + return mki(1); break; case Ollt: - if(c < 0) return mki(1); + if(c < 0) + return mki(1); break; } - return nil; } @@ -1447,6 +1514,44 @@ } static void* +evalcat(void) +{ + void *r, *a, *b; + int tag, n, m; + + a = FP->arg[0]; + b = FP->arg[1]; + if(a == nil || TAG(a) == 'i') + a = copy('b', a); /* Concat(Int, ???) -> Buf */ + tag = TAG(a); + if(b == nil || TAG(b) != tag) + b = copy(tag, b); + if(TAG(b) != tag) + return nil; /* botch */ + switch(tag){ + default: + return nil; /* botch */ + case 'b': + n = SIZE(a); + m = SIZE(b); + r = mk('b', n + m); + memmove(r, a, n); + memmove((uchar*)r + n, b, m); + break; + case 's': + n = strlen((char*)a); + m = strlen((char*)b); + r = mk('s', n + m + 1); + memmove(r, a, n); + memmove((char*)r + n, b, m); + ((char*)r)[n+m] = 0; + break; + } + store(r, FP->arg[2]); + return r; +} + +static void* evalindex(void) { Field *f; @@ -1588,6 +1693,59 @@ return r; } +static void* +evalload(void) +{ + enum { LenOffset = 4, HdrLen = 36 }; + uvlong *tid; + Region *r; + int l; + + tid = nil; + if(FP->aux){ + if(PC >= FP->end){ + PC = FP->aux; /* restore */ + FP->aux = nil; + FP->end = PC; + tid = mki(1); /* fake */ + } + } else { + store(nil, FP->arg[1]); + if(FP->arg[0] == nil) + return nil; + + l = rwreg(FP->arg[0], LenOffset, 32, 0, 0); + if(l <= HdrLen) + return nil; + + FP->aux = PC; /* save */ + FP->ref = FP->arg[0]; + switch(TAG(FP->ref)){ + case 'b': + if(SIZE(FP->ref) < l) + return nil; + PC = (uchar*)FP->ref + HdrLen; + break; + case 'r': + r = FP->ref; + if(r->len < l || r->va == nil) + return nil; + /* assuming rwreg() has mapped the region */ + PC = (uchar*)r->va + HdrLen; + break; + default: + return nil; + } + FP->end = PC + (l - HdrLen); + FP->dot = amlroot; + FP->env = nil; + + tid = mki(1); /* fake */ + store(tid, FP->arg[1]); + } + return tid; +} + static Op optab[] = { [Obad] "", "", evalbad, [Onop] "Noop", "", evalnop, @@ -1668,11 +1826,14 @@ [Oref] "RefOf", "@", evaliarg0, [Ocref] "CondRefOf", "@@", evalcondref, [Oderef] "DerefOf", "@", evalderef, + [Ocat] "Concatenate", "**@", evalcat, [Oacq] "Acquire", "@2", evalnop, [Orel] "Release", "@", evalnop, [Ostall] "Stall", "i", evalnop, [Osleep] "Sleep", "i", evalnop, + [Oload] "Load", "*@}", evalload, + [Ounload] "Unload", "@", evalnop, }; static uchar octab1[] = { @@ -1690,7 +1851,7 @@ /* 58 */ Onamec, Onamec, Onamec, Obad, Onamec, Obad, Onamec, Onamec, /* 60 */ Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, /* 68 */ Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Oenv, Obad, -/* 70 */ Ostore, Oref, Oadd, Obad, Osub, Oinc, Odec, Omul, +/* 70 */ Ostore, Oref, Oadd, Ocat, Osub, Oinc, Odec, Omul, /* 78 */ Odiv, Oshl, Oshr, Oand, Onand, Oor, Onor, Oxor, /* 80 */ Onot, Obad, Obad, Oderef, Obad, Omod, Obad, Osize, /* 88 */ Oindex, Obad, Ocfld4, Ocfld2, Ocfld1, Ocfld0, Obad, Ocfld8, @@ -1715,8 +1876,8 @@ /* 08 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 10 */ Obad, Obad, Ocref, Ocfld, Obad, Obad, Obad, Obad, /* 18 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, -/* 20 */ Obad, Ostall, Osleep, Oacq, Obad, Obad, Obad, Orel, -/* 28 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, +/* 20 */ Oload, Ostall, Osleep, Oacq, Obad, Obad, Obad, Orel, +/* 28 */ Obad, Obad, Ounload,Obad, Obad, Obad, Obad, Obad, /* 30 */ Obad, Odebug, Obad, Obad, Obad, Obad, Obad, Obad, /* 38 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 40 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,