changeset 178:e823e104b845

Add initial work on bytearrays with support for allocating executable memory
author Mike Pavone <pavone@retrodev.com>
date Sat, 24 Aug 2013 09:55:54 -0700
parents 76e3d4ae1746
children 75aca5f87969
files modules/bytearray.tp
diffstat 1 files changed, 69 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/bytearray.tp	Sat Aug 24 09:55:54 2013 -0700
@@ -0,0 +1,69 @@
+#{
+	includeSystemHeader: "unistd.h"
+	includeSystemHeader: "sys/mman.h"
+
+	executable <- :size {
+		buf <- #{
+			llProperty: bytes withType: uint32_t
+			llProperty: buffer withType: (void ptr)
+			llMessage: _init withVars: {
+				sz <- obj_int32 ptr
+			} andCode: :sz {
+				bytes <- sz num
+				buffer <- sbrk: bytes
+				mprotect: buffer bytes (PROT_READ or PROT_WRITE or PROT_EXEC)
+				self
+			}
+			llMessage: set withVars: {
+				offset <- obj_int32 ptr
+				newval <- obj_uint8 ptr
+			} andCode: :offset newval {
+				(buffer castTo: (uint8_t ptr)) set: (offset num) (newval num)
+				self
+			}
+			llMessage: get withVars: {
+				offset <- obj_int32 ptr
+				ret <- obj_uint8 ptr
+			} andCode: :offset {
+				ret <- make_object: (addr_of: obj_uint8_meta) NULL 0
+				ret num!: ((buffer castTo: (uint8_t ptr)) get: (offset num))
+				ret
+			}
+			llMessage: run withVars: {
+				fun <- uint64_t funptr
+				funret <- obj_uint64 ptr
+			} andCode: {
+				funret <- make_object: (addr_of: obj_uint64_meta) NULL 0
+				fun <- buffer
+				funret num!: ( fun: )
+				funret
+			}
+
+			llMessage: runWithArg withVars: {
+				fun <- uint64_t funptr: uint64_t
+				funret <- obj_uint64 ptr
+				arg <- obj_uint64 ptr
+			} andCode: :arg {
+				fun <- buffer
+				funret <- make_object: (addr_of: obj_uint64_meta) NULL 0
+				funret num!: ( fun: (arg num) )
+				funret
+			}
+		}
+		buf _init
+	}
+
+	executableFromBytes <- :bytes {
+		totalSize <- bytes fold: 0 with: :acc el {
+			acc + (el length)
+		}
+		ba <- executable: totalSize
+		bytes fold: 0 with: :idx el {
+			el fold: idx with: :idx byte {
+				ba set: idx byte
+				idx + 1
+			}
+		}
+		ba
+	}
+}