microPython的源码解析之 runtime.c

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


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


这段代码是一个嵌入式Python解释器MicroPython的一部分,它负责初始化和运行Python代码。下面是代码的中文注释版本,我将尽量详细解释每一部分的功能。

#include <assert.h> // 断言宏,用于调试
#include <stdarg.h> // 可变参数列表处理
#include <stdio.h> // 标准输入输出库
#include <string.h> // 字符串处理函数
#include <unistd.h> // POSIX系统接口

// MicroPython特定的头文件
#include "py/parsenum.h"
#include "py/compile.h"
#include "py/objstr.h"
#include "py/objtuple.h"
#include "py/objlist.h"
#include "py/objtype.h"
#include "py/objmodule.h"
#include "py/objgenerator.h"
#include "py/smallint.h"
#include "py/stream.h"
#include "py/runtime.h"
#include "py/builtin.h"
#include "py/stackctrl.h"
#include "py/gc.h"

// 调试信息打印宏定义
#if MICROPY_DEBUG_VERBOSE // 如果定义了MICROPY_DEBUG_VERBOSE,则打印调试信息
#define DEBUG_PRINT (1)
#define DEBUG_printf DEBUG_printf
#define DEBUG_OP_printf(...) DEBUG_printf(__VA_ARGS__)
#else // 不打印调试信息
#define DEBUG_printf(...) (void)0
#define DEBUG_OP_printf(...) (void)0
#endif

// 定义__main__模块
const mp_obj_module_t mp_module___main__ = {
   
    .base = {
    &mp_type_module }, // 继承自模块类型
    .globals = (mp_obj_dict_t *)&MP_STATE_VM(dict_main), // 指向全局字典
};

// 注册__main__模块
MP_REGISTER_MODULE(MP_QSTR___main__, mp_module___main__);

// 定义类型是否有迭代器的方法
#define TYPE_HAS_ITERNEXT(type) (type->flags & (MP_TYPE_FLAG_ITER_IS_ITERNEXT | MP_TYPE_FLAG_ITER_IS_CUSTOM | MP_TYPE_FLAG_ITER_IS_STREAM))

// 初始化MicroPython解释器
void mp_init(void) {
   
    // 初始化qstr(快速字符串)
    qstr_init();

    // 初始时没有异常
    MP_STATE_THREAD(mp_pending_exception) = MP_OBJ_NULL;

    // 如果启用了调度器,初始化调度器状态
    #if MICROPY_ENABLE_SCHEDULER
    MP_STATE_VM(sched_state) = MP_SCHED_IDLE;
    #endif

    // 初始化紧急异常缓冲区
    #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
    mp_init_emergency_exception_buf();
    #endif

    // 初始化键盘中断异常对象
    #if MICROPY_KBD_EXCEPTION
    MP_STATE_VM(mp_kbd_exception).base.type = &mp_type_KeyboardInterrupt;
    #endif

    // 初始化编译器优化选项
    #if MICROPY_ENABLE_COMPILER
    MP_STATE_VM(mp_optimise_value) = 0;
    #endif

    // 初始化全局模块字典
    mp_obj_dict_init(&MP_STATE_VM(mp_loaded_modules_dict), MICROPY_LOADED_MODULES_DICT_SIZE);

    // 初始化__main__模块的字典
    mp_obj_dict_init(&MP_STATE_VM(dict_main), 1);
    mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(dict_main)), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__));

    // 设置局部变量等于全局变量,用于最外层模块
    mp_locals_set(&MP_STATE_VM(dict_main));
    mp_globals_set(&MP_STATE_VM(dict_main));

    // 初始化其他MicroPython特性
    #if MICROPY_CAN_OVERRIDE_BUILTINS
    MP_STATE_VM(mp_module_builtins_override_dict) = NULL;
    #endif

    // 初始化VFS文件系统
    #if MICROPY_VFS
    MP_STATE_VM(vfs_cur) = NULL;
    MP_STATE_VM(vfs_mount_table) = NULL;
    #endif

    // 初始化Python系统路径
    #if MICROPY_PY_SYS_PATH_ARGV_DEFAULTS
    mp_sys_path = mp_obj_new_list(0, NULL);
    #endif

    // 初始化系统退出函数
    #if MICROPY_PY_SYS_ATEXIT
    MP_STATE_VM(sys_exitfunc) = mp_const_none;
    #endif

    // 初始化Python的PS1和PS2提示符
    #if MICROPY_PY_SYS_PS1_PS2
    MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS1]) = MP_OBJ_NEW_QSTR(MP_QSTR__gt__gt__gt__space_);
    MP_STATE_VM(sys_mutable[MP_SYS_MUTABLE_PS2]) = MP_OBJ_NEW_QSTR(MP_QSTR__dot__dot__dot__space_);
    #endif

    // 初始化跟踪回调
    #if MICROPY_PY_SYS_SETTRACE
    MP_STATE_THREAD(prof_trace_callback) = MP_OBJ_NULL;
    #endif

    // 初始化蓝牙模块
    #if MICROPY_PY_BLUETOOTH
    MP_STATE_VM(bluetooth) = MP_OBJ_NULL;
    #endif

    // 初始化USB设备
    #if MICROPY_HW_ENABLE_USB_RUNTIME_DEVICE
    MP_STATE_VM(usbd) = MP_OBJ_NULL;
    #endif

    // 初始化线程GIL(全局解释器锁)
    #if MICROPY_PY_THREAD_GIL
    mp_thread_mutex_init(&MP_STATE_VM(gil_mutex));
    #endif

    // 调用端口特定的初始化函数
    #ifdef MICROPY_PORT_INIT_FUNC
    MICROPY_PORT_INIT_FUNC;
    #endif

    // 进入全局解释器锁
    MP_THREAD_GIL_ENTER();
}

