summaryrefslogtreecommitdiff
path: root/sys/src/libaml
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-06-04 22:11:01 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-06-04 22:11:01 +0200
commit60fd776d37840b8cf47cff56b08a5e93017eb740 (patch)
treee6c17868c42cd285815d2e4a958fa3e3002e7fb3 /sys/src/libaml
parentbc9df6c60c7d2346aa89674b3b7ba26b5d3e97ad (diff)
libaml: various fixes found by plhk
- fix bogus execution of Else{} blocks - always allocate Env in amleval() - add Sleep() and Stall() instructions - keep package size for packages with empty body
Diffstat (limited to 'sys/src/libaml')
-rw-r--r--sys/src/libaml/aml.c42
1 files changed, 27 insertions, 15 deletions
diff --git a/sys/src/libaml/aml.c b/sys/src/libaml/aml.c
index a08211ac6..e24499f4a 100644
--- a/sys/src/libaml/aml.c
+++ b/sys/src/libaml/aml.c
@@ -126,6 +126,7 @@ struct Op {
struct Frame {
int tag;
+ int cond;
char *phase;
uchar *start;
uchar *end;
@@ -141,7 +142,6 @@ struct Frame {
struct Interp {
uchar *pc;
Frame *fp;
- int cond;
};
static Interp interp;
@@ -167,7 +167,7 @@ enum {
Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8,
Oif, Oelse, Owhile, Obreak, Oret, Ocall,
Ostore, Oderef, Osize, Oref, Ocref,
- Oacq, Orel,
+ Oacq, Orel, Ostall, Osleep,
};
static Op optab[];
@@ -798,6 +798,7 @@ xec(uchar *pc, uchar *end, Name *dot, Env *env, void **pret){
FP = FB;
FP->tag = 0;
+ FP->cond = 0;
FP->narg = 0;
FP->phase = "}";
FP->start = PC;
@@ -812,7 +813,7 @@ xec(uchar *pc, uchar *end, Name *dot, Env *env, void **pret){
if((++loop & 127) == 0)
gc();
if(amldebug)
- print("\n%.8p.%.2lx %-8s %d\t%N\t", PC, FP - FB, FP->phase, interp.cond, FP->dot);
+ print("\n%.8p.%.2lx %-8s\t%N\t", PC, FP - FB, FP->phase, FP->dot);
r = nil;
c = *FP->phase++;
switch(c){
@@ -1030,15 +1031,21 @@ evalbuf(void){
static void*
evalpkg(void){
Package *p;
+ void **x;
int n;
if(p = FP->ref){
- n = sizeof(Package)+p->n*sizeof(void*);
- if(n < SIZE(p))
- p->a[p->n++] = FP->arg[0];
+ x = FP->aux;
+ if(x >= &p->a[0] && x < &p->a[p->n]){
+ *x++ = FP->arg[0];
+ FP->aux = x;
+ }
}else {
- n = sizeof(Package)+ival(FP->arg[0])*sizeof(void*);
- p = mk('p', n);
+ n = ival(FP->arg[0]);
+ if(n < 0) n = 0;
+ p = mk('p', sizeof(Package) + n*sizeof(void*));
+ p->n = n;
+ FP->aux = p->a;
FP->ref = p;
}
return p;
@@ -1244,12 +1251,16 @@ static void*
evalcond(void){
switch(FP->op - optab){
case Oif:
- interp.cond = ival(FP->arg[0]) != 0;
- if(!interp.cond)
+ if(FP <= FB)
+ break;
+ FP[-1].cond = ival(FP->arg[0]) != 0;
+ if(!FP[-1].cond)
PC = FP->end;
break;
case Oelse:
- if(interp.cond)
+ if(FP <= FB)
+ break;
+ if(FP[-1].cond)
PC = FP->end;
break;
case Owhile:
@@ -1261,8 +1272,7 @@ evalcond(void){
return nil;
}
FP->aux = FP->end;
- interp.cond = ival(FP->arg[0]) != 0;
- if(!interp.cond){
+ if(ival(FP->arg[0]) == 0){
PC = FP->end;
break;
}
@@ -1616,6 +1626,8 @@ static Op optab[] = {
[Oacq] "Acquire", "@2", evalnop,
[Orel] "Release", "@", evalnop,
+ [Ostall] "Stall", "i", evalnop,
+ [Osleep] "Sleep", "i", evalnop,
};
static uchar octab1[] = {
@@ -1658,7 +1670,7 @@ static uchar octab2[] = {
/* 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, Obad, Obad, Oacq, Obad, Obad, Obad, Orel,
+/* 20 */ Obad, Ostall, Osleep, Oacq, Obad, Obad, Obad, Orel,
/* 28 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
/* 30 */ Obad, Odebug, Obad, Obad, Obad, Obad, Obad, Obad,
/* 38 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
@@ -1801,7 +1813,7 @@ amleval(void *dot, char *fmt, ...){
int i;
va_start(a, fmt);
- e = *fmt ? mk('E', sizeof(Env)) : nil;
+ e = mk('E', sizeof(Env));
for(i=0;*fmt;fmt++){
switch(*fmt){
case 's':