17 changes: 17 additions & 0 deletions examples/usercmodule/cppexample/example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
extern "C" {
#include <examplemodule.h>

// Here we implement the function using C++ code, but since it's
// declaration has to be compatible with C everything goes in extern "C" scope.
mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj) {
// Prove we have (at least) C++11 features.
const auto a = mp_obj_get_int(a_obj);
const auto b = mp_obj_get_int(b_obj);
const auto sum = [&]() {
return mp_obj_new_int(a + b);
} ();
// Prove we're being scanned for QSTRs.
mp_obj_t tup[] = {sum, MP_ROM_QSTR(MP_QSTR_hellocpp)};
return mp_obj_new_tuple(2, tup);
}
}
25 changes: 25 additions & 0 deletions examples/usercmodule/cppexample/examplemodule.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <examplemodule.h>

// Define a Python reference to the function we'll make available.
// See example.cpp for the definition.
STATIC MP_DEFINE_CONST_FUN_OBJ_2(cppfunc_obj, cppfunc);

// Define all properties of the module.
// Table entries are key/value pairs of the attribute name (a string)
// and the MicroPython object reference.
// All identifiers and strings are written as MP_QSTR_xxx and will be
// optimized to word-sized integers by the build system (interned strings).
STATIC const mp_rom_map_elem_t cppexample_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_cppexample) },
{ MP_ROM_QSTR(MP_QSTR_cppfunc), MP_ROM_PTR(&cppfunc_obj) },
};
STATIC MP_DEFINE_CONST_DICT(cppexample_module_globals, cppexample_module_globals_table);

// Define module object.
const mp_obj_module_t cppexample_user_cmodule = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&cppexample_module_globals,
};

// Register the module to make it available in Python.
MP_REGISTER_MODULE(MP_QSTR_cppexample, cppexample_user_cmodule, MODULE_CPPEXAMPLE_ENABLED);
5 changes: 5 additions & 0 deletions examples/usercmodule/cppexample/examplemodule.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// Include MicroPython API.
#include "py/runtime.h"

// Declare the function we'll make available in Python as cppexample.cppfunc().
extern mp_obj_t cppfunc(mp_obj_t a_obj, mp_obj_t b_obj);
12 changes: 12 additions & 0 deletions examples/usercmodule/cppexample/micropython.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CPPEXAMPLE_MOD_DIR := $(USERMOD_DIR)

# Add our source files to the respective variables.
SRC_USERMOD += $(CPPEXAMPLE_MOD_DIR)/examplemodule.c
SRC_USERMOD_CXX += $(CPPEXAMPLE_MOD_DIR)/example.cpp

# Add our module directory to the include path.
CFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)
CXXFLAGS_USERMOD += -I$(CPPEXAMPLE_MOD_DIR)

# We use C++ features so have to link against the standard library.
LDFLAGS_USERMOD += -lstdc++
117 changes: 117 additions & 0 deletions extmod/axtls-include/config.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*
* Automatically generated header file: don't edit
*/

#define HAVE_DOT_CONFIG 1
#define CONFIG_PLATFORM_LINUX 1
#undef CONFIG_PLATFORM_CYGWIN
#undef CONFIG_PLATFORM_WIN32

/*
* General Configuration
*/
#define PREFIX "/usr/local"
#undef CONFIG_DEBUG
#undef CONFIG_STRIP_UNWANTED_SECTIONS
#undef CONFIG_VISUAL_STUDIO_7_0
#undef CONFIG_VISUAL_STUDIO_8_0
#undef CONFIG_VISUAL_STUDIO_10_0
#define CONFIG_VISUAL_STUDIO_7_0_BASE ""
#define CONFIG_VISUAL_STUDIO_8_0_BASE ""
#define CONFIG_VISUAL_STUDIO_10_0_BASE ""
#define CONFIG_EXTRA_CFLAGS_OPTIONS ""
#define CONFIG_EXTRA_LDFLAGS_OPTIONS ""

/*
* SSL Library
*/
#undef CONFIG_SSL_SERVER_ONLY
#undef CONFIG_SSL_CERT_VERIFICATION
#undef CONFIG_SSL_FULL_MODE
#define CONFIG_SSL_SKELETON_MODE 1
#define CONFIG_SSL_ENABLE_SERVER 1
#define CONFIG_SSL_ENABLE_CLIENT 1
#undef CONFIG_SSL_DIAGNOSTICS
#define CONFIG_SSL_PROT_LOW 1
#undef CONFIG_SSL_PROT_MEDIUM
#undef CONFIG_SSL_PROT_HIGH
#define CONFIG_SSL_AES 1
#define CONFIG_SSL_USE_DEFAULT_KEY 1
#define CONFIG_SSL_PRIVATE_KEY_LOCATION ""
#define CONFIG_SSL_PRIVATE_KEY_PASSWORD ""
#define CONFIG_SSL_X509_CERT_LOCATION ""
#undef CONFIG_SSL_GENERATE_X509_CERT
#define CONFIG_SSL_X509_COMMON_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_NAME ""
#define CONFIG_SSL_X509_ORGANIZATION_UNIT_NAME ""
#undef CONFIG_SSL_HAS_PEM
#undef CONFIG_SSL_USE_PKCS12
#define CONFIG_SSL_EXPIRY_TIME
#define CONFIG_X509_MAX_CA_CERTS 0
#define CONFIG_SSL_MAX_CERTS 3
#undef CONFIG_SSL_CTX_MUTEXING
#undef CONFIG_USE_DEV_URANDOM
#undef CONFIG_WIN32_USE_CRYPTO_LIB
#undef CONFIG_OPENSSL_COMPATIBLE
#undef CONFIG_PERFORMANCE_TESTING
#undef CONFIG_SSL_TEST
#undef CONFIG_AXTLSWRAP
#undef CONFIG_AXHTTPD
#undef CONFIG_HTTP_STATIC_BUILD
#define CONFIG_HTTP_PORT
#define CONFIG_HTTP_HTTPS_PORT
#define CONFIG_HTTP_SESSION_CACHE_SIZE
#define CONFIG_HTTP_WEBROOT ""
#define CONFIG_HTTP_TIMEOUT
#undef CONFIG_HTTP_HAS_CGI
#define CONFIG_HTTP_CGI_EXTENSIONS ""
#undef CONFIG_HTTP_ENABLE_LUA
#define CONFIG_HTTP_LUA_PREFIX ""
#undef CONFIG_HTTP_BUILD_LUA
#define CONFIG_HTTP_CGI_LAUNCHER ""
#undef CONFIG_HTTP_DIRECTORIES
#undef CONFIG_HTTP_HAS_AUTHORIZATION
#undef CONFIG_HTTP_HAS_IPV6
#undef CONFIG_HTTP_ENABLE_DIFFERENT_USER
#define CONFIG_HTTP_USER ""
#undef CONFIG_HTTP_VERBOSE
#undef CONFIG_HTTP_IS_DAEMON

/*
* Language Bindings
*/
#undef CONFIG_BINDINGS
#undef CONFIG_CSHARP_BINDINGS
#undef CONFIG_VBNET_BINDINGS
#define CONFIG_DOT_NET_FRAMEWORK_BASE ""
#undef CONFIG_JAVA_BINDINGS
#define CONFIG_JAVA_HOME ""
#undef CONFIG_PERL_BINDINGS
#define CONFIG_PERL_CORE ""
#define CONFIG_PERL_LIB ""
#undef CONFIG_LUA_BINDINGS
#define CONFIG_LUA_CORE ""

/*
* Samples
*/
#undef CONFIG_SAMPLES
#undef CONFIG_C_SAMPLES
#undef CONFIG_CSHARP_SAMPLES
#undef CONFIG_VBNET_SAMPLES
#undef CONFIG_JAVA_SAMPLES
#undef CONFIG_PERL_SAMPLES
#undef CONFIG_LUA_SAMPLES
#undef CONFIG_BIGINT_CLASSICAL
#undef CONFIG_BIGINT_MONTGOMERY
#undef CONFIG_BIGINT_BARRETT
#undef CONFIG_BIGINT_CRT
#undef CONFIG_BIGINT_KARATSUBA
#define MUL_KARATSUBA_THRESH
#define SQU_KARATSUBA_THRESH
#undef CONFIG_BIGINT_SLIDING_WINDOW
#undef CONFIG_BIGINT_SQUARE
#undef CONFIG_BIGINT_CHECK_ON
#undef CONFIG_INTEGER_32BIT
#undef CONFIG_INTEGER_16BIT
#undef CONFIG_INTEGER_8BIT
1 change: 1 addition & 0 deletions extmod/axtls-include/version.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#define AXTLS_VERSION "(no version)"
3 changes: 2 additions & 1 deletion extmod/crypto-algorithms/sha256.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/*********************************************************************
* Source: https://github.com/B-Con/crypto-algorithms
* Filename: sha256.c
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Copyright: This code is released into the public domain.
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Implementation of the SHA-256 hashing algorithm.
SHA-256 is one of the three algorithms in the SHA2
Expand Down
3 changes: 2 additions & 1 deletion extmod/crypto-algorithms/sha256.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
/*********************************************************************
* Source: https://github.com/B-Con/crypto-algorithms
* Filename: sha256.h
* Author: Brad Conte (brad AT bradconte.com)
* Copyright:
* Copyright: This code is released into the public domain.
* Disclaimer: This code is presented "as is" without any guarantees.
* Details: Defines the API for the corresponding SHA1 implementation.
*********************************************************************/
Expand Down
93 changes: 93 additions & 0 deletions extmod/extmod.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# CMake fragment for MicroPython extmod component

set(MICROPY_EXTMOD_DIR "${MICROPY_DIR}/extmod")
set(MICROPY_OOFATFS_DIR "${MICROPY_DIR}/lib/oofatfs")

