py/obj: Add accessors for type slots and use everywhere.

This is a no-op, but sets the stage for changing the mp_obj_type_t
representation.

Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
This commit is contained in:
Jim Mussared 2021-07-14 17:14:16 +10:00 committed by Damien George
parent e8355eb163
commit a52cd5b07d
27 changed files with 207 additions and 188 deletions

View File

@ -137,7 +137,7 @@ int nina_bsp_spi_slave_deselect(void) {
int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) { int nina_bsp_spi_transfer(const uint8_t *tx_buf, uint8_t *rx_buf, uint32_t size) {
mp_obj_t mp_wifi_spi = MP_STATE_PORT(mp_wifi_spi); mp_obj_t mp_wifi_spi = MP_STATE_PORT(mp_wifi_spi);
((mp_machine_spi_p_t *)machine_spi_type.protocol)->transfer(mp_wifi_spi, size, tx_buf, rx_buf); ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_spi_type, protocol))->transfer(mp_wifi_spi, size, tx_buf, rx_buf);
#if NINA_DEBUG #if NINA_DEBUG
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (tx_buf) { if (tx_buf) {

View File

@ -51,7 +51,7 @@ int *__errno (void)
ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) {
mp_obj_base_t* o = stream; mp_obj_base_t* o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno);
if (out_sz == MP_STREAM_ERROR) { if (out_sz == MP_STREAM_ERROR) {
return -1; return -1;
@ -62,7 +62,7 @@ ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) {
ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) {
mp_obj_base_t* o = stream; mp_obj_base_t* o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno); mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &native_errno);
if (out_sz == MP_STREAM_ERROR) { if (out_sz == MP_STREAM_ERROR) {
return -1; return -1;
@ -73,7 +73,7 @@ ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) {
off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) {
const mp_obj_base_t* o = stream; const mp_obj_base_t* o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
struct mp_stream_seek_t seek_s; struct mp_stream_seek_t seek_s;
seek_s.offset = offset; seek_s.offset = offset;
seek_s.whence = whence; seek_s.whence = whence;
@ -86,7 +86,7 @@ off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) {
int mp_stream_posix_fsync(void *stream) { int mp_stream_posix_fsync(void *stream) {
mp_obj_base_t* o = stream; mp_obj_base_t* o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno); mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &native_errno);
if (res == MP_STREAM_ERROR) { if (res == MP_STREAM_ERROR) {
return -1; return -1;
@ -124,11 +124,11 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
btree_type.base.type = (void*)&mp_fun_table.type_type; btree_type.base.type = (void*)&mp_fun_table.type_type;
btree_type.name = MP_QSTR_btree; btree_type.name = MP_QSTR_btree;
btree_type.print = btree_print; MP_OBJ_TYPE_SET_SLOT(&btree_type, print, btree_print, 0);
btree_type.getiter = btree_getiter; MP_OBJ_TYPE_SET_SLOT(&btree_type, getiter, btree_getiter, 1);
btree_type.iternext = btree_iternext; MP_OBJ_TYPE_SET_SLOT(&btree_type, iternext, btree_iternext, 2);
btree_type.binary_op = btree_binary_op; MP_OBJ_TYPE_SET_SLOT(&btree_type, binary_op, btree_binary_op, 3);
btree_type.subscr = btree_subscr; MP_OBJ_TYPE_SET_SLOT(&btree_type, subscr, btree_subscr, 4);
btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) }; btree_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_close), MP_OBJ_FROM_PTR(&btree_close_obj) };
btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) }; btree_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_flush), MP_OBJ_FROM_PTR(&btree_flush_obj) };
btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) }; btree_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_get), MP_OBJ_FROM_PTR(&btree_get_obj) };
@ -137,7 +137,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) }; btree_locals_dict_table[5] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_keys), MP_OBJ_FROM_PTR(&btree_keys_obj) };
btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) }; btree_locals_dict_table[6] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_values), MP_OBJ_FROM_PTR(&btree_values_obj) };
btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) }; btree_locals_dict_table[7] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_items), MP_OBJ_FROM_PTR(&btree_items_obj) };
btree_type.locals_dict = (void*)&btree_locals_dict; MP_OBJ_TYPE_SET_SLOT(&btree_type, locals_dict, (void*)&btree_locals_dict, 5);
mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj)); mp_store_global(MP_QSTR__open, MP_OBJ_FROM_PTR(&btree_open_obj));
mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL)); mp_store_global(MP_QSTR_INCL, MP_OBJ_NEW_SMALL_INT(FLAG_END_KEY_INCL));

View File

@ -21,7 +21,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
mp_type_framebuf.base.type = (void*)&mp_type_type; mp_type_framebuf.base.type = (void*)&mp_type_type;
mp_type_framebuf.name = MP_QSTR_FrameBuffer; mp_type_framebuf.name = MP_QSTR_FrameBuffer;
mp_type_framebuf.make_new = framebuf_make_new; mp_type_framebuf.make_new = framebuf_make_new;
mp_type_framebuf.buffer = framebuf_get_buffer; MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, buffer, framebuf_get_buffer, 0);
framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) }; framebuf_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill), MP_OBJ_FROM_PTR(&framebuf_fill_obj) };
framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) }; framebuf_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_fill_rect), MP_OBJ_FROM_PTR(&framebuf_fill_rect_obj) };
framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) }; framebuf_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_pixel), MP_OBJ_FROM_PTR(&framebuf_pixel_obj) };
@ -33,7 +33,7 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) }; framebuf_locals_dict_table[8] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_blit), MP_OBJ_FROM_PTR(&framebuf_blit_obj) };
framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) }; framebuf_locals_dict_table[9] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_scroll), MP_OBJ_FROM_PTR(&framebuf_scroll_obj) };
framebuf_locals_dict_table[10] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) }; framebuf_locals_dict_table[10] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_text), MP_OBJ_FROM_PTR(&framebuf_text_obj) };
mp_type_framebuf.locals_dict = (void*)&framebuf_locals_dict; MP_OBJ_TYPE_SET_SLOT(&mp_type_framebuf, locals_dict, (void*)&framebuf_locals_dict, 1);
mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf)); mp_store_global(MP_QSTR_FrameBuffer, MP_OBJ_FROM_PTR(&mp_type_framebuf));
mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj)); mp_store_global(MP_QSTR_FrameBuffer1, MP_OBJ_FROM_PTR(&legacy_framebuffer1_obj));

View File

@ -54,21 +54,21 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
match_type.base.type = (void*)&mp_fun_table.type_type; match_type.base.type = (void*)&mp_fun_table.type_type;
match_type.name = MP_QSTR_match; match_type.name = MP_QSTR_match;
match_type.print = match_print; MP_OBJ_TYPE_SET_SLOT(&match_type, print, match_print, 0);
match_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_group), MP_OBJ_FROM_PTR(&match_group_obj) }; match_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_group), MP_OBJ_FROM_PTR(&match_group_obj) };
match_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_groups), MP_OBJ_FROM_PTR(&match_groups_obj) }; match_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_groups), MP_OBJ_FROM_PTR(&match_groups_obj) };
match_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_span), MP_OBJ_FROM_PTR(&match_span_obj) }; match_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_span), MP_OBJ_FROM_PTR(&match_span_obj) };
match_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_start), MP_OBJ_FROM_PTR(&match_start_obj) }; match_locals_dict_table[3] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_start), MP_OBJ_FROM_PTR(&match_start_obj) };
match_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_OBJ_FROM_PTR(&match_end_obj) }; match_locals_dict_table[4] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_end), MP_OBJ_FROM_PTR(&match_end_obj) };
match_type.locals_dict = (void*)&match_locals_dict; MP_OBJ_TYPE_SET_SLOT(&match_type, locals_dict, (void*)&match_locals_dict, 1);
re_type.base.type = (void*)&mp_fun_table.type_type; re_type.base.type = (void*)&mp_fun_table.type_type;
re_type.name = MP_QSTR_ure; re_type.name = MP_QSTR_ure;
re_type.print = re_print; MP_OBJ_TYPE_SET_SLOT(&re_type, print, re_print, 0);
re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) }; re_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_match), MP_OBJ_FROM_PTR(&re_match_obj) };
re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) }; re_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_search), MP_OBJ_FROM_PTR(&re_search_obj) };
re_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_split), MP_OBJ_FROM_PTR(&re_split_obj) }; re_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_split), MP_OBJ_FROM_PTR(&re_split_obj) };
re_type.locals_dict = (void*)&re_locals_dict; MP_OBJ_TYPE_SET_SLOT(&re_type, locals_dict, (void*)&re_locals_dict, 1);
mp_store_global(MP_QSTR_compile, MP_OBJ_FROM_PTR(&mod_re_compile_obj)); mp_store_global(MP_QSTR_compile, MP_OBJ_FROM_PTR(&mod_re_compile_obj));
mp_store_global(MP_QSTR_match, MP_OBJ_FROM_PTR(&re_match_obj)); mp_store_global(MP_QSTR_match, MP_OBJ_FROM_PTR(&re_match_obj));

View File

