[python] co_lnotab

co_lnotab is the mapping from bytecode to code line number.

# python3.6
Python 3.6.5 (default, Apr 16 2018, 16:19:06) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import six
>>> import dis
>>> def f(x):
...     x = x + 1
...     x = x * x
...     return x
... 
>>> co = f.__code__
>>> dis.dis(co)
  2           0 LOAD_FAST                0 (x)
              2 LOAD_CONST               1 (1)
              4 BINARY_ADD
              6 STORE_FAST               0 (x)

  3           8 LOAD_FAST                0 (x)
             10 LOAD_FAST                0 (x)
             12 BINARY_MULTIPLY
             14 STORE_FAST               0 (x)

  4          16 LOAD_FAST                0 (x)
             18 RETURN_VALUE
>>> co.co_lnotab
b'\x00\x01\x08\x01\x08\x01'
>>> co.co_firstlineno
1

how to decode co_lnotab?
for each byte in co_lnotab, even numbered bytes are the gap of bytecode while odd numbered bytes are the gap of python code.
bytecode starts from 0 while python code starts from co_firstlineno.

bytecode nopython no
01
0+0=01+1=2
0+8=82+1=3
8+8=163+1=4

so how to determine the line number of python code if bytecode line number A?

import six

# code_obj is the code object of function
# pos is the position in bytecode
def get_line_no(code_obj, pos):
    byte_increments = six.iterbytes(code_obj.co_lnotab[0::2])
    line_increments = six.iterbytes(code_obj.co_lnotab[1::2])

    byte_num = 0
    line_num = code_obj.co_firstlineno

    for byte_inc, line_inc in zip(byte_increments, line_increments):
        byte_num += byte_inc
        if byte_num > pos:
            return line_num
        line_num += line_inc
    return None

the code snippet is from : https://github.com/nedbat/byterun

more info of lnotab:
https://svn.python.org/projects/python/branches/pep-0384/Objects/lnotab_notes.txt

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值