set(MICROPY_SOURCE_EXTMOD
${MICROPY_DIR}/lib/embed/abort_.c
${MICROPY_DIR}/lib/utils/printf.c
${MICROPY_EXTMOD_DIR}/machine_i2c.c
${MICROPY_EXTMOD_DIR}/machine_mem.c
${MICROPY_EXTMOD_DIR}/machine_pulse.c
${MICROPY_EXTMOD_DIR}/machine_signal.c
${MICROPY_EXTMOD_DIR}/machine_spi.c
${MICROPY_EXTMOD_DIR}/modbluetooth.c
${MICROPY_EXTMOD_DIR}/modbtree.c
${MICROPY_EXTMOD_DIR}/modframebuf.c
${MICROPY_EXTMOD_DIR}/modonewire.c
${MICROPY_EXTMOD_DIR}/moduasyncio.c
${MICROPY_EXTMOD_DIR}/modubinascii.c
${MICROPY_EXTMOD_DIR}/moducryptolib.c
${MICROPY_EXTMOD_DIR}/moductypes.c
${MICROPY_EXTMOD_DIR}/moduhashlib.c
${MICROPY_EXTMOD_DIR}/moduheapq.c
${MICROPY_EXTMOD_DIR}/modujson.c
${MICROPY_EXTMOD_DIR}/modurandom.c
${MICROPY_EXTMOD_DIR}/modure.c
${MICROPY_EXTMOD_DIR}/moduselect.c
${MICROPY_EXTMOD_DIR}/modussl_axtls.c
${MICROPY_EXTMOD_DIR}/modussl_mbedtls.c
${MICROPY_EXTMOD_DIR}/modutimeq.c
${MICROPY_EXTMOD_DIR}/moduwebsocket.c
${MICROPY_EXTMOD_DIR}/moduzlib.c
${MICROPY_EXTMOD_DIR}/modwebrepl.c
${MICROPY_EXTMOD_DIR}/uos_dupterm.c
${MICROPY_EXTMOD_DIR}/utime_mphal.c
${MICROPY_EXTMOD_DIR}/vfs.c
${MICROPY_EXTMOD_DIR}/vfs_blockdev.c
${MICROPY_EXTMOD_DIR}/vfs_fat.c
${MICROPY_EXTMOD_DIR}/vfs_fat_diskio.c
${MICROPY_EXTMOD_DIR}/vfs_fat_file.c
${MICROPY_EXTMOD_DIR}/vfs_lfs.c
${MICROPY_EXTMOD_DIR}/vfs_posix.c
${MICROPY_EXTMOD_DIR}/vfs_posix_file.c
${MICROPY_EXTMOD_DIR}/vfs_reader.c
${MICROPY_EXTMOD_DIR}/virtpin.c
${MICROPY_EXTMOD_DIR}/nimble/modbluetooth_nimble.c
)

# Library for btree module and associated code

set(MICROPY_LIB_BERKELEY_DIR "${MICROPY_DIR}/lib/berkeley-db-1.xx")

if(EXISTS "${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c")
add_library(micropy_extmod_btree OBJECT
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_close.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_conv.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_debug.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_delete.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_get.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_open.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_overflow.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_page.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_put.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_search.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_seq.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_split.c
${MICROPY_LIB_BERKELEY_DIR}/btree/bt_utils.c
${MICROPY_LIB_BERKELEY_DIR}/mpool/mpool.c
)

target_include_directories(micropy_extmod_btree PRIVATE
${MICROPY_LIB_BERKELEY_DIR}/PORT/include
)

target_compile_definitions(micropy_extmod_btree PRIVATE
__DBINTERFACE_PRIVATE=1
mpool_error=printf
abort=abort_
"virt_fd_t=void*"
)

# The include directories and compile definitions below are needed to build
# modbtree.c and should be added to the main MicroPython target.

list(APPEND MICROPY_INC_CORE
"${MICROPY_LIB_BERKELEY_DIR}/PORT/include"
)

list(APPEND MICROPY_DEF_CORE
__DBINTERFACE_PRIVATE=1
"virt_fd_t=void*"
)
endif()
234 changes: 234 additions & 0 deletions extmod/extmod.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
# This makefile fragment provides rules to build 3rd-party components for extmod modules

################################################################################
# VFS FAT FS

OOFATFS_DIR = lib/oofatfs

# this sets the config file for FatFs
CFLAGS_MOD += -DFFCONF_H=\"$(OOFATFS_DIR)/ffconf.h\"

ifeq ($(MICROPY_VFS_FAT),1)
CFLAGS_MOD += -DMICROPY_VFS_FAT=1
SRC_MOD += $(addprefix $(OOFATFS_DIR)/,\
ff.c \
ffunicode.c \
)
endif

################################################################################
# VFS littlefs

LITTLEFS_DIR = lib/littlefs

ifeq ($(MICROPY_VFS_LFS1),1)
CFLAGS_MOD += -DMICROPY_VFS_LFS1=1
CFLAGS_MOD += -DLFS1_NO_MALLOC -DLFS1_NO_DEBUG -DLFS1_NO_WARN -DLFS1_NO_ERROR -DLFS1_NO_ASSERT
SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
lfs1.c \
lfs1_util.c \
)
else
CFLAGS_MOD += -DMICROPY_VFS_LFS1=0
endif

ifeq ($(MICROPY_VFS_LFS2),1)
CFLAGS_MOD += -DMICROPY_VFS_LFS2=1
CFLAGS_MOD += -DLFS2_NO_MALLOC -DLFS2_NO_DEBUG -DLFS2_NO_WARN -DLFS2_NO_ERROR -DLFS2_NO_ASSERT
SRC_MOD += $(addprefix $(LITTLEFS_DIR)/,\
lfs2.c \
lfs2_util.c \
)
else
CFLAGS_MOD += -DMICROPY_VFS_LFS2=0

$(BUILD)/$(LITTLEFS_DIR)/lfs2.o: CFLAGS += -Wno-missing-field-initializers
endif

################################################################################
# ussl

ifeq ($(MICROPY_PY_USSL),1)
CFLAGS_MOD += -DMICROPY_PY_USSL=1
ifeq ($(MICROPY_SSL_AXTLS),1)
CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I$(TOP)/lib/axtls/ssl -I$(TOP)/lib/axtls/crypto -I$(TOP)/extmod/axtls-include
AXTLS_DIR = lib/axtls
$(BUILD)/$(AXTLS_DIR)/%.o: CFLAGS += -Wno-all -Wno-unused-parameter -Wno-uninitialized -Wno-sign-compare -Wno-old-style-definition -Dmp_stream_errno=errno $(AXTLS_DEFS_EXTRA)
SRC_MOD += $(addprefix $(AXTLS_DIR)/,\
ssl/asn1.c \
ssl/loader.c \
ssl/tls1.c \
ssl/tls1_svr.c \
ssl/tls1_clnt.c \
ssl/x509.c \
crypto/aes.c \
crypto/bigint.c \
crypto/crypto_misc.c \
crypto/hmac.c \
crypto/md5.c \
crypto/rsa.c \
crypto/sha1.c \
)
else ifeq ($(MICROPY_SSL_MBEDTLS),1)
MBEDTLS_DIR = lib/mbedtls
CFLAGS_MOD += -DMICROPY_SSL_MBEDTLS=1 -I$(TOP)/$(MBEDTLS_DIR)/include
SRC_MOD += $(addprefix $(MBEDTLS_DIR)/library/,\
aes.c \
aesni.c \
arc4.c \
asn1parse.c \
asn1write.c \
base64.c \
bignum.c \
blowfish.c \
camellia.c \
ccm.c \
certs.c \
chacha20.c \
chachapoly.c \
cipher.c \
cipher_wrap.c \
cmac.c \
ctr_drbg.c \
debug.c \
des.c \
dhm.c \
ecdh.c \
ecdsa.c \
ecjpake.c \
ecp.c \
ecp_curves.c \
entropy.c \
entropy_poll.c \
error.c \
gcm.c \
havege.c \
hmac_drbg.c \
md2.c \
md4.c \
md5.c \
md.c \
md_wrap.c \
oid.c \
padlock.c \
pem.c \
pk.c \
pkcs11.c \
pkcs12.c \
pkcs5.c \
pkparse.c \
pk_wrap.c \
pkwrite.c \
platform.c \
platform_util.c \
poly1305.c \
ripemd160.c \
rsa.c \
rsa_internal.c \
sha1.c \
sha256.c \
sha512.c \
ssl_cache.c \
ssl_ciphersuites.c \
ssl_cli.c \
ssl_cookie.c \
ssl_srv.c \
ssl_ticket.c \
ssl_tls.c \
timing.c \
x509.c \
x509_create.c \
x509_crl.c \
x509_crt.c \
x509_csr.c \
x509write_crt.c \
x509write_csr.c \
xtea.c \
)
endif
endif

################################################################################
# lwip

ifeq ($(MICROPY_PY_LWIP),1)
# A port should add an include path where lwipopts.h can be found (eg extmod/lwip-include)
LWIP_DIR = lib/lwip/src
INC += -I$(TOP)/$(LWIP_DIR)/include
CFLAGS_MOD += -DMICROPY_PY_LWIP=1
$(BUILD)/$(LWIP_DIR)/core/ipv4/dhcp.o: CFLAGS_MOD += -Wno-address
SRC_MOD += extmod/modlwip.c lib/netutils/netutils.c
SRC_MOD += $(addprefix $(LWIP_DIR)/,\
apps/mdns/mdns.c \
core/def.c \
core/dns.c \
core/inet_chksum.c \
core/init.c \
core/ip.c \
core/mem.c \
core/memp.c \
core/netif.c \
core/pbuf.c \
core/raw.c \
core/stats.c \
core/sys.c \
core/tcp.c \
core/tcp_in.c \
core/tcp_out.c \
core/timeouts.c \
core/udp.c \
core/ipv4/autoip.c \
core/ipv4/dhcp.c \
core/ipv4/etharp.c \
core/ipv4/icmp.c \
core/ipv4/igmp.c \
core/ipv4/ip4_addr.c \
core/ipv4/ip4.c \
core/ipv4/ip4_frag.c \
core/ipv6/dhcp6.c \
core/ipv6/ethip6.c \
core/ipv6/icmp6.c \
core/ipv6/inet6.c \
core/ipv6/ip6_addr.c \
core/ipv6/ip6.c \
core/ipv6/ip6_frag.c \
core/ipv6/mld6.c \
core/ipv6/nd6.c \
netif/ethernet.c \
)
ifeq ($(MICROPY_PY_LWIP_SLIP),1)
CFLAGS_MOD += -DMICROPY_PY_LWIP_SLIP=1
SRC_MOD += $(LWIP_DIR)/netif/slipif.c
endif
endif

################################################################################
# btree

