From de74aa7e596f271a3c1ec5fd549a638e9bd9953a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Fri, 31 Jan 2020 11:44:57 +0100 Subject: [PATCH] [python] Enable PYSTACK for emscripten platform: this "fixes" bug probably due to gc_collect (we suspect that transpiled C does not have access to javascript variables preventing it from collecting all required roots and leading to deleting objects prematuraly). Enabling PyStack reduces the use of the heap and fixes the bug. --- python/port/genhdr/qstrdefs.in.h | 10 ++++++++++ python/port/mpconfigport.h | 13 +++++++++++++ python/port/port.cpp | 5 +++++ 3 files changed, 28 insertions(+) diff --git a/python/port/genhdr/qstrdefs.in.h b/python/port/genhdr/qstrdefs.in.h index c34eb98e3..17b4eea5c 100644 --- a/python/port/genhdr/qstrdefs.in.h +++ b/python/port/genhdr/qstrdefs.in.h @@ -136,6 +136,9 @@ Q() Q() Q() Q(utf-8) +#if __EMSCRIPTEN__ +Q(pystack exhausted) +#endif Q(ArithmeticError) Q(AssertionError) Q(AttributeError) @@ -192,6 +195,9 @@ Q(__lt__) Q(__main__) Q(__module__) Q(__name__) +#if __EMSCRIPTEN__ +Q(__ne__) +#endif Q(__new__) Q(__next__) Q(__path__) @@ -355,6 +361,10 @@ Q(pop) Q(popitem) Q(pow) Q(print) +#if __EMSCRIPTEN__ +Q(pystack_space_exhausted) +Q(pystack_use) +#endif Q(radians) Q(randint) Q(random) diff --git a/python/port/mpconfigport.h b/python/port/mpconfigport.h index 845bd0944..8ef4cad6d 100644 --- a/python/port/mpconfigport.h +++ b/python/port/mpconfigport.h @@ -5,6 +5,19 @@ /* MicroPython configuration options * We're not listing the default options as defined in mpconfig.h */ +#if __EMSCRIPTEN__ +// Enable a PyStack where most objects are allocated instead of always using the heap +/* This enables to allocate and free memory in a scope (thus, Python can call + * Python) but also has the collateral effect of removing bugs regarding + * garbage collection on the web simulator. Indeed, fewer objetcts are + * allocated on the heap and the garbage collection is less frequently called. + * We suspect that garbage collection failed in javascript because when + * collecting roots the transpiled C code is denied access to Javascript + * variables that can store pointers to the Python heap. The pointed objects + * are therefore erased prematurely. */ +#define MICROPY_ENABLE_PYSTACK (1) +#endif + // Maximum length of a path in the filesystem #define MICROPY_ALLOC_PATH_MAX (32) diff --git a/python/port/port.cpp b/python/port/port.cpp index 7bce53fee..f25544efd 100644 --- a/python/port/port.cpp +++ b/python/port/port.cpp @@ -102,6 +102,11 @@ extern "C" { } void MicroPython::init(void * heapStart, void * heapEnd) { +#if __EMSCRIPTEN__ + static mp_obj_t pystack[1024]; + mp_pystack_init(pystack, &pystack[MP_ARRAY_SIZE(pystack)]); +#endif + volatile int stackTop; void * stackTopAddress = (void *)(&stackTop); /* We delimit the stack part that will be used by Python. The stackTop is the