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>
This commit is contained in:
24
py/qstr.c
24
py/qstr.c
@@ -309,7 +309,7 @@ qstr qstr_from_str(const char *str) {
|
|||||||
return qstr_from_strn(str, strlen(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_ENTER();
|
||||||
qstr q = qstr_find_strn(str, len);
|
qstr q = qstr_find_strn(str, len);
|
||||||
if (q == 0) {
|
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"));
|
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
|
// compute number of bytes needed to intern this string
|
||||||
size_t n_bytes = len + 1;
|
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
|
// store the interned strings' data
|
||||||
memcpy(q_ptr, str, len);
|
memcpy(q_ptr, str, len);
|
||||||
q_ptr[len] = '\0';
|
q_ptr[len] = '\0';
|
||||||
q = qstr_add(len, q_ptr);
|
str = q_ptr;
|
||||||
|
|
||||||
|
add:
|
||||||
|
q = qstr_add(len, str);
|
||||||
}
|
}
|
||||||
QSTR_EXIT();
|
QSTR_EXIT();
|
||||||
return q;
|
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) {
|
mp_uint_t qstr_hash(qstr q) {
|
||||||
const qstr_pool_t *pool = find_qstr(&q);
|
const qstr_pool_t *pool = find_qstr(&q);
|
||||||
#if MICROPY_QSTR_BYTES_IN_HASH
|
#if MICROPY_QSTR_BYTES_IN_HASH
|
||||||
|
|||||||
@@ -101,6 +101,9 @@ qstr qstr_find_strn(const char *str, size_t str_len); // returns MP_QSTRnull if
|
|||||||
|
|
||||||
qstr qstr_from_str(const char *str);
|
qstr qstr_from_str(const char *str);
|
||||||
qstr qstr_from_strn(const char *str, size_t len);
|
qstr qstr_from_strn(const char *str, size_t len);
|
||||||
|
#if MICROPY_VFS_ROM
|
||||||
|
qstr qstr_from_strn_static(const char *str, size_t len);
|
||||||
|
#endif
|
||||||
|
|
||||||
mp_uint_t qstr_hash(qstr q);
|
mp_uint_t qstr_hash(qstr q);
|
||||||
const char *qstr_str(qstr q);
|
const char *qstr_str(qstr q);
|
||||||
|
|||||||
Reference in New Issue
Block a user