ifeq ($(MICROPY_PY_BTREE),1)
BTREE_DIR = lib/berkeley-db-1.xx
BTREE_DEFS = -D__DBINTERFACE_PRIVATE=1 -Dmpool_error=printf -Dabort=abort_ "-Dvirt_fd_t=void*" $(BTREE_DEFS_EXTRA)
INC += -I$(TOP)/$(BTREE_DIR)/PORT/include
SRC_MOD += extmod/modbtree.c
SRC_MOD += $(addprefix $(BTREE_DIR)/,\
btree/bt_close.c \
btree/bt_conv.c \
btree/bt_debug.c \
btree/bt_delete.c \
btree/bt_get.c \
btree/bt_open.c \
btree/bt_overflow.c \
btree/bt_page.c \
btree/bt_put.c \
btree/bt_search.c \
btree/bt_seq.c \
btree/bt_split.c \
btree/bt_utils.c \
mpool/mpool.c \
)
CFLAGS_MOD += -DMICROPY_PY_BTREE=1
# we need to suppress certain warnings to get berkeley-db to compile cleanly
# and we have separate BTREE_DEFS so the definitions don't interfere with other source code
$(BUILD)/$(BTREE_DIR)/%.o: CFLAGS += -Wno-old-style-definition -Wno-sign-compare -Wno-unused-parameter $(BTREE_DEFS)
$(BUILD)/extmod/modbtree.o: CFLAGS += $(BTREE_DEFS)
endif
94 changes: 0 additions & 94 deletions extmod/machine_mem.c

This file was deleted.

29 changes: 0 additions & 29 deletions extmod/machine_mem.h

This file was deleted.

67 changes: 0 additions & 67 deletions extmod/machine_pinbase.c

This file was deleted.

13 changes: 0 additions & 13 deletions extmod/machine_pinbase.h

This file was deleted.

44 changes: 0 additions & 44 deletions extmod/machine_pulse.c

This file was deleted.

16 changes: 0 additions & 16 deletions extmod/machine_pulse.h

This file was deleted.

159 changes: 0 additions & 159 deletions extmod/machine_signal.c

This file was deleted.

13 changes: 0 additions & 13 deletions extmod/machine_signal.h

This file was deleted.

25 changes: 0 additions & 25 deletions extmod/misc.h

This file was deleted.

24 changes: 16 additions & 8 deletions extmod/modbtree.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

typedef struct _mp_obj_btree_t {
mp_obj_base_t base;
mp_obj_t stream; // retain a reference to prevent GC from reclaiming it
DB *db;
mp_obj_t start_key;
mp_obj_t end_key;
Expand All @@ -31,20 +32,23 @@ typedef struct _mp_obj_btree_t {
byte next_flags;
} mp_obj_btree_t;

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_obj_type_t btree_type;
#endif

#define CHECK_ERROR(res) \
if (res == RET_ERROR) { \
mp_raise_OSError(errno); \
}

void __dbpanic(DB *db) {
printf("__dbpanic(%p)\n", db);
mp_printf(&mp_plat_print, "__dbpanic(%p)\n", db);
}

STATIC mp_obj_btree_t *btree_new(DB *db) {
STATIC mp_obj_btree_t *btree_new(DB *db, mp_obj_t stream) {
mp_obj_btree_t *o = m_new_obj(mp_obj_btree_t);
o->base.type = &btree_type;
o->stream = stream;
o->db = db;
o->start_key = mp_const_none;
o->end_key = mp_const_none;
Expand Down Expand Up @@ -226,14 +230,14 @@ 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_instance_cast_to_native_base(self_in, &btree_type);
mp_obj_btree_t *self = mp_obj_cast_to_native_base(self_in, &btree_type);
if (value == MP_OBJ_NULL) {
// delete
DBT key;
key.data = (void *)mp_obj_str_get_data(index, &key.size);
int res = __bt_delete(self->db, &key, 0);
if (res == RET_SPECIAL) {
nlr_raise(mp_obj_new_exception(&mp_type_KeyError));
mp_raise_type(&mp_type_KeyError);
}
CHECK_ERROR(res);
return mp_const_none;
Expand All @@ -243,7 +247,7 @@ STATIC mp_obj_t btree_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
key.data = (void *)mp_obj_str_get_data(index, &key.size);
int res = __bt_get(self->db, &key, &val, 0);
if (res == RET_SPECIAL) {
nlr_raise(mp_obj_new_exception(&mp_type_KeyError));
mp_raise_type(&mp_type_KeyError);
}
CHECK_ERROR(res);
return mp_obj_new_bytes(val.data, val.size);
Expand Down Expand Up @@ -274,6 +278,7 @@ STATIC mp_obj_t btree_binary_op(mp_binary_op_t op, mp_obj_t lhs_in, mp_obj_t rhs
}
}

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t btree_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&btree_close_obj) },
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&btree_flush_obj) },
Expand All @@ -298,14 +303,16 @@ STATIC const mp_obj_type_t btree_type = {
.subscr = btree_subscr,
.locals_dict = (void *)&btree_locals_dict,
};
#endif

STATIC FILEVTABLE btree_stream_fvtable = {
STATIC const FILEVTABLE btree_stream_fvtable = {
mp_stream_posix_read,
mp_stream_posix_write,
mp_stream_posix_lseek,
mp_stream_posix_fsync
};

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
static const mp_arg_t allowed_args[] = {
{ MP_QSTR_flags, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
Expand All @@ -331,11 +338,11 @@ STATIC mp_obj_t mod_btree_open(size_t n_args, const mp_obj_t *pos_args, mp_map_t
openinfo.psize = args.pagesize.u_int;
openinfo.minkeypage = args.minkeypage.u_int;

DB *db = __bt_open(pos_args[0], &btree_stream_fvtable, &openinfo, /*dflags*/ 0);
DB *db = __bt_open(MP_OBJ_TO_PTR(pos_args[0]), &btree_stream_fvtable, &openinfo, /*dflags*/ 0);
if (db == NULL) {
mp_raise_OSError(errno);
}
return MP_OBJ_FROM_PTR(btree_new(db));
return MP_OBJ_FROM_PTR(btree_new(db, pos_args[0]));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_btree_open_obj, 1, mod_btree_open);

Expand All @@ -352,5 +359,6 @@ const mp_obj_module_t mp_module_btree = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_btree_globals,
};
#endif

#endif // MICROPY_PY_BTREE
104 changes: 58 additions & 46 deletions extmod/modframebuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ typedef struct _mp_obj_framebuf_t {
uint8_t format;
} mp_obj_framebuf_t;

typedef void (*setpixel_t)(const mp_obj_framebuf_t *, int, int, uint32_t);
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);
#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_obj_type_t mp_type_framebuf;
#endif

typedef void (*setpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, uint32_t);
typedef uint32_t (*getpixel_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int);
typedef void (*fill_rect_t)(const mp_obj_framebuf_t *, unsigned int, unsigned int, unsigned int, unsigned int, uint32_t);

typedef struct _mp_framebuf_p_t {
MP_PROTOCOL_HEAD
setpixel_t setpixel;
getpixel_t getpixel;
fill_rect_t fill_rect;
Expand All @@ -44,25 +47,25 @@ typedef struct _mp_framebuf_p_t {

// Functions for MHLSB and MHMSB

STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
STATIC void mono_horiz_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
size_t index = (x + y * fb->stride) >> 3;
int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
}

STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
STATIC uint32_t mono_horiz_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
size_t index = (x + y * fb->stride) >> 3;
int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
unsigned int offset = fb->format == FRAMEBUF_MHMSB ? x & 0x07 : 7 - (x & 0x07);
return (((uint8_t *)fb->buf)[index] >> (offset)) & 0x01;
}

STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
int reverse = fb->format == FRAMEBUF_MHMSB;
int advance = fb->stride >> 3;
STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
unsigned int reverse = fb->format == FRAMEBUF_MHMSB;
unsigned int advance = fb->stride >> 3;
while (w--) {
uint8_t *b = &((uint8_t *)fb->buf)[(x >> 3) + y * advance];
int offset = reverse ? x & 7 : 7 - (x & 7);
for (int hh = h; hh; --hh) {
unsigned int offset = reverse ? x & 7 : 7 - (x & 7);
for (unsigned int hh = h; hh; --hh) {
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
b += advance;
}
Expand All @@ -72,21 +75,21 @@ STATIC void mono_horiz_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int

// Functions for MVLSB format

STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
STATIC void mvlsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
size_t index = (y >> 3) * fb->stride + x;
uint8_t offset = y & 0x07;
((uint8_t *)fb->buf)[index] = (((uint8_t *)fb->buf)[index] & ~(0x01 << offset)) | ((col != 0) << offset);
}

STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
STATIC uint32_t mvlsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
return (((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x] >> (y & 0x07)) & 0x01;
}

STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
while (h--) {
uint8_t *b = &((uint8_t *)fb->buf)[(y >> 3) * fb->stride + x];
uint8_t offset = y & 0x07;
for (int ww = w; ww; --ww) {
for (unsigned int ww = w; ww; --ww) {
*b = (*b & ~(0x01 << offset)) | ((col != 0) << offset);
++b;
}
Expand All @@ -96,18 +99,18 @@ STATIC void mvlsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, in

// Functions for RGB565 format

STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
STATIC void rgb565_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
((uint16_t *)fb->buf)[x + y * fb->stride] = col;
}

STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
STATIC uint32_t rgb565_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
return ((uint16_t *)fb->buf)[x + y * fb->stride];
}

STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
uint16_t *b = &((uint16_t *)fb->buf)[x + y * fb->stride];
while (h--) {
for (int ww = w; ww; --ww) {
for (unsigned int ww = w; ww; --ww) {
*b++ = col;
}
b += fb->stride - w;
Expand All @@ -116,31 +119,31 @@ STATIC void rgb565_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, i

// Functions for GS2_HMSB format

STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
STATIC void gs2_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
uint8_t shift = (x & 0x3) << 1;
uint8_t mask = 0x3 << shift;
uint8_t color = (col & 0x3) << shift;
*pixel = color | (*pixel & (~mask));
}

STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
STATIC uint32_t gs2_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
uint8_t pixel = ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 2];
uint8_t shift = (x & 0x3) << 1;
return (pixel >> shift) & 0x3;
}

STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
for (int xx = x; xx < x + w; xx++) {
for (int yy = y; yy < y + h; yy++) {
STATIC void gs2_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
for (unsigned int xx = x; xx < x + w; xx++) {
for (unsigned int yy = y; yy < y + h; yy++) {
gs2_hmsb_setpixel(fb, xx, yy, col);
}
}
}

// Functions for GS4_HMSB format

STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];

if (x % 2) {
Expand All @@ -150,24 +153,24 @@ STATIC void gs4_hmsb_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_
}
}

STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
STATIC uint32_t gs4_hmsb_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
if (x % 2) {
return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] & 0x0f;
}

return ((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1] >> 4;
}

STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
col &= 0x0f;
uint8_t *pixel_pair = &((uint8_t *)fb->buf)[(x + y * fb->stride) >> 1];
uint8_t col_shifted_left = col << 4;
uint8_t col_pixel_pair = col_shifted_left | col;
int pixel_count_till_next_line = (fb->stride - w) >> 1;
unsigned int pixel_count_till_next_line = (fb->stride - w) >> 1;
bool odd_x = (x % 2 == 1);

while (h--) {
int ww = w;
unsigned int ww = w;

if (odd_x && ww > 0) {
*pixel_pair = (*pixel_pair & 0xf0) | col;
Expand All @@ -191,38 +194,38 @@ STATIC void gs4_hmsb_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w,

// Functions for GS8 format

STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
STATIC void gs8_setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
*pixel = col & 0xff;
}

STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
STATIC uint32_t gs8_getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
return ((uint8_t *)fb->buf)[(x + y * fb->stride)];
}

STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, int x, int y, int w, int h, uint32_t col) {
STATIC void gs8_fill_rect(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, unsigned int w, unsigned int h, uint32_t col) {
uint8_t *pixel = &((uint8_t *)fb->buf)[(x + y * fb->stride)];
while (h--) {
memset(pixel, col, w);
pixel += fb->stride;
}
}

STATIC mp_framebuf_p_t formats[] = {
[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 const 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},
};

static inline void setpixel(const mp_obj_framebuf_t *fb, int x, int y, uint32_t col) {
static inline void setpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y, uint32_t col) {
formats[fb->format].setpixel(fb, x, y, col);
}

static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, int x, int y) {
static inline uint32_t getpixel(const mp_obj_framebuf_t *fb, unsigned int x, unsigned int y) {
return formats[fb->format].getpixel(fb, x, y);
}

Expand Down Expand Up @@ -278,18 +281,23 @@ STATIC mp_obj_t framebuf_make_new(const mp_obj_type_t *type, size_t n_args, cons
case FRAMEBUF_GS8:
break;
default:
mp_raise_ValueError(translate("invalid format"));
mp_raise_ValueError(MP_ERROR_TEXT("invalid format"));
}

return MP_OBJ_FROM_PTR(o);
}

#if !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)
STATIC const mp_obj_type_t mp_type_framebuf;
#endif

// 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_t native_framebuf = mp_obj_cast_to_native_base(framebuf_obj, &mp_type_framebuf);
mp_obj_assert_native_inited(native_framebuf);
if (native_framebuf == MP_OBJ_NULL) {
mp_raise_TypeError(NULL);
}
return MP_OBJ_TO_PTR(native_framebuf);
}

Expand Down Expand Up @@ -577,6 +585,7 @@ STATIC mp_obj_t framebuf_text(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(framebuf_text_obj, 4, 5, framebuf_text);

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t framebuf_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_fill), MP_ROM_PTR(&framebuf_fill_obj) },
{ MP_ROM_QSTR(MP_QSTR_fill_rect), MP_ROM_PTR(&framebuf_fill_rect_obj) },
Expand All @@ -598,6 +607,7 @@ STATIC const mp_obj_type_t mp_type_framebuf = {
.buffer_p = { .get_buffer = framebuf_get_buffer },
.locals_dict = (mp_obj_dict_t *)&framebuf_locals_dict,
};
#endif

// this factory function is provided for backwards compatibility with old FrameBuffer1 class
STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args) {
Expand All @@ -621,6 +631,7 @@ STATIC mp_obj_t legacy_framebuffer1(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(legacy_framebuffer1_obj, 3, 4, legacy_framebuffer1);

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t framebuf_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_framebuf) },
{ MP_ROM_QSTR(MP_QSTR_FrameBuffer), MP_ROM_PTR(&mp_type_framebuf) },
Expand All @@ -641,5 +652,6 @@ const mp_obj_module_t mp_module_framebuf = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&framebuf_module_globals,
};
#endif

#endif // MICROPY_PY_FRAMEBUF
1,449 changes: 0 additions & 1,449 deletions extmod/modlwip.c

This file was deleted.

20 changes: 10 additions & 10 deletions extmod/modonewire.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
// Low-level 1-Wire routines

#define TIMING_RESET1 (480)
#define TIMING_RESET2 (40)
#define TIMING_RESET3 (420)
#define TIMING_RESET2 (70)
#define TIMING_RESET3 (410)
#define TIMING_READ1 (5)
#define TIMING_READ2 (5)
#define TIMING_READ3 (40)
Expand All @@ -23,10 +23,10 @@
#define TIMING_WRITE3 (10)

STATIC int onewire_bus_reset(mp_hal_pin_obj_t pin) {
mp_hal_pin_write(pin, 0);
mp_hal_pin_od_low(pin);
mp_hal_delay_us(TIMING_RESET1);
uint32_t i = mp_hal_quiet_timing_enter();
mp_hal_pin_write(pin, 1);
mp_hal_pin_od_high(pin);
mp_hal_delay_us_fast(TIMING_RESET2);
int status = !mp_hal_pin_read(pin);
mp_hal_quiet_timing_exit(i);
Expand All @@ -35,11 +35,11 @@ STATIC int onewire_bus_reset(mp_hal_pin_obj_t pin) {
}

STATIC int onewire_bus_readbit(mp_hal_pin_obj_t pin) {
mp_hal_pin_write(pin, 1);
mp_hal_pin_od_high(pin);
uint32_t i = mp_hal_quiet_timing_enter();
mp_hal_pin_write(pin, 0);
mp_hal_pin_od_low(pin);
mp_hal_delay_us_fast(TIMING_READ1);
mp_hal_pin_write(pin, 1);
mp_hal_pin_od_high(pin);
mp_hal_delay_us_fast(TIMING_READ2);
int value = mp_hal_pin_read(pin);
mp_hal_quiet_timing_exit(i);
Expand All @@ -49,13 +49,13 @@ STATIC int onewire_bus_readbit(mp_hal_pin_obj_t pin) {

STATIC void onewire_bus_writebit(mp_hal_pin_obj_t pin, int value) {
uint32_t i = mp_hal_quiet_timing_enter();
mp_hal_pin_write(pin, 0);
mp_hal_pin_od_low(pin);
mp_hal_delay_us_fast(TIMING_WRITE1);
if (value) {
mp_hal_pin_write(pin, 1);
mp_hal_pin_od_high(pin);
}
mp_hal_delay_us_fast(TIMING_WRITE2);
mp_hal_pin_write(pin, 1);
mp_hal_pin_od_high(pin);
mp_hal_delay_us_fast(TIMING_WRITE3);
mp_hal_quiet_timing_exit(i);
}
Expand Down
309 changes: 309 additions & 0 deletions extmod/moduasyncio.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,309 @@
/*
* This file is part of the MicroPython project, http://micropython.org/
*
* The MIT License (MIT)
*
* Copyright (c) 2020 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.
*/

#include "py/runtime.h"
#include "py/smallint.h"
#include "py/pairheap.h"
#include "py/mphal.h"

#if MICROPY_PY_UASYNCIO

#define TASK_STATE_RUNNING_NOT_WAITED_ON (mp_const_true)
#define TASK_STATE_DONE_NOT_WAITED_ON (mp_const_none)
#define TASK_STATE_DONE_WAS_WAITED_ON (mp_const_false)

#define TASK_IS_DONE(task) ( \
(task)->state == TASK_STATE_DONE_NOT_WAITED_ON \
|| (task)->state == TASK_STATE_DONE_WAS_WAITED_ON)

typedef struct _mp_obj_task_t {
mp_pairheap_t pairheap;
mp_obj_t coro;
mp_obj_t data;
mp_obj_t state;
mp_obj_t ph_key;
} mp_obj_task_t;

typedef struct _mp_obj_task_queue_t {
mp_obj_base_t base;
mp_obj_task_t *heap;
} mp_obj_task_queue_t;

STATIC const mp_obj_type_t task_queue_type;
STATIC const mp_obj_type_t task_type;

STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args);

/******************************************************************************/
// Ticks for task ordering in pairing heap

STATIC mp_obj_t ticks(void) {
return MP_OBJ_NEW_SMALL_INT(mp_hal_ticks_ms() & (MICROPY_PY_UTIME_TICKS_PERIOD - 1));
}

STATIC mp_int_t ticks_diff(mp_obj_t t1_in, mp_obj_t t0_in) {
mp_uint_t t0 = MP_OBJ_SMALL_INT_VALUE(t0_in);
mp_uint_t t1 = MP_OBJ_SMALL_INT_VALUE(t1_in);
mp_int_t diff = ((t1 - t0 + MICROPY_PY_UTIME_TICKS_PERIOD / 2) & (MICROPY_PY_UTIME_TICKS_PERIOD - 1))
- MICROPY_PY_UTIME_TICKS_PERIOD / 2;
return diff;
}

STATIC int task_lt(mp_pairheap_t *n1, mp_pairheap_t *n2) {
mp_obj_task_t *t1 = (mp_obj_task_t *)n1;
mp_obj_task_t *t2 = (mp_obj_task_t *)n2;
return MP_OBJ_SMALL_INT_VALUE(ticks_diff(t1->ph_key, t2->ph_key)) < 0;
}

/******************************************************************************/
// TaskQueue class

STATIC mp_obj_t task_queue_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
(void)args;
mp_arg_check_num(n_args, kw_args, 0, 0, false);
mp_obj_task_queue_t *self = m_new_obj(mp_obj_task_queue_t);
self->base.type = type;
self->heap = (mp_obj_task_t *)mp_pairheap_new(task_lt);
return MP_OBJ_FROM_PTR(self);
}

