4343#endif
4444
4545// A qstr is an index into the qstr pool.
46- // The data for a qstr contains (hash, length, data).
47- // For now we use very simple encoding, just to get the framework correct:
48- // - hash is 2 bytes (see function below)
49- // - length is 2 bytes
50- // - data follows
51- // - \0 terminated (for now, so they can be printed using printf)
52-
53- #define Q_GET_HASH (q ) ((mp_uint_t)(q)[0] | ((mp_uint_t)(q)[1] << 8))
54- #define Q_GET_ALLOC (q ) (2 + MICROPY_QSTR_BYTES_IN_LEN + Q_GET_LENGTH(q) + 1)
55- #define Q_GET_DATA (q ) ((q) + 2 + MICROPY_QSTR_BYTES_IN_LEN)
46+ // The data for a qstr contains (hash, length, data):
47+ // - hash (configurable number of bytes)
48+ // - length (configurable number of bytes)
49+ // - data ("length" number of bytes)
50+ // - \0 terminated (so they can be printed using printf)
51+
52+ #if MICROPY_QSTR_BYTES_IN_HASH == 1
53+ #define Q_HASH_MASK (0xff)
54+ #define Q_GET_HASH (q ) ((mp_uint_t)(q)[0])
55+ #define Q_SET_HASH (q , hash ) do { (q)[0] = (hash); } while (0)
56+ #elif MICROPY_QSTR_BYTES_IN_HASH == 2
57+ #define Q_HASH_MASK (0xffff)
58+ #define Q_GET_HASH (q ) ((mp_uint_t)(q)[0] | ((mp_uint_t)(q)[1] << 8))
59+ #define Q_SET_HASH (q , hash ) do { (q)[0] = (hash); (q)[1] = (hash) >> 8; } while (0)
60+ #else
61+ #error unimplemented qstr hash decoding
62+ #endif
63+ #define Q_GET_ALLOC (q ) (MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + Q_GET_LENGTH(q) + 1)
64+ #define Q_GET_DATA (q ) ((q) + MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN)
5665#if MICROPY_QSTR_BYTES_IN_LEN == 1
57- #define Q_GET_LENGTH (q ) ((q)[2 ])
58- #define Q_SET_LENGTH (q , len ) do { (q)[2 ] = (len); } while (0)
66+ #define Q_GET_LENGTH (q ) ((q)[MICROPY_QSTR_BYTES_IN_HASH ])
67+ #define Q_SET_LENGTH (q , len ) do { (q)[MICROPY_QSTR_BYTES_IN_HASH ] = (len); } while (0)
5968#elif MICROPY_QSTR_BYTES_IN_LEN == 2
60- #define Q_GET_LENGTH (q ) ((q)[2 ] | ((q)[3 ] << 8))
61- #define Q_SET_LENGTH (q , len ) do { (q)[2 ] = (len); (q)[3 ] = (len) >> 8; } while (0)
69+ #define Q_GET_LENGTH (q ) ((q)[MICROPY_QSTR_BYTES_IN_HASH ] | ((q)[MICROPY_QSTR_BYTES_IN_HASH + 1 ] << 8))
70+ #define Q_SET_LENGTH (q , len ) do { (q)[MICROPY_QSTR_BYTES_IN_HASH ] = (len); (q)[MICROPY_QSTR_BYTES_IN_HASH + 1 ] = (len) >> 8; } while (0)
6271#else
6372 #error unimplemented qstr length decoding
6473#endif
@@ -70,7 +79,7 @@ mp_uint_t qstr_compute_hash(const byte *data, mp_uint_t len) {
7079 for (const byte * top = data + len ; data < top ; data ++ ) {
7180 hash = ((hash << 5 ) + hash ) ^ (* data ); // hash * 33 ^ data
7281 }
73- hash &= 0xffff ;
82+ hash &= Q_HASH_MASK ;
7483 // Make sure that valid hash is never zero, zero means "hash not computed"
7584 if (hash == 0 ) {
7685 hash ++ ;
@@ -156,7 +165,7 @@ qstr qstr_from_strn(const char *str, mp_uint_t len) {
156165 // qstr does not exist in interned pool so need to add it
157166
158167 // compute number of bytes needed to intern this string
159- mp_uint_t n_bytes = 2 + MICROPY_QSTR_BYTES_IN_LEN + len + 1 ;
168+ mp_uint_t n_bytes = MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + len + 1 ;
160169
161170 if (MP_STATE_VM (qstr_last_chunk ) != NULL && MP_STATE_VM (qstr_last_used ) + n_bytes > MP_STATE_VM (qstr_last_alloc )) {
162171 // not enough room at end of previously interned string so try to grow
@@ -193,19 +202,18 @@ qstr qstr_from_strn(const char *str, mp_uint_t len) {
193202
194203 // store the interned strings' data
195204 mp_uint_t hash = qstr_compute_hash ((const byte * )str , len );
196- q_ptr [0 ] = hash ;
197- q_ptr [1 ] = hash >> 8 ;
205+ Q_SET_HASH (q_ptr , hash );
198206 Q_SET_LENGTH (q_ptr , len );
199- memcpy (q_ptr + 2 + MICROPY_QSTR_BYTES_IN_LEN , str , len );
200- q_ptr [2 + MICROPY_QSTR_BYTES_IN_LEN + len ] = '\0' ;
207+ memcpy (q_ptr + MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN , str , len );
208+ q_ptr [MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + len ] = '\0' ;
201209 q = qstr_add (q_ptr );
202210 }
203211 return q ;
204212}
205213
206214byte * qstr_build_start (mp_uint_t len , byte * * q_ptr ) {
207215 assert (len < (1 << (8 * MICROPY_QSTR_BYTES_IN_LEN )));
208- * q_ptr = m_new (byte , 2 + MICROPY_QSTR_BYTES_IN_LEN + len + 1 );
216+ * q_ptr = m_new (byte , MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + len + 1 );
209217 Q_SET_LENGTH (* q_ptr , len );
210218 return Q_GET_DATA (* q_ptr );
211219}
@@ -215,9 +223,8 @@ qstr qstr_build_end(byte *q_ptr) {
215223 if (q == 0 ) {
216224 mp_uint_t len = Q_GET_LENGTH (q_ptr );
217225 mp_uint_t hash = qstr_compute_hash (Q_GET_DATA (q_ptr ), len );
218- q_ptr [0 ] = hash ;
219- q_ptr [1 ] = hash >> 8 ;
220- q_ptr [2 + MICROPY_QSTR_BYTES_IN_LEN + len ] = '\0' ;
226+ Q_SET_HASH (q_ptr , hash );
227+ q_ptr [MICROPY_QSTR_BYTES_IN_HASH + MICROPY_QSTR_BYTES_IN_LEN + len ] = '\0' ;
221228 q = qstr_add (q_ptr );
222229 } else {
223230 m_del (byte , q_ptr , Q_GET_ALLOC (q_ptr ));
0 commit comments