#{ includeSystemHeader: "unistd.h" includeSystemHeader: "sys/mman.h" fromOpaque:withSize <- :opaque :size{ #{ llProperty: bytes withType: uint32_t llProperty: buffer withType: (void ptr) llMessage: _init_buf withVars: { sz <- obj_int32 ptr opaque <- cpointer ptr } andCode: :opaque sz { bytes <- sz num buffer <- (opaque val) self } llMessage: _buf_ptr withVars: { ptrret <- cpointer ptr } andCode: { ptrret <- make_object: (addr_of: cpointer_meta) NULL 0 ptrret val!: buffer ptrret } llMessage: length withVars: { intret <- obj_int32 ptr } andCode: { intret <- make_object: (addr_of: obj_int32_meta) NULL 0 intret num!: bytes intret } 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: shrinkTo withVars: { newsize <- obj_int32 ptr } andCode: :newsize { if: (newsize num) < bytes { bytes <- newsize num } self } llMessage: clone withVars: { opaque <- cpointer ptr szo <- obj_int32 ptr } andCode: { opaque <- make_object: (addr_of: cpointer_meta) NULL 0 opaque val!: (GC_MALLOC_ATOMIC: bytes) memcpy: (opaque val) buffer bytes szo <- make_object: (addr_of: obj_int32_meta) NULL 0 szo num!: bytes mcall: fromOpaque:withSize 3 bytearray opaque szo } llMessage: stringFrom:to withVars: { from <- obj_int32 ptr to <- obj_int32 ptr str <- string ptr } andCode: :from :to { //probably should do some UTF-8 validation at some point str <- make_object: (addr_of: string_meta) NULL 0 str bytes!: (to num) - (from num) str len!: (str bytes) str data!: (GC_MALLOC_ATOMIC: (str bytes) + 1) memcpy: (str data) (buffer castTo: (uint8_t ptr)) + (from num) (str bytes) (str data) set: (str bytes) 0 str } string <- { stringFrom: 0 to: length } findChar:from:else <- :char :start found :else { notfound <- true n <- length i <- start while: { notfound && i < n } do: { if: (get: i) = char { notfound <- false } else: { i <- i + 1 } } if: notfound else else: { found: i } } } _init_buf: opaque size } normal <- :size { helper <- #{ llMessage: alloc withVars: { size <- obj_int32 ptr opaqueret <- cpointer ptr } andCode: :size { opaqueret <- make_object: (addr_of: cpointer_meta) NULL 0 opaqueret val!: (GC_MALLOC_ATOMIC: (size num)) opaqueret } } fromOpaque: (helper alloc: size) withSize: size } 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: _buf_ptr withVars: { ptrret <- cpointer ptr } andCode: { ptrret <- make_object: (addr_of: cpointer_meta) NULL 0 ptrret val!: buffer ptrret } llMessage: length withVars: { intret <- obj_int32 ptr } andCode: { intret <- make_object: (addr_of: obj_int32_meta) NULL 0 intret num!: bytes intret } 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: size } executableFromBytes <- :bytes { totalSize <- bytes fold: 0 with: :acc el { acc + (el length) } ba <- executable: totalSize bytes fold: 0 with: :idx el { el flattenTo: ba at: idx } ba } main <- { str <- "foobarbaz\n" buf <- normal: (str byte_length) i <- 0 while: { i < (str byte_length) } do: { buf set: i (str byte: i) i <- i + 1 } print: (string: buf) print: (string: (buf clone)) } }