blob: e38aae8ea3908a5e2994ebe63986c0736d54268a [file] [log] [blame]
Damien George04b91472014-05-03 23:27:38 +01001/*
Alexander Steffen55f33242017-06-30 09:22:17 +02002 * This file is part of the MicroPython project, http://micropython.org/
Damien George04b91472014-05-03 23:27:38 +01003 *
4 * The MIT License (MIT)
5 *
6 * Copyright (c) 2013, 2014 Damien P. George
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
Paul Sokolovsky8bc35162014-02-14 17:16:35 +020027#include <stdint.h>
Paul Sokolovsky1355cf42014-04-19 01:25:49 +030028#include <stdlib.h>
Paul Sokolovskyecca53b2014-08-10 20:16:39 +030029#include <stddef.h>
Paul Sokolovsky62798832014-06-02 16:04:26 +030030#include <string.h>
Paul Sokolovsky8bc35162014-02-14 17:16:35 +020031#include <assert.h>
32
Damien George51dfcb42015-01-01 20:27:54 +000033#include "py/binary.h"
34#include "py/smallint.h"
Damien George271d18e2015-04-25 23:16:39 +010035#include "py/objint.h"
Paul Sokolovskyaf904612017-01-17 22:50:20 +030036#include "py/runtime.h"
Paul Sokolovsky8bc35162014-02-14 17:16:35 +020037
38// Helpers to work with binary-encoded data
39
Paul Sokolovskyecca53b2014-08-10 20:16:39 +030040#ifndef alignof
41#define alignof(type) offsetof(struct { char c; type t; }, t)
42#endif
43
Kaspar Schleiserf5dd6f72015-05-10 13:04:38 +020044size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) {
45 size_t size = 0;
Paul Sokolovsky1355cf42014-04-19 01:25:49 +030046 int align = 1;
47 switch (struct_type) {
48 case '<': case '>':
49 switch (val_type) {
50 case 'b': case 'B':
51 size = 1; break;
52 case 'h': case 'H':
53 size = 2; break;
54 case 'i': case 'I':
55 size = 4; break;
56 case 'l': case 'L':
57 size = 4; break;
58 case 'q': case 'Q':
59 size = 8; break;
Paul Sokolovsky78fde482014-09-06 19:24:52 +030060 case 'P': case 'O': case 'S':
61 size = sizeof(void*); break;
Damien Georgec9f8f652014-11-21 18:16:25 +000062 case 'f':
63 size = sizeof(float); break;
64 case 'd':
65 size = sizeof(double); break;
Paul Sokolovsky1355cf42014-04-19 01:25:49 +030066 }
67 break;
68 case '@': {
69 // TODO:
70 // The simplest heuristic for alignment is to align by value
71 // size, but that doesn't work for "bigger than int" types,
72 // for example, long long may very well have long alignment
73 // So, we introduce separate alignment handling, but having
74 // formal support for that is different from actually supporting
75 // particular (or any) ABI.
76 switch (val_type) {
77 case BYTEARRAY_TYPECODE:
78 case 'b': case 'B':
79 align = size = 1; break;
80 case 'h': case 'H':
Paul Sokolovskyecca53b2014-08-10 20:16:39 +030081 align = alignof(short);
82 size = sizeof(short); break;
Paul Sokolovsky1355cf42014-04-19 01:25:49 +030083 case 'i': case 'I':
Paul Sokolovskyecca53b2014-08-10 20:16:39 +030084 align = alignof(int);
85 size = sizeof(int); break;
Paul Sokolovsky1355cf42014-04-19 01:25:49 +030086 case 'l': case 'L':
Paul Sokolovskyecca53b2014-08-10 20:16:39 +030087 align = alignof(long);
88 size = sizeof(long); break;
Paul Sokolovsky1355cf42014-04-19 01:25:49 +030089 case 'q': case 'Q':
Paul Sokolovskyecca53b2014-08-10 20:16:39 +030090 align = alignof(long long);
91 size = sizeof(long long); break;
Paul Sokolovsky62798832014-06-02 16:04:26 +030092 case 'P': case 'O': case 'S':
Paul Sokolovskyecca53b2014-08-10 20:16:39 +030093 align = alignof(void*);
94 size = sizeof(void*); break;
Damien Georgec9f8f652014-11-21 18:16:25 +000095 case 'f':
96 align = alignof(float);
97 size = sizeof(float); break;
98 case 'd':
99 align = alignof(double);
100 size = sizeof(double); break;
Paul Sokolovsky1355cf42014-04-19 01:25:49 +0300101 }
102 }
Paul Sokolovskyc2033242014-02-14 20:21:50 +0200103 }
Paul Sokolovskyaf904612017-01-17 22:50:20 +0300104
105 if (size == 0) {
106 mp_raise_ValueError("bad typecode");
107 }
108
Paul Sokolovsky1355cf42014-04-19 01:25:49 +0300109 if (palign != NULL) {
110 *palign = align;
111 }
112 return size;
Paul Sokolovskyc2033242014-02-14 20:21:50 +0200113}
114
Damien George42f3de92014-10-03 17:44:14 +0000115mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) {
Damien George40f3c022014-07-03 13:25:24 +0100116 mp_int_t val = 0;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200117 switch (typecode) {
118 case 'b':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200119 val = ((signed char*)p)[index];
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200120 break;
121 case BYTEARRAY_TYPECODE:
122 case 'B':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200123 val = ((unsigned char*)p)[index];
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200124 break;
125 case 'h':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200126 val = ((short*)p)[index];
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200127 break;
128 case 'H':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200129 val = ((unsigned short*)p)[index];
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200130 break;
131 case 'i':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200132 return mp_obj_new_int(((int*)p)[index]);
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200133 case 'I':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200134 return mp_obj_new_int_from_uint(((unsigned int*)p)[index]);
135 case 'l':
136 return mp_obj_new_int(((long*)p)[index]);
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200137 case 'L':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200138 return mp_obj_new_int_from_uint(((unsigned long*)p)[index]);
Damien George81794fc2015-09-01 16:25:29 +0100139 #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200140 case 'q':
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200141 return mp_obj_new_int_from_ll(((long long*)p)[index]);
Damien George81794fc2015-09-01 16:25:29 +0100142 case 'Q':
143 return mp_obj_new_int_from_ull(((unsigned long long*)p)[index]);
144 #endif
Damien Georgefb510b32014-06-01 13:32:54 +0100145#if MICROPY_PY_BUILTINS_FLOAT
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200146 case 'f':
147 return mp_obj_new_float(((float*)p)[index]);
148 case 'd':
149 return mp_obj_new_float(((double*)p)[index]);
150#endif
Paul Sokolovsky24c10002015-03-05 22:57:36 +0200151 // Extension to CPython: array of objects
152 case 'O':
153 return ((mp_obj_t*)p)[index];
Paul Sokolovsky91fc0752015-10-12 10:10:39 +0300154 // Extension to CPython: array of pointers
155 case 'P':
Damien George999cedb2015-11-27 17:01:44 +0000156 return mp_obj_new_int((mp_int_t)(uintptr_t)((void**)p)[index]);
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200157 }
158 return MP_OBJ_NEW_SMALL_INT(val);
159}
160
Damien George95307432014-09-10 22:10:33 +0100161// The long long type is guaranteed to hold at least 64 bits, and size is at
162// most 8 (for q and Q), so we will always be able to parse the given data
163// and fit it into a long long.
Damien George9336ee32014-10-06 15:05:35 +0000164long long mp_binary_get_int(mp_uint_t size, bool is_signed, bool big_endian, const byte *src) {
Paul Sokolovsky7a2f1662014-06-25 22:25:53 +0300165 int delta;
166 if (!big_endian) {
167 delta = -1;
Damien George9336ee32014-10-06 15:05:35 +0000168 src += size - 1;
Paul Sokolovsky7a2f1662014-06-25 22:25:53 +0300169 } else {
170 delta = 1;
171 }
172
Damien George95307432014-09-10 22:10:33 +0100173 long long val = 0;
Damien George9336ee32014-10-06 15:05:35 +0000174 if (is_signed && *src & 0x80) {
Paul Sokolovsky7a2f1662014-06-25 22:25:53 +0300175 val = -1;
176 }
177 for (uint i = 0; i < size; i++) {
178 val <<= 8;
Damien George9336ee32014-10-06 15:05:35 +0000179 val |= *src;
180 src += delta;
Paul Sokolovsky7a2f1662014-06-25 22:25:53 +0300181 }
182
183 return val;
184}
185
Paul Sokolovsky6582d642014-04-10 22:19:32 +0300186#define is_signed(typecode) (typecode > 'Z')
Paul Sokolovsky0c43cf92014-04-11 03:47:21 +0300187mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
Paul Sokolovskye9db8402014-04-10 03:45:38 +0300188 byte *p = *ptr;
Damien George4abff752014-08-30 14:59:21 +0100189 mp_uint_t align;
Paul Sokolovsky1355cf42014-04-19 01:25:49 +0300190
Kaspar Schleiserf5dd6f72015-05-10 13:04:38 +0200191 size_t size = mp_binary_get_size(struct_type, val_type, &align);
Paul Sokolovsky1355cf42014-04-19 01:25:49 +0300192 if (struct_type == '@') {
193 // Make pointer aligned
Damien George88a91032015-11-27 12:05:11 +0000194 p = (byte*)MP_ALIGN(p, (size_t)align);
Paul Sokolovsky1355cf42014-04-19 01:25:49 +0300195 #if MP_ENDIANNESS_LITTLE
196 struct_type = '<';
197 #else
198 struct_type = '>';
199 #endif
Paul Sokolovskye9db8402014-04-10 03:45:38 +0300200 }
Paul Sokolovsky7a2f1662014-06-25 22:25:53 +0300201 *ptr = p + size;
Paul Sokolovsky6582d642014-04-10 22:19:32 +0300202
Damien George95307432014-09-10 22:10:33 +0100203 long long val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p);
Paul Sokolovsky6582d642014-04-10 22:19:32 +0300204
Paul Sokolovsky0f836ef2014-04-20 05:19:10 +0300205 if (val_type == 'O') {
Damien George95307432014-09-10 22:10:33 +0100206 return (mp_obj_t)(mp_uint_t)val;
Paul Sokolovsky62798832014-06-02 16:04:26 +0300207 } else if (val_type == 'S') {
Damien George999cedb2015-11-27 17:01:44 +0000208 const char *s_val = (const char*)(uintptr_t)(mp_uint_t)val;
Damien George95307432014-09-10 22:10:33 +0100209 return mp_obj_new_str(s_val, strlen(s_val), false);
David Steinberg0b3014c2015-01-25 02:50:34 +0000210#if MICROPY_PY_BUILTINS_FLOAT
211 } else if (val_type == 'f') {
212 union { uint32_t i; float f; } fpu = {val};
213 return mp_obj_new_float(fpu.f);
214 } else if (val_type == 'd') {
215 union { uint64_t i; double f; } fpu = {val};
216 return mp_obj_new_float(fpu.f);
217#endif
Paul Sokolovsky0f836ef2014-04-20 05:19:10 +0300218 } else if (is_signed(val_type)) {
Damien George95307432014-09-10 22:10:33 +0100219 if ((long long)MP_SMALL_INT_MIN <= val && val <= (long long)MP_SMALL_INT_MAX) {
220 return mp_obj_new_int((mp_int_t)val);
221 } else {
222 return mp_obj_new_int_from_ll(val);
223 }
Paul Sokolovsky6582d642014-04-10 22:19:32 +0300224 } else {
Damien George95307432014-09-10 22:10:33 +0100225 if ((unsigned long long)val <= (unsigned long long)MP_SMALL_INT_MAX) {
226 return mp_obj_new_int_from_uint((mp_uint_t)val);
227 } else {
228 return mp_obj_new_int_from_ull(val);
229 }
Paul Sokolovsky6582d642014-04-10 22:19:32 +0300230 }
Paul Sokolovskye9db8402014-04-10 03:45:38 +0300231}
232
Damien George9336ee32014-10-06 15:05:35 +0000233void mp_binary_set_int(mp_uint_t val_sz, bool big_endian, byte *dest, mp_uint_t val) {
234 if (MP_ENDIANNESS_LITTLE && !big_endian) {
235 memcpy(dest, &val, val_sz);
236 } else if (MP_ENDIANNESS_BIG && big_endian) {
237 // only copy the least-significant val_sz bytes
238 memcpy(dest, (byte*)&val + sizeof(mp_uint_t) - val_sz, val_sz);
Paul Sokolovsky5fa5ca42014-07-05 23:43:00 +0300239 } else {
Damien George9336ee32014-10-06 15:05:35 +0000240 const byte *src;
241 if (MP_ENDIANNESS_LITTLE) {
242 src = (const byte*)&val + val_sz;
243 } else {
244 src = (const byte*)&val + sizeof(mp_uint_t);
245 }
246 while (val_sz--) {
247 *dest++ = *--src;
248 }
Paul Sokolovsky5fa5ca42014-07-05 23:43:00 +0300249 }
250}
251
Paul Sokolovsky62044602014-04-19 03:13:15 +0300252void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **ptr) {
253 byte *p = *ptr;
Damien George4abff752014-08-30 14:59:21 +0100254 mp_uint_t align;
Paul Sokolovsky62044602014-04-19 03:13:15 +0300255
Kaspar Schleiserf5dd6f72015-05-10 13:04:38 +0200256 size_t size = mp_binary_get_size(struct_type, val_type, &align);
Paul Sokolovsky62044602014-04-19 03:13:15 +0300257 if (struct_type == '@') {
258 // Make pointer aligned
Damien George88a91032015-11-27 12:05:11 +0000259 p = (byte*)MP_ALIGN(p, (size_t)align);
Damien George9336ee32014-10-06 15:05:35 +0000260 if (MP_ENDIANNESS_LITTLE) {
261 struct_type = '<';
262 } else {
263 struct_type = '>';
264 }
Paul Sokolovsky62044602014-04-19 03:13:15 +0300265 }
Paul Sokolovsky7a2f1662014-06-25 22:25:53 +0300266 *ptr = p + size;
Paul Sokolovsky62044602014-04-19 03:13:15 +0300267
Damien George9336ee32014-10-06 15:05:35 +0000268 mp_uint_t val;
Paul Sokolovsky0f836ef2014-04-20 05:19:10 +0300269 switch (val_type) {
270 case 'O':
Damien George9336ee32014-10-06 15:05:35 +0000271 val = (mp_uint_t)val_in;
Paul Sokolovsky0f836ef2014-04-20 05:19:10 +0300272 break;
David Steinberg0b3014c2015-01-25 02:50:34 +0000273#if MICROPY_PY_BUILTINS_FLOAT
274 case 'f': {
275 union { uint32_t i; float f; } fp_sp;
276 fp_sp.f = mp_obj_get_float(val_in);
277 val = fp_sp.i;
278 break;
279 }
280 case 'd': {
281 union { uint64_t i64; uint32_t i32[2]; double f; } fp_dp;
282 fp_dp.f = mp_obj_get_float(val_in);
283 if (BYTES_PER_WORD == 8) {
284 val = fp_dp.i64;
285 } else {
286 int be = struct_type == '>';
287 mp_binary_set_int(sizeof(uint32_t), be, p, fp_dp.i32[MP_ENDIANNESS_BIG ^ be]);
288 p += sizeof(uint32_t);
289 val = fp_dp.i32[MP_ENDIANNESS_LITTLE ^ be];
290 }
291 break;
292 }
293#endif
Paul Sokolovsky0f836ef2014-04-20 05:19:10 +0300294 default:
Damien George271d18e2015-04-25 23:16:39 +0100295 #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
Damien Georgebe6d8be2014-12-05 23:13:52 +0000296 if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) {
Damien George271d18e2015-04-25 23:16:39 +0100297 mp_obj_int_to_bytes_impl(val_in, struct_type == '>', size, p);
298 return;
299 } else
300 #endif
301 {
Damien Georgebe6d8be2014-12-05 23:13:52 +0000302 val = mp_obj_get_int(val_in);
Damien Georgea3c61002016-12-12 15:00:06 +1100303 // zero/sign extend if needed
304 if (BYTES_PER_WORD < 8 && size > sizeof(val)) {
305 int c = (is_signed(val_type) && (mp_int_t)val < 0) ? 0xff : 0x00;
306 memset(p + sizeof(val), c, size - sizeof(val));
Damien George94729072015-04-25 23:51:14 +0100307 }
Damien Georgebe6d8be2014-12-05 23:13:52 +0000308 }
Paul Sokolovsky0f836ef2014-04-20 05:19:10 +0300309 }
310
Damien George963a5a32015-01-16 17:47:07 +0000311 mp_binary_set_int(MIN((size_t)size, sizeof(val)), struct_type == '>', p, val);
Paul Sokolovsky62044602014-04-19 03:13:15 +0300312}
313
Damien George42f3de92014-10-03 17:44:14 +0000314void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t val_in) {
Damien George71e9bfa2014-04-18 23:28:12 +0100315 switch (typecode) {
Damien Georgefb510b32014-06-01 13:32:54 +0100316#if MICROPY_PY_BUILTINS_FLOAT
Damien George71e9bfa2014-04-18 23:28:12 +0100317 case 'f':
Damien Georgec9f8f652014-11-21 18:16:25 +0000318 ((float*)p)[index] = mp_obj_get_float(val_in);
Damien George71e9bfa2014-04-18 23:28:12 +0100319 break;
320 case 'd':
Damien Georgec9f8f652014-11-21 18:16:25 +0000321 ((double*)p)[index] = mp_obj_get_float(val_in);
Damien George71e9bfa2014-04-18 23:28:12 +0100322 break;
323#endif
Paul Sokolovsky24c10002015-03-05 22:57:36 +0200324 // Extension to CPython: array of objects
325 case 'O':
326 ((mp_obj_t*)p)[index] = val_in;
327 break;
Damien George71e9bfa2014-04-18 23:28:12 +0100328 default:
Damien George81794fc2015-09-01 16:25:29 +0100329 #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
Damien George6cfa61a2017-05-09 10:41:00 +1000330 if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) {
331 size_t size = mp_binary_get_size('@', typecode, NULL);
Damien George81794fc2015-09-01 16:25:29 +0100332 mp_obj_int_to_bytes_impl(val_in, MP_ENDIANNESS_BIG,
Damien George6cfa61a2017-05-09 10:41:00 +1000333 size, (uint8_t*)p + index * size);
Damien George81794fc2015-09-01 16:25:29 +0100334 return;
335 }
336 #endif
Damien George71e9bfa2014-04-18 23:28:12 +0100337 mp_binary_set_val_array_from_int(typecode, p, index, mp_obj_get_int(val_in));
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200338 }
Damien George71e9bfa2014-04-18 23:28:12 +0100339}
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200340
Damien George42f3de92014-10-03 17:44:14 +0000341void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, mp_int_t val) {
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200342 switch (typecode) {
343 case 'b':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200344 ((signed char*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200345 break;
346 case BYTEARRAY_TYPECODE:
347 case 'B':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200348 ((unsigned char*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200349 break;
350 case 'h':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200351 ((short*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200352 break;
353 case 'H':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200354 ((unsigned short*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200355 break;
356 case 'i':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200357 ((int*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200358 break;
359 case 'I':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200360 ((unsigned int*)p)[index] = val;
361 break;
362 case 'l':
363 ((long*)p)[index] = val;
364 break;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200365 case 'L':
Paul Sokolovsky91232d32015-01-24 03:18:10 +0200366 ((unsigned long*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200367 break;
Damien George81794fc2015-09-01 16:25:29 +0100368 #if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200369 case 'q':
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200370 ((long long*)p)[index] = val;
Damien George9aeba3e2017-07-04 02:11:46 +1000371 break;
Damien George81794fc2015-09-01 16:25:29 +0100372 case 'Q':
373 ((unsigned long long*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200374 break;
Damien George81794fc2015-09-01 16:25:29 +0100375 #endif
Damien Georgefb510b32014-06-01 13:32:54 +0100376#if MICROPY_PY_BUILTINS_FLOAT
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200377 case 'f':
Damien George71e9bfa2014-04-18 23:28:12 +0100378 ((float*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200379 break;
380 case 'd':
Damien George71e9bfa2014-04-18 23:28:12 +0100381 ((double*)p)[index] = val;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200382 break;
383#endif
Paul Sokolovsky91fc0752015-10-12 10:10:39 +0300384 // Extension to CPython: array of pointers
385 case 'P':
Damien George999cedb2015-11-27 17:01:44 +0000386 ((void**)p)[index] = (void*)(uintptr_t)val;
Damien George9aeba3e2017-07-04 02:11:46 +1000387 break;
Paul Sokolovsky8bc35162014-02-14 17:16:35 +0200388 }
389}