STATIC mp_obj_t task_queue_peek(mp_obj_t self_in) {
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
if (self->heap == NULL) {
return mp_const_none;
} else {
return MP_OBJ_FROM_PTR(self->heap);
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_peek_obj, task_queue_peek);

STATIC mp_obj_t task_queue_push_sorted(size_t n_args, const mp_obj_t *args) {
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(args[0]);
mp_obj_task_t *task = MP_OBJ_TO_PTR(args[1]);
task->data = mp_const_none;
if (n_args == 2) {
task->ph_key = ticks();
} else {
assert(mp_obj_is_small_int(args[2]));
task->ph_key = args[2];
}
self->heap = (mp_obj_task_t *)mp_pairheap_push(task_lt, &self->heap->pairheap, &task->pairheap);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(task_queue_push_sorted_obj, 2, 3, task_queue_push_sorted);

STATIC mp_obj_t task_queue_pop_head(mp_obj_t self_in) {
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_task_t *head = (mp_obj_task_t *)mp_pairheap_peek(task_lt, &self->heap->pairheap);
if (head == NULL) {
mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap"));
}
self->heap = (mp_obj_task_t *)mp_pairheap_pop(task_lt, &self->heap->pairheap);
return MP_OBJ_FROM_PTR(head);
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_queue_pop_head_obj, task_queue_pop_head);

STATIC mp_obj_t task_queue_remove(mp_obj_t self_in, mp_obj_t task_in) {
mp_obj_task_queue_t *self = MP_OBJ_TO_PTR(self_in);
mp_obj_task_t *task = MP_OBJ_TO_PTR(task_in);
self->heap = (mp_obj_task_t *)mp_pairheap_delete(task_lt, &self->heap->pairheap, &task->pairheap);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(task_queue_remove_obj, task_queue_remove);

STATIC const mp_rom_map_elem_t task_queue_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_peek), MP_ROM_PTR(&task_queue_peek_obj) },
{ MP_ROM_QSTR(MP_QSTR_push_sorted), MP_ROM_PTR(&task_queue_push_sorted_obj) },
{ MP_ROM_QSTR(MP_QSTR_push_head), MP_ROM_PTR(&task_queue_push_sorted_obj) },
{ MP_ROM_QSTR(MP_QSTR_pop_head), MP_ROM_PTR(&task_queue_pop_head_obj) },
{ MP_ROM_QSTR(MP_QSTR_remove), MP_ROM_PTR(&task_queue_remove_obj) },
};
STATIC MP_DEFINE_CONST_DICT(task_queue_locals_dict, task_queue_locals_dict_table);

STATIC const mp_obj_type_t task_queue_type = {
{ &mp_type_type },
.name = MP_QSTR_TaskQueue,
.make_new = task_queue_make_new,
.locals_dict = (mp_obj_dict_t *)&task_queue_locals_dict,
};

/******************************************************************************/
// Task class

// This is the core uasyncio context with cur_task, _task_queue and CancelledError.
STATIC mp_obj_t uasyncio_context = MP_OBJ_NULL;

STATIC mp_obj_t task_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_obj_task_t *self = m_new_obj(mp_obj_task_t);
self->pairheap.base.type = type;
mp_pairheap_init_node(task_lt, &self->pairheap);
self->coro = args[0];
self->data = mp_const_none;
self->state = TASK_STATE_RUNNING_NOT_WAITED_ON;
self->ph_key = MP_OBJ_NEW_SMALL_INT(0);
if (n_args == 2) {
uasyncio_context = args[1];
}
return MP_OBJ_FROM_PTR(self);
}

STATIC mp_obj_t task_done(mp_obj_t self_in) {
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
return mp_obj_new_bool(TASK_IS_DONE(self));
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_done_obj, task_done);

STATIC mp_obj_t task_cancel(mp_obj_t self_in) {
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
// Check if task is already finished.
if (TASK_IS_DONE(self)) {
return mp_const_false;
}
// Can't cancel self (not supported yet).
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
if (self_in == cur_task) {
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("can't cancel self"));
}
// If Task waits on another task then forward the cancel to the one it's waiting on.
while (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(self->data)), MP_OBJ_FROM_PTR(&task_type))) {
self = MP_OBJ_TO_PTR(self->data);
}

mp_obj_t _task_queue = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR__task_queue));

// Reschedule Task as a cancelled task.
mp_obj_t dest[3];
mp_load_method_maybe(self->data, MP_QSTR_remove, dest);
if (dest[0] != MP_OBJ_NULL) {
// Not on the main running queue, remove the task from the queue it's on.
dest[2] = MP_OBJ_FROM_PTR(self);
mp_call_method_n_kw(1, 0, dest);
// _task_queue.push_head(self)
dest[0] = _task_queue;
dest[1] = MP_OBJ_FROM_PTR(self);
task_queue_push_sorted(2, dest);
} else if (ticks_diff(self->ph_key, ticks()) > 0) {
// On the main running queue but scheduled in the future, so bring it forward to now.
// _task_queue.remove(self)
task_queue_remove(_task_queue, MP_OBJ_FROM_PTR(self));
// _task_queue.push_head(self)
dest[0] = _task_queue;
dest[1] = MP_OBJ_FROM_PTR(self);
task_queue_push_sorted(2, dest);
}

self->data = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_CancelledError));

return mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(task_cancel_obj, task_cancel);

STATIC void task_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
if (dest[0] == MP_OBJ_NULL) {
// Load
if (attr == MP_QSTR_coro) {
dest[0] = self->coro;
} else if (attr == MP_QSTR_data) {
dest[0] = self->data;
} else if (attr == MP_QSTR_state) {
dest[0] = self->state;
} else if (attr == MP_QSTR_done) {
dest[0] = MP_OBJ_FROM_PTR(&task_done_obj);
dest[1] = self_in;
} else if (attr == MP_QSTR_cancel) {
dest[0] = MP_OBJ_FROM_PTR(&task_cancel_obj);
dest[1] = self_in;
} else if (attr == MP_QSTR_ph_key) {
dest[0] = self->ph_key;
}
} else if (dest[1] != MP_OBJ_NULL) {
// Store
if (attr == MP_QSTR_data) {
self->data = dest[1];
dest[0] = MP_OBJ_NULL;
} else if (attr == MP_QSTR_state) {
self->state = dest[1];
dest[0] = MP_OBJ_NULL;
}
}
}

STATIC mp_obj_t task_getiter(mp_obj_t self_in, mp_obj_iter_buf_t *iter_buf) {
(void)iter_buf;
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
if (TASK_IS_DONE(self)) {
// Signal that the completed-task has been await'ed on.
self->state = TASK_STATE_DONE_WAS_WAITED_ON;
} else if (self->state == TASK_STATE_RUNNING_NOT_WAITED_ON) {
// Allocate the waiting queue.
self->state = task_queue_make_new(&task_queue_type, 0, 0, NULL);
}
return self_in;
}

STATIC mp_obj_t task_iternext(mp_obj_t self_in) {
mp_obj_task_t *self = MP_OBJ_TO_PTR(self_in);
if (TASK_IS_DONE(self)) {
// Task finished, raise return value to caller so it can continue.
nlr_raise(self->data);
} else {
// Put calling task on waiting queue.
mp_obj_t cur_task = mp_obj_dict_get(uasyncio_context, MP_OBJ_NEW_QSTR(MP_QSTR_cur_task));
mp_obj_t args[2] = { self->state, cur_task };
task_queue_push_sorted(2, args);
// Set calling task's data to this task that it waits on, to double-link it.
((mp_obj_task_t *)MP_OBJ_TO_PTR(cur_task))->data = self_in;
}
return mp_const_none;
}

STATIC const mp_obj_type_t task_type = {
{ &mp_type_type },
.name = MP_QSTR_Task,
.make_new = task_make_new,
.attr = task_attr,
.getiter = task_getiter,
.iternext = task_iternext,
};

/******************************************************************************/
// C-level uasyncio module

STATIC const mp_rom_map_elem_t mp_module_uasyncio_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR__uasyncio) },
{ MP_ROM_QSTR(MP_QSTR_TaskQueue), MP_ROM_PTR(&task_queue_type) },
{ MP_ROM_QSTR(MP_QSTR_Task), MP_ROM_PTR(&task_type) },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_uasyncio_globals, mp_module_uasyncio_globals_table);

const mp_obj_module_t mp_module_uasyncio = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_uasyncio_globals,
};

#endif // MICROPY_PY_UASYNCIO
39 changes: 17 additions & 22 deletions extmod/modubinascii.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,18 @@

#include "py/runtime.h"
#include "py/binary.h"
#include "extmod/modubinascii.h"

static void check_not_unicode(const mp_obj_t arg) {
#if MICROPY_CPYTHON_COMPAT
if (MP_OBJ_IS_STR(arg)) {
mp_raise_TypeError(translate("a bytes-like object is required"));
if (mp_obj_is_str(arg)) {
mp_raise_TypeError(MP_ERROR_TEXT("a bytes-like object is required"));
}
#endif
}

mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
// Second argument is for an extension to allow a separator to be used
// between values.
STATIC mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
// First argument is the data to convert.
// Second argument is an optional separator to be used between values.
const char *sep = NULL;
mp_buffer_info_t bufinfo;
check_not_unicode(args[0]);
Expand Down Expand Up @@ -59,14 +58,14 @@ mp_obj_t mod_binascii_hexlify(size_t n_args, const mp_obj_t *args) {
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_hexlify_obj, 1, 2, mod_binascii_hexlify);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_hexlify_obj, 1, 2, mod_binascii_hexlify);

mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
STATIC mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);

if ((bufinfo.len & 1) != 0) {
mp_raise_ValueError(translate("odd-length string"));
mp_raise_ValueError(MP_ERROR_TEXT("odd-length string"));
}
vstr_t vstr;
vstr_init_len(&vstr, bufinfo.len / 2);
Expand All @@ -77,7 +76,7 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
if (unichar_isxdigit(hex_ch)) {
hex_byte += unichar_xdigit_value(hex_ch);
} else {
mp_raise_ValueError(translate("non-hex digit found"));
mp_raise_ValueError(MP_ERROR_TEXT("non-hex digit found"));
}
if (i & 1) {
hex_byte <<= 4;
Expand All @@ -88,7 +87,7 @@ mp_obj_t mod_binascii_unhexlify(mp_obj_t data) {
}
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_unhexlify_obj, mod_binascii_unhexlify);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_unhexlify_obj, mod_binascii_unhexlify);

// If ch is a character in the base64 alphabet, and is not a pad character, then
// the corresponding integer between 0 and 63, inclusively, is returned.
Expand All @@ -109,7 +108,7 @@ static int mod_binascii_sextet(byte ch) {
}
}

mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
STATIC mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
byte *in = bufinfo.buf;
Expand Down Expand Up @@ -145,14 +144,14 @@ mp_obj_t mod_binascii_a2b_base64(mp_obj_t data) {
}

