summaryrefslogtreecommitdiff
path: root/extmod
diff options
context:
space:
mode:
Diffstat (limited to 'extmod')
-rw-r--r--extmod/font_petme128_8x8.h128
-rw-r--r--extmod/machine_i2c.c31
-rw-r--r--extmod/machine_i2c.h2
-rw-r--r--extmod/machine_pinbase.c5
-rw-r--r--extmod/machine_signal.c18
-rw-r--r--extmod/machine_spi.c21
-rw-r--r--extmod/machine_spi.h2
-rw-r--r--extmod/modbtree.c2
-rw-r--r--extmod/modframebuf.c56
-rw-r--r--extmod/modlwip.c1
-rw-r--r--extmod/moductypes.c8
-rw-r--r--extmod/moduhashlib.c12
-rw-r--r--extmod/modujson.c37
-rw-r--r--extmod/modure.c240
-rw-r--r--extmod/modussl_axtls.c1
-rw-r--r--extmod/modussl_mbedtls.c1
-rw-r--r--extmod/modutimeq.c4
-rw-r--r--extmod/moduzlib.c5
-rw-r--r--extmod/modwebrepl.c1
-rw-r--r--extmod/modwebsocket.c5
-rw-r--r--extmod/re1.5/compilecode.c46
m---------extmod/ulab0
-rw-r--r--extmod/vfs.c4
-rw-r--r--extmod/vfs.h2
-rw-r--r--extmod/vfs_fat.c66
-rw-r--r--extmod/vfs_fat.h2
-rw-r--r--extmod/vfs_fat_file.c32
-rw-r--r--extmod/vfs_posix.c5
-rw-r--r--extmod/vfs_posix_file.c6
-rw-r--r--extmod/virtpin.c5
-rw-r--r--extmod/virtpin.h2
31 files changed, 630 insertions, 120 deletions
diff --git a/extmod/font_petme128_8x8.h b/extmod/font_petme128_8x8.h
new file mode 100644
index 000000000..9963698b1
--- /dev/null
+++ b/extmod/font_petme128_8x8.h
@@ -0,0 +1,128 @@
+/*
+ * This file is part of the MicroPython project, http://micropython.org/
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2013, 2014 Damien P. George
+ *
+ * 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_STM32_FONT_PETME128_8X8_H
+#define MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
+
+static const uint8_t font_petme128_8x8[] = {
+ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 32=
+ 0x00,0x00,0x00,0x4f,0x4f,0x00,0x00,0x00, // 33=!
+ 0x00,0x07,0x07,0x00,0x00,0x07,0x07,0x00, // 34="
+ 0x14,0x7f,0x7f,0x14,0x14,0x7f,0x7f,0x14, // 35=#
+ 0x00,0x24,0x2e,0x6b,0x6b,0x3a,0x12,0x00, // 36=$
+ 0x00,0x63,0x33,0x18,0x0c,0x66,0x63,0x00, // 37=%
+ 0x00,0x32,0x7f,0x4d,0x4d,0x77,0x72,0x50, // 38=&
+ 0x00,0x00,0x00,0x04,0x06,0x03,0x01,0x00, // 39='
+ 0x00,0x00,0x1c,0x3e,0x63,0x41,0x00,0x00, // 40=(
+ 0x00,0x00,0x41,0x63,0x3e,0x1c,0x00,0x00, // 41=)
+ 0x08,0x2a,0x3e,0x1c,0x1c,0x3e,0x2a,0x08, // 42=*
+ 0x00,0x08,0x08,0x3e,0x3e,0x08,0x08,0x00, // 43=+
+ 0x00,0x00,0x80,0xe0,0x60,0x00,0x00,0x00, // 44=,
+ 0x00,0x08,0x08,0x08,0x08,0x08,0x08,0x00, // 45=-
+ 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, // 46=.
+ 0x00,0x40,0x60,0x30,0x18,0x0c,0x06,0x02, // 47=/
+ 0x00,0x3e,0x7f,0x49,0x45,0x7f,0x3e,0x00, // 48=0
+ 0x00,0x40,0x44,0x7f,0x7f,0x40,0x40,0x00, // 49=1
+ 0x00,0x62,0x73,0x51,0x49,0x4f,0x46,0x00, // 50=2
+ 0x00,0x22,0x63,0x49,0x49,0x7f,0x36,0x00, // 51=3
+ 0x00,0x18,0x18,0x14,0x16,0x7f,0x7f,0x10, // 52=4
+ 0x00,0x27,0x67,0x45,0x45,0x7d,0x39,0x00, // 53=5
+ 0x00,0x3e,0x7f,0x49,0x49,0x7b,0x32,0x00, // 54=6
+ 0x00,0x03,0x03,0x79,0x7d,0x07,0x03,0x00, // 55=7
+ 0x00,0x36,0x7f,0x49,0x49,0x7f,0x36,0x00, // 56=8
+ 0x00,0x26,0x6f,0x49,0x49,0x7f,0x3e,0x00, // 57=9
+ 0x00,0x00,0x00,0x24,0x24,0x00,0x00,0x00, // 58=:
+ 0x00,0x00,0x80,0xe4,0x64,0x00,0x00,0x00, // 59=;
+ 0x00,0x08,0x1c,0x36,0x63,0x41,0x41,0x00, // 60=<
+ 0x00,0x14,0x14,0x14,0x14,0x14,0x14,0x00, // 61==
+ 0x00,0x41,0x41,0x63,0x36,0x1c,0x08,0x00, // 62=>
+ 0x00,0x02,0x03,0x51,0x59,0x0f,0x06,0x00, // 63=?
+ 0x00,0x3e,0x7f,0x41,0x4d,0x4f,0x2e,0x00, // 64=@
+ 0x00,0x7c,0x7e,0x0b,0x0b,0x7e,0x7c,0x00, // 65=A
+ 0x00,0x7f,0x7f,0x49,0x49,0x7f,0x36,0x00, // 66=B
+ 0x00,0x3e,0x7f,0x41,0x41,0x63,0x22,0x00, // 67=C
+ 0x00,0x7f,0x7f,0x41,0x63,0x3e,0x1c,0x00, // 68=D
+ 0x00,0x7f,0x7f,0x49,0x49,0x41,0x41,0x00, // 69=E
+ 0x00,0x7f,0x7f,0x09,0x09,0x01,0x01,0x00, // 70=F
+ 0x00,0x3e,0x7f,0x41,0x49,0x7b,0x3a,0x00, // 71=G
+ 0x00,0x7f,0x7f,0x08,0x08,0x7f,0x7f,0x00, // 72=H
+ 0x00,0x00,0x41,0x7f,0x7f,0x41,0x00,0x00, // 73=I
+ 0x00,0x20,0x60,0x41,0x7f,0x3f,0x01,0x00, // 74=J
+ 0x00,0x7f,0x7f,0x1c,0x36,0x63,0x41,0x00, // 75=K
+ 0x00,0x7f,0x7f,0x40,0x40,0x40,0x40,0x00, // 76=L
+ 0x00,0x7f,0x7f,0x06,0x0c,0x06,0x7f,0x7f, // 77=M
+ 0x00,0x7f,0x7f,0x0e,0x1c,0x7f,0x7f,0x00, // 78=N
+ 0x00,0x3e,0x7f,0x41,0x41,0x7f,0x3e,0x00, // 79=O
+ 0x00,0x7f,0x7f,0x09,0x09,0x0f,0x06,0x00, // 80=P
+ 0x00,0x1e,0x3f,0x21,0x61,0x7f,0x5e,0x00, // 81=Q
+ 0x00,0x7f,0x7f,0x19,0x39,0x6f,0x46,0x00, // 82=R
+ 0x00,0x26,0x6f,0x49,0x49,0x7b,0x32,0x00, // 83=S
+ 0x00,0x01,0x01,0x7f,0x7f,0x01,0x01,0x00, // 84=T
+ 0x00,0x3f,0x7f,0x40,0x40,0x7f,0x3f,0x00, // 85=U
+ 0x00,0x1f,0x3f,0x60,0x60,0x3f,0x1f,0x00, // 86=V
+ 0x00,0x7f,0x7f,0x30,0x18,0x30,0x7f,0x7f, // 87=W
+ 0x00,0x63,0x77,0x1c,0x1c,0x77,0x63,0x00, // 88=X
+ 0x00,0x07,0x0f,0x78,0x78,0x0f,0x07,0x00, // 89=Y
+ 0x00,0x61,0x71,0x59,0x4d,0x47,0x43,0x00, // 90=Z
+ 0x00,0x00,0x7f,0x7f,0x41,0x41,0x00,0x00, // 91=[
+ 0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0x40, // 92='\'
+ 0x00,0x00,0x41,0x41,0x7f,0x7f,0x00,0x00, // 93=]
+ 0x00,0x08,0x0c,0x06,0x06,0x0c,0x08,0x00, // 94=^
+ 0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0, // 95=_
+ 0x00,0x00,0x01,0x03,0x06,0x04,0x00,0x00, // 96=`
+ 0x00,0x20,0x74,0x54,0x54,0x7c,0x78,0x00, // 97=a
+ 0x00,0x7f,0x7f,0x44,0x44,0x7c,0x38,0x00, // 98=b
+ 0x00,0x38,0x7c,0x44,0x44,0x6c,0x28,0x00, // 99=c
+ 0x00,0x38,0x7c,0x44,0x44,0x7f,0x7f,0x00, // 100=d
+ 0x00,0x38,0x7c,0x54,0x54,0x5c,0x58,0x00, // 101=e
+ 0x00,0x08,0x7e,0x7f,0x09,0x03,0x02,0x00, // 102=f
+ 0x00,0x98,0xbc,0xa4,0xa4,0xfc,0x7c,0x00, // 103=g
+ 0x00,0x7f,0x7f,0x04,0x04,0x7c,0x78,0x00, // 104=h
+ 0x00,0x00,0x00,0x7d,0x7d,0x00,0x00,0x00, // 105=i
+ 0x00,0x40,0xc0,0x80,0x80,0xfd,0x7d,0x00, // 106=j
+ 0x00,0x7f,0x7f,0x30,0x38,0x6c,0x44,0x00, // 107=k
+ 0x00,0x00,0x41,0x7f,0x7f,0x40,0x00,0x00, // 108=l
+ 0x00,0x7c,0x7c,0x18,0x30,0x18,0x7c,0x7c, // 109=m
+ 0x00,0x7c,0x7c,0x04,0x04,0x7c,0x78,0x00, // 110=n
+ 0x00,0x38,0x7c,0x44,0x44,0x7c,0x38,0x00, // 111=o
+ 0x00,0xfc,0xfc,0x24,0x24,0x3c,0x18,0x00, // 112=p
+ 0x00,0x18,0x3c,0x24,0x24,0xfc,0xfc,0x00, // 113=q
+ 0x00,0x7c,0x7c,0x04,0x04,0x0c,0x08,0x00, // 114=r
+ 0x00,0x48,0x5c,0x54,0x54,0x74,0x20,0x00, // 115=s
+ 0x04,0x04,0x3f,0x7f,0x44,0x64,0x20,0x00, // 116=t
+ 0x00,0x3c,0x7c,0x40,0x40,0x7c,0x3c,0x00, // 117=u
+ 0x00,0x1c,0x3c,0x60,0x60,0x3c,0x1c,0x00, // 118=v
+ 0x00,0x1c,0x7c,0x30,0x18,0x30,0x7c,0x1c, // 119=w
+ 0x00,0x44,0x6c,0x38,0x38,0x6c,0x44,0x00, // 120=x
+ 0x00,0x9c,0xbc,0xa0,0xa0,0xfc,0x7c,0x00, // 121=y
+ 0x00,0x44,0x64,0x74,0x5c,0x4c,0x44,0x00, // 122=z
+ 0x00,0x08,0x08,0x3e,0x77,0x41,0x41,0x00, // 123={
+ 0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00, // 124=|
+ 0x00,0x41,0x41,0x77,0x3e,0x08,0x08,0x00, // 125=}
+ 0x00,0x02,0x03,0x01,0x03,0x02,0x03,0x01, // 126=~
+ 0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55, // 127
+};
+
+#endif // MICROPY_INCLUDED_STM32_FONT_PETME128_8X8_H
diff --git a/extmod/machine_i2c.c b/extmod/machine_i2c.c
index b91f1a1eb..4129ace0a 100644
--- a/extmod/machine_i2c.c
+++ b/extmod/machine_i2c.c
@@ -287,14 +287,14 @@ STATIC void machine_i2c_obj_init_helper(machine_i2c_obj_t *self, size_t n_args,
mp_hal_i2c_init(self, args[ARG_freq].u_int);
}
-STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
// check the id argument, if given
if (n_args > 0) {
if (args[0] != MP_OBJ_NEW_SMALL_INT(-1)) {
#if defined(MICROPY_PY_MACHINE_I2C_MAKE_NEW)
// dispatch to port-specific constructor
- extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
- return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, n_kw, args);
+ extern mp_obj_t MICROPY_PY_MACHINE_I2C_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args);
+ return MICROPY_PY_MACHINE_I2C_MAKE_NEW(type, n_args, args, kw_args);
#else
mp_raise_ValueError(translate("invalid I2C peripheral"));
#endif
@@ -306,9 +306,7 @@ STATIC mp_obj_t machine_i2c_make_new(const mp_obj_type_t *type, size_t n_args, s
// create new soft I2C object
machine_i2c_obj_t *self = m_new_obj(machine_i2c_obj_t);
self->base.type = &machine_i2c_type;
- mp_map_t kw_args;
- mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
- machine_i2c_obj_init_helper(self, n_args, args, &kw_args);
+ machine_i2c_obj_init_helper(self, n_args, args, kw_args);
return (mp_obj_t)self;
}
@@ -320,7 +318,7 @@ MP_DEFINE_CONST_FUN_OBJ_KW(machine_i2c_init_obj, 1, machine_i2c_obj_init);
STATIC mp_obj_t machine_i2c_scan(mp_obj_t self_in) {
mp_obj_base_t *self = 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_proto_get(self, QSTR_protocol_i2c);
mp_obj_t list = mp_obj_new_list(0, NULL);
// 7-bit addresses 0b0000xxx and 0b1111xxx are reserved
for (int addr = 0x08; addr < 0x78; ++addr) {
@@ -335,7 +333,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) {
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_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->start == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -349,7 +347,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) {
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_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->stop == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -363,7 +361,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) {
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_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->read == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -387,7 +385,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) {
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_proto_get(self, QSTR_protocol_i2c);
if (i2c_p->write == NULL) {
mp_raise_msg(&mp_type_OSError, translate("I2C operation not supported"));
}
@@ -409,7 +407,7 @@ MP_DEFINE_CONST_FUN_OBJ_2(machine_i2c_write_obj, machine_i2c_write);
STATIC mp_obj_t machine_i2c_readfrom(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_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_proto_get(self, QSTR_protocol_i2c);
mp_int_t addr = mp_obj_get_int(args[1]);
vstr_t vstr;
vstr_init_len(&vstr, mp_obj_get_int(args[2]));
@@ -424,7 +422,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_obj, 3, 4, machine_i2c_
STATIC mp_obj_t machine_i2c_readfrom_into(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_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_proto_get(self, QSTR_protocol_i2c);
mp_int_t addr = mp_obj_get_int(args[1]);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_WRITE);
@@ -439,7 +437,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_readfrom_into_obj, 3, 4, machine
STATIC mp_obj_t machine_i2c_writeto(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_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_proto_get(self, QSTR_protocol_i2c);
mp_int_t addr = mp_obj_get_int(args[1]);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(args[2], &bufinfo, MP_BUFFER_READ);
@@ -455,7 +453,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_i2c_writeto_obj, 3, 4, machin
STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, uint8_t *buf, size_t len) {
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_proto_get(self, QSTR_protocol_i2c);
uint8_t memaddr_buf[4];
size_t memaddr_len = 0;
for (int16_t i = addrsize - 8; i >= 0; i -= 8) {
@@ -475,7 +473,7 @@ STATIC int read_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t a
STATIC int write_mem(mp_obj_t self_in, uint16_t addr, uint32_t memaddr, uint8_t addrsize, const uint8_t *buf, size_t len) {
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_proto_get(self, QSTR_protocol_i2c);
// need some memory to create the buffer to send; try to use stack if possible
uint8_t buf2_stack[MAX_MEMADDR_SIZE + BUF_STACK_SIZE];
@@ -623,6 +621,7 @@ int mp_machine_soft_i2c_write(mp_obj_base_t *self_in, const uint8_t *src, size_t
}
STATIC const mp_machine_i2c_p_t mp_machine_soft_i2c_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_i2c)
.start = (int(*)(mp_obj_base_t*))mp_hal_i2c_start,
.stop = (int(*)(mp_obj_base_t*))mp_hal_i2c_stop,
.read = mp_machine_soft_i2c_read,
diff --git a/extmod/machine_i2c.h b/extmod/machine_i2c.h
index f5af6656f..7f5ee568e 100644
--- a/extmod/machine_i2c.h
+++ b/extmod/machine_i2c.h
@@ -27,10 +27,12 @@
#define MICROPY_INCLUDED_EXTMOD_MACHINE_I2C_H
#include "py/obj.h"
+#include "py/proto.h"
// I2C protocol
// the first 4 methods can be NULL, meaning operation is not supported
typedef struct _mp_machine_i2c_p_t {
+ MP_PROTOCOL_HEAD
int (*start)(mp_obj_base_t *obj);
int (*stop)(mp_obj_base_t *obj);
int (*read)(mp_obj_base_t *obj, uint8_t *dest, size_t len, bool nack);
diff --git a/extmod/machine_pinbase.c b/extmod/machine_pinbase.c
index 070c5cde9..6cd14c187 100644
--- a/extmod/machine_pinbase.c
+++ b/extmod/machine_pinbase.c
@@ -45,11 +45,11 @@ STATIC const mp_pinbase_t pinbase_singleton = {
.base = { &machine_pinbase_type },
};
-STATIC mp_obj_t pinbase_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t pinbase_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)type;
(void)n_args;
- (void)n_kw;
(void)args;
+ (void)kw_args;
return MP_OBJ_FROM_PTR(&pinbase_singleton);
}
@@ -74,6 +74,7 @@ mp_uint_t pinbase_ioctl(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *err
}
STATIC const mp_pin_p_t pinbase_pin_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
.ioctl = pinbase_ioctl,
};
diff --git a/extmod/machine_signal.c b/extmod/machine_signal.c
index 3f9f5af94..50501e34f 100644
--- a/extmod/machine_signal.c
+++ b/extmod/machine_signal.c
@@ -42,17 +42,12 @@ typedef struct _machine_signal_t {
bool invert;
} machine_signal_t;
-STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_obj_t pin = args[0];
bool invert = false;
#if defined(MICROPY_PY_MACHINE_PIN_MAKE_NEW)
- mp_pin_p_t *pin_p = NULL;
-
- if (MP_OBJ_IS_OBJ(pin)) {
- 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;
- }
+ mp_pin_p_t *pin_p = (mp_pin_t*)mp_proto_get(QSTR_pin_protocol, pin);
if (pin_p == NULL) {
// If first argument isn't a Pin-like object, we filter out "invert"
@@ -96,9 +91,9 @@ STATIC mp_obj_t signal_make_new(const mp_obj_type_t *type, size_t n_args, size_t
// Otherwise there should be 1 or 2 args
{
if (n_args == 1) {
- if (n_kw == 0) {
- } else if (n_kw == 1 && args[1] == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) {
- invert = mp_obj_is_true(args[2]);
+ if (kw_args == NULL || kw_args->used == 0) {
+ } else if (kw_args->used == 1 && kw_args->table[0].key == MP_OBJ_NEW_QSTR(MP_QSTR_invert)) {
+ invert = mp_obj_is_true(kw_args->table[0].value);
} else {
goto error;
}
@@ -133,7 +128,7 @@ STATIC mp_uint_t signal_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg
// fast method for getting/setting signal value
STATIC mp_obj_t signal_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+ mp_arg_check_num_kw_array(n_args, n_kw, 0, 1, false);
if (n_args == 0) {
// get pin
return MP_OBJ_NEW_SMALL_INT(mp_virtual_pin_read(self_in));
@@ -170,6 +165,7 @@ STATIC const mp_rom_map_elem_t signal_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(signal_locals_dict, signal_locals_dict_table);
STATIC const mp_pin_p_t signal_pin_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_pin)
.ioctl = signal_ioctl,
};
diff --git a/extmod/machine_spi.c b/extmod/machine_spi.c
index 3bbab2824..4ead321d9 100644
--- a/extmod/machine_spi.c
+++ b/extmod/machine_spi.c
@@ -43,16 +43,16 @@
/******************************************************************************/
// MicroPython bindings for generic machine.SPI
-STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
+STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
-mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
// check the id argument, if given
if (n_args > 0) {
if (args[0] != MP_OBJ_NEW_SMALL_INT(-1)) {
#if defined(MICROPY_PY_MACHINE_SPI_MAKE_NEW)
// dispatch to port-specific constructor
- extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args);
- return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, n_kw, args);
+ extern mp_obj_t MICROPY_PY_MACHINE_SPI_MAKE_NEW(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
+ return MICROPY_PY_MACHINE_SPI_MAKE_NEW(type, n_args, args, kw_args);
#else
mp_raise_ValueError(translate("invalid SPI peripheral"));
#endif
@@ -62,12 +62,12 @@ mp_obj_t mp_machine_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_
}
// software SPI
- return mp_machine_soft_spi_make_new(type, n_args, n_kw, args);
+ return mp_machine_soft_spi_make_new(type, n_args, args, 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_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_proto_get(QSTR_protocol_spi, s);
spi_p->init(s, n_args - 1, args + 1, kw_args);
return mp_const_none;
}
@@ -75,7 +75,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) {
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_proto_get(QSTR_protocol_spi, s);
if (spi_p->deinit != NULL) {
spi_p->deinit(s);
}
@@ -85,7 +85,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) {
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_proto_get(QSTR_protocol_spi, s);
spi_p->transfer(s, len, src, dest);
}
@@ -180,7 +180,7 @@ STATIC void mp_machine_soft_spi_print(const mp_print_t *print, mp_obj_t self_in,
mp_hal_pin_name(self->spi.sck), mp_hal_pin_name(self->spi.mosi), mp_hal_pin_name(self->spi.miso));
}
-STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
+STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *all_args, mp_map_t *kw_args) {
enum { ARG_baudrate, ARG_polarity, ARG_phase, ARG_bits, ARG_firstbit, ARG_sck, ARG_mosi, ARG_miso };
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 500000} },
@@ -193,7 +193,7 @@ STATIC mp_obj_t mp_machine_soft_spi_make_new(const mp_obj_type_t *type, size_t n
{ MP_QSTR_miso, 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_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
+ mp_arg_parse_all(n_args, all_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
// create new object
mp_machine_soft_spi_obj_t *self = m_new_obj(mp_machine_soft_spi_obj_t);
@@ -268,6 +268,7 @@ STATIC void mp_machine_soft_spi_transfer(mp_obj_base_t *self_in, size_t len, con
}
const mp_machine_spi_p_t mp_machine_soft_spi_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_spi)
.init = mp_machine_soft_spi_init,
.deinit = NULL,
.transfer = mp_machine_soft_spi_transfer,
diff --git a/extmod/machine_spi.h b/extmod/machine_spi.h
index db21e1cd3..365b44d6e 100644
--- a/extmod/machine_spi.h
+++ b/extmod/machine_spi.h
@@ -27,11 +27,13 @@
#define MICROPY_INCLUDED_EXTMOD_MACHINE_SPI_H
#include "py/obj.h"
+#include "py/proto.h"
#include "py/mphal.h"
#include "drivers/bus/spi.h"
// SPI protocol
typedef struct _mp_machine_spi_p_t {
+ MP_PROTOCOL_HEAD
void (*init)(mp_obj_base_t *obj, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args);
void (*deinit)(mp_obj_base_t *obj); // can be NULL
void (*transfer)(mp_obj_base_t *obj, size_t len, const uint8_t *src, uint8_t *dest);
diff --git a/extmod/modbtree.c b/extmod/modbtree.c
index 8b7688580..7cfa9c6af 100644
--- a/extmod/modbtree.c
+++ b/extmod/modbtree.c
@@ -247,7 +247,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) {
- 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/modframebuf.c b/extmod/modframebuf.c
index 413540540..c59d1592b 100644
--- a/extmod/modframebuf.c
+++ b/extmod/modframebuf.c
@@ -28,10 +28,12 @@
#include <string.h>
#include "py/runtime.h"
+#include "py/objtype.h"
+#include "py/proto.h"
#if MICROPY_PY_FRAMEBUF
-#include "ports/stm32/font_petme128_8x8.h"
+#include "font_petme128_8x8.h"
typedef struct _mp_obj_framebuf_t {
mp_obj_base_t base;
@@ -46,6 +48,7 @@ typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t*, int, int);
typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, int, int, int, int, uint32_t);
typedef struct _mp_framebuf_p_t {
+ MP_PROTOCOL_HEAD
setpixel_t setpixel;
getpixel_t getpixel;
fill_rect_t fill_rect;
@@ -227,13 +230,13 @@ STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int
}
STATIC mp_framebuf_p_t formats[] = {
- [FRAMEBUF_MVLSB] = {mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
- [FRAMEBUF_RGB565] = {rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
- [FRAMEBUF_GS2_HMSB] = {gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
- [FRAMEBUF_GS4_HMSB] = {gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
- [FRAMEBUF_GS8] = {gs8_setpixel, gs8_getpixel, gs8_fill_rect},
- [FRAMEBUF_MHLSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
- [FRAMEBUF_MHMSB] = {mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
+ [FRAMEBUF_MVLSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mvlsb_setpixel, mvlsb_getpixel, mvlsb_fill_rect},
+ [FRAMEBUF_RGB565] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) rgb565_setpixel, rgb565_getpixel, rgb565_fill_rect},
+ [FRAMEBUF_GS2_HMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs2_hmsb_setpixel, gs2_hmsb_getpixel, gs2_hmsb_fill_rect},
+ [FRAMEBUF_GS4_HMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs4_hmsb_setpixel, gs4_hmsb_getpixel, gs4_hmsb_fill_rect},
+ [FRAMEBUF_GS8] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) gs8_setpixel, gs8_getpixel, gs8_fill_rect},
+ [FRAMEBUF_MHLSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
+ [FRAMEBUF_MHMSB] = {MP_PROTO_IMPLEMENT(MP_QSTR_protocol_framebuf) mono_horiz_setpixel, mono_horiz_getpixel, mono_horiz_fill_rect},
};
static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
@@ -259,8 +262,8 @@ STATIC void fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, u
formats[fb->format].fill_rect(fb, x, y, xend - x, yend - y, col);
}
-STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 4, 5, false);
+STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 4, 5, false);
mp_obj_framebuf_t *o = m_new_obj(mp_obj_framebuf_t);
o->base.type = type;
@@ -302,9 +305,18 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, size
return MP_OBJ_FROM_PTR(o);
}
+STATIC const mp_obj_type_t mp_type_framebuf;
+
+// Helper to ensure we have the native super class instead of a subclass.
+static mp_obj_framebuf_t* native_framebuf(mp_obj_t framebuf_obj) {
+ mp_obj_t native_framebuf = mp_instance_cast_to_native_base(framebuf_obj, &mp_type_framebuf);
+ mp_obj_assert_native_inited(native_framebuf);
+ return MP_OBJ_TO_PTR(native_framebuf);
+}
+
STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo, mp_uint_t flags) {
(void)flags;
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_framebuf_t *self = native_framebuf(self_in);
bufinfo->buf = self->buf;
bufinfo->len = self->stride * self->height * (self->format == FRAMEBUF_RGB565 ? 2 : 1);
bufinfo->typecode = 'B'; // view framebuf as bytes
@@ -312,7 +324,7 @@ STATIC mp_int_t framebuf_get_buffer(mp_obj_t self_in, mp_buffer_info_t *bufinfo,
}
STATIC mp_obj_t framebuf_fill(mp_obj_t self_in, mp_obj_t col_in) {
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_framebuf_t *self = native_framebuf(self_in);
mp_int_t col = mp_obj_get_int(col_in);
formats[self->format].fill_rect(self, 0, 0, self->width, self->height, col);
return mp_const_none;
@@ -322,7 +334,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(framebuf_fill_obj, framebuf_fill);
STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
(void)n_args;
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_int_t width = mp_obj_get_int(args[3]);
@@ -336,7 +348,7 @@ STATIC mp_obj_t framebuf_fill_rect(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_fill_rect_obj, 6, 6, framebuf_fill_rect);
STATIC mp_obj_t framebuf_pixel(size_t n_args, const mp_obj_t *args) {
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
if (0 <= x && x < self->width && 0 <= y && y < self->height) {
@@ -355,7 +367,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_pixel_obj, 3, 4, framebuf_pi
STATIC mp_obj_t framebuf_hline(size_t n_args, const mp_obj_t *args) {
(void)n_args;
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_int_t w = mp_obj_get_int(args[3]);
@@ -370,7 +382,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_hline_obj, 5, 5, framebuf_hl
STATIC mp_obj_t framebuf_vline(size_t n_args, const mp_obj_t *args) {
(void)n_args;
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_int_t h = mp_obj_get_int(args[3]);
@@ -385,7 +397,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_vline_obj, 5, 5, framebuf_vl
STATIC mp_obj_t framebuf_rect(size_t n_args, const mp_obj_t *args) {
(void)n_args;
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
mp_int_t x = mp_obj_get_int(args[1]);
mp_int_t y = mp_obj_get_int(args[2]);
mp_int_t w = mp_obj_get_int(args[3]);
@@ -404,7 +416,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_rect_obj, 6, 6, framebuf_rec
STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
(void)n_args;
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
mp_int_t x1 = mp_obj_get_int(args[1]);
mp_int_t y1 = mp_obj_get_int(args[2]);
mp_int_t x2 = mp_obj_get_int(args[3]);
@@ -468,8 +480,8 @@ STATIC mp_obj_t framebuf_line(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_line_obj, 6, 6, framebuf_line);
STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
- mp_obj_framebuf_t *source = MP_OBJ_TO_PTR(args[1]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
+ mp_obj_framebuf_t *source = native_framebuf(args[1]);
mp_int_t x = mp_obj_get_int(args[2]);
mp_int_t y = mp_obj_get_int(args[3]);
mp_int_t key = -1;
@@ -511,7 +523,7 @@ STATIC mp_obj_t framebuf_blit(size_t n_args, const mp_obj_t *args) {
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_blit_obj, 4, 5, framebuf_blit);
STATIC mp_obj_t framebuf_scroll(mp_obj_t self_in, mp_obj_t xstep_in, mp_obj_t ystep_in) {
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_framebuf_t *self = native_framebuf(self_in);
mp_int_t xstep = mp_obj_get_int(xstep_in);
mp_int_t ystep = mp_obj_get_int(ystep_in);
int sx, y, xend, yend, dx, dy;
@@ -544,7 +556,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(framebuf_scroll_obj, framebuf_scroll);
STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) {
// extract arguments
- mp_obj_framebuf_t *self = MP_OBJ_TO_PTR(args[0]);
+ mp_obj_framebuf_t *self = native_framebuf(args[0]);
const char *str = mp_obj_str_get_str(args[1]);
mp_int_t x0 = mp_obj_get_int(args[2]);
mp_int_t y0 = mp_obj_get_int(args[3]);
diff --git a/extmod/modlwip.c b/extmod/modlwip.c
index e5e92c42b..776b81ee5 100644
--- a/extmod/modlwip.c
+++ b/extmod/modlwip.c
@@ -1261,6 +1261,7 @@ STATIC const mp_rom_map_elem_t lwip_socket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(lwip_socket_locals_dict, lwip_socket_locals_dict_table);
STATIC const mp_stream_p_t lwip_socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = lwip_socket_read,
.write = lwip_socket_write,
.ioctl = lwip_socket_ioctl,
diff --git a/extmod/moductypes.c b/extmod/moductypes.c
index e627cd146..451dc29ed 100644
--- a/extmod/moductypes.c
+++ b/extmod/moductypes.c
@@ -122,8 +122,8 @@ STATIC NORETURN void syntax_error(void) {
mp_raise_TypeError(translate("syntax error in uctypes descriptor"));
}
-STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 2, 3, false);
+STATIC mp_obj_t uctypes_struct_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 2, 3, false);
mp_obj_uctypes_struct_t *o = m_new_obj(mp_obj_uctypes_struct_t);
o->base.type = type;
o->addr = (void*)(uintptr_t)mp_obj_int_get_truncated(args[0]);
@@ -518,8 +518,8 @@ 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) {
- 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_uctypes_struct_t *self = mp_instance_cast_to_native_base(base_in, &uctypes_struct_type);
if (value == MP_OBJ_NULL) {
// delete
diff --git a/extmod/moduhashlib.c b/extmod/moduhashlib.c
index 1618594e9..970c63da8 100644
--- a/extmod/moduhashlib.c
+++ b/extmod/moduhashlib.c
@@ -66,8 +66,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_MBEDTLS
-STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context));
o->base.type = type;
mbedtls_sha256_init((mbedtls_sha256_context*)&o->state);
@@ -104,8 +104,8 @@ static void check_not_unicode(const mp_obj_t arg) {
#endif
}
-STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(CRYAL_SHA256_CTX));
o->base.type = type;
sha256_init((CRYAL_SHA256_CTX*)o->state);
@@ -155,8 +155,8 @@ STATIC const mp_obj_type_t uhashlib_sha256_type = {
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg);
#if MICROPY_SSL_AXTLS
-STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(SHA1_CTX));
o->base.type = type;
SHA1_Init((SHA1_CTX*)o->state);
diff --git a/extmod/modujson.c b/extmod/modujson.c
index ea6c8b40f..0f93ccb11 100644
--- a/extmod/modujson.c
+++ b/extmod/modujson.c
@@ -53,6 +53,10 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps);
+#define JSON_DEBUG(...) (void)0
+// #define JSON_DEBUG(...) mp_printf(&mp_plat_print __VA_OPT__(,) __VA_ARGS__)
+
+
// The function below implements a simple non-recursive JSON parser.
//
// The JSON specification is at http://www.ietf.org/rfc/rfc4627.txt
@@ -80,6 +84,7 @@ typedef struct _ujson_stream_t {
STATIC byte ujson_stream_next(ujson_stream_t *s) {
mp_uint_t ret = s->read(s->stream_obj, &s->cur, 1, &s->errcode);
+ JSON_DEBUG(" usjon_stream_next err:%2d cur: %c \n", s->errcode, s->cur);
if (s->errcode != 0) {
mp_raise_OSError(s->errcode);
}
@@ -89,9 +94,10 @@ STATIC byte ujson_stream_next(ujson_stream_t *s) {
return s->cur;
}
-STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
+STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
const mp_stream_p_t *stream_p = mp_get_stream_raise(stream_obj, MP_STREAM_OP_READ);
ujson_stream_t s = {stream_obj, stream_p->read, 0, 0};
+ JSON_DEBUG("got JSON stream\n");
vstr_t vstr;
vstr_init(&vstr, 8);
mp_obj_list_t stack; // we use a list as a simple stack for nested JSON
@@ -262,13 +268,18 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
}
}
success:
- // eat trailing whitespace
- while (unichar_isspace(S_CUR(s))) {
- S_NEXT(s);
- }
- if (!S_END(s)) {
- // unexpected chars
- goto fail;
+ // It is legal for a stream to have contents after JSON.
+ // E.g., A UART is not closed after receiving an object; in load() we will
+ // return the first complete JSON object, while in loads() we will retain
+ // strict adherence to the buffer's complete semantic.
+ if (!return_first_json) {
+ while (unichar_isspace(S_CUR(s))) {
+ S_NEXT(s);
+ }
+ if (!S_END(s)) {
+ // unexpected chars
+ goto fail;
+ }
}
if (stack_top == MP_OBJ_NULL || stack.len != 0) {
// not exactly 1 object
@@ -280,6 +291,10 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
fail:
mp_raise_ValueError(translate("syntax error in JSON"));
}
+
+STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
+ return _mod_ujson_load(stream_obj, true);
+}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_load_obj, mod_ujson_load);
STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
@@ -287,12 +302,16 @@ STATIC mp_obj_t mod_ujson_loads(mp_obj_t obj) {
const char *buf = mp_obj_str_get_data(obj, &len);
vstr_t vstr = {len, len, (char*)buf, true};
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
- return mod_ujson_load(MP_OBJ_FROM_PTR(&sio));
+ return _mod_ujson_load(MP_OBJ_FROM_PTR(&sio), false);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_loads_obj, mod_ujson_loads);
STATIC const mp_rom_map_elem_t mp_module_ujson_globals_table[] = {
+#if CIRCUITPY
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_json) },
+#else
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ujson) },
+#endif
{ MP_ROM_QSTR(MP_QSTR_dump), MP_ROM_PTR(&mod_ujson_dump_obj) },
{ MP_ROM_QSTR(MP_QSTR_dumps), MP_ROM_PTR(&mod_ujson_dumps_obj) },
{ MP_ROM_QSTR(MP_QSTR_load), MP_ROM_PTR(&mod_ujson_load_obj) },
diff --git a/extmod/modure.c b/extmod/modure.c
index 1a7027026..125afef4d 100644
--- a/extmod/modure.c
+++ b/extmod/modure.c
@@ -77,8 +77,83 @@ STATIC mp_obj_t match_group(mp_obj_t self_in, mp_obj_t no_in) {
}
MP_DEFINE_CONST_FUN_OBJ_2(match_group_obj, match_group);
+#if MICROPY_PY_URE_MATCH_GROUPS
+
+STATIC mp_obj_t match_groups(mp_obj_t self_in) {
+ mp_obj_match_t *self = MP_OBJ_TO_PTR(self_in);
+ if (self->num_matches <= 1) {
+ return mp_const_empty_tuple;
+ }
+ mp_obj_tuple_t *groups = MP_OBJ_TO_PTR(mp_obj_new_tuple(self->num_matches - 1, NULL));
+ for (int i = 1; i < self->num_matches; ++i) {
+ groups->items[i - 1] = match_group(self_in, MP_OBJ_NEW_SMALL_INT(i));
+ }
+ return MP_OBJ_FROM_PTR(groups);
+}
+MP_DEFINE_CONST_FUN_OBJ_1(match_groups_obj, match_groups);
+
+#endif
+
+#if MICROPY_PY_URE_MATCH_SPAN_START_END
+
+STATIC void match_span_helper(size_t n_args, const mp_obj_t *args, mp_obj_t span[2]) {
+ mp_obj_match_t *self = MP_OBJ_TO_PTR(args[0]);
+
+ mp_int_t no = 0;
+ if (n_args == 2) {
+ no = mp_obj_get_int(args[1]);
+ if (no < 0 || no >= self->num_matches) {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_IndexError, args[1]));
+ }
+ }
+
+ mp_int_t s = -1;
+ mp_int_t e = -1;
+ const char *start = self->caps[no * 2];
+ if (start != NULL) {
+ // have a match for this group
+ const char *begin = mp_obj_str_get_str(self->str);
+ s = start - begin;
+ e = self->caps[no * 2 + 1] - begin;
+ }
+
+ span[0] = mp_obj_new_int(s);
+ span[1] = mp_obj_new_int(e);
+}
+
+STATIC mp_obj_t match_span(size_t n_args, const mp_obj_t *args) {
+ mp_obj_t span[2];
+ match_span_helper(n_args, args, span);
+ return mp_obj_new_tuple(2, span);
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_span_obj, 1, 2, match_span);
+
+STATIC mp_obj_t match_start(size_t n_args, const mp_obj_t *args) {
+ mp_obj_t span[2];
+ match_span_helper(n_args, args, span);
+ return span[0];
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_start_obj, 1, 2, match_start);
+
+STATIC mp_obj_t match_end(size_t n_args, const mp_obj_t *args) {
+ mp_obj_t span[2];
+ match_span_helper(n_args, args, span);
+ return span[1];
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_end_obj, 1, 2, match_end);
+
+#endif
+
STATIC const mp_rom_map_elem_t match_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_group), MP_ROM_PTR(&match_group_obj) },
+ #if MICROPY_PY_URE_MATCH_GROUPS
+ { MP_ROM_QSTR(MP_QSTR_groups), MP_ROM_PTR(&match_groups_obj) },
+ #endif
+ #if MICROPY_PY_URE_MATCH_SPAN_START_END
+ { MP_ROM_QSTR(MP_QSTR_span), MP_ROM_PTR(&match_span_obj) },
+ { MP_ROM_QSTR(MP_QSTR_start), MP_ROM_PTR(&match_start_obj) },
+ { MP_ROM_QSTR(MP_QSTR_end), MP_ROM_PTR(&match_end_obj) },
+ #endif
};
STATIC MP_DEFINE_CONST_DICT(match_locals_dict, match_locals_dict_table);
@@ -103,6 +178,35 @@ STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
size_t len;
subj.begin = mp_obj_str_get_data(args[1], &len);
subj.end = subj.begin + len;
+#if MICROPY_PY_URE_MATCH_SPAN_START_END
+ if (n_args > 2) {
+ const mp_obj_type_t *self_type = mp_obj_get_type(args[1]);
+ mp_int_t str_len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len_maybe(args[1]));
+ const byte *begin = (const byte *)subj.begin;
+
+ int pos = mp_obj_get_int(args[2]);
+ if (pos >= str_len) {
+ return mp_const_none;
+ }
+ if (pos < 0) {
+ pos = 0;
+ }
+ const byte *pos_ptr = str_index_to_ptr(self_type, begin, len, MP_OBJ_NEW_SMALL_INT(pos), true);
+
+ const byte *endpos_ptr = (const byte *)subj.end;
+ if (n_args > 3) {
+ int endpos = mp_obj_get_int(args[3]);
+ if (endpos <= pos) {
+ return mp_const_none;
+ }
+ // Will cap to length
+ endpos_ptr = str_index_to_ptr(self_type, begin, len, args[3], true);
+ }
+
+ subj.begin = (const char *)pos_ptr;
+ subj.end = (const char *)endpos_ptr;
+ }
+#endif
int caps_num = (self->re.sub + 1) * 2;
mp_obj_match_t *match = m_new_obj_var(mp_obj_match_t, char*, caps_num);
// cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char
@@ -174,17 +278,138 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_split_obj, 2, 3, re_split);
+#if MICROPY_PY_URE_SUB
+
+STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *args) {
+ mp_obj_re_t *self = MP_OBJ_TO_PTR(self_in);
+ mp_obj_t replace = args[1];
+ mp_obj_t where = args[2];
+ mp_int_t count = 0;
+ if (n_args > 3) {
+ count = mp_obj_get_int(args[3]);
+ // Note: flags are currently ignored
+ }
+
+ size_t where_len;
+ const char *where_str = mp_obj_str_get_data(where, &where_len);
+ Subject subj;
+ subj.begin = where_str;
+ subj.end = subj.begin + where_len;
+ int caps_num = (self->re.sub + 1) * 2;
+
+ vstr_t vstr_return;
+ vstr_return.buf = NULL; // We'll init the vstr after the first match
+ mp_obj_match_t *match = mp_local_alloc(sizeof(mp_obj_match_t) + caps_num * sizeof(char*));
+ match->base.type = &match_type;
+ match->num_matches = caps_num / 2; // caps_num counts start and end pointers
+ match->str = where;
+
+ for (;;) {
+ // cast is a workaround for a bug in msvc: it treats const char** as a const pointer instead of a pointer to pointer to const char
+ memset((char*)match->caps, 0, caps_num * sizeof(char*));
+ int res = re1_5_recursiveloopprog(&self->re, &subj, match->caps, caps_num, false);
+
+ // If we didn't have a match, or had an empty match, it's time to stop
+ if (!res || match->caps[0] == match->caps[1]) {
+ break;
+ }
+
+ // Initialise the vstr if it's not already
+ if (vstr_return.buf == NULL) {
+ vstr_init(&vstr_return, match->caps[0] - subj.begin);
+ }
+
+ // Add pre-match string
+ vstr_add_strn(&vstr_return, subj.begin, match->caps[0] - subj.begin);
+
+ // Get replacement string
+ const char* repl = mp_obj_str_get_str((mp_obj_is_callable(replace) ? mp_call_function_1(replace, MP_OBJ_FROM_PTR(match)) : replace));
+
+ // Append replacement string to result, substituting any regex groups
+ while (*repl != '\0') {
+ if (*repl == '\\') {
+ ++repl;
+ bool is_g_format = false;
+ if (*repl == 'g' && repl[1] == '<') {
+ // Group specified with syntax "\g<number>"
+ repl += 2;
+ is_g_format = true;
+ }
+
+ if ('0' <= *repl && *repl <= '9') {
+ // Group specified with syntax "\g<number>" or "\number"
+ unsigned int match_no = 0;
+ do {
+ match_no = match_no * 10 + (*repl++ - '0');
+ } while ('0' <= *repl && *repl <= '9');
+ if (is_g_format && *repl == '>') {
+ ++repl;
+ }
+
+ if (match_no >= (unsigned int)match->num_matches) {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_IndexError, MP_OBJ_NEW_SMALL_INT(match_no)));
+ }
+
+ const char *start_match = match->caps[match_no * 2];
+ if (start_match != NULL) {
+ // Add the substring matched by group
+ const char *end_match = match->caps[match_no * 2 + 1];
+ vstr_add_strn(&vstr_return, start_match, end_match - start_match);
+ }
+ }
+ } else {
+ // Just add the current byte from the replacement string
+ vstr_add_byte(&vstr_return, *repl++);
+ }
+ }
+
+ // Move start pointer to end of last match
+ subj.begin = match->caps[1];
+
+ // Stop substitutions if count was given and gets to 0
+ if (count > 0 && --count == 0) {
+ break;
+ }
+ }
+
+ mp_local_free(match);
+
+ if (vstr_return.buf == NULL) {
+ // Optimisation for case of no substitutions
+ return where;
+ }
+
+ // Add post-match string
+ vstr_add_strn(&vstr_return, subj.begin, subj.end - subj.begin);
+
+ return mp_obj_new_str_from_vstr(mp_obj_get_type(where), &vstr_return);
+}
+
+STATIC mp_obj_t re_sub(size_t n_args, const mp_obj_t *args) {
+ return re_sub_helper(args[0], n_args, args);
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub);
+
+#endif
+
STATIC const mp_rom_map_elem_t re_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) },
{ MP_ROM_QSTR(MP_QSTR_split), MP_ROM_PTR(&re_split_obj) },
+ #if MICROPY_PY_URE_SUB
+ { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) },
+ #endif
};
STATIC MP_DEFINE_CONST_DICT(re_locals_dict, re_locals_dict_table);
STATIC const mp_obj_type_t re_type = {
{ &mp_type_type },
+#if CIRCUITPY
+ .name = MP_QSTR_re,
+#else
.name = MP_QSTR_ure,
+#endif
.print = re_print,
.locals_dict = (void*)&re_locals_dict,
};
@@ -232,11 +457,26 @@ STATIC mp_obj_t mod_re_search(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_search_obj, 2, 4, mod_re_search);
+#if MICROPY_PY_URE_SUB
+STATIC mp_obj_t mod_re_sub(size_t n_args, const mp_obj_t *args) {
+ mp_obj_t self = mod_re_compile(1, args);
+ return re_sub_helper(self, n_args, args);
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_sub_obj, 3, 5, mod_re_sub);
+#endif
+
STATIC const mp_rom_map_elem_t mp_module_re_globals_table[] = {
+#if CIRCUITPY
+ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_re) },
+#else
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_ure) },
+#endif
{ MP_ROM_QSTR(MP_QSTR_compile), MP_ROM_PTR(&mod_re_compile_obj) },
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&mod_re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&mod_re_search_obj) },
+ #if MICROPY_PY_URE_SUB
+ { MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) },
+ #endif
{ MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) },
};
diff --git a/extmod/modussl_axtls.c b/extmod/modussl_axtls.c
index cfa652585..032dea09f 100644
--- a/extmod/modussl_axtls.c
+++ b/extmod/modussl_axtls.c
@@ -221,6 +221,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
STATIC const mp_stream_p_t ussl_socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = socket_read,
.write = socket_write,
.ioctl = socket_ioctl,
diff --git a/extmod/modussl_mbedtls.c b/extmod/modussl_mbedtls.c
index 08807d20b..9abdeb966 100644
--- a/extmod/modussl_mbedtls.c
+++ b/extmod/modussl_mbedtls.c
@@ -305,6 +305,7 @@ STATIC const mp_rom_map_elem_t ussl_socket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(ussl_socket_locals_dict, ussl_socket_locals_dict_table);
STATIC const mp_stream_p_t ussl_socket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = socket_read,
.write = socket_write,
.ioctl = socket_ioctl,
diff --git a/extmod/modutimeq.c b/extmod/modutimeq.c
index 614820443..99b51016d 100644
--- a/extmod/modutimeq.c
+++ b/extmod/modutimeq.c
@@ -76,8 +76,8 @@ STATIC bool time_less_than(struct qentry *item, struct qentry *parent) {
return res && res < (MODULO / 2);
}
-STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, 1, false);
+STATIC mp_obj_t utimeq_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 1, 1, false);
mp_uint_t alloc = mp_obj_get_int(args[0]);
mp_obj_utimeq_t *o = m_new_obj_var(mp_obj_utimeq_t, struct qentry, alloc);
o->base.type = type;
diff --git a/extmod/moduzlib.c b/extmod/moduzlib.c
index 253deac1e..3a081bc45 100644
--- a/extmod/moduzlib.c
+++ b/extmod/moduzlib.c
@@ -69,8 +69,8 @@ STATIC int read_src_stream(TINF_DATA *data) {
return c;
}
-STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, 2, false);
+STATIC mp_obj_t decompio_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 1, 2, false);
mp_get_stream_raise(args[0], MP_STREAM_OP_READ);
mp_obj_decompio_t *o = m_new_obj(mp_obj_decompio_t);
o->base.type = type;
@@ -134,6 +134,7 @@ STATIC const mp_rom_map_elem_t decompio_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(decompio_locals_dict, decompio_locals_dict_table);
STATIC const mp_stream_p_t decompio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = decompio_read,
};
diff --git a/extmod/modwebrepl.c b/extmod/modwebrepl.c
index 06da210d1..fb4d97358 100644
--- a/extmod/modwebrepl.c
+++ b/extmod/modwebrepl.c
@@ -331,6 +331,7 @@ STATIC const mp_rom_map_elem_t webrepl_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(webrepl_locals_dict, webrepl_locals_dict_table);
STATIC const mp_stream_p_t webrepl_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = webrepl_read,
.write = webrepl_write,
.ioctl = webrepl_ioctl,
diff --git a/extmod/modwebsocket.c b/extmod/modwebsocket.c
index c556f2b77..496e4b5bb 100644
--- a/extmod/modwebsocket.c
+++ b/extmod/modwebsocket.c
@@ -57,8 +57,8 @@ typedef struct _mp_obj_websocket_t {
STATIC mp_uint_t websocket_write(mp_obj_t self_in, const void *buf, mp_uint_t size, int *errcode);
-STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, 2, false);
+STATIC mp_obj_t websocket_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 1, 2, false);
mp_get_stream_raise(args[0], MP_STREAM_OP_READ | MP_STREAM_OP_WRITE | MP_STREAM_OP_IOCTL);
mp_obj_websocket_t *o = m_new_obj(mp_obj_websocket_t);
o->base.type = type;
@@ -286,6 +286,7 @@ STATIC const mp_rom_map_elem_t websocket_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(websocket_locals_dict, websocket_locals_dict_table);
STATIC const mp_stream_p_t websocket_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = websocket_read,
.write = websocket_write,
.ioctl = websocket_ioctl,
diff --git a/extmod/re1.5/compilecode.c b/extmod/re1.5/compilecode.c
index a685a508a..01d3d1498 100644
--- a/extmod/re1.5/compilecode.c
+++ b/extmod/re1.5/compilecode.c
@@ -10,6 +10,29 @@
#define EMIT(at, byte) (code ? (code[at] = byte) : (at))
#define PC (prog->bytelen)
+
+static char unescape(char c) {
+ switch (c) {
+ case 'a':
+ return '\a';
+ case 'b':
+ return '\b';
+ case 'f':
+ return '\f';
+ case 'n':
+ return '\n';
+ case 'r':
+ return '\r';
+ case 'v':
+ return '\v';
+ case 'x':
+ return '\\';
+ default:
+ return c;
+ }
+}
+
+
static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
{
char *code = sizecode ? NULL : prog->insts;
@@ -22,13 +45,16 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
case '\\':
re++;
if (!*re) return NULL; // Trailing backslash
+ term = PC;
if ((*re | 0x20) == 'd' || (*re | 0x20) == 's' || (*re | 0x20) == 'w') {
- term = PC;
EMIT(PC++, NamedClass);
EMIT(PC++, *re);
- prog->len++;
- break;
+ } else {
+ EMIT(PC++, Char);
+ EMIT(PC++, unescape(*re));
}
+ prog->len++;
+ break;
default:
term = PC;
EMIT(PC++, Char);
@@ -54,11 +80,21 @@ static const char *_compilecode(const char *re, ByteProg *prog, int sizecode)
prog->len++;
for (cnt = 0; *re != ']'; re++, cnt++) {
if (!*re) return NULL;
- EMIT(PC++, *re);
+ if (*re == '\\') {
+ re += 1;
+ EMIT(PC++, unescape(*re));
+ } else {
+ EMIT(PC++, *re);
+ }
if (re[1] == '-' && re[2] != ']') {
re += 2;
}
- EMIT(PC++, *re);
+ if (*re == '\\') {
+ re += 1;
+ EMIT(PC++, unescape(*re));
+ } else {
+ EMIT(PC++, *re);
+ }
}
EMIT(term + 1, cnt);
break;
diff --git a/extmod/ulab b/extmod/ulab
new file mode 160000
+Subproject 0394801933f6e68a5bc7cdb0da76c7884e8cf70
diff --git a/extmod/vfs.c b/extmod/vfs.c
index cc794aad5..2bb4057e7 100644
--- a/extmod/vfs.c
+++ b/extmod/vfs.c
@@ -126,7 +126,7 @@ mp_import_stat_t mp_vfs_import_stat(const char *path) {
}
// 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_vfs_proto_t *proto = (mp_vfs_proto_t*)mp_proto_get(MP_QSTR_protocol_vfs, vfs->obj);
if (proto != NULL) {
return proto->import_stat(MP_OBJ_TO_PTR(vfs->obj), path_out);
}
@@ -176,7 +176,7 @@ mp_obj_t mp_vfs_mount(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args
// auto-detect the filesystem and create the corresponding VFS entity.
// (At the moment we only support FAT filesystems.)
#if MICROPY_VFS_FAT
- vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, 0, &vfs_obj);
+ vfs_obj = mp_fat_vfs_type.make_new(&mp_fat_vfs_type, 1, &vfs_obj, NULL);
#endif
}
diff --git a/extmod/vfs.h b/extmod/vfs.h
index 38c77943c..6c0692365 100644
--- a/extmod/vfs.h
+++ b/extmod/vfs.h
@@ -28,6 +28,7 @@
#include "py/lexer.h"
#include "py/obj.h"
+#include "py/proto.h"
// return values of mp_vfs_lookup_path
// ROOT is 0 so that the default current directory is the root directory
@@ -47,6 +48,7 @@
// At the moment the VFS protocol just has import_stat, but could be extended to other methods
typedef struct _mp_vfs_proto_t {
+ MP_PROTOCOL_HEAD
mp_import_stat_t (*import_stat)(void *self, const char *path);
} mp_vfs_proto_t;
diff --git a/extmod/vfs_fat.c b/extmod/vfs_fat.c
index 945ba9e80..9cb4d9842 100644
--- a/extmod/vfs_fat.c
+++ b/extmod/vfs_fat.c
@@ -39,7 +39,7 @@
#include "lib/oofatfs/ff.h"
#include "extmod/vfs_fat.h"
#include "lib/timeutils/timeutils.h"
-
+#include "supervisor/filesystem.h"
#include "supervisor/shared/translate.h"
#if _MAX_SS == _MIN_SS
@@ -65,8 +65,8 @@ mp_import_stat_t fat_vfs_import_stat(void *vfs_in, const char *path) {
return MP_IMPORT_STAT_NO_EXIST;
}
-STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 1, 1, false);
+STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 1, 1, false);
// create new object
fs_user_mount_t *vfs = m_new_obj(fs_user_mount_t);
@@ -99,6 +99,12 @@ STATIC mp_obj_t fat_vfs_make_new(const mp_obj_type_t *type, size_t n_args, size_
return MP_OBJ_FROM_PTR(vfs);
}
+STATIC void verify_fs_writable(fs_user_mount_t *vfs) {
+ if (!filesystem_is_writable_by_python(vfs)) {
+ mp_raise_OSError(MP_EROFS);
+ }
+}
+
#if _FS_REENTRANT
STATIC mp_obj_t fat_vfs_del(mp_obj_t self_in) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(self_in);
@@ -111,7 +117,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_del_obj, fat_vfs_del);
STATIC mp_obj_t fat_vfs_mkfs(mp_obj_t bdev_in) {
// create new object
- fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, 0, &bdev_in));
+ fs_user_mount_t *vfs = MP_OBJ_TO_PTR(fat_vfs_make_new(&mp_fat_vfs_type, 1, &bdev_in, NULL));
// make the filesystem
uint8_t working_buf[_MAX_SS];
@@ -201,6 +207,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(fat_vfs_ilistdir_obj, 1, 2, fat_vfs_i
STATIC mp_obj_t fat_vfs_remove_internal(mp_obj_t vfs_in, mp_obj_t path_in, mp_int_t attr) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
+ verify_fs_writable(self);
const char *path = mp_obj_str_get_str(path_in);
FILINFO fno;
@@ -235,9 +242,26 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(fat_vfs_rmdir_obj, fat_vfs_rmdir);
STATIC mp_obj_t fat_vfs_rename(mp_obj_t vfs_in, mp_obj_t path_in, mp_obj_t path_out) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
+ verify_fs_writable(self);
const char *old_path = mp_obj_str_get_str(path_in);
const char *new_path = mp_obj_str_get_str(path_out);
- FRESULT res = f_rename(&self->fatfs, old_path, new_path);
+
+ // Check to see if we're moving a directory into itself. This occurs when we're moving a
+ // directory where the old path is a prefix of the new and the next character is a "/" and thus
+ // preserves the original directory name.
+ FILINFO fno;
+ FRESULT res = f_stat(&self->fatfs, old_path, &fno);
+ if (res != FR_OK) {
+ mp_raise_OSError(fresult_to_errno_table[res]);
+ }
+ if ((fno.fattrib & AM_DIR) != 0 &&
+ strlen(new_path) > strlen(old_path) &&
+ new_path[strlen(old_path)] == '/' &&
+ strncmp(old_path, new_path, strlen(old_path)) == 0) {
+ mp_raise_OSError(MP_EINVAL);
+ }
+
+ res = f_rename(&self->fatfs, old_path, new_path);
if (res == FR_EXIST) {
// if new_path exists then try removing it (but only if it's a file)
fat_vfs_remove_internal(vfs_in, path_out, 0); // 0 == file attribute
@@ -255,6 +279,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_3(fat_vfs_rename_obj, fat_vfs_rename);
STATIC mp_obj_t fat_vfs_mkdir(mp_obj_t vfs_in, mp_obj_t path_o) {
mp_obj_fat_vfs_t *self = MP_OBJ_TO_PTR(vfs_in);
+ verify_fs_writable(self);
const char *path = mp_obj_str_get_str(path_o);
FRESULT res = f_mkdir(&self->fatfs, path);
if (res == FR_OK) {
@@ -320,14 +345,21 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
} else {
mode |= MP_S_IFREG;
}
- mp_uint_t seconds = timeutils_seconds_since_epoch(
- 1980 + ((fno.fdate >> 9) & 0x7f),
- (fno.fdate >> 5) & 0x0f,
- fno.fdate & 0x1f,
- (fno.ftime >> 11) & 0x1f,
- (fno.ftime >> 5) & 0x3f,
- 2 * (fno.ftime & 0x1f)
- );
+#if MICROPY_LONGINT_IMPL == MICROPY_LONGINT_IMPL_NONE
+ // On non-longint builds, the number of seconds since 1970 (epoch) is too
+ // large to fit in a smallint, so just return 31-DEC-1999 (0).
+ mp_obj_t seconds = MP_OBJ_NEW_SMALL_INT(946684800);
+#else
+ mp_obj_t seconds = mp_obj_new_int_from_uint(
+ timeutils_seconds_since_epoch(
+ 1980 + ((fno.fdate >> 9) & 0x7f),
+ (fno.fdate >> 5) & 0x0f,
+ fno.fdate & 0x1f,
+ (fno.ftime >> 11) & 0x1f,
+ (fno.ftime >> 5) & 0x3f,
+ 2 * (fno.ftime & 0x1f)
+ ));
+#endif
t->items[0] = MP_OBJ_NEW_SMALL_INT(mode); // st_mode
t->items[1] = MP_OBJ_NEW_SMALL_INT(0); // st_ino
t->items[2] = MP_OBJ_NEW_SMALL_INT(0); // st_dev
@@ -335,9 +367,9 @@ STATIC mp_obj_t fat_vfs_stat(mp_obj_t vfs_in, mp_obj_t path_in) {
t->items[4] = MP_OBJ_NEW_SMALL_INT(0); // st_uid
t->items[5] = MP_OBJ_NEW_SMALL_INT(0); // st_gid
t->items[6] = mp_obj_new_int_from_uint(fno.fsize); // st_size
- t->items[7] = mp_obj_new_int_from_uint(seconds); // st_atime
- t->items[8] = mp_obj_new_int_from_uint(seconds); // st_mtime
- t->items[9] = mp_obj_new_int_from_uint(seconds); // st_ctime
+ t->items[7] = seconds; // st_atime
+ t->items[8] = seconds; // st_mtime
+ t->items[9] = seconds; // st_ctime
return MP_OBJ_FROM_PTR(t);
}
@@ -419,6 +451,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(fat_vfs_getlabel_obj, vfs_fat_getlabel);
STATIC mp_obj_t vfs_fat_setlabel(mp_obj_t self_in, mp_obj_t label_in) {
fs_user_mount_t *self = MP_OBJ_TO_PTR(self_in);
+ verify_fs_writable(self);
const char *label_str = mp_obj_str_get_str(label_in);
FRESULT res = f_setlabel(&self->fatfs, label_str);
if (res != FR_OK) {
@@ -462,6 +495,7 @@ STATIC const mp_rom_map_elem_t fat_vfs_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(fat_vfs_locals_dict, fat_vfs_locals_dict_table);
STATIC const mp_vfs_proto_t fat_vfs_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_vfs)
.import_stat = fat_vfs_import_stat,
};
diff --git a/extmod/vfs_fat.h b/extmod/vfs_fat.h
index dd5e5ffcb..08b03d0d1 100644
--- a/extmod/vfs_fat.h
+++ b/extmod/vfs_fat.h
@@ -38,6 +38,8 @@
#define FSUSER_NO_FILESYSTEM (0x0008) // the block device has no filesystem on it
// Device is writable over USB and read-only to MicroPython.
#define FSUSER_USB_WRITABLE (0x0010)
+// Bit set when the above flag is checked before opening a file for write.
+#define FSUSER_CONCURRENT_WRITE_PROTECTED (0x0020)
typedef struct _fs_user_mount_t {
mp_obj_base_t base;
diff --git a/extmod/vfs_fat_file.c b/extmod/vfs_fat_file.c
index e3eebc9c4..422f057a8 100644
--- a/extmod/vfs_fat_file.c
+++ b/extmod/vfs_fat_file.c
@@ -28,12 +28,14 @@
#if MICROPY_VFS && MICROPY_VFS_FAT
#include <stdio.h>
+#include <string.h>
#include "py/runtime.h"
#include "py/stream.h"
#include "py/mperrno.h"
#include "lib/oofatfs/ff.h"
#include "extmod/vfs_fat.h"
+#include "supervisor/filesystem.h"
// this table converts from FRESULT to POSIX errno
const byte fresult_to_errno_table[20] = {
@@ -186,16 +188,36 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
break;
}
}
+ assert(vfs != NULL);
+ if ((mode & FA_WRITE) != 0 && !filesystem_is_writable_by_python(vfs)) {
+ mp_raise_OSError(MP_EROFS);
+ }
pyb_file_obj_t *o = m_new_obj_with_finaliser(pyb_file_obj_t);
o->base.type = type;
const char *fname = mp_obj_str_get_str(args[0].u_obj);
- assert(vfs != NULL);
FRESULT res = f_open(&vfs->fatfs, &o->fp, fname, mode);
if (res != FR_OK) {
m_del_obj(pyb_file_obj_t, o);
- mp_raise_OSError(fresult_to_errno_table[res]);
+ mp_raise_OSError_errno_str(fresult_to_errno_table[res], args[0].u_obj);
+ }
+ // If we're reading, turn on fast seek.
+ if (mode == FA_READ) {
+ // one call to determine how much space we need.
+ DWORD temp_table[2];
+ temp_table[0] = 2;
+ o->fp.cltbl = temp_table;
+ f_lseek(&o->fp, CREATE_LINKMAP);
+ DWORD size = (temp_table[0] + 1) * 2;
+ o->fp.cltbl = m_malloc_maybe(size * sizeof(DWORD), false);
+ if (o->fp.cltbl != NULL) {
+ o->fp.cltbl[0] = size;
+ res = f_lseek(&o->fp, CREATE_LINKMAP);
+ if (res != FR_OK) {
+ o->fp.cltbl = NULL;
+ }
+ }
}
// for 'a' mode, we must begin at the end of the file
@@ -206,9 +228,9 @@ STATIC mp_obj_t file_open(fs_user_mount_t *vfs, const mp_obj_type_t *type, mp_ar
return MP_OBJ_FROM_PTR(o);
}
-STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t file_obj_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
mp_arg_val_t arg_vals[FILE_OPEN_NUM_ARGS];
- mp_arg_parse_all_kw_array(n_args, n_kw, args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
+ mp_arg_parse_all(n_args, args, kw_args, FILE_OPEN_NUM_ARGS, file_open_args, arg_vals);
return file_open(NULL, type, arg_vals);
}
@@ -233,6 +255,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
#if MICROPY_PY_IO_FILEIO
STATIC const mp_stream_p_t fileio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = file_obj_read,
.write = file_obj_write,
.ioctl = file_obj_ioctl,
@@ -251,6 +274,7 @@ const mp_obj_type_t mp_type_vfs_fat_fileio = {
#endif
STATIC const mp_stream_p_t textio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = file_obj_read,
.write = file_obj_write,
.ioctl = file_obj_ioctl,
diff --git a/extmod/vfs_posix.c b/extmod/vfs_posix.c
index 39e197f29..56a5de303 100644
--- a/extmod/vfs_posix.c
+++ b/extmod/vfs_posix.c
@@ -90,8 +90,8 @@ STATIC mp_import_stat_t mp_vfs_posix_import_stat(void *self_in, const char *path
return MP_IMPORT_STAT_NO_EXIST;
}
-STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
- mp_arg_check_num(n_args, n_kw, 0, 1, false);
+STATIC mp_obj_t vfs_posix_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
+ mp_arg_check_num(n_args, kw_args, 0, 1, false);
mp_obj_vfs_posix_t *vfs = m_new_obj(mp_obj_vfs_posix_t);
vfs->base.type = type;
@@ -350,6 +350,7 @@ STATIC const mp_rom_map_elem_t vfs_posix_locals_dict_table[] = {
STATIC MP_DEFINE_CONST_DICT(vfs_posix_locals_dict, vfs_posix_locals_dict_table);
STATIC const mp_vfs_proto_t vfs_posix_proto = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_vfs)
.import_stat = mp_vfs_posix_import_stat,
};
diff --git a/extmod/vfs_posix_file.c b/extmod/vfs_posix_file.c
index 3eca47eb4..be455fa28 100644
--- a/extmod/vfs_posix_file.c
+++ b/extmod/vfs_posix_file.c
@@ -109,14 +109,14 @@ mp_obj_t mp_vfs_posix_file_open(const mp_obj_type_t *type, mp_obj_t file_in, mp_
return MP_OBJ_FROM_PTR(o);
}
-STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
+STATIC mp_obj_t vfs_posix_file_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_file, MP_ARG_OBJ | MP_ARG_REQUIRED, {.u_rom_obj = MP_ROM_PTR(&mp_const_none_obj)} },
{ MP_QSTR_mode, MP_ARG_OBJ, {.u_rom_obj = MP_ROM_QSTR(MP_QSTR_r)} },
};
mp_arg_val_t arg_vals[MP_ARRAY_SIZE(allowed_args)];
- mp_arg_parse_all_kw_array(n_args, n_kw, args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals);
+ mp_arg_parse_all(n_args, args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, arg_vals);
return mp_vfs_posix_file_open(type, arg_vals[0].u_obj, arg_vals[1].u_obj);
}
@@ -220,6 +220,7 @@ STATIC MP_DEFINE_CONST_DICT(rawfile_locals_dict, rawfile_locals_dict_table);
#if MICROPY_PY_IO_FILEIO
STATIC const mp_stream_p_t fileio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = vfs_posix_file_read,
.write = vfs_posix_file_write,
.ioctl = vfs_posix_file_ioctl,
@@ -238,6 +239,7 @@ const mp_obj_type_t mp_type_vfs_posix_fileio = {
#endif
STATIC const mp_stream_p_t textio_stream_p = {
+ MP_PROTO_IMPLEMENT(MP_QSTR_protocol_stream)
.read = vfs_posix_file_read,
.write = vfs_posix_file_write,
.ioctl = vfs_posix_file_ioctl,
diff --git a/extmod/virtpin.c b/extmod/virtpin.c
index dbfa21d66..559f99265 100644
--- a/extmod/virtpin.c
+++ b/extmod/virtpin.c
@@ -25,15 +25,16 @@
*/
#include "extmod/virtpin.h"
+#include "py/proto.h"
int mp_virtual_pin_read(mp_obj_t 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;
+ const mp_pin_p_t *pin_p = mp_proto_get(MP_QSTR_protocol_pin, s);
return pin_p->ioctl(pin, MP_PIN_READ, 0, NULL);
}
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_pin_p_t *pin_p = (mp_pin_p_t*)s->type->protocol;
+ const mp_pin_p_t *pin_p = mp_proto_get(MP_QSTR_protocol_pin, s);
pin_p->ioctl(pin, MP_PIN_WRITE, value, NULL);
}
diff --git a/extmod/virtpin.h b/extmod/virtpin.h
index 706affc19..591249e48 100644
--- a/extmod/virtpin.h
+++ b/extmod/virtpin.h
@@ -27,6 +27,7 @@
#define MICROPY_INCLUDED_EXTMOD_VIRTPIN_H
#include "py/obj.h"
+#include "py/proto.h"
#define MP_PIN_READ (1)
#define MP_PIN_WRITE (2)
@@ -35,6 +36,7 @@
// Pin protocol
typedef struct _mp_pin_p_t {
+ MP_PROTOCOL_HEAD
mp_uint_t (*ioctl)(mp_obj_t obj, mp_uint_t request, uintptr_t arg, int *errcode);
} mp_pin_p_t;