diff options
author | Damien George <damien@micropython.org> | 2022-03-04 10:40:15 +1100 |
---|---|---|
committer | Damien George <damien@micropython.org> | 2024-12-23 13:04:54 +1100 |
commit | a1c32101ac3bc70ed2774f461c69548ce8dae23d (patch) | |
tree | da59dc3488eda8f87cf485cc3b2b10cd0505c052 /py/qstr.c | |
parent | 50637ff239cb6a09294f49fe2d2534c2d7ae8b76 (diff) |
py/qstr: Add qstr_from_strn_static() helper function.
Allows an interned string to reference static/ROM data, instead of
allocating it on the GC heap.
Signed-off-by: Damien George <damien@micropython.org>
Diffstat (limited to 'py/qstr.c')
-rw-r--r-- | py/qstr.c | 24 |
1 files changed, 22 insertions, 2 deletions
@@ -309,7 +309,7 @@ qstr qstr_from_str(const char *str) { return qstr_from_strn(str, strlen(str)); } -qstr qstr_from_strn(const char *str, size_t len) { +static qstr qstr_from_strn_helper(const char *str, size_t len, bool data_is_static) { QSTR_ENTER(); qstr q = qstr_find_strn(str, len); if (q == 0) { @@ -321,6 +321,12 @@ qstr qstr_from_strn(const char *str, size_t len) { mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("name too long")); } + if (data_is_static) { + // Given string data will be forever available so use it directly. + assert(str[len] == '\0'); + goto add; + } + // compute number of bytes needed to intern this string size_t n_bytes = len + 1; @@ -364,12 +370,26 @@ qstr qstr_from_strn(const char *str, size_t len) { // store the interned strings' data memcpy(q_ptr, str, len); q_ptr[len] = '\0'; - q = qstr_add(len, q_ptr); + str = q_ptr; + + add: + q = qstr_add(len, str); } QSTR_EXIT(); return q; } +qstr qstr_from_strn(const char *str, size_t len) { + return qstr_from_strn_helper(str, len, false); +} + +#if MICROPY_VFS_ROM +// Create a new qstr that can forever reference the given string data. +qstr qstr_from_strn_static(const char *str, size_t len) { + return qstr_from_strn_helper(str, len, true); +} +#endif + mp_uint_t qstr_hash(qstr q) { const qstr_pool_t *pool = find_qstr(&q); #if MICROPY_QSTR_BYTES_IN_HASH |