@ -20,12 +20,12 @@ mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *a
decompio_type.base.type = mp_fun_table.type_type; decompio_type.base.type = mp_fun_table.type_type;
decompio_type.name = MP_QSTR_DecompIO; decompio_type.name = MP_QSTR_DecompIO;
decompio_type.make_new = decompio_make_new; decompio_type.make_new = &decompio_make_new;
decompio_type.protocol = &decompio_stream_p; MP_OBJ_TYPE_SET_SLOT(&decompio_type, protocol, &decompio_stream_p, 0);
decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) }; decompio_locals_dict_table[0] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_read), MP_OBJ_FROM_PTR(&mp_stream_read_obj) };
decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) }; decompio_locals_dict_table[1] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_OBJ_FROM_PTR(&mp_stream_readinto_obj) };
decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) }; decompio_locals_dict_table[2] = (mp_map_elem_t){ MP_OBJ_NEW_QSTR(MP_QSTR_readline), MP_OBJ_FROM_PTR(&mp_stream_unbuffered_readline_obj) };
decompio_type.locals_dict = (void*)&decompio_locals_dict; MP_OBJ_TYPE_SET_SLOT(&decompio_type, locals_dict, (void*)&decompio_locals_dict, 1);
mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib)); mp_store_global(MP_QSTR___name__, MP_OBJ_NEW_QSTR(MP_QSTR_uzlib));
mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj)); mp_store_global(MP_QSTR_decompress, MP_OBJ_FROM_PTR(&mod_uzlib_decompress_obj));

View File

@ -273,7 +273,7 @@ int mp_machine_i2c_transfer_adaptor(mp_obj_base_t *self, uint16_t addr, size_t n
} }
} }
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
int ret = i2c_p->transfer_single(self, addr, len, buf, flags); int ret = i2c_p->transfer_single(self, addr, len, buf, flags);
if (n > 1) { if (n > 1) {
@ -292,14 +292,14 @@ int mp_machine_i2c_transfer_adaptor(mp_obj_base_t *self, uint16_t addr, size_t n
} }
STATIC int mp_machine_i2c_readfrom(mp_obj_base_t *self, uint16_t addr, uint8_t *dest, size_t len, bool stop) { STATIC int mp_machine_i2c_readfrom(mp_obj_base_t *self, uint16_t addr, uint8_t *dest, size_t len, bool stop) {
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
mp_machine_i2c_buf_t buf = {.len = len, .buf = dest}; mp_machine_i2c_buf_t buf = {.len = len, .buf = dest};
unsigned int flags = MP_MACHINE_I2C_FLAG_READ | (stop ? MP_MACHINE_I2C_FLAG_STOP : 0); unsigned int flags = MP_MACHINE_I2C_FLAG_READ | (stop ? MP_MACHINE_I2C_FLAG_STOP : 0);
return i2c_p->transfer(self, addr, 1, &buf, flags); return i2c_p->transfer(self, addr, 1, &buf, flags);
} }
STATIC int mp_machine_i2c_writeto(mp_obj_base_t *self, uint16_t addr, const uint8_t *src, size_t len, bool stop) { STATIC int mp_machine_i2c_writeto(mp_obj_base_t *self, uint16_t addr, const uint8_t *src, size_t len, bool stop) {
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
mp_machine_i2c_buf_t buf = {.len = len, .buf = (uint8_t *)src}; mp_machine_i2c_buf_t buf = {.len = len, .buf = (uint8_t *)src};
unsigned int flags = stop ? MP_MACHINE_I2C_FLAG_STOP : 0; unsigned int flags = stop ? MP_MACHINE_I2C_FLAG_STOP : 0;
return i2c_p->transfer(self, addr, 1, &buf, flags); return i2c_p->transfer(self, addr, 1, &buf, flags);
@ -310,7 +310,7 @@ STATIC int mp_machine_i2c_writeto(mp_obj_base_t *self, uint16_t addr, const uint
STATIC mp_obj_t machine_i2c_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { STATIC mp_obj_t machine_i2c_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
if (i2c_p->init == NULL) { if (i2c_p->init == NULL) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
} }
@ -338,7 +338,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_scan_obj, machine_i2c_scan);
STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) { STATIC mp_obj_t machine_i2c_start(mp_obj_t self_in) {
mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in); mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
if (i2c_p->start == NULL) { if (i2c_p->start == NULL) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
} }
@ -352,7 +352,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_start_obj, machine_i2c_start);
STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) { STATIC mp_obj_t machine_i2c_stop(mp_obj_t self_in) {
mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in); mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
if (i2c_p->stop == NULL) { if (i2c_p->stop == NULL) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
} }
@ -366,7 +366,7 @@ MP_DEFINE_CONST_FUN_OBJ_1(machine_i2c_stop_obj, machine_i2c_stop);
STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) { STATIC mp_obj_t machine_i2c_readinto(size_t n_args, const mp_obj_t *args) {
mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
if (i2c_p->read == NULL) { if (i2c_p->read == NULL) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
} }
@ -390,7 +390,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readinto_obj, 2, 3, machine_i2c_
STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) { STATIC mp_obj_t machine_i2c_write(mp_obj_t self_in, mp_obj_t buf_in) {
mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in); mp_obj_base_t *self = (mp_obj_base_t *)MP_OBJ_TO_PTR(self_in);
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
if (i2c_p->write == NULL) { if (i2c_p->write == NULL) {
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("I2C operation not supported"));
} }
@ -486,7 +486,7 @@ STATIC mp_obj_t machine_i2c_writevto(size_t n_args, const mp_obj_t *args) {
} }
// Do the I2C transfer // Do the I2C transfer
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
int ret = i2c_p->transfer(self, addr, nbufs, bufs, stop ? MP_MACHINE_I2C_FLAG_STOP : 0); int ret = i2c_p->transfer(self, addr, nbufs, bufs, stop ? MP_MACHINE_I2C_FLAG_STOP : 0);
mp_local_free(bufs); mp_local_free(bufs);
@ -519,7 +519,7 @@ STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t a
#if MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1 #if MICROPY_PY_MACHINE_I2C_TRANSFER_WRITE1
// The I2C transfer function may support the MP_MACHINE_I2C_FLAG_WRITE1 option // The I2C transfer function may support the MP_MACHINE_I2C_FLAG_WRITE1 option
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
if (i2c_p->transfer_supports_write1) { if (i2c_p->transfer_supports_write1) {
// Create partial write and read buffers // Create partial write and read buffers
mp_machine_i2c_buf_t bufs[2] = { mp_machine_i2c_buf_t bufs[2] = {
@ -556,7 +556,7 @@ STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t
}; };
// Do I2C transfer // Do I2C transfer
mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)self->type->protocol; mp_machine_i2c_p_t *i2c_p = (mp_machine_i2c_p_t *)MP_OBJ_TYPE_GET_SLOT(self->type, protocol);
return i2c_p->transfer(self, addr, 2, bufs, MP_MACHINE_I2C_FLAG_STOP); return i2c_p->transfer(self, addr, 2, bufs, MP_MACHINE_I2C_FLAG_STOP);
} }

View File

@ -51,7 +51,7 @@ STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t
if (n_args > 0 && mp_obj_is_obj(args[0])) { if (n_args > 0 && mp_obj_is_obj(args[0])) {
mp_obj_base_t *pin_base = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); mp_obj_base_t *pin_base = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
pin_p = (mp_pin_p_t *)pin_base->type->protocol; pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT_OR_NULL(pin_base->type, protocol);
} }
if (pin_p == NULL) { if (pin_p == NULL) {

View File

@ -43,7 +43,7 @@
STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) { STATIC mp_obj_t machine_spi_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]); mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(args[0]);
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol; mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol);
spi_p->init(s, n_args - 1, args + 1, kw_args); spi_p->init(s, n_args - 1, args + 1, kw_args);
return mp_const_none; return mp_const_none;
} }
@ -51,7 +51,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(machine_spi_init_obj, 1, machine_spi_init);
STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) { STATIC mp_obj_t machine_spi_deinit(mp_obj_t self) {
mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(self); mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(self);
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol; mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol);
if (spi_p->deinit != NULL) { if (spi_p->deinit != NULL) {
spi_p->deinit(s); spi_p->deinit(s);
} }
@ -61,7 +61,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_spi_deinit_obj, machine_spi_deinit);
STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) { STATIC void mp_machine_spi_transfer(mp_obj_t self, size_t len, const void *src, void *dest) {
mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(self); mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(self);
mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)s->type->protocol; mp_machine_spi_p_t *spi_p = (mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol);
spi_p->transfer(s, len, src, dest); spi_p->transfer(s, len, src, dest);
} }

View File

@ -744,7 +744,7 @@ STATIC mp_obj_t wiznet5k_make_new(const mp_obj_type_t *type, size_t n_args, size
wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k; wiznet5k_obj.base.type = (mp_obj_type_t *)&mod_network_nic_type_wiznet5k;
wiznet5k_obj.cris_state = 0; wiznet5k_obj.cris_state = 0;
wiznet5k_obj.spi = spi; wiznet5k_obj.spi = spi;
wiznet5k_obj.spi_transfer = ((mp_machine_spi_p_t *)spi->type->protocol)->transfer; wiznet5k_obj.spi_transfer = ((mp_machine_spi_p_t *)MP_OBJ_TYPE_GET_SLOT(spi->type, protocol))->transfer;
wiznet5k_obj.cs = cs; wiznet5k_obj.cs = cs;
wiznet5k_obj.rst = rst; wiznet5k_obj.rst = rst;
#if WIZNET5K_WITH_LWIP_STACK #if WIZNET5K_WITH_LWIP_STACK

View File

@ -132,8 +132,9 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
} }
// If the mounted object has the VFS protocol, call its import_stat helper // If the mounted object has the VFS protocol, call its import_stat helper
const mp_vfs_proto_t *proto = mp_obj_get_type(vfs->obj)->protocol; const mp_obj_type_t *type = mp_obj_get_type(vfs->obj);
if (proto != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, protocol)) {
const mp_vfs_proto_t *proto = MP_OBJ_TYPE_GET_SLOT(type, protocol);
return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out); return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
} }

