环境对象
Environment对象(Env)用于维护对python对象的引用,这些对象是支持对象模式和nopython模式编译函数所必需的。
在 nopython 模式下,Env 用于:
存储用于从原生值重建的 pyobjects,例如:
用于打印NumPy数组的本地值;
用于将本机值返回或生成回解释器。
在对象模式下,环境(Env)用于:
存储代码中引用的常量值。
存储对函数的全局字典的引用以加载全局值。
实现
Env 的实现分为两部分。在 _dynfunc.c
中,Env 被定义为 EnvironmentObject
,作为一个 Python C 扩展类型。在 lowering.py
中,EnvironmentObject``(导出为 ``_dynfunc.Environment`)被扩展以支持在 lowering 过程中所需的必要操作。
序列化
Env 支持被序列化。编译缓存文件和预编译模块会序列化所有使用的 Envs,以便在运行时重新创建。
用法
在函数或生成器的降低开始时,会创建一个 Env。在整个编译过程中,Env 会被修改以附加额外的信息。编译后的代码通过在生成的 LLVM IR 中的全局变量引用一个 Env。全局变量以“common”链接方式进行零初始化,这是 C 全局值的默认链接方式。这种链接方式的使用允许在模块链接在一起时将全局变量的多个定义合并为一个定义。全局变量的名称是从函数名称计算得出的(参见目标上下文的 FunctionDescriptor.env_name
和 .get_env_name()
)。
当编译函数被加载时,Env 被初始化。JIT 引擎找到与 Env 相关的全局变量的地址,并将 Env 的地址存储到其中。对于缓存函数,同样的过程适用。对于提前编译的函数,生成的库中的模块初始化器负责初始化模块中所有 Env 的全局变量。