From 3a910b15650636efc58bce48cc1bfa0debfd375c Mon Sep 17 00:00:00 2001 From: Jim Mussared Date: Tue, 23 Aug 2022 18:35:37 +1000 Subject: [PATCH] py/objstr: Optimise mp_obj_new_str_from_vstr for known-safe strings. The new `mp_obj_new_str_from_utf8_vstr` can be used when you know you already have a unicode-safe string. Signed-off-by: Jim Mussared --- extmod/modujson.c | 4 ++-- extmod/modure.c | 2 +- ports/unix/modusocket.c | 2 +- py/modbuiltins.c | 2 +- py/obj.h | 5 +++++ py/objstr.c | 7 +++++++ py/parsenum.c | 2 +- py/persistentcode.c | 2 +- 8 files changed, 19 insertions(+), 7 deletions(-) diff --git a/extmod/modujson.c b/extmod/modujson.c index 57c50deec0..4e992e2245 100644 --- a/extmod/modujson.c +++ b/extmod/modujson.c @@ -67,7 +67,7 @@ STATIC mp_obj_t mod_ujson_dump_helper(size_t n_args, const mp_obj_t *pos_args, m vstr_t vstr; vstr_init_print(&vstr, 8, &print_ext.base); mp_obj_print_helper(&print_ext.base, pos_args[0], PRINT_JSON); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } else { // dump(obj, stream) print_ext.base.data = MP_OBJ_TO_PTR(pos_args[1]); @@ -103,7 +103,7 @@ STATIC mp_obj_t mod_ujson_dumps(mp_obj_t obj) { mp_print_t print; vstr_init_print(&vstr, 8, &print); mp_obj_print_helper(&print, obj, PRINT_JSON); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_1(mod_ujson_dumps_obj, mod_ujson_dumps); diff --git a/extmod/modure.c b/extmod/modure.c index 59fbfddbf2..799fef13b1 100644 --- a/extmod/modure.c +++ b/extmod/modure.c @@ -373,7 +373,7 @@ STATIC mp_obj_t re_sub_helper(size_t n_args, const mp_obj_t *args) { vstr_add_strn(&vstr_return, subj.begin, subj.end - subj.begin); if (mp_obj_get_type(where) == &mp_type_str) { - return mp_obj_new_str_from_vstr(&vstr_return); + return mp_obj_new_str_from_utf8_vstr(&vstr_return); } else { return mp_obj_new_bytes_from_vstr(&vstr_return); } diff --git a/ports/unix/modusocket.c b/ports/unix/modusocket.c index 88e7675a92..72c70d1750 100644 --- a/ports/unix/modusocket.c +++ b/ports/unix/modusocket.c @@ -559,7 +559,7 @@ STATIC mp_obj_t mod_socket_inet_ntop(mp_obj_t family_in, mp_obj_t binaddr_in) { mp_raise_OSError(errno); } vstr.len = strlen(vstr.buf); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } STATIC MP_DEFINE_CONST_FUN_OBJ_2(mod_socket_inet_ntop_obj, mod_socket_inet_ntop); diff --git a/py/modbuiltins.c b/py/modbuiltins.c index 2459edda13..f74db95cf5 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -467,7 +467,7 @@ STATIC mp_obj_t mp_builtin_repr(mp_obj_t o_in) { mp_print_t print; vstr_init_print(&vstr, 16, &print); mp_obj_print_helper(&print, o_in, PRINT_REPR); - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_repr_obj, mp_builtin_repr); diff --git a/py/obj.h b/py/obj.h index d171e0fe62..0b0a9692ed 100644 --- a/py/obj.h +++ b/py/obj.h @@ -792,6 +792,11 @@ mp_obj_t mp_obj_new_int_from_ull(unsigned long long val); // this must return a mp_obj_t mp_obj_new_str(const char *data, size_t len); mp_obj_t mp_obj_new_str_via_qstr(const char *data, size_t len); mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr); +#if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK +mp_obj_t mp_obj_new_str_from_utf8_vstr(vstr_t *vstr); // only use when vstr is already known to be utf-8 encoded +#else +#define mp_obj_new_str_from_utf8_vstr mp_obj_new_str_from_vstr +#endif mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr); mp_obj_t mp_obj_new_bytes(const byte *data, size_t len); mp_obj_t mp_obj_new_bytearray(size_t n, const void *items); diff --git a/py/objstr.c b/py/objstr.c index ab1229ad66..5a62237516 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -2256,6 +2256,13 @@ mp_obj_t mp_obj_new_str_from_vstr(vstr_t *vstr) { return mp_obj_new_str_type_from_vstr(&mp_type_str, vstr); } +#if MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK +mp_obj_t mp_obj_new_str_from_utf8_vstr(vstr_t *vstr) { + // bypasses utf8_check. + return mp_obj_new_str_type_from_vstr(&mp_type_str, vstr); +} +#endif // MICROPY_PY_BUILTINS_STR_UNICODE && MICROPY_PY_BUILTINS_STR_UNICODE_CHECK + mp_obj_t mp_obj_new_bytes_from_vstr(vstr_t *vstr) { return mp_obj_new_str_type_from_vstr(&mp_type_bytes, vstr); } diff --git a/py/parsenum.c b/py/parsenum.c index 79765f84f6..d59715fdc9 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -160,7 +160,7 @@ value_error: mp_printf(&print, "invalid syntax for integer with base %d: ", base); mp_str_print_quoted(&print, str_val_start, top - str_val_start, true); mp_obj_t exc = mp_obj_new_exception_arg1(&mp_type_ValueError, - mp_obj_new_str_from_vstr(&vstr)); + mp_obj_new_str_from_utf8_vstr(&vstr)); raise_exc(exc, lex); #endif } diff --git a/py/persistentcode.c b/py/persistentcode.c index 995dedb456..82ef0c4995 100644 --- a/py/persistentcode.c +++ b/py/persistentcode.c @@ -203,7 +203,7 @@ STATIC mp_obj_t load_obj(mp_reader_t *reader) { if (obj_type == MP_PERSISTENT_OBJ_STR || obj_type == MP_PERSISTENT_OBJ_BYTES) { read_byte(reader); // skip null terminator if (obj_type == MP_PERSISTENT_OBJ_STR) { - return mp_obj_new_str_from_vstr(&vstr); + return mp_obj_new_str_from_utf8_vstr(&vstr); } else { return mp_obj_new_bytes_from_vstr(&vstr); }