// 反初始化MicroPython解释器
void mp_deinit(void) {
   
    // 退出全局解释器锁
    MP_THREAD_GIL_EXIT();

    // 调用端口特定的反初始化函数
    #ifdef MICROPY_PORT_DEINIT_FUNC
    MICROPY_PORT_DEINIT_FUNC;
    #endif
}

// 从异常跳转回调中设置全局和局部变量
void mp_globals_locals_set_from_nlr_jump_callback(void *ctx_in) {
   
    nlr_jump_callback_node_globals_locals_t *ctx = ctx_in;
    mp_globals_set(ctx->globals);
    mp_locals_set(ctx->locals);
}

// 从异常跳转回调中调用函数
void mp_call_function_1_from_nlr_jump_callback(void *ctx_in) {
   
    nlr_jump_callback_node_call_function_1_t *ctx = ctx_in;
    ctx->func(ctx->arg);
}

// 加载名称(变量或函数名)
mp_obj_t MICROPY_WRAP_MP_LOAD_NAME(mp_load_name)(qstr qst) {
   
    // 首先在局部变量中查找,如果找不到再到全局变量和内置变量中查找
    DEBUG_OP_printf("加载名称 %s\n", qstr_str(qst));
    if (mp_locals_get() != mp_globals_get()) {
   
        mp_map_elem_t *elem = mp_map_lookup(&mp_locals_get()->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
        if (elem != NULL) {
   
            return elem->value;
        }
    }
    return mp_load_global(qst); // 如果局部变量中没有找到,调用全局查找函数
}

// 加载全局名称
mp_obj_t MICROPY_WRAP_MP_LOAD_GLOBAL(mp_load_global)(qstr qst) {
   
    // 在全局变量和内置变量中查找名称
    DEBUG_OP_printf("加载全局 %s\n", qstr_str(qst));
    mp_map_elem_t *elem = mp_map_lookup(&mp_globals_get()->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
    if (elem == NULL) {
   
        #if MICROPY_CAN_OVERRIDE_BUILTINS
        // 如果允许覆盖内置模块,先在动态表中查找
        if (MP_STATE_VM(mp_module_builtins_override_dict) != NULL) {
   
            elem = mp_map_lookup(&MP_STATE_VM(mp_module_builtins_override_dict)->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
            if (elem != NULL) {
   
                return elem->value;
            }
        }
        #endif
        // 接着在内置模块的全局字典中查找
        elem = mp_map_lookup((mp_map_t *)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP);
        if (elem == NULL) {
   
            // 如果还是没有找到,抛出名称未定义的错误
            #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
            mp_raise_msg(&mp_type_NameError, MP_ERROR_TEXT("name not defined"));
            #else
            mp_raise_msg_varg(&mp_type_NameError, MP_ERROR_TEXT("name '%q' isn't defined"), qst);
            #endif
        }
    }
    return elem->value; // 返回找到的值
}

// 加载构建类的功能
mp_obj_t mp_load_build_class(void) {
   
    DEBUG_OP_printf("加载构建类\n");
    #if MICROPY_CAN_OVERRIDE_BUILTINS
    // 如果允许覆盖内置模块,先在动态表中查找
    if (MP_STATE_VM(mp_module_builtins_override_dict) != NULL) {
   
        mp_map_elem_t *elem = mp_map_lookup(&MP_STATE_VM(mp_module_builtins_override_dict)->map, MP_OBJ_NEW_QSTR(MP_QSTR___build_class__), MP_MAP_LOOKUP);       if (elem != NULL) {
   
            return elem->value;
        }
    }
    #endif
    // 如果没有找到,返回内置的构建类对象
    return MP_OBJ_FROM_PTR(&mp_builtin___build_class___obj);
}

// 存储名称到局部变量字典
void mp_store_name(qstr qst, mp_obj_t obj) {
   
    DEBUG_OP_printf("存储名称 %s <- %p\n", qstr_str(qst), obj);
    mp_obj_dict_store(MP_OBJ_FROM_PTR(mp_locals_get()), MP_OBJ_NEW_QSTR(qst), obj);
}

// 从局部变量字典中删除名称
void mp_delete_name(qstr qst) {
   
    DEBUG_OP_printf("删除名称 %s\n", qstr_str(qst));
    mp_obj_dict_delete(MP_OBJ_FROM_PTR(mp_locals_get()), MP_OBJ_NEW_QSTR(qst));
}

// 存储名称到全局变量字典
void mp_store_global(qstr qst, mp_obj_t obj) {
   
    DEBUG_OP_printf("存储全局 %s <- %p\n", qstr_str(qst), obj);
    mp_obj_dict_store(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(qst), obj);
}

// 从全局变量字典中删除名称
void mp_delete_global(qstr qst) {
   
    DEBUG_OP_printf("删除全局 %s\n", qstr_str(qst));
    mp_obj_dict_delete(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(qst));
}

// 执行一元操作
mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) {
   
    DEBUG_OP_printf("一元操作 %u %q %p\n", op, mp_unary_op_method_name[op], arg);

    // 根据不同的一元操作类型执行相应的操作
    switch (op) {
   
        case MP_UNARY_OP_NOT: // 逻辑非
            return mp_obj_new_bool(mp_obj_is_true(arg) == 0);
        case MP_UNARY_OP_BOOL: // 布尔值
            return mp_obj_new_bool(MP_OBJ_SMALL_INT_VALUE(arg) != 0);
        case MP_UNARY_OP_HASH: // 哈希值
            return arg;
        case MP_UNARY_OP_POSITIVE:
        case MP_UNARY_OP_INT_MAYBE:
            return arg;
        case MP_UNARY_OP_NEGATIVE: // 取反
            if (MP_OBJ_SMALL_INT_VALUE(arg) == MP_SMALL_INT_MIN) {
   
                return mp_obj_new_int(-MP_OBJ_SMALL_INT_VALUE(arg));
            } else {
   
                return MP_OBJ_NEW_SMALL_INT(-MP_OBJ_SMALL_INT_VALUE(arg));
            }
        case MP_UNARY_OP_ABS: // 绝对值
            if (MP_OBJ_SMALL_INT_VALUE(arg) >= 0) {
   
                return arg;
            } else if (MP_OBJ_SMALL_INT_VALUE(arg) == MP_SMALL_INT_MIN) {
   
                return mp_obj_new_int(-MP_OBJ_SMALL_INT_VALUE(arg));
            } else {
   
                return MP_OBJ_NEW_SMALL_INT(-MP_OBJ_SMALL_INT_VALUE(arg));
            }
        default:
            assert(op == MP_UNARY_OP_INVERT); // 位取反
            return MP_OBJ_NEW_SMALL_INT(~MP_OBJ_SMALL_INT_VALUE(arg));
    }
}
以下是翻译和补充注释后的代码:

```c
mp_obj_t MICROPY_WRAP_MP_BINARY_OP(mp_binary_op)(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs) {
   
    DEBUG_OP_printf("binary " UINT_FMT " %q %p %p\n", op, mp_binary_op_method_name[op], lhs, rhs);

    // TODO: 正确区分可变对象的就地操作符
    // CPython用于+=的查找逻辑:
    //   检查是否实现了 +=
    //   然后检查是否实现了 +
    //   然后检查是否实现了seq.inplace_concat
    //   然后检查是否实现了seq.concat
    //   然后失败
    // 请注意,列表没有实现+或+=,因此在+=时首先到达inplace_concat

    // 处理is
    if (op == MP_BINARY_OP_IS) {
   
        return mp_obj_new_bool(lhs == rhs);
    }

    // 处理所有类型的==和!=
    if (op == MP_BINARY_OP_EQUAL || op == MP_BINARY_OP_NOT_EQUAL) {
   
        // mp_obj_equal_not_equal支持许多快捷方式
        return mp_obj_equal_not_equal(op, lhs, rhs);
    }

    // 处理所有类型的exception_match
    if (op == MP_BINARY_OP_EXCEPTION_MATCH) {
   
        // 必须是rhs是BaseException的子类
        if (mp_obj_is_exception_type(rhs)) {
   
            if (mp_obj_exception_match(lhs, rhs)) {
   
                return mp_const_true;
            } else {
   
                return mp_const_false;
            }
        } else if (mp_obj_is_type(rhs, &mp_type_tuple)) {
   
            mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(rhs);
            for (size_t i = 0; i < tuple->len; i++) {
   
                rhs = tuple->items[i];
                if (!mp_obj_is_exception_type(rhs)) {
   
                    goto unsupported_op;
                }
                if (mp_obj_exception_match(lhs, rhs)) {
   
                    return mp_const_true;
                }
            }
            return mp_const_false;
        }
        goto unsupported_op;
    }

    // 小整数的二元操作
    if (mp_obj_is_small_int(lhs)) {
   
        mp_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs);
        if (mp_obj_is_small_int(rhs)) {
   
            mp_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs);
            // 这是一个二元操作:lhs_val op rhs_val
            // 我们需要小心处理溢出问题;参见CERT INT32-C
            // 可能溢出的操作:
            //      +       结果始终适合mp_int_t,然后由SMALL_INT检查处理
            //      -       结果始终适合mp_int_t,然后由SMALL_INT检查处理
            //      *       显式检查
            //      /       如果lhs=MIN且rhs=-1;结果始终适合mp_int_t,然后由SMALL_INT检查处理
            //      %       如果lhs=MIN且rhs=-1;结果始终适合mp_int_t,然后由SMALL_INT检查处理
            //      <<      显式检查

            switch (op) {
   
                // 位运算符
                case MP_BINARY_OP_OR:
                case MP_BINARY_OP_INPLACE_OR:
                    lhs_val |= rhs_val;
                    break;
                case MP_BINARY_OP_XOR:
                case MP_BINARY_OP_INPLACE_XOR:
                    lhs_val ^= rhs_val;
                    break;
                case MP_BINARY_OP_AND:
                case MP_BINARY_OP_INPLACE_AND:
                    lhs_val &= rhs_val;
                    break;
                case MP_BINARY_OP_LSHIFT:
                case MP_BINARY_OP_INPLACE_LSHIFT: {
   
                    if (rhs_val < 0) {
   
                        // 负数位移不允许
                        mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
                    } else if (rhs_val >= (mp_int_t)(sizeof(lhs_val) * MP_BITS_PER_BYTE)
                               || lhs_val > (MP_SMALL_INT_MAX >> rhs_val)
                               || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) {
   
                        // 左移将发生溢出,因此使用更高精度的整数
                        lhs = mp_obj_new_int_from_ll(lhs_val);
                        goto generic_binary_op;
                    } else {
   
                        // 使用标准精度
                        lhs_val = (mp_uint_t)lhs_val << rhs_val;
                    }
                    break;
                }
                case MP_BINARY_OP_RSHIFT:
                case MP_BINARY_OP_INPLACE_RSHIFT:
                    if (rhs_val < 0) {
   
                        // 负数位移不允许
                        mp_raise_ValueError(MP_ERROR_TEXT("negative shift count"));
                    } else {
   
                        // 右移使用标准精度
                        if (rhs_val >= (mp_int_t)(sizeof(lhs_val) * MP_BITS_PER_BYTE)) {
   
                            // 大量移位是未定义行为
                            // 在C中是CPU依赖的;传播符号位
                            rhs_val = sizeof(lhs_val) * MP_BITS_PER_BYTE - 1;
                        }
                        lhs_val >>= rhs_val;
                    }
                    break;
                // 算术运算符
                case MP_BINARY_OP_ADD:
                case MP_BINARY_OP_INPLACE_ADD:
                    lhs_val += rhs_val;
                    break;
                case MP_BINARY_OP_SUBTRACT:
                case MP_BINARY_OP_INPLACE_SUBTRACT:
                    lhs_val -= rhs_val;
                    break;
                case MP_BINARY_OP_MULTIPLY:
                case MP_BINARY_OP_INPLACE_MULTIPLY: {
   
                    // 如果存在长长整型并且比mp_int_t更大,则可以使用以下代码
                    // 执行溢出检查乘法。
                    // 否则(例如x64情况),我们必须使用mp_small_int_mul_overflow。
                    #if 0
                    // 使用长长整型精度计算结果
                    long long res = (long long)lhs_val * (long long)rhs_val;
                    if (res > MP_SMALL_INT_MAX || res < MP_SMALL_INT_MIN) {
   
                        // 结果溢出了SMALL_INT,因此返回更高精度的整数
                        return mp_obj_new_int_from_ll(res);
                    } else {
   
                        // 使用标准精度
                        lhs_val = (mp_int_t)res;
                    }
                    #endif

                    if (mp_small_int_mul_overflow(lhs_val, rhs_val)) {
   
                        // 使用更高精度
                        lhs = mp_obj_new_int_from_ll(lhs_val);
                        goto generic_binary_op;
                    } else {
   
                        // 使用标准精度
                        return MP_OBJ_NEW_SMALL_INT(lhs_val * rhs_val);
                    }
                }
                // 其他运算符的实现...
                default:
                    goto unsupported_op;
            }
            // 这是一个内联版本的mp_obj_new_int,为了速度
            if (MP_SMALL_INT_FITS(lhs_val)) {
   
                return MP_OBJ_NEW_SMALL_INT(lhs_val);
            } else {
   
                return mp_obj_new_int_from_ll(lhs_val);
            }
        #if MICROPY_PY_BUILTINS_FLOAT
        } else if (mp_obj_is_float(rhs)) {
   
            mp_obj_t res = mp_obj_float_binary_op(op, (mp_float_t)lhs_val, rhs);
            if (res == MP_OBJ_NULL) {
   
                goto unsupported_op;
            } else {
   
                return res;
            }
        }
        #if MICROPY_PY_BUILTINS_COMPLEX
        } else if (mp_obj_is_type(rhs, &mp_type_complex)) {
   
            mp_obj_t res = mp_obj_complex_binary_op(op, (mp_float_t)lhs_val, 0, rhs);
            if (res == MP_OBJ_NULL) 
  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

openwin_top

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

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

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

打赏作者

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

抵扣说明:

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

余额充值