跳转到主要内容

通过“汇编”字节码生成Python代码对象(现在还包括功能/AST导向的API!)

项目描述

peak.util.assembler 是一个简单的字节码汇编模块,处理大多数底层字节码生成细节,如跳转偏移、栈大小跟踪、行号表生成、常量和变量名索引跟踪等。这样,您可以专注于字节码的期望语义,而不是这些机械问题。

除了直接生成特定Python字节码的低级操作码导向的API之外,此模块还提供了一个可扩展的迷你AST框架,用于从高级规范生成代码。此框架完成了将树状结构转换为线性字节码指令所需的大部分工作,并包括编译时常量折叠的能力。

有关更多详细信息,请参阅字节码汇编器参考手册

自0.6版本以来的更改

  • 修复了BUILD_CLASS操作码的坏栈计算

自0.5.2版本以来的更改

  • 对Python 2.7向后兼容的JUMP_IF_TRUEJUMP_IF_FALSE 操作码的符号反汇编以及完整仿真——现在测试在Python 2.7上运行正常。

  • 对早期Python版本中Python 2.7的JUMP_IF_TRUE_OR_POPJUMP_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_FASTSTORE_DEREFSTORE_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_ITERYIELD_VALUE操作码的错误堆栈跟踪

  • 确保使用YIELD_VALUE操作码时设置CO_GENERATOR标志

  • 修改测试,以便Python 2.3的dis.dis和常量折叠优化器在测试套件中不会生成虚假失败。

自0.2版本以来的变更

  • 添加了SuiteTryExceptTryFinally节点类型

  • 添加了执行静态或动态属性访问和常量折叠的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.0True),或相等的不可哈希对象(例如两个空列表)。

  • 已删除nilast_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 (53.5 kB 查看哈希值)

上传时间: 源代码

由以下支持