py: Convert all uses of alloca() to use new scoped allocation API.
diff --git a/py/builtinimport.c b/py/builtinimport.c
index 9235e94..2157902 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -318,7 +318,7 @@
         }
 
         uint new_mod_l = (mod_len == 0 ? (size_t)(p - this_name) : (size_t)(p - this_name) + 1 + mod_len);
-        char *new_mod = alloca(new_mod_l);
+        char *new_mod = mp_local_alloc(new_mod_l);
         memcpy(new_mod, this_name, p - this_name);
         if (mod_len != 0) {
             new_mod[p - this_name] = '.';
@@ -326,9 +326,10 @@
         }
 
         qstr new_mod_q = qstr_from_strn(new_mod, new_mod_l);
+        mp_local_free(new_mod);
         DEBUG_printf("Resolved base name for relative import: '%s'\n", qstr_str(new_mod_q));
         module_name = MP_OBJ_NEW_QSTR(new_mod_q);
-        mod_str = new_mod;
+        mod_str = qstr_str(new_mod_q);
         mod_len = new_mod_l;
     }
 
diff --git a/py/compile.c b/py/compile.c
index ee01749..52d10ee 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1050,7 +1050,7 @@
             for (int i = 0; i < n; i++) {
                 len += qstr_len(MP_PARSE_NODE_LEAF_ARG(pns->nodes[i]));
             }
-            char *q_ptr = alloca(len);
+            char *q_ptr = mp_local_alloc(len);
             char *str_dest = q_ptr;
             for (int i = 0; i < n; i++) {
                 if (i > 0) {
@@ -1062,6 +1062,7 @@
                 str_dest += str_src_len;
             }
             qstr q_full = qstr_from_strn(q_ptr, len);
+            mp_local_free(q_ptr);
             EMIT_ARG(import_name, q_full);
             if (is_as) {
                 for (int i = 1; i < n; i++) {
diff --git a/py/objboundmeth.c b/py/objboundmeth.c
index 890f8b1..b0df6a6 100644
--- a/py/objboundmeth.c
+++ b/py/objboundmeth.c
@@ -51,6 +51,9 @@
     // need to insert self before all other args and then call meth
     size_t n_total = n_args + 2 * n_kw;
     mp_obj_t *args2 = NULL;
+    #if MICROPY_ENABLE_PYSTACK
+    args2 = mp_pystack_alloc(sizeof(mp_obj_t) * (1 + n_total));
+    #else
     mp_obj_t *free_args2 = NULL;
     if (n_total > 4) {
         // try to use heap to allocate temporary args array
@@ -61,12 +64,17 @@
         // (fallback to) use stack to allocate temporary args array
         args2 = alloca(sizeof(mp_obj_t) * (1 + n_total));
     }
+    #endif
     args2[0] = self;
     memcpy(args2 + 1, args, n_total * sizeof(mp_obj_t));
     mp_obj_t res = mp_call_function_n_kw(meth, n_args + 1, n_kw, args2);
+    #if MICROPY_ENABLE_PYSTACK
+    mp_pystack_free(args2);
+    #else
     if (free_args2 != NULL) {
         m_del(mp_obj_t, free_args2, 1 + n_total);
     }
+    #endif
     return res;
 }
 
diff --git a/py/objfun.c b/py/objfun.c
index 8fb3ec6..e6d33d2 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -225,6 +225,9 @@
     DECODE_CODESTATE_SIZE(self->bytecode, n_state, state_size);
 
     mp_code_state_t *code_state;
+    #if MICROPY_ENABLE_PYSTACK
+    code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
+    #else
     // If we use m_new_obj_var(), then on no memory, MemoryError will be
     // raised. But this is not correct exception for a function call,
     // RuntimeError should be raised instead. So, we use m_new_obj_var_maybe(),
@@ -234,6 +237,7 @@
     if (!code_state) {
         return NULL;
     }
+    #endif
 
     INIT_CODESTATE(code_state, self, n_args, n_kw, args);
 
@@ -260,6 +264,9 @@
 
     // allocate state for locals and stack
     mp_code_state_t *code_state = NULL;
+    #if MICROPY_ENABLE_PYSTACK
+    code_state = mp_pystack_alloc(sizeof(mp_code_state_t) + state_size);
+    #else
     if (state_size > VM_MAX_STATE_ON_STACK) {
         code_state = m_new_obj_var_maybe(mp_code_state_t, byte, state_size);
     }
@@ -267,6 +274,7 @@
         code_state = alloca(sizeof(mp_code_state_t) + state_size);
         state_size = 0; // indicate that we allocated using alloca
     }
+    #endif
 
     INIT_CODESTATE(code_state, self, n_args, n_kw, args);
 
@@ -312,10 +320,14 @@
         result = code_state->state[n_state - 1];
     }
 
+    #if MICROPY_ENABLE_PYSTACK
+    mp_pystack_free(code_state);
+    #else
     // free the state if it was allocated on the heap
     if (state_size != 0) {
         m_del_var(mp_code_state_t, byte, state_size, code_state);
     }
+    #endif
 
     if (vm_return_kind == MP_VM_RETURN_NORMAL) {
         return result;
diff --git a/py/runtime.c b/py/runtime.c
index 3a4a8a9..8df0c0a 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -1348,11 +1348,12 @@
     const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len);
 
     const uint dot_name_len = pkg_name_len + 1 + qstr_len(name);
-    char *dot_name = alloca(dot_name_len);
+    char *dot_name = mp_local_alloc(dot_name_len);
     memcpy(dot_name, pkg_name, pkg_name_len);
     dot_name[pkg_name_len] = '.';
     memcpy(dot_name + pkg_name_len + 1, qstr_str(name), qstr_len(name));
     qstr dot_name_q = qstr_from_strn(dot_name, dot_name_len);
+    mp_local_free(dot_name);
 
     mp_obj_t args[5];
     args[0] = MP_OBJ_NEW_QSTR(dot_name_q);
diff --git a/py/vm.c b/py/vm.c
index 5011af5..a8a73f3 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -1108,7 +1108,13 @@
                     if (code_state->prev != NULL) {
                         mp_obj_t res = *sp;
                         mp_globals_set(code_state->old_globals);
-                        code_state = code_state->prev;
+                        mp_code_state_t *new_code_state = code_state->prev;
+                        #if MICROPY_ENABLE_PYSTACK
+                        // The sizeof in the following statement does not include the size of the variable
+                        // part of the struct.  This arg is anyway not used if pystack is enabled.
+                        mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
+                        #endif
+                        code_state = new_code_state;
                         *code_state->sp = res;
                         goto run_code_state;
                     }
@@ -1450,7 +1456,13 @@
             #if MICROPY_STACKLESS
             } else if (code_state->prev != NULL) {
                 mp_globals_set(code_state->old_globals);
-                code_state = code_state->prev;
+                mp_code_state_t *new_code_state = code_state->prev;
+                #if MICROPY_ENABLE_PYSTACK
+                // The sizeof in the following statement does not include the size of the variable
+                // part of the struct.  This arg is anyway not used if pystack is enabled.
+                mp_nonlocal_free(code_state, sizeof(mp_code_state_t));
+                #endif
+                code_state = new_code_state;
                 size_t n_state = mp_decode_uint_value(code_state->fun_bc->bytecode);
                 fastn = &code_state->state[n_state - 1];
                 exc_stack = (mp_exc_stack_t*)(code_state->state + n_state);