summaryrefslogtreecommitdiffstatshomepage
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/asmthumb.c2
-rw-r--r--py/bc.c10
-rw-r--r--py/bc.h1
-rw-r--r--py/builtinimport.c4
-rw-r--r--py/compile.c4
-rw-r--r--py/makeqstrdefs.py28
-rw-r--r--py/misc.h2
-rw-r--r--py/mkenv.mk2
-rw-r--r--py/modbuiltins.c32
-rw-r--r--py/modsys.c6
-rw-r--r--py/mpconfig.h8
-rw-r--r--py/mperrno.h2
-rw-r--r--py/obj.c2
-rw-r--r--py/objfun.c22
-rw-r--r--py/objgenerator.c7
-rw-r--r--py/objstr.c13
-rw-r--r--py/objstringio.c30
-rw-r--r--py/objstringio.h2
-rw-r--r--py/persistentcode.c10
-rw-r--r--py/py.mk2
-rw-r--r--py/ringbuf.h2
-rw-r--r--py/stream.c2
-rw-r--r--py/vm.c17
23 files changed, 144 insertions, 66 deletions
diff --git a/py/asmthumb.c b/py/asmthumb.c
index 749c1e405b..7e92e4de41 100644
--- a/py/asmthumb.c
+++ b/py/asmthumb.c
@@ -52,7 +52,7 @@ void asm_thumb_end_pass(asm_thumb_t *as) {
#if defined(MCU_SERIES_F7)
if (as->base.pass == MP_ASM_PASS_EMIT) {
- // flush D-cache, so the code emited is stored in memory
+ // flush D-cache, so the code emitted is stored in memory
SCB_CleanDCache_by_Addr((uint32_t*)as->base.code_base, as->base.code_size);
// invalidate I-cache
SCB_InvalidateICache();
diff --git a/py/bc.c b/py/bc.c
index fc17946839..2e481bce77 100644
--- a/py/bc.c
+++ b/py/bc.c
@@ -64,6 +64,14 @@ mp_uint_t mp_decode_uint_value(const byte *ptr) {
return mp_decode_uint(&ptr);
}
+// This function is used to help reduce stack usage at the caller, for the case when
+// the caller doesn't need the actual value and just wants to skip over it.
+const byte *mp_decode_uint_skip(const byte *ptr) {
+ while ((*ptr++) & 0x80) {
+ }
+ return ptr;
+}
+
STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, size_t given) {
#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE
// generic message, used also for other argument issues
@@ -115,7 +123,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw
// get params
size_t n_state = mp_decode_uint(&code_state->ip);
- mp_decode_uint(&code_state->ip); // skip n_exc_stack
+ code_state->ip = mp_decode_uint_skip(code_state->ip); // skip n_exc_stack
size_t scope_flags = *code_state->ip++;
size_t n_pos_args = *code_state->ip++;
size_t n_kwonly_args = *code_state->ip++;
diff --git a/py/bc.h b/py/bc.h
index e8d4286125..88045dc55b 100644
--- a/py/bc.h
+++ b/py/bc.h
@@ -92,6 +92,7 @@ typedef struct _mp_code_state_t {
mp_uint_t mp_decode_uint(const byte **ptr);
mp_uint_t mp_decode_uint_value(const byte *ptr);
+const byte *mp_decode_uint_skip(const byte *ptr);
mp_vm_return_kind_t mp_execute_bytecode(mp_code_state_t *code_state, volatile mp_obj_t inject_exc);
mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t func, size_t n_args, size_t n_kw, const mp_obj_t *args);
diff --git a/py/builtinimport.c b/py/builtinimport.c
index d01ebbe73f..6994fc48f4 100644
--- a/py/builtinimport.c
+++ b/py/builtinimport.c
@@ -271,7 +271,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
if (level != 0) {
// What we want to do here is to take name of current module,
// chop <level> trailing components, and concatenate with passed-in
- // module name, thus resolving relative import name into absolue.
+ // module name, thus resolving relative import name into absolute.
// This even appears to be correct per
// http://legacy.python.org/dev/peps/pep-0328/#relative-imports-and-name
// "Relative imports use a module's __name__ attribute to determine that
@@ -441,7 +441,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) {
#if MICROPY_CPYTHON_COMPAT
// Store module as "__main__" in the dictionary of loaded modules (returned by sys.modules).
mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(mp_loaded_modules_dict)), MP_OBJ_NEW_QSTR(MP_QSTR___main__), module_obj);
- // Store real name in "__main__" attribute. Choosen semi-randonly, to reuse existing qstr's.
+ // Store real name in "__main__" attribute. Chosen semi-randonly, to reuse existing qstr's.
mp_obj_dict_store(MP_OBJ_FROM_PTR(o->globals), MP_OBJ_NEW_QSTR(MP_QSTR___main__), MP_OBJ_NEW_QSTR(mod_name));
#endif
}
diff --git a/py/compile.c b/py/compile.c
index 8533e0528f..3b6a264d61 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -939,7 +939,7 @@ STATIC void c_del_stmt(compiler_t *comp, mp_parse_node_t pn) {
}
}
} else {
- // some arbitrary statment that we can't delete (eg del 1)
+ // some arbitrary statement that we can't delete (eg del 1)
goto cannot_delete;
}
@@ -1090,7 +1090,7 @@ STATIC void compile_import_name(compiler_t *comp, mp_parse_node_struct_t *pns) {
STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
mp_parse_node_t pn_import_source = pns->nodes[0];
- // extract the preceeding .'s (if any) for a relative import, to compute the import level
+ // extract the preceding .'s (if any) for a relative import, to compute the import level
uint import_level = 0;
do {
mp_parse_node_t pn_rel;
diff --git a/py/makeqstrdefs.py b/py/makeqstrdefs.py
index 92a19c3920..525dec1973 100644
--- a/py/makeqstrdefs.py
+++ b/py/makeqstrdefs.py
@@ -5,8 +5,10 @@ qstr. Each qstr is transformed into a qstr definition of the form 'Q(...)'.
This script works with Python 2.6, 2.7, 3.3 and 3.4.
"""
+from __future__ import print_function
+
import re
-import argparse
+import sys
import os
# Blacklist of qstrings that are specially handled in further
@@ -84,18 +86,18 @@ def cat_together():
if __name__ == "__main__":
- parser = argparse.ArgumentParser(description='Generates qstr definitions from a specified source')
-
- parser.add_argument('command',
- help='Command (split/cat)')
- parser.add_argument('input_filename',
- help='Name of the input file (when not specified, the script reads standard input)')
- parser.add_argument('output_dir',
- help='Output directory to store individual qstr files')
- parser.add_argument('output_file',
- help='Name of the output file with collected qstrs')
-
- args = parser.parse_args()
+ if len(sys.argv) != 5:
+ print('usage: %s command input_filename output_dir output_file' % sys.argv[0])
+ sys.exit(2)
+
+ class Args:
+ pass
+ args = Args()
+ args.command = sys.argv[1]
+ args.input_filename = sys.argv[2]
+ args.output_dir = sys.argv[3]
+ args.output_file = sys.argv[4]
+
try:
os.makedirs(args.output_dir)
except OSError:
diff --git a/py/misc.h b/py/misc.h
index a84603ceb5..c2b1b232b2 100644
--- a/py/misc.h
+++ b/py/misc.h
@@ -198,7 +198,7 @@ int DEBUG_printf(const char *fmt, ...);
extern mp_uint_t mp_verbose_flag;
// This is useful for unicode handling. Some CPU archs has
-// special instructions for efficient implentation of this
+// special instructions for efficient implementation of this
// function (e.g. CLZ on ARM).
// NOTE: this function is unused at the moment
#ifndef count_lead_ones
diff --git a/py/mkenv.mk b/py/mkenv.mk
index eb1e44fef5..b167b2533d 100644
--- a/py/mkenv.mk
+++ b/py/mkenv.mk
@@ -32,7 +32,7 @@ ifeq ($(BUILD_VERBOSE),0)
$(info Use make V=1 or set BUILD_VERBOSE in your environment to increase build verbosity.)
endif
-# default settings; can be overriden in main Makefile
+# default settings; can be overridden in main Makefile
PY_SRC ?= $(TOP)/py
BUILD ?= build
diff --git a/py/modbuiltins.c b/py/modbuiltins.c
index 17bd30c521..fe8159953a 100644
--- a/py/modbuiltins.c
+++ b/py/modbuiltins.c
@@ -259,6 +259,35 @@ STATIC mp_obj_t mp_builtin_hex(mp_obj_t o_in) {
}
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_hex_obj, mp_builtin_hex);
+#if MICROPY_PY_BUILTINS_INPUT
+
+#include "py/mphal.h"
+#include "lib/mp-readline/readline.h"
+
+// A port can define mp_hal_readline if they want to use a custom function here
+#ifndef mp_hal_readline
+#define mp_hal_readline readline
+#endif
+
+STATIC mp_obj_t mp_builtin_input(size_t n_args, const mp_obj_t *args) {
+ if (n_args == 1) {
+ mp_obj_print(args[0], PRINT_STR);
+ }
+ vstr_t line;
+ vstr_init(&line, 16);
+ int ret = mp_hal_readline(&line, "");
+ if (ret == CHAR_CTRL_C) {
+ nlr_raise(mp_obj_new_exception(&mp_type_KeyboardInterrupt));
+ }
+ if (line.len == 0 && ret == CHAR_CTRL_D) {
+ nlr_raise(mp_obj_new_exception(&mp_type_EOFError));
+ }
+ return mp_obj_new_str_from_vstr(&mp_type_str, &line);
+}
+MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_builtin_input_obj, 0, 1, mp_builtin_input);
+
+#endif
+
STATIC mp_obj_t mp_builtin_iter(mp_obj_t o_in) {
return mp_getiter(o_in, NULL);
}
@@ -676,6 +705,9 @@ STATIC const mp_rom_map_elem_t mp_module_builtins_globals_table[] = {
#endif
{ MP_ROM_QSTR(MP_QSTR_hex), MP_ROM_PTR(&mp_builtin_hex_obj) },
{ MP_ROM_QSTR(MP_QSTR_id), MP_ROM_PTR(&mp_builtin_id_obj) },
+ #if MICROPY_PY_BUILTINS_INPUT
+ { MP_ROM_QSTR(MP_QSTR_input), MP_ROM_PTR(&mp_builtin_input_obj) },
+ #endif
{ MP_ROM_QSTR(MP_QSTR_isinstance), MP_ROM_PTR(&mp_builtin_isinstance_obj) },
{ MP_ROM_QSTR(MP_QSTR_issubclass), MP_ROM_PTR(&mp_builtin_issubclass_obj) },
{ MP_ROM_QSTR(MP_QSTR_iter), MP_ROM_PTR(&mp_builtin_iter_obj) },
diff --git a/py/modsys.c b/py/modsys.c
index 5fbcb944c4..b8c427ba87 100644
--- a/py/modsys.c
+++ b/py/modsys.c
@@ -74,12 +74,12 @@ STATIC MP_DEFINE_ATTRTUPLE(
MP_ROM_PTR(&mp_sys_implementation_version_info_obj)
);
#else
-STATIC const mp_obj_tuple_t mp_sys_implementation_obj = {
+STATIC const mp_rom_obj_tuple_t mp_sys_implementation_obj = {
{&mp_type_tuple},
2,
{
- MP_OBJ_NEW_QSTR(MP_QSTR_micropython),
- (mp_obj_t)&mp_sys_implementation_version_info_obj,
+ MP_ROM_QSTR(MP_QSTR_micropython),
+ MP_ROM_PTR(&mp_sys_implementation_version_info_obj),
}
};
#endif
diff --git a/py/mpconfig.h b/py/mpconfig.h
index a61d431e5a..1ec8ae21c8 100644
--- a/py/mpconfig.h
+++ b/py/mpconfig.h
@@ -32,7 +32,7 @@
// mpconfigport.h is a file containing configuration settings for a
// particular port. mpconfigport.h is actually a default name for
-// such config, and it can be overriden using MP_CONFIGFILE preprocessor
+// such config, and it can be overridden using MP_CONFIGFILE preprocessor
// define (you can do that by passing CFLAGS_EXTRA='-DMP_CONFIGFILE="<file.h>"'
// argument to make when using standard MicroPython makefiles).
// This is useful to have more than one config per port, for example,
@@ -791,6 +791,12 @@ typedef double mp_float_t;
#define MICROPY_PY_BUILTINS_NOTIMPLEMENTED (0)
#endif
+// Whether to provide the built-in input() function. The implementation of this
+// uses mp-readline, so can only be enabled if the port uses this readline.
+#ifndef MICROPY_PY_BUILTINS_INPUT
+#define MICROPY_PY_BUILTINS_INPUT (0)
+#endif
+
// Whether to support min/max functions
#ifndef MICROPY_PY_BUILTINS_MIN_MAX
#define MICROPY_PY_BUILTINS_MIN_MAX (1)
diff --git a/py/mperrno.h b/py/mperrno.h
index 4d092de452..6ea99ae227 100644
--- a/py/mperrno.h
+++ b/py/mperrno.h
@@ -73,6 +73,7 @@
#define MP_ECONNABORTED (103) // Software caused connection abort
#define MP_ECONNRESET (104) // Connection reset by peer
#define MP_ENOBUFS (105) // No buffer space available
+#define MP_EISCONN (106) // Transport endpoint is already connected
#define MP_ENOTCONN (107) // Transport endpoint is not connected
#define MP_ETIMEDOUT (110) // Connection timed out
#define MP_ECONNREFUSED (111) // Connection refused
@@ -127,6 +128,7 @@
#define MP_ECONNABORTED ECONNABORTED
#define MP_ECONNRESET ECONNRESET
#define MP_ENOBUFS ENOBUFS
+#define MP_EISCONN EISCONN
#define MP_ENOTCONN ENOTCONN
#define MP_ETIMEDOUT ETIMEDOUT
#define MP_ECONNREFUSED ECONNREFUSED
diff --git a/py/obj.c b/py/obj.c
index 98ffa930b5..493945a227 100644
--- a/py/obj.c
+++ b/py/obj.c
@@ -401,7 +401,7 @@ mp_obj_t mp_obj_id(mp_obj_t o_in) {
return MP_OBJ_NEW_SMALL_INT(id);
} else {
// If that didn't work, well, let's return long int, just as
- // a (big) positve value, so it will never clash with the range
+ // a (big) positive value, so it will never clash with the range
// of small int returned in previous case.
return mp_obj_new_int_from_uint((mp_uint_t)id);
}
diff --git a/py/objfun.c b/py/objfun.c
index 08d031c8d8..9f35891243 100644
--- a/py/objfun.c
+++ b/py/objfun.c
@@ -141,11 +141,11 @@ const mp_obj_type_t mp_type_fun_builtin_var = {
/* byte code functions */
qstr mp_obj_code_get_name(const byte *code_info) {
- mp_decode_uint(&code_info); // skip code_info_size entry
+ code_info = mp_decode_uint_skip(code_info); // skip code_info_size entry
#if MICROPY_PERSISTENT_CODE
return code_info[0] | (code_info[1] << 8);
#else
- return mp_decode_uint(&code_info);
+ return mp_decode_uint_value(code_info);
#endif
}
@@ -163,8 +163,8 @@ qstr mp_obj_fun_get_name(mp_const_obj_t fun_in) {
#endif
const byte *bc = fun->bytecode;
- mp_decode_uint(&bc); // skip n_state
- mp_decode_uint(&bc); // skip n_exc_stack
+ bc = mp_decode_uint_skip(bc); // skip n_state
+ bc = mp_decode_uint_skip(bc); // skip n_exc_stack
bc++; // skip scope_params
bc++; // skip n_pos_args
bc++; // skip n_kwonly_args
@@ -205,12 +205,9 @@ mp_code_state_t *mp_obj_fun_bc_prepare_codestate(mp_obj_t self_in, size_t n_args
MP_STACK_CHECK();
mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in);
- // get start of bytecode
- const byte *ip = self->bytecode;
-
// bytecode prelude: state size and exception stack size
- size_t n_state = mp_decode_uint(&ip);
- size_t n_exc_stack = mp_decode_uint(&ip);
+ size_t n_state = mp_decode_uint_value(self->bytecode);
+ size_t n_exc_stack = mp_decode_uint_value(mp_decode_uint_skip(self->bytecode));
// allocate state for locals and stack
size_t state_size = n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t);
@@ -243,12 +240,9 @@ STATIC mp_obj_t fun_bc_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const
mp_obj_fun_bc_t *self = MP_OBJ_TO_PTR(self_in);
DEBUG_printf("Func n_def_args: %d\n", self->n_def_args);
- // get start of bytecode
- const byte *ip = self->bytecode;
-
// bytecode prelude: state size and exception stack size
- size_t n_state = mp_decode_uint(&ip);
- size_t n_exc_stack = mp_decode_uint(&ip);
+ size_t n_state = mp_decode_uint_value(self->bytecode);
+ size_t n_exc_stack = mp_decode_uint_value(mp_decode_uint_skip(self->bytecode));
#if VM_DETECT_STACK_OVERFLOW
n_state += 1;
diff --git a/py/objgenerator.c b/py/objgenerator.c
index 2e57fdf4b6..8cb0e60ccb 100644
--- a/py/objgenerator.c
+++ b/py/objgenerator.c
@@ -54,12 +54,9 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons
mp_obj_fun_bc_t *self_fun = (mp_obj_fun_bc_t*)self->fun;
assert(self_fun->base.type == &mp_type_fun_bc);
- // get start of bytecode
- const byte *ip = self_fun->bytecode;
-
// bytecode prelude: get state size and exception stack size
- mp_uint_t n_state = mp_decode_uint(&ip);
- mp_uint_t n_exc_stack = mp_decode_uint(&ip);
+ size_t n_state = mp_decode_uint_value(self_fun->bytecode);
+ size_t n_exc_stack = mp_decode_uint_value(mp_decode_uint_skip(self_fun->bytecode));
// allocate the generator object, with room for local stack and exception stack
mp_obj_gen_instance_t *o = m_new_obj_var(mp_obj_gen_instance_t, byte,
diff --git a/py/objstr.c b/py/objstr.c
index 70de0a693a..e758dd0062 100644
--- a/py/objstr.c
+++ b/py/objstr.c
@@ -602,6 +602,11 @@ STATIC mp_obj_t str_rsplit(size_t n_args, const mp_obj_t *args) {
GET_STR_DATA_LEN(args[0], s, len);
mp_int_t splits = mp_obj_get_int(args[2]);
+ if (splits < 0) {
+ // Negative limit means no limit, so delegate to split().
+ return mp_obj_str_split(n_args, args);
+ }
+
mp_int_t org_splits = splits;
// Preallocate list to the max expected # of elements, as we
// will fill it from the end.
@@ -798,7 +803,7 @@ STATIC mp_obj_t str_uni_strip(int type, size_t n_args, const mp_obj_t *args) {
}
assert(last_good_char_pos >= first_good_char_pos);
- //+1 to accomodate the last character
+ //+1 to accommodate the last character
size_t stripped_len = last_good_char_pos - first_good_char_pos + 1;
if (stripped_len == orig_str_len) {
// If nothing was stripped, don't bother to dup original string
@@ -1811,7 +1816,7 @@ STATIC mp_obj_t str_islower(mp_obj_t self_in) {
}
#if MICROPY_CPYTHON_COMPAT
-// These methods are superfluous in the presense of str() and bytes()
+// These methods are superfluous in the presence of str() and bytes()
// constructors.
// TODO: should accept kwargs too
STATIC mp_obj_t bytes_decode(size_t n_args, const mp_obj_t *args) {
@@ -2130,7 +2135,7 @@ typedef struct _mp_obj_str8_it_t {
#if !MICROPY_PY_BUILTINS_STR_UNICODE
STATIC mp_obj_t str_it_iternext(mp_obj_t self_in) {
- mp_obj_str8_it_t *self = self_in;
+ mp_obj_str8_it_t *self = MP_OBJ_TO_PTR(self_in);
GET_STR_DATA_LEN(self->str, str, len);
if (self->cur < len) {
mp_obj_t o_out = mp_obj_new_str((const char*)str + self->cur, 1, true);
@@ -2148,7 +2153,7 @@ STATIC mp_obj_t mp_obj_new_str_iterator(mp_obj_t str, mp_obj_iter_buf_t *iter_bu
o->iternext = str_it_iternext;
o->str = str;
o->cur = 0;
- return o;
+ return MP_OBJ_FROM_PTR(o);
}
#endif
diff --git a/py/objstringio.c b/py/objstringio.c
index 9f4adeebbf..645c441cb2 100644
--- a/py/objstringio.c
+++ b/py/objstringio.c
@@ -68,10 +68,23 @@ STATIC mp_uint_t stringio_read(mp_obj_t o_in, void *buf, mp_uint_t size, int *er
return size;
}
+STATIC void stringio_copy_on_write(mp_obj_stringio_t *o) {
+ const void *buf = o->vstr->buf;
+ o->vstr->buf = m_new(char, o->vstr->len);
+ memcpy(o->vstr->buf, buf, o->vstr->len);
+ o->vstr->fixed_buf = false;
+ o->ref_obj = MP_OBJ_NULL;
+}
+
STATIC mp_uint_t stringio_write(mp_obj_t o_in, const void *buf, mp_uint_t size, int *errcode) {
(void)errcode;
mp_obj_stringio_t *o = MP_OBJ_TO_PTR(o_in);
check_stringio_is_open(o);
+
+ if (o->vstr->fixed_buf) {
+ stringio_copy_on_write(o);
+ }
+
mp_uint_t new_pos = o->pos + size;
if (new_pos < size) {
// Writing <size> bytes will overflow o->pos beyond limit of mp_uint_t.
@@ -155,11 +168,11 @@ STATIC mp_obj_t stringio___exit__(size_t n_args, const mp_obj_t *args) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(stringio___exit___obj, 4, 4, stringio___exit__);
-STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type, mp_uint_t alloc) {
+STATIC mp_obj_stringio_t *stringio_new(const mp_obj_type_t *type) {
mp_obj_stringio_t *o = m_new_obj(mp_obj_stringio_t);
o->base.type = type;
- o->vstr = vstr_new(alloc);
o->pos = 0;
+ o->ref_obj = MP_OBJ_NULL;
return o;
}
@@ -170,17 +183,28 @@ STATIC mp_obj_t stringio_make_new(const mp_obj_type_t *type_in, size_t n_args, s
bool initdata = false;
mp_buffer_info_t bufinfo;
+ mp_obj_stringio_t *o = stringio_new(type_in);
+
if (n_args > 0) {
if (MP_OBJ_IS_INT(args[0])) {
sz = mp_obj_get_int(args[0]);
} else {
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
+
+ if (MP_OBJ_IS_STR_OR_BYTES(args[0])) {
+ o->vstr = m_new_obj(vstr_t);
+ vstr_init_fixed_buf(o->vstr, bufinfo.len, bufinfo.buf);
+ o->vstr->len = bufinfo.len;
+ o->ref_obj = args[0];
+ return MP_OBJ_FROM_PTR(o);
+ }
+
sz = bufinfo.len;
initdata = true;
}
}
- mp_obj_stringio_t *o = stringio_new(type_in, sz);
+ o->vstr = vstr_new(sz);
if (initdata) {
stringio_write(MP_OBJ_FROM_PTR(o), bufinfo.buf, bufinfo.len, NULL);
diff --git a/py/objstringio.h b/py/objstringio.h
index 853bfb11b7..56738f4e45 100644
--- a/py/objstringio.h
+++ b/py/objstringio.h
@@ -33,6 +33,8 @@ typedef struct _mp_obj_stringio_t {
vstr_t *vstr;
// StringIO has single pointer used for both reading and writing
mp_uint_t pos;
+ // Underlying object buffered by this StringIO
+ mp_obj_t ref_obj;
} mp_obj_stringio_t;
#endif // MICROPY_INCLUDED_PY_OBJSTRINGIO_H
diff --git a/py/persistentcode.c b/py/persistentcode.c
index a71045a290..2fa8c1df07 100644
--- a/py/persistentcode.c
+++ b/py/persistentcode.c
@@ -286,11 +286,13 @@ STATIC void save_obj(mp_print_t *print, mp_obj_t o) {
byte obj_type;
if (MP_OBJ_IS_TYPE(o, &mp_type_int)) {
obj_type = 'i';
- } else if (mp_obj_is_float(o)) {
- obj_type = 'f';
- } else {
- assert(MP_OBJ_IS_TYPE(o, &mp_type_complex));
+ #if MICROPY_PY_BUILTINS_COMPLEX
+ } else if (MP_OBJ_IS_TYPE(o, &mp_type_complex)) {
obj_type = 'c';
+ #endif
+ } else {
+ assert(mp_obj_is_float(o));
+ obj_type = 'f';
}
vstr_t vstr;
mp_print_t pr;
diff --git a/py/py.mk b/py/py.mk
index 30109ac06f..96fc92cac3 100644
--- a/py/py.mk
+++ b/py/py.mk
@@ -25,7 +25,7 @@ ifeq ($(MICROPY_SSL_AXTLS),1)
CFLAGS_MOD += -DMICROPY_SSL_AXTLS=1 -I../lib/axtls/ssl -I../lib/axtls/crypto -I../lib/axtls/config
LDFLAGS_MOD += -Lbuild -laxtls
else ifeq ($(MICROPY_SSL_MBEDTLS),1)
-# Can be overriden by ports which have "builtin" mbedTLS
+# Can be overridden by ports which have "builtin" mbedTLS
MICROPY_SSL_MBEDTLS_INCLUDE ?= ../lib/mbedtls/include
CFLAGS_MOD += -DMICROPY_SSL_MBEDTLS=1 -I$(MICROPY_SSL_MBEDTLS_INCLUDE)
LDFLAGS_MOD += -L../lib/mbedtls/library -lmbedx509 -lmbedtls -lmbedcrypto
diff --git a/py/ringbuf.h b/py/ringbuf.h
index 5662594f76..5e108afad7 100644
--- a/py/ringbuf.h
+++ b/py/ringbuf.h
@@ -33,7 +33,7 @@ typedef struct _ringbuf_t {
uint16_t iput;
} ringbuf_t;
-// Static initalization:
+// Static initialization:
// byte buf_array[N];
// ringbuf_t buf = {buf_array, sizeof(buf_array)};
diff --git a/py/stream.c b/py/stream.c
index c915110e0b..d3fc767bbd 100644
--- a/py/stream.c
+++ b/py/stream.c
@@ -51,7 +51,7 @@ STATIC mp_obj_t stream_readall(mp_obj_t self_in);
#define STREAM_CONTENT_TYPE(stream) (((stream)->is_text) ? &mp_type_str : &mp_type_bytes)
// Returns error condition in *errcode, if non-zero, return value is number of bytes written
-// before error condition occured. If *errcode == 0, returns total bytes written (which will
+// before error condition occurred. If *errcode == 0, returns total bytes written (which will
// be equal to input size).
mp_uint_t mp_stream_rw(mp_obj_t stream, void *buf_, mp_uint_t size, int *errcode, byte flags) {
byte *buf = buf_;
diff --git a/py/vm.c b/py/vm.c
index 5094e3e450..404c799123 100644
--- a/py/vm.c
+++ b/py/vm.c
@@ -947,7 +947,7 @@ unwind_jump:;
DECODE_UINT;
// unum & 0xff == n_positional
// (unum >> 8) & 0xff == n_keyword
- // We have folowing stack layout here:
+ // We have following stack layout here:
// fun arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 2;
#if MICROPY_STACKLESS
@@ -1018,7 +1018,7 @@ unwind_jump:;
DECODE_UINT;
// unum & 0xff == n_positional
// (unum >> 8) & 0xff == n_keyword
- // We have folowing stack layout here:
+ // We have following stack layout here:
// fun self arg0 arg1 ... kw0 val0 kw1 val1 ... seq dict <- TOS
sp -= (unum & 0xff) + ((unum >> 7) & 0x1fe) + 3;
#if MICROPY_STACKLESS
@@ -1363,22 +1363,25 @@ unwind_loop:
// TODO need a better way of not adding traceback to constant objects (right now, just GeneratorExit_obj and MemoryError_obj)
if (nlr.ret_val != &mp_const_GeneratorExit_obj && nlr.ret_val != &mp_const_MemoryError_obj) {
const byte *ip = code_state->fun_bc->bytecode;
- mp_decode_uint(&ip); // skip n_state
- mp_decode_uint(&ip); // skip n_exc_stack
+ ip = mp_decode_uint_skip(ip); // skip n_state
+ ip = mp_decode_uint_skip(ip); // skip n_exc_stack
ip++; // skip scope_params
ip++; // skip n_pos_args
ip++; // skip n_kwonly_args
ip++; // skip n_def_pos_args
size_t bc = code_state->ip - ip;
- size_t code_info_size = mp_decode_uint(&ip);
+ size_t code_info_size = mp_decode_uint_value(ip);
+ ip = mp_decode_uint_skip(ip); // skip code_info_size
bc -= code_info_size;
#if MICROPY_PERSISTENT_CODE
qstr block_name = ip[0] | (ip[1] << 8);
qstr source_file = ip[2] | (ip[3] << 8);
ip += 4;
#else
- qstr block_name = mp_decode_uint(&ip);
- qstr source_file = mp_decode_uint(&ip);
+ qstr block_name = mp_decode_uint_value(ip);
+ ip = mp_decode_uint_skip(ip);
+ qstr source_file = mp_decode_uint_value(ip);
+ ip = mp_decode_uint_skip(ip);
#endif
size_t source_line = 1;
size_t c;