diff options
28 files changed, 165 insertions, 117 deletions
diff --git a/mpy-cross/main.c b/mpy-cross/main.c index 16f749ae4..b7771ce6e 100644 --- a/mpy-cross/main.c +++ b/mpy-cross/main.c @@ -81,7 +81,7 @@ static int compile_and_save(const char *file, const char *output_file, const cha source_name = qstr_from_str(source_file); } - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif diff --git a/mpy-cross/mpconfigport.h b/mpy-cross/mpconfigport.h index 81cbfc2ee..0a6478b4f 100644 --- a/mpy-cross/mpconfigport.h +++ b/mpy-cross/mpconfigport.h @@ -85,7 +85,7 @@ #define MICROPY_GCREGS_SETJMP (1) #endif -#define MICROPY_PY___FILE__ (0) +#define MICROPY_MODULE___FILE__ (0) #define MICROPY_PY_ARRAY (0) #define MICROPY_PY_ATTRTUPLE (0) #define MICROPY_PY_COLLECTIONS (0) diff --git a/ports/alif/mpconfigport.h b/ports/alif/mpconfigport.h index 08b27e278..6b30ea2e6 100644 --- a/ports/alif/mpconfigport.h +++ b/ports/alif/mpconfigport.h @@ -112,9 +112,6 @@ // Extended modules #define MICROPY_EPOCH_IS_1970 (1) -#define MICROPY_PY_CRYPTOLIB (MICROPY_PY_SSL) -#define MICROPY_PY_HASHLIB_MD5 (MICROPY_PY_SSL) -#define MICROPY_PY_HASHLIB_SHA1 (MICROPY_PY_SSL) #define MICROPY_PY_OS_INCLUDEFILE "ports/alif/modos.c" #define MICROPY_PY_OS_DUPTERM (1) #define MICROPY_PY_OS_SEP (1) diff --git a/ports/esp32/mpconfigport.h b/ports/esp32/mpconfigport.h index e47b333c7..9b12dbd34 100644 --- a/ports/esp32/mpconfigport.h +++ b/ports/esp32/mpconfigport.h @@ -105,10 +105,6 @@ #define MICROPY_BLUETOOTH_NIMBLE (1) #define MICROPY_BLUETOOTH_NIMBLE_BINDINGS_ONLY (1) #endif -#define MICROPY_PY_HASHLIB_MD5 (1) -#define MICROPY_PY_HASHLIB_SHA1 (1) -#define MICROPY_PY_HASHLIB_SHA256 (1) -#define MICROPY_PY_CRYPTOLIB (1) #define MICROPY_PY_RANDOM_SEED_INIT_FUNC (esp_random()) #define MICROPY_PY_OS_INCLUDEFILE "ports/esp32/modos.c" #define MICROPY_PY_OS_DUPTERM (1) diff --git a/ports/esp8266/boards/ESP8266_GENERIC/mpconfigboard.h b/ports/esp8266/boards/ESP8266_GENERIC/mpconfigboard.h index 1f679961e..cea2267c7 100644 --- a/ports/esp8266/boards/ESP8266_GENERIC/mpconfigboard.h +++ b/ports/esp8266/boards/ESP8266_GENERIC/mpconfigboard.h @@ -12,8 +12,6 @@ #define MICROPY_READER_VFS (MICROPY_VFS) #define MICROPY_VFS (1) -#define MICROPY_PY_CRYPTOLIB (1) - #elif defined(MICROPY_ESP8266_1M) #define MICROPY_HW_BOARD_NAME "ESP module (1M)" @@ -28,9 +26,6 @@ #define MICROPY_READER_VFS (MICROPY_VFS) #define MICROPY_VFS (1) - -#define MICROPY_PY_CRYPTOLIB (1) - #elif defined(MICROPY_ESP8266_512K) #define MICROPY_HW_BOARD_NAME "ESP module (512K)" @@ -45,6 +40,7 @@ #define MICROPY_PY_SYS_STDIO_BUFFER (0) #define MICROPY_PY_ASYNCIO (0) #define MICROPY_PY_RE_SUB (0) +#define MICROPY_PY_CRYPTOLIB (0) #define MICROPY_PY_FRAMEBUF (0) #endif diff --git a/ports/esp8266/mpconfigport.h b/ports/esp8266/mpconfigport.h index 323fba67f..0321de45d 100644 --- a/ports/esp8266/mpconfigport.h +++ b/ports/esp8266/mpconfigport.h @@ -23,6 +23,7 @@ #define MICROPY_OPT_MATH_FACTORIAL (0) #define MICROPY_REPL_EMACS_KEYS (0) #define MICROPY_PY_BUILTINS_COMPLEX (0) +#define MICROPY_MODULE___FILE__ (0) #define MICROPY_PY_DELATTR_SETATTR (0) #define MICROPY_PY_BUILTINS_STR_CENTER (0) #define MICROPY_PY_BUILTINS_STR_PARTITION (0) @@ -32,7 +33,6 @@ #define MICROPY_PY_BUILTINS_EXECFILE (0) #define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0) #define MICROPY_PY_BUILTINS_POW3 (0) -#define MICROPY_PY___FILE__ (0) #define MICROPY_PY_MATH_CONSTANTS (0) #define MICROPY_PY_MATH_SPECIAL_FUNCTIONS (0) #define MICROPY_PY_MATH_FACTORIAL (0) @@ -56,6 +56,7 @@ #define MICROPY_REPL_EVENT_DRIVEN (0) #define MICROPY_USE_INTERNAL_ERRNO (1) #define MICROPY_PY_BUILTINS_HELP_TEXT esp_help_text +#define MICROPY_PY_HASHLIB_MD5 (0) #define MICROPY_PY_HASHLIB_SHA1 (MICROPY_PY_SSL && MICROPY_SSL_AXTLS) #define MICROPY_PY_RANDOM_SEED_INIT_FUNC (*WDEV_HWRNG) #define MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME (1) diff --git a/ports/mimxrt/mpconfigport.h b/ports/mimxrt/mpconfigport.h index 3cf6550d7..d6694badb 100644 --- a/ports/mimxrt/mpconfigport.h +++ b/ports/mimxrt/mpconfigport.h @@ -145,9 +145,6 @@ uint32_t trng_random_u32(void); #define MICROPY_PY_WEBSOCKET (MICROPY_PY_LWIP) #define MICROPY_PY_WEBREPL (MICROPY_PY_LWIP) #define MICROPY_PY_LWIP_SOCK_RAW (MICROPY_PY_LWIP) -#define MICROPY_PY_HASHLIB_MD5 (MICROPY_PY_SSL) -#define MICROPY_PY_HASHLIB_SHA1 (MICROPY_PY_SSL) -#define MICROPY_PY_CRYPTOLIB (MICROPY_PY_SSL) #ifndef MICROPY_PY_NETWORK_PPP_LWIP #define MICROPY_PY_NETWORK_PPP_LWIP (MICROPY_PY_LWIP) #endif diff --git a/ports/nrf/mpconfigport.h b/ports/nrf/mpconfigport.h index 963e1e883..d944fc8a1 100644 --- a/ports/nrf/mpconfigport.h +++ b/ports/nrf/mpconfigport.h @@ -264,6 +264,7 @@ #define MICROPY_ERROR_REPORTING (2) #define MICROPY_FULL_CHECKS (1) #define MICROPY_GC_ALLOC_THRESHOLD (1) +#define MICROPY_MODULE___FILE__ (1) #define MICROPY_MODULE_GETATTR (1) #define MICROPY_MULTIPLE_INHERITANCE (1) #define MICROPY_PY_ARRAY (1) @@ -290,7 +291,6 @@ #define MICROPY_PY_STRUCT (1) #define MICROPY_PY_SYS (1) #define MICROPY_PY_SYS_PATH_ARGV_DEFAULTS (1) -#define MICROPY_PY___FILE__ (1) #endif #ifndef MICROPY_PY_UBLUEPY diff --git a/ports/pic16bit/mpconfigport.h b/ports/pic16bit/mpconfigport.h index 7e6e1c4e0..e95f25aa0 100644 --- a/ports/pic16bit/mpconfigport.h +++ b/ports/pic16bit/mpconfigport.h @@ -43,6 +43,7 @@ #define MICROPY_ENABLE_SOURCE_LINE (0) #define MICROPY_ENABLE_DOC_STRING (0) #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) +#define MICROPY_MODULE___FILE__ (0) #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_BUILTINS_BYTEARRAY (0) #define MICROPY_PY_BUILTINS_MEMORYVIEW (0) @@ -51,7 +52,6 @@ #define MICROPY_PY_BUILTINS_SLICE (0) #define MICROPY_PY_BUILTINS_PROPERTY (0) #define MICROPY_PY_MICROPYTHON_MEM_INFO (1) -#define MICROPY_PY___FILE__ (0) #define MICROPY_PY_GC (1) #define MICROPY_PY_ARRAY (0) #define MICROPY_PY_COLLECTIONS (0) diff --git a/ports/powerpc/mpconfigport.h b/ports/powerpc/mpconfigport.h index 25d85c9e6..091e94bda 100644 --- a/ports/powerpc/mpconfigport.h +++ b/ports/powerpc/mpconfigport.h @@ -57,6 +57,7 @@ #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) #define MICROPY_BUILTIN_METHOD_CHECK_SELF_ARG (0) #define MICROPY_PY_ASYNC_AWAIT (0) +#define MICROPY_MODULE___FILE__ (0) #define MICROPY_MODULE_BUILTIN_INIT (1) #define MICROPY_PY_BUILTINS_BYTEARRAY (1) #define MICROPY_PY_BUILTINS_DICT_FROMKEYS (1) @@ -73,7 +74,6 @@ #define MICROPY_PY_BUILTINS_STR_OP_MODULO (1) #define MICROPY_PY_BUILTINS_HELP (1) #define MICROPY_PY_BUILTINS_HELP_MODULES (1) -#define MICROPY_PY___FILE__ (0) #define MICROPY_PY_GC (1) #define MICROPY_PY_ARRAY (1) #define MICROPY_PY_COLLECTIONS (1) diff --git a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h index 7783c0a17..11aa66329 100644 --- a/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h +++ b/ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h @@ -10,9 +10,6 @@ // Enable networking. #define MICROPY_PY_NETWORK (1) -// Enable MD5 hash. -#define MICROPY_PY_HASHLIB_MD5 (1) - // Disable internal error numbers. #define MICROPY_USE_INTERNAL_ERRNO (0) diff --git a/ports/rp2/mpconfigport.h b/ports/rp2/mpconfigport.h index c312293ac..0c226538c 100644 --- a/ports/rp2/mpconfigport.h +++ b/ports/rp2/mpconfigport.h @@ -150,8 +150,6 @@ #define MICROPY_PY_OS_URANDOM (1) #define MICROPY_PY_RE_MATCH_GROUPS (1) #define MICROPY_PY_RE_MATCH_SPAN_START_END (1) -#define MICROPY_PY_HASHLIB_SHA1 (1) -#define MICROPY_PY_CRYPTOLIB (1) #define MICROPY_PY_TIME_GMTIME_LOCALTIME_MKTIME (1) #define MICROPY_PY_TIME_TIME_TIME_NS (1) #define MICROPY_PY_TIME_INCLUDEFILE "ports/rp2/modtime.c" diff --git a/ports/stm32/eth_phy.h b/ports/stm32/eth_phy.h index 5036905c1..dccfb7951 100644 --- a/ports/stm32/eth_phy.h +++ b/ports/stm32/eth_phy.h @@ -26,7 +26,7 @@ */ #ifndef MICROPY_INCLUDED_STM32_PHY_H -#define MICROPY_INCLUDED_STM32_PYH_H +#define MICROPY_INCLUDED_STM32_PHY_H #if defined(MICROPY_HW_ETH_MDC) diff --git a/ports/stm32/mpconfigport.h b/ports/stm32/mpconfigport.h index 191503cd4..fac261f7e 100644 --- a/ports/stm32/mpconfigport.h +++ b/ports/stm32/mpconfigport.h @@ -97,9 +97,6 @@ #endif // extended modules -#define MICROPY_PY_HASHLIB_MD5 (MICROPY_PY_SSL) -#define MICROPY_PY_HASHLIB_SHA1 (MICROPY_PY_SSL) -#define MICROPY_PY_CRYPTOLIB (MICROPY_PY_SSL) #define MICROPY_PY_OS_INCLUDEFILE "ports/stm32/modos.c" #define MICROPY_PY_OS_DUPTERM (3) #define MICROPY_PY_OS_DUPTERM_BUILTIN_STREAM (1) diff --git a/ports/unix/main.c b/ports/unix/main.c index 5f6b99f98..51d99ce5f 100644 --- a/ports/unix/main.c +++ b/ports/unix/main.c @@ -54,6 +54,7 @@ #include "extmod/vfs_posix.h" #include "genhdr/mpversion.h" #include "input.h" +#include "stack_size.h" // Command line options, with their defaults static bool compile_only = false; @@ -138,7 +139,7 @@ static int execute_from_lexer(int source_kind, const void *source, mp_parse_inpu qstr source_name = lex->source_name; - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ if (input_kind == MP_PARSE_FILE_INPUT) { mp_store_global(MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); } @@ -479,11 +480,7 @@ int main(int argc, char **argv) { #endif // Define a reasonable stack limit to detect stack overflow. - mp_uint_t stack_size = 40000 * (sizeof(void *) / 4); - #if defined(__arm__) && !defined(__thumb2__) - // ARM (non-Thumb) architectures require more stack. - stack_size *= 2; - #endif + mp_uint_t stack_size = 40000 * UNIX_STACK_MULTIPLIER; // We should capture stack top ASAP after start, and it should be // captured guaranteedly before any other stack variables are allocated. diff --git a/ports/unix/mpthreadport.c b/ports/unix/mpthreadport.c index 141cd0218..a41b3ec9f 100644 --- a/ports/unix/mpthreadport.c +++ b/ports/unix/mpthreadport.c @@ -31,6 +31,7 @@ #include "py/runtime.h" #include "py/mpthread.h" #include "py/gc.h" +#include "stack_size.h" #if MICROPY_PY_THREAD @@ -244,9 +245,9 @@ void mp_thread_start(void) { } mp_uint_t mp_thread_create(void *(*entry)(void *), void *arg, size_t *stack_size) { - // default stack size is 8k machine-words + // default stack size if (*stack_size == 0) { - *stack_size = 8192 * sizeof(void *); + *stack_size = 32768 * UNIX_STACK_MULTIPLIER; } // minimum stack size is set by pthreads diff --git a/ports/unix/stack_size.h b/ports/unix/stack_size.h new file mode 100644 index 000000000..f6159bb69 --- /dev/null +++ b/ports/unix/stack_size.h @@ -0,0 +1,54 @@ +/* + * This file is part of the MicroPython project, http://micropython.org/ + * + * The MIT License (MIT) + * + * Copyright (c) 2025 Angus Gratton + * + * 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_UNIX_STACK_SIZE_H +#define MICROPY_INCLUDED_UNIX_STACK_SIZE_H + +#include "py/misc.h" + +// Define scaling factors for the stack size (also applies to main thread) +#ifndef UNIX_STACK_MULTIPLIER + +#if defined(__arm__) && !defined(__thumb2__) +// ARM (non-Thumb) architectures require more stack. +#define UNIX_STACK_MUL_ARM 2 +#else +#define UNIX_STACK_MUL_ARM 1 +#endif + +#if MP_SANITIZER_BUILD +// Sanitizer features consume significant stack in some cases +// This multiplier can probably be removed when using GCC 12 or newer. +#define UNIX_STACK_MUL_SANITIZERS 4 +#else +#define UNIX_STACK_MUL_SANITIZERS 1 +#endif + +// Double the stack size for 64-bit builds, plus additional scaling +#define UNIX_STACK_MULTIPLIER ((sizeof(void *) / 4) * UNIX_STACK_MUL_ARM * UNIX_STACK_MUL_SANITIZERS) + +#endif // UNIX_STACK_MULTIPLIER + +#endif // MICROPY_INCLUDED_UNIX_STACK_SIZE_H diff --git a/ports/unix/variants/mpconfigvariant_common.h b/ports/unix/variants/mpconfigvariant_common.h index 65c874317..1ac59c955 100644 --- a/ports/unix/variants/mpconfigvariant_common.h +++ b/ports/unix/variants/mpconfigvariant_common.h @@ -104,12 +104,6 @@ #define MICROPY_PY_TIME_CUSTOM_SLEEP (1) #define MICROPY_PY_TIME_INCLUDEFILE "ports/unix/modtime.c" -#if MICROPY_PY_SSL -#define MICROPY_PY_HASHLIB_MD5 (1) -#define MICROPY_PY_HASHLIB_SHA1 (1) -#define MICROPY_PY_CRYPTOLIB (1) -#endif - // The "select" module is enabled by default, but disable select.select(). #define MICROPY_PY_SELECT_POSIX_OPTIMISATIONS (1) #define MICROPY_PY_SELECT_SELECT (0) diff --git a/py/asmthumb.c b/py/asmthumb.c index 93860d2fd..58cc7aea8 100644 --- a/py/asmthumb.c +++ b/py/asmthumb.c @@ -267,9 +267,8 @@ bool asm_thumb_b_n_label(asm_thumb_t *as, uint label) { #define OP_BCC_N(cond, byte_offset) (0xd000 | ((cond) << 8) | (((byte_offset) >> 1) & 0x00ff)) -// all these bit-arithmetic operations need coverage testing! -#define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 14) & 0x003f)) -#define OP_BCC_W_LO(byte_offset) (0x8000 | ((byte_offset) & 0x2000) | (((byte_offset) >> 1) & 0x0fff)) +#define OP_BCC_W_HI(cond, byte_offset) (0xf000 | ((cond) << 6) | (((byte_offset) >> 10) & 0x0400) | (((byte_offset) >> 12) & 0x003f)) +#define OP_BCC_W_LO(byte_offset) (0x8000 | (((byte_offset) >> 5) & 0x2000) | (((byte_offset) >> 8) & 0x0800) | (((byte_offset) >> 1) & 0x07ff)) bool asm_thumb_bcc_nw_label(asm_thumb_t *as, int cond, uint label, bool wide) { mp_uint_t dest = get_label_dest(as, label); diff --git a/py/builtinimport.c b/py/builtinimport.c index 0611926fd..a2737a03e 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -153,7 +153,7 @@ static mp_import_stat_t stat_top_level(qstr mod_name, vstr_t *dest) { #if MICROPY_MODULE_FROZEN_STR || MICROPY_ENABLE_COMPILER static void do_load_from_lexer(mp_module_context_t *context, mp_lexer_t *lex) { - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ qstr source_name = lex->source_name; mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #endif @@ -166,7 +166,7 @@ static void do_load_from_lexer(mp_module_context_t *context, mp_lexer_t *lex) { #if (MICROPY_HAS_FILE_READER && MICROPY_PERSISTENT_CODE_LOAD) || MICROPY_MODULE_FROZEN_MPY static void do_execute_proto_fun(const mp_module_context_t *context, mp_proto_fun_t proto_fun, qstr source_name) { - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ mp_store_attr(MP_OBJ_FROM_PTR(&context->module), MP_QSTR___file__, MP_OBJ_NEW_QSTR(source_name)); #else (void)source_name; @@ -225,7 +225,7 @@ static void do_load(mp_module_context_t *module_obj, vstr_t *file) { if (frozen_type == MP_FROZEN_MPY) { const mp_frozen_module_t *frozen = modref; module_obj->constants = frozen->constants; - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ qstr frozen_file_qstr = qstr_from_str(file_str + frozen_path_prefix_len); #else qstr frozen_file_qstr = MP_QSTRnull; @@ -43,6 +43,11 @@ typedef unsigned int uint; #ifndef __has_builtin #define __has_builtin(x) (0) #endif +#ifndef __has_feature +// This macro is supported by Clang and gcc>=14 +#define __has_feature(x) (0) +#endif + /** generic ops *************************************************/ @@ -538,4 +543,23 @@ inline static bool mp_sub_ll_overflow(long long int lhs, long long int rhs, long } #endif + +// Helper macros for detecting if sanitizers are enabled +// +// Use sparingly, not for masking issues reported by sanitizers! +// +// Can be detected automatically in Clang and gcc>=14, need to be +// set manually otherwise. +#ifndef MP_UBSAN +#define MP_UBSAN __has_feature(undefined_behavior_sanitizer) +#endif + +#ifndef MP_ASAN +#define MP_ASAN __has_feature(address_sanitizer) +#endif + +#ifndef MP_SANITIZER_BUILD +#define MP_SANITIZER_BUILD (MP_UBSAN || MP_ASAN) +#endif + #endif // MICROPY_INCLUDED_PY_MISC_H diff --git a/py/mpconfig.h b/py/mpconfig.h index 5fe0e822f..877b262c8 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -990,6 +990,16 @@ typedef time_t mp_timestamp_t; #define MICROPY_STREAMS_POSIX_API (0) #endif +// Whether to process __all__ when importing all public symbols from a module. +#ifndef MICROPY_MODULE___ALL__ +#define MICROPY_MODULE___ALL__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_BASIC_FEATURES) +#endif + +// Whether to set __file__ on imported modules. +#ifndef MICROPY_MODULE___FILE__ +#define MICROPY_MODULE___FILE__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) +#endif + // Whether modules can use MP_REGISTER_MODULE_DELEGATION() to delegate failed // attribute lookups to a custom handler function. #ifndef MICROPY_MODULE_ATTR_DELEGATION @@ -1422,16 +1432,6 @@ typedef time_t mp_timestamp_t; #define MICROPY_PY_BUILTINS_HELP_MODULES (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) #endif -// Whether to set __file__ for imported modules -#ifndef MICROPY_PY___FILE__ -#define MICROPY_PY___FILE__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_CORE_FEATURES) -#endif - -// Whether to process __all__ when importing all public symbols from module -#ifndef MICROPY_MODULE___ALL__ -#define MICROPY_MODULE___ALL__ (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_BASIC_FEATURES) -#endif - // Whether to provide mem-info related functions in micropython module #ifndef MICROPY_PY_MICROPYTHON_MEM_INFO #define MICROPY_PY_MICROPYTHON_MEM_INFO (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) @@ -1860,11 +1860,11 @@ typedef time_t mp_timestamp_t; #endif #ifndef MICROPY_PY_HASHLIB_MD5 -#define MICROPY_PY_HASHLIB_MD5 (0) +#define MICROPY_PY_HASHLIB_MD5 (MICROPY_PY_SSL) #endif #ifndef MICROPY_PY_HASHLIB_SHA1 -#define MICROPY_PY_HASHLIB_SHA1 (0) +#define MICROPY_PY_HASHLIB_SHA1 (MICROPY_PY_SSL) #endif #ifndef MICROPY_PY_HASHLIB_SHA256 @@ -1872,7 +1872,7 @@ typedef time_t mp_timestamp_t; #endif #ifndef MICROPY_PY_CRYPTOLIB -#define MICROPY_PY_CRYPTOLIB (0) +#define MICROPY_PY_CRYPTOLIB (MICROPY_PY_SSL) #endif // Depends on MICROPY_PY_CRYPTOLIB diff --git a/py/objmodule.c b/py/objmodule.c index 5ce373b83..5ee2f7dc8 100644 --- a/py/objmodule.c +++ b/py/objmodule.c @@ -44,7 +44,7 @@ static void module_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kin module_name = mp_obj_str_get_str(elem->value); } - #if MICROPY_PY___FILE__ + #if MICROPY_MODULE___FILE__ // If we store __file__ to imported modules then try to lookup this // symbol to give more information about the module. elem = mp_map_lookup(&self->globals->map, MP_OBJ_NEW_QSTR(MP_QSTR___file__), MP_MAP_LOOKUP); diff --git a/py/objtype.c b/py/objtype.c index 25c2dee99..d40f619fa 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -1292,8 +1292,7 @@ static mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals mp_raise_TypeError(MP_ERROR_TEXT("multiple bases have instance lay-out conflict")); } - mp_map_t *locals_map = &MP_OBJ_TYPE_GET_SLOT(o, locals_dict)->map; - mp_map_elem_t *elem = mp_map_lookup(locals_map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); + mp_map_elem_t *elem = mp_map_lookup(&locals_ptr->map, MP_OBJ_NEW_QSTR(MP_QSTR___new__), MP_MAP_LOOKUP); if (elem != NULL) { // __new__ slot exists; check if it is a function if (mp_obj_is_fun(elem->value)) { diff --git a/tests/micropython/viper_large_jump.py b/tests/micropython/viper_large_jump.py new file mode 100644 index 000000000..1c5913dec --- /dev/null +++ b/tests/micropython/viper_large_jump.py @@ -0,0 +1,20 @@ +COUNT = 600 + + +try: + code = """ +@micropython.viper +def f() -> int: + x = 0 + while x < 10: +""" + for i in range(COUNT): + code += " x += 1\n" + code += " return x" + exec(code) +except MemoryError: + print("SKIP-TOO-LARGE") + raise SystemExit + + +print(f()) diff --git a/tests/micropython/viper_large_jump.py.exp b/tests/micropython/viper_large_jump.py.exp new file mode 100644 index 000000000..e9f960cf4 --- /dev/null +++ b/tests/micropython/viper_large_jump.py.exp @@ -0,0 +1 @@ +600 diff --git a/tests/stress/recursive_iternext.py b/tests/stress/recursive_iternext.py index bbc389e72..c737f1e36 100644 --- a/tests/stress/recursive_iternext.py +++ b/tests/stress/recursive_iternext.py @@ -1,4 +1,8 @@ # This tests that recursion with iternext doesn't lead to segfault. +# +# This test segfaults CPython, but that's not a bug as CPython doesn't enforce +# limits on C recursion - see +# https://github.com/python/cpython/issues/58218#issuecomment-1093570209 try: enumerate filter @@ -9,49 +13,25 @@ except: print("SKIP") raise SystemExit -# We need to pick an N that is large enough to hit the recursion -# limit, but not too large that we run out of heap memory. -try: - # large stack/heap, eg unix - [0] * 80000 - N = 5000 -except: - try: - # medium, eg pyboard - [0] * 10000 - N = 1000 - except: - # small, eg esp8266 - N = 100 - -try: - x = (1, 2) - for i in range(N): - x = enumerate(x) - tuple(x) -except RuntimeError: - print("RuntimeError") -try: +# Progressively build a bigger nested iterator structure (10 at a time for speed), +# and then try to evaluate it via tuple(x) which makes deep recursive function calls. +# +# Eventually this should raise a RuntimeError as MicroPython runs out of stack. +# It shouldn't ever raise a MemoryError, if it does then somehow MicroPython has +# run out of heap (for the nested structure) before running out of stack. +def recurse_iternext(nested_fn): x = (1, 2) - for i in range(N): - x = filter(None, x) - tuple(x) -except RuntimeError: - print("RuntimeError") + while True: + for _ in range(10): + x = nested_fn(x) + try: + tuple(x) + except RuntimeError: + print("RuntimeError") + break -try: - x = (1, 2) - for i in range(N): - x = map(max, x, ()) - tuple(x) -except RuntimeError: - print("RuntimeError") -try: - x = (1, 2) - for i in range(N): - x = zip(x) - tuple(x) -except RuntimeError: - print("RuntimeError") +# Test on various nested iterator structures +for nested_fn in [enumerate, lambda x: filter(None, x), lambda x: map(max, x, ()), zip]: + recurse_iternext(nested_fn) diff --git a/tools/ci.sh b/tools/ci.sh index 9152c2e2d..e165cb2cf 100755 --- a/tools/ci.sh +++ b/tools/ci.sh @@ -518,14 +518,14 @@ CI_UNIX_OPTS_QEMU_RISCV64=( ) CI_UNIX_OPTS_SANITIZE_ADDRESS=( - VARIANT=coverage - CFLAGS_EXTRA="-fsanitize=address --param asan-use-after-return=0" + # Macro MP_ASAN allows detecting ASan on gcc<=13 + CFLAGS_EXTRA="-fsanitize=address --param asan-use-after-return=0 -DMP_ASAN=1" LDFLAGS_EXTRA="-fsanitize=address --param asan-use-after-return=0" ) CI_UNIX_OPTS_SANITIZE_UNDEFINED=( - VARIANT=coverage - CFLAGS_EXTRA="-fsanitize=undefined -fno-sanitize=nonnull-attribute" + # Macro MP_UBSAN allows detecting UBSan on gcc<=13 + CFLAGS_EXTRA="-fsanitize=undefined -fno-sanitize=nonnull-attribute -DMP_UBSAN=1" LDFLAGS_EXTRA="-fsanitize=undefined -fno-sanitize=nonnull-attribute" ) @@ -699,7 +699,7 @@ function ci_unix_nanbox_run_tests { } function ci_unix_longlong_build { - ci_unix_build_helper VARIANT=longlong + ci_unix_build_helper VARIANT=longlong "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" } function ci_unix_longlong_run_tests { @@ -765,23 +765,23 @@ function ci_unix_settrace_stackless_run_tests { function ci_unix_sanitize_undefined_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix submodules - make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" + make ${MAKEOPTS} -C ports/unix VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" ci_unix_build_ffi_lib_helper gcc } function ci_unix_sanitize_undefined_run_tests { - MICROPY_TEST_TIMEOUT=60 ci_unix_run_tests_full_helper coverage "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" + MICROPY_TEST_TIMEOUT=60 ci_unix_run_tests_full_helper coverage VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_UNDEFINED[@]}" } function ci_unix_sanitize_address_build { make ${MAKEOPTS} -C mpy-cross make ${MAKEOPTS} -C ports/unix submodules - make ${MAKEOPTS} -C ports/unix "${CI_UNIX_OPTS_SANITIZE_ADDRESS[@]}" + make ${MAKEOPTS} -C ports/unix VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_ADDRESS[@]}" ci_unix_build_ffi_lib_helper gcc } function ci_unix_sanitize_address_run_tests { - MICROPY_TEST_TIMEOUT=60 ci_unix_run_tests_full_helper coverage "${CI_UNIX_OPTS_SANITIZE_ADDRESS[@]}" + MICROPY_TEST_TIMEOUT=60 ci_unix_run_tests_full_helper coverage VARIANT=coverage "${CI_UNIX_OPTS_SANITIZE_ADDRESS[@]}" } function ci_unix_macos_build { |