if (nbits) {
mp_raise_ValueError(translate("incorrect padding"));
mp_raise_ValueError(MP_ERROR_TEXT("incorrect padding"));
}

return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_a2b_base64_obj, mod_binascii_a2b_base64);

mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
STATIC mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
check_not_unicode(data);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
Expand Down Expand Up @@ -203,24 +202,22 @@ mp_obj_t mod_binascii_b2a_base64(mp_obj_t data) {
*out = '\n';
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_binascii_b2a_base64_obj, mod_binascii_b2a_base64);

#if MICROPY_PY_UBINASCII_CRC32
#include "../../lib/uzlib/src/tinf.h"

mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) {
STATIC mp_obj_t mod_binascii_crc32(size_t n_args, const mp_obj_t *args) {
mp_buffer_info_t bufinfo;
check_not_unicode(args[0]);
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
uint32_t crc = (n_args > 1) ? mp_obj_get_int_truncated(args[1]) : 0;
crc = uzlib_crc32(bufinfo.buf, bufinfo.len, crc ^ 0xffffffff);
return mp_obj_new_int_from_uint(crc ^ 0xffffffff);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_binascii_crc32);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_binascii_crc32_obj, 1, 2, mod_binascii_crc32);
#endif

#if MICROPY_PY_UBINASCII

STATIC const mp_rom_map_elem_t mp_module_binascii_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_binascii) },
{ MP_ROM_QSTR(MP_QSTR_hexlify), MP_ROM_PTR(&mod_binascii_hexlify_obj) },
Expand All @@ -238,5 +235,3 @@ const mp_obj_module_t mp_module_ubinascii = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_binascii_globals,
};

#endif // MICROPY_PY_UBINASCII
21 changes: 0 additions & 21 deletions extmod/modubinascii.h

This file was deleted.

247 changes: 122 additions & 125 deletions extmod/moductypes.c

Large diffs are not rendered by default.

171 changes: 155 additions & 16 deletions extmod/moduhashlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

#if MICROPY_PY_UHASHLIB

#if MICROPY_SSL_MBEDTLS
#include "mbedtls/version.h"
#endif

#if MICROPY_PY_UHASHLIB_SHA256

#if MICROPY_SSL_MBEDTLS
Expand All @@ -22,13 +26,14 @@

#endif

#if MICROPY_PY_UHASHLIB_SHA1
#if MICROPY_PY_UHASHLIB_SHA1 || MICROPY_PY_UHASHLIB_MD5

#if MICROPY_SSL_AXTLS
#include "lib/axtls/crypto/crypto.h"
#endif

#if MICROPY_SSL_MBEDTLS
#include "mbedtls/md5.h"
#include "mbedtls/sha1.h"
#endif

Expand All @@ -37,20 +42,34 @@

typedef struct _mp_obj_hash_t {
mp_obj_base_t base;
char state[0];
bool final; // if set, update and digest raise an exception
uintptr_t state[0]; // must be aligned to a machine word
} mp_obj_hash_t;

static void uhashlib_ensure_not_final(mp_obj_hash_t *self) {
if (self->final) {
mp_raise_ValueError(MP_ERROR_TEXT("hash is final"));
}
}

#if MICROPY_PY_UHASHLIB_SHA256
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, const mp_obj_t *args, mp_map_t *kw_args) {
mp_arg_check_num(n_args, kw_args, 0, 1, false);
#if MBEDTLS_VERSION_NUMBER < 0x02070000
#define mbedtls_sha256_starts_ret mbedtls_sha256_starts
#define mbedtls_sha256_update_ret mbedtls_sha256_update
#define mbedtls_sha256_finish_ret mbedtls_sha256_finish
#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);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha256_context));
o->base.type = type;
o->final = false;
mbedtls_sha256_init((mbedtls_sha256_context *)&o->state);
mbedtls_sha256_starts((mbedtls_sha256_context *)&o->state, 0);
mbedtls_sha256_starts_ret((mbedtls_sha256_context *)&o->state, 0);
if (n_args == 1) {
uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]);
}
Expand All @@ -59,34 +78,42 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg

STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_sha256_update((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len);
mbedtls_sha256_update_ret((mbedtls_sha256_context *)&self->state, bufinfo.buf, bufinfo.len);
return mp_const_none;
}

STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
self->final = true;
vstr_t vstr;
vstr_init_len(&vstr, 32);
mbedtls_sha256_finish((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf);
mbedtls_sha256_finish_ret((mbedtls_sha256_context *)&self->state, (unsigned char *)vstr.buf);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}

#else

static void check_not_unicode(const mp_obj_t arg) {
#if MICROPY_CPYTHON_COMPAT
if (MP_OBJ_IS_STR(arg)) {
mp_raise_TypeError(translate("a bytes-like object is required"));
if (mp_obj_is_str(arg)) {
mp_raise_TypeError(MP_ERROR_TEXT("a bytes-like object is required"));
}
#endif
}

#if MICROPY_PY_UHASHLIB_SHA256
#include "crypto-algorithms/sha256.c"
#endif

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;
o->final = false;
sha256_init((CRYAL_SHA256_CTX *)o->state);
if (n_args == 1) {
uhashlib_sha256_update(MP_OBJ_FROM_PTR(o), args[0]);
Expand All @@ -97,6 +124,7 @@ STATIC mp_obj_t uhashlib_sha256_make_new(const mp_obj_type_t *type, size_t n_arg
STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) {
check_not_unicode(arg);
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
sha256_update((CRYAL_SHA256_CTX *)self->state, bufinfo.buf, bufinfo.len);
Expand All @@ -105,6 +133,8 @@ STATIC mp_obj_t uhashlib_sha256_update(mp_obj_t self_in, mp_obj_t arg) {

STATIC mp_obj_t uhashlib_sha256_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
self->final = true;
vstr_t vstr;
vstr_init_len(&vstr, SHA256_BLOCK_SIZE);
sha256_final((CRYAL_SHA256_CTX *)self->state, (byte *)vstr.buf);
Expand Down Expand Up @@ -138,6 +168,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_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;
o->final = false;
SHA1_Init((SHA1_CTX *)o->state);
if (n_args == 1) {
uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]);
Expand All @@ -148,6 +179,7 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args,
STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
check_not_unicode(arg);
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
SHA1_Update((SHA1_CTX *)self->state, bufinfo.buf, bufinfo.len);
Expand All @@ -156,6 +188,8 @@ STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {

STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
self->final = true;
vstr_t vstr;
vstr_init_len(&vstr, SHA1_SIZE);
SHA1_Final((byte *)vstr.buf, (SHA1_CTX *)self->state);
Expand All @@ -164,12 +198,20 @@ STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
#endif

#if MICROPY_SSL_MBEDTLS

#if MBEDTLS_VERSION_NUMBER < 0x02070000
#define mbedtls_sha1_starts_ret mbedtls_sha1_starts
#define mbedtls_sha1_update_ret mbedtls_sha1_update
#define mbedtls_sha1_finish_ret mbedtls_sha1_finish
#endif

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);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_sha1_context));
o->base.type = type;
o->final = false;
mbedtls_sha1_init((mbedtls_sha1_context *)o->state);
mbedtls_sha1_starts((mbedtls_sha1_context *)o->state);
mbedtls_sha1_starts_ret((mbedtls_sha1_context *)o->state);
if (n_args == 1) {
uhashlib_sha1_update(MP_OBJ_FROM_PTR(o), args[0]);
}
Expand All @@ -178,17 +220,20 @@ STATIC mp_obj_t uhashlib_sha1_make_new(const mp_obj_type_t *type, size_t n_args,

STATIC mp_obj_t uhashlib_sha1_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_sha1_update((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len);
mbedtls_sha1_update_ret((mbedtls_sha1_context *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none;
}

STATIC mp_obj_t uhashlib_sha1_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
self->final = true;
vstr_t vstr;
vstr_init_len(&vstr, 20);
mbedtls_sha1_finish((mbedtls_sha1_context *)self->state, (byte *)vstr.buf);
mbedtls_sha1_finish_ret((mbedtls_sha1_context *)self->state, (byte *)vstr.buf);
mbedtls_sha1_free((mbedtls_sha1_context *)self->state);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
Expand All @@ -211,6 +256,101 @@ STATIC const mp_obj_type_t uhashlib_sha1_type = {
};
#endif

#if MICROPY_PY_UHASHLIB_MD5
STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg);

#if MICROPY_SSL_AXTLS
STATIC mp_obj_t uhashlib_md5_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);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(MD5_CTX));
o->base.type = type;
o->final = false;
MD5_Init((MD5_CTX *)o->state);
if (n_args == 1) {
uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]);
}
return MP_OBJ_FROM_PTR(o);
}

STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
MD5_Update((MD5_CTX *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none;
}

STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
self->final = true;
vstr_t vstr;
vstr_init_len(&vstr, MD5_SIZE);
MD5_Final((byte *)vstr.buf, (MD5_CTX *)self->state);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
#endif // MICROPY_SSL_AXTLS

#if MICROPY_SSL_MBEDTLS

#if MBEDTLS_VERSION_NUMBER < 0x02070000
#define mbedtls_md5_starts_ret mbedtls_md5_starts
#define mbedtls_md5_update_ret mbedtls_md5_update
#define mbedtls_md5_finish_ret mbedtls_md5_finish
#endif

STATIC mp_obj_t uhashlib_md5_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);
mp_obj_hash_t *o = m_new_obj_var(mp_obj_hash_t, char, sizeof(mbedtls_md5_context));
o->base.type = type;
o->final = false;
mbedtls_md5_init((mbedtls_md5_context *)o->state);
mbedtls_md5_starts_ret((mbedtls_md5_context *)o->state);
if (n_args == 1) {
uhashlib_md5_update(MP_OBJ_FROM_PTR(o), args[0]);
}
return MP_OBJ_FROM_PTR(o);
}

STATIC mp_obj_t uhashlib_md5_update(mp_obj_t self_in, mp_obj_t arg) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(arg, &bufinfo, MP_BUFFER_READ);
mbedtls_md5_update_ret((mbedtls_md5_context *)self->state, bufinfo.buf, bufinfo.len);
return mp_const_none;
}

