通过“汇编”字节码生成Python代码对象(现在还包括功能/AST导向的API!)
项目描述
peak.util.assembler 是一个简单的字节码汇编模块,处理大多数底层字节码生成细节,如跳转偏移、栈大小跟踪、行号表生成、常量和变量名索引跟踪等。这样,您可以专注于字节码的期望语义,而不是这些机械问题。
除了直接生成特定Python字节码的低级操作码导向的API之外,此模块还提供了一个可扩展的迷你AST框架,用于从高级规范生成代码。此框架完成了将树状结构转换为线性字节码指令所需的大部分工作,并包括编译时常量折叠的能力。
有关更多详细信息,请参阅字节码汇编器参考手册。
自0.6版本以来的更改
修复了BUILD_CLASS操作码的坏栈计算
自0.5.2版本以来的更改
对Python 2.7向后兼容的JUMP_IF_TRUE 和 JUMP_IF_FALSE 操作码的符号反汇编以及完整仿真——现在测试在Python 2.7上运行正常。
对早期Python版本中Python 2.7的JUMP_IF_TRUE_OR_POP 和 JUMP_IF_FALSE_OR_POP 指令的向后仿真支持;这些仿真也用于字节码汇编器内部代码生成,以在2.7+上实现最大性能(对旧版本的性能没有改变)。
自0.5.1版本以来的更改
对Python 2.7的新操作码和语义更改的初始支持,主要通过宏模拟旧版本的行为。(0.5.2实际上只是一个快速修复版本,允许使用字节码汇编器的包在2.7上运行而无需更改任何代码生成;未来的版本将提供对新操作码和更改操作码的适当支持,以及一个在Python 2.7下不显示假差异的反汇编列表测试套件。)
自0.5版本以来的变更
修复了Python 2.5+上MAKE_CLOSURE的堆栈大小计算错误
自0.3版本以来的变更
新增节点类型
For(iterable, assign, body) – 定义一个遍历iterable的“for”循环
UnpackSequence(nodes) – 解包长度为len(nodes)的序列,然后生成指定的节点
LocalAssign(name) – 根据给定的名称发出适当的STORE_FAST、STORE_DEREF或STORE_LOCAL
Function(body, name='<lambda>', args=(), var=None, kw=None, defaults=()) – 从body创建嵌套函数并将其放入堆栈中
If(cond, then_, else_=Pass) – “if”语句的类似物
ListComp(body)和LCAppend(value) – 实现列表推导式
YieldStmt(value) – 生成YIELD_VALUE(Python 2.5+中的POP_TOP)
Code对象现在可迭代,生成(offset, op, arg)三元组,其中op是数字,arg是数字或None。
Code对象的.code()方法现在可以接受一个“parent” Code对象,以便将子代码的免费变量链接到父代码的单元格变量。
添加了Code.from_spec()类方法,可以从名称和参数规范初始化代码对象。
Code对象现在有一个.nested(name, args, var, kw)方法,该方法创建具有相同co_filename和提供的名称/参数规范的子代码对象。
修复了FOR_ITER和YIELD_VALUE操作码的错误堆栈跟踪
确保使用YIELD_VALUE操作码时设置CO_GENERATOR标志
修改测试,以便Python 2.3的dis.dis和常量折叠优化器在测试套件中不会生成虚假失败。
自0.2版本以来的变更
添加了Suite、TryExcept和TryFinally节点类型
添加了执行静态或动态属性访问和常量折叠的Getattr节点类型
修复了当指定copy_lineno时,code.from_function()不复制co_filename属性的问题。
AST节点的repr()不再为1-参数节点类型包含尾随逗号。
添加了一个不生成代码的Pass符号,一个执行n路比较的Compare()节点类型,以及用于逻辑运算的And()和Or()节点类型。
COMPARE_OP()方法现在接受操作符字符串,如"<="、"not in"、"exception match"等,以及数字操作码。有关接受的字符串的完整列表,请参阅标准库中的opcode模块(在cmp_op元组中)。"<>"也被接受为"!="的别名。
添加了代码以验证前向跳转偏移量不超过64KB范围,并支持绝对后向跳转到大于64KB的位置。
自0.1版本以来的更改
已修复常量处理,以确保不会混淆不同类型但相等的值(例如1.0和True),或相等的不可哈希对象(例如两个空列表)。
已删除nil、ast_curry()和folding_curry(),并用nodetype()装饰器和fold_args()替换它们;请参阅文档获取更多详细信息。
添加了跨跳转的堆栈跟踪,全局验证堆栈级别预测的一致性,并自动拒绝生成死代码的尝试。现在几乎不可能意外生成会导致解释器崩溃的字节码。(如果你找到了方法,请告诉我!)
自0.0.1版本以来的更改
添加了大量新的文档和示例
支持完整的块、循环和闭包
从树中生成高级函数代码,具有智能标签和块、常量折叠、可扩展性、智能局部变量名等。
将.label()方法重命名为.here(),以区分新的智能Label对象。
将文档和测试移动到README.txt,而不是assembler.txt
添加了一个演示,实现了类似“switch”的语句模板,展示了如何扩展代码生成系统以及如何滥用END_FINALLY在字节码中实现“计算跳转”。
各种错误修复
有一些功能尚未经过测试,并且并非所有操作码都可能完全支持。此外,请注意以下限制
跳转到尚未定义的标签的距离不能超过65,535字节。
Python 2.3中的dis()函数有一个错误,当两个相邻行号之间的差异大于255时,它会显示不正确的行号。(为了解决这个问题,test_suite使用dis()的较新版本,但请注意,如果你使用Python 2.3和广泛分隔的行号使用dis(),它可能影响你自己的测试。)
如果你发现任何其他问题,请告诉我。
请记住,这是一个正在进行中的项目,如果我想出更好的方法来做某事,API可能会发生变化。
关于此软件的问题和讨论应发送到PEAK邮件列表。
项目详细信息
BytecodeAssembler-0.6.1.zip的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | c949167dc6ec620003ded3124db24efc299ca5a31c8d3a5c22f0578745e82771 |
|
MD5 | d0680fcbc3043ba3fa2f27ad6e5217f1 |
|
BLAKE2b-256 | 5191f9faa7ddd6e42c0d8de47e5e06fca2b8b4be56261389ad0dea3abeb1b177 |