summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--bare-arm/mpconfigport.h5
-rw-r--r--py/bc.h15
-rw-r--r--py/binary.c6
-rw-r--r--py/builtin.c4
-rw-r--r--py/builtintables.c12
-rw-r--r--py/compile.c2
-rw-r--r--py/modcmath.c4
-rw-r--r--py/modmath.c4
-rw-r--r--py/mpconfig.h28
-rw-r--r--py/mpz.c2
-rw-r--r--py/mpz.h2
-rw-r--r--py/obj.c2
-rw-r--r--py/obj.h10
-rw-r--r--py/objarray.c5
-rw-r--r--py/objcomplex.c2
-rw-r--r--py/objfloat.c4
-rw-r--r--py/objfun.c2
-rw-r--r--py/objgenerator.c51
-rw-r--r--py/objint.c6
-rw-r--r--py/objint_longlong.c2
-rw-r--r--py/objint_mpz.c6
-rw-r--r--py/objlist.c6
-rw-r--r--py/objproperty.c4
-rw-r--r--py/objset.c20
-rw-r--r--py/objslice.c2
-rw-r--r--py/objstr.c64
-rw-r--r--py/objtuple.c2
-rw-r--r--py/objtype.c4
-rw-r--r--py/parsenum.c4
-rw-r--r--py/pfenv.c4
-rw-r--r--py/pfenv.h2
-rw-r--r--py/qstrdefs.h4
-rw-r--r--py/runtime.c10
-rw-r--r--py/runtime0.h4
-rw-r--r--py/sequence.c4
-rw-r--r--py/showbc.c2
-rw-r--r--py/vm.c120
-rw-r--r--stmhal/accel.c17
-rw-r--r--stmhal/boards/stm32f4xx-af.csv2
-rw-r--r--stmhal/modtime.c4
-rw-r--r--stmhal/mpconfigport.h2
-rw-r--r--stmhal/printf.c4
-rw-r--r--stmhal/servo.c4
-rw-r--r--teensy/mpconfigport.h2
-rw-r--r--tests/basics/for_break.py12
-rw-r--r--tests/basics/for_return.py7
-rw-r--r--tests/micropython/heapalloc.py26
-rwxr-xr-xtests/run-tests15
-rw-r--r--unix/modtime.c6
-rw-r--r--unix/mpconfigport.h2
-rw-r--r--windows/mpconfigport.h2
51 files changed, 304 insertions, 231 deletions
diff --git a/bare-arm/mpconfigport.h b/bare-arm/mpconfigport.h
index 3a3c8615d0..73b66802fe 100644
--- a/bare-arm/mpconfigport.h
+++ b/bare-arm/mpconfigport.h
@@ -12,13 +12,16 @@
#define MICROPY_HELPER_REPL (0)
#define MICROPY_HELPER_LEXER_UNIX (0)
#define MICROPY_ENABLE_SOURCE_LINE (0)
+#define MICROPY_PY_BUILTINS_FROZENSET (0)
+#define MICROPY_PY_BUILTINS_SET (0)
+#define MICROPY_PY_BUILTINS_SLICE (0)
+#define MICROPY_PY_BUILTINS_PROPERTY (0)
#define MICROPY_PY_COLLECTIONS (0)
#define MICROPY_PY_MATH (0)
#define MICROPY_PY_CMATH (0)
#define MICROPY_PY_IO (0)
#define MICROPY_PY_STRUCT (0)
#define MICROPY_PY_SYS (0)
-#define MICROPY_PY_PROPERTY (0)
#define MICROPY_CPYTHON_COMPAT (0)
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
diff --git a/py/bc.h b/py/bc.h
index 6c1e45b2b3..6c604fe1c0 100644
--- a/py/bc.h
+++ b/py/bc.h
@@ -36,8 +36,21 @@ typedef struct _mp_exc_stack {
byte opcode;
} mp_exc_stack_t;
+typedef struct _mp_code_state {
+ const byte *code_info;
+ const byte *ip;
+ mp_obj_t *sp;
+ // bit 0 is saved currently_in_except_block value
+ mp_exc_stack_t *exc_sp;
+ uint n_state;
+ // Variable-length
+ mp_obj_t state[0];
+ // Variable-length, never accessed by name, only as (void*)(state + n_state)
+ //mp_exc_stack_t exc_state[0];
+} mp_code_state;
+
mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args, uint n_args, const mp_obj_t *args2, uint n_args2, mp_obj_t *ret);
-mp_vm_return_kind_t mp_execute_bytecode2(const byte *code_info, const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **sp_in_out, mp_exc_stack_t *exc_stack, mp_exc_stack_t **exc_sp_in_out, volatile mp_obj_t inject_exc);
+mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_obj_t inject_exc);
void mp_bytecode_print(const byte *code, int len);
void mp_bytecode_print2(const byte *code, int len);
diff --git a/py/binary.c b/py/binary.c
index 7640b7590d..cec2374460 100644
--- a/py/binary.c
+++ b/py/binary.c
@@ -114,7 +114,7 @@ mp_obj_t mp_binary_get_val_array(char typecode, void *p, int index) {
// TODO: Explode API more to cover signedness
return mp_obj_new_int_from_ll(((long long*)p)[index]);
#endif
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
case 'f':
return mp_obj_new_float(((float*)p)[index]);
case 'd':
@@ -217,7 +217,7 @@ void mp_binary_set_val(char struct_type, char val_type, mp_obj_t val_in, byte **
void mp_binary_set_val_array(char typecode, void *p, int index, mp_obj_t val_in) {
switch (typecode) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
case 'f':
((float*)p)[index] = mp_obj_float_get(val_in);
break;
@@ -260,7 +260,7 @@ void mp_binary_set_val_array_from_int(char typecode, void *p, int index, machine
((long long*)p)[index] = val;
break;
#endif
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
case 'f':
((float*)p)[index] = val;
break;
diff --git a/py/builtin.c b/py/builtin.c
index 178a6835aa..c336378109 100644
--- a/py/builtin.c
+++ b/py/builtin.c
@@ -37,7 +37,7 @@
#include "runtime.h"
#include "builtin.h"
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
#include <math.h>
#endif
@@ -104,7 +104,7 @@ mp_obj_t mp_builtin_abs(mp_obj_t o_in) {
val = -val;
}
return MP_OBJ_NEW_SMALL_INT(val);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
} else if (MP_OBJ_IS_TYPE(o_in, &mp_type_float)) {
mp_float_t value = mp_obj_float_get(o_in);
// TODO check for NaN etc
diff --git a/py/builtintables.c b/py/builtintables.c
index 1d22683d97..628514da1c 100644
--- a/py/builtintables.c
+++ b/py/builtintables.c
@@ -44,27 +44,29 @@ STATIC const mp_map_elem_t mp_builtin_object_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_bool), (mp_obj_t)&mp_type_bool },
{ MP_OBJ_NEW_QSTR(MP_QSTR_bytes), (mp_obj_t)&mp_type_bytes },
{ MP_OBJ_NEW_QSTR(MP_QSTR_bytearray), (mp_obj_t)&mp_type_bytearray },
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
{ MP_OBJ_NEW_QSTR(MP_QSTR_complex), (mp_obj_t)&mp_type_complex },
#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_dict), (mp_obj_t)&mp_type_dict },
{ MP_OBJ_NEW_QSTR(MP_QSTR_enumerate), (mp_obj_t)&mp_type_enumerate },
{ MP_OBJ_NEW_QSTR(MP_QSTR_filter), (mp_obj_t)&mp_type_filter },
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
{ MP_OBJ_NEW_QSTR(MP_QSTR_float), (mp_obj_t)&mp_type_float },
#endif
-#if MICROPY_PY_FROZENSET
+#if MICROPY_PY_BUILTINS_FROZENSET
{ MP_OBJ_NEW_QSTR(MP_QSTR_frozenset), (mp_obj_t)&mp_type_frozenset },
#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_int), (mp_obj_t)&mp_type_int },
{ MP_OBJ_NEW_QSTR(MP_QSTR_list), (mp_obj_t)&mp_type_list },
{ MP_OBJ_NEW_QSTR(MP_QSTR_map), (mp_obj_t)&mp_type_map },
{ MP_OBJ_NEW_QSTR(MP_QSTR_object), (mp_obj_t)&mp_type_object },
-#if MICROPY_PY_PROPERTY
+#if MICROPY_PY_BUILTINS_PROPERTY
{ MP_OBJ_NEW_QSTR(MP_QSTR_property), (mp_obj_t)&mp_type_property },
#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_range), (mp_obj_t)&mp_type_range },
+#if MICROPY_PY_BUILTINS_SET
{ MP_OBJ_NEW_QSTR(MP_QSTR_set), (mp_obj_t)&mp_type_set },
+#endif
{ MP_OBJ_NEW_QSTR(MP_QSTR_str), (mp_obj_t)&mp_type_str },
{ MP_OBJ_NEW_QSTR(MP_QSTR_super), (mp_obj_t)&mp_type_super },
{ MP_OBJ_NEW_QSTR(MP_QSTR_tuple), (mp_obj_t)&mp_type_tuple },
@@ -169,7 +171,7 @@ STATIC const mp_map_elem_t mp_builtin_module_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&mp_module_struct },
#endif
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&mp_module_math },
#if MICROPY_PY_CMATH
{ MP_OBJ_NEW_QSTR(MP_QSTR_cmath), (mp_obj_t)&mp_module_cmath },
diff --git a/py/compile.c b/py/compile.c
index c90772a7e3..1f0d90570e 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1745,7 +1745,7 @@ void compile_while_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
// And, if the loop never runs, the loop variable should never be assigned
void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var, mp_parse_node_t pn_start, mp_parse_node_t pn_end, mp_parse_node_t pn_step, mp_parse_node_t pn_body, mp_parse_node_t pn_else) {
START_BREAK_CONTINUE_BLOCK
- comp->break_label |= MP_EMIT_BREAK_FROM_FOR;
+ // note that we don't need to pop anything when breaking from an optimise for loop
uint top_label = comp_next_label(comp);
uint entry_label = comp_next_label(comp);
diff --git a/py/modcmath.c b/py/modcmath.c
index 9e4de2585f..3bc3055dc8 100644
--- a/py/modcmath.c
+++ b/py/modcmath.c
@@ -32,7 +32,7 @@
#include "obj.h"
#include "builtin.h"
-#if MICROPY_ENABLE_FLOAT && MICROPY_PY_CMATH
+#if MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_CMATH
// These are defined in modmath.c
extern const mp_obj_float_t mp_math_e_obj;
@@ -154,4 +154,4 @@ const mp_obj_module_t mp_module_cmath = {
.globals = (mp_obj_dict_t*)&mp_module_cmath_globals,
};
-#endif // MICROPY_ENABLE_FLOAT && MICROPY_PY_CMATH
+#endif // MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_CMATH
diff --git a/py/modmath.c b/py/modmath.c
index e0ff163436..0fd583c2ff 100644
--- a/py/modmath.c
+++ b/py/modmath.c
@@ -32,7 +32,7 @@
#include "obj.h"
#include "builtin.h"
-#if MICROPY_ENABLE_FLOAT && MICROPY_PY_MATH
+#if MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_MATH
//TODO: Change macros to check for overflow and raise OverflowError or RangeError
#define MATH_FUN_1(py_name, c_name) \
@@ -184,4 +184,4 @@ const mp_obj_module_t mp_module_math = {
.globals = (mp_obj_dict_t*)&mp_module_math_globals,
};
-#endif // MICROPY_ENABLE_FLOAT && MICROPY_PY_MATH
+#endif // MICROPY_PY_BUILTINS_FLOAT && MICROPY_PY_MATH
diff --git a/py/mpconfig.h b/py/mpconfig.h
index 1af27f7679..77b76bf13d 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -212,15 +212,15 @@ typedef long long mp_longint_impl_t;
#endif
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
-#define MICROPY_ENABLE_FLOAT (1)
+#define MICROPY_PY_BUILTINS_FLOAT (1)
#define MICROPY_FLOAT_C_FUN(fun) fun##f
typedef float mp_float_t;
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
-#define MICROPY_ENABLE_FLOAT (1)
+#define MICROPY_PY_BUILTINS_FLOAT (1)
#define MICROPY_FLOAT_C_FUN(fun) fun
typedef double mp_float_t;
#else
-#define MICROPY_ENABLE_FLOAT (0)
+#define MICROPY_PY_BUILTINS_FLOAT (0)
#endif
// Enable features which improve CPython compatibility
@@ -239,20 +239,24 @@ typedef double mp_float_t;
/*****************************************************************************/
/* Fine control over Python builtins, classes, modules, etc */
-// Whether to support slice object and correspondingly
-// slice subscript operators
-#ifndef MICROPY_PY_SLICE
-#define MICROPY_PY_SLICE (1)
+// Whether to support set object
+#ifndef MICROPY_PY_BUILTINS_SET
+#define MICROPY_PY_BUILTINS_SET (1)
+#endif
+
+// Whether to support slice subscript operators and slice object
+#ifndef MICROPY_PY_BUILTINS_SLICE
+#define MICROPY_PY_BUILTINS_SLICE (1)
#endif
// Whether to support frozenset object
-#ifndef MICROPY_PY_FROZENSET
-#define MICROPY_PY_FROZENSET (0)
+#ifndef MICROPY_PY_BUILTINS_FROZENSET
+#define MICROPY_PY_BUILTINS_FROZENSET (0)
#endif
-// Whether to support the property object
-#ifndef MICROPY_PY_PROPERTY
-#define MICROPY_PY_PROPERTY (1)
+// Whether to support property object
+#ifndef MICROPY_PY_BUILTINS_PROPERTY
+#define MICROPY_PY_BUILTINS_PROPERTY (1)
#endif
// Whether to provide "collections" module
diff --git a/py/mpz.c b/py/mpz.c
index 9c42878ff8..ab300b91df 100644
--- a/py/mpz.c
+++ b/py/mpz.c
@@ -1262,7 +1262,7 @@ bool mpz_as_int_checked(const mpz_t *i, machine_int_t *value) {
return true;
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mpz_as_float(const mpz_t *i) {
mp_float_t val = 0;
mpz_dig_t *d = i->dig + i->len;
diff --git a/py/mpz.h b/py/mpz.h
index 654be21c09..0f962cc024 100644
--- a/py/mpz.h
+++ b/py/mpz.h
@@ -98,7 +98,7 @@ mpz_t *mpz_mod(const mpz_t *lhs, const mpz_t *rhs);
machine_int_t mpz_as_int(const mpz_t *z);
bool mpz_as_int_checked(const mpz_t *z, machine_int_t *value);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mpz_as_float(const mpz_t *z);
#endif
uint mpz_as_str_size(const mpz_t *z, uint base);
diff --git a/py/obj.c b/py/obj.c
index f8b5ee34d9..6d0966db24 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -257,7 +257,7 @@ bool mp_obj_get_int_maybe(mp_const_obj_t arg, machine_int_t *value) {
return true;
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mp_obj_get_float(mp_obj_t arg) {
if (arg == mp_const_false) {
return 0;
diff --git a/py/obj.h b/py/obj.h
index 185fe14db0..7c83715111 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -371,7 +371,7 @@ mp_obj_t mp_obj_new_int_from_str_len(const char **str, uint len, bool neg, uint
mp_obj_t mp_obj_new_int_from_ll(long long val); // this must return a multi-precision integer object (or raise an overflow exception)
mp_obj_t mp_obj_new_str(const char* data, uint len, bool make_qstr_if_not_already);
mp_obj_t mp_obj_new_bytes(const byte* data, uint len);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_obj_t mp_obj_new_float(mp_float_t val);
mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag);
#endif
@@ -420,7 +420,7 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2);
machine_int_t mp_obj_get_int(mp_const_obj_t arg);
bool mp_obj_get_int_maybe(mp_const_obj_t arg, machine_int_t *value);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mp_obj_get_float(mp_obj_t self_in);
void mp_obj_get_complex(mp_obj_t self_in, mp_float_t *real, mp_float_t *imag);
#endif
@@ -442,7 +442,7 @@ void mp_obj_cell_set(mp_obj_t self_in, mp_obj_t obj);
// int
// For long int, returns value truncated to machine_int_t
machine_int_t mp_obj_int_get(mp_const_obj_t self_in);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mp_obj_int_as_float(mp_obj_t self_in);
#endif
// Will raise exception if value doesn't fit into machine_int_t
@@ -470,7 +470,7 @@ const char *mp_obj_str_get_str(mp_obj_t self_in); // use this only if you need t
const char *mp_obj_str_get_data(mp_obj_t self_in, uint *len);
void mp_str_print_quoted(void (*print)(void *env, const char *fmt, ...), void *env, const byte *str_data, uint str_len);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
// float
typedef struct _mp_obj_float_t {
mp_obj_base_t base;
@@ -568,7 +568,9 @@ typedef struct {
} mp_bound_slice_t;
void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest);
+#if MICROPY_PY_BUILTINS_SLICE
bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes);
+#endif
#define mp_seq_copy(dest, src, len, item_t) memcpy(dest, src, len * sizeof(item_t))
#define mp_seq_cat(dest, src1, len1, src2, len2, item_t) { memcpy(dest, src1, (len1) * sizeof(item_t)); memcpy(dest + (len1), src2, (len2) * sizeof(item_t)); }
bool mp_seq_cmp_bytes(int op, const byte *data1, uint len1, const byte *data2, uint len2);
diff --git a/py/objarray.c b/py/objarray.c
index 91fcec624a..44fbf2f998 100644
--- a/py/objarray.c
+++ b/py/objarray.c
@@ -169,7 +169,9 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
return MP_OBJ_NULL; // op not supported
} else {
mp_obj_array_t *o = self_in;
- if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
+ if (0) {
+#if MICROPY_PY_BUILTINS_SLICE
+ } else if (MP_OBJ_IS_TYPE(index_in, &mp_type_slice)) {
if (value != MP_OBJ_SENTINEL) {
// Only getting a slice is suported so far, not assignment
// TODO: confirmed that both bytearray and array.array support
@@ -187,6 +189,7 @@ STATIC mp_obj_t array_subscr(mp_obj_t self_in, mp_obj_t index_in, mp_obj_t value
byte *p = o->items;
memcpy(res->items, p + slice.start * sz, (slice.stop - slice.start) * sz);
return res;
+#endif
} else {
uint index = mp_get_index(o->base.type, o->len, index_in, false);
if (value == MP_OBJ_SENTINEL) {
diff --git a/py/objcomplex.c b/py/objcomplex.c
index 80a13c6d8f..d58b53463c 100644
--- a/py/objcomplex.c
+++ b/py/objcomplex.c
@@ -36,7 +36,7 @@
#include "runtime0.h"
#include "runtime.h"
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
#include <math.h>
diff --git a/py/objfloat.c b/py/objfloat.c
index 6732f31215..b608b1a3d7 100644
--- a/py/objfloat.c
+++ b/py/objfloat.c
@@ -39,7 +39,7 @@
#include "runtime0.h"
#include "runtime.h"
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
#include "formatfloat.h"
@@ -170,4 +170,4 @@ mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) {
return mp_obj_new_float(lhs_val);
}
-#endif // MICROPY_ENABLE_FLOAT
+#endif // MICROPY_PY_BUILTINS_FLOAT
diff --git a/py/objfun.c b/py/objfun.c
index 8ee5365d5d..77d57821b9 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -469,7 +469,7 @@ STATIC machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) {
} else {
mp_obj_type_t *type = mp_obj_get_type(obj);
if (0) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
} else if (type == &mp_type_float) {
// convert float to int (could also pass in float registers)
return (machine_int_t)mp_obj_float_get(obj);
diff --git a/py/objgenerator.c b/py/objgenerator.c
index d9825f814f..7326bced30 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -82,42 +82,31 @@ mp_obj_t mp_obj_new_gen_wrap(mp_obj_t fun) {
typedef struct _mp_obj_gen_instance_t {
mp_obj_base_t base;
mp_obj_dict_t *globals;
- const byte *code_info;
- const byte *ip;
- mp_obj_t *sp;
- // bit 0 is saved currently_in_except_block value
- mp_exc_stack_t *exc_sp;
- uint n_state;
- // Variable-length
- mp_obj_t state[0];
- // Variable-length, never accessed by name, only as (void*)(state + n_state)
- //mp_exc_stack_t exc_state[0];
+ mp_code_state code_state;
} mp_obj_gen_instance_t;
void gen_instance_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_gen_instance_t *self = self_in;
- print(env, "<generator object '%s' at %p>", mp_obj_code_get_name(self->code_info), self_in);
+ print(env, "<generator object '%s' at %p>", mp_obj_code_get_name(self->code_state.code_info), self_in);
}
mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) {
assert(MP_OBJ_IS_TYPE(self_in, &mp_type_gen_instance));
mp_obj_gen_instance_t *self = self_in;
- if (self->ip == 0) {
+ if (self->code_state.ip == 0) {
*ret_val = MP_OBJ_STOP_ITERATION;
return MP_VM_RETURN_NORMAL;
}
- if (self->sp == self->state - 1) {
+ if (self->code_state.sp == self->code_state.state - 1) {
if (send_value != mp_const_none) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "can't send non-None value to a just-started generator"));
}
} else {
- *self->sp = send_value;
+ *self->code_state.sp = send_value;
}
mp_obj_dict_t *old_globals = mp_globals_get();
mp_globals_set(self->globals);
- mp_vm_return_kind_t ret_kind = mp_execute_bytecode2(self->code_info, &self->ip,
- &self->state[self->n_state - 1], &self->sp, (mp_exc_stack_t*)(self->state + self->n_state),
- &self->exc_sp, throw_value);
+ mp_vm_return_kind_t ret_kind = mp_execute_bytecode2(&self->code_state, throw_value);
mp_globals_set(old_globals);
switch (ret_kind) {
@@ -127,17 +116,17 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
// again and again, leading to side effects.
// TODO: check how return with value behaves under such conditions
// in CPython.
- self->ip = 0;
- *ret_val = *self->sp;
+ self->code_state.ip = 0;
+ *ret_val = *self->code_state.sp;
break;
case MP_VM_RETURN_YIELD:
- *ret_val = *self->sp;
+ *ret_val = *self->code_state.sp;
break;
case MP_VM_RETURN_EXCEPTION:
- self->ip = 0;
- *ret_val = self->state[self->n_state - 1];
+ self->code_state.ip = 0;
+ *ret_val = self->code_state.state[self->code_state.n_state - 1];
break;
default:
@@ -269,32 +258,32 @@ mp_obj_t mp_obj_new_gen_instance(mp_obj_dict_t *globals, const byte *bytecode,
mp_obj_gen_instance_t *o = m_new_obj_var(mp_obj_gen_instance_t, byte, n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t));
o->base.type = &mp_type_gen_instance;
o->globals = globals;
- o->code_info = code_info;
- o->sp = &o->state[0] - 1; // sp points to top of stack, which starts off 1 below the state
- o->exc_sp = (mp_exc_stack_t*)(o->state + n_state) - 1;
- o->n_state = n_state;
+ o->code_state.code_info = code_info;
+ o->code_state.sp = &o->code_state.state[0] - 1; // sp points to top of stack, which starts off 1 below the state
+ o->code_state.exc_sp = (mp_exc_stack_t*)(o->code_state.state + n_state) - 1;
+ o->code_state.n_state = n_state;
// copy args to end of state array, in reverse (that's how mp_execute_bytecode2 needs it)
for (uint i = 0; i < n_args; i++) {
- o->state[n_state - 1 - i] = args[i];
+ o->code_state.state[n_state - 1 - i] = args[i];
}
for (uint i = 0; i < n_args2; i++) {
- o->state[n_state - 1 - n_args - i] = args2[i];
+ o->code_state.state[n_state - 1 - n_args - i] = args2[i];
}
// set rest of state to MP_OBJ_NULL
for (uint i = 0; i < n_state - n_args - n_args2; i++) {
- o->state[i] = MP_OBJ_NULL;
+ o->code_state.state[i] = MP_OBJ_NULL;
}
// bytecode prelude: initialise closed over variables
for (uint n_local = *bytecode++; n_local > 0; n_local--) {
uint local_num = *bytecode++;
- o->state[n_state - 1 - local_num] = mp_obj_new_cell(o->state[n_state - 1 - local_num]);
+ o->code_state.state[n_state - 1 - local_num] = mp_obj_new_cell(o->code_state.state[n_state - 1 - local_num]);
}
// set ip to start of actual byte code
- o->ip = bytecode;
+ o->code_state.ip = bytecode;
return o;
}
diff --git a/py/objint.c b/py/objint.c
index f631d698f3..74b7564550 100644
--- a/py/objint.c
+++ b/py/objint.c
@@ -41,7 +41,7 @@
#include "runtime0.h"
#include "runtime.h"
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
#include <math.h>
#endif
@@ -62,7 +62,7 @@ STATIC mp_obj_t mp_obj_int_make_new(mp_obj_t type_in, uint n_args, uint n_kw, co
uint l;
const char *s = mp_obj_str_get_data(args[0], &l);
return mp_parse_num_integer(s, l, 0);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
} else if (MP_OBJ_IS_TYPE(args[0], &mp_type_float)) {
return MP_OBJ_NEW_SMALL_INT((machine_int_t)(MICROPY_FLOAT_C_FUN(trunc)(mp_obj_float_get(args[0]))));
#endif
@@ -267,7 +267,7 @@ machine_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
return MP_OBJ_SMALL_INT_VALUE(self_in);
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mp_obj_int_as_float(mp_obj_t self_in) {
return MP_OBJ_SMALL_INT_VALUE(self_in);
}
diff --git a/py/objint_longlong.c b/py/objint_longlong.c
index 82db9e6608..dfe069c087 100644
--- a/py/objint_longlong.c
+++ b/py/objint_longlong.c
@@ -188,7 +188,7 @@ machine_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
return mp_obj_int_get(self_in);
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mp_obj_int_as_float(mp_obj_t self_in) {
if (MP_OBJ_IS_SMALL_INT(self_in)) {
return MP_OBJ_SMALL_INT_VALUE(self_in);
diff --git a/py/objint_mpz.c b/py/objint_mpz.c
index 9cdbb71688..516fb52746 100644
--- a/py/objint_mpz.c
+++ b/py/objint_mpz.c
@@ -118,7 +118,7 @@ mp_obj_t mp_obj_int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
zrhs = &z_int;
} else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_int)) {
zrhs = &((mp_obj_int_t*)rhs_in)->mpz;
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
} else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_float)) {
return mp_obj_float_binary_op(op, mpz_as_float(zlhs), rhs_in);
} else if (MP_OBJ_IS_TYPE(rhs_in, &mp_type_complex)) {
@@ -130,7 +130,7 @@ mp_obj_t mp_obj_int_binary_op(int op, mp_obj_t lhs_in, mp_obj_t rhs_in) {
}
if (0) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
} else if (op == MP_BINARY_OP_TRUE_DIVIDE || op == MP_BINARY_OP_INPLACE_TRUE_DIVIDE) {
mp_float_t flhs = mpz_as_float(zlhs);
mp_float_t frhs = mpz_as_float(zrhs);
@@ -292,7 +292,7 @@ machine_int_t mp_obj_int_get_checked(mp_const_obj_t self_in) {
}
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
mp_float_t mp_obj_int_as_float(mp_obj_t self_in) {
if (MP_OBJ_IS_SMALL_INT(self_in)) {
return MP_OBJ_SMALL_INT_VALUE(self_in);
diff --git a/py/objlist.c b/py/objlist.c
index 647096f0dd..6e22169fd9 100644
--- a/py/objlist.c
+++ b/py/objlist.c
@@ -150,7 +150,7 @@ STATIC mp_obj_t list_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
if (value == MP_OBJ_NULL) {
// delete
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
mp_obj_list_t *self = self_in;
mp_bound_slice_t slice;
@@ -174,7 +174,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
} else if (value == MP_OBJ_SENTINEL) {
// load
mp_obj_list_t *self = self_in;
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
mp_bound_slice_t slice;
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
@@ -188,7 +188,7 @@ STATIC mp_obj_t list_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
uint index_val = mp_get_index(self->base.type, self->len, index, false);
return self->items[index_val];
} else {
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
mp_obj_list_t *self = self_in;
assert(MP_OBJ_IS_TYPE(value, &mp_type_list));
diff --git a/py/objproperty.c b/py/objproperty.c
index 147a755a42..5a9311ac96 100644
--- a/py/objproperty.c
+++ b/py/objproperty.c
@@ -34,7 +34,7 @@
#include "obj.h"
#include "runtime.h"
-#if MICROPY_PY_PROPERTY
+#if MICROPY_PY_BUILTINS_PROPERTY
typedef struct _mp_obj_property_t {
mp_obj_base_t base;
@@ -115,4 +115,4 @@ const mp_obj_t *mp_obj_property_get(mp_obj_t self_in) {
return self->proxy;
}
-#endif // MICROPY_PY_PROPERTY
+#endif // MICROPY_PY_BUILTINS_PROPERTY
diff --git a/py/objset.c b/py/objset.c
index 6a6a375faa..ab76b57642 100644
--- a/py/objset.c
+++ b/py/objset.c
@@ -37,6 +37,8 @@
#include "runtime0.h"
#include "builtin.h"
+#if MICROPY_PY_BUILTINS_SET
+
typedef struct _mp_obj_set_t {
mp_obj_base_t base;
mp_set_t set;
@@ -52,13 +54,13 @@ STATIC mp_obj_t set_it_iternext(mp_obj_t self_in);
STATIC bool is_set_or_frozenset(mp_obj_t o) {
return MP_OBJ_IS_TYPE(o, &mp_type_set)
-#if MICROPY_PY_FROZENSET
+#if MICROPY_PY_BUILTINS_FROZENSET
|| MP_OBJ_IS_TYPE(o, &mp_type_frozenset)
#endif
;
}
-#if MICROPY_PY_FROZENSET
+#if MICROPY_PY_BUILTINS_FROZENSET
STATIC void check_set_or_frozenset(mp_obj_t o) {
if (!is_set_or_frozenset(o)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'set' object required"));
@@ -72,7 +74,7 @@ STATIC void check_set(mp_obj_t o) {
if (!MP_OBJ_IS_TYPE(o, &mp_type_set)) {
// Emulate CPython behavior
// AttributeError: 'frozenset' object has no attribute 'add'
- #if MICROPY_PY_FROZENSET
+ #if MICROPY_PY_BUILTINS_FROZENSET
if (MP_OBJ_IS_TYPE(o, &mp_type_frozenset)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError, "'frozenset' has no such attribute"));
}
@@ -83,11 +85,11 @@ STATIC void check_set(mp_obj_t o) {
STATIC void set_print(void (*print)(void *env, const char *fmt, ...), void *env, mp_obj_t self_in, mp_print_kind_t kind) {
mp_obj_set_t *self = self_in;
- #if MICROPY_PY_FROZENSET
+ #if MICROPY_PY_BUILTINS_FROZENSET
bool is_frozen = MP_OBJ_IS_TYPE(self_in, &mp_type_frozenset);
#endif
if (self->set.used == 0) {
- #if MICROPY_PY_FROZENSET
+ #if MICROPY_PY_BUILTINS_FROZENSET
if (is_frozen) {
print(env, "frozen");
}
@@ -96,7 +98,7 @@ STATIC void set_print(void (*print)(void *env, const char *fmt, ...), void *env,
return;
}
bool first = true;
- #if MICROPY_PY_FROZENSET
+ #if MICROPY_PY_BUILTINS_FROZENSET
if (is_frozen) {
print(env, "frozenset(");
}
@@ -112,7 +114,7 @@ STATIC void set_print(void (*print)(void *env, const char *fmt, ...), void *env,
}
}
print(env, "}");
- #if MICROPY_PY_FROZENSET
+ #if MICROPY_PY_BUILTINS_FROZENSET
if (is_frozen) {
print(env, ")");
}
@@ -556,7 +558,7 @@ const mp_obj_type_t mp_type_set = {
.locals_dict = (mp_obj_t)&set_locals_dict,
};
-#if MICROPY_PY_FROZENSET
+#if MICROPY_PY_BUILTINS_FROZENSET
const mp_obj_type_t mp_type_frozenset = {
{ &mp_type_type },
.name = MP_QSTR_frozenset,
@@ -584,3 +586,5 @@ void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item) {
mp_obj_set_t *self = self_in;
mp_set_lookup(&self->set, item, MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
}
+
+#endif // MICROPY_PY_BUILTINS_SET
diff --git a/py/objslice.c b/py/objslice.c
index dfd070f8d0..6324c0e49b 100644
--- a/py/objslice.c
+++ b/py/objslice.c
@@ -56,7 +56,7 @@ const mp_obj_ellipsis_t mp_const_ellipsis_obj = {{&mp_type_ellipsis}};
/******************************************************************************/
/* slice object */
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
// TODO: This implements only variant of slice with 2 integer args only.
// CPython supports 3rd arg (step), plus args can be arbitrary Python objects.
diff --git a/py/objstr.c b/py/objstr.c
index 27f6d9cd6f..9ff9106375 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -348,7 +348,7 @@ STATIC mp_obj_t str_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
GET_STR_DATA_LEN(self_in, self_data, self_len);
if (value == MP_OBJ_SENTINEL) {
// load
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
mp_bound_slice_t slice;
if (!mp_seq_get_fast_slice_indexes(self_len, index, &slice)) {
@@ -741,14 +741,14 @@ static bool arg_looks_integer(mp_obj_t arg) {
static bool arg_looks_numeric(mp_obj_t arg) {
return arg_looks_integer(arg)
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
|| MP_OBJ_IS_TYPE(arg, &mp_type_float)
#endif
;
}
static mp_obj_t arg_as_int(mp_obj_t arg) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
// TODO: Needs a way to construct an mpz integer from a float
@@ -1066,7 +1066,7 @@ mp_obj_t mp_obj_str_format(uint n_args, const mp_obj_t *args) {
flags |= PF_FLAG_PAD_NAN_INF; // '{:06e}'.format(float('-inf')) should give '-00inf'
switch (type) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
case 'e':
case 'E':
case 'f':
@@ -1214,7 +1214,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, uint n_args, const mp_obj_t
pfenv_print_strn(&pfenv_vstr, &ch, 1, flags, ' ', width);
break;
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
// This is what CPython reports, so we report the same.
if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "integer argument expected, got float"));
@@ -1230,7 +1230,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, uint n_args, const mp_obj_t
pfenv_print_mp_int(&pfenv_vstr, arg_as_int(arg), 1, 10, 'a', flags, fill, width);
break;
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
case 'e':
case 'E':
case 'f':
@@ -1476,73 +1476,47 @@ STATIC mp_obj_t str_rpartition(mp_obj_t self_in, mp_obj_t arg) {
return str_partitioner(self_in, arg, -1);
}
-enum { CASE_UPPER, CASE_LOWER };
-
// Supposedly not too critical operations, so optimize for code size
-STATIC mp_obj_t str_caseconv(int op, mp_obj_t self_in) {
+STATIC mp_obj_t str_caseconv(unichar (*op)(unichar), mp_obj_t self_in) {
GET_STR_DATA_LEN(self_in, self_data, self_len);
byte *data;
mp_obj_t s = mp_obj_str_builder_start(mp_obj_get_type(self_in), self_len, &data);
for (int i = 0; i < self_len; i++) {
- if (op == CASE_UPPER) {
- *data++ = unichar_toupper(*self_data++);
- } else {
- *data++ = unichar_tolower(*self_data++);
- }
+ *data++ = op(*self_data++);
}
*data = 0;
return mp_obj_str_builder_end(s);
}
STATIC mp_obj_t str_lower(mp_obj_t self_in) {
- return str_caseconv(CASE_LOWER, self_in);
+ return str_caseconv(unichar_tolower, self_in);
}
STATIC mp_obj_t str_upper(mp_obj_t self_in) {
- return str_caseconv(CASE_UPPER, self_in);
+ return str_caseconv(unichar_toupper, self_in);
}
-enum { IS_SPACE, IS_ALPHA, IS_DIGIT, IS_UPPER, IS_LOWER };
-
-STATIC mp_obj_t str_uni_istype(int type, mp_obj_t self_in) {
+STATIC mp_obj_t str_uni_istype(bool (*f)(unichar), mp_obj_t self_in) {
GET_STR_DATA_LEN(self_in, self_data, self_len);
if (self_len == 0) {
return mp_const_false; // default to False for empty str
}
- typedef bool (*check_function)(unichar);
- check_function f;
-
- if (type != IS_UPPER && type != IS_LOWER) {
- switch (type) {
- case IS_SPACE: f = &unichar_isspace; break;
- case IS_ALPHA: f = &unichar_isalpha; break;
- case IS_DIGIT: f = &unichar_isdigit; break;
- default:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unknown type provided for str_uni_istype"));
- }
-
+ if (f != unichar_isupper && f != unichar_islower) {
for (int i = 0; i < self_len; i++) {
if (!f(*self_data++)) {
return mp_const_false;
}
}
} else {
- switch (type) {
- case IS_UPPER: f = &unichar_isupper; break;
- case IS_LOWER: f = &unichar_islower; break;
- default:
- nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unknown type provided for str_uni_istype"));
- }
-
bool contains_alpha = false;
for (int i = 0; i < self_len; i++) { // only check alphanumeric characters
if (unichar_isalpha(*self_data++)) {
contains_alpha = true;
- if (!f(*(self_data-1))) {
- return mp_const_false; // we already incremented
+ if (!f(*(self_data - 1))) { // -1 because we already incremented above
+ return mp_const_false;
}
}
}
@@ -1556,23 +1530,23 @@ STATIC mp_obj_t str_uni_istype(int type, mp_obj_t self_in) {
}
STATIC mp_obj_t str_isspace(mp_obj_t self_in) {
- return str_uni_istype(IS_SPACE, self_in);
+ return str_uni_istype(unichar_isspace, self_in);
}
STATIC mp_obj_t str_isalpha(mp_obj_t self_in) {
- return str_uni_istype(IS_ALPHA, self_in);
+ return str_uni_istype(unichar_isalpha, self_in);
}
STATIC mp_obj_t str_isdigit(mp_obj_t self_in) {
- return str_uni_istype(IS_DIGIT, self_in);
+ return str_uni_istype(unichar_isdigit, self_in);
}
STATIC mp_obj_t str_isupper(mp_obj_t self_in) {
- return str_uni_istype(IS_UPPER, self_in);
+ return str_uni_istype(unichar_isupper, self_in);
}
STATIC mp_obj_t str_islower(mp_obj_t self_in) {
- return str_uni_istype(IS_LOWER, self_in);
+ return str_uni_istype(unichar_islower, self_in);
}
#if MICROPY_CPYTHON_COMPAT
diff --git a/py/objtuple.c b/py/objtuple.c
index c0a33dad7e..fc97f53cf2 100644
--- a/py/objtuple.c
+++ b/py/objtuple.c
@@ -161,7 +161,7 @@ mp_obj_t mp_obj_tuple_subscr(mp_obj_t self_in, mp_obj_t index, mp_obj_t value) {
if (value == MP_OBJ_SENTINEL) {
// load
mp_obj_tuple_t *self = self_in;
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
if (MP_OBJ_IS_TYPE(index, &mp_type_slice)) {
mp_bound_slice_t slice;
if (!mp_seq_get_fast_slice_indexes(self->len, index, &slice)) {
diff --git a/py/objtype.c b/py/objtype.c
index 0561282b8a..ebbb6097dd 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -413,7 +413,7 @@ STATIC void instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
mp_obj_class_lookup(self, self->base.type, attr, 0, dest);
mp_obj_t member = dest[0];
if (member != MP_OBJ_NULL) {
-#if MICROPY_PY_PROPERTY
+#if MICROPY_PY_BUILTINS_PROPERTY
if (MP_OBJ_IS_TYPE(member, &mp_type_property)) {
// object member is a property
// delegate the store to the property
@@ -447,7 +447,7 @@ STATIC void instance_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
STATIC bool instance_store_attr(mp_obj_t self_in, qstr attr, mp_obj_t value) {
mp_obj_instance_t *self = self_in;
-#if MICROPY_PY_PROPERTY
+#if MICROPY_PY_BUILTINS_PROPERTY
// for property, we need to do a lookup first in the class dict
// this makes all stores slow... how to fix?
mp_obj_t member[2] = {MP_OBJ_NULL};
diff --git a/py/parsenum.c b/py/parsenum.c
index 9729ffe64a..2e513e5159 100644
--- a/py/parsenum.c
+++ b/py/parsenum.c
@@ -36,7 +36,7 @@
#include "parsenum.h"
#include "smallint.h"
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
#include <math.h>
#endif
@@ -144,7 +144,7 @@ value_error:
#define PARSE_DEC_IN_EXP (3)
mp_obj_t mp_parse_num_decimal(const char *str, uint len, bool allow_imag, bool force_complex) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
const char *top = str + len;
mp_float_t dec_val = 0;
bool dec_neg = false;
diff --git a/py/pfenv.c b/py/pfenv.c
index c1a2eee0df..e4db4da046 100644
--- a/py/pfenv.c
+++ b/py/pfenv.c
@@ -39,7 +39,7 @@
#include <stdio.h>
#endif
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
#include "formatfloat.h"
#endif
@@ -266,7 +266,7 @@ int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int
return len;
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
int pfenv_print_float(const pfenv_t *pfenv, mp_float_t f, char fmt, int flags, char fill, int width, int prec) {
char buf[32];
char sign = '\0';
diff --git a/py/pfenv.h b/py/pfenv.h
index 4c902c6bc2..2a3de6c32d 100644
--- a/py/pfenv.h
+++ b/py/pfenv.h
@@ -46,6 +46,6 @@ void pfenv_vstr_add_strn(void *data, const char *str, unsigned int len);
int pfenv_print_strn(const pfenv_t *pfenv, const char *str, unsigned int len, int flags, char fill, int width);
int pfenv_print_int(const pfenv_t *pfenv, machine_uint_t x, int sgn, int base, int base_char, int flags, char fill, int width);
int pfenv_print_mp_int(const pfenv_t *pfenv, mp_obj_t x, int sgn, int base, int base_char, int flags, char fill, int width);
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
int pfenv_print_float(const pfenv_t *pfenv, mp_float_t f, char fmt, int flags, char fill, int width, int prec);
#endif
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index 4ee56db909..69182f2809 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -263,7 +263,7 @@ Q(iterator)
Q(module)
Q(slice)
-#if MICROPY_PY_FROZENSET
+#if MICROPY_PY_BUILTINS_FROZENSET
Q(frozenset)
#endif
@@ -375,7 +375,7 @@ Q(disable)
Q(enable)
#endif
-#if MICROPY_PY_PROPERTY
+#if MICROPY_PY_BUILTINS_PROPERTY
Q(property)
Q(getter)
Q(setter)
diff --git a/py/runtime.c b/py/runtime.c
index a9d57460ac..ecaf40deb4 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -353,7 +353,7 @@ mp_obj_t mp_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
lhs_val = mp_small_int_floor_divide(lhs_val, rhs_val);
break;
- #if MICROPY_ENABLE_FLOAT
+ #if MICROPY_PY_BUILTINS_FLOAT
case MP_BINARY_OP_TRUE_DIVIDE:
case MP_BINARY_OP_INPLACE_TRUE_DIVIDE:
if (rhs_val == 0) {
@@ -371,7 +371,7 @@ mp_obj_t mp_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
case MP_BINARY_OP_POWER:
case MP_BINARY_OP_INPLACE_POWER:
if (rhs_val < 0) {
- #if MICROPY_ENABLE_FLOAT
+ #if MICROPY_PY_BUILTINS_FLOAT
lhs = mp_obj_new_float(lhs_val);
goto generic_binary_op;
#else
@@ -418,7 +418,7 @@ mp_obj_t mp_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
} else {
return mp_obj_new_int(lhs_val);
}
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
} else if (MP_OBJ_IS_TYPE(rhs, &mp_type_float)) {
mp_obj_t res = mp_obj_float_binary_op(op, lhs_val, rhs);
if (res == MP_OBJ_NULL) {
@@ -1173,8 +1173,10 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_obj_list_append,
mp_obj_new_dict,
mp_obj_dict_store,
+#if MICROPY_PY_BUILTINS_SET
mp_obj_new_set,
mp_obj_set_store,
+#endif
mp_make_function_from_raw_code,
mp_call_function_n_kw_for_native,
mp_call_method_n_kw,
@@ -1183,7 +1185,9 @@ void *const mp_fun_table[MP_F_NUMBER_OF] = {
mp_import_name,
mp_import_from,
mp_import_all,
+#if MICROPY_PY_BUILTINS_SLICE
mp_obj_new_slice,
+#endif
mp_unpack_sequence,
mp_unpack_ex,
};
diff --git a/py/runtime0.h b/py/runtime0.h
index 542edf4a62..eea578237a 100644
--- a/py/runtime0.h
+++ b/py/runtime0.h
@@ -115,8 +115,10 @@ typedef enum {
MP_F_LIST_APPEND,
MP_F_BUILD_MAP,
MP_F_STORE_MAP,
+#if MICROPY_PY_BUILTINS_SET
MP_F_BUILD_SET,
MP_F_STORE_SET,
+#endif
MP_F_MAKE_FUNCTION_FROM_RAW_CODE,
MP_F_CALL_FUNCTION_N_KW_FOR_NATIVE,
MP_F_CALL_METHOD_N_KW,
@@ -125,7 +127,9 @@ typedef enum {
MP_F_IMPORT_NAME,
MP_F_IMPORT_FROM,
MP_F_IMPORT_ALL,
+#if MICROPY_PY_BUILTINS_SLICE
MP_F_NEW_SLICE,
+#endif
MP_F_UNPACK_SEQUENCE,
MP_F_UNPACK_EX,
MP_F_NUMBER_OF,
diff --git a/py/sequence.c b/py/sequence.c
index c940d9f69f..c73f3baba1 100644
--- a/py/sequence.c
+++ b/py/sequence.c
@@ -51,6 +51,8 @@ void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void
}
}
+#if MICROPY_PY_BUILTINS_SLICE
+
bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, mp_bound_slice_t *indexes) {
mp_obj_t ostart, ostop, ostep;
machine_int_t start, stop;
@@ -102,6 +104,8 @@ bool mp_seq_get_fast_slice_indexes(machine_uint_t len, mp_obj_t slice, mp_bound_
return true;
}
+#endif
+
mp_obj_t mp_seq_extract_slice(uint len, const mp_obj_t *seq, mp_bound_slice_t *indexes) {
machine_int_t start = indexes->start, stop = indexes->stop;
machine_int_t step = indexes->step;
diff --git a/py/showbc.c b/py/showbc.c
index 33c59dcba9..fc02f4c580 100644
--- a/py/showbc.c
+++ b/py/showbc.c
@@ -419,7 +419,7 @@ void mp_bytecode_print2(const byte *ip, int len) {
printf("SET_ADD " UINT_FMT, unum);
break;
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
case MP_BC_BUILD_SLICE:
DECODE_UINT;
printf("BUILD_SLICE " UINT_FMT, unum);
diff --git a/py/vm.c b/py/vm.c
index c04eb89547..cfb390bae7 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -28,6 +28,7 @@
#include <stdio.h>
#include <string.h>
#include <assert.h>
+#include <alloca.h>
#include "mpconfig.h"
#include "nlr.h"
@@ -40,11 +41,10 @@
#include "bc.h"
#include "objgenerator.h"
-// With these macros you can tune the maximum number of state slots
+// With these macros you can tune the maximum number of function state bytes
// that will be allocated on the stack. Any function that needs more
// than this will use the heap.
-#define VM_MAX_STATE_ON_STACK (10)
-#define VM_MAX_EXC_STATE_ON_STACK (4)
+#define VM_MAX_STATE_ON_STACK (10 * sizeof(machine_uint_t))
#define DETECT_VM_STACK_OVERFLOW (0)
#if 0
@@ -93,7 +93,7 @@ typedef enum {
#define PUSH_EXC_BLOCK() \
DECODE_ULABEL; /* except labels are always forward */ \
++exc_sp; \
- exc_sp->opcode = *save_ip; \
+ exc_sp->opcode = *code_state->ip; \
exc_sp->handler = ip + unum; \
exc_sp->val_sp = MP_TAGPTR_MAKE(sp, currently_in_except_block); \
exc_sp->prev_exc = MP_OBJ_NULL; \
@@ -117,47 +117,54 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args,
ip += 4;
// allocate state for locals and stack
- mp_obj_t temp_state[VM_MAX_STATE_ON_STACK];
- mp_obj_t *state = &temp_state[0];
#if DETECT_VM_STACK_OVERFLOW
n_state += 1;
#endif
- if (n_state > VM_MAX_STATE_ON_STACK) {
- state = m_new(mp_obj_t, n_state);
- }
- mp_obj_t *sp = &state[0] - 1;
- // allocate state for exceptions
- mp_exc_stack_t exc_state[VM_MAX_EXC_STATE_ON_STACK];
- mp_exc_stack_t *exc_stack = &exc_state[0];
- if (n_exc_stack > VM_MAX_EXC_STATE_ON_STACK) {
- exc_stack = m_new(mp_exc_stack_t, n_exc_stack);
+ int state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
+ mp_code_state *code_state;
+ if (state_size > VM_MAX_STATE_ON_STACK) {
+ code_state = m_new_obj_var(mp_code_state, byte, state_size);
+ } else {
+ code_state = alloca(sizeof(mp_code_state) + state_size);
}
- mp_exc_stack_t *exc_sp = &exc_stack[0] - 1;
+
+ code_state->code_info = code;
+ code_state->sp = &code_state->state[0] - 1;
+ code_state->exc_sp = (mp_exc_stack_t*)(code_state->state + n_state) - 1;
+ code_state->n_state = n_state;
// init args
for (uint i = 0; i < n_args; i++) {
- state[n_state - 1 - i] = args[i];
+ code_state->state[n_state - 1 - i] = args[i];
}
for (uint i = 0; i < n_args2; i++) {
- state[n_state - 1 - n_args - i] = args2[i];
+ code_state->state[n_state - 1 - n_args - i] = args2[i];
}
// set rest of state to MP_OBJ_NULL
for (uint i = 0; i < n_state - n_args - n_args2; i++) {
- state[i] = MP_OBJ_NULL;
+ code_state->state[i] = MP_OBJ_NULL;
}
// bytecode prelude: initialise closed over variables
for (uint n_local = *ip++; n_local > 0; n_local--) {
uint local_num = *ip++;
- state[n_state - 1 - local_num] = mp_obj_new_cell(state[n_state - 1 - local_num]);
+ code_state->state[n_state - 1 - local_num] = mp_obj_new_cell(code_state->state[n_state - 1 - local_num]);
}
+ code_state->ip = ip;
+
// execute the byte code
- mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode2(code, &ip, &state[n_state - 1], &sp, exc_stack, &exc_sp, MP_OBJ_NULL);
+ mp_vm_return_kind_t vm_return_kind = mp_execute_bytecode2(code_state, MP_OBJ_NULL);
#if DETECT_VM_STACK_OVERFLOW
+ if (vm_return_kind == MP_VM_RETURN_NORMAL) {
+ if (code_state->sp < code_state->state) {
+ printf("VM stack underflow: " INT_FMT "\n", code_state->sp - code_state->state);
+ assert(0);
+ }
+ }
// We can't check the case when an exception is returned in state[n_state - 1]
// and there are no arguments, because in this case our detection slot may have
// been overwritten by the returned exception (which is allowed).
@@ -165,13 +172,13 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args,
// Just check to see that we have at least 1 null object left in the state.
bool overflow = true;
for (uint i = 0; i < n_state - n_args - n_args2; i++) {
- if (state[i] == MP_OBJ_NULL) {
+ if (code_state->state[i] == MP_OBJ_NULL) {
overflow = false;
break;
}
}
if (overflow) {
- printf("VM stack overflow state=%p n_state+1=%u\n", state, n_state);
+ printf("VM stack overflow state=%p n_state+1=" UINT_FMT "\n", code_state->state, n_state);
assert(0);
}
}
@@ -181,13 +188,13 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args,
switch (vm_return_kind) {
case MP_VM_RETURN_NORMAL:
// return value is in *sp
- *ret = *sp;
+ *ret = *code_state->sp;
ret_kind = MP_VM_RETURN_NORMAL;
break;
case MP_VM_RETURN_EXCEPTION:
// return value is in state[n_state - 1]
- *ret = state[n_state - 1];
+ *ret = code_state->state[n_state - 1];
ret_kind = MP_VM_RETURN_EXCEPTION;
break;
@@ -196,18 +203,13 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args,
assert(0);
*ret = mp_const_none;
ret_kind = MP_VM_RETURN_NORMAL;
+ break;
}
// free the state if it was allocated on the heap
- if (n_state > VM_MAX_STATE_ON_STACK) {
- m_free(state, n_state);
- }
-
- // free the exception state if it was allocated on the heap
- if (n_exc_stack > VM_MAX_EXC_STATE_ON_STACK) {
- m_free(exc_stack, n_exc_stack);
+ if (state_size > VM_MAX_STATE_ON_STACK) {
+ m_del_var(mp_code_state, byte, state_size, code_state);
}
-
return ret_kind;
}
@@ -217,15 +219,12 @@ mp_vm_return_kind_t mp_execute_bytecode(const byte *code, const mp_obj_t *args,
// MP_VM_RETURN_NORMAL, sp valid, return value in *sp
// MP_VM_RETURN_YIELD, ip, sp valid, yielded value in *sp
// MP_VM_RETURN_EXCEPTION, exception in fastn[0]
-mp_vm_return_kind_t mp_execute_bytecode2(const byte *code_info, const byte **ip_in_out,
- mp_obj_t *fastn, mp_obj_t **sp_in_out,
- mp_exc_stack_t *exc_stack, mp_exc_stack_t **exc_sp_in_out,
- volatile mp_obj_t inject_exc) {
+mp_vm_return_kind_t mp_execute_bytecode2(mp_code_state *code_state, volatile mp_obj_t inject_exc) {
#if MICROPY_OPT_COMPUTED_GOTO
#include "vmentrytable.h"
#define DISPATCH() do { \
TRACE(ip); \
- save_ip = ip; \
+ code_state->ip = ip; \
goto *entry_table[*ip++]; \
} while(0)
#define ENTRY(op) entry_##op
@@ -242,11 +241,13 @@ mp_vm_return_kind_t mp_execute_bytecode2(const byte *code_info, const byte **ip_
// loop and the exception handler, leading to very obscure bugs.
#define RAISE(o) do { nlr_pop(); nlr.ret_val = o; goto exception_handler; } while(0)
+ // Pointers which are constant for particular invocation of mp_execute_bytecode2()
+ mp_obj_t *const fastn = &code_state->state[code_state->n_state - 1];
+ mp_exc_stack_t *const exc_stack = (mp_exc_stack_t*)(code_state->state + code_state->n_state);
+
// variables that are visible to the exception handler (declared volatile)
- volatile bool currently_in_except_block = MP_TAGPTR_TAG(*exc_sp_in_out); // 0 or 1, to detect nested exceptions
- mp_exc_stack_t *volatile exc_sp = MP_TAGPTR_PTR(*exc_sp_in_out); // stack grows up, exc_sp points to top of stack
- const byte *volatile save_ip = *ip_in_out; // this is so we can access ip in the exception handler without making ip volatile (which means the compiler can't keep it in a register in the main loop)
- mp_obj_t *volatile save_sp = *sp_in_out; // this is so we can access sp in the exception handler when needed
+ volatile bool currently_in_except_block = MP_TAGPTR_TAG(code_state->exc_sp); // 0 or 1, to detect nested exceptions
+ mp_exc_stack_t *volatile exc_sp = MP_TAGPTR_PTR(code_state->exc_sp); // stack grows up, exc_sp points to top of stack
// outer exception handling loop
for (;;) {
@@ -254,8 +255,8 @@ mp_vm_return_kind_t mp_execute_bytecode2(const byte *code_info, const byte **ip_
outer_dispatch_loop:
if (nlr_push(&nlr) == 0) {
// local variables that are not visible to the exception handler
- const byte *ip = *ip_in_out;
- mp_obj_t *sp = *sp_in_out;
+ const byte *ip = code_state->ip;
+ mp_obj_t *sp = code_state->sp;
machine_uint_t unum;
mp_obj_t obj_shared;
@@ -278,7 +279,7 @@ dispatch_loop:
DISPATCH();
#else
TRACE(ip);
- save_ip = ip;
+ code_state->ip = ip;
switch (*ip++) {
#endif
@@ -683,7 +684,7 @@ unwind_jump:
ENTRY(MP_BC_FOR_ITER): {
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
- save_sp = sp;
+ code_state->sp = sp;
assert(TOP());
mp_obj_t value = mp_iternext_allow_raise(TOP());
if (value == MP_OBJ_STOP_ITERATION) {
@@ -771,6 +772,7 @@ unwind_jump:
sp -= 2;
DISPATCH();
+#if MICROPY_PY_BUILTINS_SET
ENTRY(MP_BC_BUILD_SET):
DECODE_UINT;
sp -= unum - 1;
@@ -783,8 +785,9 @@ unwind_jump:
mp_obj_set_store(sp[-unum], sp[0]);
sp--;
DISPATCH();
+#endif
-#if MICROPY_PY_SLICE
+#if MICROPY_PY_BUILTINS_SLICE
ENTRY(MP_BC_BUILD_SLICE):
DECODE_UINT;
if (unum == 2) {
@@ -898,7 +901,7 @@ unwind_return:
exc_sp--;
}
nlr_pop();
- *sp_in_out = sp;
+ code_state->sp = sp;
assert(exc_sp == exc_stack - 1);
return MP_VM_RETURN_NORMAL;
@@ -929,9 +932,9 @@ unwind_return:
ENTRY(MP_BC_YIELD_VALUE):
yield:
nlr_pop();
- *ip_in_out = ip;
- *sp_in_out = sp;
- *exc_sp_in_out = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block);
+ code_state->ip = ip;
+ code_state->sp = sp;
+ code_state->exc_sp = MP_TAGPTR_MAKE(exc_sp, currently_in_except_block);
return MP_VM_RETURN_YIELD;
ENTRY(MP_BC_YIELD_FROM): {
@@ -1021,12 +1024,12 @@ exception_handler:
// exception occurred
// check if it's a StopIteration within a for block
- if (*save_ip == MP_BC_FOR_ITER && mp_obj_is_subclass_fast(mp_obj_get_type(nlr.ret_val), &mp_type_StopIteration)) {
- const byte *ip = save_ip + 1;
+ if (*code_state->ip == MP_BC_FOR_ITER && mp_obj_is_subclass_fast(mp_obj_get_type(nlr.ret_val), &mp_type_StopIteration)) {
+ const byte *ip = code_state->ip + 1;
machine_uint_t unum;
DECODE_ULABEL; // the jump offset if iteration finishes; for labels are always forward
- *ip_in_out = ip + unum; // jump to after for-block
- *sp_in_out = save_sp - 1; // pop the exhausted iterator
+ code_state->ip = ip + unum; // jump to after for-block
+ code_state->sp -= 1; // pop the exhausted iterator
goto outer_dispatch_loop; // continue with dispatch loop
}
@@ -1035,11 +1038,12 @@ exception_handler:
// But consider how to handle nested exceptions.
// TODO need a better way of not adding traceback to constant objects (right now, just GeneratorExit_obj and MemoryError_obj)
if (mp_obj_is_exception_instance(nlr.ret_val) && nlr.ret_val != &mp_const_GeneratorExit_obj && nlr.ret_val != &mp_const_MemoryError_obj) {
+ const byte *code_info = code_state->code_info;
machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24);
qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24);
qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24);
machine_uint_t source_line = 1;
- machine_uint_t bc = save_ip - code_info - code_info_size;
+ machine_uint_t bc = code_state->ip - code_info - code_info_size;
//printf("find %lu %d %d\n", bc, code_info[12], code_info[13]);
for (const byte* ci = code_info + 12; *ci && bc >= ((*ci) & 31); ci++) {
bc -= *ci & 31;
@@ -1065,7 +1069,7 @@ exception_handler:
currently_in_except_block = 1;
// catch exception and pass to byte code
- *ip_in_out = exc_sp->handler;
+ code_state->ip = exc_sp->handler;
mp_obj_t *sp = MP_TAGPTR_PTR(exc_sp->val_sp);
// save this exception in the stack so it can be used in a reraise, if needed
exc_sp->prev_exc = nlr.ret_val;
@@ -1073,7 +1077,7 @@ exception_handler:
PUSH(mp_const_none);
PUSH(nlr.ret_val);
PUSH(mp_obj_get_type(nlr.ret_val));
- *sp_in_out = sp;
+ code_state->sp = sp;
} else {
// propagate exception to higher level
diff --git a/stmhal/accel.c b/stmhal/accel.c
index 85c1815636..cfc80f9d3c 100644
--- a/stmhal/accel.c
+++ b/stmhal/accel.c
@@ -43,9 +43,13 @@
/// \moduleref pyb
/// \class Accel - accelerometer control
///
-/// Accel is an object that controls the accelerometer.
+/// Accel is an object that controls the accelerometer. Example usage:
///
-/// Raw values are between -30 and 30.
+/// accel = pyb.Accel()
+/// for i in range(10):
+/// print(accel.x(), accel.y(), accel.z())
+///
+/// Raw values are between -32 and 31.
#define MMA_ADDR (0x98)
#define MMA_REG_X (0)
@@ -118,6 +122,15 @@ STATIC pyb_accel_obj_t pyb_accel_obj;
/// \classmethod \constructor()
/// Create and return an accelerometer object.
+///
+/// Note: if you read accelerometer values immediately after creating this object
+/// you will get 0. It takes around 20ms for the first sample to be ready, so,
+/// unless you have some other code between creating this object and reading its
+/// values, you should put a `pyb.delay(20)` after creating it. For example:
+///
+/// accel = pyb.Accel()
+/// pyb.delay(20)
+/// print(accel.x())
STATIC mp_obj_t pyb_accel_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp_obj_t *args) {
// check arguments
mp_arg_check_num(n_args, n_kw, 0, 0, false);
diff --git a/stmhal/boards/stm32f4xx-af.csv b/stmhal/boards/stm32f4xx-af.csv
index 5746ac8cc9..466be06002 100644
--- a/stmhal/boards/stm32f4xx-af.csv
+++ b/stmhal/boards/stm32f4xx-af.csv
@@ -1,4 +1,4 @@
-Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15
+Port,,AF0,AF1,AF2,AF3,AF4,AF5,AF6,AF7,AF8,AF9,AF10,AF11,AF12,AF13,AF14,AF15,
,,SYS,TIM1/2,TIM3/4/5,TIM8/9/10/11,I2C1/2/3,SPI1/SPI2/I2S2/I2S2ext,SPI3/I2Sext/I2S3,USART1/2/3/I2S3ext,UART4/5/USART6,CAN1/CAN2/TIM12/13/14,OTG_FS/OTG_HS,ETH,FSMC/SDIO/OTG_FS,DCMI,,,ADC
PortA,PA0,,TIM2_CH1_ETR,TIM5_CH1,TIM8_ETR,,,,USART2_CTS,UART4_TX,,,ETH_MII_CRS,,,,EVENTOUT,ADC123_IN0
PortA,PA1,,TIM2_CH2,TIM5_CH2,,,,,USART2_RTS,UART4_RX,,,ETH_MII_RX_CLK/ETH_RMII__REF_CLK,,,,EVENTOUT,ADC123_IN1
diff --git a/stmhal/modtime.c b/stmhal/modtime.c
index 2e50a58df1..4fbee31293 100644
--- a/stmhal/modtime.c
+++ b/stmhal/modtime.c
@@ -74,11 +74,11 @@ STATIC mp_obj_t time_localtime(void) {
MP_DEFINE_CONST_FUN_OBJ_0(time_localtime_obj, time_localtime);
STATIC mp_obj_t time_sleep(mp_obj_t seconds_o) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
if (MP_OBJ_IS_INT(seconds_o)) {
#endif
HAL_Delay(1000 * mp_obj_get_int(seconds_o));
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
} else {
HAL_Delay((uint32_t)(1000 * mp_obj_get_float(seconds_o)));
}
diff --git a/stmhal/mpconfigport.h b/stmhal/mpconfigport.h
index 33b81336ca..36a60dfa7c 100644
--- a/stmhal/mpconfigport.h
+++ b/stmhal/mpconfigport.h
@@ -44,7 +44,7 @@
*/
#define MICROPY_ENABLE_LFN (1)
#define MICROPY_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
-#define MICROPY_PY_FROZENSET (1)
+#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_STDFILES (1)
#define MICROPY_PY_CMATH (1)
diff --git a/stmhal/printf.c b/stmhal/printf.c
index 3f88a9c5aa..6cfeda2637 100644
--- a/stmhal/printf.c
+++ b/stmhal/printf.c
@@ -41,7 +41,7 @@
#include "uart.h"
#include "usb.h"
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
#include "formatfloat.h"
#endif
@@ -162,7 +162,7 @@ int pfenv_printf(const pfenv_t *pfenv, const char *fmt, va_list args) {
case 'P': // ?
chrs += pfenv_print_int(pfenv, va_arg(args, int), 0, 16, 'A', flags, fill, width);
break;
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
case 'e':
case 'E':
case 'f':
diff --git a/stmhal/servo.c b/stmhal/servo.c
index e44e129ef4..3da445fa8d 100644
--- a/stmhal/servo.c
+++ b/stmhal/servo.c
@@ -271,7 +271,7 @@ STATIC mp_obj_t pyb_servo_angle(uint n_args, const mp_obj_t *args) {
// get angle
return mp_obj_new_int((self->pulse_cur - self->pulse_centre) * 90 / self->pulse_angle_90);
} else {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
self->pulse_dest = self->pulse_centre + self->pulse_angle_90 * mp_obj_get_float(args[1]) / 90.0;
#else
self->pulse_dest = self->pulse_centre + self->pulse_angle_90 * mp_obj_get_int(args[1]) / 90;
@@ -301,7 +301,7 @@ STATIC mp_obj_t pyb_servo_speed(uint n_args, const mp_obj_t *args) {
// get speed
return mp_obj_new_int((self->pulse_cur - self->pulse_centre) * 100 / self->pulse_speed_100);
} else {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
self->pulse_dest = self->pulse_centre + self->pulse_speed_100 * mp_obj_get_float(args[1]) / 100.0;
#else
self->pulse_dest = self->pulse_centre + self->pulse_speed_100 * mp_obj_get_int(args[1]) / 100;
diff --git a/teensy/mpconfigport.h b/teensy/mpconfigport.h
index c01f13a6dd..f7c66d8874 100644
--- a/teensy/mpconfigport.h
+++ b/teensy/mpconfigport.h
@@ -6,7 +6,7 @@
#define MICROPY_EMIT_INLINE_THUMB (1)
#define MICROPY_ENABLE_GC (1)
#define MICROPY_HELPER_REPL (1)
-#define MICROPY_ENABLE_FLOAT (1)
+#define MICROPY_PY_BUILTINS_FLOAT (1)
// type definitions for the specific machine
diff --git a/tests/basics/for_break.py b/tests/basics/for_break.py
index fa8dabd150..f8bb0578e2 100644
--- a/tests/basics/for_break.py
+++ b/tests/basics/for_break.py
@@ -13,3 +13,15 @@ def foo():
i -= 1
foo()
+
+# break from within nested for loop
+def bar():
+ l = [1, 2, 3]
+ for e1 in l:
+ print(e1)
+ for e2 in l:
+ print(e1, e2)
+ if e2 == 2:
+ break
+
+bar()
diff --git a/tests/basics/for_return.py b/tests/basics/for_return.py
new file mode 100644
index 0000000000..0441352ad9
--- /dev/null
+++ b/tests/basics/for_return.py
@@ -0,0 +1,7 @@
+# test returning from within a for loop
+
+def f():
+ for i in [1, 2, 3]:
+ return i
+
+print(f())
diff --git a/tests/micropython/heapalloc.py b/tests/micropython/heapalloc.py
new file mode 100644
index 0000000000..c62428a084
--- /dev/null
+++ b/tests/micropython/heapalloc.py
@@ -0,0 +1,26 @@
+# check that we can do certain things without allocating heap memory
+
+import gc
+
+def f(a):
+ print(a)
+
+def g(a, b=2):
+ print(a, b)
+
+global_var = 1
+
+def h():
+ global global_var
+ global_var = 2 # set an existing global variable
+ for i in range(2): # for loop
+ f(i) # function call
+ f(i * 2 + 1) # binary operation with small ints
+ f(a=i) # keyword arguments
+ g(i) # default arg (second one)
+ g(i, i) # 2 args
+
+# call h with heap allocation disabled
+gc.disable()
+h()
+gc.enable()
diff --git a/tests/run-tests b/tests/run-tests
index 102655abea..1e6dd50538 100755
--- a/tests/run-tests
+++ b/tests/run-tests
@@ -111,6 +111,7 @@ def run_tests(pyb, tests):
def main():
cmd_parser = argparse.ArgumentParser(description='Run tests for Micro Python.')
cmd_parser.add_argument('--pyboard', action='store_true', help='run the tests on the pyboard')
+ cmd_parser.add_argument('-d', '--test-dirs', nargs='*', help='input test directories (if no files given)')
cmd_parser.add_argument('files', nargs='*', help='input test files')
args = cmd_parser.parse_args()
@@ -122,12 +123,16 @@ def main():
pyb = None
if len(args.files) == 0:
- if pyb is None:
- # run PC tests
- test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc')
+ if args.test_dirs is None:
+ if pyb is None:
+ # run PC tests
+ test_dirs = ('basics', 'micropython', 'float', 'import', 'io', 'misc')
+ else:
+ # run pyboard tests
+ test_dirs = ('basics', 'float', 'pyb', 'pybnative', 'inlineasm')
else:
- # run pyboard tests
- test_dirs = ('basics', 'float', 'pyb', 'pybnative', 'inlineasm')
+ # run tests from these directories
+ test_dirs = args.test_dirs
tests = sorted(test_file for test_files in (glob('{}/*.py'.format(dir)) for dir in test_dirs) for test_file in test_files)
else:
# tests explicitly given
diff --git a/unix/modtime.c b/unix/modtime.c
index 77d2945b8f..f957b96784 100644
--- a/unix/modtime.c
+++ b/unix/modtime.c
@@ -64,7 +64,7 @@ void msec_sleep_tv(struct timeval *tv) {
#endif
STATIC mp_obj_t mod_time_time() {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
struct timeval tv;
gettimeofday(&tv, NULL);
mp_float_t val = tv.tv_sec + (mp_float_t)tv.tv_usec / 1000000;
@@ -77,7 +77,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_time_obj, mod_time_time);
// Note: this is deprecated since CPy3.3, but pystone still uses it.
STATIC mp_obj_t mod_time_clock() {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
// float cannot represent full range of int32 precisely, so we pre-divide
// int to reduce resolution, and then actually do float division hoping
// to preserve integer part resolution.
@@ -89,7 +89,7 @@ STATIC mp_obj_t mod_time_clock() {
STATIC MP_DEFINE_CONST_FUN_OBJ_0(mod_time_clock_obj, mod_time_clock);
STATIC mp_obj_t mod_time_sleep(mp_obj_t arg) {
-#if MICROPY_ENABLE_FLOAT
+#if MICROPY_PY_BUILTINS_FLOAT
struct timeval tv;
mp_float_t val = mp_obj_get_float(arg);
double ipart;
diff --git a/unix/mpconfigport.h b/unix/mpconfigport.h
index c56c9fa1a6..1b1d938a84 100644
--- a/unix/mpconfigport.h
+++ b/unix/mpconfigport.h
@@ -41,7 +41,7 @@
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
#define MICROPY_STREAMS_NON_BLOCK (1)
#define MICROPY_OPT_COMPUTED_GOTO (1)
-#define MICROPY_PY_FROZENSET (1)
+#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_SYS_EXIT (1)
#define MICROPY_PY_SYS_STDFILES (1)
#define MICROPY_PY_CMATH (1)
diff --git a/windows/mpconfigport.h b/windows/mpconfigport.h
index 0ac715f405..94304e20d2 100644
--- a/windows/mpconfigport.h
+++ b/windows/mpconfigport.h
@@ -39,7 +39,7 @@
#define MICROPY_DEBUG_PRINTERS (1)
#define MICROPY_HELPER_REPL (1)
#define MICROPY_HELPER_LEXER_UNIX (1)
-#define MICROPY_PY_FROZENSET (1)
+#define MICROPY_PY_BUILTINS_FROZENSET (1)
#define MICROPY_PY_CMATH (1)
#define MICROPY_PY_SYS_STDFILES (1)
#define MICROPY_PY_SYS_EXIT (1)