STATIC mp_obj_t uhashlib_md5_digest(mp_obj_t self_in) {
mp_obj_hash_t *self = MP_OBJ_TO_PTR(self_in);
uhashlib_ensure_not_final(self);
self->final = true;
vstr_t vstr;
vstr_init_len(&vstr, 16);
mbedtls_md5_finish_ret((mbedtls_md5_context *)self->state, (byte *)vstr.buf);
mbedtls_md5_free((mbedtls_md5_context *)self->state);
return mp_obj_new_str_from_vstr(&mp_type_bytes, &vstr);
}
#endif // MICROPY_SSL_MBEDTLS

STATIC MP_DEFINE_CONST_FUN_OBJ_2(uhashlib_md5_update_obj, uhashlib_md5_update);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(uhashlib_md5_digest_obj, uhashlib_md5_digest);

STATIC const mp_rom_map_elem_t uhashlib_md5_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_update), MP_ROM_PTR(&uhashlib_md5_update_obj) },
{ MP_ROM_QSTR(MP_QSTR_digest), MP_ROM_PTR(&uhashlib_md5_digest_obj) },
};
STATIC MP_DEFINE_CONST_DICT(uhashlib_md5_locals_dict, uhashlib_md5_locals_dict_table);

STATIC const mp_obj_type_t uhashlib_md5_type = {
{ &mp_type_type },
.name = MP_QSTR_md5,
.make_new = uhashlib_md5_make_new,
.locals_dict = (void *)&uhashlib_md5_locals_dict,
};
#endif // MICROPY_PY_UHASHLIB_MD5

STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_hashlib) },
#if MICROPY_PY_UHASHLIB_SHA256
Expand All @@ -219,6 +359,9 @@ STATIC const mp_rom_map_elem_t mp_module_uhashlib_globals_table[] = {
#if MICROPY_PY_UHASHLIB_SHA1
{ MP_ROM_QSTR(MP_QSTR_sha1), MP_ROM_PTR(&uhashlib_sha1_type) },
#endif
#if MICROPY_PY_UHASHLIB_MD5
{ MP_ROM_QSTR(MP_QSTR_md5), MP_ROM_PTR(&uhashlib_md5_type) },
#endif
};

STATIC MP_DEFINE_CONST_DICT(mp_module_uhashlib_globals, mp_module_uhashlib_globals_table);
Expand All @@ -228,8 +371,4 @@ const mp_obj_module_t mp_module_uhashlib = {
.globals = (mp_obj_dict_t *)&mp_module_uhashlib_globals,
};

#if MICROPY_PY_UHASHLIB_SHA256
#include "crypto-algorithms/sha256.c"
#endif

#endif // MICROPY_PY_UHASHLIB
28 changes: 15 additions & 13 deletions extmod/moduheapq.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@

// the algorithm here is modelled on CPython's heapq.py

STATIC mp_obj_list_t *get_heap(mp_obj_t heap_in) {
if (!MP_OBJ_IS_TYPE(heap_in, &mp_type_list)) {
mp_raise_TypeError(translate("heap must be a list"));
STATIC mp_obj_list_t *uheapq_get_heap(mp_obj_t heap_in) {
if (!mp_obj_is_type(heap_in, &mp_type_list)) {
mp_raise_TypeError(MP_ERROR_TEXT("heap must be a list"));
}
return MP_OBJ_TO_PTR(heap_in);
}

STATIC void heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t pos) {
STATIC void uheapq_heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t pos) {
mp_obj_t item = heap->items[pos];
while (pos > start_pos) {
mp_uint_t parent_pos = (pos - 1) >> 1;
Expand All @@ -34,7 +34,7 @@ STATIC void heap_siftdown(mp_obj_list_t *heap, mp_uint_t start_pos, mp_uint_t po
heap->items[pos] = item;
}

STATIC void heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) {
STATIC void uheapq_heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) {
mp_uint_t start_pos = pos;
mp_uint_t end_pos = heap->len;
mp_obj_t item = heap->items[pos];
Expand All @@ -48,42 +48,43 @@ STATIC void heap_siftup(mp_obj_list_t *heap, mp_uint_t pos) {
pos = child_pos;
}
heap->items[pos] = item;
heap_siftdown(heap, start_pos, pos);
uheapq_heap_siftdown(heap, start_pos, pos);
}

STATIC mp_obj_t mod_uheapq_heappush(mp_obj_t heap_in, mp_obj_t item) {
mp_obj_list_t *heap = get_heap(heap_in);
mp_obj_list_t *heap = uheapq_get_heap(heap_in);
mp_obj_list_append(heap_in, item);
heap_siftdown(heap, 0, heap->len - 1);
uheapq_heap_siftdown(heap, 0, heap->len - 1);
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_uheapq_heappush_obj, mod_uheapq_heappush);

STATIC mp_obj_t mod_uheapq_heappop(mp_obj_t heap_in) {
mp_obj_list_t *heap = get_heap(heap_in);
mp_obj_list_t *heap = uheapq_get_heap(heap_in);
if (heap->len == 0) {
mp_raise_IndexError(translate("empty heap"));
mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("empty heap"));
}
mp_obj_t item = heap->items[0];
heap->len -= 1;
heap->items[0] = heap->items[heap->len];
heap->items[heap->len] = MP_OBJ_NULL; // so we don't retain a pointer
if (heap->len) {
heap_siftup(heap, 0);
uheapq_heap_siftup(heap, 0);
}
return item;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_uheapq_heappop_obj, mod_uheapq_heappop);

STATIC mp_obj_t mod_uheapq_heapify(mp_obj_t heap_in) {
mp_obj_list_t *heap = get_heap(heap_in);
mp_obj_list_t *heap = uheapq_get_heap(heap_in);
for (mp_uint_t i = heap->len / 2; i > 0;) {
heap_siftup(heap, --i);
uheapq_heap_siftup(heap, --i);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_uheapq_heapify_obj, mod_uheapq_heapify);

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t mp_module_uheapq_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_uheapq) },
{ MP_ROM_QSTR(MP_QSTR_heappush), MP_ROM_PTR(&mod_uheapq_heappush_obj) },
Expand All @@ -97,5 +98,6 @@ const mp_obj_module_t mp_module_uheapq = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_uheapq_globals,
};
#endif

