git: 9front

Download patch

ref: a688aaa66f920d3c20f8ae9aa3bce74c30cf35a5
parent: fcaca10d9ff0e2363519f5f3b88693ec98473f6f
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sat Jun 29 18:14:34 EDT 2013

libaml: add Load and Unload instructions

not very usefull at the moment as theres no code to map/unmap
memory regions right now.

--- a/sys/src/libaml/aml.c
+++ b/sys/src/libaml/aml.c
@@ -86,7 +86,7 @@
 	int	space;
 	uvlong	off;
 	uvlong	len;
-	uchar	*va;
+	uchar	*va;	/* non nil when mapped */
 };
 
 struct Field {
@@ -168,7 +168,7 @@
 	Ocfld, Ocfld0, Ocfld1, Ocfld2, Ocfld4, Ocfld8,
 	Oif, Oelse, Owhile, Obreak, Oret, Ocall, 
 	Ostore, Oderef, Osize, Oref, Ocref,
-	Oacq, Orel, Ostall, Osleep,
+	Oacq, Orel, Ostall, Osleep, Oload, Ounload,
 };
 
 static Op optab[];
@@ -269,6 +269,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++;
@@ -459,6 +465,7 @@
 		p = reg;
 		if((off+len) > SIZE(p))
 			break;
+	RWMem:
 		if(write){
 			for(i=0; i<len; i++){
 				p[off+i] = v & 0xFF;
@@ -479,6 +486,11 @@
 				spacename[r->space],
 				r->off, off, len, v);
 		}
+		/* TODO: map region */
+		if(r->va != nil){
+			p = r->va + off;
+			goto RWMem;
+		}
 		break;
 	}
 
@@ -1130,12 +1142,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;
@@ -1585,6 +1598,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,
@@ -1670,6 +1736,8 @@
 	[Orel]		"Release",		"@",		evalnop,
 	[Ostall]	"Stall",		"i",		evalnop,
 	[Osleep]	"Sleep",		"i",		evalnop,
+	[Oload] 	"Load", 		"*@}", 		evalload,
+	[Ounload]	"Unload",		"@",		evalnop,
 };
 
 static uchar octab1[] = {
@@ -1712,8 +1780,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,
--