microPython的源码解析之 nativeglue.c

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

microPython Python最小内核源码解析
这段代码是MicroPython的一部分,MicroPython是一个为微控制器设计的Python解释器。代码主要涉及本地桥接(将MicroPython对象和C/C++代码相互转换)和函数表的定义,这些函数表用于MicroPython的本地代码生成和执行。代码中的注释已经翻译成中文,并且添加了一些额外的注释来帮助理解代码的功能。

#include <stdarg.h> // 包含可变参数函数头文件
#include <stdio.h>  // 包含标准输入输出库头文件
#include <string.h> // 包含字符串处理函数库头文件
#include <assert.h>  // 包含断言宏的头文件

// 包含MicroPython运行时环境的头文件
#include "py/runtime.h"
// 包含MicroPython小整数处理的头文件
#include "py/smallint.h"
// 包含MicroPython本地桥接的头文件
#include "py/nativeglue.h"
// 包含垃圾收集的头文件
#include "py/gc.h"

#if MICROPY_DEBUG_VERBOSE // 如果定义了详细的调试信息
#define DEBUG_printf DEBUG_printf
#else // 如果没有定义详细的调试信息
#define DEBUG_printf(...) (void)0 // 忽略调试信息
#endif

#if MICROPY_EMIT_NATIVE // 如果定义了本地代码的生成

// 根据qstr(字符串常量)获取对应的本地类型
int mp_native_type_from_qstr(qstr qst) {
   
    switch (qst) {
   
        case MP_QSTR_object: // 对象类型
            return MP_NATIVE_TYPE_OBJ;
        case MP_QSTR_bool: // 布尔类型
            return MP_NATIVE_TYPE_BOOL;
        case MP_QSTR_int: // 整数类型
            return MP_NATIVE_TYPE_INT;
        case MP_QSTR_uint: // 无符号整数类型
            return MP_NATIVE_TYPE_UINT;
        case MP_QSTR_ptr: // 指针类型
            return MP_NATIVE_TYPE_PTR;
        case MP_QSTR_ptr8: // 8位指针类型
            return MP_NATIVE_TYPE_PTR8;
        case MP_QSTR_ptr16: // 16位指针类型
            return MP_NATIVE_TYPE_PTR16;
        case MP_QSTR_ptr32: // 32位指针类型
            return MP_NATIVE_TYPE_PTR32;
        default:
            return -1; // 默认返回-1表示不支持的类型
    }
}

// 根据类型将MicroPython对象转换为有效的本地值
mp_uint_t mp_native_from_obj(mp_obj_t obj, mp_uint_t type) {
   
    DEBUG_printf("mp_native_from_obj(%p, " UINT_FMT ")\n", obj, type);
    switch (type & 0xf) {
    // 转换低4位作为类型
        case MP_NATIVE_TYPE_OBJ: // 对象类型
            return (mp_uint_t)obj;
        case MP_NATIVE_TYPE_BOOL: // 布尔类型
            return mp_obj_is_true(obj); // 判断对象是否为真
        case MP_NATIVE_TYPE_INT: // 整数类型
        case MP_NATIVE_TYPE_UINT: // 无符号整数类型
            return mp_obj_get_int_truncated(obj); // 获取对象的整数值,如果超出范围则进行截断
        default: {
    // 其他类型,将对象转换为指针
            mp_buffer_info_t bufinfo;
            if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_READ)) {
    // 获取对象的缓冲区信息
                return (mp_uint_t)bufinfo.buf; // 返回缓冲区的地址
            } else {
   
                // 假设对象是一个表示地址的整数
                return mp_obj_get_int_truncated(obj);
            }
        }
    }
}

#endif

#if MICROPY_EMIT_MACHINE_CODE // 如果定义了机器代码的生成

// 根据类型将本地值转换为MicroPython对象
mp_obj_t mp_native_to_obj(mp_uint_t val, mp_uint_t type) {
   
    DEBUG_printf("mp_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type);
    switch (type & 0xf) {
    // 转换低4位作为类型
        case MP_NATIVE_TYPE_OBJ: // 对象类型
            return (mp_obj_t)val;
        case MP_NATIVE_TYPE_BOOL: // 布尔类型
            return mp_obj_new_bool(val); // 创建一个新的布尔对象
        case MP_NATIVE_TYPE_INT: // 整数类型
            return mp_obj_new_int(val); // 创建一个新的整数对象
        case MP_NATIVE_TYPE_UINT: // 无符号整数类型
            return mp_obj_new_int_from_uint(val); // 创建一个新的无符号整数对象
        case MP_NATIVE_TYPE_QSTR: // 字符串常量类型
            return MP_OBJ_NEW_QSTR(val);
        default: // 指针类型
            // 将指针的值作为整数返回
            return mp_obj_new_int_from_uint(val);
    }
}

#endif

#if MICROPY_EMIT_NATIVE && !MICROPY_DYNAMIC_COMPILER // 如果定义了本地代码的生成且没有定义动态编译器

#if !MICROPY_PY_BUILTINS_SET
// 没有定义集合类型时,抛出不支持的异常
mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) {
   
    (void)n_args;
    (void)items;
    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("set unsupported"));
}
#endif

#if !MICROPY_PY_BUILTINS_SLICE
// 没有定义切片类型时,抛出不支持的异常
mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) {
   
    (void)ostart;
    (void)ostop;
    (void)ostep;
    mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("slice unsupported"));
}
#endif

// 交换全局变量字典
static mp_obj_dict_t *mp_native_swap_globals(mp_obj_dict_t *new_globals) {
   
    if (new_globals == NULL) {
   
        // 如果新的全局变量字典为空,则不需要恢复原来的全局变量字典
        return NULL;
    }
    mp_obj_dict_t *old_globals = mp_globals_get(); // 获取当前的全局变量字典
    if (old_globals == new_globals) {
   
        // 如果新的全局变量字典和原来的相同,则不需要设置新的全局变量字典,并返回NULL
        return NULL;
    }
    mp_globals_set(new_globals); // 设置新的全局变量字典
    return old_globals; // 返回原来的全局变量字典
}

// 调用函数,接受n_args和n_kw作为单个参数
static mp_obj_t mp_native_call_function_n_kw(mp_obj_t fun_in, size_t n_args_kw, const mp_obj_t *args) {
   
    return mp_call_function_n_kw(fun_in, n_args_kw & 0xff, (n_args_kw >> 8) & 0xff, args); // 调用函数并返回结果
}

// 抛出异常
static void mp_native_raise(mp_obj_t o) {
   
    if (o != MP_OBJ_NULL && o != mp_const_none) {
    // 如果o不是None对象
        nlr_raise(mp_make_raise_obj(o)); // 抛出异常
    }
}

// 获取迭代器的缓冲区
static mp_obj_t mp_native_getiter(mp_obj_t obj, mp_obj_iter_buf_t *iter) {
   
    if (iter == NULL) {
   
        return mp_getiter(obj, NULL); // 获取迭代器,如果没有提供缓冲区则返回NULL
    } else {
   
        obj = mp_getiter(obj, iter); // 获取迭代器
        if (obj != MP_OBJ_FROM_PTR(iter)) {
   
            // 如果迭代器没有使用栈,则用MP_OBJ_NULL表示
            iter->base.type = MP_OBJ_NULL;
            iter->buf[0] = obj;
        }
        return NULL;
    }
}

// 获取迭代器的下一个元素
static mp_obj_t mp_native_iternext(mp_obj_iter_buf_t *</
  • 7
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

openwin_top

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

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

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

打赏作者

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

抵扣说明:

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

余额充值