# HG changeset patch # User Mike Pavone # Date 1377363354 25200 # Node ID e823e104b84553d1bc05069d68da38b36ce0d831 # Parent 76e3d4ae1746d63227c5ee720ae64bbb17595947 Add initial work on bytearrays with support for allocating executable memory diff -r 76e3d4ae1746 -r e823e104b845 modules/bytearray.tp --- /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 + } +}