Merge pull request #483 from rocky/xdis-fix-woes

Xdis fix woes
This commit is contained in:
R. Bernstein
2024-02-11 23:28:43 -05:00
committed by GitHub
6 changed files with 74 additions and 84 deletions

View File

@@ -15,8 +15,8 @@ from typing import List
import click import click
from xdis.version_info import version_tuple_to_str from xdis.version_info import version_tuple_to_str
from uncompyle6 import verify
from uncompyle6.main import main, status_msg from uncompyle6.main import main, status_msg
from uncompyle6.verify import VerifyCmpError
from uncompyle6.version import __version__ from uncompyle6.version import __version__
program = "uncompyle6" program = "uncompyle6"
@@ -245,7 +245,7 @@ def main_bin(
sys.exit(2) sys.exit(2)
except KeyboardInterrupt: except KeyboardInterrupt:
pass pass
except verify.VerifyCmpError: except VerifyCmpError:
raise raise
else: else:
from multiprocessing import Process, Queue from multiprocessing import Process, Queue
@@ -266,18 +266,18 @@ def main_bin(
tot_files = okay_files = failed_files = verify_failed_files = 0 tot_files = okay_files = failed_files = verify_failed_files = 0
def process_func(): def process_func():
(tot_files, okay_files, failed_files, verify_failed_files) = (
0,
0,
0,
0,
)
try: try:
(tot_files, okay_files, failed_files, verify_failed_files) = (
0,
0,
0,
0,
)
while 1: while 1:
f = fqueue.get() f = fqueue.get()
if f is None: if f is None:
break break
(t, o, f, v) = main(src_base, out_base, [f], [], outfile, **options) (t, o, f, v) = main(src_base, out_base, [f], [], outfile)
tot_files += t tot_files += t
okay_files += o okay_files += o
failed_files += f failed_files += f

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2023 Rocky Bernstein # Copyright (c) 2015-2024 Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org> # Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# Copyright (c) 1999 John Aycock # Copyright (c) 1999 John Aycock
@@ -1221,9 +1221,24 @@ class Python3Parser(PythonParser):
) )
) )
else: else:
rule = "mkfunc ::= %s%sload_closure LOAD_CODE LOAD_STR %s" % ( if self.version == (3, 3):
kwargs_str, # 3.3 puts kwargs before pos_arg
"pos_arg " * pos_args_count, pos_kw_tuple = (
("kwargs " * kw_args_count),
("pos_arg " * pos_args_count),
)
else:
# 3.4 and 3.5 puts pos_arg before kwargs
pos_kw_tuple = (
"pos_arg " * (pos_args_count),
("kwargs " * kw_args_count),
)
rule = (
"mkfunc ::= %s%s%s " "load_closure LOAD_CODE LOAD_STR %s"
) % (
pos_kw_tuple[0],
pos_kw_tuple[1],
"annotate_pair " * (annotate_args),
opname, opname,
) )
self.add_unique_rule(rule, opname, token.attr, customize) self.add_unique_rule(rule, opname, token.attr, customize)
@@ -1465,12 +1480,12 @@ class Python3Parser(PythonParser):
) )
self.add_unique_rule(rule, opname, token.attr, customize) self.add_unique_rule(rule, opname, token.attr, customize)
rule = ( rule = (
"mkfunc_annotate ::= %s%sannotate_tuple LOAD_CODE LOAD_STR %s" "mkfunc_annotate ::= %s%sannotate_tuple LOAD_CODE "
% ( "LOAD_STR %s"
("pos_arg " * pos_args_count), ) % (
("annotate_arg " * annotate_args), ("pos_arg " * pos_args_count),
opname, ("annotate_arg " * annotate_args),
) opname,
) )
if self.version >= (3, 3): if self.version >= (3, 3):
if self.version == (3, 3): if self.version == (3, 3):
@@ -1480,29 +1495,19 @@ class Python3Parser(PythonParser):
("pos_arg " * pos_args_count), ("pos_arg " * pos_args_count),
) )
else: else:
# 3.4 and 3.5puts pos_arg before kwargs # 3.4 and 3.5 puts pos_arg before kwargs
pos_kw_tuple = ( pos_kw_tuple = (
"pos_arg " * (pos_args_count), "pos_arg " * (pos_args_count),
("kwargs " * kw_args_count), ("kwargs " * kw_args_count),
) )
rule = ( rule = (
"mkfunc_annotate ::= %s%s%sannotate_tuple LOAD_CODE LOAD_STR %s" "mkfunc_annotate ::= %s%s%sannotate_tuple LOAD_CODE "
% ( "LOAD_STR %s"
pos_kw_tuple[0], ) % (
pos_kw_tuple[1], pos_kw_tuple[0],
("annotate_arg " * annotate_args), pos_kw_tuple[1],
opname, ("annotate_arg " * annotate_args),
) opname,
)
self.add_unique_rule(rule, opname, token.attr, customize)
rule = (
"mkfunc_annotate ::= %s%s%sannotate_tuple LOAD_CODE LOAD_STR %s"
% (
pos_kw_tuple[0],
pos_kw_tuple[1],
("annotate_arg " * annotate_args),
opname,
)
) )
else: else:
rule = ( rule = (

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2019, 2021-2023 by Rocky Bernstein # Copyright (c) 2015-2019, 2021-2024 by Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org> # Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# #
@@ -482,7 +482,6 @@ class Scanner3(Scanner):
last_op_was_break = False last_op_was_break = False
new_tokens = [] new_tokens = []
operand_value = 0
for i, inst in enumerate(self.insts): for i, inst in enumerate(self.insts):
opname = inst.opname opname = inst.opname
@@ -534,11 +533,9 @@ class Scanner3(Scanner):
op = inst.opcode op = inst.opcode
if opname == "EXTENDED_ARG": if opname == "EXTENDED_ARG":
if i + 1 < n: # EXTEND_ARG adjustments to the operand value should have
operand_value = argval << 16 # already been accounted for in xdis instruction creation.
continue continue
else:
operand_value = 0
if inst.offset in jump_targets: if inst.offset in jump_targets:
jump_idx = 0 jump_idx = 0
@@ -645,7 +642,7 @@ class Scanner3(Scanner):
attr = attr[:4] # remove last value: attr[5] == False attr = attr[:4] # remove last value: attr[5] == False
else: else:
pos_args, name_pair_args, annotate_args = parse_fn_counts_30_35( pos_args, name_pair_args, annotate_args = parse_fn_counts_30_35(
inst.argval + operand_value inst.argval
) )
pattr = f"{pos_args} positional, {name_pair_args} keyword only, {annotate_args} annotated" pattr = f"{pos_args} positional, {name_pair_args} keyword only, {annotate_args} annotated"

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2017, 2021-2022 by Rocky Bernstein # Copyright (c) 2017, 2021-2022, 2024 by Rocky Bernstein
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -22,21 +22,22 @@ This sets up opcodes Python's 3.5 and calls a generalized
scanner routine for Python 3. scanner routine for Python 3.
""" """
from __future__ import print_function # bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_35 as opc
from uncompyle6.scanners.scanner3 import Scanner3 from uncompyle6.scanners.scanner3 import Scanner3
# bytecode verification, verify(), uses JUMP_OPs from here
from xdis.opcodes import opcode_35 as opc
JUMP_OPS = opc.JUMP_OPS JUMP_OPS = opc.JUMP_OPS
class Scanner35(Scanner3):
class Scanner35(Scanner3):
def __init__(self, show_asm=None, is_pypy=False): def __init__(self, show_asm=None, is_pypy=False):
Scanner3.__init__(self, (3, 5), show_asm, is_pypy) Scanner3.__init__(self, (3, 5), show_asm, is_pypy)
return return
pass pass
if __name__ == "__main__": if __name__ == "__main__":
from xdis.version_info import PYTHON_VERSION_TRIPLE, version_tuple_to_str from xdis.version_info import PYTHON_VERSION_TRIPLE, version_tuple_to_str

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2020, 2022-2023 by Rocky Bernstein # Copyright (c) 2015-2020, 2022-2024 by Rocky Bernstein
# Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org> # Copyright (c) 2005 by Dan Pascu <dan@windowmaker.org>
# Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com> # Copyright (c) 2000-2002 by hartmut Goebel <h.goebel@crazy-compilers.com>
# #
@@ -15,7 +15,7 @@
# 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/>.
""" """
Python 37 bytecode scanner/deparser base. Python 3.7 bytecode scanner/deparser base.
Also we *modify* the instruction sequence to assist deparsing code. Also we *modify* the instruction sequence to assist deparsing code.
For example: For example:
@@ -29,20 +29,17 @@ For example:
Finally we save token information. Finally we save token information.
""" """
import sys
from typing import Any, Dict, List, Set, Tuple from typing import Any, Dict, List, Set, Tuple
from xdis import iscode, instruction_size, Instruction
from xdis.bytecode import _get_const_info
from uncompyle6.scanner import Token
import xdis import xdis
# Get all the opcodes into globals # Get all the opcodes into globals
import xdis.opcodes.opcode_37 as op3 import xdis.opcodes.opcode_37 as op3
from xdis import Instruction, instruction_size, iscode
from xdis.bytecode import _get_const_info
from uncompyle6.scanner import Scanner from uncompyle6.scanner import Scanner, Token
import sys
globals().update(op3.opmap) globals().update(op3.opmap)
@@ -51,7 +48,9 @@ CONST_COLLECTIONS = ("CONST_LIST", "CONST_SET", "CONST_DICT")
class Scanner37Base(Scanner): class Scanner37Base(Scanner):
def __init__(self, version: Tuple[int, int], show_asm=None, debug="", is_pypy=False): def __init__(
self, version: Tuple[int, int], 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.offset2tok_index = None
self.debug = debug self.debug = debug
@@ -254,7 +253,6 @@ class Scanner37Base(Scanner):
n = len(self.insts) n = len(self.insts)
for i, inst in enumerate(self.insts): for i, inst in enumerate(self.insts):
# We need to detect the difference between: # We need to detect the difference between:
# raise AssertionError # raise AssertionError
# and # and
@@ -284,7 +282,6 @@ class Scanner37Base(Scanner):
# To simplify things we want to untangle this. We also # To simplify things we want to untangle this. We also
# do this loop before we compute jump targets. # do this loop before we compute jump targets.
for i, inst in enumerate(self.insts): for i, inst in enumerate(self.insts):
# One artifact of the "too-small" operand problem, is that # One artifact of the "too-small" operand problem, is that
# some backward jumps, are turned into forward jumps to another # some backward jumps, are turned into forward jumps to another
# "extended arg" backward jump to the same location. # "extended arg" backward jump to the same location.
@@ -321,16 +318,9 @@ class Scanner37Base(Scanner):
j = 0 j = 0
for i, inst in enumerate(self.insts): for i, inst in enumerate(self.insts):
argval = inst.argval argval = inst.argval
op = inst.opcode op = inst.opcode
if inst.opname == "EXTENDED_ARG":
# FIXME: The EXTENDED_ARG is used to signal annotation
# parameters
if i + 1 < n and self.insts[i + 1].opcode != self.opc.MAKE_FUNCTION:
continue
if inst.offset in jump_targets: if inst.offset in jump_targets:
jump_idx = 0 jump_idx = 0
# We want to process COME_FROMs to the same offset to be in *descending* # We want to process COME_FROMs to the same offset to be in *descending*

View File

@@ -1,4 +1,4 @@
# Copyright (c) 2015-2021 by Rocky Bernstein # Copyright (c) 2015-2021, 2024 by Rocky Bernstein
# #
# This program is free software: you can redistribute it and/or modify # This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by # it under the terms of the GNU General Public License as published by
@@ -16,18 +16,18 @@
All the crazy things we have to do to handle Python functions in 3.0-3.5 or so. All the crazy things we have to do to handle Python functions in 3.0-3.5 or so.
The saga of changes before and after is in other files. The saga of changes before and after is in other files.
""" """
from xdis import iscode, code_has_star_arg, code_has_star_star_arg, CO_GENERATOR from xdis import CO_GENERATOR, code_has_star_arg, code_has_star_star_arg, iscode
from uncompyle6.scanner import Code
from uncompyle6.parsers.treenode import SyntaxTree
from uncompyle6.semantics.parser_error import ParserError
from uncompyle6.parser import ParserError as ParserError2 from uncompyle6.parser import ParserError as ParserError2
from uncompyle6.parsers.treenode import SyntaxTree
from uncompyle6.scanner import Code
from uncompyle6.semantics.helper import ( from uncompyle6.semantics.helper import (
print_docstring,
find_all_globals, find_all_globals,
find_globals_and_nonlocals, find_globals_and_nonlocals,
find_none, find_none,
print_docstring,
) )
from uncompyle6.semantics.parser_error import ParserError
from uncompyle6.show import maybe_show_tree_param_default from uncompyle6.show import maybe_show_tree_param_default
# FIXME: DRY the below code... # FIXME: DRY the below code...
@@ -42,8 +42,8 @@ def make_function3_annotate(
def build_param(ast, name, default): def build_param(ast, name, default):
"""build parameters: """build parameters:
- handle defaults - handle defaults
- handle format tuple parameters - handle format tuple parameters
""" """
if default: if default:
value = self.traverse(default, indent="") value = self.traverse(default, indent="")
@@ -300,7 +300,7 @@ def make_function3_annotate(
def make_function3(self, node, is_lambda, nested=1, code_node=None): def make_function3(self, node, is_lambda, nested=1, code_node=None):
"""Dump function definition, doc string, and function body in """Dump function definition, doc string, and function body in
Python version 3.0 and above Python version 3.0 and above
""" """
# For Python 3.3, the evaluation stack in MAKE_FUNCTION is: # For Python 3.3, the evaluation stack in MAKE_FUNCTION is:
@@ -333,8 +333,8 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
def build_param(ast, name, default, annotation=None): def build_param(ast, name, default, annotation=None):
"""build parameters: """build parameters:
- handle defaults - handle defaults
- handle format tuple parameters - handle format tuple parameters
""" """
value = self.traverse(default, indent="") value = self.traverse(default, indent="")
maybe_show_tree_param_default(self.showast, name, value) maybe_show_tree_param_default(self.showast, name, value)
@@ -419,7 +419,6 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
pass pass
if len(node) > 2 and (have_kwargs or node[lc_index].kind != "load_closure"): if len(node) > 2 and (have_kwargs or node[lc_index].kind != "load_closure"):
# Find the index in "node" where the first default # Find the index in "node" where the first default
# parameter value is located. Note this is in contrast to # parameter value is located. Note this is in contrast to
# key-word arguments, pairs of (name, value), which appear after "*". # key-word arguments, pairs of (name, value), which appear after "*".
@@ -492,8 +491,6 @@ def make_function3(self, node, is_lambda, nested=1, code_node=None):
self.ERROR = p self.ERROR = p
return return
kw_pairs = 0
i = len(paramnames) - len(defparams) i = len(paramnames) - len(defparams)
# build parameters # build parameters