From 2fc5a934a1b038be2acd6fe9241e0ae809d3675a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Fri, 29 Sep 2023 23:01:02 -0400 Subject: [PATCH] add back generic subscript iterator, gc_never_free --- py/gc.c | 32 ++++++++++++++++++ py/mkrules.mk | 3 +- py/obj.c | 33 +++++++++++++++++++ py/obj.h | 2 +- shared-bindings/adafruit_pixelbuf/PixelBuf.c | 2 +- shared-bindings/displayio/Group.c | 2 +- shared-bindings/displayio/Palette.c | 3 +- .../memorymonitor/AllocationSize.c | 2 +- 8 files changed, 72 insertions(+), 7 deletions(-) diff --git a/py/gc.c b/py/gc.c index acb7edf873..cccc096e57 100644 --- a/py/gc.c +++ b/py/gc.c @@ -1099,6 +1099,38 @@ void *gc_realloc(void *ptr_in, size_t n_bytes, bool allow_move) { } #endif // Alternative gc_realloc impl +bool gc_never_free(void *ptr) { + // Check to make sure the pointer is on the heap in the first place. + if (gc_nbytes(ptr) == 0) { + return false; + } + // Pointers are stored in a linked list where each block is BYTES_PER_BLOCK long and the first + // pointer is the next block of pointers. + void **current_reference_block = MP_STATE_MEM(permanent_pointers); + void **last_reference_block = NULL; + while (current_reference_block != NULL) { + for (size_t i = 1; i < BYTES_PER_BLOCK / sizeof(void *); i++) { + if (current_reference_block[i] == NULL) { + current_reference_block[i] = ptr; + return true; + } + } + last_reference_block = current_reference_block; // keep a record of last "proper" reference block + current_reference_block = current_reference_block[0]; + } + void **next_block = gc_alloc(BYTES_PER_BLOCK, false); + if (next_block == NULL) { + return false; + } + if (MP_STATE_MEM(permanent_pointers) == NULL) { + MP_STATE_MEM(permanent_pointers) = next_block; + } else { + last_reference_block[0] = next_block; + } + next_block[1] = ptr; + return true; +} + void gc_dump_info(const mp_print_t *print) { gc_info_t info; gc_info(&info); diff --git a/py/mkrules.mk b/py/mkrules.mk index 421a0d1c59..0dd35573d0 100644 --- a/py/mkrules.mk +++ b/py/mkrules.mk @@ -78,7 +78,8 @@ $(Q)$(CXX) $(CXXFLAGS) -c -MD -o $@ $< || (echo -e $(HELP_BUILD_ERROR); false) $(RM) -f $(@:.o=.d) endef -vpath %.c . $(TOP) $(USER_C_MODULES) +# CIRCUITPY: add $(DEVICES_MODULES) and $(BUILD) +vpath %.c . $(TOP) $(USER_C_MODULES) $(DEVICES_MODULES) $(BUILD) $(BUILD)/%.o: %.c $(call compile_c) diff --git a/py/obj.c b/py/obj.c index 9c1cffc728..f8316ce5b2 100644 --- a/py/obj.c +++ b/py/obj.c @@ -640,6 +640,39 @@ mp_obj_t mp_identity(mp_obj_t self) { } MP_DEFINE_CONST_FUN_OBJ_1(mp_identity_obj, mp_identity); +// CIRCUITPY +// generic subscript iterator, which iterates through anything with a 0-based subscript. +typedef struct { + mp_obj_base_t base; + mp_fun_1_t iternext; + mp_obj_t obj; + mp_int_t cur; +} mp_obj_generic_subscript_it_t; + +STATIC mp_obj_t generic_subscript_it_iternext(mp_obj_t self_in) { + mp_obj_generic_subscript_it_t *self = MP_OBJ_TO_PTR(self_in); + const mp_obj_type_t *type = mp_obj_get_type(self->obj); + mp_obj_t current_length = MP_OBJ_TYPE_GET_SLOT(type, unary_op)(MP_UNARY_OP_LEN, self->obj); + if (self->cur < MP_OBJ_SMALL_INT_VALUE(current_length)) { + mp_obj_t o_out = + MP_OBJ_TYPE_GET_SLOT(type, subscr)(self->obj, MP_OBJ_NEW_SMALL_INT(self->cur), MP_OBJ_SENTINEL); + self->cur += 1; + return o_out; + } else { + return MP_OBJ_STOP_ITERATION; + } +} + +mp_obj_t mp_obj_generic_subscript_getiter(mp_obj_t obj, mp_obj_iter_buf_t *iter_buf) { + assert(sizeof(mp_obj_generic_subscript_it_t) <= sizeof(mp_obj_iter_buf_t)); + mp_obj_generic_subscript_it_t *o = (mp_obj_generic_subscript_it_t *)iter_buf; + o->base.type = &mp_type_polymorph_iter; + o->iternext = &generic_subscript_it_iternext; + o->obj = obj; + o->cur = 0; + return MP_OBJ_FROM_PTR(o); +} + // mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) { // (void)iter_buf; // return self; diff --git a/py/obj.h b/py/obj.h index bb55ea3351..2576f87cf1 100644 --- a/py/obj.h +++ b/py/obj.h @@ -1251,7 +1251,7 @@ MP_DECLARE_CONST_FUN_OBJ_1(mp_identity_obj); // Generic iterator that uses unary op and subscr to iterate over a native type. It will be slower // than a custom iterator but applies broadly. -mp_obj_t mp_obj_new_generic_iterator(mp_obj_t self, mp_obj_iter_buf_t *iter_buf); +mp_obj_t mp_obj_generic_subscript_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf); // module typedef struct _mp_obj_module_t { diff --git a/shared-bindings/adafruit_pixelbuf/PixelBuf.c b/shared-bindings/adafruit_pixelbuf/PixelBuf.c index e7bde6f429..20455026b4 100644 --- a/shared-bindings/adafruit_pixelbuf/PixelBuf.c +++ b/shared-bindings/adafruit_pixelbuf/PixelBuf.c @@ -376,5 +376,5 @@ MP_DEFINE_CONST_OBJ_TYPE( make_new, pixelbuf_pixelbuf_make_new, subscr, pixelbuf_pixelbuf_subscr, unary_op, pixelbuf_pixelbuf_unary_op, - iter, mp_obj_new_generic_iterator + iter, mp_obj_generic_subscript_getiter ); diff --git a/shared-bindings/displayio/Group.c b/shared-bindings/displayio/Group.c index 03ba3c4165..177d62f83a 100644 --- a/shared-bindings/displayio/Group.c +++ b/shared-bindings/displayio/Group.c @@ -356,5 +356,5 @@ MP_DEFINE_CONST_OBJ_TYPE( locals_dict, &displayio_group_locals_dict, subscr, group_subscr, unary_op, group_unary_op, - iter, mp_obj_new_generic_iterator + iter, mp_obj_generic_subscript_getiter ); diff --git a/shared-bindings/displayio/Palette.c b/shared-bindings/displayio/Palette.c index dcf0f7bd9b..2c0e7ee3a1 100644 --- a/shared-bindings/displayio/Palette.c +++ b/shared-bindings/displayio/Palette.c @@ -223,6 +223,5 @@ MP_DEFINE_CONST_OBJ_TYPE( locals_dict, &displayio_palette_locals_dict, subscr, palette_subscr, unary_op, group_unary_op, - iter, mp_obj_new_generic_iterator - + iter, mp_obj_generic_subscript_getiter ); diff --git a/shared-bindings/memorymonitor/AllocationSize.c b/shared-bindings/memorymonitor/AllocationSize.c index 53ca66227d..117ad2a9d4 100644 --- a/shared-bindings/memorymonitor/AllocationSize.c +++ b/shared-bindings/memorymonitor/AllocationSize.c @@ -171,6 +171,6 @@ MP_DEFINE_CONST_OBJ_TYPE( make_new, memorymonitor_allocationsize_make_new, subscr, memorymonitor_allocationsize_subscr, unary_op, memorymonitor_allocationsize_unary_op, - getiter, mp_obj_new_generic_iterator, + iter, mp_obj_generic_subscript_getiter, locals_dict, &memorymonitor_allocationsize_locals_dict );