#endif // MICROPY_PY_UHEAPQ
14 changes: 7 additions & 7 deletions extmod/modujson.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-FileCopyrightText: 2014 MicroPython & CircuitPython contributors (https://github.com/adafruit/circuitpython/graphs/contributors)
// SPDX-FileCopyrightText: Copyright (c) 2014-2016 Damien P. George
// SPDX-FileCopyrightText: Copyright (c) 2014-2019 Damien P. George
//
// SPDX-License-Identifier: MIT

Expand Down Expand Up @@ -135,7 +135,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
stack.len = 0;
stack.items = NULL;
mp_obj_t stack_top = MP_OBJ_NULL;
mp_obj_type_t *stack_top_type = NULL;
const mp_obj_type_t *stack_top_type = NULL;
mp_obj_t stack_key = MP_OBJ_NULL;
S_NEXT(s);
for (;;) {
Expand Down Expand Up @@ -243,7 +243,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
cur = S_CUR(s);
if (cur == '.' || cur == 'E' || cur == 'e') {
flt = true;
} else if (cur == '-' || unichar_isdigit(cur)) {
} else if (cur == '+' || cur == '-' || unichar_isdigit(cur)) {
// pass
} else {
break;
Expand Down Expand Up @@ -339,7 +339,7 @@ STATIC mp_obj_t _mod_ujson_load(mp_obj_t stream_obj, bool return_first_json) {
return stack_top;

fail:
mp_raise_ValueError(translate("syntax error in JSON"));
mp_raise_ValueError(MP_ERROR_TEXT("syntax error in JSON"));
}

STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
Expand All @@ -348,9 +348,9 @@ STATIC mp_obj_t mod_ujson_load(mp_obj_t stream_obj) {
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) {
size_t len;
const char *buf = mp_obj_str_get_data(obj, &len);
vstr_t vstr = {len, len, (char *)buf, true};
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(obj, &bufinfo, MP_BUFFER_READ);
vstr_t vstr = {bufinfo.len, bufinfo.len, (char *)bufinfo.buf, true};
mp_obj_stringio_t sio = {{&mp_type_stringio}, &vstr, 0, MP_OBJ_NULL};
return _mod_ujson_load(MP_OBJ_FROM_PTR(&sio), false);
}
Expand Down
75 changes: 54 additions & 21 deletions extmod/modurandom.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,29 @@

#if MICROPY_PY_URANDOM

// Work out if the seed will be set on import or not.
#if MICROPY_MODULE_BUILTIN_INIT && defined(MICROPY_PY_URANDOM_SEED_INIT_FUNC)
#define SEED_ON_IMPORT (1)
#else
#define SEED_ON_IMPORT (0)
#endif

// Yasmarang random number generator
// by Ilya Levin
// http://www.literatecode.com/yasmarang
// Public Domain

#if !MICROPY_ENABLE_DYNRUNTIME
#if SEED_ON_IMPORT
// If the state is seeded on import then keep these variables in the BSS.
STATIC uint32_t yasmarang_pad, yasmarang_n, yasmarang_d;
STATIC uint8_t yasmarang_dat;
#else
// Without seed-on-import these variables must be initialised via the data section.
STATIC uint32_t yasmarang_pad = 0xeda4baba, yasmarang_n = 69, yasmarang_d = 233;
STATIC uint8_t yasmarang_dat = 0;
#endif
#endif

STATIC uint32_t yasmarang(void) {
yasmarang_pad += yasmarang_dat + yasmarang_d * yasmarang_n;
Expand Down Expand Up @@ -50,8 +66,11 @@ STATIC uint32_t yasmarang_randbelow(uint32_t n) {

STATIC mp_obj_t mod_urandom_getrandbits(mp_obj_t num_in) {
int n = mp_obj_get_int(num_in);
if (n > 32 || n == 0) {
mp_raise_ValueError(NULL);
if (n > 32 || n < 0) {
mp_raise_ValueError(MP_ERROR_TEXT("bits must be 32 or less"));
}
if (n == 0) {
return MP_OBJ_NEW_SMALL_INT(0);
}
uint32_t mask = ~0;
// Beware of C undefined behavior when shifting by >= than bit size
Expand All @@ -60,15 +79,24 @@ STATIC mp_obj_t mod_urandom_getrandbits(mp_obj_t num_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_getrandbits_obj, mod_urandom_getrandbits);

STATIC mp_obj_t mod_urandom_seed(mp_obj_t seed_in) {
mp_uint_t seed = mp_obj_get_int_truncated(seed_in);
STATIC mp_obj_t mod_urandom_seed(size_t n_args, const mp_obj_t *args) {
mp_uint_t seed;
if (n_args == 0 || args[0] == mp_const_none) {
#ifdef MICROPY_PY_URANDOM_SEED_INIT_FUNC
seed = MICROPY_PY_URANDOM_SEED_INIT_FUNC;
#else
mp_raise_ValueError(MP_ERROR_TEXT("no default seed"));
#endif
} else {
seed = mp_obj_get_int_truncated(args[0]);
}
yasmarang_pad = seed;
yasmarang_n = 69;
yasmarang_d = 233;
yasmarang_dat = 0;
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_seed_obj, mod_urandom_seed);
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_urandom_seed_obj, 0, 1, mod_urandom_seed);

#if MICROPY_PY_URANDOM_EXTRA_FUNCS

Expand Down Expand Up @@ -130,7 +158,7 @@ STATIC mp_obj_t mod_urandom_choice(mp_obj_t seq) {
if (len > 0) {
return mp_obj_subscr(seq, mp_obj_new_int(yasmarang_randbelow(len)), MP_OBJ_SENTINEL);
} else {
nlr_raise(mp_obj_new_exception(&mp_type_IndexError));
mp_raise_type(&mp_type_IndexError);
}
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_choice_obj, mod_urandom_choice);
Expand All @@ -139,21 +167,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_urandom_choice_obj, mod_urandom_choice);

// returns a number in the range [0..1) using Yasmarang to fill in the fraction bits
STATIC mp_float_t yasmarang_float(void) {
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
typedef uint64_t mp_float_int_t;
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
typedef uint32_t mp_float_int_t;
#endif
union {
mp_float_t f;
#if MP_ENDIANNESS_LITTLE
struct { mp_float_int_t frc : MP_FLOAT_FRAC_BITS, exp : MP_FLOAT_EXP_BITS, sgn : 1;
} p;
#else
struct { mp_float_int_t sgn : 1, exp : MP_FLOAT_EXP_BITS, frc : MP_FLOAT_FRAC_BITS;
} p;
#endif
} u;
mp_float_union_t u;
u.p.sgn = 0;
u.p.exp = (1 << (MP_FLOAT_EXP_BITS - 1)) - 1;
if (MP_FLOAT_FRAC_BITS <= 32) {
Expand All @@ -180,8 +194,26 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_urandom_uniform_obj, mod_urandom_uniform);

#endif // MICROPY_PY_URANDOM_EXTRA_FUNCS

#if SEED_ON_IMPORT
STATIC mp_obj_t mod_urandom___init__() {
// This module may be imported by more than one name so need to ensure
// that it's only ever seeded once.
static bool seeded = false;
if (!seeded) {
seeded = true;
mod_urandom_seed(0, NULL);
}
return mp_const_none;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_urandom___init___obj, mod_urandom___init__);
#endif

#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_rom_map_elem_t mp_module_urandom_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_urandom) },
#if SEED_ON_IMPORT
{ MP_ROM_QSTR(MP_QSTR___init__), MP_ROM_PTR(&mod_urandom___init___obj) },
#endif
{ MP_ROM_QSTR(MP_QSTR_getrandbits), MP_ROM_PTR(&mod_urandom_getrandbits_obj) },
{ MP_ROM_QSTR(MP_QSTR_seed), MP_ROM_PTR(&mod_urandom_seed_obj) },
#if MICROPY_PY_URANDOM_EXTRA_FUNCS
Expand All @@ -201,5 +233,6 @@ const mp_obj_module_t mp_module_urandom = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_urandom_globals,
};
#endif

#endif // MICROPY_PY_URANDOM
87 changes: 41 additions & 46 deletions extmod/modure.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

#include "re1.5/re1.5.h"

#if CIRCUITPY_RE_DEBUG
#if MICROPY_PY_URE_DEBUG
#define FLAG_DEBUG 0x1000
#endif

Expand All @@ -34,6 +34,10 @@ typedef struct _mp_obj_match_t {
const char *caps[0];
} mp_obj_match_t;

STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args);
#if !MICROPY_ENABLE_DYNRUNTIME
STATIC const mp_obj_type_t re_type;
#endif

STATIC void match_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
Expand Down Expand Up @@ -125,6 +129,7 @@ MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(match_end_obj, 1, 2, match_end);

#endif

#if !MICROPY_ENABLE_DYNRUNTIME
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
Expand All @@ -145,6 +150,7 @@ STATIC const mp_obj_type_t match_type = {
.print = match_print,
.locals_dict = (void *)&match_locals_dict,
};
#endif

STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
(void)kind;
Expand All @@ -154,15 +160,21 @@ STATIC void re_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t

STATIC mp_obj_t ure_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
(void)n_args;
mp_obj_re_t *self = MP_OBJ_TO_PTR(args[0]);
mp_obj_re_t *self;
if (mp_obj_is_type(args[0], &re_type)) {
self = MP_OBJ_TO_PTR(args[0]);
} else {
self = MP_OBJ_TO_PTR(mod_re_compile(1, args));
}
Subject subj;
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 MICROPY_PY_URE_MATCH_SPAN_START_END && !(defined(MICROPY_ENABLE_DYNRUNTIME) && MICROPY_ENABLE_DYNRUNTIME)

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]));
mp_int_t str_len = MP_OBJ_SMALL_INT_VALUE(mp_obj_len(args[1]));
const byte *begin = (const byte *)subj.begin;

int pos = mp_obj_get_int(args[2]);
Expand Down Expand Up @@ -243,7 +255,7 @@ STATIC mp_obj_t re_split(size_t n_args, const mp_obj_t *args) {
mp_obj_t s = mp_obj_new_str_of_type(str_type, (const byte *)subj.begin, caps[0] - subj.begin);
mp_obj_list_append(retval, s);
if (self->re.sub > 0) {
mp_raise_NotImplementedError(translate("Splitting with sub-captures"));
mp_raise_NotImplementedError(MP_ERROR_TEXT("Splitting with sub-captures"));
}
subj.begin = caps[1];
if (maxsplit > 0 && --maxsplit == 0) {
Expand All @@ -261,8 +273,13 @@ 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);
STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) {
mp_obj_re_t *self;
if (mp_obj_is_type(args[0], &re_type)) {
self = MP_OBJ_TO_PTR(args[0]);
} else {
self = MP_OBJ_TO_PTR(mod_re_compile(1, args));
}
mp_obj_t replace = args[1];
mp_obj_t where = args[2];
mp_int_t count = 0;
Expand Down Expand Up @@ -337,6 +354,9 @@ STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *a
const char *end_match = match->caps[match_no * 2 + 1];
vstr_add_strn(&vstr_return, start_match, end_match - start_match);
}
} else if (*repl == '\\') {
// Add the \ character
vstr_add_byte(&vstr_return, *repl++);
}
} else {
// Just add the current byte from the replacement string
Expand Down Expand Up @@ -366,13 +386,11 @@ STATIC mp_obj_t re_sub_helper(mp_obj_t self_in, size_t n_args, const mp_obj_t *a
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);
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(re_sub_obj, 3, 5, re_sub_helper);

#endif

#if !MICROPY_ENABLE_DYNRUNTIME
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) },
Expand All @@ -394,16 +412,18 @@ STATIC const mp_obj_type_t re_type = {
.print = re_print,
.locals_dict = (void *)&re_locals_dict,
};
#endif

STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
(void)n_args;
const char *re_str = mp_obj_str_get_str(args[0]);
int size = re1_5_sizecode(re_str);
if (size == -1) {
goto error;
}
mp_obj_re_t *o = m_new_obj_var(mp_obj_re_t, char, size);
o->base.type = &re_type;
#if CIRCUITPY_RE_DEBUG
#if MICROPY_PY_URE_DEBUG
int flags = 0;
if (n_args > 1) {
flags = mp_obj_get_int(args[1]);
Expand All @@ -414,9 +434,9 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
int error = re1_5_compilecode(&o->re, re_str);
if (error != 0) {
error:
mp_raise_ValueError(translate("Error in regex"));
mp_raise_ValueError(MP_ERROR_TEXT("Error in regex"));
}
#if CIRCUITPY_RE_DEBUG
#if MICROPY_PY_URE_DEBUG
if (flags & FLAG_DEBUG) {
re1_5_dumpcode(&o->re);
}
Expand All @@ -425,46 +445,20 @@ STATIC mp_obj_t mod_re_compile(size_t n_args, const mp_obj_t *args) {
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_compile_obj, 1, 2, mod_re_compile);

STATIC mp_obj_t mod_re_exec(bool is_anchored, uint n_args, const mp_obj_t *args) {
(void)n_args;
mp_obj_t self = mod_re_compile(1, args);

const mp_obj_t args2[] = {self, args[1]};
mp_obj_t match = ure_exec(is_anchored, 2, args2);
return match;
}

STATIC mp_obj_t mod_re_match(size_t n_args, const mp_obj_t *args) {
return mod_re_exec(true, n_args, args);
}
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_re_match_obj, 2, 4, mod_re_match);

STATIC mp_obj_t mod_re_search(size_t n_args, const mp_obj_t *args) {
return mod_re_exec(false, n_args, 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

#if !MICROPY_ENABLE_DYNRUNTIME
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) },
{ MP_ROM_QSTR(MP_QSTR_match), MP_ROM_PTR(&re_match_obj) },
{ MP_ROM_QSTR(MP_QSTR_search), MP_ROM_PTR(&re_search_obj) },
#if MICROPY_PY_URE_SUB
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&mod_re_sub_obj) },
{ MP_ROM_QSTR(MP_QSTR_sub), MP_ROM_PTR(&re_sub_obj) },
#endif
#if CIRCUITPY_RE_DEBUG
#if MICROPY_PY_URE_DEBUG
{ MP_ROM_QSTR(MP_QSTR_DEBUG), MP_ROM_INT(FLAG_DEBUG) },
#endif
};
Expand All @@ -475,13 +469,14 @@ const mp_obj_module_t mp_module_ure = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_re_globals,
};
#endif

// Source files #include'd here to make sure they're compiled in
// only if module is enabled by config setting.

#define re1_5_fatal(x) assert(!x)
#include "re1.5/compilecode.c"
#if CIRCUITPY_RE_DEBUG
#if MICROPY_PY_URE_DEBUG
#include "re1.5/dumpcode.c"
#endif
#include "re1.5/recursiveloop.c"
Expand Down
Loading