From 2970680e6af663200b35227bfbca5240542a4c47 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sun, 20 Oct 2019 19:54:25 -0400 Subject: fix show and fix step > 1 --- py/obj.c | 9 +++++++-- py/objtype.c | 3 ++- 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'py') diff --git a/py/obj.c b/py/obj.c index bd2aaf9d2..f91b00a64 100644 --- a/py/obj.c +++ b/py/obj.c @@ -489,14 +489,19 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { mp_obj_type_t *type = mp_obj_get_type(base); + mp_obj_t instance = base; + // If we got an MP_OBJ_SENTINEL as the type, then we got called by instance_subscr + if (type == MP_OBJ_SENTINEL) { + instance = ((mp_obj_t *)base)[1]; + type = mp_obj_get_type(((mp_obj_t *)base)[2]); + } if (type->subscr != NULL) { - mp_obj_t ret = type->subscr(base, index, value); + mp_obj_t ret = type->subscr(instance, index, value); // May have called port specific C code. Make sure it didn't mess up the heap. assert_heap_ok(); if (ret != MP_OBJ_NULL) { return ret; } - // TODO: call base classes here? } if (value == MP_OBJ_NULL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { diff --git a/py/objtype.c b/py/objtype.c index 5133d849f..7d41b8656 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -850,7 +850,8 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value meth_args = 3; } if (member[0] == MP_OBJ_SENTINEL) { - return mp_obj_subscr(self->subobj[0], index, value); + mp_obj_t args[3] = {MP_OBJ_SENTINEL, self_in, self->subobj[0]}; + return mp_obj_subscr(args, index, value); } else if (member[0] != MP_OBJ_NULL) { mp_obj_t args[3] = {self_in, index, value}; // TODO probably need to call mp_convert_member_lookup, and use mp_call_method_n_kw -- cgit v1.2.3 From fa57de06886f3ec6785ec74676da0b08758c81c7 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 16 Nov 2019 14:04:12 -0500 Subject: use instance for verbose errors --- py/obj.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'py') diff --git a/py/obj.c b/py/obj.c index f91b00a64..6177f74b5 100644 --- a/py/obj.c +++ b/py/obj.c @@ -508,21 +508,21 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { mp_raise_TypeError(translate("object does not support item deletion")); } else { mp_raise_TypeError_varg( - translate("'%s' object does not support item deletion"), mp_obj_get_type_str(base)); + translate("'%s' object does not support item deletion"), mp_obj_get_type_str(instance)); } } else if (value == MP_OBJ_SENTINEL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_raise_TypeError(translate("object is not subscriptable")); } else { mp_raise_TypeError_varg( - translate("'%s' object is not subscriptable"), mp_obj_get_type_str(base)); + translate("'%s' object is not subscriptable"), mp_obj_get_type_str(instance)); } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_raise_TypeError(translate("object does not support item assignment")); } else { mp_raise_TypeError_varg( - translate("'%s' object does not support item assignment"), mp_obj_get_type_str(base)); + translate("'%s' object does not support item assignment"), mp_obj_get_type_str(instance)); } } } -- cgit v1.2.3 From c770ccd93917cf46a7b8cef7613ff389d7c3d18d Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 23 Nov 2019 12:09:26 -0500 Subject: make ->subscr take an instance to pass when instance_subscr is called from subscr. --- extmod/machine_mem.c | 2 +- extmod/modbtree.c | 2 +- extmod/moductypes.c | 2 +- ports/unix/modjni.c | 2 +- py/obj.c | 15 +++++++-------- py/obj.h | 3 ++- py/objarray.c | 2 +- py/objdict.c | 2 +- py/objlist.c | 2 +- py/objrange.c | 2 +- py/objstr.c | 2 +- py/objstrunicode.c | 2 +- py/objtuple.c | 2 +- py/objtuple.h | 2 +- py/objtype.c | 5 ++--- py/opmethods.c | 6 +++--- shared-bindings/_pixelbuf/PixelBuf.c | 6 +++--- shared-bindings/displayio/Bitmap.c | 2 +- shared-bindings/displayio/Group.c | 2 +- shared-bindings/displayio/Palette.c | 2 +- shared-bindings/displayio/TileGrid.c | 2 +- shared-bindings/nvm/ByteArray.c | 2 +- shared-bindings/pulseio/PulseIn.c | 2 +- 23 files changed, 35 insertions(+), 36 deletions(-) (limited to 'py') diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index e0649290e..b80eaea99 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -60,7 +60,7 @@ STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_prin mp_printf(print, "<%u-bit memory>", 8 * self->elem_size); } -STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { // TODO support slice index to read/write multiple values at once machine_mem_obj_t *self = MP_OBJ_TO_PTR(self_in); if (value == MP_OBJ_NULL) { diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 8b7688580..cfc614c13 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -246,7 +246,7 @@ STATIC mp_obj_t btree_iternext(mp_obj_t self_in) { } } -STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); if (value == MP_OBJ_NULL) { // delete diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 9eea30bf3..2165152ea 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -518,7 +518,7 @@ STATIC void uctypes_struct_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { +STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); if (value == MP_OBJ_NULL) { diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 8ec5ae54d..4aefb2476 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -241,7 +241,7 @@ STATIC void get_jclass_name(jobject obj, char *buf) { check_exception(); } -STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_jobject_t *self = self_in; mp_uint_t idx = mp_obj_get_int(index); char class_name[64]; diff --git a/py/obj.c b/py/obj.c index 6177f74b5..94c509be6 100644 --- a/py/obj.c +++ b/py/obj.c @@ -488,15 +488,14 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { } mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { + return mp_obj_subscr_impl(base, index, value, base); +} + +mp_obj_t mp_obj_subscr_impl(mp_obj_t base, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_type_t *type = mp_obj_get_type(base); - mp_obj_t instance = base; - // If we got an MP_OBJ_SENTINEL as the type, then we got called by instance_subscr - if (type == MP_OBJ_SENTINEL) { - instance = ((mp_obj_t *)base)[1]; - type = mp_obj_get_type(((mp_obj_t *)base)[2]); - } + if (type->subscr != NULL) { - mp_obj_t ret = type->subscr(instance, index, value); + mp_obj_t ret = type->subscr(base, index, value, instance); // May have called port specific C code. Make sure it didn't mess up the heap. assert_heap_ok(); if (ret != MP_OBJ_NULL) { @@ -551,7 +550,7 @@ STATIC mp_obj_t generic_it_iternext(mp_obj_t self_in) { mp_obj_type_t *type = mp_obj_get_type(self->obj); mp_obj_t current_length = type->unary_op(MP_UNARY_OP_LEN, self->obj); if (self->cur < MP_OBJ_SMALL_INT_VALUE(current_length)) { - mp_obj_t o_out = type->subscr(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL); + mp_obj_t o_out = type->subscr(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL, self->obj); self->cur += 1; return o_out; } else { diff --git a/py/obj.h b/py/obj.h index cf4216d02..edeeb2a4b 100644 --- a/py/obj.h +++ b/py/obj.h @@ -444,7 +444,7 @@ typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, cons typedef mp_obj_t (*mp_unary_op_fun_t)(mp_unary_op_t op, mp_obj_t); typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t); typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest); -typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); +typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance); typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf); // Buffer protocol @@ -708,6 +708,7 @@ mp_obj_t mp_obj_id(mp_obj_t o_in); mp_obj_t mp_obj_len(mp_obj_t o_in); mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); // may return MP_OBJ_NULL mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val); +mp_obj_t mp_obj_subscr_impl(mp_obj_t base, mp_obj_t index, mp_obj_t val, mp_obj_t instance); mp_obj_t mp_generic_unary_op(mp_unary_op_t op, mp_obj_t o_in); // cell diff --git a/py/objarray.c b/py/objarray.c index 9114a63c5..70e57f190 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -396,7 +396,7 @@ STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_extend_obj, array_extend); #endif -STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { +STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete item // TODO implement diff --git a/py/objdict.c b/py/objdict.c index 683fcb748..c13ad88e5 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -174,7 +174,7 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) { } } -STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete mp_obj_dict_delete(self_in, index); diff --git a/py/objlist.c b/py/objlist.c index ea38e64e5..b0c62a6ee 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -158,7 +158,7 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } } -STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete #if MICROPY_PY_BUILTINS_SLICE diff --git a/py/objrange.c b/py/objrange.c index 30d55c56c..f8b960900 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -158,7 +158,7 @@ STATIC mp_obj_t range_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs } #endif -STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_SENTINEL) { // load mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/py/objstr.c b/py/objstr.c index 6ef9a15b5..3d2cb338f 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -431,7 +431,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s #endif // This is used for both bytes and 8-bit strings. This is not used for unicode strings. -STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_type_t *type = mp_obj_get_type(self_in); GET_STR_DATA_LEN(self_in, self_data, self_len); if (value == MP_OBJ_SENTINEL) { diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 30000a51e..e29926683 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -197,7 +197,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s return s; } -STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_type_t *type = mp_obj_get_type(self_in); assert(type == &mp_type_str); GET_STR_DATA_LEN(self_in, self_data, self_len); diff --git a/py/objtuple.c b/py/objtuple.c index ed13cdcef..625c53bdd 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -177,7 +177,7 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } } -mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_SENTINEL) { // load mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/py/objtuple.h b/py/objtuple.h index 7f20ab7b6..4df3aeded 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -45,7 +45,7 @@ extern const mp_obj_type_t mp_type_tuple; void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); mp_obj_t mp_obj_tuple_unary_op(mp_unary_op_t op, mp_obj_t self_in); mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs); -mp_obj_t mp_obj_tuple_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value); +mp_obj_t mp_obj_tuple_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value, mp_obj_t instance); mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf); extern const mp_obj_type_t mp_type_attrtuple; diff --git a/py/objtype.c b/py/objtype.c index 7d41b8656..41ebe7b61 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -823,7 +823,7 @@ STATIC void mp_obj_instance_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { +STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t member[2] = {MP_OBJ_NULL}; struct class_lookup_data lookup = { @@ -850,8 +850,7 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value meth_args = 3; } if (member[0] == MP_OBJ_SENTINEL) { - mp_obj_t args[3] = {MP_OBJ_SENTINEL, self_in, self->subobj[0]}; - return mp_obj_subscr(args, index, value); + return mp_obj_subscr_impl(self->subobj[0], index, value, instance); } else if (member[0] != MP_OBJ_NULL) { mp_obj_t args[3] = {self_in, index, value}; // TODO probably need to call mp_convert_member_lookup, and use mp_call_method_n_kw diff --git a/py/opmethods.c b/py/opmethods.c index 247fa5bbc..d906ddb6a 100644 --- a/py/opmethods.c +++ b/py/opmethods.c @@ -29,19 +29,19 @@ STATIC mp_obj_t op_getitem(mp_obj_t self_in, mp_obj_t key_in) { mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, MP_OBJ_SENTINEL); + return type->subscr(self_in, key_in, MP_OBJ_SENTINEL, self_in); } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem); STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) { mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, value_in); + return type->subscr(self_in, key_in, value_in, self_in); } MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem); STATIC mp_obj_t op_delitem(mp_obj_t self_in, mp_obj_t key_in) { mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, MP_OBJ_NULL); + return type->subscr(self_in, key_in, MP_OBJ_NULL, self_in); } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_delitem_obj, op_delitem); diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c index aeed6f504..851c3a276 100644 --- a/shared-bindings/_pixelbuf/PixelBuf.c +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -348,7 +348,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(pixelbuf_pixelbuf_show_obj, pixelbuf_pixelbuf_s //| //| Sets the pixel value at the given index. //| -STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { +STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete item // slice deletion @@ -410,7 +410,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp } } if (self->auto_write) - call_show(self_in, 's'); + call_show(instance, 's'); return mp_const_none; #else return MP_OBJ_NULL; // op not supported @@ -430,7 +430,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL, self->brightness, value, &self->byteorder, self->byteorder.is_dotstar); if (self->auto_write) - call_show(self_in, 'i'); + call_show(instance, 'i'); return mp_const_none; } } diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 91c17f2d1..764313e1e 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -133,7 +133,7 @@ const mp_obj_property_t displayio_bitmap_height_obj = { //| //| bitmap[0,1] = 3 //| -STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { +STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj, mp_obj_t instance) { if (value_obj == mp_const_none) { // delete item mp_raise_AttributeError(translate("Cannot delete values")); diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index dd7600eb9..2288026dc 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -310,7 +310,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| //| del group[0] //| -STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { +STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value, mp_obj_t instance) { displayio_group_t *self = native_group(self_in); if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index dda58e3c5..491f9343b 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -95,7 +95,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| palette[2] = b'\xff\xff\x00\x00' # set using 4 bytes //| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes //| -STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { +STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete item return MP_OBJ_NULL; // op not supported diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index 288eb4b23..5acf8496f 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -349,7 +349,7 @@ const mp_obj_property_t displayio_tilegrid_pixel_shader_obj = { //| //| grid[0,0] = 10 //| -STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { +STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj, mp_obj_t instance) { displayio_tilegrid_t *self = native_tilegrid(self_in); diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c index 31bedeacc..5ac46b260 100644 --- a/shared-bindings/nvm/ByteArray.c +++ b/shared-bindings/nvm/ByteArray.c @@ -70,7 +70,7 @@ STATIC const mp_rom_map_elem_t nvm_bytearray_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(nvm_bytearray_locals_dict, nvm_bytearray_locals_dict_table); -STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { +STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete item // slice deletion diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 8b69109f0..5947329a5 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -272,7 +272,7 @@ STATIC mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| pulses = pulseio.PulseIn(pin) //| print(pulses[0]) //| -STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { +STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value, mp_obj_t instance) { if (value == mp_const_none) { // delete item mp_raise_AttributeError(translate("Cannot delete values")); -- cgit v1.2.3 From 27979f51ace467215d5d823e0ce9f4f2ef690369 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 23 Nov 2019 12:15:12 -0500 Subject: use base for errors --- py/obj.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'py') diff --git a/py/obj.c b/py/obj.c index 94c509be6..54822c977 100644 --- a/py/obj.c +++ b/py/obj.c @@ -507,21 +507,21 @@ mp_obj_t mp_obj_subscr_impl(mp_obj_t base, mp_obj_t index, mp_obj_t value, mp_ob mp_raise_TypeError(translate("object does not support item deletion")); } else { mp_raise_TypeError_varg( - translate("'%s' object does not support item deletion"), mp_obj_get_type_str(instance)); + translate("'%s' object does not support item deletion"), mp_obj_get_type_str(base)); } } else if (value == MP_OBJ_SENTINEL) { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_raise_TypeError(translate("object is not subscriptable")); } else { mp_raise_TypeError_varg( - translate("'%s' object is not subscriptable"), mp_obj_get_type_str(instance)); + translate("'%s' object is not subscriptable"), mp_obj_get_type_str(base)); } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_raise_TypeError(translate("object does not support item assignment")); } else { mp_raise_TypeError_varg( - translate("'%s' object does not support item assignment"), mp_obj_get_type_str(instance)); + translate("'%s' object does not support item assignment"), mp_obj_get_type_str(base)); } } } -- cgit v1.2.3 From a9baa441c94bf4ba9fe676a34e8a47fee6001559 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Sat, 23 Nov 2019 13:52:14 -0500 Subject: disable -Wunused-parameter on subscr functions --- extmod/machine_mem.c | 1 + extmod/modbtree.c | 1 + extmod/moductypes.c | 1 + ports/unix/modjni.c | 1 + py/objarray.c | 1 + py/objdict.c | 1 + py/objlist.c | 1 + py/objrange.c | 1 + py/objstr.c | 1 + py/objstrunicode.c | 1 + py/objtuple.c | 1 + shared-bindings/displayio/Bitmap.c | 1 + shared-bindings/displayio/Group.c | 1 + shared-bindings/displayio/Palette.c | 1 + 14 files changed, 14 insertions(+) (limited to 'py') diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index b80eaea99..826c59d0f 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -60,6 +60,7 @@ STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_prin mp_printf(print, "<%u-bit memory>", 8 * self->elem_size); } +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { // TODO support slice index to read/write multiple values at once machine_mem_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/extmod/modbtree.c b/extmod/modbtree.c index cfc614c13..97a4de3d5 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -246,6 +246,7 @@ STATIC mp_obj_t btree_iternext(mp_obj_t self_in) { } } +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); if (value == MP_OBJ_NULL) { diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 2165152ea..722f4bb87 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -518,6 +518,7 @@ STATIC void uctypes_struct_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 4aefb2476..50dd10dd2 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -241,6 +241,7 @@ STATIC void get_jclass_name(jobject obj, char *buf) { check_exception(); } +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_jobject_t *self = self_in; mp_uint_t idx = mp_obj_get_int(index); diff --git a/py/objarray.c b/py/objarray.c index 70e57f190..6fffa8412 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -396,6 +396,7 @@ STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_extend_obj, array_extend); #endif +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete item diff --git a/py/objdict.c b/py/objdict.c index c13ad88e5..2c07331e7 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -174,6 +174,7 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) { } } +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete diff --git a/py/objlist.c b/py/objlist.c index b0c62a6ee..c544c27f0 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -158,6 +158,7 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } } +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete diff --git a/py/objrange.c b/py/objrange.c index f8b960900..328416303 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -158,6 +158,7 @@ STATIC mp_obj_t range_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs } #endif +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_SENTINEL) { // load diff --git a/py/objstr.c b/py/objstr.c index 4e1715322..fd802fe85 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -439,6 +439,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s #endif // This is used for both bytes and 8-bit strings. This is not used for unicode strings. +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_type_t *type = mp_obj_get_type(self_in); GET_STR_DATA_LEN(self_in, self_data, self_len); diff --git a/py/objstrunicode.c b/py/objstrunicode.c index e29926683..dc8c0743d 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -197,6 +197,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s return s; } +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_type_t *type = mp_obj_get_type(self_in); assert(type == &mp_type_str); diff --git a/py/objtuple.c b/py/objtuple.c index 625c53bdd..b6640def5 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -177,6 +177,7 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } } +#pragma GCC diagnostic ignored "-Wunused-parameter" mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_SENTINEL) { // load diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 764313e1e..7c77d05ed 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -133,6 +133,7 @@ const mp_obj_property_t displayio_bitmap_height_obj = { //| //| bitmap[0,1] = 3 //| +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj, mp_obj_t instance) { if (value_obj == mp_const_none) { // delete item diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 2288026dc..40f2704c0 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -310,6 +310,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| //| del group[0] //| +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value, mp_obj_t instance) { displayio_group_t *self = native_group(self_in); diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index 491f9343b..2fa65867a 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -95,6 +95,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| palette[2] = b'\xff\xff\x00\x00' # set using 4 bytes //| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes //| +#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { if (value == MP_OBJ_NULL) { // delete item -- cgit v1.2.3 From 56720eae0a9eb6fe8845cf20eb1298c3fb68a373 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Tue, 26 Nov 2019 18:39:08 -0500 Subject: remove unnecessary intermediate mp_obj_subscr wrapper --- extmod/modurandom.c | 2 +- extmod/vfs.c | 2 +- ports/unix/modjni.c | 2 +- py/obj.c | 6 +----- py/obj.h | 3 +-- py/objreversed.c | 2 +- py/objtype.c | 2 +- py/vm.c | 4 ++-- shared-bindings/random/__init__.c | 2 +- shared-module/os/__init__.c | 2 +- 10 files changed, 11 insertions(+), 16 deletions(-) (limited to 'py') diff --git a/extmod/modurandom.c b/extmod/modurandom.c index 1512a3fd4..101c80cf8 100644 --- a/extmod/modurandom.c +++ b/extmod/modurandom.c @@ -150,7 +150,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_randint_obj, mod_urandom_randint); STATIC mp_obj_t mod_urandom_choice(mp_obj_t seq) { mp_int_t len = mp_obj_get_int(mp_obj_len(seq)); if (len > 0) { - return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL); + return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL, seq); } else { nlr_raise(mp_obj_new_exception(&mp_type_IndexError)); } diff --git a/extmod/vfs.c b/extmod/vfs.c index 7d6e6999b..7599739e0 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -373,7 +373,7 @@ mp_obj_t mp_vfs_listdir(size_t n_args, const mp_obj_t *args) { mp_obj_t dir_list = mp_obj_new_list(0, NULL); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { - mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL)); + mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL, next)); } return dir_list; } diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 50dd10dd2..8f0eac5a9 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -311,7 +311,7 @@ STATIC mp_obj_t jobject_unary_op(mp_unary_op_t op, mp_obj_t self_in) { // TODO: subscr_load_adaptor & subscr_getiter convenience functions // should be moved to common location for reuse. STATIC mp_obj_t subscr_load_adaptor(mp_obj_t self_in, mp_obj_t index_in) { - return mp_obj_subscr(self_in, index_in, MP_OBJ_SENTINEL); + return mp_obj_subscr(self_in, index_in, MP_OBJ_SENTINEL, self_in); } MP_DEFINE_CONST_FUN_OBJ_2(subscr_load_adaptor_obj, subscr_load_adaptor); diff --git a/py/obj.c b/py/obj.c index 54822c977..47aa1aebf 100644 --- a/py/obj.c +++ b/py/obj.c @@ -487,11 +487,7 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { } } -mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { - return mp_obj_subscr_impl(base, index, value, base); -} - -mp_obj_t mp_obj_subscr_impl(mp_obj_t base, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { mp_obj_type_t *type = mp_obj_get_type(base); if (type->subscr != NULL) { diff --git a/py/obj.h b/py/obj.h index edeeb2a4b..ff97b34d8 100644 --- a/py/obj.h +++ b/py/obj.h @@ -707,8 +707,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool mp_obj_t mp_obj_id(mp_obj_t o_in); mp_obj_t mp_obj_len(mp_obj_t o_in); mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); // may return MP_OBJ_NULL -mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val); -mp_obj_t mp_obj_subscr_impl(mp_obj_t base, mp_obj_t index, mp_obj_t val, mp_obj_t instance); +mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val, mp_obj_t instance); mp_obj_t mp_generic_unary_op(mp_unary_op_t op, mp_obj_t o_in); // cell diff --git a/py/objreversed.c b/py/objreversed.c index 4937d0818..0b21e6938 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -66,7 +66,7 @@ STATIC mp_obj_t reversed_iternext(mp_obj_t self_in) { // pre-decrement and index sequence self->cur_index -= 1; - return mp_obj_subscr(self->seq, MP_OBJ_NEW_SMALL_INT(self->cur_index), MP_OBJ_SENTINEL); + return mp_obj_subscr(self->seq, MP_OBJ_NEW_SMALL_INT(self->cur_index), MP_OBJ_SENTINEL, self->seq); } const mp_obj_type_t mp_type_reversed = { diff --git a/py/objtype.c b/py/objtype.c index 7d0760a10..9608a9242 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -852,7 +852,7 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value meth_args = 3; } if (member[0] == MP_OBJ_SENTINEL) { - return mp_obj_subscr_impl(self->subobj[0], index, value, instance); + return mp_obj_subscr(self->subobj[0], index, value, instance); } else if (member[0] != MP_OBJ_NULL) { mp_obj_t args[3] = {self_in, index, value}; // TODO probably need to call mp_convert_member_lookup, and use mp_call_method_n_kw diff --git a/py/vm.c b/py/vm.c index 353fc8810..2fe8d3237 100644 --- a/py/vm.c +++ b/py/vm.c @@ -386,7 +386,7 @@ dispatch_loop: ENTRY(MP_BC_LOAD_SUBSCR): { MARK_EXC_IP_SELECTIVE(); mp_obj_t index = POP(); - SET_TOP(mp_obj_subscr(TOP(), index, MP_OBJ_SENTINEL)); + SET_TOP(mp_obj_subscr(TOP(), index, MP_OBJ_SENTINEL, TOP())); DISPATCH(); } @@ -464,7 +464,7 @@ dispatch_loop: ENTRY(MP_BC_STORE_SUBSCR): MARK_EXC_IP_SELECTIVE(); - mp_obj_subscr(sp[-1], sp[0], sp[-2]); + mp_obj_subscr(sp[-1], sp[0], sp[-2], sp[-1]); sp -= 3; DISPATCH(); diff --git a/shared-bindings/random/__init__.c b/shared-bindings/random/__init__.c index 83698eac5..fdef91443 100644 --- a/shared-bindings/random/__init__.c +++ b/shared-bindings/random/__init__.c @@ -145,7 +145,7 @@ STATIC mp_obj_t random_choice(mp_obj_t seq) { if (len == 0) { mp_raise_IndexError(translate("empty sequence")); } - return mp_obj_subscr(seq, mp_obj_new_int(shared_modules_random_randrange(0, len, 1)), MP_OBJ_SENTINEL); + return mp_obj_subscr(seq, mp_obj_new_int(shared_modules_random_randrange(0, len, 1)), MP_OBJ_SENTINEL, seq); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(random_choice_obj, random_choice); diff --git a/shared-module/os/__init__.c b/shared-module/os/__init__.c index 8060eec4f..ad76251c8 100644 --- a/shared-module/os/__init__.c +++ b/shared-module/os/__init__.c @@ -127,7 +127,7 @@ mp_obj_t common_hal_os_listdir(const char* path) { mp_obj_t next; while ((next = mp_iternext(iter_obj)) != MP_OBJ_STOP_ITERATION) { // next[0] is the filename. - mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL)); + mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL, dir_list)); RUN_BACKGROUND_TASKS; } return dir_list; -- cgit v1.2.3 From 15072c69c9e940fa5cb0239fc821d2c0353f918e Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Fri, 13 Dec 2019 13:32:58 -0500 Subject: push changes --- extmod/modbtree.c | 3 ++- extmod/moductypes.c | 4 ++-- py/objlist.c | 8 +++----- py/objtype.c | 10 ++++++++-- 4 files changed, 15 insertions(+), 10 deletions(-) (limited to 'py') diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 97a4de3d5..939ab813e 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -248,7 +248,8 @@ STATIC mp_obj_t btree_iternext(mp_obj_t self_in) { #pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { - mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); + //mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_btree_t *self = mp_instance_cast_to_native_base(self_in, &btree_type); if (value == MP_OBJ_NULL) { // delete DBT key; diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 722f4bb87..145b34887 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -519,8 +519,8 @@ STATIC void uctypes_struct_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { - mp_obj_uctypes_struct_t *self = MP_OBJ_TO_PTR(self_in); +STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { + mp_obj_uctypes_struct_t *self = mp_instance_cast_to_native_base(base_in, &uctypes_struct_type); if (value == MP_OBJ_NULL) { // delete diff --git a/py/objlist.c b/py/objlist.c index c544c27f0..0c0d60aa8 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -160,11 +160,11 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { #pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { + mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); if (value == MP_OBJ_NULL) { // delete #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { - mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); mp_bound_slice_t slice; if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) { mp_raise_NotImplementedError(NULL); @@ -180,12 +180,11 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp return mp_const_none; } #endif - mp_obj_t args[2] = {self_in, index}; + mp_obj_t args[2] = {self, index}; list_pop(2, args); return mp_const_none; } else if (value == MP_OBJ_SENTINEL) { // load - mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_bound_slice_t slice; @@ -202,7 +201,6 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp } else { #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { - mp_obj_list_t *self = MP_OBJ_TO_PTR(self_in); size_t value_len; mp_obj_t *value_items; mp_obj_get_array(value, &value_len, &value_items); mp_bound_slice_t slice_out; @@ -231,7 +229,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp return mp_const_none; } #endif - mp_obj_list_store(self_in, index, value); + mp_obj_list_store(self, index, value); return mp_const_none; } } diff --git a/py/objtype.c b/py/objtype.c index 9608a9242..c7dc2ae78 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -34,6 +34,7 @@ #include "py/objtype.h" #include "py/runtime.h" +#include "supervisor/shared/stack.h" #include "supervisor/shared/translate.h" #if MICROPY_DEBUG_VERBOSE // print debugging info @@ -851,8 +852,13 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value mp_obj_class_lookup(&lookup, self->base.type); meth_args = 3; } - if (member[0] == MP_OBJ_SENTINEL) { - return mp_obj_subscr(self->subobj[0], index, value, instance); + if (member[0] == MP_OBJ_SENTINEL) { // native base subscr exists + mp_obj_type_t *subobj_type = mp_obj_get_type(self->subobj[0]); + // return mp_obj_subscr(self->subobj[0], index, value, instance); + mp_obj_t ret = subobj_type->subscr(self_in, index, value, instance); + // May have called port specific C code. Make sure it didn't mess up the heap. + assert_heap_ok(); + return ret; } else if (member[0] != MP_OBJ_NULL) { mp_obj_t args[3] = {self_in, index, value}; // TODO probably need to call mp_convert_member_lookup, and use mp_call_method_n_kw -- cgit v1.2.3 From dc8dd6df20f4904917169f4ec1172c8f3827e822 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Fri, 13 Dec 2019 14:29:15 -0500 Subject: Revert subscr signature change --- extmod/machine_mem.c | 2 +- extmod/modbtree.c | 2 +- extmod/moductypes.c | 2 +- extmod/modurandom.c | 2 +- extmod/vfs.c | 2 +- ports/unix/modjni.c | 4 ++-- py/obj.c | 6 +++--- py/obj.h | 4 ++-- py/objarray.c | 3 +-- py/objdict.c | 2 +- py/objlist.c | 2 +- py/objrange.c | 2 +- py/objreversed.c | 2 +- py/objstr.c | 2 +- py/objstrunicode.c | 2 +- py/objtuple.c | 2 +- py/objtuple.h | 2 +- py/objtype.c | 4 ++-- py/opmethods.c | 6 +++--- py/vm.c | 4 ++-- shared-bindings/_pixelbuf/PixelBuf.c | 6 +++--- shared-bindings/displayio/Bitmap.c | 2 +- shared-bindings/displayio/Group.c | 2 +- shared-bindings/displayio/Palette.c | 2 +- shared-bindings/displayio/TileGrid.c | 2 +- shared-bindings/nvm/ByteArray.c | 2 +- shared-bindings/pulseio/PulseIn.c | 2 +- shared-bindings/random/__init__.c | 2 +- shared-module/os/__init__.c | 2 +- 29 files changed, 39 insertions(+), 40 deletions(-) (limited to 'py') diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index 826c59d0f..75496c6b5 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -61,7 +61,7 @@ STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_prin } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { // TODO support slice index to read/write multiple values at once machine_mem_obj_t *self = MP_OBJ_TO_PTR(self_in); if (value == MP_OBJ_NULL) { diff --git a/extmod/modbtree.c b/extmod/modbtree.c index 939ab813e..ad845163d 100644 --- a/extmod/modbtree.c +++ b/extmod/modbtree.c @@ -247,7 +247,7 @@ STATIC mp_obj_t btree_iternext(mp_obj_t self_in) { } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { //mp_obj_btree_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_btree_t *self = mp_instance_cast_to_native_base(self_in, &btree_type); if (value == MP_OBJ_NULL) { diff --git a/extmod/moductypes.c b/extmod/moductypes.c index 145b34887..bf5f1cef7 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -519,7 +519,7 @@ STATIC void uctypes_struct_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_obj_t value) { mp_obj_uctypes_struct_t *self = mp_instance_cast_to_native_base(base_in, &uctypes_struct_type); if (value == MP_OBJ_NULL) { diff --git a/extmod/modurandom.c b/extmod/modurandom.c index 101c80cf8..1512a3fd4 100644 --- a/extmod/modurandom.c +++ b/extmod/modurandom.c @@ -150,7 +150,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_randint_obj, mod_urandom_randint); STATIC mp_obj_t mod_urandom_choice(mp_obj_t seq) { mp_int_t len = mp_obj_get_int(mp_obj_len(seq)); if (len > 0) { - return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL, seq); + return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL); } else { nlr_raise(mp_obj_new_exception(&mp_type_IndexError)); } diff --git a/extmod/vfs.c b/extmod/vfs.c index 4d344095a..2bb4057e7 100644 --- a/extmod/vfs.c +++ b/extmod/vfs.c @@ -373,7 +373,7 @@ mp_obj_t mp_vfs_listdir(size_t n_args, const mp_obj_t *args) { mp_obj_t dir_list = mp_obj_new_list(0, NULL); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { - mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL, next)); + mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL)); } return dir_list; } diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index 8f0eac5a9..e18a26f3c 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -242,7 +242,7 @@ STATIC void get_jclass_name(jobject obj, char *buf) { } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_jobject_t *self = self_in; mp_uint_t idx = mp_obj_get_int(index); char class_name[64]; @@ -311,7 +311,7 @@ STATIC mp_obj_t jobject_unary_op(mp_unary_op_t op, mp_obj_t self_in) { // TODO: subscr_load_adaptor & subscr_getiter convenience functions // should be moved to common location for reuse. STATIC mp_obj_t subscr_load_adaptor(mp_obj_t self_in, mp_obj_t index_in) { - return mp_obj_subscr(self_in, index_in, MP_OBJ_SENTINEL, self_in); + return mp_obj_subscr(self_in, index_in, MP_OBJ_SENTINEL); } MP_DEFINE_CONST_FUN_OBJ_2(subscr_load_adaptor_obj, subscr_load_adaptor); diff --git a/py/obj.c b/py/obj.c index 47aa1aebf..09e71be4d 100644 --- a/py/obj.c +++ b/py/obj.c @@ -487,11 +487,11 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) { } } -mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { mp_obj_type_t *type = mp_obj_get_type(base); if (type->subscr != NULL) { - mp_obj_t ret = type->subscr(base, index, value, instance); + mp_obj_t ret = type->subscr(base, index, value); // May have called port specific C code. Make sure it didn't mess up the heap. assert_heap_ok(); if (ret != MP_OBJ_NULL) { @@ -546,7 +546,7 @@ STATIC mp_obj_t generic_it_iternext(mp_obj_t self_in) { mp_obj_type_t *type = mp_obj_get_type(self->obj); mp_obj_t current_length = type->unary_op(MP_UNARY_OP_LEN, self->obj); if (self->cur < MP_OBJ_SMALL_INT_VALUE(current_length)) { - mp_obj_t o_out = type->subscr(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL, self->obj); + mp_obj_t o_out = type->subscr(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL); self->cur += 1; return o_out; } else { diff --git a/py/obj.h b/py/obj.h index ff97b34d8..cf4216d02 100644 --- a/py/obj.h +++ b/py/obj.h @@ -444,7 +444,7 @@ typedef mp_obj_t (*mp_call_fun_t)(mp_obj_t fun, size_t n_args, size_t n_kw, cons typedef mp_obj_t (*mp_unary_op_fun_t)(mp_unary_op_t op, mp_obj_t); typedef mp_obj_t (*mp_binary_op_fun_t)(mp_binary_op_t op, mp_obj_t, mp_obj_t); typedef void (*mp_attr_fun_t)(mp_obj_t self_in, qstr attr, mp_obj_t *dest); -typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance); +typedef mp_obj_t (*mp_subscr_fun_t)(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); typedef mp_obj_t (*mp_getiter_fun_t)(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf); // Buffer protocol @@ -707,7 +707,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool mp_obj_t mp_obj_id(mp_obj_t o_in); mp_obj_t mp_obj_len(mp_obj_t o_in); mp_obj_t mp_obj_len_maybe(mp_obj_t o_in); // may return MP_OBJ_NULL -mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val, mp_obj_t instance); +mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t val); mp_obj_t mp_generic_unary_op(mp_unary_op_t op, mp_obj_t o_in); // cell diff --git a/py/objarray.c b/py/objarray.c index 6fffa8412..9114a63c5 100644 --- a/py/objarray.c +++ b/py/objarray.c @@ -396,8 +396,7 @@ STATIC mp_obj_t array_extend(mp_obj_t self_in, mp_obj_t arg_in) { STATIC MP_DEFINE_CONST_FUN_OBJ_2(array_extend_obj, array_extend); #endif -#pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item // TODO implement diff --git a/py/objdict.c b/py/objdict.c index 2c07331e7..5bbe939b1 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -175,7 +175,7 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) { } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete mp_obj_dict_delete(self_in, index); diff --git a/py/objlist.c b/py/objlist.c index 0c0d60aa8..64381bc70 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -159,7 +159,7 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); if (value == MP_OBJ_NULL) { // delete diff --git a/py/objrange.c b/py/objrange.c index 328416303..6f14bcc9f 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -159,7 +159,7 @@ STATIC mp_obj_t range_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs #endif #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { // load mp_obj_range_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/py/objreversed.c b/py/objreversed.c index 0b21e6938..4937d0818 100644 --- a/py/objreversed.c +++ b/py/objreversed.c @@ -66,7 +66,7 @@ STATIC mp_obj_t reversed_iternext(mp_obj_t self_in) { // pre-decrement and index sequence self->cur_index -= 1; - return mp_obj_subscr(self->seq, MP_OBJ_NEW_SMALL_INT(self->cur_index), MP_OBJ_SENTINEL, self->seq); + return mp_obj_subscr(self->seq, MP_OBJ_NEW_SMALL_INT(self->cur_index), MP_OBJ_SENTINEL); } const mp_obj_type_t mp_type_reversed = { diff --git a/py/objstr.c b/py/objstr.c index fd802fe85..567e73444 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -440,7 +440,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s // This is used for both bytes and 8-bit strings. This is not used for unicode strings. #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_type_t *type = mp_obj_get_type(self_in); GET_STR_DATA_LEN(self_in, self_data, self_len); if (value == MP_OBJ_SENTINEL) { diff --git a/py/objstrunicode.c b/py/objstrunicode.c index dc8c0743d..2540a1d7b 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -198,7 +198,7 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s } #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_type_t *type = mp_obj_get_type(self_in); assert(type == &mp_type_str); GET_STR_DATA_LEN(self_in, self_data, self_len); diff --git a/py/objtuple.c b/py/objtuple.c index b6640def5..7a4c09ab7 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -178,7 +178,7 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } #pragma GCC diagnostic ignored "-Wunused-parameter" -mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { // load mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/py/objtuple.h b/py/objtuple.h index 4df3aeded..7f20ab7b6 100644 --- a/py/objtuple.h +++ b/py/objtuple.h @@ -45,7 +45,7 @@ extern const mp_obj_type_t mp_type_tuple; void mp_obj_tuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); mp_obj_t mp_obj_tuple_unary_op(mp_unary_op_t op, mp_obj_t self_in); mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs); -mp_obj_t mp_obj_tuple_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value, mp_obj_t instance); +mp_obj_t mp_obj_tuple_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value); mp_obj_t mp_obj_tuple_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf); extern const mp_obj_type_t mp_type_attrtuple; diff --git a/py/objtype.c b/py/objtype.c index c7dc2ae78..a5e733208 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -826,7 +826,7 @@ STATIC void mp_obj_instance_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_instance_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_t member[2] = {MP_OBJ_NULL}; struct class_lookup_data lookup = { @@ -855,7 +855,7 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value if (member[0] == MP_OBJ_SENTINEL) { // native base subscr exists mp_obj_type_t *subobj_type = mp_obj_get_type(self->subobj[0]); // return mp_obj_subscr(self->subobj[0], index, value, instance); - mp_obj_t ret = subobj_type->subscr(self_in, index, value, instance); + mp_obj_t ret = subobj_type->subscr(self_in, index, value); // May have called port specific C code. Make sure it didn't mess up the heap. assert_heap_ok(); return ret; diff --git a/py/opmethods.c b/py/opmethods.c index d906ddb6a..247fa5bbc 100644 --- a/py/opmethods.c +++ b/py/opmethods.c @@ -29,19 +29,19 @@ STATIC mp_obj_t op_getitem(mp_obj_t self_in, mp_obj_t key_in) { mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, MP_OBJ_SENTINEL, self_in); + return type->subscr(self_in, key_in, MP_OBJ_SENTINEL); } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem); STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) { mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, value_in, self_in); + return type->subscr(self_in, key_in, value_in); } MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem); STATIC mp_obj_t op_delitem(mp_obj_t self_in, mp_obj_t key_in) { mp_obj_type_t *type = mp_obj_get_type(self_in); - return type->subscr(self_in, key_in, MP_OBJ_NULL, self_in); + return type->subscr(self_in, key_in, MP_OBJ_NULL); } MP_DEFINE_CONST_FUN_OBJ_2(mp_op_delitem_obj, op_delitem); diff --git a/py/vm.c b/py/vm.c index 2fe8d3237..353fc8810 100644 --- a/py/vm.c +++ b/py/vm.c @@ -386,7 +386,7 @@ dispatch_loop: ENTRY(MP_BC_LOAD_SUBSCR): { MARK_EXC_IP_SELECTIVE(); mp_obj_t index = POP(); - SET_TOP(mp_obj_subscr(TOP(), index, MP_OBJ_SENTINEL, TOP())); + SET_TOP(mp_obj_subscr(TOP(), index, MP_OBJ_SENTINEL)); DISPATCH(); } @@ -464,7 +464,7 @@ dispatch_loop: ENTRY(MP_BC_STORE_SUBSCR): MARK_EXC_IP_SELECTIVE(); - mp_obj_subscr(sp[-1], sp[0], sp[-2], sp[-1]); + mp_obj_subscr(sp[-1], sp[0], sp[-2]); sp -= 3; DISPATCH(); diff --git a/shared-bindings/_pixelbuf/PixelBuf.c b/shared-bindings/_pixelbuf/PixelBuf.c index feda2c573..a3579c92c 100644 --- a/shared-bindings/_pixelbuf/PixelBuf.c +++ b/shared-bindings/_pixelbuf/PixelBuf.c @@ -368,7 +368,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(pixelbuf_pixelbuf_fill_obj, pixelbuf_pixelbuf_f //| //| Sets the pixel value at the given index. //| -STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item // slice deletion @@ -431,7 +431,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp } } if (self->auto_write) - call_show(instance); + call_show(self_in); return mp_const_none; #else return MP_OBJ_NULL; // op not supported @@ -451,7 +451,7 @@ STATIC mp_obj_t pixelbuf_pixelbuf_subscr(mp_obj_t self_in, mp_obj_t index_in, mp pixelbuf_set_pixel(self->buf + offset, self->two_buffers ? self->rawbuf + offset : NULL, self->brightness, value, &self->byteorder, self->byteorder.is_dotstar); if (self->auto_write) - call_show(instance); + call_show(self_in); return mp_const_none; } } diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index 7c77d05ed..ca9484a40 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -134,7 +134,7 @@ const mp_obj_property_t displayio_bitmap_height_obj = { //| bitmap[0,1] = 3 //| #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj, mp_obj_t instance) { +STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { if (value_obj == mp_const_none) { // delete item mp_raise_AttributeError(translate("Cannot delete values")); diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 40f2704c0..f5e3c2263 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -311,7 +311,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| del group[0] //| #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { displayio_group_t *self = native_group(self_in); if (MP_OBJ_IS_TYPE(index_obj, &mp_type_slice)) { diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index 2fa65867a..903338abb 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -96,7 +96,7 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes //| #pragma GCC diagnostic ignored "-Wunused-parameter" -STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item return MP_OBJ_NULL; // op not supported diff --git a/shared-bindings/displayio/TileGrid.c b/shared-bindings/displayio/TileGrid.c index 5acf8496f..288eb4b23 100644 --- a/shared-bindings/displayio/TileGrid.c +++ b/shared-bindings/displayio/TileGrid.c @@ -349,7 +349,7 @@ const mp_obj_property_t displayio_tilegrid_pixel_shader_obj = { //| //| grid[0,0] = 10 //| -STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj, mp_obj_t instance) { +STATIC mp_obj_t tilegrid_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { displayio_tilegrid_t *self = native_tilegrid(self_in); diff --git a/shared-bindings/nvm/ByteArray.c b/shared-bindings/nvm/ByteArray.c index 5ac46b260..31bedeacc 100644 --- a/shared-bindings/nvm/ByteArray.c +++ b/shared-bindings/nvm/ByteArray.c @@ -70,7 +70,7 @@ STATIC const mp_rom_map_elem_t nvm_bytearray_locals_dict_table[] = { STATIC MP_DEFINE_CONST_DICT(nvm_bytearray_locals_dict, nvm_bytearray_locals_dict_table); -STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t nvm_bytearray_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item // slice deletion diff --git a/shared-bindings/pulseio/PulseIn.c b/shared-bindings/pulseio/PulseIn.c index 5947329a5..8b69109f0 100644 --- a/shared-bindings/pulseio/PulseIn.c +++ b/shared-bindings/pulseio/PulseIn.c @@ -272,7 +272,7 @@ STATIC mp_obj_t pulsein_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| pulses = pulseio.PulseIn(pin) //| print(pulses[0]) //| -STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value, mp_obj_t instance) { +STATIC mp_obj_t pulsein_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { if (value == mp_const_none) { // delete item mp_raise_AttributeError(translate("Cannot delete values")); diff --git a/shared-bindings/random/__init__.c b/shared-bindings/random/__init__.c index fdef91443..83698eac5 100644 --- a/shared-bindings/random/__init__.c +++ b/shared-bindings/random/__init__.c @@ -145,7 +145,7 @@ STATIC mp_obj_t random_choice(mp_obj_t seq) { if (len == 0) { mp_raise_IndexError(translate("empty sequence")); } - return mp_obj_subscr(seq, mp_obj_new_int(shared_modules_random_randrange(0, len, 1)), MP_OBJ_SENTINEL, seq); + return mp_obj_subscr(seq, mp_obj_new_int(shared_modules_random_randrange(0, len, 1)), MP_OBJ_SENTINEL); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(random_choice_obj, random_choice); diff --git a/shared-module/os/__init__.c b/shared-module/os/__init__.c index ad76251c8..8060eec4f 100644 --- a/shared-module/os/__init__.c +++ b/shared-module/os/__init__.c @@ -127,7 +127,7 @@ mp_obj_t common_hal_os_listdir(const char* path) { mp_obj_t next; while ((next = mp_iternext(iter_obj)) != MP_OBJ_STOP_ITERATION) { // next[0] is the filename. - mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL, dir_list)); + mp_obj_list_append(dir_list, mp_obj_subscr(next, MP_OBJ_NEW_SMALL_INT(0), MP_OBJ_SENTINEL)); RUN_BACKGROUND_TASKS; } return dir_list; -- cgit v1.2.3 From 7f7105d36d5775e6b7842a24f06604a229b2aae3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 13 Dec 2019 14:52:04 -0800 Subject: Fix tuple test --- py/objtuple.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'py') diff --git a/py/objtuple.c b/py/objtuple.c index 7a4c09ab7..cc69f5469 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -181,7 +181,7 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { // load - mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); + mp_obj_tuple_t *self = mp_instance_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_tuple)); #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_bound_slice_t slice; -- cgit v1.2.3 From d8e66a5f32749f29f5274432c616b2bd001dc7b3 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 13 Dec 2019 16:00:04 -0800 Subject: try 2. make namedtuple types handle subclasses --- py/objnamedtuple.c | 12 +++++++++++- py/objnamedtuple.h | 1 + py/objtuple.c | 3 ++- 3 files changed, 14 insertions(+), 2 deletions(-) (limited to 'py') diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index a044fe3ff..a0a64f9b2 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -31,6 +31,7 @@ #include "py/runtime.h" #include "py/objstr.h" #include "py/objnamedtuple.h" +#include "py/objtype.h" #include "supervisor/shared/translate.h" @@ -70,6 +71,15 @@ void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t ki mp_obj_attrtuple_print_helper(print, fields, &o->tuple); } +mp_obj_t namedtuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { + mp_obj_type_t *type = mp_obj_get_type(self_in); + // Check for subclasses of namedtuple and unpack if needed. + if (type->parent != &mp_type_tuple) { + self_in = ((mp_obj_instance_t*) self_in)->subobj[0]; + } + return mp_obj_tuple_subscr(self_in, index, value); +} + void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // load attribute @@ -167,7 +177,7 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t o->base.unary_op = mp_obj_tuple_unary_op; o->base.binary_op = mp_obj_tuple_binary_op; o->base.attr = namedtuple_attr; - o->base.subscr = mp_obj_tuple_subscr; + o->base.subscr = namedtuple_subscr; o->base.getiter = mp_obj_tuple_getiter; o->base.parent = &mp_type_tuple; return MP_OBJ_FROM_PTR(o); diff --git a/py/objnamedtuple.h b/py/objnamedtuple.h index 0ea0d2862..5a7512e3a 100644 --- a/py/objnamedtuple.h +++ b/py/objnamedtuple.h @@ -49,6 +49,7 @@ typedef struct _mp_obj_namedtuple_t { void namedtuple_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); size_t mp_obj_namedtuple_find_field(const mp_obj_namedtuple_type_t *type, qstr name); +mp_obj_t namedtuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value); void namedtuple_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); mp_obj_namedtuple_type_t *mp_obj_new_namedtuple_base(size_t n_fields, mp_obj_t *fields); mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args); diff --git a/py/objtuple.c b/py/objtuple.c index cc69f5469..b7f50d3b2 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -179,9 +179,10 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { #pragma GCC diagnostic ignored "-Wunused-parameter" mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { + if (value == MP_OBJ_SENTINEL) { // load - mp_obj_tuple_t *self = mp_instance_cast_to_native_base(self_in, MP_OBJ_FROM_PTR(&mp_type_tuple)); + mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); #if MICROPY_PY_BUILTINS_SLICE if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) { mp_bound_slice_t slice; -- cgit v1.2.3 From 201f4648c40c13bdbf91f8cc078c1fbecc09256d Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 16 Dec 2019 15:33:55 -0600 Subject: py.mk: Fix race condition building .mo files By having an order-only dependency on the directory itself, the directory is sure to be created before the rule to create a .mo file is. This fixes a low-freqency error on github actions such as > msgfmt: error while opening "build/genhdr/en_US.mo" for writing: No such file or directory --- py/py.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'py') diff --git a/py/py.mk b/py/py.mk index 0c68e9af1..9031c009f 100644 --- a/py/py.mk +++ b/py/py.mk @@ -317,7 +317,7 @@ SRC_QSTR += $(HEADER_BUILD)/moduledefs.h # overall config, so they need to be caught MPCONFIGPORT_MK = $(wildcard mpconfigport.mk) -$(HEADER_BUILD)/$(TRANSLATION).mo: $(TOP)/locale/$(TRANSLATION).po +$(HEADER_BUILD)/$(TRANSLATION).mo: $(TOP)/locale/$(TRANSLATION).po | $(HEADER_BUILD) $(Q)msgfmt -o $@ $^ $(HEADER_BUILD)/qstrdefs.preprocessed.h: $(PY_QSTR_DEFS) $(QSTR_DEFS) $(QSTR_DEFS_COLLECTED) mpconfigport.h $(MPCONFIGPORT_MK) $(PY_SRC)/mpconfig.h | $(HEADER_BUILD) -- cgit v1.2.3 From b859e2b71013f603bb91539a62ada4e0eee15d48 Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 20 Dec 2019 11:42:32 -0800 Subject: Remove `re` from CPX Displayio build to make space. --- .../boards/circuitplayground_express_displayio/mpconfigboard.h | 2 ++ .../boards/circuitplayground_express_displayio/mpconfigboard.mk | 2 +- py/circuitpy_mpconfig.h | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) (limited to 'py') diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h index 4486e8a6d..c9a7ce040 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.h @@ -43,3 +43,5 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 + +#define MICROPY_PY_URE 0 diff --git a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk index cf3d11d12..b5a7c2424 100644 --- a/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk +++ b/ports/atmel-samd/boards/circuitplayground_express_displayio/mpconfigboard.mk @@ -20,7 +20,7 @@ CIRCUITPY_GAMEPAD = 0 CIRCUITPY_RTC = 0 SUPEROPT_GC = 0 -CFLAGS_INLINE_LIMIT = 35 +CFLAGS_INLINE_LIMIT = 55 # Include these Python libraries in firmware. FROZEN_MPY_DIRS += $(TOP)/frozen/Adafruit_CircuitPython_BusDevice diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 3161938c4..932d4f855 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -193,7 +193,9 @@ typedef long mp_off_t; #define MICROPY_PY_UERRNO (CIRCUITPY_FULL_BUILD) // Opposite setting is deliberate. #define MICROPY_PY_UERRNO_ERRORCODE (!CIRCUITPY_FULL_BUILD) +#ifndef MICROPY_PY_URE #define MICROPY_PY_URE (CIRCUITPY_FULL_BUILD) +#endif #define MICROPY_PY_URE_MATCH_GROUPS (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_URE_MATCH_SPAN_START_END (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_URE_SUB (CIRCUITPY_FULL_BUILD) -- cgit v1.2.3 From 767ce1cdf8c56ed00f2b88c4babcd92b91b51755 Mon Sep 17 00:00:00 2001 From: Roy Hooper Date: Thu, 2 Jan 2020 18:03:18 -0500 Subject: remove unnecessary GCC pragmas --- extmod/machine_mem.c | 1 - extmod/moductypes.c | 1 - ports/unix/modjni.c | 1 - py/objdict.c | 1 - py/objlist.c | 1 - py/objrange.c | 1 - py/objstr.c | 1 - py/objstrunicode.c | 1 - py/objtuple.c | 1 - shared-bindings/displayio/Bitmap.c | 1 - shared-bindings/displayio/Group.c | 1 - shared-bindings/displayio/Palette.c | 1 - 12 files changed, 12 deletions(-) (limited to 'py') diff --git a/extmod/machine_mem.c b/extmod/machine_mem.c index 75496c6b5..e0649290e 100644 --- a/extmod/machine_mem.c +++ b/extmod/machine_mem.c @@ -60,7 +60,6 @@ STATIC void machine_mem_print(const mp_print_t *print, mp_obj_t self_in, mp_prin mp_printf(print, "<%u-bit memory>", 8 * self->elem_size); } -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t machine_mem_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { // TODO support slice index to read/write multiple values at once machine_mem_obj_t *self = MP_OBJ_TO_PTR(self_in); diff --git a/extmod/moductypes.c b/extmod/moductypes.c index bf5f1cef7..451dc29ed 100644 --- a/extmod/moductypes.c +++ b/extmod/moductypes.c @@ -518,7 +518,6 @@ STATIC void uctypes_struct_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { } } -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t uctypes_struct_subscr(mp_obj_t base_in, mp_obj_t index_in, mp_obj_t value) { mp_obj_uctypes_struct_t *self = mp_instance_cast_to_native_base(base_in, &uctypes_struct_type); diff --git a/ports/unix/modjni.c b/ports/unix/modjni.c index e18a26f3c..8ec5ae54d 100644 --- a/ports/unix/modjni.c +++ b/ports/unix/modjni.c @@ -241,7 +241,6 @@ STATIC void get_jclass_name(jobject obj, char *buf) { check_exception(); } -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t jobject_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_jobject_t *self = self_in; mp_uint_t idx = mp_obj_get_int(index); diff --git a/py/objdict.c b/py/objdict.c index 5bbe939b1..683fcb748 100644 --- a/py/objdict.c +++ b/py/objdict.c @@ -174,7 +174,6 @@ mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index) { } } -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t dict_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete diff --git a/py/objlist.c b/py/objlist.c index 64381bc70..b32f82085 100644 --- a/py/objlist.c +++ b/py/objlist.c @@ -158,7 +158,6 @@ STATIC mp_obj_t list_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } } -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_list_t *self = mp_instance_cast_to_native_base(self_in, &mp_type_list); if (value == MP_OBJ_NULL) { diff --git a/py/objrange.c b/py/objrange.c index 6f14bcc9f..30d55c56c 100644 --- a/py/objrange.c +++ b/py/objrange.c @@ -158,7 +158,6 @@ STATIC mp_obj_t range_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs } #endif -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t range_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { // load diff --git a/py/objstr.c b/py/objstr.c index 567e73444..fde264681 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -439,7 +439,6 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s #endif // This is used for both bytes and 8-bit strings. This is not used for unicode strings. -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t bytes_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_type_t *type = mp_obj_get_type(self_in); GET_STR_DATA_LEN(self_in, self_data, self_len); diff --git a/py/objstrunicode.c b/py/objstrunicode.c index 2540a1d7b..30000a51e 100644 --- a/py/objstrunicode.c +++ b/py/objstrunicode.c @@ -197,7 +197,6 @@ const byte *str_index_to_ptr(const mp_obj_type_t *type, const byte *self_data, s return s; } -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { mp_obj_type_t *type = mp_obj_get_type(self_in); assert(type == &mp_type_str); diff --git a/py/objtuple.c b/py/objtuple.c index b7f50d3b2..2b483f8b8 100644 --- a/py/objtuple.c +++ b/py/objtuple.c @@ -177,7 +177,6 @@ mp_obj_t mp_obj_tuple_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) { } } -#pragma GCC diagnostic ignored "-Wunused-parameter" mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) { if (value == MP_OBJ_SENTINEL) { diff --git a/shared-bindings/displayio/Bitmap.c b/shared-bindings/displayio/Bitmap.c index ca9484a40..91c17f2d1 100644 --- a/shared-bindings/displayio/Bitmap.c +++ b/shared-bindings/displayio/Bitmap.c @@ -133,7 +133,6 @@ const mp_obj_property_t displayio_bitmap_height_obj = { //| //| bitmap[0,1] = 3 //| -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t bitmap_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value_obj) { if (value_obj == mp_const_none) { // delete item diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index f5e3c2263..dd7600eb9 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -310,7 +310,6 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| //| del group[0] //| -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t group_subscr(mp_obj_t self_in, mp_obj_t index_obj, mp_obj_t value) { displayio_group_t *self = native_group(self_in); diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index 903338abb..dda58e3c5 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -95,7 +95,6 @@ STATIC mp_obj_t group_unary_op(mp_unary_op_t op, mp_obj_t self_in) { //| palette[2] = b'\xff\xff\x00\x00' # set using 4 bytes //| palette[3] = bytearray(b'\x00\x00\xFF') # set using a bytearay of 3 or 4 bytes //| -#pragma GCC diagnostic ignored "-Wunused-parameter" STATIC mp_obj_t palette_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value) { if (value == MP_OBJ_NULL) { // delete item -- cgit v1.2.3 From 82fb761c0f93152feb7cef0a177a160d370a8b6e Mon Sep 17 00:00:00 2001 From: Scott Shawcroft Date: Fri, 6 Dec 2019 12:27:46 -0800 Subject: Add PacketBuffer and MTU negotiation support. PacketBuffer facilitates packet oriented BLE protocols such as BLE MIDI and the Apple Media Service. This also adds PHY, MTU and connection event extension negotiation to speed up data transfer when possible. --- ports/nrf/bluetooth/ble_drv.c | 2 +- ports/nrf/boards/common.template.ld | 8 +- ports/nrf/common-hal/_bleio/Adapter.c | 60 ++++- ports/nrf/common-hal/_bleio/Adapter.h | 2 +- ports/nrf/common-hal/_bleio/Characteristic.c | 2 +- ports/nrf/common-hal/_bleio/Connection.c | 41 +++- ports/nrf/common-hal/_bleio/Connection.h | 1 + ports/nrf/common-hal/_bleio/PacketBuffer.c | 331 +++++++++++++++++++++++++++ ports/nrf/common-hal/_bleio/PacketBuffer.h | 49 ++++ ports/nrf/common-hal/_bleio/__init__.c | 3 + py/circuitpy_defns.mk | 1 + shared-bindings/_bleio/PacketBuffer.c | 201 ++++++++++++++++ shared-bindings/_bleio/PacketBuffer.h | 43 ++++ shared-bindings/_bleio/__init__.c | 5 +- 14 files changed, 726 insertions(+), 23 deletions(-) create mode 100644 ports/nrf/common-hal/_bleio/PacketBuffer.c create mode 100644 ports/nrf/common-hal/_bleio/PacketBuffer.h create mode 100644 shared-bindings/_bleio/PacketBuffer.c create mode 100644 shared-bindings/_bleio/PacketBuffer.h (limited to 'py') diff --git a/ports/nrf/bluetooth/ble_drv.c b/ports/nrf/bluetooth/ble_drv.c index 7dbb31582..28a265b7f 100644 --- a/ports/nrf/bluetooth/ble_drv.c +++ b/ports/nrf/bluetooth/ble_drv.c @@ -46,7 +46,7 @@ nrf_nvic_state_t nrf_nvic_state = { 0 }; volatile sd_flash_operation_status_t sd_flash_operation_status; __attribute__((aligned(4))) -static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATT_ATT_MTU_DEFAULT)]; +static uint8_t m_ble_evt_buf[sizeof(ble_evt_t) + (BLE_GATTS_VAR_ATTR_LEN_MAX)]; void ble_drv_reset() { // Linked list items will be gc'd. diff --git a/ports/nrf/boards/common.template.ld b/ports/nrf/boards/common.template.ld index 931f95ee9..b110e6052 100644 --- a/ports/nrf/boards/common.template.ld +++ b/ports/nrf/boards/common.template.ld @@ -16,7 +16,13 @@ MEMORY FLASH_FATFS (r) : ORIGIN = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_START_ADDR}, LENGTH = ${CIRCUITPY_INTERNAL_FLASH_FILESYSTEM_SIZE} FLASH_BOOTLOADER (rx) : ORIGIN = ${BOOTLOADER_START_ADDR}, LENGTH = ${BOOTLOADER_SIZE} FLASH_BOOTLOADER_SETTINGS (r) : ORIGIN = ${BOOTLOADER_SETTINGS_START_ADDR}, LENGTH = ${BOOTLOADER_SETTINGS_SIZE} - RAM (xrw) : ORIGIN = 0x20004000, LENGTH = 0x03C000 /* 240 KiB */ + + + /* 0x2000000 - RAM:ORIGIN is reserved for Softdevice */ + /* SoftDevice 6.1.0 takes 0x7b78 bytes (30.86 kb) minimum with high ATT MTU. */ + /* To measure the minimum required amount of memory for given configuration, set this number + high enough to work and then check the mutation of the value done by sd_ble_enable. */ + RAM (xrw) : ORIGIN = 0x20000000 + 32K, LENGTH = 256K - 32K } /* produce a link error if there is not this amount of RAM for these sections */ diff --git a/ports/nrf/common-hal/_bleio/Adapter.c b/ports/nrf/common-hal/_bleio/Adapter.c index cee40a5a0..b9b6d2e88 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.c +++ b/ports/nrf/common-hal/_bleio/Adapter.c @@ -67,7 +67,7 @@ STATIC void softdevice_assert_handler(uint32_t id, uint32_t pc, uint32_t info) { reset_into_safe_mode(NORDIC_SOFT_DEVICE_ASSERT); } -bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT]; +bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; // Linker script provided ram start. extern uint32_t _ram_start; @@ -133,6 +133,15 @@ STATIC uint32_t ble_stack_enable(void) { return err_code; } + // Set ATT_MTU so that the maximum MTU we can negotiate is up to the full characteristic size. + memset(&ble_conf, 0, sizeof(ble_conf)); + ble_conf.conn_cfg.conn_cfg_tag = BLE_CONN_CFG_TAG_CUSTOM; + ble_conf.conn_cfg.params.gatt_conn_cfg.att_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX; + err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATT, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) { + return err_code; + } + // Triple the GATT Server attribute size to accomodate both the CircuitPython built-in service // and anything the user does. memset(&ble_conf, 0, sizeof(ble_conf)); @@ -142,7 +151,14 @@ STATIC uint32_t ble_stack_enable(void) { return err_code; } - // TODO set ATT_MTU so that the maximum MTU we can negotiate is higher than the default. + // Increase the number of vendor UUIDs supported. Apple uses a complete random number per + // service and characteristic. + memset(&ble_conf, 0, sizeof(ble_conf)); + ble_conf.common_cfg.vs_uuid_cfg.vs_uuid_count = 32; // Defaults to 10. + err_code = sd_ble_cfg_set(BLE_COMMON_CFG_VS_UUID, &ble_conf, app_ram_start); + if (err_code != NRF_SUCCESS) { + return err_code; + } // This sets app_ram_start to the minimum value needed for the settings set above. err_code = sd_ble_enable(&app_ram_start); @@ -150,6 +166,14 @@ STATIC uint32_t ble_stack_enable(void) { return err_code; } + // Turn on connection event extension so we can transmit for a longer period of time as needed. + ble_opt_t opt; + opt.common_opt.conn_evt_ext.enable = true; + err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt); + if (err_code != NRF_SUCCESS) { + return err_code; + } + ble_gap_conn_params_t gap_conn_params = { .min_conn_interval = BLE_MIN_CONN_INTERVAL, .max_conn_interval = BLE_MAX_CONN_INTERVAL, @@ -177,7 +201,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { // total connection limit. bleio_connection_internal_t *connection; for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - connection = &connections[i]; + connection = &bleio_connections[i]; if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) { break; } @@ -189,6 +213,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { connection->conn_handle = ble_evt->evt.gap_evt.conn_handle; connection->connection_obj = mp_const_none; connection->pair_status = PAIR_NOT_PAIRED; + connection->mtu = 0; ble_drv_add_event_handler_entry(&connection->handler_entry, connection_on_ble_evt, connection); self->connection_objs = NULL; @@ -216,7 +241,7 @@ STATIC bool adapter_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { // Find the connection that was disconnected. bleio_connection_internal_t *connection; for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - connection = &connections[i]; + connection = &bleio_connections[i]; if (connection->conn_handle == ble_evt->evt.gap_evt.conn_handle) { break; } @@ -293,7 +318,7 @@ void common_hal_bleio_adapter_set_enabled(bleio_adapter_obj_t *self, bool enable // Add a handler for incoming peripheral connections. if (enabled) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - bleio_connection_internal_t *connection = &connections[i]; + bleio_connection_internal_t *connection = &bleio_connections[i]; connection->conn_handle = BLE_CONN_HANDLE_INVALID; } bleio_adapter_reset_name(self); @@ -497,14 +522,25 @@ mp_obj_t common_hal_bleio_adapter_connect(bleio_adapter_obj_t *self, bleio_addre ble_drv_remove_event_handler(connect_on_ble_evt, &event_info); - if (event_info.conn_handle == BLE_CONN_HANDLE_INVALID) { + uint16_t conn_handle = event_info.conn_handle; + if (conn_handle == BLE_CONN_HANDLE_INVALID) { mp_raise_bleio_BluetoothError(translate("Failed to connect: timeout")); } + // Negotiate for better PHY, larger MTU and data lengths since we are the central. These are + // nice-to-haves so ignore any errors. + ble_gap_phys_t const phys = { + .rx_phys = BLE_GAP_PHY_AUTO, + .tx_phys = BLE_GAP_PHY_AUTO, + }; + sd_ble_gap_phy_update(conn_handle, &phys); + sd_ble_gattc_exchange_mtu_request(conn_handle, BLE_GATTS_VAR_ATTR_LEN_MAX); + sd_ble_gap_data_length_update(conn_handle, NULL, NULL); + // Make the connection object and return it. for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - bleio_connection_internal_t *connection = &connections[i]; - if (connection->conn_handle == event_info.conn_handle) { + bleio_connection_internal_t *connection = &bleio_connections[i]; + if (connection->conn_handle == conn_handle) { return bleio_connection_new_from_internal(connection); } } @@ -628,7 +664,7 @@ void common_hal_bleio_adapter_stop_advertising(bleio_adapter_obj_t *self) { bool common_hal_bleio_adapter_get_connected(bleio_adapter_obj_t *self) { for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - bleio_connection_internal_t *connection = &connections[i]; + bleio_connection_internal_t *connection = &bleio_connections[i]; if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) { return true; } @@ -643,7 +679,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) { size_t total_connected = 0; mp_obj_t items[BLEIO_TOTAL_CONNECTION_COUNT]; for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - bleio_connection_internal_t *connection = &connections[i]; + bleio_connection_internal_t *connection = &bleio_connections[i]; if (connection->conn_handle != BLE_CONN_HANDLE_INVALID) { if (connection->connection_obj == mp_const_none) { connection->connection_obj = bleio_connection_new_from_internal(connection); @@ -658,7 +694,7 @@ mp_obj_t common_hal_bleio_adapter_get_connections(bleio_adapter_obj_t *self) { void bleio_adapter_gc_collect(bleio_adapter_obj_t* adapter) { gc_collect_root((void**)adapter, sizeof(bleio_adapter_obj_t) / sizeof(size_t)); - gc_collect_root((void**)connections, sizeof(connections) / sizeof(size_t)); + gc_collect_root((void**)bleio_connections, sizeof(bleio_connections) / sizeof(size_t)); } void bleio_adapter_reset(bleio_adapter_obj_t* adapter) { @@ -666,7 +702,7 @@ void bleio_adapter_reset(bleio_adapter_obj_t* adapter) { common_hal_bleio_adapter_stop_advertising(adapter); adapter->connection_objs = NULL; for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - bleio_connection_internal_t *connection = &connections[i]; + bleio_connection_internal_t *connection = &bleio_connections[i]; connection->connection_obj = mp_const_none; } } diff --git a/ports/nrf/common-hal/_bleio/Adapter.h b/ports/nrf/common-hal/_bleio/Adapter.h index dca443990..2ac568d66 100644 --- a/ports/nrf/common-hal/_bleio/Adapter.h +++ b/ports/nrf/common-hal/_bleio/Adapter.h @@ -37,7 +37,7 @@ #define BLEIO_TOTAL_CONNECTION_COUNT 2 -extern bleio_connection_internal_t connections[BLEIO_TOTAL_CONNECTION_COUNT]; +extern bleio_connection_internal_t bleio_connections[BLEIO_TOTAL_CONNECTION_COUNT]; typedef struct { mp_obj_base_t base; diff --git a/ports/nrf/common-hal/_bleio/Characteristic.c b/ports/nrf/common-hal/_bleio/Characteristic.c index 9f1255e32..c7eec94c0 100644 --- a/ports/nrf/common-hal/_bleio/Characteristic.c +++ b/ports/nrf/common-hal/_bleio/Characteristic.c @@ -154,7 +154,7 @@ void common_hal_bleio_characteristic_set_value(bleio_characteristic_obj_t *self, common_hal_bleio_gatts_write(self->handle, BLE_CONN_HANDLE_INVALID, bufinfo); // Check to see if we need to notify or indicate any active connections. for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { - bleio_connection_internal_t *connection = &connections[i]; + bleio_connection_internal_t *connection = &bleio_connections[i]; uint16_t conn_handle = connection->conn_handle; if (connection->conn_handle == BLE_CONN_HANDLE_INVALID) { continue; diff --git a/ports/nrf/common-hal/_bleio/Connection.c b/ports/nrf/common-hal/_bleio/Connection.c index e0b50901a..daf5b937b 100644 --- a/ports/nrf/common-hal/_bleio/Connection.c +++ b/ports/nrf/common-hal/_bleio/Connection.c @@ -85,6 +85,7 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { switch (ble_evt->header.evt_id) { case BLE_GAP_EVT_DISCONNECTED: break; + case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { ble_gap_phys_t const phys = { .rx_phys = BLE_GAP_PHY_AUTO, @@ -94,20 +95,45 @@ bool connection_on_ble_evt(ble_evt_t *ble_evt, void *self_in) { break; } - case BLE_GAP_EVT_PHY_UPDATE: // 0x22 + case BLE_GAP_EVT_PHY_UPDATE: { // 0x22 break; + } case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST: // SoftDevice will respond to a length update request. sd_ble_gap_data_length_update(self->conn_handle, NULL, NULL); break; - case BLE_GAP_EVT_DATA_LENGTH_UPDATE: // 0x24 + case BLE_GAP_EVT_DATA_LENGTH_UPDATE: { // 0x24 break; + } case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST: { - // We only handle MTU of size BLE_GATT_ATT_MTU_DEFAULT. - sd_ble_gatts_exchange_mtu_reply(self->conn_handle, BLE_GATT_ATT_MTU_DEFAULT); + ble_gatts_evt_exchange_mtu_request_t *request = + &ble_evt->evt.gatts_evt.params.exchange_mtu_request; + + uint16_t new_mtu = BLE_GATTS_VAR_ATTR_LEN_MAX; + if (request->client_rx_mtu < new_mtu) { + new_mtu = request->client_rx_mtu; + } + if (new_mtu < BLE_GATT_ATT_MTU_DEFAULT) { + new_mtu = BLE_GATT_ATT_MTU_DEFAULT; + } + if (self->mtu > 0) { + new_mtu = self->mtu; + } + + self->mtu = new_mtu; + sd_ble_gatts_exchange_mtu_reply(self->conn_handle, new_mtu); + break; + } + + + case BLE_GATTC_EVT_EXCHANGE_MTU_RSP: { + ble_gattc_evt_exchange_mtu_rsp_t *response = + &ble_evt->evt.gattc_evt.params.exchange_mtu_rsp; + + self->mtu = response->server_rx_mtu; break; } @@ -319,8 +345,11 @@ STATIC bool discover_next_services(bleio_connection_internal_t* connection, uint m_discovery_successful = false; m_discovery_in_process = true; - check_nrf_error(sd_ble_gattc_primary_services_discover(connection->conn_handle, - start_handle, service_uuid)); + uint32_t nrf_err = NRF_ERROR_BUSY; + while (nrf_err == NRF_ERROR_BUSY) { + nrf_err = sd_ble_gattc_primary_services_discover(connection->conn_handle, start_handle, service_uuid); + } + check_nrf_error(nrf_err); // Wait for a discovery event. while (m_discovery_in_process) { diff --git a/ports/nrf/common-hal/_bleio/Connection.h b/ports/nrf/common-hal/_bleio/Connection.h index 1474a0a6c..61bbea4a1 100644 --- a/ports/nrf/common-hal/_bleio/Connection.h +++ b/ports/nrf/common-hal/_bleio/Connection.h @@ -65,6 +65,7 @@ typedef struct { ble_drv_evt_handler_entry_t handler_entry; ble_gap_conn_params_t conn_params; volatile bool conn_params_updating; + uint16_t mtu; } bleio_connection_internal_t; typedef struct { diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.c b/ports/nrf/common-hal/_bleio/PacketBuffer.c new file mode 100644 index 000000000..fbcc72a6a --- /dev/null +++ b/ports/nrf/common-hal/_bleio/PacketBuffer.c @@ -0,0 +1,331 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019-2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include +#include + +#include "ble_drv.h" +#include "ble_gatts.h" +#include "nrf_nvic.h" + +#include "lib/utils/interrupt_char.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include "tick.h" + +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/Connection.h" +#include "shared-bindings/_bleio/PacketBuffer.h" +#include "supervisor/shared/tick.h" + +STATIC void write_to_ringbuf(bleio_packet_buffer_obj_t *self, uint8_t *data, uint16_t len) { + if (len + sizeof(uint16_t) > self->ringbuf.size) { + // This shouldn't happen. + return; + } + // Push all the data onto the ring buffer. + uint8_t is_nested_critical_region; + sd_nvic_critical_region_enter(&is_nested_critical_region); + // Make room for the new value by dropping the oldest packets first. + while (self->ringbuf.size - ringbuf_count(&self->ringbuf) < (int) (len + sizeof(uint16_t))) { + uint16_t packet_length; + ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t)); + for (uint16_t i = 0; i < packet_length; i++) { + ringbuf_get(&self->ringbuf); + } + // set an overflow flag? + } + ringbuf_put_n(&self->ringbuf, (uint8_t*) &len, sizeof(uint16_t)); + ringbuf_put_n(&self->ringbuf, data, len); + sd_nvic_critical_region_exit(is_nested_critical_region); +} + +STATIC uint32_t queue_next_write(bleio_packet_buffer_obj_t *self) { + self->packet_queued = false; + if (self->pending_size > 0) { + uint16_t conn_handle = self->conn_handle; + uint32_t err_code; + if (self->client) { + ble_gattc_write_params_t write_params = { + .write_op = self->write_type, + .handle = self->characteristic->handle, + .p_value = self->outgoing[self->pending_index], + .len = self->pending_size, + }; + + err_code = sd_ble_gattc_write(conn_handle, &write_params); + } else { + uint16_t hvx_len = self->pending_size; + + ble_gatts_hvx_params_t hvx_params = { + .handle = self->characteristic->handle, + .type = self->write_type, + .offset = 0, + .p_len = &hvx_len, + .p_data = self->outgoing[self->pending_index], + }; + err_code = sd_ble_gatts_hvx(conn_handle, &hvx_params); + } + if (err_code != NRF_SUCCESS) { + // On error, simply skip updating the pending buffers so that the next HVC or WRITE + // complete event triggers another attempt. + return err_code; + } + self->pending_size = 0; + self->pending_index = (self->pending_index + 1) % 2; + self->packet_queued = true; + } + return NRF_SUCCESS; +} + +STATIC bool packet_buffer_on_ble_client_evt(ble_evt_t *ble_evt, void *param) { + bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param; + uint16_t conn_handle = ble_evt->evt.gattc_evt.conn_handle; + if (conn_handle != self->conn_handle) { + return false; + } + switch (ble_evt->header.evt_id) { + case BLE_GATTC_EVT_HVX: { + // A remote service wrote to this characteristic. + ble_gattc_evt_hvx_t* evt_hvx = &ble_evt->evt.gattc_evt.params.hvx; + // Must be a notification, and event handle must match the handle for my characteristic. + if (evt_hvx->handle == self->characteristic->handle) { + write_to_ringbuf(self, evt_hvx->data, evt_hvx->len); + if (evt_hvx->type == BLE_GATT_HVX_INDICATION) { + sd_ble_gattc_hv_confirm(conn_handle, evt_hvx->handle); + } + } + break; + } + case BLE_GATTC_EVT_WRITE_CMD_TX_COMPLETE: { + queue_next_write(self); + break; + } + case BLE_GATTC_EVT_WRITE_RSP: { + queue_next_write(self); + break; + } + default: + return false; + break; + } + return true; +} + +STATIC bool packet_buffer_on_ble_server_evt(ble_evt_t *ble_evt, void *param) { + bleio_packet_buffer_obj_t *self = (bleio_packet_buffer_obj_t *) param; + uint16_t conn_handle = ble_evt->evt.gatts_evt.conn_handle; + switch (ble_evt->header.evt_id) { + case BLE_GATTS_EVT_WRITE: { + // A client wrote to this server characteristic. + + ble_gatts_evt_write_t *evt_write = &ble_evt->evt.gatts_evt.params.write; + // Event handle must match the handle for my characteristic. + if (evt_write->handle == self->characteristic->handle) { + if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { + self->conn_handle = conn_handle; + } else if (self->conn_handle != conn_handle) { + return false; + } + write_to_ringbuf(self, evt_write->data, evt_write->len); + } else if (evt_write->handle == self->characteristic->cccd_handle && + self->conn_handle == BLE_CONN_HANDLE_INVALID) { + uint16_t cccd = *((uint16_t*) evt_write->data); + if (cccd & BLE_GATT_HVX_NOTIFICATION) { + self->conn_handle = conn_handle; + } else { + self->conn_handle = BLE_CONN_HANDLE_INVALID; + } + } + break; + } + case BLE_GATTS_EVT_HVN_TX_COMPLETE: { + queue_next_write(self); + } + default: + return false; + break; + } + return true; +} + +void common_hal_bleio_packet_buffer_construct( + bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, + size_t buffer_size) { + + self->characteristic = characteristic; + self->client = self->characteristic->service->is_remote; + bleio_characteristic_properties_t incoming = self->characteristic->props & (CHAR_PROP_WRITE_NO_RESPONSE | CHAR_PROP_WRITE); + bleio_characteristic_properties_t outgoing = self->characteristic->props & (CHAR_PROP_NOTIFY | CHAR_PROP_INDICATE); + + if (self->client) { + // Swap if we're the client. + bleio_characteristic_properties_t temp = incoming; + incoming = outgoing; + outgoing = temp; + self->conn_handle = bleio_connection_get_conn_handle(MP_OBJ_TO_PTR(self->characteristic->service->connection)); + } + + if (incoming) { + // This is a macro. + ringbuf_alloc(&self->ringbuf, buffer_size * (sizeof(uint16_t) + characteristic->max_length), false); + + if (self->ringbuf.buf == NULL) { + mp_raise_ValueError(translate("Buffer too large and unable to allocate")); + } + } + + if (outgoing) { + self->packet_queued = false; + self->pending_index = 0; + self->pending_size = 0; + self->outgoing[0] = m_malloc(characteristic->max_length, false); + self->outgoing[1] = m_malloc(characteristic->max_length, false); + } else { + self->outgoing[0] = NULL; + self->outgoing[1] = NULL; + } + + if (self->client) { + ble_drv_add_event_handler(packet_buffer_on_ble_client_evt, self); + if (incoming) { + // Prefer notify if both are available. + if (incoming & CHAR_PROP_NOTIFY) { + self->write_type = BLE_GATT_HVX_NOTIFICATION; + common_hal_bleio_characteristic_set_cccd(self->characteristic, true, false); + } else { + common_hal_bleio_characteristic_set_cccd(self->characteristic, false, true); + } + } + if (outgoing) { + self->write_type = BLE_GATT_OP_WRITE_REQ; + if (outgoing & CHAR_PROP_WRITE_NO_RESPONSE) { + self->write_type = BLE_GATT_OP_WRITE_CMD; + } + } + } else { + ble_drv_add_event_handler(packet_buffer_on_ble_server_evt, self); + if (outgoing) { + self->write_type = BLE_GATT_HVX_INDICATION; + if (outgoing & CHAR_PROP_NOTIFY) { + self->write_type = BLE_GATT_HVX_NOTIFICATION; + } + } + } +} + +int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len) { + if (ringbuf_count(&self->ringbuf) < 2) { + return 0; + } + + uint16_t packet_length; + ringbuf_get_n(&self->ringbuf, (uint8_t*) &packet_length, sizeof(uint16_t)); + + // Copy received data. Lock out write interrupt handler while copying. + uint8_t is_nested_critical_region; + sd_nvic_critical_region_enter(&is_nested_critical_region); + + if (packet_length > len) { + // TODO: raise an exception. + packet_length = len; + } + + ringbuf_get_n(&self->ringbuf, data, packet_length); + + // Writes now OK. + sd_nvic_critical_region_exit(is_nested_critical_region); + + return packet_length; +} + +void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len) { + if (self->outgoing[0] == NULL) { + mp_raise_bleio_BluetoothError(translate("Writes not supported on Characteristic")); + } + if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { + return; + } + uint16_t packet_size = common_hal_bleio_packet_buffer_get_packet_size(self); + uint16_t max_size = packet_size - len; + while (max_size < self->pending_size && self->conn_handle != BLE_CONN_HANDLE_INVALID) { + RUN_BACKGROUND_TASKS; + } + if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { + return; + } + uint8_t is_nested_critical_region; + sd_nvic_critical_region_enter(&is_nested_critical_region); + + uint8_t* pending = self->outgoing[self->pending_index]; + + if (self->pending_size == 0) { + memcpy(pending, header, header_len); + self->pending_size += header_len; + } + memcpy(pending + self->pending_size, data, len); + self->pending_size += len; + + sd_nvic_critical_region_exit(is_nested_critical_region); + + // If no writes are queued then sneak in this data. + if (!self->packet_queued) { + queue_next_write(self); + } +} + +uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self) { + uint16_t mtu; + if (self->conn_handle == BLE_CONN_HANDLE_INVALID) { + return 0; + } + bleio_connection_internal_t *connection; + for (size_t i = 0; i < BLEIO_TOTAL_CONNECTION_COUNT; i++) { + connection = &bleio_connections[i]; + if (connection->conn_handle == self->conn_handle) { + break; + } + } + if (connection->mtu == 0) { + mtu = 23; + } + if (self->characteristic->max_length > mtu) { + mtu = self->characteristic->max_length; + } + uint16_t att_overhead = 3; + return mtu - att_overhead; +} + +bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self) { + return self->characteristic == NULL; +} + +void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self) { + if (!common_hal_bleio_packet_buffer_deinited(self)) { + ble_drv_remove_event_handler(packet_buffer_on_ble_client_evt, self); + } +} diff --git a/ports/nrf/common-hal/_bleio/PacketBuffer.h b/ports/nrf/common-hal/_bleio/PacketBuffer.h new file mode 100644 index 000000000..7a090f539 --- /dev/null +++ b/ports/nrf/common-hal/_bleio/PacketBuffer.h @@ -0,0 +1,49 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019-2020 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PACKETBUFFER_H +#define MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PACKETBUFFER_H + +#include "nrf_soc.h" + +#include "py/ringbuf.h" +#include "shared-bindings/_bleio/Characteristic.h" + +typedef struct { + mp_obj_base_t base; + bleio_characteristic_obj_t *characteristic; + // Ring buffer storing consecutive incoming values. + ringbuf_t ringbuf; + uint8_t* outgoing[2]; + uint16_t pending_size; + uint16_t conn_handle; + uint8_t pending_index; + uint8_t write_type; + bool client; + bool packet_queued; +} bleio_packet_buffer_obj_t; + +#endif // MICROPY_INCLUDED_NRF_COMMON_HAL_BLEIO_PACKETBUFFER_H diff --git a/ports/nrf/common-hal/_bleio/__init__.c b/ports/nrf/common-hal/_bleio/__init__.c index 4b2780ded..8606c89ec 100644 --- a/ports/nrf/common-hal/_bleio/__init__.c +++ b/ports/nrf/common-hal/_bleio/__init__.c @@ -48,6 +48,9 @@ void check_nrf_error(uint32_t err_code) { case NRF_ERROR_TIMEOUT: mp_raise_msg(&mp_type_TimeoutError, NULL); return; + case BLE_ERROR_INVALID_CONN_HANDLE: + mp_raise_bleio_ConnectionError(translate("Not connected")); + return; default: mp_raise_bleio_BluetoothError(translate("Unknown soft device error: %04x"), err_code); break; diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 8dd4fc6b1..35a977946 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -236,6 +236,7 @@ SRC_COMMON_HAL_ALL = \ _bleio/CharacteristicBuffer.c \ _bleio/Connection.c \ _bleio/Descriptor.c \ + _bleio/PacketBuffer.c \ _bleio/Service.c \ _bleio/UUID.c \ analogio/AnalogIn.c \ diff --git a/shared-bindings/_bleio/PacketBuffer.c b/shared-bindings/_bleio/PacketBuffer.c new file mode 100644 index 000000000..f9f171870 --- /dev/null +++ b/shared-bindings/_bleio/PacketBuffer.c @@ -0,0 +1,201 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include "py/mperrno.h" +#include "py/ioctl.h" +#include "py/objproperty.h" +#include "py/runtime.h" +#include "py/stream.h" + +#include "shared-bindings/_bleio/__init__.h" +#include "shared-bindings/_bleio/PacketBuffer.h" +#include "shared-bindings/_bleio/UUID.h" +#include "shared-bindings/util.h" + +//| .. currentmodule:: _bleio +//| +//| :class:`PacketBuffer` -- Packet-oriented characteristic usage. +//| ===================================================================== +//| +//| Accumulates a Characteristic's incoming packets in a FIFO buffer and facilitates packet aware +//| outgoing writes. A packet's size is either the characteristic length or the maximum transmission +//| unit (MTU), whichever is smaller. The MTU can change so check `packet_size` before creating a +//| buffer to store data. +//| +//| When we're the server, we ignore all connections besides the first to subscribe to +//| notifications. +//| +//| .. class:: PacketBuffer(characteristic, *, buffer_size) +//| +//| Monitor the given Characteristic. Each time a new value is written to the Characteristic +//| add the newly-written bytes to a FIFO buffer. +//| +//| :param Characteristic characteristic: The Characteristic to monitor. +//| It may be a local Characteristic provided by a Peripheral Service, or a remote Characteristic +//| in a remote Service that a Central has connected to. +//| :param int buffer_size: Size of ring buffer (in packets of the Characteristic's maximum +//| length) that stores incoming packets coming from the peer. +//| +STATIC mp_obj_t bleio_packet_buffer_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_characteristic, ARG_buffer_size }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_characteristic, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_buffer_size, MP_ARG_KW_ONLY | MP_ARG_REQUIRED | MP_ARG_INT }, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + const mp_obj_t characteristic = args[ARG_characteristic].u_obj; + + const int buffer_size = args[ARG_buffer_size].u_int; + if (buffer_size < 1) { + mp_raise_ValueError_varg(translate("%q must be >= 1"), MP_QSTR_buffer_size); + } + + if (!MP_OBJ_IS_TYPE(characteristic, &bleio_characteristic_type)) { + mp_raise_TypeError(translate("Expected a Characteristic")); + } + + bleio_packet_buffer_obj_t *self = m_new_obj(bleio_packet_buffer_obj_t); + self->base.type = &bleio_packet_buffer_type; + + common_hal_bleio_packet_buffer_construct(self, MP_OBJ_TO_PTR(characteristic), buffer_size); + + return MP_OBJ_FROM_PTR(self); +} + +STATIC void check_for_deinit(bleio_packet_buffer_obj_t *self) { + if (common_hal_bleio_packet_buffer_deinited(self)) { + raise_deinited_error(); + } +} + +//| .. method:: readinto(buf) +//| +//| Reads a single BLE packet into the ``buf``. Raises an exception if the next packet is longer +//| than the given buffer. Use `packet_size` to read the maximum length of a single packet. +//| +//| :return: number of bytes read and stored into ``buf`` +//| :rtype: int +//| +STATIC mp_obj_t bleio_packet_buffer_readinto(mp_obj_t self_in, mp_obj_t buffer_obj) { + bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + + mp_buffer_info_t bufinfo; + mp_get_buffer_raise(buffer_obj, &bufinfo, MP_BUFFER_WRITE); + + return MP_OBJ_NEW_SMALL_INT(common_hal_bleio_packet_buffer_readinto(self, bufinfo.buf, bufinfo.len)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_2(bleio_packet_buffer_readinto_obj, bleio_packet_buffer_readinto); + +//| .. method:: write(data, *, header=None) +//| +//| Writes all bytes from data into the same outgoing packet. The bytes from header are included +//| before data when the pending packet is currently empty. +//| +//| This does not block until the data is sent. It only blocks until the data is pending. +//| +// TODO: Add a kwarg `merge=False` to dictate whether subsequent writes are merged into a pending +// one. +STATIC mp_obj_t bleio_packet_buffer_write(mp_uint_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { + enum { ARG_data, ARG_header }; + static const mp_arg_t allowed_args[] = { + { MP_QSTR_data, MP_ARG_REQUIRED | MP_ARG_OBJ }, + { MP_QSTR_header, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}}, + }; + + mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; + mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); + + bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]); + check_for_deinit(self); + + mp_buffer_info_t data_bufinfo; + mp_get_buffer_raise(args[ARG_data].u_obj, &data_bufinfo, MP_BUFFER_READ); + + mp_buffer_info_t header_bufinfo; + header_bufinfo.len = 0; + if (args[ARG_header].u_obj != MP_OBJ_NULL) { + mp_get_buffer_raise(args[ARG_header].u_obj, &header_bufinfo, MP_BUFFER_READ); + } + + common_hal_bleio_packet_buffer_write(self, data_bufinfo.buf, data_bufinfo.len, + header_bufinfo.buf, header_bufinfo.len); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_KW(bleio_packet_buffer_write_obj, 1, bleio_packet_buffer_write); + +//| .. method:: deinit() +//| +//| Disable permanently. +//| +STATIC mp_obj_t bleio_packet_buffer_deinit(mp_obj_t self_in) { + bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + common_hal_bleio_packet_buffer_deinit(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_deinit_obj, bleio_packet_buffer_deinit); + +//| .. attribute:: packet_size +//| +//| Maximum size of each packet in bytes. This is the minimum of the Characterstic length and +//| the negotiated Maximum Transfer Unit (MTU). +//| +STATIC mp_obj_t bleio_packet_buffer_get_packet_size(mp_obj_t self_in) { + bleio_packet_buffer_obj_t *self = MP_OBJ_TO_PTR(self_in); + + return mp_obj_new_bool(common_hal_bleio_packet_buffer_get_packet_size(self)); +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(bleio_packet_buffer_get_packet_size_obj, bleio_packet_buffer_get_packet_size); + +const mp_obj_property_t bleio_packet_buffer_packet_size_obj = { + .base.type = &mp_type_property, + .proxy = { (mp_obj_t)&bleio_packet_buffer_get_packet_size_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj }, +}; + +STATIC const mp_rom_map_elem_t bleio_packet_buffer_locals_dict_table[] = { + { MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&bleio_packet_buffer_deinit_obj) }, + + // Standard stream methods. + { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&bleio_packet_buffer_readinto_obj) }, + { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&bleio_packet_buffer_write_obj) }, + + { MP_OBJ_NEW_QSTR(MP_QSTR_packet_size), MP_ROM_PTR(&bleio_packet_buffer_packet_size_obj) }, +}; + +STATIC MP_DEFINE_CONST_DICT(bleio_packet_buffer_locals_dict, bleio_packet_buffer_locals_dict_table); + + +const mp_obj_type_t bleio_packet_buffer_type = { + { &mp_type_type }, + .name = MP_QSTR_PacketBuffer, + .make_new = bleio_packet_buffer_make_new, + .locals_dict = (mp_obj_dict_t*)&bleio_packet_buffer_locals_dict +}; diff --git a/shared-bindings/_bleio/PacketBuffer.h b/shared-bindings/_bleio/PacketBuffer.h new file mode 100644 index 000000000..990a2f8bb --- /dev/null +++ b/shared-bindings/_bleio/PacketBuffer.h @@ -0,0 +1,43 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2019 Scott Shawcroft for Adafruit Industries + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PACKETBUFFER_H +#define MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PACKETBUFFER_H + +#include "common-hal/_bleio/PacketBuffer.h" + +extern const mp_obj_type_t bleio_packet_buffer_type; + +extern void common_hal_bleio_packet_buffer_construct( + bleio_packet_buffer_obj_t *self, bleio_characteristic_obj_t *characteristic, + size_t buffer_size); +void common_hal_bleio_packet_buffer_write(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len, uint8_t* header, size_t header_len); +int common_hal_bleio_packet_buffer_readinto(bleio_packet_buffer_obj_t *self, uint8_t *data, size_t len); +uint16_t common_hal_bleio_packet_buffer_get_packet_size(bleio_packet_buffer_obj_t *self); +bool common_hal_bleio_packet_buffer_deinited(bleio_packet_buffer_obj_t *self); +void common_hal_bleio_packet_buffer_deinit(bleio_packet_buffer_obj_t *self); + +#endif // MICROPY_INCLUDED_SHARED_BINDINGS_BLEIO_PACKETBUFFER_H diff --git a/shared-bindings/_bleio/__init__.c b/shared-bindings/_bleio/__init__.c index ba2454da4..5d26862a6 100644 --- a/shared-bindings/_bleio/__init__.c +++ b/shared-bindings/_bleio/__init__.c @@ -35,6 +35,7 @@ #include "shared-bindings/_bleio/CharacteristicBuffer.h" #include "shared-bindings/_bleio/Connection.h" #include "shared-bindings/_bleio/Descriptor.h" +#include "shared-bindings/_bleio/PacketBuffer.h" #include "shared-bindings/_bleio/ScanEntry.h" #include "shared-bindings/_bleio/ScanResults.h" #include "shared-bindings/_bleio/Service.h" @@ -69,6 +70,7 @@ //| CharacteristicBuffer //| Connection //| Descriptor +//| PacketBuffer //| ScanEntry //| ScanResults //| Service @@ -140,8 +142,9 @@ STATIC const mp_rom_map_elem_t bleio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Characteristic), MP_ROM_PTR(&bleio_characteristic_type) }, { MP_ROM_QSTR(MP_QSTR_CharacteristicBuffer), MP_ROM_PTR(&bleio_characteristic_buffer_type) }, { MP_ROM_QSTR(MP_QSTR_Descriptor), MP_ROM_PTR(&bleio_descriptor_type) }, + { MP_ROM_QSTR(MP_QSTR_PacketBuffer), MP_ROM_PTR(&bleio_packet_buffer_type) }, { MP_ROM_QSTR(MP_QSTR_ScanEntry), MP_ROM_PTR(&bleio_scanentry_type) }, - { MP_ROM_QSTR(MP_QSTR_ScanResults), MP_ROM_PTR(&bleio_scanresults_type) }, + { MP_ROM_QSTR(MP_QSTR_ScanResults), MP_ROM_PTR(&bleio_scanresults_type) }, { MP_ROM_QSTR(MP_QSTR_Service), MP_ROM_PTR(&bleio_service_type) }, { MP_ROM_QSTR(MP_QSTR_UUID), MP_ROM_PTR(&bleio_uuid_type) }, -- cgit v1.2.3 From d2b2cf0addd3476256d34cde4df2f53f6a2868a9 Mon Sep 17 00:00:00 2001 From: Marius-450 Date: Sat, 4 Jan 2020 12:20:32 -0500 Subject: CIRCUITPY_DISPLAY_LIMIT = 2 --- py/circuitpy_mpconfig.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'py') diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 932d4f855..95f1056db 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -328,7 +328,7 @@ extern const struct _mp_obj_module_t terminalio_module; #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #define FONTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_fontio), (mp_obj_t)&fontio_module }, #define TERMINALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module }, -#define CIRCUITPY_DISPLAY_LIMIT (1) +#define CIRCUITPY_DISPLAY_LIMIT (2) #else #define DISPLAYIO_MODULE #define FONTIO_MODULE -- cgit v1.2.3 From 3ad3d49959271b4b33950d9d68daf1b9a722c95f Mon Sep 17 00:00:00 2001 From: Marius-450 Date: Sat, 4 Jan 2020 12:32:49 -0500 Subject: changes only for monster m4sk --- ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h | 7 +++++++ py/circuitpy_mpconfig.h | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'py') diff --git a/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h index 42fb4548e..4bd01706d 100644 --- a/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h +++ b/ports/atmel-samd/boards/monster_m4sk/mpconfigboard.h @@ -19,3 +19,10 @@ // USB is always used internally so skip the pin objects for it. #define IGNORE_PIN_PA24 1 #define IGNORE_PIN_PA25 1 + +// Enable the use of 2 displays + +#define CIRCUITPY_DISPLAY_LIMIT (2) + + + diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 95f1056db..8c7454cf2 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -328,7 +328,9 @@ extern const struct _mp_obj_module_t terminalio_module; #define DISPLAYIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_displayio), (mp_obj_t)&displayio_module }, #define FONTIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_fontio), (mp_obj_t)&fontio_module }, #define TERMINALIO_MODULE { MP_OBJ_NEW_QSTR(MP_QSTR_terminalio), (mp_obj_t)&terminalio_module }, -#define CIRCUITPY_DISPLAY_LIMIT (2) +#ifndef CIRCUITPY_DISPLAY_LIMIT +#define CIRCUITPY_DISPLAY_LIMIT (1) +#endif #else #define DISPLAYIO_MODULE #define FONTIO_MODULE -- cgit v1.2.3 From dd6010a17ef8e12e1cb3f36721b205cc1cb8eee9 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Mon, 6 Jan 2020 13:35:43 -0600 Subject: Fix more build problems --- py/circuitpy_defns.mk | 2 +- shared-module/audiomp3/MP3Decoder.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'py') diff --git a/py/circuitpy_defns.mk b/py/circuitpy_defns.mk index 8dd4fc6b1..38b41c619 100644 --- a/py/circuitpy_defns.mk +++ b/py/circuitpy_defns.mk @@ -322,7 +322,7 @@ SRC_SHARED_MODULE_ALL = \ audiomixer/Mixer.c \ audiomixer/MixerVoice.c \ audiomp3/__init__.c \ - audiomp3/MP3File.c \ + audiomp3/MP3Decoder.c \ bitbangio/I2C.c \ bitbangio/OneWire.c \ bitbangio/SPI.c \ diff --git a/shared-module/audiomp3/MP3Decoder.c b/shared-module/audiomp3/MP3Decoder.c index 515aa0086..30357c616 100644 --- a/shared-module/audiomp3/MP3Decoder.c +++ b/shared-module/audiomp3/MP3Decoder.c @@ -25,7 +25,7 @@ * THE SOFTWARE. */ -#include "shared-bindings/audiomp3/MP3File.h" +#include "shared-bindings/audiomp3/MP3Decoder.h" #include #include @@ -34,7 +34,7 @@ #include "py/mperrno.h" #include "py/runtime.h" -#include "shared-module/audiomp3/MP3File.h" +#include "shared-module/audiomp3/MP3Decoder.h" #include "supervisor/shared/translate.h" #include "lib/mp3/src/mp3common.h" -- cgit v1.2.3 From 5baaac55ce2b9fb89c1f395e92f67abb5276ce6f Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 8 Jan 2020 09:42:44 -0600 Subject: vstr_init_len: Don't crash if (size_t)-1 is passed In this unusual case, (len + 1) is zero, the allocation in vstr_init succeeds (allocating 1 byte), and then the caller is likely to erroneously access outside the allocated region, for instance with a memset(). This could be triggered with os.urandom(-1) after it was converted to use mp_obj_new_bytes_of_zeros. --- py/vstr.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'py') diff --git a/py/vstr.c b/py/vstr.c index 869b27805..888f7069b 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -50,6 +50,8 @@ void vstr_init(vstr_t *vstr, size_t alloc) { // Init the vstr so it allocs exactly enough ram to hold a null-terminated // string of the given length, and set the length. void vstr_init_len(vstr_t *vstr, size_t len) { + if(len == SIZE_MAX) + m_malloc_fail(len); vstr_init(vstr, len + 1); vstr->len = len; } -- cgit v1.2.3 From f1c2dee1c05227d63e3833cb10d6fe99b9bd5092 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 8 Jan 2020 16:36:43 -0600 Subject: style --- py/vstr.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'py') diff --git a/py/vstr.c b/py/vstr.c index 888f7069b..91cd7f584 100644 --- a/py/vstr.c +++ b/py/vstr.c @@ -50,8 +50,9 @@ void vstr_init(vstr_t *vstr, size_t alloc) { // Init the vstr so it allocs exactly enough ram to hold a null-terminated // string of the given length, and set the length. void vstr_init_len(vstr_t *vstr, size_t len) { - if(len == SIZE_MAX) + if(len == SIZE_MAX) { m_malloc_fail(len); + } vstr_init(vstr, len + 1); vstr->len = len; } -- cgit v1.2.3 From 10eed78dd8047f406d3be26f540e39eecba437c7 Mon Sep 17 00:00:00 2001 From: Hierophect Date: Wed, 8 Jan 2020 17:37:20 -0500 Subject: use CFLAG to properly set define --- ports/stm32f4/mpconfigport.mk | 2 +- py/circuitpy_mpconfig.h | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'py') diff --git a/ports/stm32f4/mpconfigport.mk b/ports/stm32f4/mpconfigport.mk index 48bd3ad61..f214282cb 100644 --- a/ports/stm32f4/mpconfigport.mk +++ b/ports/stm32f4/mpconfigport.mk @@ -69,7 +69,7 @@ ifndef CIRCUITPY_DISPLAYIO CIRCUITPY_DISPLAYIO = 1 endif -MICROPY_CPYTHON_COMPAT = 1 +CFLAGS += -DMICROPY_CPYTHON_COMPAT=1 #ifeq ($(MCU_SUB_VARIANT), stm32f412zx) #endif diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 8c7454cf2..5b705a088 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -182,7 +182,10 @@ typedef long mp_off_t; // Remove some lesser-used functionality to make small builds fit. #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (CIRCUITPY_FULL_BUILD) -#define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD) +//TODO: replace this with a rework of the FULL_BUILD system +#if !defined(MICROPY_CPYTHON_COMPAT) + #define MICROPY_CPYTHON_COMPAT (CIRCUITPY_FULL_BUILD) +#endif #define MICROPY_MODULE_WEAK_LINKS (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_ALL_SPECIAL_METHODS (CIRCUITPY_FULL_BUILD) #define MICROPY_PY_BUILTINS_COMPLEX (CIRCUITPY_FULL_BUILD) -- cgit v1.2.3 From 189f2d5f077cd4c30e6ad0fe6033869b580ea9a6 Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Thu, 9 Jan 2020 17:31:50 -0500 Subject: Make requiring I2C pullups be optional --- ports/atmel-samd/common-hal/busio/I2C.c | 3 +++ ports/nrf/common-hal/busio/I2C.c | 2 ++ py/circuitpy_mpconfig.mk | 7 +++++++ 3 files changed, 12 insertions(+) (limited to 'py') diff --git a/ports/atmel-samd/common-hal/busio/I2C.c b/ports/atmel-samd/common-hal/busio/I2C.c index b0e5714a7..ffe74a274 100644 --- a/ports/atmel-samd/common-hal/busio/I2C.c +++ b/ports/atmel-samd/common-hal/busio/I2C.c @@ -76,6 +76,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, mp_raise_ValueError(translate("Invalid pins")); } +#if CIRCUITPY_REQUIRE_I2C_PULLUPS // Test that the pins are in a high state. (Hopefully indicating they are pulled up.) gpio_set_pin_function(sda->number, GPIO_PIN_FUNCTION_OFF); gpio_set_pin_function(scl->number, GPIO_PIN_FUNCTION_OFF); @@ -98,6 +99,8 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, reset_pin_number(scl->number); mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); } +#endif + gpio_set_pin_function(sda->number, sda_pinmux); gpio_set_pin_function(scl->number, scl_pinmux); diff --git a/ports/nrf/common-hal/busio/I2C.c b/ports/nrf/common-hal/busio/I2C.c index f6f686cdf..219fbf447 100644 --- a/ports/nrf/common-hal/busio/I2C.c +++ b/ports/nrf/common-hal/busio/I2C.c @@ -115,6 +115,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t * mp_raise_ValueError(translate("All I2C peripherals are in use")); } +#if CIRCUITPY_REQUIRE_I2C_PULLUPS // Test that the pins are in a high state. (Hopefully indicating they are pulled up.) nrf_gpio_cfg_input(scl->number, NRF_GPIO_PIN_PULLDOWN); nrf_gpio_cfg_input(sda->number, NRF_GPIO_PIN_PULLDOWN); @@ -132,6 +133,7 @@ void common_hal_busio_i2c_construct(busio_i2c_obj_t *self, const mcu_pin_obj_t * reset_pin_number(scl->number); mp_raise_RuntimeError(translate("SDA or SCL needs a pull up")); } +#endif nrfx_twim_config_t config = NRFX_TWIM_DEFAULT_CONFIG(scl->number, sda->number); diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index a464583f3..93175e136 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -310,6 +310,13 @@ CIRCUITPY_BITBANG_APA102 = 0 endif CFLAGS += -DCIRCUITPY_BITBANG_APA102=$(CIRCUITPY_BITBANG_APA102) +# Should busio.I2C() check for pullups? +# Some boards in combination with certain peripherals may not want this. +ifndef CIRCUITPY_REQUIRE_I2C_PULLUPS +CIRCUITPY_REQUIRE_I2C_PULLUPS = 1 +endif +CFLAGS += -DCIRCUITPY_REQUIRE_I2C_PULLUPS=$(CIRCUITPY_REQUIRE_I2C_PULLUPS) + # REPL over BLE ifndef CIRCUITPY_SERIAL_BLE CIRCUITPY_SERIAL_BLE = 0 -- cgit v1.2.3