Created
December 10, 2024 00:06
-
-
Save jepler/181ab2c5ccd4175d3635d459ee739e2c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
From 7188d09390183a4333562fcb6bba7f93b85d5ac4 Mon Sep 17 00:00:00 2001 | |
From: Jeff Epler <[email protected]> | |
Date: Mon, 9 Dec 2024 18:06:17 -0600 | |
Subject: [PATCH] proof of concept: mpy-cross -mno-long | |
This causes an OverflowError to be raised if an integer constant doesn't | |
fit on builds without long int support. | |
Hypothetically, circuitpython-build-tools could first run mpy-cross with | |
this flag; if it fails, put into some new metadata file "requires | |
long integers" and run again without the flag. | |
--- | |
mpy-cross/main.c | 3 +++ | |
py/mpstate.h | 1 + | |
py/persistentcode.c | 26 ++++++++++++++++++++++++++ | |
3 files changed, 30 insertions(+) | |
diff --git a/mpy-cross/main.c b/mpy-cross/main.c | |
index 611da76468..83913f33e8 100644 | |
--- a/mpy-cross/main.c | |
+++ b/mpy-cross/main.c | |
@@ -274,6 +274,9 @@ MP_NOINLINE int main_(int argc, char **argv) { | |
} | |
a += 1; | |
source_file = backslash_to_forwardslash(argv[a]); | |
+ } else if (strcmp(argv[a], "-mno-long") == 0) { | |
+ mp_printf(&mp_plat_print, "no-long"); | |
+ mp_dynamic_compiler.no_long_int = true; | |
} else if (strncmp(argv[a], "-msmall-int-bits=", sizeof("-msmall-int-bits=") - 1) == 0) { | |
char *end; | |
mp_dynamic_compiler.small_int_bits = | |
diff --git a/py/mpstate.h b/py/mpstate.h | |
index 7308e57b58..f1709b68b5 100644 | |
--- a/py/mpstate.h | |
+++ b/py/mpstate.h | |
@@ -74,6 +74,7 @@ typedef struct mp_dynamic_compiler_t { | |
uint8_t small_int_bits; // must be <= host small_int_bits | |
uint8_t native_arch; | |
uint8_t nlr_buf_num_regs; | |
+ bool no_long_int; | |
} mp_dynamic_compiler_t; | |
extern mp_dynamic_compiler_t mp_dynamic_compiler; | |
#endif | |
diff --git a/py/persistentcode.c b/py/persistentcode.c | |
index 09beeef451..ae69f99dea 100644 | |
--- a/py/persistentcode.c | |
+++ b/py/persistentcode.c | |
@@ -69,6 +69,7 @@ typedef struct _bytecode_prelude_t { | |
#include "py/parsenum.h" | |
+} | |
static int read_byte(mp_reader_t *reader); | |
static size_t read_uint(mp_reader_t *reader); | |
@@ -476,6 +477,30 @@ void mp_raw_code_load_file(qstr filename, mp_compiled_module_t *context) { | |
#include "py/objstr.h" | |
+static void small_int_check(mp_obj_t o) { | |
+ #if MICROPY_DYNAMIC_COMPILER | |
+ if (!mp_dynamic_compiler.no_long_int) { | |
+ return; | |
+ } | |
+ if (!mp_obj_is_int(o)) { | |
+ return; | |
+ } | |
+ bool fail = false; | |
+ if (!mp_obj_is_small_int(o)) { | |
+ fail = true; | |
+ } else { | |
+ mp_int_t arg = MP_OBJ_SMALL_INT_VALUE(o); | |
+ mp_uint_t sign_mask = -((mp_uint_t)1 << (mp_dynamic_compiler.small_int_bits - 1)); | |
+ if (!((arg & sign_mask) == 0 || (arg & sign_mask) == sign_mask)) { | |
+ fail = true; | |
+ } | |
+ } | |
+ if (fail) { | |
+ mp_raise_type(&mp_type_OverflowError); | |
+ } | |
+ #endif | |
+} | |
+ | |
static void mp_print_bytes(mp_print_t *print, const byte *data, size_t len) { | |
print->print_strn(print->data, (const char *)data, len); | |
} | |
@@ -551,6 +576,7 @@ static void save_obj(mp_print_t *print, mp_obj_t o) { | |
byte obj_type; | |
if (mp_obj_is_int(o)) { | |
obj_type = MP_PERSISTENT_OBJ_INT; | |
+ small_int_check(o); | |
#if MICROPY_PY_BUILTINS_COMPLEX | |
} else if (mp_obj_is_type(o, &mp_type_complex)) { | |
obj_type = MP_PERSISTENT_OBJ_COMPLEX; | |
-- | |
2.39.5 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment