Conditionally compile out nonstandard array/struct typecodes

.. defaulting to off for circuitpython-supported boards, on for others.

.. fixing up the tests that fail when it is turned off, so that they skip
instead of failing
This commit is contained in:
Jeff Epler 2018-03-26 18:13:49 -05:00
parent fa88446679
commit 355bf8b553
9 changed files with 40 additions and 1 deletions

View File

@ -46,6 +46,7 @@
#define MICROPY_PY_BUILTINS_SLICE (1)
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
#define MICROPY_NONSTANDARD_TYPECODES (0)
#define MICROPY_PY_BUILTINS_PROPERTY (1)
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
#define MICROPY_PY___FILE__ (1)

View File

@ -49,6 +49,7 @@
#define MICROPY_PY_GC (1)
#define MICROPY_PY_ARRAY (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
#define MICROPY_NONSTANDARD_TYPECODES (0)
#define MICROPY_PY_COLLECTIONS (1)
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
#define MICROPY_PY_MATH (0)

View File

@ -99,6 +99,7 @@
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (0)
#define MICROPY_NONSTANDARD_TYPECODES (0)
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (0)
#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_MAXSIZE (1)

View File

@ -57,8 +57,10 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) {
size = 4; break;
case 'q': case 'Q':
size = 8; break;
#if MICROPY_NONSTANDARD_TYPECODES
case 'P': case 'O': case 'S':
size = sizeof(void*); break;
#endif
case 'f':
size = sizeof(float); break;
case 'd':
@ -89,9 +91,11 @@ size_t mp_binary_get_size(char struct_type, char val_type, mp_uint_t *palign) {
case 'q': case 'Q':
align = alignof(long long);
size = sizeof(long long); break;
#if MICROPY_NONSTANDARD_TYPECODES
case 'P': case 'O': case 'S':
align = alignof(void*);
size = sizeof(void*); break;
#endif
case 'f':
align = alignof(float);
size = sizeof(float); break;
@ -148,12 +152,14 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, mp_uint_t index) {
case 'd':
return mp_obj_new_float(((double*)p)[index]);
#endif
#if MICROPY_NONSTANDARD_TYPECODES
// Extension to CPython: array of objects
case 'O':
return ((mp_obj_t*)p)[index];
// Extension to CPython: array of pointers
case 'P':
return mp_obj_new_int((mp_int_t)(uintptr_t)((void**)p)[index]);
#endif
}
return MP_OBJ_NEW_SMALL_INT(val);
}
@ -202,11 +208,13 @@ mp_obj_t mp_binary_get_val(char struct_type, char val_type, byte **ptr) {
long long val = mp_binary_get_int(size, is_signed(val_type), (struct_type == '>'), p);
if (val_type == 'O') {
if (MICROPY_NONSTANDARD_TYPECODES && (val_type == 'O')) {
return (mp_obj_t)(mp_uint_t)val;
#if MICROPY_NONSTANDARD_TYPECODES
} else if (val_type == 'S') {
const char *s_val = (const char*)(uintptr_t)(mp_uint_t)val;
return mp_obj_new_str(s_val, strlen(s_val), false);
#endif
#if MICROPY_PY_BUILTINS_FLOAT
} else if (val_type == 'f') {
union { uint32_t i; float f; } fpu = {val};
@ -267,9 +275,11 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
mp_uint_t val;
switch (val_type) {
#if MICROPY_NONSTANDARD_TYPECODES
case 'O':
val = (mp_uint_t)val_in;
break;
#endif
#if MICROPY_PY_BUILTINS_FLOAT
case 'f': {
union { uint32_t i; float f; } fp_sp;
@ -324,10 +334,12 @@ void mp_binary_set_val_array(char typecode, void *p, mp_uint_t index, mp_obj_t v
((double*)p)[index] = mp_obj_get_float(val_in);
break;
#endif
#if MICROPY_NONSTANDARD_TYPECODES
// Extension to CPython: array of objects
case 'O':
((mp_obj_t*)p)[index] = val_in;
break;
#endif
default:
#if MICROPY_LONGINT_IMPL != MICROPY_LONGINT_IMPL_NONE
if (MP_OBJ_IS_TYPE(val_in, &mp_type_int)) {
@ -384,9 +396,11 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, mp_uint_t index, m
((double*)p)[index] = val;
break;
#endif
#if MICROPY_NONSTANDARD_TYPECODES
// Extension to CPython: array of pointers
case 'P':
((void**)p)[index] = (void*)(uintptr_t)val;
break;
#endif
}
}

View File

@ -888,6 +888,12 @@ typedef double mp_float_t;
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (0)
#endif
// Whether to support nonstandard typecodes "O", "P" and "S"
// in array and struct modules.
#ifndef MICROPY_NONSTANDARD_TYPECODES
#define MICROPY_NONSTANDARD_TYPECODES (1)
#endif
// Whether to support attrtuple type (MicroPython extension)
// It provides space-efficient tuples with attribute access
#ifndef MICROPY_PY_ATTRTUPLE

View File

@ -470,9 +470,11 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
} else {
mp_seq_replace_slice_no_grow(dest_items, o->len,
slice.start, slice.stop, src_items, src_len, item_sz);
#if MICROPY_NONSTANDARD_TYPECODES
// Clear "freed" elements at the end of list
// TODO: This is actually only needed for typecode=='O'
mp_seq_clear(dest_items, o->len + len_adj, o->len, item_sz);
#endif
// TODO: alloc policy after shrinking
}
o->len += len_adj;

View File

@ -33,9 +33,11 @@
#include "py/parsenum.h"
void struct_validate_format(char fmt) {
#if MICROPY_NONSTANDARD_TYPECODES
if( fmt == 'S' || fmt == 'O') {
mp_raise_RuntimeError("'S' and 'O' are not supported format types");
}
#endif
}
char get_fmt_type(const char **fmt) {

View File

@ -5,6 +5,12 @@ except ImportError:
print("SKIP")
raise SystemExit
try:
array.array('O')
except ValueError:
print("SKIP")
raise SystemExit
# arrays of objects
a = array.array('O')
a.append(1)

View File

@ -9,6 +9,12 @@ except:
print("SKIP")
raise SystemExit
try:
struct.pack('O', None)
except ValueError:
print("SKIP")
raise SystemExit
class A():
pass