MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.
#include <stdint.h> // 包含标准整数类型定义的头文件
#include <stdio.h> // 包含输入输出函数的头文件
#include <string.h> // 包含字符串操作函数的头文件
#include <assert.h> // 包含断言宏的头文件
// 包含MicroPython特有的头文件
#include "py/emitglue.h"
#include "py/runtime0.h"
#include "py/bc.h"
#include "py/objfun.h"
#include "py/profile.h"
// 调试宏定义,根据编译时的MICROPY_DEBUG_VERBOSE设置来决定是否打印调试信息
#if defined(MICROPY_DEBUG_VERBOSE) // 如果定义了MICROPY_DEBUG_VERBOSE,则打印调试信息
#define DEBUG_PRINT (1)
#define WRITE_CODE (1)
#define DEBUG_printf DEBUG_printf
#define DEBUG_OP_printf(...) DEBUG_printf(__VA_ARGS__)
#else // 如果没有定义MICROPY_DEBUG_VERBOSE,则不打印调试信息
#define DEBUG_printf(...) (void)0
#define DEBUG_OP_printf(...) (void)0
#endif
// 如果定义了MICROPY_DEBUG_PRINTERS,则声明一个全局变量mp_verbose_flag用于控制打印级别
#if defined(MICROPY_DEBUG_PRINTERS)
mp_uint_t mp_verbose_flag = 0;
#endif
// 函数定义:创建一个新的原始代码对象
mp_raw_code_t *mp_emit_glue_new_raw_code(void) {
mp_raw_code_t *rc = m_new0(mp_raw_code_t, 1); // 使用m_new0函数分配并初始化一个新的原始代码对象
rc->kind = MP_CODE_RESERVED; // 设置代码对象的类型为保留类型
#if defined(MICROPY_PY_SYS_SETTRACE)
rc->line_of_definition = 0; // 用于追踪代码定义行号的字段,初始值为0
#endif
return rc; // 返回新创建的原始代码对象
}
// 函数定义:将字节码分配给原始代码对象
void mp_emit_glue_assign_bytecode(mp_raw_code_t *rc, const byte *code, // 字节码和原始代码对象的指针
mp_raw_code_t **children,
#if defined(MICROPY_PERSISTENT_CODE_SAVE)
size_t len, // 字节码的长度
uint16_t n_children, // 子代码对象的数量
#endif
uint16_t scope_flags) // 作用域标志
{
rc->kind = MP_CODE_BYTECODE; // 设置代码对象的类型为字节码
rc->is_generator = (scope_flags & MP_SCOPE_FLAG_GENERATOR) != 0; // 判断是否为生成器函数
rc->fun_data = code; // 设置字节码数据
rc->children = children; // 设置子代码对象数组
#if defined(MICROPY_PERSISTENT_CODE_SAVE)
rc->fun_data_len = len; // 记录字节码的长度
rc->n_children = n_children; // 记录子代码对象的数量
#endif
#if defined(MICROPY_PY_SYS_SETTRACE)
mp_bytecode_prelude_t *prelude = &rc->prelude; // 获取字节码序言的指针
mp_prof_extract_prelude(code, prelude); // 提取字节码序言信息
#endif
#if defined(MICROPY_DEBUG_PRINT)
#if !defined(MICROPY_PERSISTENT_CODE_SAVE)
const size_t len = 0; // 如果没有定义MICROPY_PERSISTENT_CODE_SAVE,则长度设置为0
#endif
DEBUG_printf("assign byte code: code=%p len=" UINT_FMT " flags=%x\n", code, len, (uint)scope_flags); // 打印调试信息
#endif
}
// 如果定义了MICROPY_EMIT_MACHINE_CODE,则包含以下代码
#if defined(MICROPY_EMIT_MACHINE_CODE)
// 函数定义:将本地代码分配给原始代码对象
void mp_emit_glue_assign_native(mp_raw_code_t *rc, mp_raw_code_kind_t kind, // 原始代码的类型和本地代码的指针
const void *fun_data, mp_uint_t fun_len,
mp_raw_code_t **children,
#if defined(MICROPY_PERSISTENT_CODE_SAVE)
uint16_t n_children,
uint16_t prelude_offset,
#endif
uint16_t scope_flags, uint32_t asm_n_pos_args, uint32_t asm_type_sig
) {
assert(kind == MP_CODE_NATIVE_PY || kind == MP_CODE_NATIVE_VIPER || kind == MP_CODE_NATIVE_ASM); // 断言代码类型为本地Python、V