View File

@ -28,12 +28,12 @@
int mp_virtual_pin_read(mp_obj_t pin) { int mp_virtual_pin_read(mp_obj_t pin) {
mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin); mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin);
mp_pin_p_t *pin_p = (mp_pin_p_t *)s->type->protocol; mp_pin_p_t *pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol);
return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL); return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL);
} }
void mp_virtual_pin_write(mp_obj_t pin, int value) { void mp_virtual_pin_write(mp_obj_t pin, int value) {
mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin); mp_obj_base_t *s = (mp_obj_base_t *)MP_OBJ_TO_PTR(pin);
mp_pin_p_t *pin_p = (mp_pin_p_t *)s->type->protocol; mp_pin_p_t *pin_p = (mp_pin_p_t *)MP_OBJ_TYPE_GET_SLOT(s->type, protocol);
pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL); pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL);
} }

View File

@ -91,7 +91,7 @@ STATIC mp_obj_t scan_entry_get_scan_data(mp_obj_t self_in) {
mp_obj_t description = mp_const_none; mp_obj_t description = mp_const_none;
mp_map_t *constant_map = mp_obj_dict_get_map(ubluepy_constants_ad_types_type.locals_dict); mp_map_t *constant_map = mp_obj_dict_get_map(MP_OBJ_TYPE_GET_SLOT(&ubluepy_constants_ad_types_type, locals_dict));
mp_map_elem_t *ad_types_table = MP_OBJ_TO_PTR(constant_map->table); mp_map_elem_t *ad_types_table = MP_OBJ_TO_PTR(constant_map->table);
uint16_t num_of_elements = constant_map->used; uint16_t num_of_elements = constant_map->used;

View File

@ -128,7 +128,7 @@ int mp_bluetooth_hci_uart_set_baudrate(uint32_t baudrate) {
int mp_bluetooth_hci_uart_any(void) { int mp_bluetooth_hci_uart_any(void) {
int errcode = 0; int errcode = 0;
const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; const mp_stream_p_t *proto = (mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, protocol);
mp_uint_t ret = proto->ioctl(mp_bthci_uart, MP_STREAM_POLL, MP_STREAM_POLL_RD, &errcode); mp_uint_t ret = proto->ioctl(mp_bthci_uart, MP_STREAM_POLL, MP_STREAM_POLL_RD, &errcode);
if (errcode != 0) { if (errcode != 0) {
@ -142,7 +142,7 @@ int mp_bluetooth_hci_uart_write(const uint8_t *buf, size_t len) {
debug_printf("mp_bluetooth_hci_uart_write\n"); debug_printf("mp_bluetooth_hci_uart_write\n");
int errcode = 0; int errcode = 0;
const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; const mp_stream_p_t *proto = (mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, protocol);
mp_bluetooth_hci_controller_wakeup(); mp_bluetooth_hci_controller_wakeup();
@ -159,7 +159,7 @@ int mp_bluetooth_hci_uart_readchar(void) {
if (mp_bluetooth_hci_uart_any()) { if (mp_bluetooth_hci_uart_any()) {
int errcode = 0; int errcode = 0;
uint8_t buf = 0; uint8_t buf = 0;
const mp_stream_p_t *proto = (mp_stream_p_t *)machine_uart_type.protocol; const mp_stream_p_t *proto = (mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, protocol);
if (proto->read(mp_bthci_uart, (void *)&buf, 1, &errcode) < 0) { if (proto->read(mp_bthci_uart, (void *)&buf, 1, &errcode) < 0) {
error_printf("mp_bluetooth_hci_uart_readchar: failed to read UART %d\n", errcode); error_printf("mp_bluetooth_hci_uart_readchar: failed to read UART %d\n", errcode);
return -1; return -1;

View File

@ -506,10 +506,10 @@ STATIC mp_obj_t ffifunc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
} else if (mp_obj_is_str(a)) { } else if (mp_obj_is_str(a)) {
const char *s = mp_obj_str_get_str(a); const char *s = mp_obj_str_get_str(a);
values[i].ffi = (ffi_arg)(intptr_t)s; values[i].ffi = (ffi_arg)(intptr_t)s;
} else if (((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type->buffer != NULL) { } else if (MP_OBJ_TYPE_HAS_SLOT(((mp_obj_base_t *)MP_OBJ_TO_PTR(a))->type, buffer)) {
mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a); mp_obj_base_t *o = (mp_obj_base_t *)MP_OBJ_TO_PTR(a);
mp_buffer_info_t bufinfo; mp_buffer_info_t bufinfo;
int ret = o->type->buffer(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ? int ret = MP_OBJ_TYPE_GET_SLOT(o->type, buffer)(MP_OBJ_FROM_PTR(o), &bufinfo, MP_BUFFER_READ); // TODO: MP_BUFFER_READ?
if (ret != 0) { if (ret != 0) {
goto error; goto error;
} }

View File

@ -143,8 +143,8 @@ STATIC void mp_help_print_obj(const mp_obj_t obj) {
if (type == &mp_type_type) { if (type == &mp_type_type) {
type = MP_OBJ_TO_PTR(obj); type = MP_OBJ_TO_PTR(obj);
} }
if (type->locals_dict != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) {
map = &type->locals_dict->map; map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map;
} }
} }
if (map != NULL) { if (map != NULL) {

View File

@ -150,7 +150,7 @@ static inline mp_obj_t mp_obj_cast_to_native_base_dyn(mp_obj_t self_in, mp_const
if (MP_OBJ_FROM_PTR(self_type) == native_type) { if (MP_OBJ_FROM_PTR(self_type) == native_type) {
return self_in; return self_in;
} else if (self_type->parent != native_type) { } else if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(self_type, parent) != native_type) {
// The self_in object is not a direct descendant of native_type, so fail the cast. // The self_in object is not a direct descendant of native_type, so fail the cast.
// This is a very simple version of mp_obj_is_subclass_fast that could be improved. // This is a very simple version of mp_obj_is_subclass_fast that could be improved.
return MP_OBJ_NULL; return MP_OBJ_NULL;

View File

@ -455,7 +455,7 @@ STATIC mp_obj_t mp_builtin___repl_print__(mp_obj_t o) {
#if MICROPY_CAN_OVERRIDE_BUILTINS #if MICROPY_CAN_OVERRIDE_BUILTINS
// Set "_" special variable // Set "_" special variable
mp_obj_t dest[2] = {MP_OBJ_SENTINEL, o}; mp_obj_t dest[2] = {MP_OBJ_SENTINEL, o};
mp_type_module.attr(MP_OBJ_FROM_PTR(&mp_module_builtins), MP_QSTR__, dest); MP_OBJ_TYPE_GET_SLOT(&mp_type_module, attr)(MP_OBJ_FROM_PTR(&mp_module_builtins), MP_QSTR__, dest);
#endif #endif
} }
return mp_const_none; return mp_const_none;

View File

@ -116,8 +116,8 @@ void mp_obj_print_helper(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t
} }
#endif #endif
const mp_obj_type_t *type = mp_obj_get_type(o_in); const mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->print != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, print)) {
type->print((mp_print_t *)print, o_in, kind); MP_OBJ_TYPE_GET_SLOT(type, print)((mp_print_t *)print, o_in, kind);
} else { } else {
mp_printf(print, "<%q>", type->name); mp_printf(print, "<%q>", type->name);
} }
@ -170,8 +170,8 @@ bool mp_obj_is_true(mp_obj_t arg) {
} }
} else { } else {
const mp_obj_type_t *type = mp_obj_get_type(arg); const mp_obj_type_t *type = mp_obj_get_type(arg);
if (type->unary_op != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, unary_op)) {
mp_obj_t result = type->unary_op(MP_UNARY_OP_BOOL, arg); mp_obj_t result = MP_OBJ_TYPE_GET_SLOT(type, unary_op)(MP_UNARY_OP_BOOL, arg);
if (result != MP_OBJ_NULL) { if (result != MP_OBJ_NULL) {
return result == mp_const_true; return result == mp_const_true;
} }
@ -189,7 +189,7 @@ bool mp_obj_is_true(mp_obj_t arg) {
} }
bool mp_obj_is_callable(mp_obj_t o_in) { bool mp_obj_is_callable(mp_obj_t o_in) {
const mp_call_fun_t call = mp_obj_get_type(o_in)->call; const mp_call_fun_t call = MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o_in), call);
if (call != mp_obj_instance_call) { if (call != mp_obj_instance_call) {
return call != NULL; return call != NULL;
} }
@ -256,19 +256,19 @@ mp_obj_t mp_obj_equal_not_equal(mp_binary_op_t op, mp_obj_t o1, mp_obj_t o2) {
const mp_obj_type_t *type = mp_obj_get_type(o1); const mp_obj_type_t *type = mp_obj_get_type(o1);
// If a full equality test is not needed and the other object is a different // If a full equality test is not needed and the other object is a different
// type then we don't need to bother trying the comparison. // type then we don't need to bother trying the comparison.
if (type->binary_op != NULL && if (MP_OBJ_TYPE_HAS_SLOT(type, binary_op) &&
((type->flags & MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE) || mp_obj_get_type(o2) == type)) { ((type->flags & MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE) || mp_obj_get_type(o2) == type)) {
// CPython is asymmetric: it will try __eq__ if there's no __ne__ but not the // CPython is asymmetric: it will try __eq__ if there's no __ne__ but not the
// other way around. If the class doesn't need a full test we can skip __ne__. // other way around. If the class doesn't need a full test we can skip __ne__.
if (op == MP_BINARY_OP_NOT_EQUAL && (type->flags & MP_TYPE_FLAG_EQ_HAS_NEQ_TEST)) { if (op == MP_BINARY_OP_NOT_EQUAL && (type->flags & MP_TYPE_FLAG_EQ_HAS_NEQ_TEST)) {
mp_obj_t r = type->binary_op(MP_BINARY_OP_NOT_EQUAL, o1, o2); mp_obj_t r = MP_OBJ_TYPE_GET_SLOT(type, binary_op)(MP_BINARY_OP_NOT_EQUAL, o1, o2);
if (r != MP_OBJ_NULL) { if (r != MP_OBJ_NULL) {
return r; return r;
} }
} }
// Try calling __eq__. // Try calling __eq__.
mp_obj_t r = type->binary_op(MP_BINARY_OP_EQUAL, o1, o2); mp_obj_t r = MP_OBJ_TYPE_GET_SLOT(type, binary_op)(MP_BINARY_OP_EQUAL, o1, o2);
if (r != MP_OBJ_NULL) { if (r != MP_OBJ_NULL) {
if (op == MP_BINARY_OP_EQUAL) { if (op == MP_BINARY_OP_EQUAL) {
return r; return r;
@ -524,8 +524,8 @@ mp_obj_t mp_obj_len_maybe(mp_obj_t o_in) {
return MP_OBJ_NEW_SMALL_INT(l); return MP_OBJ_NEW_SMALL_INT(l);
} else { } else {
const mp_obj_type_t *type = mp_obj_get_type(o_in); const mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->unary_op != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, unary_op)) {
return type->unary_op(MP_UNARY_OP_LEN, o_in); return MP_OBJ_TYPE_GET_SLOT(type, unary_op)(MP_UNARY_OP_LEN, o_in);
} else { } else {
return MP_OBJ_NULL; return MP_OBJ_NULL;
} }
@ -534,8 +534,8 @@ 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 mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
const mp_obj_type_t *type = mp_obj_get_type(base); const mp_obj_type_t *type = mp_obj_get_type(base);
if (type->subscr != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, subscr)) {
mp_obj_t ret = type->subscr(base, index, value); mp_obj_t ret = MP_OBJ_TYPE_GET_SLOT(type, subscr)(base, index, value);
if (ret != MP_OBJ_NULL) { if (ret != MP_OBJ_NULL) {
return ret; return ret;
} }
@ -579,10 +579,10 @@ mp_obj_t mp_identity_getiter(mp_obj_t self, mp_obj_iter_buf_t *iter_buf) {
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) { bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
const mp_obj_type_t *type = mp_obj_get_type(obj); const mp_obj_type_t *type = mp_obj_get_type(obj);
if (type->buffer == NULL) { if (!MP_OBJ_TYPE_HAS_SLOT(type, buffer)) {
return false; return false;
} }
int ret = type->buffer(obj, bufinfo, flags); int ret = MP_OBJ_TYPE_GET_SLOT(type, buffer)(obj, bufinfo, flags);
if (ret != 0) { if (ret != 0) {
return false; return false;
} }

View File

@ -660,6 +660,16 @@ typedef mp_obj_type_t mp_obj_full_type_t;
#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11 } #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_11(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11 }
#define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11, .f12 = v12 } #define MP_DEFINE_CONST_OBJ_TYPE_NARGS_12(_struct_type, _typename, _name, _flags, _make_new, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8, f9, v9, f10, v10, f11, v11, f12, v12) const _struct_type _typename = { .base = { &mp_type_type }, .name = _name, .flags = _flags, .make_new = _make_new, .f1 = v1, .f2 = v2, .f3 = v3, .f4 = v4, .f5 = v5, .f6 = v6, .f7 = v7, .f8 = v8, .f9 = v9, .f10 = v10, .f11 = v11, .f12 = v12 }
// Always safe, checks if the type can and does have this slot.
#define MP_OBJ_TYPE_HAS_SLOT(t, f) ((t)->f)
// Requires you know that this type can have this slot.
#define MP_OBJ_TYPE_GET_SLOT(t, f) ((t)->f)
// Always safe, returns NULL if the type cannot have this slot.
#define MP_OBJ_TYPE_GET_SLOT_OR_NULL(t, f) ((t)->f)
#define MP_OBJ_TYPE_SET_SLOT(t, f, v, n) ((t)->f = v)
#define MP_OBJ_TYPE_OFFSETOF_SLOT(f) (offsetof(mp_obj_type_t, f))
#define MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(t, offset) (*(void **)((char *)(t) + (offset)) != NULL)
// Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked // Workaround for https://docs.microsoft.com/en-us/cpp/preprocessor/preprocessor-experimental-overview?view=msvc-160#macro-arguments-are-unpacked
#define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x #define MP_DEFINE_CONST_OBJ_TYPE_EXPAND(x) x
@ -822,7 +832,7 @@ void *mp_obj_malloc_helper(size_t num_bytes, const mp_obj_type_t *type);
#endif #endif
#define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_exact_type(o, &mp_type_int)) #define mp_obj_is_int(o) (mp_obj_is_small_int(o) || mp_obj_is_exact_type(o, &mp_type_int))
#define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_exact_type(o, &mp_type_str)) #define mp_obj_is_str(o) (mp_obj_is_qstr(o) || mp_obj_is_exact_type(o, &mp_type_str))
#define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->binary_op == mp_obj_str_binary_op)) #define mp_obj_is_str_or_bytes(o) (mp_obj_is_qstr(o) || (mp_obj_is_obj(o) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type, binary_op) == mp_obj_str_binary_op))
#define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == mp_obj_dict_make_new) #define mp_obj_is_dict_or_ordereddict(o) (mp_obj_is_obj(o) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->make_new == mp_obj_dict_make_new)
#define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function)) #define mp_obj_is_fun(o) (mp_obj_is_obj(o) && (((mp_obj_base_t *)MP_OBJ_TO_PTR(o))->type->name == MP_QSTR_function))

View File

@ -443,7 +443,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
size_t src_len; size_t src_len;
void *src_items; void *src_items;
size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL); size_t item_sz = mp_binary_get_size('@', o->typecode & TYPECODE_MASK, NULL);
if (mp_obj_is_obj(value) && ((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type->subscr == array_subscr) { if (mp_obj_is_obj(value) && MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_base_t *)MP_OBJ_TO_PTR(value))->type, subscr) == array_subscr) {
// value is array, bytearray or memoryview // value is array, bytearray or memoryview
mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value); mp_obj_array_t *src_slice = MP_OBJ_TO_PTR(value);
if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) { if (item_sz != mp_binary_get_size('@', src_slice->typecode & TYPECODE_MASK, NULL)) {

View File

@ -157,14 +157,14 @@ STATIC mp_obj_t mp_obj_new_namedtuple_type(qstr name, size_t n_fields, mp_obj_t
o->base.base.type = &mp_type_type; o->base.base.type = &mp_type_type;
o->base.flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple o->base.flags = MP_TYPE_FLAG_EQ_CHECKS_OTHER_TYPE; // can match tuple
o->base.name = name; o->base.name = name;
o->base.print = namedtuple_print;
o->base.make_new = namedtuple_make_new; o->base.make_new = namedtuple_make_new;
o->base.unary_op = mp_obj_tuple_unary_op; MP_OBJ_TYPE_SET_SLOT(&o->base, print, namedtuple_print, 0);
o->base.binary_op = mp_obj_tuple_binary_op; MP_OBJ_TYPE_SET_SLOT(&o->base, unary_op, mp_obj_tuple_unary_op, 1);
o->base.attr = namedtuple_attr; MP_OBJ_TYPE_SET_SLOT(&o->base, binary_op, mp_obj_tuple_binary_op, 2);
o->base.subscr = mp_obj_tuple_subscr; MP_OBJ_TYPE_SET_SLOT(&o->base, attr, namedtuple_attr, 3);
o->base.getiter = mp_obj_tuple_getiter; MP_OBJ_TYPE_SET_SLOT(&o->base, subscr, mp_obj_tuple_subscr, 4);
o->base.parent = &mp_type_tuple; MP_OBJ_TYPE_SET_SLOT(&o->base, getiter, mp_obj_tuple_getiter, 5);
MP_OBJ_TYPE_SET_SLOT(&o->base, parent, &mp_type_tuple, 6);
return MP_OBJ_FROM_PTR(o); return MP_OBJ_FROM_PTR(o);
} }

View File

@ -32,7 +32,7 @@
#include "py/runtime.h" #include "py/runtime.h"
// type check is done on getiter method to allow tuple, namedtuple, attrtuple // type check is done on getiter method to allow tuple, namedtuple, attrtuple
#define mp_obj_is_tuple_compatible(o) (mp_obj_get_type(o)->getiter == mp_obj_tuple_getiter) #define mp_obj_is_tuple_compatible(o) (MP_OBJ_TYPE_GET_SLOT_OR_NULL(mp_obj_get_type(o), getiter) == mp_obj_tuple_getiter)
/******************************************************************************/ /******************************************************************************/
/* tuple */ /* tuple */
@ -111,7 +111,7 @@ STATIC mp_obj_t tuple_cmp_helper(mp_uint_t op, mp_obj_t self_in, mp_obj_t anothe
mp_check_self(mp_obj_is_tuple_compatible(self_in)); mp_check_self(mp_obj_is_tuple_compatible(self_in));
const mp_obj_type_t *another_type = mp_obj_get_type(another_in); const mp_obj_type_t *another_type = mp_obj_get_type(another_in);
mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in); mp_obj_tuple_t *self = MP_OBJ_TO_PTR(self_in);
if (another_type->getiter != mp_obj_tuple_getiter) { if (MP_OBJ_TYPE_GET_SLOT_OR_NULL(another_type, getiter) != mp_obj_tuple_getiter) {
// Slow path for user subclasses // Slow path for user subclasses
another_in = mp_obj_cast_to_native_base(another_in, MP_OBJ_FROM_PTR(&mp_type_tuple)); another_in = mp_obj_cast_to_native_base(another_in, MP_OBJ_FROM_PTR(&mp_type_tuple));
if (another_in == MP_OBJ_NULL) { if (another_in == MP_OBJ_NULL) {

View File

@ -59,13 +59,13 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t
// Native types don't have parents (at least not from our perspective) so end. // Native types don't have parents (at least not from our perspective) so end.
*last_native_base = type; *last_native_base = type;
return count + 1; return count + 1;
} else if (type->parent == NULL) { } else if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) {
// No parents so end search here. // No parents so end search here.
return count; return count;
#if MICROPY_MULTIPLE_INHERITANCE #if MICROPY_MULTIPLE_INHERITANCE
} else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) { } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) {
// Multiple parents, search through them all recursively. // Multiple parents, search through them all recursively.
const mp_obj_tuple_t *parent_tuple = type->parent; const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent);
const mp_obj_t *item = parent_tuple->items; const mp_obj_t *item = parent_tuple->items;
const mp_obj_t *top = item + parent_tuple->len; const mp_obj_t *top = item + parent_tuple->len;
for (; item < top; ++item) { for (; item < top; ++item) {
@ -77,7 +77,7 @@ STATIC int instance_count_native_bases(const mp_obj_type_t *type, const mp_obj_t
#endif #endif
} else { } else {
// A single parent, use iteration to continue the search. // A single parent, use iteration to continue the search.
type = type->parent; type = MP_OBJ_TYPE_GET_SLOT(type, parent);
} }
} }
} }
@ -118,7 +118,7 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_
// will keep lookup->dest[0]'s value (should be MP_OBJ_NULL on invocation) if attribute // will keep lookup->dest[0]'s value (should be MP_OBJ_NULL on invocation) if attribute
// is not found // is not found
// will set lookup->dest[0] to MP_OBJ_SENTINEL if special method was found in a native // will set lookup->dest[0] to MP_OBJ_SENTINEL if special method was found in a native
// type base via slot id (as specified by lookup->meth_offset). As there can be only one // type base via slot id (as specified by lookup->slot_offset). As there can be only one
// native base, it's known that it applies to instance->subobj[0]. In most cases, we also // native base, it's known that it applies to instance->subobj[0]. In most cases, we also
// don't need to know which type it was - because instance->subobj[0] is of that type. // don't need to know which type it was - because instance->subobj[0] is of that type.
// The only exception is when object is not yet constructed, then we need to know base // The only exception is when object is not yet constructed, then we need to know base
@ -127,7 +127,7 @@ mp_obj_instance_t *mp_obj_new_instance(const mp_obj_type_t *class, const mp_obj_
struct class_lookup_data { struct class_lookup_data {
mp_obj_instance_t *obj; mp_obj_instance_t *obj;
qstr attr; qstr attr;
size_t meth_offset; size_t slot_offset;
mp_obj_t *dest; mp_obj_t *dest;
bool is_type; bool is_type;
}; };
@ -141,19 +141,19 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
// This avoids extra method_name => slot lookup. On the other hand, // This avoids extra method_name => slot lookup. On the other hand,
// this should not be applied to class types, as will result in extra // this should not be applied to class types, as will result in extra
// lookup either. // lookup either.
if (lookup->meth_offset != 0 && mp_obj_is_native_type(type)) { if (lookup->slot_offset != 0 && mp_obj_is_native_type(type)) {
if (*(void **)((char *)type + lookup->meth_offset) != NULL) { if (MP_OBJ_TYPE_HAS_SLOT_BY_OFFSET(type, lookup->slot_offset)) {
DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n", DEBUG_printf("mp_obj_class_lookup: Matched special meth slot (off=%d) for %s\n",
lookup->meth_offset, qstr_str(lookup->attr)); lookup->slot_offset, qstr_str(lookup->attr));
lookup->dest[0] = MP_OBJ_SENTINEL; lookup->dest[0] = MP_OBJ_SENTINEL;
return; return;
} }
} }
if (type->locals_dict != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) {
// search locals_dict (the set of methods/attributes) // search locals_dict (the set of methods/attributes)
assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(type->locals_dict))); // MicroPython restriction, for now assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(type, locals_dict)))); // MicroPython restriction, for now
mp_map_t *locals_map = &type->locals_dict->map; mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map;
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(lookup->attr), MP_MAP_LOOKUP); mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(lookup->attr), MP_MAP_LOOKUP);
if (elem != NULL) { if (elem != NULL) {
if (lookup->is_type) { if (lookup->is_type) {
@ -197,12 +197,12 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
// attribute not found, keep searching base classes // attribute not found, keep searching base classes
if (type->parent == NULL) { if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) {
DEBUG_printf("mp_obj_class_lookup: No more parents\n"); DEBUG_printf("mp_obj_class_lookup: No more parents\n");
return; return;
#if MICROPY_MULTIPLE_INHERITANCE #if MICROPY_MULTIPLE_INHERITANCE
} else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) { } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) {
const mp_obj_tuple_t *parent_tuple = type->parent; const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent);
const mp_obj_t *item = parent_tuple->items; const mp_obj_t *item = parent_tuple->items;
const mp_obj_t *top = item + parent_tuple->len - 1; const mp_obj_t *top = item + parent_tuple->len - 1;
for (; item < top; ++item) { for (; item < top; ++item) {
@ -223,7 +223,7 @@ STATIC void mp_obj_class_lookup(struct class_lookup_data *lookup, const mp_obj_t
type = (mp_obj_type_t *)MP_OBJ_TO_PTR(*item); type = (mp_obj_type_t *)MP_OBJ_TO_PTR(*item);
#endif #endif
} else { } else {
type = type->parent; type = MP_OBJ_TYPE_GET_SLOT(type, parent);
} }
if (type == &mp_type_object) { if (type == &mp_type_object) {
// Not a "real" type // Not a "real" type
@ -239,7 +239,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.attr = meth, .attr = meth,
.meth_offset = offsetof(mp_obj_type_t, print), .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(print),
.dest = member, .dest = member,
.is_type = false, .is_type = false,
}; };
@ -247,7 +247,7 @@ STATIC void instance_print(const mp_print_t *print, mp_obj_t self_in, mp_print_k
if (member[0] == MP_OBJ_NULL && kind == PRINT_STR) { if (member[0] == MP_OBJ_NULL && kind == PRINT_STR) {
// If there's no __str__, fall back to __repr__ // If there's no __str__, fall back to __repr__
lookup.attr = MP_QSTR___repr__; lookup.attr = MP_QSTR___repr__;
lookup.meth_offset = 0; lookup.slot_offset = 0;
mp_obj_class_lookup(&lookup, self->base.type); mp_obj_class_lookup(&lookup, self->base.type);
} }
@ -282,7 +282,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = NULL, .obj = NULL,
.attr = MP_QSTR___new__, .attr = MP_QSTR___new__,
.meth_offset = offsetof(mp_obj_type_t, make_new), .slot_offset = offsetof(mp_obj_type_t, make_new),
.dest = init_fn, .dest = init_fn,
.is_type = false, .is_type = false,
}; };
@ -332,7 +332,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size
init_fn[0] = init_fn[1] = MP_OBJ_NULL; init_fn[0] = init_fn[1] = MP_OBJ_NULL;
lookup.obj = o; lookup.obj = o;
lookup.attr = MP_QSTR___init__; lookup.attr = MP_QSTR___init__;
lookup.meth_offset = 0; lookup.slot_offset = 0;
mp_obj_class_lookup(&lookup, self); mp_obj_class_lookup(&lookup, self);
if (init_fn[0] != MP_OBJ_NULL) { if (init_fn[0] != MP_OBJ_NULL) {
mp_obj_t init_ret; mp_obj_t init_ret;
@ -414,7 +414,7 @@ STATIC mp_obj_t instance_unary_op(mp_unary_op_t op, mp_obj_t self_in) {
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.attr = op_name, .attr = op_name,
.meth_offset = offsetof(mp_obj_type_t, unary_op), .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(unary_op),
.dest = member, .dest = member,
.is_type = false, .is_type = false,
}; };
@ -542,7 +542,7 @@ retry:;
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = lhs, .obj = lhs,
.attr = op_name, .attr = op_name,
.meth_offset = offsetof(mp_obj_type_t, binary_op), .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(binary_op),
.dest = dest, .dest = dest,
.is_type = false, .is_type = false,
}; };
@ -608,7 +608,7 @@ STATIC void mp_obj_instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *des
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.attr = attr, .attr = attr,
.meth_offset = 0, .slot_offset = 0,
.dest = dest, .dest = dest,
.is_type = false, .is_type = false,
}; };
@ -693,7 +693,7 @@ STATIC bool mp_obj_instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t val
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.attr = attr, .attr = attr,
.meth_offset = 0, .slot_offset = 0,
.dest = member, .dest = member,
.is_type = false, .is_type = false,
}; };
@ -815,7 +815,7 @@ STATIC mp_obj_t instance_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value
mp_obj_t member[4] = {MP_OBJ_NULL, MP_OBJ_NULL, index, value}; mp_obj_t member[4] = {MP_OBJ_NULL, MP_OBJ_NULL, index, value};
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.meth_offset = offsetof(mp_obj_type_t, subscr), .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(subscr),
.dest = member, .dest = member,
.is_type = false, .is_type = false,
}; };
@ -850,7 +850,7 @@ STATIC mp_obj_t mp_obj_instance_get_call(mp_obj_t self_in, mp_obj_t *member) {
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.attr = MP_QSTR___call__, .attr = MP_QSTR___call__,
.meth_offset = offsetof(mp_obj_type_t, call), .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(call),
.dest = member, .dest = member,
.is_type = false, .is_type = false,
}; };
@ -889,7 +889,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf)
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.attr = MP_QSTR___iter__, .attr = MP_QSTR___iter__,
.meth_offset = offsetof(mp_obj_type_t, getiter), .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(getiter),
.dest = member, .dest = member,
.is_type = false, .is_type = false,
}; };
@ -901,7 +901,7 @@ mp_obj_t mp_obj_instance_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf)
if (iter_buf == NULL) { if (iter_buf == NULL) {
iter_buf = m_new_obj(mp_obj_iter_buf_t); iter_buf = m_new_obj(mp_obj_iter_buf_t);
} }
return type->getiter(self->subobj[0], iter_buf); return MP_OBJ_TYPE_GET_SLOT(type, getiter)(self->subobj[0], iter_buf);
} else { } else {
return mp_call_method_n_kw(0, 0, member); return mp_call_method_n_kw(0, 0, member);
} }
@ -913,14 +913,14 @@ STATIC mp_int_t instance_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo,
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = self, .obj = self,
.attr = MP_QSTR_, // don't actually look for a method .attr = MP_QSTR_, // don't actually look for a method
.meth_offset = offsetof(mp_obj_type_t, buffer), .slot_offset = MP_OBJ_TYPE_OFFSETOF_SLOT(buffer),
.dest = member, .dest = member,
.is_type = false, .is_type = false,
}; };
mp_obj_class_lookup(&lookup, self->base.type); mp_obj_class_lookup(&lookup, self->base.type);
if (member[0] == MP_OBJ_SENTINEL) { if (member[0] == MP_OBJ_SENTINEL) {
const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]); const mp_obj_type_t *type = mp_obj_get_type(self->subobj[0]);
return type->buffer(self->subobj[0], bufinfo, flags); return MP_OBJ_TYPE_GET_SLOT(type, buffer)(self->subobj[0], bufinfo, flags);
} else { } else {
return 1; // object does not support buffer protocol return 1; // object does not support buffer protocol
} }
@ -1021,7 +1021,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
if (attr == MP_QSTR___dict__) { if (attr == MP_QSTR___dict__) {
// Returns a read-only dict of the class attributes. // Returns a read-only dict of the class attributes.
// If the internal locals is not fixed, a copy will be created. // If the internal locals is not fixed, a copy will be created.
const mp_obj_dict_t *dict = self->locals_dict; const mp_obj_dict_t *dict = MP_OBJ_TYPE_GET_SLOT_OR_NULL(self, locals_dict);
if (!dict) { if (!dict) {
dict = &mp_const_empty_dict_obj; dict = &mp_const_empty_dict_obj;
} }
@ -1040,7 +1040,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
dest[0] = mp_const_empty_tuple; dest[0] = mp_const_empty_tuple;
return; return;
} }
mp_obj_t parent_obj = self->parent ? MP_OBJ_FROM_PTR(self->parent) : MP_OBJ_FROM_PTR(&mp_type_object); mp_obj_t parent_obj = MP_OBJ_TYPE_HAS_SLOT(self, parent) ? MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, parent)) : MP_OBJ_FROM_PTR(&mp_type_object);
#if MICROPY_MULTIPLE_INHERITANCE #if MICROPY_MULTIPLE_INHERITANCE
if (mp_obj_is_type(parent_obj, &mp_type_tuple)) { if (mp_obj_is_type(parent_obj, &mp_type_tuple)) {
dest[0] = parent_obj; dest[0] = parent_obj;
@ -1054,7 +1054,7 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = (mp_obj_instance_t *)self, .obj = (mp_obj_instance_t *)self,
.attr = attr, .attr = attr,
.meth_offset = 0, .slot_offset = 0,
.dest = dest, .dest = dest,
.is_type = true, .is_type = true,
}; };
@ -1062,9 +1062,9 @@ STATIC void type_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
} else { } else {
// delete/store attribute // delete/store attribute
if (self->locals_dict != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(self, locals_dict)) {
assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(self->locals_dict))); // MicroPython restriction, for now assert(mp_obj_is_dict_or_ordereddict(MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, locals_dict)))); // MicroPython restriction, for now
mp_map_t *locals_map = &self->locals_dict->map; mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(self, locals_dict)->map;
if (locals_map->is_fixed) { if (locals_map->is_fixed) {
// can't apply delete/store to a fixed map // can't apply delete/store to a fixed map
return; return;
@ -1155,43 +1155,44 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
o->base.type = &mp_type_type; o->base.type = &mp_type_type;
o->flags = base_flags; o->flags = base_flags;
o->name = name; o->name = name;
o->print = instance_print;
o->make_new = mp_obj_instance_make_new; o->make_new = mp_obj_instance_make_new;
o->call = mp_obj_instance_call; MP_OBJ_TYPE_SET_SLOT(o, print, instance_print, 0);
o->unary_op = instance_unary_op; MP_OBJ_TYPE_SET_SLOT(o, call, mp_obj_instance_call, 1);
o->binary_op = instance_binary_op; MP_OBJ_TYPE_SET_SLOT(o, unary_op, instance_unary_op, 2);
o->attr = mp_obj_instance_attr; MP_OBJ_TYPE_SET_SLOT(o, binary_op, instance_binary_op, 3);
o->subscr = instance_subscr; MP_OBJ_TYPE_SET_SLOT(o, attr, mp_obj_instance_attr, 4);
o->getiter = mp_obj_instance_getiter; MP_OBJ_TYPE_SET_SLOT(o, subscr, instance_subscr, 5);
// o->iternext = ; not implemented MP_OBJ_TYPE_SET_SLOT(o, getiter, mp_obj_instance_getiter, 6);
o->buffer = instance_get_buffer; // MP_OBJ_TYPE_SET_SLOT(o, iternext, not implemented)
MP_OBJ_TYPE_SET_SLOT(o, buffer, instance_get_buffer, 7);
if (bases_len > 0) { if (bases_len > 0) {
// Inherit protocol from a base class. This allows to define an // Inherit protocol from a base class. This allows to define an
// abstract base class which would translate C-level protocol to // abstract base class which would translate C-level protocol to
// Python method calls, and any subclass inheriting from it will // Python method calls, and any subclass inheriting from it will
// support this feature. // support this feature.
o->protocol = ((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0]))->protocol; MP_OBJ_TYPE_SET_SLOT(o, protocol, MP_OBJ_TYPE_GET_SLOT_OR_NULL(((mp_obj_type_t *)MP_OBJ_TO_PTR(bases_items[0])), protocol), 8);
if (bases_len >= 2) { if (bases_len >= 2) {
#if MICROPY_MULTIPLE_INHERITANCE #if MICROPY_MULTIPLE_INHERITANCE
o->parent = MP_OBJ_TO_PTR(bases_tuple); MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_tuple), 9);
#else #else
mp_raise_NotImplementedError(MP_ERROR_TEXT("multiple inheritance not supported")); mp_raise_NotImplementedError(MP_ERROR_TEXT("multiple inheritance not supported"));
#endif #endif
} else { } else {
o->parent = MP_OBJ_TO_PTR(bases_items[0]); MP_OBJ_TYPE_SET_SLOT(o, parent, MP_OBJ_TO_PTR(bases_items[0]), 9);
} }
} }
o->locals_dict = MP_OBJ_TO_PTR(locals_dict); mp_obj_dict_t *locals_ptr = MP_OBJ_TO_PTR(locals_dict);
MP_OBJ_TYPE_SET_SLOT(o, locals_dict, locals_ptr, 10);
#if ENABLE_SPECIAL_ACCESSORS #if ENABLE_SPECIAL_ACCESSORS
// Check if the class has any special accessor methods // Check if the class has any special accessor methods
if (!(o->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) { if (!(o->flags & MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS)) {
for (size_t i = 0; i < o->locals_dict->map.alloc; i++) { for (size_t i = 0; i < locals_ptr->map.alloc; i++) {
if (mp_map_slot_is_filled(&o->locals_dict->map, i)) { if (mp_map_slot_is_filled(&locals_ptr->map, i)) {
const mp_map_elem_t *elem = &o->locals_dict->map.table[i]; const mp_map_elem_t *elem = &locals_ptr->map.table[i];
if (check_for_special_accessors(elem->key, elem->value)) { if (check_for_special_accessors(elem->key, elem->value)) {
o->flags |= MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS; o->flags |= MP_TYPE_FLAG_HAS_SPECIAL_ACCESSORS;
break; break;
@ -1207,7 +1208,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
mp_raise_TypeError(MP_ERROR_TEXT("multiple bases have instance lay-out conflict")); mp_raise_TypeError(MP_ERROR_TEXT("multiple bases have instance lay-out conflict"));
} }
mp_map_t *locals_map = &o->locals_dict->map; mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(o, locals_dict)->map;
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP);
if (elem != NULL) { if (elem != NULL) {
// __new__ slot exists; check if it is a function // __new__ slot exists; check if it is a function
@ -1268,21 +1269,21 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
struct class_lookup_data lookup = { struct class_lookup_data lookup = {
.obj = MP_OBJ_TO_PTR(self->obj), .obj = MP_OBJ_TO_PTR(self->obj),
.attr = attr, .attr = attr,
.meth_offset = 0, .slot_offset = 0,
.dest = dest, .dest = dest,
.is_type = false, .is_type = false,
}; };
// Allow a call super().__init__() to reach any native base classes // Allow a call super().__init__() to reach any native base classes.
if (attr == MP_QSTR___init__) { if (attr == MP_QSTR___init__) {
lookup.meth_offset = offsetof(mp_obj_type_t, make_new); lookup.slot_offset = offsetof(mp_obj_type_t, make_new);
} }
if (type->parent == NULL) { if (!MP_OBJ_TYPE_HAS_SLOT(type, parent)) {
// no parents, do nothing // no parents, do nothing
#if MICROPY_MULTIPLE_INHERITANCE #if MICROPY_MULTIPLE_INHERITANCE
} else if (((mp_obj_base_t *)type->parent)->type == &mp_type_tuple) { } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(type, parent))->type == &mp_type_tuple) {
const mp_obj_tuple_t *parent_tuple = type->parent; const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(type, parent);
size_t len = parent_tuple->len; size_t len = parent_tuple->len;
const mp_obj_t *items = parent_tuple->items; const mp_obj_t *items = parent_tuple->items;
for (size_t i = 0; i < len; i++) { for (size_t i = 0; i < len; i++) {
@ -1292,14 +1293,15 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
// and we don't want to lookup native methods in object. // and we don't want to lookup native methods in object.
continue; continue;
} }
mp_obj_class_lookup(&lookup, (mp_obj_type_t *)MP_OBJ_TO_PTR(items[i])); mp_obj_class_lookup(&lookup, (mp_obj_type_t *)MP_OBJ_TO_PTR(items[i]));
if (dest[0] != MP_OBJ_NULL) { if (dest[0] != MP_OBJ_NULL) {
break; break;
} }
} }
#endif #endif
} else if (type->parent != &mp_type_object) { } else if (MP_OBJ_TYPE_GET_SLOT(type, parent) != &mp_type_object) {
mp_obj_class_lookup(&lookup, type->parent); mp_obj_class_lookup(&lookup, MP_OBJ_TYPE_GET_SLOT(type, parent));
} }
if (dest[0] != MP_OBJ_NULL) { if (dest[0] != MP_OBJ_NULL) {
@ -1311,9 +1313,9 @@ STATIC void super_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
return; return;
} }
// Reset meth_offset so we don't look up any native methods in object, // Reset slot_offset so we don't look up any native methods in object,
// because object never takes up the native base-class slot. // because object never takes up the native base-class slot.
lookup.meth_offset = 0; lookup.slot_offset = 0;
mp_obj_class_lookup(&lookup, &mp_type_object); mp_obj_class_lookup(&lookup, &mp_type_object);
} }
@ -1352,13 +1354,13 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) {
const mp_obj_type_t *self = MP_OBJ_TO_PTR(object); const mp_obj_type_t *self = MP_OBJ_TO_PTR(object);
if (self->parent == NULL) { if (!MP_OBJ_TYPE_HAS_SLOT(self, parent)) {
// type has no parents // type has no parents
return false; return false;
#if MICROPY_MULTIPLE_INHERITANCE #if MICROPY_MULTIPLE_INHERITANCE
} else if (((mp_obj_base_t *)self->parent)->type == &mp_type_tuple) { } else if (((mp_obj_base_t *)MP_OBJ_TYPE_GET_SLOT(self, parent))->type == &mp_type_tuple) {
// get the base objects (they should be type objects) // get the base objects (they should be type objects)
const mp_obj_tuple_t *parent_tuple = self->parent; const mp_obj_tuple_t *parent_tuple = MP_OBJ_TYPE_GET_SLOT(self, parent);
const mp_obj_t *item = parent_tuple->items; const mp_obj_t *item = parent_tuple->items;
const mp_obj_t *top = item + parent_tuple->len - 1; const mp_obj_t *top = item + parent_tuple->len - 1;
@ -1374,7 +1376,7 @@ bool mp_obj_is_subclass_fast(mp_const_obj_t object, mp_const_obj_t classinfo) {
#endif #endif
} else { } else {
// type has 1 parent // type has 1 parent
object = MP_OBJ_FROM_PTR(self->parent); object = MP_OBJ_FROM_PTR(MP_OBJ_TYPE_GET_SLOT(self, parent));
} }
} }
} }

