summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mpy-cross/main.c2
-rw-r--r--mpy-cross/mpconfigport.h2
-rw-r--r--ports/alif/mpconfigport.h3
-rw-r--r--ports/esp32/mpconfigport.h4
-rw-r--r--ports/esp8266/boards/ESP8266_GENERIC/mpconfigboard.h6
-rw-r--r--ports/esp8266/mpconfigport.h3
-rw-r--r--ports/mimxrt/mpconfigport.h3
-rw-r--r--ports/nrf/mpconfigport.h2
-rw-r--r--ports/pic16bit/mpconfigport.h2
-rw-r--r--ports/powerpc/mpconfigport.h2
-rw-r--r--ports/rp2/boards/ARDUINO_NANO_RP2040_CONNECT/mpconfigboard.h3
-rw-r--r--ports/rp2/mpconfigport.h2
-rw-r--r--ports/stm32/eth_phy.h2
-rw-r--r--ports/stm32/mpconfigport.h3
-rw-r--r--ports/unix/main.c9
-rw-r--r--ports/unix/mpthreadport.c5
-rw-r--r--ports/unix/stack_size.h54
-rw-r--r--ports/unix/variants/mpconfigvariant_common.h6
-rw-r--r--py/asmthumb.c5
-rw-r--r--py/builtinimport.c6
-rw-r--r--py/misc.h24
-rw-r--r--py/mpconfig.h26
-rw-r--r--py/objmodule.c2
-rw-r--r--py/objtype.c3
-rw-r--r--tests/micropython/viper_large_jump.py20
-rw-r--r--tests/micropython/viper_large_jump.py.exp1
-rw-r--r--tests/stress/recursive_iternext.py64
-rwxr-xr-xtools/ci.sh18
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;
diff --git a/py/misc.h b/py/misc.h
index 5c1cc2f7a..081163cad 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -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 {