Message260925
The findlabels function takes a bytecode array of type bytes, usually the
actual code from a function. My original test case uses the full Python
compiler from source code to a CodeType object to create the bytecodes
(plus all that other stuff that makes up a function), then extracts just
the interesting part and passes that into findlabels.
The good part is that you can pretend you're the compiler by just putting
the correct bytes into a array and feed it into the various dis functions.
The EXTENDED_ARG operator plays with the operand of the succeeding
instruction, everything else either doesn't have an argument or has two
bytes.
Here's a real test case, I don't know how you write unit tests for the
stdlib, but you can compare the output of the findlabels call with a known
value, and that should get you pretty close.
from opcode import *
code = bytes(
chr(opmap["JUMP_FORWARD"]) + chr(0) + chr(0) +
chr(EXTENDED_ARG) + chr(1) + chr(0) +
chr(opmap["JUMP_FORWARD"]) + chr(0) + chr(0) +
chr(opmap["RETURN_VALUE"]),
encoding="latin-1"
)
import dis
dis.dis(code)
print(dis.findlabels(code))
if dis.findlabels(code) == [0x0000+3, 0x00010000+9]:
print("Test passed")
Take a look in the stdlib opcode.py and find the various "JUMP" operators,
those are the guys we care about for this. Try out a bunch of cases by
augmenting the above definition of "code" and you'll soon get a feel for
what's going on.
As real, executable bytecode the above is of course non-sensical, but for a
test, it's great because you can predict exactly what should be produced.
|
|
Date |
User |
Action |
Args |
2016-02-27 06:48:44 | eric.fahlgren | set | recipients:
+ eric.fahlgren, llllllllll, Barun Parruck |
2016-02-27 06:48:44 | eric.fahlgren | link | issue26448 messages |
2016-02-27 06:48:43 | eric.fahlgren | create | |
|