You've already forked python-uncompyle6
mirror of
https://github.com/rocky/python-uncompyle6.git
synced 2025-08-04 01:09:52 +08:00
Merge branch 'python-3.3-to-3.5' into python-2.4
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
import os.path
|
import os.path
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from uncompyle6.disas import disassemble_file
|
from uncompyle6.code_fns import disassemble_file
|
||||||
|
|
||||||
def get_srcdir():
|
def get_srcdir():
|
||||||
filename = os.path.normcase(os.path.dirname(__file__))
|
filename = os.path.normcase(os.path.dirname(__file__))
|
||||||
|
@@ -2,3 +2,8 @@
|
|||||||
hypothesis==2.0.0
|
hypothesis==2.0.0
|
||||||
pytest
|
pytest
|
||||||
-e .
|
-e .
|
||||||
|
|
||||||
|
Click~=7.0
|
||||||
|
xdis>=6.0.4
|
||||||
|
configobj~=5.0.6
|
||||||
|
setuptools~=65.3.0
|
||||||
|
7
setup.py
7
setup.py
@@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
"""Setup script for the 'uncompyle6' distribution."""
|
"""Setup script for the 'uncompyle6' distribution."""
|
||||||
|
|
||||||
|
import setuptools
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
SYS_VERSION = sys.version_info[0:2]
|
SYS_VERSION = sys.version_info[0:2]
|
||||||
@@ -37,9 +38,7 @@ from __pkginfo__ import (
|
|||||||
zip_safe,
|
zip_safe,
|
||||||
)
|
)
|
||||||
|
|
||||||
from setuptools import setup, find_packages
|
setuptools.setup(
|
||||||
|
|
||||||
setup(
|
|
||||||
author=author,
|
author=author,
|
||||||
author_email=author_email,
|
author_email=author_email,
|
||||||
classifiers=classifiers,
|
classifiers=classifiers,
|
||||||
@@ -50,7 +49,7 @@ setup(
|
|||||||
long_description=long_description,
|
long_description=long_description,
|
||||||
long_description_content_type="text/x-rst",
|
long_description_content_type="text/x-rst",
|
||||||
name=modname,
|
name=modname,
|
||||||
packages=find_packages(),
|
packages=setuptools.find_packages(),
|
||||||
py_modules=py_modules,
|
py_modules=py_modules,
|
||||||
test_suite="nose.collector",
|
test_suite="nose.collector",
|
||||||
url=web,
|
url=web,
|
||||||
|
BIN
test/bytecode_3.7_run/10_extendedargifelse.pyc
Normal file
BIN
test/bytecode_3.7_run/10_extendedargifelse.pyc
Normal file
Binary file not shown.
272
test/simple_source/bug37/10_extendedargifelse.py
Normal file
272
test/simple_source/bug37/10_extendedargifelse.py
Normal file
@@ -0,0 +1,272 @@
|
|||||||
|
# This is RUNNABLE!
|
||||||
|
|
||||||
|
"""This program is self-checking!"""
|
||||||
|
|
||||||
|
# Bug was handling if which has EXTENDED_ARG
|
||||||
|
# See https://github.com/rocky/python-uncompyle6/pull/406
|
||||||
|
|
||||||
|
aa = 0
|
||||||
|
ab = 0
|
||||||
|
ac = 0
|
||||||
|
ad = 0
|
||||||
|
ae = 0
|
||||||
|
af = 0
|
||||||
|
ag = 0
|
||||||
|
ah = 0
|
||||||
|
ai = 0
|
||||||
|
aj = 0
|
||||||
|
ak = 0
|
||||||
|
al = 0
|
||||||
|
am = 0
|
||||||
|
an = 0
|
||||||
|
ao = 0
|
||||||
|
ap = 0
|
||||||
|
aq = 0
|
||||||
|
ar = 0
|
||||||
|
at = 0
|
||||||
|
au = 0
|
||||||
|
av = 0
|
||||||
|
aw = 0
|
||||||
|
ax = 0
|
||||||
|
ay = 0
|
||||||
|
az = 0
|
||||||
|
ba = 0
|
||||||
|
bb = 0
|
||||||
|
bc = 0
|
||||||
|
bd = 0
|
||||||
|
be = 0
|
||||||
|
bf = 0
|
||||||
|
bg = 0
|
||||||
|
bh = 0
|
||||||
|
bi = 0
|
||||||
|
bj = 0
|
||||||
|
bk = 0
|
||||||
|
bl = 0
|
||||||
|
bm = 0
|
||||||
|
bn = 0
|
||||||
|
bo = 0
|
||||||
|
bp = 0
|
||||||
|
bq = 0
|
||||||
|
br = 0
|
||||||
|
bs = 0
|
||||||
|
bt = 0
|
||||||
|
bu = 0
|
||||||
|
bv = 0
|
||||||
|
bw = 0
|
||||||
|
bx = 0
|
||||||
|
by = 0
|
||||||
|
bz = 0
|
||||||
|
ca = 0
|
||||||
|
cb = 0
|
||||||
|
cc = 0
|
||||||
|
cd = 0
|
||||||
|
ce = 0
|
||||||
|
cf = 0
|
||||||
|
cg = 0
|
||||||
|
ch = 0
|
||||||
|
ci = 0
|
||||||
|
cj = 0
|
||||||
|
ck = 0
|
||||||
|
cl = 0
|
||||||
|
cm = 0
|
||||||
|
cn = 0
|
||||||
|
co = 0
|
||||||
|
cp = 0
|
||||||
|
cq = 0
|
||||||
|
cr = 0
|
||||||
|
cs = 0
|
||||||
|
ct = 0
|
||||||
|
cu = 0
|
||||||
|
cv = 0
|
||||||
|
cw = 0
|
||||||
|
cx = 0
|
||||||
|
cy = 0
|
||||||
|
cz = 0
|
||||||
|
da = 0
|
||||||
|
db = 0
|
||||||
|
dc = 0
|
||||||
|
dd = 0
|
||||||
|
de = 0
|
||||||
|
df = 0
|
||||||
|
dg = 0
|
||||||
|
dh = 0
|
||||||
|
di = 0
|
||||||
|
dj = 0
|
||||||
|
dk = 0
|
||||||
|
dl = 0
|
||||||
|
dm = 0
|
||||||
|
dn = 0
|
||||||
|
do = 0
|
||||||
|
dp = 0
|
||||||
|
dq = 0
|
||||||
|
dr = 0
|
||||||
|
ds = 0
|
||||||
|
dt = 0
|
||||||
|
du = 0
|
||||||
|
dv = 0
|
||||||
|
dw = 0
|
||||||
|
dx = 0
|
||||||
|
dy = 0
|
||||||
|
dz = 0
|
||||||
|
ea = 0
|
||||||
|
eb = 0
|
||||||
|
ec = 0
|
||||||
|
ed = 0
|
||||||
|
ee = 0
|
||||||
|
ef = 0
|
||||||
|
eg = 0
|
||||||
|
eh = 0
|
||||||
|
ei = 0
|
||||||
|
ej = 0
|
||||||
|
ek = 0
|
||||||
|
el = 0
|
||||||
|
em = 0
|
||||||
|
en = 0
|
||||||
|
eo = 0
|
||||||
|
ep = 0
|
||||||
|
eq = 0
|
||||||
|
er = 0
|
||||||
|
es = 0
|
||||||
|
et = 0
|
||||||
|
eu = 0
|
||||||
|
ev = 0
|
||||||
|
ew = 0
|
||||||
|
ex = 0
|
||||||
|
ey = 0
|
||||||
|
ez = 0
|
||||||
|
fa = 0
|
||||||
|
fb = 0
|
||||||
|
fc = 0
|
||||||
|
fd = 0
|
||||||
|
fe = 0
|
||||||
|
ff = 0
|
||||||
|
fg = 0
|
||||||
|
fh = 0
|
||||||
|
fi = 0
|
||||||
|
fj = 0
|
||||||
|
fk = 0
|
||||||
|
fl = 0
|
||||||
|
fm = 0
|
||||||
|
fn = 0
|
||||||
|
fo = 0
|
||||||
|
fp = 0
|
||||||
|
fq = 0
|
||||||
|
fr = 0
|
||||||
|
fs = 0
|
||||||
|
ft = 0
|
||||||
|
fu = 0
|
||||||
|
fv = 0
|
||||||
|
fw = 0
|
||||||
|
fx = 0
|
||||||
|
fy = 0
|
||||||
|
fz = 0
|
||||||
|
ga = 0
|
||||||
|
gb = 0
|
||||||
|
gc = 0
|
||||||
|
gd = 0
|
||||||
|
ge = 0
|
||||||
|
gf = 0
|
||||||
|
gg = 0
|
||||||
|
gh = 0
|
||||||
|
gi = 0
|
||||||
|
gj = 0
|
||||||
|
gk = 0
|
||||||
|
gl = 0
|
||||||
|
gm = 0
|
||||||
|
gn = 0
|
||||||
|
go = 0
|
||||||
|
gp = 0
|
||||||
|
gq = 0
|
||||||
|
gr = 0
|
||||||
|
gs = 0
|
||||||
|
gt = 0
|
||||||
|
gu = 0
|
||||||
|
gv = 0
|
||||||
|
gw = 0
|
||||||
|
gx = 0
|
||||||
|
gy = 0
|
||||||
|
gz = 0
|
||||||
|
ha = 0
|
||||||
|
hb = 0
|
||||||
|
hc = 0
|
||||||
|
hd = 0
|
||||||
|
he = 0
|
||||||
|
hf = 0
|
||||||
|
hg = 0
|
||||||
|
hh = 0
|
||||||
|
hi = 0
|
||||||
|
hj = 0
|
||||||
|
hk = 0
|
||||||
|
hl = 0
|
||||||
|
hm = 0
|
||||||
|
hn = 0
|
||||||
|
ho = 0
|
||||||
|
hp = 0
|
||||||
|
hq = 0
|
||||||
|
hr = 0
|
||||||
|
hs = 0
|
||||||
|
ht = 0
|
||||||
|
hu = 0
|
||||||
|
hv = 0
|
||||||
|
hw = 0
|
||||||
|
hx = 0
|
||||||
|
hy = 0
|
||||||
|
hz = 0
|
||||||
|
ia = 0
|
||||||
|
ib = 0
|
||||||
|
ic = 0
|
||||||
|
id = 0
|
||||||
|
ie = 0
|
||||||
|
ig = 0
|
||||||
|
ih = 0
|
||||||
|
ii = 0
|
||||||
|
ij = 0
|
||||||
|
ik = 0
|
||||||
|
il = 0
|
||||||
|
im = 0
|
||||||
|
io = 0
|
||||||
|
ip = 0
|
||||||
|
iq = 0
|
||||||
|
ir = 0
|
||||||
|
it = 0
|
||||||
|
iu = 0
|
||||||
|
iv = 0
|
||||||
|
iw = 0
|
||||||
|
ix = 0
|
||||||
|
iy = 0
|
||||||
|
iz = 0
|
||||||
|
ja = 0
|
||||||
|
jb = 0
|
||||||
|
jc = 0
|
||||||
|
jd = 0
|
||||||
|
je = 0
|
||||||
|
jf = 0
|
||||||
|
jg = 0
|
||||||
|
jh = 0
|
||||||
|
ji = 0
|
||||||
|
jj = 0
|
||||||
|
jk = 0
|
||||||
|
jl = 0
|
||||||
|
jm = 0
|
||||||
|
jn = 0
|
||||||
|
jo = 0
|
||||||
|
jp = 0
|
||||||
|
jq = 0
|
||||||
|
jr = 0
|
||||||
|
js = 0
|
||||||
|
jt = 0
|
||||||
|
ju = 0
|
||||||
|
jv = 0
|
||||||
|
jw = 0
|
||||||
|
jx = 0
|
||||||
|
jy = 0
|
||||||
|
jz = 0
|
||||||
|
ka = 0
|
||||||
|
kb = 0
|
||||||
|
kc = 0
|
||||||
|
var = True
|
||||||
|
if var:
|
||||||
|
aa = 1
|
||||||
|
else:
|
||||||
|
aa = 2
|
||||||
|
assert aa == 1
|
@@ -5,7 +5,7 @@
|
|||||||
#
|
#
|
||||||
import sys, os, getopt
|
import sys, os, getopt
|
||||||
|
|
||||||
from uncompyle6.disas import disassemble_file
|
from uncompyle6.code_fns import disassemble_file
|
||||||
from uncompyle6.version import __version__
|
from uncompyle6.version import __version__
|
||||||
|
|
||||||
program, ext = os.path.splitext(os.path.basename(__file__))
|
program, ext = os.path.splitext(os.path.basename(__file__))
|
||||||
|
@@ -16,7 +16,7 @@ import datetime, os, py_compile, subprocess, sys
|
|||||||
|
|
||||||
from xdis import iscode
|
from xdis import iscode
|
||||||
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE, version_tuple_to_str
|
from xdis.version_info import IS_PYPY, PYTHON_VERSION_TRIPLE, version_tuple_to_str
|
||||||
from uncompyle6.disas import check_object_path
|
from uncompyle6.code_fns import check_object_path
|
||||||
from uncompyle6.semantics import pysource
|
from uncompyle6.semantics import pysource
|
||||||
from uncompyle6.semantics.pysource import PARSER_DEFAULT_DEBUG
|
from uncompyle6.semantics.pysource import PARSER_DEFAULT_DEBUG
|
||||||
from uncompyle6.parser import ParserError
|
from uncompyle6.parser import ParserError
|
||||||
|
@@ -136,6 +136,8 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
# print(tokens[t])
|
# print(tokens[t])
|
||||||
# print("=" * 30)
|
# print("=" * 30)
|
||||||
|
|
||||||
|
first_offset = tokens[first].off2int()
|
||||||
|
|
||||||
if rule not in IFELSE_STMT_RULES:
|
if rule not in IFELSE_STMT_RULES:
|
||||||
# print("XXX", rule)
|
# print("XXX", rule)
|
||||||
return False
|
return False
|
||||||
@@ -151,7 +153,7 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
):
|
):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Make sure all of the "come froms" offset at the
|
# Make sure all the offsets from the "come froms" at the
|
||||||
# end of the "if" come from somewhere inside the "if".
|
# end of the "if" come from somewhere inside the "if".
|
||||||
# Since the come_froms are ordered so that lowest
|
# Since the come_froms are ordered so that lowest
|
||||||
# offset COME_FROM is last, it is sufficient to test
|
# offset COME_FROM is last, it is sufficient to test
|
||||||
@@ -163,8 +165,8 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
end_come_froms = end_come_froms[0]
|
end_come_froms = end_come_froms[0]
|
||||||
if not isinstance(end_come_froms, Token):
|
if not isinstance(end_come_froms, Token):
|
||||||
if len(end_come_froms):
|
if len(end_come_froms):
|
||||||
return tokens[first].offset > end_come_froms[-1].attr
|
return first_offset > end_come_froms[-1].attr
|
||||||
elif tokens[first].offset > end_come_froms.attr:
|
elif first_offset > end_come_froms.attr:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# FIXME: There is weirdness in the grammar we need to work around.
|
# FIXME: There is weirdness in the grammar we need to work around.
|
||||||
@@ -173,7 +175,7 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
last_token = tree[-1]
|
last_token = tree[-1]
|
||||||
else:
|
else:
|
||||||
last_token = tokens[last]
|
last_token = tokens[last]
|
||||||
if last_token == "COME_FROM" and tokens[first].offset > last_token.attr:
|
if last_token == "COME_FROM" and first_offset > last_token.attr:
|
||||||
if self.version < (3, 0) and self.insts[self.offset2inst_index[last_token.attr]].opname != "SETUP_LOOP":
|
if self.version < (3, 0) and self.insts[self.offset2inst_index[last_token.attr]].opname != "SETUP_LOOP":
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -237,7 +239,7 @@ def ifelsestmt(self, lhs, n, rule, tree, tokens, first, last):
|
|||||||
if jump_else_end[-1].off2int() != jmp_target:
|
if jump_else_end[-1].off2int() != jmp_target:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if tokens[first].off2int() > jmp_target:
|
if first_offset > jmp_target:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return (jmp_target > last_offset) and tokens[last] != "JUMP_FORWARD"
|
return (jmp_target > last_offset) and tokens[last] != "JUMP_FORWARD"
|
||||||
|
@@ -6,7 +6,6 @@ If statement reduction check for Python 2.6 (and older?)
|
|||||||
|
|
||||||
def ifstmt2(self, lhs, n, rule, ast, tokens, first, last):
|
def ifstmt2(self, lhs, n, rule, ast, tokens, first, last):
|
||||||
|
|
||||||
# print("XXX", first, last)
|
|
||||||
# for t in range(first, last):
|
# for t in range(first, last):
|
||||||
# print(tokens[t])
|
# print(tokens[t])
|
||||||
# print("=" * 30)
|
# print("=" * 30)
|
||||||
@@ -61,15 +60,24 @@ def ifstmt2(self, lhs, n, rule, ast, tokens, first, last):
|
|||||||
|
|
||||||
if testexpr[0] in ("testtrue", "testfalse"):
|
if testexpr[0] in ("testtrue", "testfalse"):
|
||||||
test = testexpr[0]
|
test = testexpr[0]
|
||||||
if len(test) > 1 and test[1].kind.startswith("jmp_"):
|
jmp = test[1]
|
||||||
jmp_target = int(test[1][0].pattr)
|
if len(test) > 1 and jmp.kind.startswith("jmp_"):
|
||||||
|
jmp_target = int(jmp[0].pattr)
|
||||||
if last == len(tokens):
|
if last == len(tokens):
|
||||||
last -= 1
|
last -= 1
|
||||||
|
|
||||||
|
if_end_offset = tokens[last].off2int(prefer_last=False)
|
||||||
if (
|
if (
|
||||||
tokens[first].off2int(prefer_last=True)
|
tokens[first].off2int(prefer_last=True)
|
||||||
<= jmp_target
|
<= jmp_target
|
||||||
< tokens[last].off2int(prefer_last=False)
|
< if_end_offset
|
||||||
):
|
):
|
||||||
|
# In 2.6 (and before?) we need to check if the previous instruction
|
||||||
|
# is a jump to the last token. If so, testexpr is negated? and so
|
||||||
|
# jmp_target < if_end_offset.
|
||||||
|
previous_inst_index = self.offset2inst_index[jmp_target] - 1
|
||||||
|
previous_inst = self.insts[previous_inst_index]
|
||||||
|
if previous_inst.opname != "JUMP_ABSOLUTE" and previous_inst.argval != if_end_offset:
|
||||||
return True
|
return True
|
||||||
# jmp_target less than tokens[first] is okay - is to a loop
|
# jmp_target less than tokens[first] is okay - is to a loop
|
||||||
# jmp_target equal tokens[last] is also okay: normal non-optimized non-loop jump
|
# jmp_target equal tokens[last] is also okay: normal non-optimized non-loop jump
|
||||||
|
@@ -137,9 +137,9 @@ class Scanner(object):
|
|||||||
assert count <= i
|
assert count <= i
|
||||||
|
|
||||||
if collection_type == "CONST_DICT":
|
if collection_type == "CONST_DICT":
|
||||||
# constant dictonaries work via BUILD_CONST_KEY_MAP and
|
# constant dictionaries work via BUILD_CONST_KEY_MAP and
|
||||||
# handle the values() like sets and lists.
|
# handle the values() like sets and lists.
|
||||||
# However the keys() are an LOAD_CONST of the keys.
|
# However, the keys() are an LOAD_CONST of the keys.
|
||||||
# adjust offset to account for this
|
# adjust offset to account for this
|
||||||
count += 1
|
count += 1
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@ from xdis.opcodes import opcode_37pypy as opc # is this right?
|
|||||||
|
|
||||||
JUMP_OPs = opc.JUMP_OPS
|
JUMP_OPs = opc.JUMP_OPS
|
||||||
|
|
||||||
|
|
||||||
# We base this off of 3.7
|
# We base this off of 3.7
|
||||||
class ScannerPyPy37(scan.Scanner37):
|
class ScannerPyPy37(scan.Scanner37):
|
||||||
def __init__(self, show_asm):
|
def __init__(self, show_asm):
|
||||||
|
@@ -13,6 +13,7 @@ from xdis.opcodes import opcode_38pypy as opc
|
|||||||
|
|
||||||
JUMP_OPs = opc.JUMP_OPS
|
JUMP_OPs = opc.JUMP_OPS
|
||||||
|
|
||||||
|
|
||||||
# We base this off of 3.8
|
# We base this off of 3.8
|
||||||
class ScannerPyPy38(scan.Scanner38):
|
class ScannerPyPy38(scan.Scanner38):
|
||||||
def __init__(self, show_asm):
|
def __init__(self, show_asm):
|
||||||
|
@@ -119,9 +119,7 @@ class Scanner37(Scanner37Base):
|
|||||||
)
|
)
|
||||||
return new_tokens
|
return new_tokens
|
||||||
|
|
||||||
def ingest(
|
def ingest(self, bytecode, classname=None, code_objects={}, show_asm=None):
|
||||||
self, co, classname=None, code_objects={}, show_asm=None
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Create "tokens" the bytecode of an Python code object. Largely these
|
Create "tokens" the bytecode of an Python code object. Largely these
|
||||||
are the opcode name, but in some cases that has been modified to make parsing
|
are the opcode name, but in some cases that has been modified to make parsing
|
||||||
@@ -141,7 +139,7 @@ class Scanner37(Scanner37Base):
|
|||||||
cause specific rules for the specific number of arguments they take.
|
cause specific rules for the specific number of arguments they take.
|
||||||
"""
|
"""
|
||||||
tokens, customize = Scanner37Base.ingest(
|
tokens, customize = Scanner37Base.ingest(
|
||||||
self, co, classname, code_objects, show_asm
|
self, bytecode, classname, code_objects, show_asm
|
||||||
)
|
)
|
||||||
new_tokens = []
|
new_tokens = []
|
||||||
for i, t in enumerate(tokens):
|
for i, t in enumerate(tokens):
|
||||||
|
@@ -45,14 +45,18 @@ import sys
|
|||||||
globals().update(op3.opmap)
|
globals().update(op3.opmap)
|
||||||
|
|
||||||
|
|
||||||
|
CONST_COLLECTIONS = ("CONST_LIST", "CONST_SET", "CONST_DICT")
|
||||||
|
|
||||||
|
|
||||||
class Scanner37Base(Scanner):
|
class Scanner37Base(Scanner):
|
||||||
def __init__(self, version, show_asm=None, debug="", is_pypy=False):
|
def __init__(self, version, show_asm=None, debug="", is_pypy=False):
|
||||||
super(Scanner37Base, self).__init__(version, show_asm, is_pypy)
|
super(Scanner37Base, self).__init__(version, show_asm, is_pypy)
|
||||||
|
self.offset2tok_index = None
|
||||||
self.debug = debug
|
self.debug = debug
|
||||||
self.is_pypy = is_pypy
|
self.is_pypy = is_pypy
|
||||||
|
|
||||||
# Create opcode classification sets
|
# Create opcode classification sets
|
||||||
# Note: super initilization above initializes self.opc
|
# Note: super initialization above initializes self.opc
|
||||||
|
|
||||||
# Ops that start SETUP_ ... We will COME_FROM with these names
|
# Ops that start SETUP_ ... We will COME_FROM with these names
|
||||||
# Some blocks and END_ statements. And they can start
|
# Some blocks and END_ statements. And they can start
|
||||||
@@ -137,7 +141,7 @@ class Scanner37Base(Scanner):
|
|||||||
self.opc.POP_JUMP_IF_FALSE,
|
self.opc.POP_JUMP_IF_FALSE,
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
# Not really a set, but still clasification-like
|
# Not really a set, but still classification-like
|
||||||
self.statement_opcode_sequences = [
|
self.statement_opcode_sequences = [
|
||||||
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_FORWARD),
|
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_FORWARD),
|
||||||
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_ABSOLUTE),
|
(self.opc.POP_JUMP_IF_FALSE, self.opc.JUMP_ABSOLUTE),
|
||||||
@@ -272,7 +276,7 @@ class Scanner37Base(Scanner):
|
|||||||
if inst.opname == "JUMP_FORWARD":
|
if inst.opname == "JUMP_FORWARD":
|
||||||
jump_inst = self.insts[self.offset2inst_index[inst.argval]]
|
jump_inst = self.insts[self.offset2inst_index[inst.argval]]
|
||||||
if jump_inst.has_extended_arg and jump_inst.opname.startswith("JUMP"):
|
if jump_inst.has_extended_arg and jump_inst.opname.startswith("JUMP"):
|
||||||
# Create comination of the jump-to instruction and
|
# Create a combination of the jump-to instruction and
|
||||||
# this one. Keep the position information of this instruction,
|
# this one. Keep the position information of this instruction,
|
||||||
# but the operator and operand properties come from the other
|
# but the operator and operand properties come from the other
|
||||||
# instruction
|
# instruction
|
||||||
@@ -440,9 +444,9 @@ class Scanner37Base(Scanner):
|
|||||||
elif op == self.opc.JUMP_ABSOLUTE:
|
elif op == self.opc.JUMP_ABSOLUTE:
|
||||||
# Refine JUMP_ABSOLUTE further in into:
|
# Refine JUMP_ABSOLUTE further in into:
|
||||||
#
|
#
|
||||||
# * "JUMP_LOOP" - which are are used in loops. This is sometimes
|
# * "JUMP_LOOP" - which are used in loops. This is sometimes
|
||||||
# found at the end of a looping construct
|
# found at the end of a looping construct
|
||||||
# * "BREAK_LOOP" - which are are used to break loops.
|
# * "BREAK_LOOP" - which are used to break loops.
|
||||||
# * "CONTINUE" - jumps which may appear in a "continue" statement.
|
# * "CONTINUE" - jumps which may appear in a "continue" statement.
|
||||||
# It is okay to confuse this with JUMP_LOOP. The
|
# It is okay to confuse this with JUMP_LOOP. The
|
||||||
# grammar should tolerate this.
|
# grammar should tolerate this.
|
||||||
|
@@ -41,9 +41,7 @@ class Scanner38(Scanner37):
|
|||||||
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def ingest(
|
def ingest(self, bytecode, classname=None, code_objects={}, show_asm=None):
|
||||||
self, co, classname=None, code_objects={}, show_asm=None
|
|
||||||
):
|
|
||||||
"""
|
"""
|
||||||
Create "tokens" the bytecode of an Python code object. Largely these
|
Create "tokens" the bytecode of an Python code object. Largely these
|
||||||
are the opcode name, but in some cases that has been modified to make parsing
|
are the opcode name, but in some cases that has been modified to make parsing
|
||||||
@@ -63,7 +61,7 @@ class Scanner38(Scanner37):
|
|||||||
cause specific rules for the specific number of arguments they take.
|
cause specific rules for the specific number of arguments they take.
|
||||||
"""
|
"""
|
||||||
tokens, customize = super(Scanner38, self).ingest(
|
tokens, customize = super(Scanner38, self).ingest(
|
||||||
co, classname, code_objects, show_asm
|
bytecode, classname, code_objects, show_asm
|
||||||
)
|
)
|
||||||
|
|
||||||
# Hacky way to detect loop ranges.
|
# Hacky way to detect loop ranges.
|
||||||
|
@@ -15,7 +15,8 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import re, sys
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
def off2int(offset, prefer_last=True):
|
def off2int(offset, prefer_last=True):
|
||||||
@@ -90,7 +91,7 @@ class Token: # Python 2.4 can't have empty ()
|
|||||||
print("I don't know about Python version %s yet." % e)
|
print("I don't know about Python version %s yet." % e)
|
||||||
try:
|
try:
|
||||||
version_tuple = tuple(int(i) for i in str(e)[1:-1].split("."))
|
version_tuple = tuple(int(i) for i in str(e)[1:-1].split("."))
|
||||||
except:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if version_tuple > (3, 9):
|
if version_tuple > (3, 9):
|
||||||
|
Reference in New Issue
Block a user