Davi Souza
/
pymite
python
Fork of pymite by
vm/bytearray.c@0:65f1469d6bfb, 2013-03-02 (annotated)
- Committer:
- va009039
- Date:
- Sat Mar 02 11:54:20 2013 +0000
- Revision:
- 0:65f1469d6bfb
- Child:
- 12:d27ad05214e3
first commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
va009039 | 0:65f1469d6bfb | 1 | /* |
va009039 | 0:65f1469d6bfb | 2 | # This file is Copyright 2010 Dean Hall. |
va009039 | 0:65f1469d6bfb | 3 | # This file is part of the PyMite VM. |
va009039 | 0:65f1469d6bfb | 4 | # This file is licensed under the MIT License. |
va009039 | 0:65f1469d6bfb | 5 | # See the LICENSE file for details. |
va009039 | 0:65f1469d6bfb | 6 | */ |
va009039 | 0:65f1469d6bfb | 7 | |
va009039 | 0:65f1469d6bfb | 8 | |
va009039 | 0:65f1469d6bfb | 9 | #undef __FILE_ID__ |
va009039 | 0:65f1469d6bfb | 10 | #define __FILE_ID__ 0x19 |
va009039 | 0:65f1469d6bfb | 11 | |
va009039 | 0:65f1469d6bfb | 12 | |
va009039 | 0:65f1469d6bfb | 13 | /** |
va009039 | 0:65f1469d6bfb | 14 | * \file |
va009039 | 0:65f1469d6bfb | 15 | * \brief VM Bytearray Type |
va009039 | 0:65f1469d6bfb | 16 | * |
va009039 | 0:65f1469d6bfb | 17 | * VM Bytearray object type operations. |
va009039 | 0:65f1469d6bfb | 18 | */ |
va009039 | 0:65f1469d6bfb | 19 | |
va009039 | 0:65f1469d6bfb | 20 | #include "pm.h" |
va009039 | 0:65f1469d6bfb | 21 | #ifdef HAVE_BYTEARRAY |
va009039 | 0:65f1469d6bfb | 22 | |
va009039 | 0:65f1469d6bfb | 23 | |
va009039 | 0:65f1469d6bfb | 24 | #define ROUND_UP_TO_MUL_OF_FOUR(n) n = (((n) + 3) & ~3) |
va009039 | 0:65f1469d6bfb | 25 | |
va009039 | 0:65f1469d6bfb | 26 | |
va009039 | 0:65f1469d6bfb | 27 | /* Returns a container that can hold at least n bytes */ |
va009039 | 0:65f1469d6bfb | 28 | static |
va009039 | 0:65f1469d6bfb | 29 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 30 | bytes_new(int16_t n, pPmObj_t *r_pobj) |
va009039 | 0:65f1469d6bfb | 31 | { |
va009039 | 0:65f1469d6bfb | 32 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 33 | pPmBytes_t pb = C_NULL; |
va009039 | 0:65f1469d6bfb | 34 | |
va009039 | 0:65f1469d6bfb | 35 | ROUND_UP_TO_MUL_OF_FOUR(n); |
va009039 | 0:65f1469d6bfb | 36 | |
va009039 | 0:65f1469d6bfb | 37 | /* Allocate a container */ |
va009039 | 0:65f1469d6bfb | 38 | retval = heap_getChunk(sizeof(PmBytes_t) + n, (uint8_t **)&pb); |
va009039 | 0:65f1469d6bfb | 39 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 40 | OBJ_SET_TYPE(pb, OBJ_TYPE_BYS); |
va009039 | 0:65f1469d6bfb | 41 | pb->length = n; |
va009039 | 0:65f1469d6bfb | 42 | |
va009039 | 0:65f1469d6bfb | 43 | *r_pobj = (pPmObj_t)pb; |
va009039 | 0:65f1469d6bfb | 44 | return retval; |
va009039 | 0:65f1469d6bfb | 45 | } |
va009039 | 0:65f1469d6bfb | 46 | |
va009039 | 0:65f1469d6bfb | 47 | |
va009039 | 0:65f1469d6bfb | 48 | /* Returns the int or one-char string as a byte */ |
va009039 | 0:65f1469d6bfb | 49 | static |
va009039 | 0:65f1469d6bfb | 50 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 51 | bytes_getByteFromObj(pPmObj_t pobj, uint8_t *b) |
va009039 | 0:65f1469d6bfb | 52 | { |
va009039 | 0:65f1469d6bfb | 53 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 54 | |
va009039 | 0:65f1469d6bfb | 55 | if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_INT) |
va009039 | 0:65f1469d6bfb | 56 | { |
va009039 | 0:65f1469d6bfb | 57 | if ((((pPmInt_t)pobj)->val > 255) || (((pPmInt_t)pobj)->val < 0)) |
va009039 | 0:65f1469d6bfb | 58 | { |
va009039 | 0:65f1469d6bfb | 59 | PM_RAISE(retval, PM_RET_EX_VAL); |
va009039 | 0:65f1469d6bfb | 60 | return retval; |
va009039 | 0:65f1469d6bfb | 61 | } |
va009039 | 0:65f1469d6bfb | 62 | |
va009039 | 0:65f1469d6bfb | 63 | *b = (uint8_t)((pPmInt_t)pobj)->val; |
va009039 | 0:65f1469d6bfb | 64 | } |
va009039 | 0:65f1469d6bfb | 65 | |
va009039 | 0:65f1469d6bfb | 66 | else if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_STR) |
va009039 | 0:65f1469d6bfb | 67 | { |
va009039 | 0:65f1469d6bfb | 68 | if (((pPmString_t)pobj)->length != 1) |
va009039 | 0:65f1469d6bfb | 69 | { |
va009039 | 0:65f1469d6bfb | 70 | PM_RAISE(retval, PM_RET_EX_VAL); |
va009039 | 0:65f1469d6bfb | 71 | return retval; |
va009039 | 0:65f1469d6bfb | 72 | } |
va009039 | 0:65f1469d6bfb | 73 | *b = ((pPmString_t)pobj)->val[0]; |
va009039 | 0:65f1469d6bfb | 74 | } |
va009039 | 0:65f1469d6bfb | 75 | |
va009039 | 0:65f1469d6bfb | 76 | else |
va009039 | 0:65f1469d6bfb | 77 | { |
va009039 | 0:65f1469d6bfb | 78 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 79 | } |
va009039 | 0:65f1469d6bfb | 80 | return retval; |
va009039 | 0:65f1469d6bfb | 81 | } |
va009039 | 0:65f1469d6bfb | 82 | |
va009039 | 0:65f1469d6bfb | 83 | |
va009039 | 0:65f1469d6bfb | 84 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 85 | bytearray_new(pPmObj_t pobj, pPmObj_t *r_pobj) |
va009039 | 0:65f1469d6bfb | 86 | { |
va009039 | 0:65f1469d6bfb | 87 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 88 | pPmBytearray_t pba = C_NULL; |
va009039 | 0:65f1469d6bfb | 89 | pPmBytes_t pb = C_NULL; |
va009039 | 0:65f1469d6bfb | 90 | pPmObj_t pitem; |
va009039 | 0:65f1469d6bfb | 91 | int32_t i; |
va009039 | 0:65f1469d6bfb | 92 | int16_t n; |
va009039 | 0:65f1469d6bfb | 93 | uint8_t b; |
va009039 | 0:65f1469d6bfb | 94 | uint8_t objid; |
va009039 | 0:65f1469d6bfb | 95 | |
va009039 | 0:65f1469d6bfb | 96 | /* If object is an instance, get the thing it is containing */ |
va009039 | 0:65f1469d6bfb | 97 | if (OBJ_GET_TYPE(pobj) == OBJ_TYPE_CLI) |
va009039 | 0:65f1469d6bfb | 98 | { |
va009039 | 0:65f1469d6bfb | 99 | retval = dict_getItem((pPmObj_t)((pPmInstance_t)pobj)->cli_attrs, |
va009039 | 0:65f1469d6bfb | 100 | PM_NONE, |
va009039 | 0:65f1469d6bfb | 101 | (pPmObj_t *)&pba); |
va009039 | 0:65f1469d6bfb | 102 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 103 | pobj = (pPmObj_t)pba; |
va009039 | 0:65f1469d6bfb | 104 | } |
va009039 | 0:65f1469d6bfb | 105 | |
va009039 | 0:65f1469d6bfb | 106 | /* Get the requested length of the new bytearray */ |
va009039 | 0:65f1469d6bfb | 107 | switch (OBJ_GET_TYPE(pobj)) |
va009039 | 0:65f1469d6bfb | 108 | { |
va009039 | 0:65f1469d6bfb | 109 | case OBJ_TYPE_INT: |
va009039 | 0:65f1469d6bfb | 110 | i = ((pPmInt_t)pobj)->val; |
va009039 | 0:65f1469d6bfb | 111 | if ((i < 0) || (i > 65535)) |
va009039 | 0:65f1469d6bfb | 112 | { |
va009039 | 0:65f1469d6bfb | 113 | PM_RAISE(retval, PM_RET_EX_VAL); |
va009039 | 0:65f1469d6bfb | 114 | return retval; |
va009039 | 0:65f1469d6bfb | 115 | } |
va009039 | 0:65f1469d6bfb | 116 | n = i; |
va009039 | 0:65f1469d6bfb | 117 | break; |
va009039 | 0:65f1469d6bfb | 118 | |
va009039 | 0:65f1469d6bfb | 119 | case OBJ_TYPE_STR: |
va009039 | 0:65f1469d6bfb | 120 | n = ((pPmString_t)pobj)->length; |
va009039 | 0:65f1469d6bfb | 121 | break; |
va009039 | 0:65f1469d6bfb | 122 | |
va009039 | 0:65f1469d6bfb | 123 | case OBJ_TYPE_LST: |
va009039 | 0:65f1469d6bfb | 124 | n = ((pPmList_t)pobj)->length; |
va009039 | 0:65f1469d6bfb | 125 | break; |
va009039 | 0:65f1469d6bfb | 126 | |
va009039 | 0:65f1469d6bfb | 127 | case OBJ_TYPE_TUP: |
va009039 | 0:65f1469d6bfb | 128 | n = ((pPmTuple_t)pobj)->length; |
va009039 | 0:65f1469d6bfb | 129 | break; |
va009039 | 0:65f1469d6bfb | 130 | |
va009039 | 0:65f1469d6bfb | 131 | case OBJ_TYPE_BYA: |
va009039 | 0:65f1469d6bfb | 132 | n = ((pPmBytearray_t)pobj)->length; |
va009039 | 0:65f1469d6bfb | 133 | break; |
va009039 | 0:65f1469d6bfb | 134 | |
va009039 | 0:65f1469d6bfb | 135 | default: |
va009039 | 0:65f1469d6bfb | 136 | PM_RAISE(retval, PM_RET_EX_TYPE); |
va009039 | 0:65f1469d6bfb | 137 | return retval; |
va009039 | 0:65f1469d6bfb | 138 | } |
va009039 | 0:65f1469d6bfb | 139 | |
va009039 | 0:65f1469d6bfb | 140 | /* Allocate a bytearray */ |
va009039 | 0:65f1469d6bfb | 141 | retval = heap_getChunk(sizeof(PmBytearray_t), (uint8_t **)&pba); |
va009039 | 0:65f1469d6bfb | 142 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 143 | OBJ_SET_TYPE(pba, OBJ_TYPE_BYA); |
va009039 | 0:65f1469d6bfb | 144 | pba->length = n; |
va009039 | 0:65f1469d6bfb | 145 | pba->val = C_NULL; |
va009039 | 0:65f1469d6bfb | 146 | |
va009039 | 0:65f1469d6bfb | 147 | /* Allocate the bytes container */ |
va009039 | 0:65f1469d6bfb | 148 | heap_gcPushTempRoot((pPmObj_t)pba, &objid); |
va009039 | 0:65f1469d6bfb | 149 | retval = bytes_new(n, (pPmObj_t *)&pb); |
va009039 | 0:65f1469d6bfb | 150 | heap_gcPopTempRoot(objid); |
va009039 | 0:65f1469d6bfb | 151 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 152 | pba->val = pb; |
va009039 | 0:65f1469d6bfb | 153 | |
va009039 | 0:65f1469d6bfb | 154 | /* Fill the bytes */ |
va009039 | 0:65f1469d6bfb | 155 | switch (OBJ_GET_TYPE(pobj)) |
va009039 | 0:65f1469d6bfb | 156 | { |
va009039 | 0:65f1469d6bfb | 157 | case OBJ_TYPE_INT: |
va009039 | 0:65f1469d6bfb | 158 | sli_memset((unsigned char *)&(pb->val), '\0', n); |
va009039 | 0:65f1469d6bfb | 159 | break; |
va009039 | 0:65f1469d6bfb | 160 | |
va009039 | 0:65f1469d6bfb | 161 | case OBJ_TYPE_BYA: |
va009039 | 0:65f1469d6bfb | 162 | pitem = (pPmObj_t)((pPmBytearray_t)pobj)->val; |
va009039 | 0:65f1469d6bfb | 163 | sli_memcpy(&(pb->val[0]), &(((pPmBytes_t)pitem)->val[0]), n); |
va009039 | 0:65f1469d6bfb | 164 | break; |
va009039 | 0:65f1469d6bfb | 165 | |
va009039 | 0:65f1469d6bfb | 166 | case OBJ_TYPE_STR: |
va009039 | 0:65f1469d6bfb | 167 | sli_memcpy(&(pb->val[0]), &(((pPmString_t)pobj)->val[0]), n); |
va009039 | 0:65f1469d6bfb | 168 | break; |
va009039 | 0:65f1469d6bfb | 169 | |
va009039 | 0:65f1469d6bfb | 170 | case OBJ_TYPE_LST: |
va009039 | 0:65f1469d6bfb | 171 | case OBJ_TYPE_TUP: |
va009039 | 0:65f1469d6bfb | 172 | for (i = 0; i < n; i++) |
va009039 | 0:65f1469d6bfb | 173 | { |
va009039 | 0:65f1469d6bfb | 174 | retval = seq_getSubscript(pobj, i, &pitem); |
va009039 | 0:65f1469d6bfb | 175 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 176 | retval = bytes_getByteFromObj(pitem, &b); |
va009039 | 0:65f1469d6bfb | 177 | PM_RETURN_IF_ERROR(retval); |
va009039 | 0:65f1469d6bfb | 178 | pb->val[i] = b; |
va009039 | 0:65f1469d6bfb | 179 | } |
va009039 | 0:65f1469d6bfb | 180 | break; |
va009039 | 0:65f1469d6bfb | 181 | } |
va009039 | 0:65f1469d6bfb | 182 | |
va009039 | 0:65f1469d6bfb | 183 | *r_pobj = (pPmObj_t)pba; |
va009039 | 0:65f1469d6bfb | 184 | return retval; |
va009039 | 0:65f1469d6bfb | 185 | } |
va009039 | 0:65f1469d6bfb | 186 | |
va009039 | 0:65f1469d6bfb | 187 | |
va009039 | 0:65f1469d6bfb | 188 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 189 | bytearray_getItem(pPmObj_t pobj, int16_t index, pPmObj_t *r_pobj) |
va009039 | 0:65f1469d6bfb | 190 | { |
va009039 | 0:65f1469d6bfb | 191 | PmReturn_t retval = PM_RET_OK; |
va009039 | 0:65f1469d6bfb | 192 | pPmBytearray_t pba; |
va009039 | 0:65f1469d6bfb | 193 | pPmBytes_t pb; |
va009039 | 0:65f1469d6bfb | 194 | int32_t n; |
va009039 | 0:65f1469d6bfb | 195 | |
va009039 | 0:65f1469d6bfb | 196 | pba = (pPmBytearray_t)pobj; |
va009039 | 0:65f1469d6bfb | 197 | |
va009039 | 0:65f1469d6bfb | 198 | /* Adjust a negative index */ |
va009039 | 0:65f1469d6bfb | 199 | if (index < 0) |
va009039 | 0:65f1469d6bfb | 200 | { |
va009039 | 0:65f1469d6bfb | 201 | index += pba->length; |
va009039 | 0:65f1469d6bfb | 202 | } |
va009039 | 0:65f1469d6bfb | 203 | |
va009039 | 0:65f1469d6bfb | 204 | /* Check the bounds of the index */ |
va009039 | 0:65f1469d6bfb | 205 | if ((index < 0) || (index >= pba->length)) |
va009039 | 0:65f1469d6bfb | 206 | { |
va009039 | 0:65f1469d6bfb | 207 | PM_RAISE(retval, PM_RET_EX_INDX); |
va009039 | 0:65f1469d6bfb | 208 | return retval; |
va009039 | 0:65f1469d6bfb | 209 | } |
va009039 | 0:65f1469d6bfb | 210 | |
va009039 | 0:65f1469d6bfb | 211 | /* Create int from byte at index */ |
va009039 | 0:65f1469d6bfb | 212 | pb = pba->val; |
va009039 | 0:65f1469d6bfb | 213 | n = (int32_t)pb->val[index]; |
va009039 | 0:65f1469d6bfb | 214 | retval = int_new(n, r_pobj); |
va009039 | 0:65f1469d6bfb | 215 | |
va009039 | 0:65f1469d6bfb | 216 | return retval; |
va009039 | 0:65f1469d6bfb | 217 | } |
va009039 | 0:65f1469d6bfb | 218 | |
va009039 | 0:65f1469d6bfb | 219 | |
va009039 | 0:65f1469d6bfb | 220 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 221 | bytearray_setItem(pPmObj_t pba, int16_t index, pPmObj_t pobj) |
va009039 | 0:65f1469d6bfb | 222 | { |
va009039 | 0:65f1469d6bfb | 223 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 224 | pPmBytes_t pb; |
va009039 | 0:65f1469d6bfb | 225 | uint8_t b = 0; |
va009039 | 0:65f1469d6bfb | 226 | |
va009039 | 0:65f1469d6bfb | 227 | /* Adjust a negative index */ |
va009039 | 0:65f1469d6bfb | 228 | if (index < 0) |
va009039 | 0:65f1469d6bfb | 229 | { |
va009039 | 0:65f1469d6bfb | 230 | index += ((pPmBytearray_t)pba)->length; |
va009039 | 0:65f1469d6bfb | 231 | } |
va009039 | 0:65f1469d6bfb | 232 | |
va009039 | 0:65f1469d6bfb | 233 | /* Check the bounds of the index */ |
va009039 | 0:65f1469d6bfb | 234 | if ((index < 0) || (index >= ((pPmBytearray_t)pba)->length)) |
va009039 | 0:65f1469d6bfb | 235 | { |
va009039 | 0:65f1469d6bfb | 236 | PM_RAISE(retval, PM_RET_EX_INDX); |
va009039 | 0:65f1469d6bfb | 237 | return retval; |
va009039 | 0:65f1469d6bfb | 238 | } |
va009039 | 0:65f1469d6bfb | 239 | |
va009039 | 0:65f1469d6bfb | 240 | /* Set the item */ |
va009039 | 0:65f1469d6bfb | 241 | retval = bytes_getByteFromObj(pobj, &b); |
va009039 | 0:65f1469d6bfb | 242 | pb = ((pPmBytearray_t)pba)->val; |
va009039 | 0:65f1469d6bfb | 243 | pb->val[index] = b; |
va009039 | 0:65f1469d6bfb | 244 | |
va009039 | 0:65f1469d6bfb | 245 | return retval; |
va009039 | 0:65f1469d6bfb | 246 | } |
va009039 | 0:65f1469d6bfb | 247 | |
va009039 | 0:65f1469d6bfb | 248 | |
va009039 | 0:65f1469d6bfb | 249 | #ifdef HAVE_PRINT |
va009039 | 0:65f1469d6bfb | 250 | PmReturn_t |
va009039 | 0:65f1469d6bfb | 251 | bytearray_print(pPmObj_t pobj) |
va009039 | 0:65f1469d6bfb | 252 | { |
va009039 | 0:65f1469d6bfb | 253 | PmReturn_t retval; |
va009039 | 0:65f1469d6bfb | 254 | pPmBytes_t pb; |
va009039 | 0:65f1469d6bfb | 255 | |
va009039 | 0:65f1469d6bfb | 256 | obj_print(PM_BYTEARRAY_STR, C_FALSE, C_FALSE); |
va009039 | 0:65f1469d6bfb | 257 | plat_putByte('('); |
va009039 | 0:65f1469d6bfb | 258 | plat_putByte('b'); |
va009039 | 0:65f1469d6bfb | 259 | pb = ((pPmBytearray_t)pobj)->val; |
va009039 | 0:65f1469d6bfb | 260 | retval = string_printFormattedBytes(&(pb->val[0]), |
va009039 | 0:65f1469d6bfb | 261 | C_TRUE, |
va009039 | 0:65f1469d6bfb | 262 | ((pPmBytearray_t)pobj)->length); |
va009039 | 0:65f1469d6bfb | 263 | plat_putByte(')'); |
va009039 | 0:65f1469d6bfb | 264 | return retval; |
va009039 | 0:65f1469d6bfb | 265 | } |
va009039 | 0:65f1469d6bfb | 266 | #endif /* HAVE_PRINT */ |
va009039 | 0:65f1469d6bfb | 267 | #endif /* HAVE_BYTEARRAY */ |