microPython的源码解析之 qstr.c

MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.


microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
python编程示例系列 python编程示例系列二
python的Web神器Streamlit


这段代码是MicroPython的一部分,用于管理和查找qstr(快速字符串)。qstr是MicroPython中的一个概念,表示一个已经被存储在只读内存中的字符串,这样可以快速地通过索引来访问它们。代码中使用了哈希表来快速查找字符串,并且支持多线程环境下的线程安全。此外,还支持字符串的压缩和解压缩,以节省内存空间。代码中还包含了一些用于调试和内存管理的辅助函数。

#include <assert.h>
#include <string.h>
#include <stdio.h>

// 引入MicroPython特定的头文件
#include "py/mpstate.h"
#include "py/qstr.h"
#include "py/gc.h"
#include "py/runtime.h"

// 根据编译时定义的宏开关,决定是否打印调试信息
#if MICROPY_DEBUG_VERBOSE // 打印调试信息
#define DEBUG_printf DEBUG_printf
#else // 不打印调试信息
#define DEBUG_printf(...) (void)0
#endif

// qstr是qstr池中字符串的索引。
// qstr的数据是\0结尾的(因此可以使用printf打印)

// 根据宏定义决定哈希掩码的大小
#if MICROPY_QSTR_BYTES_IN_HASH
#define Q_HASH_MASK ((1 << (8 * MICROPY_QSTR_BYTES_IN_HASH)) - 1)
#else
#define Q_HASH_MASK (0xffff)
#endif

// 如果启用了线程支持,定义线程安全的操作
#if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
#define QSTR_ENTER() mp_thread_mutex_lock(&MP_STATE_VM(qstr_mutex), 1)
#define QSTR_EXIT() mp_thread_mutex_unlock(&MP_STATE_VM(qstr_mutex))
#else
#define QSTR_ENTER()
#define QSTR_EXIT()
#endif

// qstr池的初始大小,设置为使第一次动态分配的池大小是这个值的两倍
#define MICROPY_ALLOC_QSTR_ENTRIES_INIT (10)

// 计算字符串的哈希值,使用djb2算法
size_t qstr_compute_hash(const byte *data, size_t len) {
   
    size_t hash = 5381; // 初始化哈希值为5381
    for (const byte *top = data + len; data < top; data++) {
   
        hash = ((hash << 5) + hash) ^ (*data); // 对每个字节进行哈希计算
    }
    hash &= Q_HASH_MASK; // 应用哈希掩码
    // 确保有效的哈希值永远不会是0,0表示“哈希未计算”
    if (hash == 0) {
   
        hash++;
    }
    return hash;
}

// 静态qstr表,内容必须保持稳定,因为它是.mpy ABI的一部分
#if MICROPY_QSTR_BYTES_IN_HASH
const qstr_hash_t mp_qstr_const_hashes_static[] = {
   
    // 根据genhdr/qstrdefs.generated.h文件生成的qstr哈希值
    #ifndef NO_QSTR
#define QDEF0(id, hash, len, str) hash,
#define QDEF1(id, hash, len, str)
    #include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
    #endif
};
#endif

const qstr_len_t mp_qstr_const_lengths_static[] = {
   
    // 根据genhdr/qstrdefs.generated.h文件生成的qstr长度
    #ifndef NO_QSTR
#define QDEF0(id, hash, len, str) len,
#define QDEF1(id, hash, len, str)
    #include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
    #endif
};

const qstr_pool_t mp_qstr_const_pool_static = {
   
    NULL,               // 没有前一个池
    0,                  // 没有前一个池
    false,              // 未排序
    MICROPY_ALLOC_QSTR_ENTRIES_INIT,
    MP_QSTRnumber_of_static,   // 对应于数组中字符串的数量
    #if MICROPY_QSTR_BYTES_IN_HASH
    (qstr_hash_t *)mp_qstr_const_hashes_static,
    #endif
    (qstr_len_t *)mp_qstr_const_lengths_static,
    {
   
        // 根据genhdr/qstrdefs.generated.h文件生成的字符串
        #ifndef NO_QSTR
#define QDEF0(id, hash, len, str) str,
#define QDEF1(id, hash, len, str)
        #include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
        #endif
    },
};

// 固件中定义的其余qstrs的池,已排序
#if MICROPY_QSTR_BYTES_IN_HASH
const qstr_hash_t mp_qstr_const_hashes[] = {
   
    // 根据genhdr/qstrdefs.generated.h文件生成的qstr哈希值
    #ifndef NO_QSTR
#define QDEF0(id, hash, len, str)
#define QDEF1(id, hash, len, str) hash,
    #include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
    #endif
};
#endif

const qstr_len_t mp_qstr_const_lengths[] = {
   
    // 根据genhdr/qstrdefs.generated.h文件生成的qstr长度
    #ifndef NO_QSTR
#define QDEF0(id, hash, len, str)
#define QDEF1(id, hash, len, str) len,
    #include "genhdr/qstrdefs.generated.h"
#undef QDEF0
#undef QDEF1
    #endif
};

const qstr_pool_t mp_qstr_const_pool = {
   
    &mp_qstr_const_pool_static,
    MP_QSTRnumber_of_static,
    true,               // 已排序
    MICROPY_ALLOC_QSTR_ENTRIES_INIT,
    MP_QSTRnumber_of - MP_QSTRnumber_of_static,   // 对应于数组中字符串的数量
    #if MICROPY_QSTR_BYTES_IN_HASH
    (qstr_hash_t *)mp_qstr_const_hashes,
    #endif
    (qstr_len_t *)mp_qstr_const_lengths,
    {
   
        // 根据genhdr/qstrdefs.generated.h文件生成的字符串
        #ifndef NO_QSTR
#define QDEF0(id, hash, len, str)
#define QDEF1(id, hash, len, str) str,
        #include "genhdr/qstrdefs.generated.h"
#undef 
  • 13
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

openwin_top

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值