libaml: add Load and Unload instructions

not very usefull at the moment as theres no code to map/unmap
memory regions right now.
This commit is contained in:
cinap_lenrek 2013-06-29 22:14:34 +02:00
parent 639cec9329
commit 1bf892cc67

View file

@ -86,7 +86,7 @@ struct Region {
int space; int space;
uvlong off; uvlong off;
uvlong len; uvlong len;
uchar *va; uchar *va; /* non nil when mapped */
}; };
struct Field { struct Field {
@ -168,7 +168,7 @@ enum {
Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8, Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8,
Oif, Oelse, Owhile, Obreak, Oret, Ocall, Oif, Oelse, Owhile, Obreak, Oret, Ocall,
Ostore, Oderef, Osize, Oref, Ocref, Ostore, Oderef, Osize, Oref, Ocref,
Oacq, Orel, Ostall, Osleep, Oacq, Orel, Ostall, Osleep, Oload, Ounload,
}; };
static Op optab[]; static Op optab[];
@ -269,6 +269,12 @@ gc(void)
continue; continue;
} }
*hh = h->link; *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); memset(h, ~0, sizeof(Heap)+h->size);
amlfree(h); amlfree(h);
i++; i++;
@ -459,6 +465,7 @@ rwreg(void *reg, int off, int len, uvlong v, int write)
p = reg; p = reg;
if((off+len) > SIZE(p)) if((off+len) > SIZE(p))
break; break;
RWMem:
if(write){ if(write){
for(i=0; i<len; i++){ for(i=0; i<len; i++){
p[off+i] = v & 0xFF; p[off+i] = v & 0xFF;
@ -479,6 +486,11 @@ rwreg(void *reg, int off, int len, uvlong v, int write)
spacename[r->space], spacename[r->space],
r->off, off, len, v); r->off, off, len, v);
} }
/* TODO: map region */
if(r->va != nil){
p = r->va + off;
goto RWMem;
}
break; break;
} }
@ -1130,12 +1142,13 @@ evalreg(void)
Name *n; Name *n;
Region *r; Region *r;
if(n = FP->arg[0]){ if((n = FP->arg[0]) != nil){
r = mk('r', sizeof(Region)); r = mk('r', sizeof(Region));
r->space = ival(FP->arg[1]); r->space = ival(FP->arg[1]);
r->off = ival(FP->arg[2]); r->off = ival(FP->arg[2]);
r->len = ival(FP->arg[3]); r->len = ival(FP->arg[3]);
r->name = n; r->name = n;
r->va = nil;
n->v = r; n->v = r;
} }
return nil; return nil;
@ -1585,6 +1598,59 @@ evalarith(void)
return r; 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[] = { static Op optab[] = {
[Obad] "", "", evalbad, [Obad] "", "", evalbad,
[Onop] "Noop", "", evalnop, [Onop] "Noop", "", evalnop,
@ -1670,6 +1736,8 @@ static Op optab[] = {
[Orel] "Release", "@", evalnop, [Orel] "Release", "@", evalnop,
[Ostall] "Stall", "i", evalnop, [Ostall] "Stall", "i", evalnop,
[Osleep] "Sleep", "i", evalnop, [Osleep] "Sleep", "i", evalnop,
[Oload] "Load", "*@}", evalload,
[Ounload] "Unload", "@", evalnop,
}; };
static uchar octab1[] = { static uchar octab1[] = {
@ -1712,8 +1780,8 @@ static uchar octab2[] = {
/* 08 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 08 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
/* 10 */ Obad, Obad, Ocref, Ocfld, Obad, Obad, Obad, Obad, /* 10 */ Obad, Obad, Ocref, Ocfld, Obad, Obad, Obad, Obad,
/* 18 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 18 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
/* 20 */ Obad, Ostall, Osleep, Oacq, Obad, Obad, Obad, Orel, /* 20 */ Oload, Ostall, Osleep, Oacq, Obad, Obad, Obad, Orel,
/* 28 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 28 */ Obad, Obad, Ounload,Obad, Obad, Obad, Obad, Obad,
/* 30 */ Obad, Odebug, Obad, Obad, Obad, Obad, Obad, Obad, /* 30 */ Obad, Odebug, Obad, Obad, Obad, Obad, Obad, Obad,
/* 38 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 38 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,
/* 40 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad, /* 40 */ Obad, Obad, Obad, Obad, Obad, Obad, Obad, Obad,