NaleRaphael / bytefall

Another Python bytecode interpreter implemented in Python for version >= py34, with a few new features

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

bytefall

Build Status codecov Python Version License

This is a Python virtual machine implemented in pure Python and targeting Python version >= 3.4. It mainly derives from the following great works: nedbat/byterun and darius/tailbiter.

In this project, complete bytecode operations are implemented. And the structure of implementation is modified to make it more easily be extended for multiple versions of Python.

Besides, operations related to asyncio are also supported.

More features for debugging bytecode are going to be implemented, because I'm also trying to use this tool to fix some bugs in my own project bytejection.

Installation

$ pip install git+https://github.com/NaleRaphael/bytefall.git

Usage

Currently, version of virtual machine is automatically chosen according to your base Python runtime. Because it requires a base runtime to compile Python code to bytecode.

Therefore, you may need to create different virtual environment with the version of Python runtime you want to run this virtual machine.

$ python -m bytefall [YOUR_SCRIPT.py]

Run tests

$ python -m pytest ./tests/

# run tests including cases that usually take long time
$ python -m pytest ./tests/ --runslow

Features

  • You can run bytefall with an argument --debug to get detailed traceback of an unexpected error

    $ python -m bytefall --debug [YOUR_SCRIPT.py]
  • To show detailed information of each bytecode instruction which is going to be executed, you can run bytefall with --show_oparg.

    $ python -m bytefall --show_oparg [YOUR_SCRIPT.py]

    Then you can get something like this:

    # Format:
    # Instruction name | Arguments of instruction | Stack content on current frame
    
    LOAD_CONST (<code object main at 0x0000021583CAC150, file "foo.py", line 2>,) []
    LOAD_CONST ('main',) [<code object main at 0x0000021583CAC150, file "foo.py", line 2>]
    MAKE_FUNCTION (0,) [<code object main at 0x0000021583CAC150, file "foo.py", line 2>, 'main']
    STORE_NAME ('main',) [<Function main at 0x0000021583DDAA58>]
    # ...
    
  • To trace execution of each bytecode instruction, you can run bytefall with --trace_opcode, and use pdb.set_trace() to determine the entry.

    Try it online (repl.it)

    $ python -m bytefall --trace_opcode [YOUR_SCRIPT.py]
    # YOUR_SCRIPT.py
    def main():
        foo()
        import pdb; pdb.set_trace()
        bar()   # <- entry
        buzz()
  • To explore the internal execution of virtual machine with pdb, you can run it with an environment variable DEBUG_INTERNAL

    $ DEBUG_INTERNAL=1 python -m bytefall [YOUR_SCRIPT.py]

About

Another Python bytecode interpreter implemented in Python for version >= py34, with a few new features

License:Other


Languages

Language:Python 97.8%Language:Shell 2.2%