Mercurial > repos > tabletprog
view modules/bytearray.tp @ 331:61f5b794d939
Breaking change: method call syntax now always uses the syntactic receiver as the actual receiver. This makes its behavior different from function call syntax, but solves some problems with methods being shadowed by local variables and the like.
author | Michael Pavone <pavone@retrodev.com> |
---|---|
date | Sat, 28 Mar 2015 14:21:04 -0700 |
parents | 4c669942c30d |
children | ff7ea11b4b60 |
line wrap: on
line source
#{ 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: 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: 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 } }