View File

@ -29,24 +29,28 @@
STATIC mp_obj_t op_getitem(mp_obj_t self_in, mp_obj_t key_in) { STATIC mp_obj_t op_getitem(mp_obj_t self_in, mp_obj_t key_in) {
const mp_obj_type_t *type = mp_obj_get_type(self_in); const mp_obj_type_t *type = mp_obj_get_type(self_in);
return type->subscr(self_in, key_in, MP_OBJ_SENTINEL); // Note: assumes type must have subscr (only used by dict).
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_SENTINEL);
} }
MP_DEFINE_CONST_FUN_OBJ_2(mp_op_getitem_obj, op_getitem); 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) { STATIC mp_obj_t op_setitem(mp_obj_t self_in, mp_obj_t key_in, mp_obj_t value_in) {
const mp_obj_type_t *type = mp_obj_get_type(self_in); const mp_obj_type_t *type = mp_obj_get_type(self_in);
return type->subscr(self_in, key_in, value_in); // Note: assumes type must have subscr (only used by dict).
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, value_in);
} }
MP_DEFINE_CONST_FUN_OBJ_3(mp_op_setitem_obj, op_setitem); 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) { STATIC mp_obj_t op_delitem(mp_obj_t self_in, mp_obj_t key_in) {
const mp_obj_type_t *type = mp_obj_get_type(self_in); const mp_obj_type_t *type = mp_obj_get_type(self_in);
return type->subscr(self_in, key_in, MP_OBJ_NULL); // Note: assumes type must have subscr (only used by dict).
return MP_OBJ_TYPE_GET_SLOT(type, subscr)(self_in, key_in, MP_OBJ_NULL);
} }
MP_DEFINE_CONST_FUN_OBJ_2(mp_op_delitem_obj, op_delitem); MP_DEFINE_CONST_FUN_OBJ_2(mp_op_delitem_obj, op_delitem);
STATIC mp_obj_t op_contains(mp_obj_t lhs_in, mp_obj_t rhs_in) { STATIC mp_obj_t op_contains(mp_obj_t lhs_in, mp_obj_t rhs_in) {
const mp_obj_type_t *type = mp_obj_get_type(lhs_in); const mp_obj_type_t *type = mp_obj_get_type(lhs_in);
return type->binary_op(MP_BINARY_OP_CONTAINS, lhs_in, rhs_in); // Note: assumes type must have binary_op (only used by set/frozenset).
return MP_OBJ_TYPE_GET_SLOT(type, binary_op)(MP_BINARY_OP_CONTAINS, lhs_in, rhs_in);
} }
MP_DEFINE_CONST_FUN_OBJ_2(mp_op_contains_obj, op_contains); MP_DEFINE_CONST_FUN_OBJ_2(mp_op_contains_obj, op_contains);

View File

@ -307,8 +307,8 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
return MP_OBJ_NEW_SMALL_INT(h); return MP_OBJ_NEW_SMALL_INT(h);
} else { } else {
const mp_obj_type_t *type = mp_obj_get_type(arg); const mp_obj_type_t *type = mp_obj_get_type(arg);
if (type->unary_op != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, unary_op)) {
mp_obj_t result = type->unary_op(op, arg); mp_obj_t result = MP_OBJ_TYPE_GET_SLOT(type, unary_op)(op, arg);
if (result != MP_OBJ_NULL) { if (result != MP_OBJ_NULL) {
return result; return result;
} }
@ -613,8 +613,8 @@ mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs
const mp_obj_type_t *type; const mp_obj_type_t *type;
generic_binary_op: generic_binary_op:
type = mp_obj_get_type(lhs); type = mp_obj_get_type(lhs);
if (type->binary_op != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, binary_op)) {
mp_obj_t result = type->binary_op(op, lhs, rhs); mp_obj_t result = MP_OBJ_TYPE_GET_SLOT(type, binary_op)(op, lhs, rhs);
if (result != MP_OBJ_NULL) { if (result != MP_OBJ_NULL) {
return result; return result;
} }
@ -689,8 +689,8 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons
const mp_obj_type_t *type = mp_obj_get_type(fun_in); const mp_obj_type_t *type = mp_obj_get_type(fun_in);
// do the call // do the call
if (type->call != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, call)) {
return type->call(fun_in, n_args, n_kw, args); return MP_OBJ_TYPE_GET_SLOT(type, call)(fun_in, n_args, n_kw, args);
} }
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
@ -1167,14 +1167,14 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) {
} }
#endif #endif
if (attr == MP_QSTR___next__ && type->iternext != NULL) { if (attr == MP_QSTR___next__ && MP_OBJ_TYPE_HAS_SLOT(type, iternext)) {
dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj); dest[0] = MP_OBJ_FROM_PTR(&mp_builtin_next_obj);
dest[1] = obj; dest[1] = obj;
return; return;
} }
if (type->attr != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, attr)) {
// this type can do its own load, so call it // this type can do its own load, so call it
type->attr(obj, attr, dest); MP_OBJ_TYPE_GET_SLOT(type, attr)(obj, attr, dest);
// If type->attr has set dest[1] = MP_OBJ_SENTINEL, we should proceed // If type->attr has set dest[1] = MP_OBJ_SENTINEL, we should proceed
// with lookups below (i.e. in locals_dict). If not, return right away. // with lookups below (i.e. in locals_dict). If not, return right away.
if (dest[1] != MP_OBJ_SENTINEL) { if (dest[1] != MP_OBJ_SENTINEL) {
@ -1183,11 +1183,11 @@ void mp_load_method_maybe(mp_obj_t obj, qstr attr, mp_obj_t *dest) {
// Clear the fail flag set by type->attr so it's like it never ran. // Clear the fail flag set by type->attr so it's like it never ran.
dest[1] = MP_OBJ_NULL; dest[1] = MP_OBJ_NULL;
} }
if (type->locals_dict != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, locals_dict)) {
// generic method lookup // generic method lookup
// this is a lookup in the object (ie not class or type) // this is a lookup in the object (ie not class or type)
assert(type->locals_dict->base.type == &mp_type_dict); // MicroPython restriction, for now assert(MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->base.type == &mp_type_dict); // MicroPython restriction, for now
mp_map_t *locals_map = &type->locals_dict->map; mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(type, locals_dict)->map;
mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP); mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(attr), MP_MAP_LOOKUP);
if (elem != NULL) { if (elem != NULL) {
mp_convert_member_lookup(obj, type, elem->value, dest); mp_convert_member_lookup(obj, type, elem->value, dest);
@ -1239,9 +1239,9 @@ void mp_load_method_protected(mp_obj_t obj, qstr attr, mp_obj_t *dest, bool catc
void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
DEBUG_OP_printf("store attr %p.%s <- %p\n", base, qstr_str(attr), value); DEBUG_OP_printf("store attr %p.%s <- %p\n", base, qstr_str(attr), value);
const mp_obj_type_t *type = mp_obj_get_type(base); const mp_obj_type_t *type = mp_obj_get_type(base);
if (type->attr != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, attr)) {
mp_obj_t dest[2] = {MP_OBJ_SENTINEL, value}; mp_obj_t dest[2] = {MP_OBJ_SENTINEL, value};
type->attr(base, attr, dest); MP_OBJ_TYPE_GET_SLOT(type, attr)(base, attr, dest);
if (dest[0] == MP_OBJ_NULL) { if (dest[0] == MP_OBJ_NULL) {
// success // success
return; return;
@ -1260,20 +1260,21 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
assert(o_in); assert(o_in);
const mp_obj_type_t *type = mp_obj_get_type(o_in); const mp_obj_type_t *type = mp_obj_get_type(o_in);
if (MP_OBJ_TYPE_HAS_SLOT(type, getiter)) {
// Check for native getiter which is the identity. We handle this case explicitly // Check for native getiter which is the identity. We handle this case explicitly
// so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used. // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used.
if (type->getiter == mp_identity_getiter) { if (MP_OBJ_TYPE_GET_SLOT(type, getiter) == mp_identity_getiter) {
return o_in; return o_in;
} }
// check for native getiter (corresponds to __iter__) // check for native getiter (corresponds to __iter__)
if (type->getiter != NULL) { if (iter_buf == NULL && MP_OBJ_TYPE_GET_SLOT(type, getiter) != mp_obj_instance_getiter) {
if (iter_buf == NULL && type->getiter != mp_obj_instance_getiter) {
// if caller did not provide a buffer then allocate one on the heap // if caller did not provide a buffer then allocate one on the heap
// mp_obj_instance_getiter is special, it will allocate only if needed // mp_obj_instance_getiter is special, it will allocate only if needed
iter_buf = m_new_obj(mp_obj_iter_buf_t); iter_buf = m_new_obj(mp_obj_iter_buf_t);
} }
mp_obj_t iter = type->getiter(o_in, iter_buf); mp_obj_t iter = MP_OBJ_TYPE_GET_SLOT(type, getiter)(o_in, iter_buf);
if (iter != MP_OBJ_NULL) { if (iter != MP_OBJ_NULL) {
return iter; return iter;
} }
@ -1305,9 +1306,9 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
// may also raise StopIteration() // may also raise StopIteration()
mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
const mp_obj_type_t *type = mp_obj_get_type(o_in); const mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->iternext != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) {
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
return type->iternext(o_in); return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in);
} else { } else {
// check for __next__ method // check for __next__ method
mp_obj_t dest[2]; mp_obj_t dest[2];
@ -1331,9 +1332,9 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
mp_obj_t mp_iternext(mp_obj_t o_in) { mp_obj_t mp_iternext(mp_obj_t o_in) {
MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext
const mp_obj_type_t *type = mp_obj_get_type(o_in); const mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->iternext != NULL) { if (MP_OBJ_TYPE_HAS_SLOT(type, iternext)) {
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
return type->iternext(o_in); return MP_OBJ_TYPE_GET_SLOT(type, iternext)(o_in);
} else { } else {
// check for __next__ method // check for __next__ method
mp_obj_t dest[2]; mp_obj_t dest[2];
@ -1371,9 +1372,9 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val); return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val);
} }
if (type->iternext != NULL && send_value == mp_const_none) { if (MP_OBJ_TYPE_HAS_SLOT(type, iternext) && send_value == mp_const_none) {
MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL; MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
mp_obj_t ret = type->iternext(self_in); mp_obj_t ret = MP_OBJ_TYPE_GET_SLOT(type, iternext)(self_in);
*ret_val = ret; *ret_val = ret;
if (ret != MP_OBJ_STOP_ITERATION) { if (ret != MP_OBJ_STOP_ITERATION) {
return MP_VM_RETURN_YIELD; return MP_VM_RETURN_YIELD;

View File

@ -84,16 +84,17 @@ mp_uint_t mp_stream_rw(mp_obj_t stream, void *buf_, mp_uint_t size, int *errcode
const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) { const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags) {
const mp_obj_type_t *type = mp_obj_get_type(self_in); const mp_obj_type_t *type = mp_obj_get_type(self_in);
const mp_stream_p_t *stream_p = type->protocol; if (MP_OBJ_TYPE_HAS_SLOT(type, protocol)) {
if (stream_p == NULL const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(type, protocol);
|| ((flags & MP_STREAM_OP_READ) && stream_p->read == NULL) if (!((flags & MP_STREAM_OP_READ) && stream_p->read == NULL)
|| ((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL) && !((flags & MP_STREAM_OP_WRITE) && stream_p->write == NULL)
|| ((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) { && !((flags & MP_STREAM_OP_IOCTL) && stream_p->ioctl == NULL)) {
return stream_p;
}
}
// CPython: io.UnsupportedOperation, OSError subclass // CPython: io.UnsupportedOperation, OSError subclass
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("stream operation not supported")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("stream operation not supported"));
} }
return stream_p;
}
STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte flags) { STATIC mp_obj_t stream_read_generic(size_t n_args, const mp_obj_t *args, byte flags) {
// What to do if sz < -1? Python docs don't specify this case. // What to do if sz < -1? Python docs don't specify this case.
@ -517,7 +518,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj, 2, 3, stream_ioctl);
ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) { ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) {
mp_obj_base_t *o = stream; mp_obj_base_t *o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &errno); mp_uint_t out_sz = stream_p->write(MP_OBJ_FROM_PTR(stream), buf, len, &errno);
if (out_sz == MP_STREAM_ERROR) { if (out_sz == MP_STREAM_ERROR) {
return -1; return -1;
@ -528,7 +529,7 @@ ssize_t mp_stream_posix_write(void *stream, const void *buf, size_t len) {
ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) { ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) {
mp_obj_base_t *o = stream; mp_obj_base_t *o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &errno); mp_uint_t out_sz = stream_p->read(MP_OBJ_FROM_PTR(stream), buf, len, &errno);
if (out_sz == MP_STREAM_ERROR) { if (out_sz == MP_STREAM_ERROR) {
return -1; return -1;
@ -539,7 +540,7 @@ ssize_t mp_stream_posix_read(void *stream, void *buf, size_t len) {
off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) { off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) {
const mp_obj_base_t *o = stream; const mp_obj_base_t *o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
struct mp_stream_seek_t seek_s; struct mp_stream_seek_t seek_s;
seek_s.offset = offset; seek_s.offset = offset;
seek_s.whence = whence; seek_s.whence = whence;
@ -552,7 +553,7 @@ off_t mp_stream_posix_lseek(void *stream, off_t offset, int whence) {
int mp_stream_posix_fsync(void *stream) { int mp_stream_posix_fsync(void *stream) {
mp_obj_base_t *o = stream; mp_obj_base_t *o = stream;
const mp_stream_p_t *stream_p = o->type->protocol; const mp_stream_p_t *stream_p = MP_OBJ_TYPE_GET_SLOT(o->type, protocol);
mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &errno); mp_uint_t res = stream_p->ioctl(MP_OBJ_FROM_PTR(stream), MP_STREAM_FLUSH, 0, &errno);
if (res == MP_STREAM_ERROR) { if (res == MP_STREAM_ERROR) {
return -1; return -1;

View File

@ -95,7 +95,7 @@ MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(mp_stream_ioctl_obj);
// Object is assumed to have a non-NULL stream protocol with valid r/w/ioctl methods // Object is assumed to have a non-NULL stream protocol with valid r/w/ioctl methods
static inline const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) { static inline const mp_stream_p_t *mp_get_stream(mp_const_obj_t self) {
return (const mp_stream_p_t *)((const mp_obj_base_t *)MP_OBJ_TO_PTR(self))->type->protocol; return (const mp_stream_p_t *)MP_OBJ_TYPE_GET_SLOT(((const mp_obj_base_t *)MP_OBJ_TO_PTR(self))->type, protocol);
} }
const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags); const mp_stream_p_t *mp_get_stream_raise(mp_obj_t self_in, int flags);